@go-to-k/cdkd 0.298.0 → 0.298.1

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.
@@ -2,7 +2,7 @@ import { r as getAwsClients, s as __exportAll } from "./aws-clients-CnmtbrxD.js"
2
2
  import { A as UNRENDERABLE, C as looksLikeCdkdGeneratedName, E as withoutGeneratedFallbackName, F as displayStackName, H as truncateCodePoints, I as isPasteableIdent, M as displayAwsMessage, N as displayIdent, O as SECRET_REF_MAX_CODE_POINTS, P as displaySafe, R as plainIdentOr, S as getCurrentStackName, T as withStackName, V as terminalSafe, a as getLogger, b as generateResourceNameWithFallback, d as installLogLineMaskerSource, f as getLiveRenderer, g as applyDefaultNameForFallback, k as STACK_REF_MAX_CODE_POINTS, o as isStdoutReservedForPayload, r as safeStringify$1, t as describeAwsFailure, u as currentLogLineMasker, v as explicitNamePropertyFor, w as withSkipPrefix, x as getCurrentSkipPrefix, y as generateResourceName, z as safeMsg } from "./aws-failure-text-DtvlUugx.js";
3
3
  import { $ as protectedReplacementAdvice, $n as isAmbiguousOutcomeError, $t as credentialFingerprint, A as isQuotableImportValue, An as UNSHOWABLE_VALUE, At as isAuxiliaryMarkOf, B as isTerminalDeleteFailure, Bn as withheldTargetClause, Bt as recoveryCommandFlags, Ct as RETRY_AUXILIARY_OWNER, Dt as createdResourceIdentityBeforeFailure, E as assertRegionMatch, Et as createdBeforeFailure, F as resolveExplicitPhysicalId, Fn as physicalIdShownBesideCommand, G as runDeleteAttempt, Gn as isNameCollisionErrorFrom, H as observeThenDisableProtection, Ht as CUSTOM_RESOURCE_RESPONSE_PREFIX, In as plainOrDescribed, J as DELETION_PROTECTION_DOC_POINTER, Jn as isReplayedNameCollisionFrom, Kn as isNameCooldownError, L as ProtectionFlipRegistry, Ln as quotedOrDescribed, Lt as formatLockExpiry, M as quotedRemedyLogicalId, Mt as markCreatedBeforeFailure, N as refusalTypeShown, Nn as isInertUnquoted, Nt as UNREPRODUCIBLE_LOCK_CLAUSE, On as SHELL_ACTIVE, Ot as hasCreatedBeforeFailure, Pn as pasteableCommand, Pt as buildForceUnlockCommand, Q as pasteableAwsCommand, Qn as isAmbiguousCcHandlerErrorCode, Qt as clientDefaultsFor, R as compensateProtectionFlip, Rn as shellBoundedDisplay, Rt as formatLockOperation, Sn as SynthesisError, St as withDerivedNameMasks, T as RESOURCE_NOT_FOUND, Tn as normalizeAwsError, U as protectionFlipKey, Un as isUpdateUnsupportedError, Ut as DEFAULT_STATE_PREFIX, Vt as sanitizeRecoveryValue, Wn as hasReplayMayCollide, Wt as injectiveKey, Xn as markReplayMayCollide, Xt as ambientClientDefaults, Yt as withPasteableAwsProfile, Zn as formatRetryClassificationSignals, Zt as ambientCredentialConfig, _n as ResourceTimeoutError, _t as createMaskedLogSinks, an as DependencyError, ar as isMarkedNonRetryable, at as startInterruptWatch, bt as maskDeep, cn as IntrinsicResolutionRefusalError, cr as markRedactedCause, ct as canonicalizeRoute53QueryName, d as prepareRemovalForUpdate, dn as LockError, en as AccountIdUnavailableError, er as isIamPropagationError, f as removalWarning, fn as MacroExpansionError, ft as logicalIdShown, gn as ProvisioningError, gt as stateOrphanRecordRemedy, ht as segmentAfterAnchor, i as holdsSecretDerivedEntry, in as CrossAccountSecretRefusalError, it as isInterruptedWaitError, j as normalizeAwsTagsToCfn, jn as commandHole, jt as markAuxiliaryFailure, kn as SHELL_ACTIVE_WHY, kt as isAuxiliaryFailure, l as withUnchangedSecretPrincipalLists, lr as wrapMaskedAwsError, m as withoutInjectedRemovals, mt as resourceTypeShown, nn as CdkdError, nr as isTransientServerError, or as isThrottlingError, ot as ElapsedBudgetRegistry, pn as MalformedProducerRecordRefusalError, qn as isRecreateRetryableError, qt as producerRecordKey, rr as retryClassificationText, sn as DynamicReferenceRegionAmbiguousError, sr as markNonRetryable, st as monotonicNowMs, tn as AssetError, tr as isRetryableTransientError, ut as compositeIdSeparatorRefusal, vn as ResourceUpdateNotSupportedError, vt as createMaskedRetryLogger, w as withoutServerErrorRetries, wt as carryCreatedBeforeFailure, xn as StateError, xt as maskerOrIdentity, yt as isSecretDerivedValue, z as deleteWithProtectionCompensation, zn as shellQuote, zt as formatLockOwner } from "./iam-policy-targets-CwKiK9nS.js";
4
4
  import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as ambientRegion, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-D0q0z4dG.js";
5
- import { t as getCdkdVersion } from "./version-D96I6uiO.js";
5
+ import { t as getCdkdVersion } from "./version-CItAaDXu.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";
@@ -7439,6 +7439,23 @@ function positionByCrossStackSource(bag, source, secrets) {
7439
7439
  return certifiedExpressionForLeaf(secrets, association, bag);
7440
7440
  }
7441
7441
 
7442
+ //#endregion
7443
+ //#region src/deployment/secret-redaction/physical-name-copies.ts
7444
+ const physicalNameCopiesOf = /* @__PURE__ */ new WeakMap();
7445
+ function recordPhysicalNameCopy(secrets, physicalId) {
7446
+ if (physicalId === "") return;
7447
+ sideSetOf(physicalNameCopiesOf, secrets).add(physicalId);
7448
+ }
7449
+ function physicalNameSpans(names, value) {
7450
+ const spans = [];
7451
+ if (names === void 0) return spans;
7452
+ for (const name of names) for (let at = value.indexOf(name); at !== -1; at = value.indexOf(name, at + 1)) spans.push({
7453
+ start: at,
7454
+ end: at + name.length
7455
+ });
7456
+ return spans;
7457
+ }
7458
+
7442
7459
  //#endregion
7443
7460
  //#region src/deployment/secret-redaction/fresh-noecho.ts
7444
7461
  function embedsFreshNoEchoValue(text, secrets, freshClass) {
@@ -7507,9 +7524,14 @@ function isStrictlyInsideASpan(spans, start, end) {
7507
7524
  }
7508
7525
  function embedsNeedleOutsideReferences(leaf, needles, secrets) {
7509
7526
  let spans;
7527
+ let names;
7510
7528
  for (const needle of needles) for (let at = leaf.indexOf(needle); at >= 0; at = leaf.indexOf(needle, at + 1)) {
7511
7529
  spans ??= isDynamicReferenceString(leaf) ? resolvableReferenceSpans(leaf, new Set(secrets.values())) : [];
7512
- if (!isStrictlyInsideASpan(spans, at, at + needle.length)) return true;
7530
+ if (isStrictlyInsideASpan(spans, at, at + needle.length)) continue;
7531
+ names ??= physicalNameSpans(physicalNameCopiesOf.get(secrets), leaf);
7532
+ const end = at + needle.length;
7533
+ if (names.some((n) => n.start <= at && end <= n.end)) continue;
7534
+ return true;
7513
7535
  }
7514
7536
  return false;
7515
7537
  }
@@ -8407,23 +8429,6 @@ function deriveReadbackNeedles(bag, source, secrets, rules) {
8407
8429
  };
8408
8430
  }
8409
8431
 
8410
- //#endregion
8411
- //#region src/deployment/secret-redaction/physical-name-copies.ts
8412
- const physicalNameCopiesOf = /* @__PURE__ */ new WeakMap();
8413
- function recordPhysicalNameCopy(secrets, physicalId) {
8414
- if (physicalId === "") return;
8415
- sideSetOf(physicalNameCopiesOf, secrets).add(physicalId);
8416
- }
8417
- function physicalNameSpans(names, value) {
8418
- const spans = [];
8419
- if (names === void 0) return spans;
8420
- for (const name of names) for (let at = value.indexOf(name); at !== -1; at = value.indexOf(name, at + 1)) spans.push({
8421
- start: at,
8422
- end: at + name.length
8423
- });
8424
- return spans;
8425
- }
8426
-
8427
8432
  //#endregion
8428
8433
  //#region src/deployment/secret-redaction/redact-state.ts
8429
8434
  function redactSecretsForState(bag, secrets, source, rules = TEMPLATE_DERIVED_RULES) {
@@ -9738,7 +9743,7 @@ function noEchoParametersReadBy(node, sources) {
9738
9743
  }
9739
9744
  function noEchoComparison(options) {
9740
9745
  const { sources, values, minNeedleLength, publicTokens } = options;
9741
- return ({ templateProperties, desired, current, record }) => {
9746
+ return ({ templateProperties, desired, current }) => {
9742
9747
  const coordinates = noEchoCoordinatesOf(templateProperties, desired, sources);
9743
9748
  const needles = [];
9744
9749
  for (const name of noEchoParametersReadBy(templateProperties, sources)) {
@@ -9774,10 +9779,6 @@ function noEchoComparison(options) {
9774
9779
  };
9775
9780
  masked = walk(masked);
9776
9781
  }
9777
- if (noEchoLeavesOf(record) !== void 0) return {
9778
- desired: masked,
9779
- current
9780
- };
9781
9782
  const witnessed = witnessNormalize(current, desired, masked);
9782
9783
  const shown = maskAtCoordinatesWith(witnessed.current, witnessed.differing, PREVIOUS_NOECHO_VALUE);
9783
9784
  return {
@@ -19154,6 +19155,80 @@ function quotedRender(rendered, quote, described = "(not shown: it is not a plai
19154
19155
  return QUOTABLE_RENDER.test(rendered) ? `${quote}${rendered}${quote}` : described;
19155
19156
  }
19156
19157
 
19158
+ //#endregion
19159
+ //#region src/deployment/secret-region-classification.ts
19160
+ const REPLAY_SECRET_SERVICES = /* @__PURE__ */ new Set([
19161
+ "secretsmanager",
19162
+ "ssm",
19163
+ "ssm-secure"
19164
+ ]);
19165
+ function secretsManagerSecretId(inner) {
19166
+ const afterService = inner.substring(15);
19167
+ let stringIdx = afterService.indexOf(":SecretString:");
19168
+ let binaryIdx = afterService.indexOf(":SecretBinary:");
19169
+ if (stringIdx < 0 && afterService.endsWith(":SecretString")) stringIdx = afterService.length - 13;
19170
+ if (binaryIdx < 0 && afterService.endsWith(":SecretBinary")) binaryIdx = afterService.length - 13;
19171
+ const delimiterIdx = stringIdx >= 0 && binaryIdx >= 0 ? Math.min(stringIdx, binaryIdx) : stringIdx >= 0 ? stringIdx : binaryIdx;
19172
+ return delimiterIdx >= 0 ? afterService.substring(0, delimiterIdx) : afterService;
19173
+ }
19174
+ function ssmParameterName(inner) {
19175
+ const serviceEnd = inner.indexOf(":");
19176
+ return serviceEnd < 0 ? "" : inner.substring(serviceEnd + 1);
19177
+ }
19178
+ function arnRegion(secretId) {
19179
+ if (!secretId.startsWith("arn:")) return void 0;
19180
+ const region = secretId.split(":")[3];
19181
+ return region ? region : void 0;
19182
+ }
19183
+ function producerRegionsFromState(state) {
19184
+ const seen = /* @__PURE__ */ new Set();
19185
+ const regions = [];
19186
+ for (const entry of [...state.imports ?? [], ...state.outputReads ?? []]) {
19187
+ const canonical = canonicalizeRegion(entry.sourceRegion);
19188
+ if (!canonical || seen.has(canonical)) continue;
19189
+ seen.add(canonical);
19190
+ regions.push(entry.sourceRegion);
19191
+ }
19192
+ return regions;
19193
+ }
19194
+ function secretReferenceName(expression) {
19195
+ const inner = expression.startsWith("{{resolve:") ? expression.slice(10, -2) : void 0;
19196
+ if (inner === void 0) return void 0;
19197
+ const service = inner.split(":")[0];
19198
+ if (service === void 0 || !REPLAY_SECRET_SERVICES.has(service)) return void 0;
19199
+ const secretName = service === "secretsmanager" ? secretsManagerSecretId(inner) : ssmParameterName(inner);
19200
+ return secretName ? secretName : void 0;
19201
+ }
19202
+ function regionLessSecretName(expression) {
19203
+ const secretName = secretReferenceName(expression);
19204
+ return secretName !== void 0 && arnRegion(secretName) === void 0 ? secretName : void 0;
19205
+ }
19206
+ function classifyReplaySecretRegion(expression, consumerRegion, importedProducerRegions) {
19207
+ const secretName = secretReferenceName(expression);
19208
+ if (!secretName) return { kind: "local" };
19209
+ const named = arnRegion(secretName);
19210
+ if (named !== void 0) return canonicalizeRegion(named) === canonicalizeRegion(consumerRegion) ? { kind: "local" } : {
19211
+ kind: "named-region",
19212
+ secretName,
19213
+ region: named
19214
+ };
19215
+ const seen = /* @__PURE__ */ new Set();
19216
+ const foreignProducerRegions = [];
19217
+ for (const candidate of importedProducerRegions ?? []) {
19218
+ const canonical = canonicalizeRegion(candidate);
19219
+ if (!canonical || canonical === canonicalizeRegion(consumerRegion)) continue;
19220
+ if (seen.has(canonical)) continue;
19221
+ seen.add(canonical);
19222
+ foreignProducerRegions.push(candidate);
19223
+ }
19224
+ if (foreignProducerRegions.length === 0) return { kind: "local" };
19225
+ return {
19226
+ kind: "ambiguous",
19227
+ secretName,
19228
+ foreignProducerRegions
19229
+ };
19230
+ }
19231
+
19157
19232
  //#endregion
19158
19233
  //#region src/utils/s3-endpoints.ts
19159
19234
  const S3_WEBSITE_ENDPOINT_LEGACY_DASH_REGIONS = /* @__PURE__ */ new Set([
@@ -19802,6 +19877,7 @@ function noteAttributeSecrecy(logicalId, attributeName, value, context) {
19802
19877
  const served = override !== void 0 && Object.hasOwn(override, attributeName);
19803
19878
  if (served) value = override[attributeName];
19804
19879
  recordSecretNamedRead(logicalId, value, context);
19880
+ recordProducerSecretPairs(logicalId, value, context);
19805
19881
  const declared = context.noEchoAttributeResources?.get(logicalId);
19806
19882
  if ((served || declared === true || declared !== void 0 && declared.has(attributeName)) && context.recordedSecretValues) recordFreshNoEchoValuesIn(value, context.recordedSecretValues, void 0, this.publicNoEchoTokens(context, logicalId));
19807
19883
  if (context.redactedAttributeReads !== void 0 && carriesSecretMask(value)) {
@@ -19818,6 +19894,24 @@ function noteAttributeSecrecy(logicalId, attributeName, value, context) {
19818
19894
  }
19819
19895
  return value;
19820
19896
  }
19897
+ function recordProducerSecretPairs(logicalId, value, context) {
19898
+ const bag = context.recordedSecretValues;
19899
+ if (bag === void 0 || context.producerSecrets === void 0) return;
19900
+ const producer = context.producerSecrets(logicalId);
19901
+ if (producer === void 0 || producer === bag || producer.size === 0) return;
19902
+ const preRun = context.producerPreRunPhysicalId?.(logicalId);
19903
+ const record = Object.hasOwn(context.resources, logicalId) ? context.resources[logicalId] : void 0;
19904
+ if (typeof preRun !== "string" || record?.physicalId !== preRun) return;
19905
+ const physicalId = preRun.toLowerCase();
19906
+ const leaves = [...wholeStringLeavesOf(value)];
19907
+ if (leaves.length === 0) return;
19908
+ for (const [plaintext, expression] of producer) {
19909
+ if (plaintext.length < 4 || bag.has(plaintext)) continue;
19910
+ if (typeof expression !== "string" || !expression.startsWith("{{resolve:")) continue;
19911
+ if (!physicalId.includes(plaintext.toLowerCase())) continue;
19912
+ if (leaves.some((leaf) => leaf.includes(plaintext))) bag.set(plaintext, expression);
19913
+ }
19914
+ }
19821
19915
  function recordSecretNamedRead(logicalId, value, context) {
19822
19916
  const bag = context.secretNameSink ?? context.printingSecrets ?? context.recordedSecretValues;
19823
19917
  if (bag === void 0 || context.secretNameNeedles === void 0) return;
@@ -19832,8 +19926,8 @@ function recordSecretNamedRead(logicalId, value, context) {
19832
19926
  async function reresolveRecordedReferences(value, logicalId, context, origin, sourceKey) {
19833
19927
  if (!carriesDynamicReference(value) || carriesSecretMask(value)) return value;
19834
19928
  if (context.recordedSecretValues === void 0) return value;
19835
- if (!referencesProvenLocal(value, logicalId, context)) {
19836
- this.logger.debug(safeMsg`Not re-resolving the reference(s) in ${this.displayMasked(origin, context)}: the template of ${this.displayMasked(logicalId, context)} does not spell them, so the region that resolved them is unknown`);
19929
+ if (!referencesProvenLocal(value, logicalId, context) && !referencesRegionProven(value, context, this.resolverRegion)) {
19930
+ this.logger.debug(safeMsg`Not re-resolving the reference(s) in ${this.displayMasked(origin, context)}: the template of ${this.displayMasked(logicalId, context)} does not spell them, and this stack may read a stack in another region, so the region that resolved them is unknown`);
19837
19931
  return value;
19838
19932
  }
19839
19933
  if (!await this.referencesMatchPhysicalId(value, logicalId, context)) {
@@ -19853,6 +19947,11 @@ async function referencesMatchPhysicalId(value, logicalId, context) {
19853
19947
  }
19854
19948
  return true;
19855
19949
  }
19950
+ function referencesRegionProven(value, context, region) {
19951
+ const evidence = context.secretRegionEvidence?.();
19952
+ if (evidence?.complete !== true) return false;
19953
+ return [...wholeStringLeavesOf(value)].every((leaf) => dynamicReferenceTokens(leaf).every((token) => classifyReplaySecretRegion(token, region, evidence.regions).kind !== "ambiguous"));
19954
+ }
19856
19955
  function readsAnotherStack(node) {
19857
19956
  if (Object.hasOwn(node, "Fn::ImportValue") || Object.hasOwn(node, "Fn::GetStackOutput")) return true;
19858
19957
  if (!Object.hasOwn(node, "Fn::GetAtt")) return false;
@@ -20087,6 +20186,13 @@ async function reresolveCrossStackValue(value, producerRegion, context, origin,
20087
20186
  });
20088
20187
  }
20089
20188
  }
20189
+ if (context.recordedSecretValues !== void 0 && producerOutput !== void 0 && producerOutput.crossAccount !== true && context.stateBackend !== void 0 && context.skipDynamicReferences !== true) {
20190
+ const plain = [...wholeStringLeavesOf(value)].filter((leaf) => !leaf.includes("{{resolve:") && !carriesSecretMask(leaf));
20191
+ if (plain.length > 0) {
20192
+ const ids = await producerPhysicalIds(context.recordedImports ?? context.recordedSecretValues, context.stateBackend, producerOutput.stackName, producerOutput.region || this.resolverRegion, () => this.logger.debug(safeMsg`Could not read the state of producer ${this.displayMasked(producerOutput.stackName, context)} for its physical ids; no cross-stack copy of one is kept (go-to-k/cdkd#4819)`));
20193
+ for (const leaf of plain) if (ids.has(leaf)) recordPhysicalNameCopy(context.recordedSecretValues, leaf);
20194
+ }
20195
+ }
20090
20196
  if (!carriesDynamicReference(value)) return value;
20091
20197
  const resolver = this.resolverForProducerRegion(producerRegion, context, producerRegionLogText);
20092
20198
  const pinnedContext = producerRegion ? withoutProducerRegions(context) : context;
@@ -20205,6 +20311,33 @@ function recordImport(context, exportName, producerStack, producerRegion) {
20205
20311
  sourceRegion: producerRegion
20206
20312
  });
20207
20313
  }
20314
+ const producerPhysicalIdReads = /* @__PURE__ */ new WeakMap();
20315
+ function producerPhysicalIds(scope, stateBackend, stackName, region, onFailure) {
20316
+ let reads = producerPhysicalIdReads.get(scope);
20317
+ if (reads === void 0) {
20318
+ reads = /* @__PURE__ */ new Map();
20319
+ producerPhysicalIdReads.set(scope, reads);
20320
+ }
20321
+ const key = JSON.stringify([stackName, region]);
20322
+ let read = reads.get(key);
20323
+ if (read === void 0) {
20324
+ read = (async () => {
20325
+ const ids = /* @__PURE__ */ new Set();
20326
+ try {
20327
+ const data = await stateBackend.getState(stackName, region);
20328
+ for (const record of Object.values(data?.state.resources ?? {})) {
20329
+ const id = record?.physicalId;
20330
+ if (typeof id === "string" && id !== "") ids.add(id);
20331
+ }
20332
+ } catch {
20333
+ onFailure();
20334
+ }
20335
+ return ids;
20336
+ })();
20337
+ reads.set(key, read);
20338
+ }
20339
+ return read;
20340
+ }
20208
20341
 
20209
20342
  //#endregion
20210
20343
  //#region src/deployment/intrinsic-resolver/cfn-fallback.ts
@@ -20859,80 +20992,6 @@ async function getCrossAccountStackState(roleArn, stackName, region, context) {
20859
20992
  }).getState(stackName, region);
20860
20993
  }
20861
20994
 
20862
- //#endregion
20863
- //#region src/deployment/secret-region-classification.ts
20864
- const REPLAY_SECRET_SERVICES = /* @__PURE__ */ new Set([
20865
- "secretsmanager",
20866
- "ssm",
20867
- "ssm-secure"
20868
- ]);
20869
- function secretsManagerSecretId(inner) {
20870
- const afterService = inner.substring(15);
20871
- let stringIdx = afterService.indexOf(":SecretString:");
20872
- let binaryIdx = afterService.indexOf(":SecretBinary:");
20873
- if (stringIdx < 0 && afterService.endsWith(":SecretString")) stringIdx = afterService.length - 13;
20874
- if (binaryIdx < 0 && afterService.endsWith(":SecretBinary")) binaryIdx = afterService.length - 13;
20875
- const delimiterIdx = stringIdx >= 0 && binaryIdx >= 0 ? Math.min(stringIdx, binaryIdx) : stringIdx >= 0 ? stringIdx : binaryIdx;
20876
- return delimiterIdx >= 0 ? afterService.substring(0, delimiterIdx) : afterService;
20877
- }
20878
- function ssmParameterName(inner) {
20879
- const serviceEnd = inner.indexOf(":");
20880
- return serviceEnd < 0 ? "" : inner.substring(serviceEnd + 1);
20881
- }
20882
- function arnRegion(secretId) {
20883
- if (!secretId.startsWith("arn:")) return void 0;
20884
- const region = secretId.split(":")[3];
20885
- return region ? region : void 0;
20886
- }
20887
- function producerRegionsFromState(state) {
20888
- const seen = /* @__PURE__ */ new Set();
20889
- const regions = [];
20890
- for (const entry of [...state.imports ?? [], ...state.outputReads ?? []]) {
20891
- const canonical = canonicalizeRegion(entry.sourceRegion);
20892
- if (!canonical || seen.has(canonical)) continue;
20893
- seen.add(canonical);
20894
- regions.push(entry.sourceRegion);
20895
- }
20896
- return regions;
20897
- }
20898
- function secretReferenceName(expression) {
20899
- const inner = expression.startsWith("{{resolve:") ? expression.slice(10, -2) : void 0;
20900
- if (inner === void 0) return void 0;
20901
- const service = inner.split(":")[0];
20902
- if (service === void 0 || !REPLAY_SECRET_SERVICES.has(service)) return void 0;
20903
- const secretName = service === "secretsmanager" ? secretsManagerSecretId(inner) : ssmParameterName(inner);
20904
- return secretName ? secretName : void 0;
20905
- }
20906
- function regionLessSecretName(expression) {
20907
- const secretName = secretReferenceName(expression);
20908
- return secretName !== void 0 && arnRegion(secretName) === void 0 ? secretName : void 0;
20909
- }
20910
- function classifyReplaySecretRegion(expression, consumerRegion, importedProducerRegions) {
20911
- const secretName = secretReferenceName(expression);
20912
- if (!secretName) return { kind: "local" };
20913
- const named = arnRegion(secretName);
20914
- if (named !== void 0) return canonicalizeRegion(named) === canonicalizeRegion(consumerRegion) ? { kind: "local" } : {
20915
- kind: "named-region",
20916
- secretName,
20917
- region: named
20918
- };
20919
- const seen = /* @__PURE__ */ new Set();
20920
- const foreignProducerRegions = [];
20921
- for (const candidate of importedProducerRegions ?? []) {
20922
- const canonical = canonicalizeRegion(candidate);
20923
- if (!canonical || canonical === canonicalizeRegion(consumerRegion)) continue;
20924
- if (seen.has(canonical)) continue;
20925
- seen.add(canonical);
20926
- foreignProducerRegions.push(candidate);
20927
- }
20928
- if (foreignProducerRegions.length === 0) return { kind: "local" };
20929
- return {
20930
- kind: "ambiguous",
20931
- secretName,
20932
- foreignProducerRegions
20933
- };
20934
- }
20935
-
20936
20995
  //#endregion
20937
20996
  //#region src/deployment/intrinsic-resolver/dynamic-refs.ts
20938
20997
  function secretVerdictScope(resolver) {
@@ -22188,6 +22247,7 @@ function recordInheritedParameterSecrets(parameterName, value, context) {
22188
22247
  const inherited = context.inheritedSecrets;
22189
22248
  const recorded = context.recordedSecretValues;
22190
22249
  if (inherited && recorded) carryLogOnlyValuesCarriedBy(inherited, recorded, value);
22250
+ if (recorded) carryPhysicalNameCopiesCarriedBy(context, recorded, value);
22191
22251
  if (inherited && recorded) recordInheritedNoEchoListElements(this, inherited, recorded, value, context);
22192
22252
  if (!inherited || inherited.size === 0 || !recorded) return;
22193
22253
  for (const [plaintext, expression] of inheritedSecretsCarriedBy(value, inherited)) {
@@ -22196,6 +22256,12 @@ function recordInheritedParameterSecrets(parameterName, value, context) {
22196
22256
  carryFreshNoEchoMark(inherited, recorded, plaintext);
22197
22257
  }
22198
22258
  }
22259
+ function carryPhysicalNameCopiesCarriedBy(context, recorded, value) {
22260
+ const names = context.inheritedPhysicalNameCopies ?? (context.inheritedSecrets && physicalNameCopiesOf.get(context.inheritedSecrets));
22261
+ if (names === void 0 || names.size === 0) return;
22262
+ const leaves = [...wholeStringLeavesOf(value)];
22263
+ for (const name of names) if (leaves.some((leaf) => leaf.includes(name))) recordPhysicalNameCopy(recorded, name);
22264
+ }
22199
22265
  function carriedExpressionFor(inherited, parameterName, value, plaintext, survivor) {
22200
22266
  const own = inheritedParameterExpression(inherited, parameterName, plaintext);
22201
22267
  if (typeof own === "string") return own;
@@ -22787,8 +22853,7 @@ var DiffCalculator = class DiffCalculator {
22787
22853
  resourceType: desiredResource.Type,
22788
22854
  templateProperties: rawDesiredProps,
22789
22855
  desired: desiredPropsForCompare,
22790
- current: currentPropsForCompare,
22791
- record: currentResource
22856
+ current: currentPropsForCompare
22792
22857
  });
22793
22858
  const desiredCompared = noEchoCompared?.desired ?? desiredPropsForCompare;
22794
22859
  const currentCompared = noEchoCompared?.current ?? currentPropsForCompare;
@@ -24194,6 +24259,10 @@ const WRITABLE_GETATT_ATTRIBUTES = {
24194
24259
  "AWS::MediaConvert::JobTemplate": ["Name"],
24195
24260
  "AWS::MediaConvert::Preset": ["Name"],
24196
24261
  "AWS::MediaConvert::Queue": ["Name"],
24262
+ "AWS::NetworkManager::ConnectAttachment": ["ProposedSegmentChange"],
24263
+ "AWS::NetworkManager::SiteToSiteVpnAttachment": ["ProposedSegmentChange"],
24264
+ "AWS::NetworkManager::TransitGatewayRouteTableAttachment": ["ProposedSegmentChange"],
24265
+ "AWS::NetworkManager::VpcAttachment": ["ProposedSegmentChange"],
24197
24266
  "AWS::OpsWorks::Instance": ["AvailabilityZone"],
24198
24267
  "AWS::OpsWorks::UserProfile": ["SshUsername"],
24199
24268
  "AWS::QuickSight::Analysis": ["Errors", "Sheets"],
@@ -24873,7 +24942,7 @@ var CloudControlProvider = class {
24873
24942
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
24874
24943
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
24875
24944
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
24876
- const { ASGProvider } = await import("./asg-provider-B1xRE8do.js");
24945
+ const { ASGProvider } = await import("./asg-provider-semUK44T.js");
24877
24946
  const delegateRegion = ambientRegion();
24878
24947
  let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
24879
24948
  if (asgProvider === void 0) {
@@ -24979,7 +25048,7 @@ var CloudControlProvider = class {
24979
25048
  const family = SDK_DELETE_FAMILIES.get(resourceType);
24980
25049
  const cached = this.sdkDeleteDelegates.get(family);
24981
25050
  if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
24982
- const provider = family === "rds" ? new (await (import("./rds-provider-J40R0ysf.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-CU_1O2FR.js"))).NeptuneProvider({ region: ccRegion });
25051
+ const provider = family === "rds" ? new (await (import("./rds-provider-X4mc-nGw.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-C4A86Y7P.js"))).NeptuneProvider({ region: ccRegion });
24983
25052
  this.sdkDeleteDelegates.set(family, {
24984
25053
  region: ccRegion,
24985
25054
  provider
@@ -36295,9 +36364,13 @@ function buildResolverContext(base, stackName) {
36295
36364
  recordedOutputReads: this.recordedOutputReads,
36296
36365
  attributeHealer: (logicalId, resource) => this.healStaleAttributes(logicalId, resource, stackName),
36297
36366
  ...this.options.inheritedSecrets && hasMaskableValues(this.options.inheritedSecrets) && { inheritedSecrets: this.options.inheritedSecrets },
36367
+ ...this.options.inheritedPhysicalNameCopies && { inheritedPhysicalNameCopies: this.options.inheritedPhysicalNameCopies },
36298
36368
  recordedSecretValues,
36299
36369
  noEchoAttributeResources: this.noEchoAttributeResources,
36300
36370
  secretNameNeedles: (logicalId) => this.noteSecretNamedRecord(logicalId, Object.hasOwn(base.resources, logicalId) ? base.resources[logicalId] : void 0),
36371
+ producerSecrets: (logicalId) => this.perResourceSecrets.get(logicalId),
36372
+ secretRegionEvidence: () => this.runProducerRegionEvidence?.(),
36373
+ producerPreRunPhysicalId: (logicalId) => Object.hasOwn(this.healBaseline, logicalId) ? this.healBaseline[logicalId]?.physicalId : void 0,
36301
36374
  ...base.redactedAttributeReads && { redactedAttributeReads: base.redactedAttributeReads }
36302
36375
  };
36303
36376
  }
@@ -39422,7 +39495,10 @@ function noEchoPositionSources(resources = {}, template = this.constructPathTemp
39422
39495
  function noEchoLeavesFor(logicalId, record, templateProps, sources) {
39423
39496
  if (templateProps !== void 0 && isWrittenFromDeployedTemplate(record.properties)) return canonicalCoordinates(noEchoCoordinatesOf(templateProps, record.properties, sources));
39424
39497
  const existing = noEchoLeavesOf(record);
39425
- if (existing !== void 0) return canonicalCoordinates(existing);
39498
+ if (existing !== void 0) {
39499
+ const confirmed = this.witnessConfirmedLeaves.get(logicalId) ?? [];
39500
+ return canonicalCoordinates([...existing, ...confirmed]);
39501
+ }
39426
39502
  const resolvedAsSame = this.perResourceResolvedType.get(logicalId) === record.resourceType;
39427
39503
  const source = (templateProps !== void 0 && resolvedAsSame ? templateProps : void 0) ?? templatePropertiesFor(this, logicalId, record.resourceType);
39428
39504
  if (source === void 0) return void 0;
@@ -39634,6 +39710,981 @@ function noEchoComparisonForTemplate(template, knownConditions, values, resource
39634
39710
  return (input) => compare(input);
39635
39711
  }
39636
39712
 
39713
+ //#endregion
39714
+ //#region src/analyzer/security-changes.ts
39715
+ const RESOURCE_SCRUTINY = {
39716
+ "AWS::Bedrock::KnowledgeBasePolicy": "ResourcePolicyResource",
39717
+ "AWS::Bedrock::ResourcePolicy": "ResourcePolicyResource",
39718
+ "AWS::CloudTrail::ResourcePolicy": "ResourcePolicyResource",
39719
+ "AWS::EC2::SecurityGroupEgress": "EgressRuleResource",
39720
+ "AWS::EC2::SecurityGroupIngress": "IngressRuleResource",
39721
+ "AWS::ECR::RegistryPolicy": "ResourcePolicyResource",
39722
+ "AWS::EventSchemas::RegistryPolicy": "ResourcePolicyResource",
39723
+ "AWS::EventsV2::ResourcePolicy": "ResourcePolicyResource",
39724
+ "AWS::IAM::GroupPolicy": "IdentityPolicyResource",
39725
+ "AWS::IAM::ManagedPolicy": "IdentityPolicyResource",
39726
+ "AWS::IAM::Policy": "IdentityPolicyResource",
39727
+ "AWS::IAM::RolePolicy": "IdentityPolicyResource",
39728
+ "AWS::IAM::UserPolicy": "IdentityPolicyResource",
39729
+ "AWS::IoT::Policy": "ResourcePolicyResource",
39730
+ "AWS::Kinesis::ResourcePolicy": "ResourcePolicyResource",
39731
+ "AWS::Lambda::Permission": "LambdaPermission",
39732
+ "AWS::Lambda::ResourcePolicy": "ResourcePolicyResource",
39733
+ "AWS::Lex::ResourcePolicy": "ResourcePolicyResource",
39734
+ "AWS::Logs::ResourcePolicy": "ResourcePolicyResource",
39735
+ "AWS::MSK::ClusterPolicy": "ResourcePolicyResource",
39736
+ "AWS::MediaPackageV2::ChannelPolicy": "ResourcePolicyResource",
39737
+ "AWS::MediaPackageV2::OriginEndpointPolicy": "ResourcePolicyResource",
39738
+ "AWS::MediaTailor::ChannelPolicy": "ResourcePolicyResource",
39739
+ "AWS::S3::BucketPolicy": "ResourcePolicyResource",
39740
+ "AWS::S3::MultiRegionAccessPointPolicy": "ResourcePolicyResource",
39741
+ "AWS::S3Express::BucketPolicy": "ResourcePolicyResource",
39742
+ "AWS::S3Files::FileSystemPolicy": "ResourcePolicyResource",
39743
+ "AWS::S3ObjectLambda::AccessPointPolicy": "ResourcePolicyResource",
39744
+ "AWS::S3Outposts::BucketPolicy": "ResourcePolicyResource",
39745
+ "AWS::S3Tables::TableBucketPolicy": "ResourcePolicyResource",
39746
+ "AWS::S3Tables::TablePolicy": "ResourcePolicyResource",
39747
+ "AWS::S3Vectors::VectorBucketPolicy": "ResourcePolicyResource",
39748
+ "AWS::SMSVOICE::ResourcePolicy": "ResourcePolicyResource",
39749
+ "AWS::SNS::TopicInlinePolicy": "ResourcePolicyResource",
39750
+ "AWS::SNS::TopicPolicy": "ResourcePolicyResource",
39751
+ "AWS::SQS::QueueInlinePolicy": "ResourcePolicyResource",
39752
+ "AWS::SQS::QueuePolicy": "ResourcePolicyResource",
39753
+ "AWS::SSM::ResourcePolicy": "ResourcePolicyResource",
39754
+ "AWS::SSO::Assignment": "SsoAssignmentResource",
39755
+ "AWS::SSO::InstanceAccessControlAttributeConfiguration": "SsoInstanceACAConfigResource",
39756
+ "AWS::SSO::PermissionSet": "SsoPermissionSet",
39757
+ "AWS::SecretsManager::ResourcePolicy": "ResourcePolicyResource",
39758
+ "AWS::VpcLattice::AuthPolicy": "ResourcePolicyResource",
39759
+ "AWS::VpcLattice::ResourcePolicy": "ResourcePolicyResource"
39760
+ };
39761
+ const PROPERTY_SCRUTINY = {
39762
+ "AWS::ApiGateway::DomainNameV2": { Policy: "InlineResourcePolicy" },
39763
+ "AWS::ApiGateway::RestApi": { Policy: "InlineResourcePolicy" },
39764
+ "AWS::Backup::BackupVault": { AccessPolicy: "InlineResourcePolicy" },
39765
+ "AWS::Backup::LogicallyAirGappedBackupVault": { AccessPolicy: "InlineResourcePolicy" },
39766
+ "AWS::CodeArtifact::Domain": { PermissionsPolicyDocument: "InlineResourcePolicy" },
39767
+ "AWS::CodeArtifact::Repository": { PermissionsPolicyDocument: "InlineResourcePolicy" },
39768
+ "AWS::EC2::SecurityGroup": {
39769
+ SecurityGroupEgress: "EgressRules",
39770
+ SecurityGroupIngress: "IngressRules"
39771
+ },
39772
+ "AWS::EC2::VPCEndpoint": { PolicyDocument: "InlineResourcePolicy" },
39773
+ "AWS::ECR::PublicRepository": { RepositoryPolicyText: "InlineResourcePolicy" },
39774
+ "AWS::ECR::Repository": { RepositoryPolicyText: "InlineResourcePolicy" },
39775
+ "AWS::EFS::FileSystem": { FileSystemPolicy: "InlineResourcePolicy" },
39776
+ "AWS::Events::EventBus": { Policy: "InlineResourcePolicy" },
39777
+ "AWS::IAM::Group": {
39778
+ ManagedPolicyArns: "ManagedPolicies",
39779
+ Policies: "InlineIdentityPolicies"
39780
+ },
39781
+ "AWS::IAM::Role": {
39782
+ AssumeRolePolicyDocument: "InlineResourcePolicy",
39783
+ ManagedPolicyArns: "ManagedPolicies",
39784
+ Policies: "InlineIdentityPolicies"
39785
+ },
39786
+ "AWS::IAM::User": {
39787
+ ManagedPolicyArns: "ManagedPolicies",
39788
+ Policies: "InlineIdentityPolicies"
39789
+ },
39790
+ "AWS::KMS::Key": { KeyPolicy: "InlineResourcePolicy" },
39791
+ "AWS::KMS::ReplicaKey": { KeyPolicy: "InlineResourcePolicy" },
39792
+ "AWS::Logs::LogGroup": {
39793
+ DataProtectionPolicy: "InlineResourcePolicy",
39794
+ ResourcePolicyDocument: "InlineResourcePolicy"
39795
+ },
39796
+ "AWS::MPA::ApprovalTeam": { Policies: "InlineIdentityPolicies" },
39797
+ "AWS::NetworkManager::CoreNetwork": { PolicyDocument: "InlineResourcePolicy" },
39798
+ "AWS::Oam::Sink": { Policy: "InlineResourcePolicy" },
39799
+ "AWS::Omics::SequenceStore": { S3AccessPolicy: "InlineResourcePolicy" },
39800
+ "AWS::RAM::Permission": { PolicyTemplate: "InlineResourcePolicy" },
39801
+ "AWS::Redshift::Cluster": { NamespaceResourcePolicy: "InlineResourcePolicy" },
39802
+ "AWS::RedshiftServerless::Namespace": { NamespaceResourcePolicy: "InlineResourcePolicy" },
39803
+ "AWS::RolesAnywhere::Profile": { ManagedPolicyArns: "ManagedPolicies" },
39804
+ "AWS::S3::AccessPoint": { Policy: "InlineResourcePolicy" },
39805
+ "AWS::S3Express::AccessPoint": { Policy: "InlineResourcePolicy" },
39806
+ "AWS::S3Outposts::AccessPoint": { Policy: "InlineResourcePolicy" },
39807
+ "AWS::SNS::Subscription": {
39808
+ RedrivePolicy: "InlineResourcePolicy",
39809
+ ReplayPolicy: "InlineResourcePolicy"
39810
+ },
39811
+ "AWS::SNS::Topic": {
39812
+ DataProtectionPolicy: "InlineResourcePolicy",
39813
+ ArchivePolicy: "InlineResourcePolicy"
39814
+ },
39815
+ "AWS::SQS::Queue": { RedriveAllowPolicy: "InlineResourcePolicy" },
39816
+ "AWS::SSO::PermissionSet": {
39817
+ InlinePolicy: "InlineResourcePolicy",
39818
+ ManagedPolicies: "ManagedPolicies"
39819
+ },
39820
+ "AWS::SageMaker::ModelPackageGroup": { ModelPackageGroupPolicy: "InlineResourcePolicy" },
39821
+ "AWS::Serverless::Function": { AssumeRolePolicyDocument: "InlineResourcePolicy" }
39822
+ };
39823
+ function resourceScrutiny(type) {
39824
+ return Object.hasOwn(RESOURCE_SCRUTINY, type) ? RESOURCE_SCRUTINY[type] : void 0;
39825
+ }
39826
+ function propertyScrutinies(type) {
39827
+ return Object.hasOwn(PROPERTY_SCRUTINY, type) ? PROPERTY_SCRUTINY[type] ?? {} : {};
39828
+ }
39829
+ function isScrutinizedProperty(type, path) {
39830
+ return resourceScrutiny(type) !== void 0 || Object.hasOwn(propertyScrutinies(type), path);
39831
+ }
39832
+ function strictEqual(a, b) {
39833
+ if (a === b) return true;
39834
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return a !== a && b !== b;
39835
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
39836
+ if (Array.isArray(a)) {
39837
+ const bArr = b;
39838
+ return a.length === bArr.length && a.every((v, i) => strictEqual(v, bArr[i]));
39839
+ }
39840
+ const aKeys = Object.keys(a);
39841
+ if (aKeys.length !== Object.keys(b).length) return false;
39842
+ return aKeys.every((k) => Object.hasOwn(b, k) && strictEqual(a[k], b[k]));
39843
+ }
39844
+ function cfnEqual(lvalue, rvalue) {
39845
+ if (lvalue === rvalue) return true;
39846
+ if ((typeof lvalue === "string" && typeof rvalue === "boolean" || typeof lvalue === "boolean" && typeof rvalue === "string") && lvalue.toString() === rvalue.toString()) return true;
39847
+ if ((typeof lvalue === "string" || typeof rvalue === "string") && Number(lvalue) === Number(rvalue)) return true;
39848
+ if (typeof lvalue !== typeof rvalue) return false;
39849
+ if (Array.isArray(lvalue) !== Array.isArray(rvalue)) return false;
39850
+ if (Array.isArray(lvalue)) {
39851
+ if (lvalue.length !== rvalue.length) return false;
39852
+ for (let i = 0; i < lvalue.length; i++) if (!cfnEqual(lvalue[i], rvalue[i])) return false;
39853
+ return true;
39854
+ }
39855
+ if (typeof lvalue === "object") {
39856
+ if (lvalue === null || rvalue === null) return false;
39857
+ const keys = Object.keys(lvalue);
39858
+ if (keys.length !== Object.keys(rvalue).length) return false;
39859
+ for (const key of keys) {
39860
+ if (!Object.hasOwn(rvalue, key)) return false;
39861
+ if (key === "DependsOn") {
39862
+ if (!dependsOnEqual(lvalue[key], rvalue[key])) return false;
39863
+ continue;
39864
+ }
39865
+ if (!cfnEqual(lvalue[key], rvalue[key])) return false;
39866
+ }
39867
+ return true;
39868
+ }
39869
+ return false;
39870
+ }
39871
+ function dependsOnEqual(lvalue, rvalue) {
39872
+ if (Array.isArray(lvalue) !== Array.isArray(rvalue)) {
39873
+ const array = Array.isArray(lvalue) ? lvalue : rvalue;
39874
+ const nonArray = Array.isArray(lvalue) ? rvalue : lvalue;
39875
+ return array.length === 1 && cfnEqual(array[0], nonArray);
39876
+ }
39877
+ if (Array.isArray(lvalue) && Array.isArray(rvalue)) {
39878
+ if (lvalue.length !== rvalue.length) return false;
39879
+ for (let i = 0; i < lvalue.length; i++) if (!cfnEqual(lvalue[i], rvalue[0]) && lvalue.length === 1) return false;
39880
+ return true;
39881
+ }
39882
+ return false;
39883
+ }
39884
+ function normalize(template) {
39885
+ if (typeof template !== "object" || template === null) return;
39886
+ for (const key of Object.keys(template)) {
39887
+ if (key === "Fn::GetAtt" && typeof template[key] === "string") {
39888
+ template[key] = template[key].split(".");
39889
+ continue;
39890
+ } else if (key === "DependsOn") {
39891
+ if (typeof template[key] === "string") template[key] = [template[key]];
39892
+ else if (Array.isArray(template[key])) template[key] = template[key].sort((x, y) => String(x) < String(y) ? -1 : String(x) > String(y) ? 1 : 0);
39893
+ continue;
39894
+ }
39895
+ if (Array.isArray(template[key])) for (const element of template[key]) normalize(element);
39896
+ else normalize(template[key]);
39897
+ }
39898
+ }
39899
+ function getIntrinsic(x) {
39900
+ if (x === void 0 || x === null || Array.isArray(x) || typeof x !== "object") return void 0;
39901
+ const keys = Object.keys(x);
39902
+ return keys.length === 1 && (keys[0] === "Ref" || keys[0].startsWith("Fn::")) ? {
39903
+ fn: keys[0],
39904
+ args: x[keys[0]]
39905
+ } : void 0;
39906
+ }
39907
+ function isNoValue(x) {
39908
+ const intrinsic = getIntrinsic(x);
39909
+ return intrinsic !== void 0 && intrinsic.fn === "Ref" && intrinsic.args === "AWS::NoValue";
39910
+ }
39911
+ function renderIntrinsics(x) {
39912
+ if (Array.isArray(x)) return x.filter((el) => !isNoValue(el)).map(renderIntrinsics);
39913
+ if (isNoValue(x)) return void 0;
39914
+ const intrinsic = getIntrinsic(x);
39915
+ if (intrinsic !== void 0) {
39916
+ if (intrinsic.fn === "Ref") return "${" + intrinsic.args + "}";
39917
+ if (intrinsic.fn === "Fn::GetAtt") return "${" + intrinsic.args[0] + "." + intrinsic.args[1] + "}";
39918
+ if (intrinsic.fn === "Fn::Join") {
39919
+ const [separator, args] = intrinsic.args;
39920
+ if (Array.isArray(args)) return args.filter((el) => !isNoValue(el)).map(renderIntrinsics).join(separator);
39921
+ return JSON.stringify({ "Fn::Join": renderIntrinsics([separator, args]) });
39922
+ }
39923
+ return JSON.stringify({ [intrinsic.fn]: renderIntrinsics(intrinsic.args) });
39924
+ }
39925
+ if (typeof x === "object" && x !== null) {
39926
+ const ret = {};
39927
+ for (const [key, value] of Object.entries(x)) if (!isNoValue(value)) ret[key] = renderIntrinsics(value);
39928
+ return ret;
39929
+ }
39930
+ return x;
39931
+ }
39932
+ var Targets = class {
39933
+ values;
39934
+ not;
39935
+ constructor(statement, positiveKey, negativeKey) {
39936
+ if (negativeKey in statement) {
39937
+ this.values = forceListOfStrings(statement[negativeKey]);
39938
+ this.not = true;
39939
+ } else {
39940
+ this.values = forceListOfStrings(statement[positiveKey]);
39941
+ this.not = false;
39942
+ }
39943
+ this.values.sort();
39944
+ }
39945
+ get empty() {
39946
+ return this.values.length === 0;
39947
+ }
39948
+ equal(other) {
39949
+ return this.not === other.not && strictEqual(this.values.sort(), other.values.sort());
39950
+ }
39951
+ replaceEmpty(replacement) {
39952
+ if (this.empty) this.values.push(replacement);
39953
+ }
39954
+ replaceStar(replacement) {
39955
+ for (let i = 0; i < this.values.length; i++) if (this.values[i] === "*") this.values[i] = replacement;
39956
+ this.values.sort();
39957
+ }
39958
+ render() {
39959
+ return this.not ? this.values.map((s) => `NOT ${s}`).join("\n") : this.values.join("\n");
39960
+ }
39961
+ };
39962
+ function forceListOfStrings(x) {
39963
+ if (typeof x === "string") return [x];
39964
+ if (x === void 0 || x === null) return [];
39965
+ if (Array.isArray(x)) return x.map((e) => forceListOfStrings(e).join(","));
39966
+ if (typeof x === "object") {
39967
+ const ret = [];
39968
+ for (const [key, value] of Object.entries(x)) ret.push(...forceListOfStrings(value).map((s) => `${key}:${s}`));
39969
+ return ret;
39970
+ }
39971
+ return [`${x}`];
39972
+ }
39973
+ var Statement = class {
39974
+ sid;
39975
+ effect;
39976
+ resources;
39977
+ actions;
39978
+ principals;
39979
+ condition;
39980
+ serializedIntrinsic;
39981
+ constructor(statement) {
39982
+ if (typeof statement === "string") {
39983
+ this.sid = void 0;
39984
+ this.effect = "Unknown";
39985
+ this.resources = new Targets({}, "", "");
39986
+ this.actions = new Targets({}, "", "");
39987
+ this.principals = new Targets({}, "", "");
39988
+ this.condition = void 0;
39989
+ this.serializedIntrinsic = statement;
39990
+ } else {
39991
+ if (typeof statement !== "object" || statement === null) throw new Error("An IAM policy statement is neither an object nor a string");
39992
+ this.sid = typeof statement.Sid === "string" ? statement.Sid : void 0;
39993
+ this.effect = statement.Effect === "Allow" || statement.Effect === "Deny" ? statement.Effect : "Unknown";
39994
+ this.resources = new Targets(statement, "Resource", "NotResource");
39995
+ this.actions = new Targets(statement, "Action", "NotAction");
39996
+ this.principals = new Targets(statement, "Principal", "NotPrincipal");
39997
+ this.condition = statement.Condition;
39998
+ this.serializedIntrinsic = void 0;
39999
+ }
40000
+ }
40001
+ equal(other) {
40002
+ return this.sid === other.sid && this.effect === other.effect && this.serializedIntrinsic === other.serializedIntrinsic && this.resources.equal(other.resources) && this.actions.equal(other.actions) && this.principals.equal(other.principals) && strictEqual(this.condition, other.condition);
40003
+ }
40004
+ get isNegativeStatement() {
40005
+ const notTarget = this.actions.not || this.principals.not || this.resources.not;
40006
+ return this.effect === "Allow" ? notTarget : !notTarget;
40007
+ }
40008
+ render() {
40009
+ return this.serializedIntrinsic ? [
40010
+ this.serializedIntrinsic,
40011
+ "",
40012
+ "",
40013
+ this.principals.render(),
40014
+ ""
40015
+ ] : [
40016
+ this.resources.render(),
40017
+ this.effect,
40018
+ this.actions.render(),
40019
+ this.principals.render(),
40020
+ renderCondition(this.condition)
40021
+ ];
40022
+ }
40023
+ };
40024
+ function parseStatements(x) {
40025
+ if (x === void 0) x = [];
40026
+ if (!Array.isArray(x)) x = [x];
40027
+ return x.map((s) => new Statement(s));
40028
+ }
40029
+ function parseLambdaPermission(x) {
40030
+ const statement = {
40031
+ Effect: "Allow",
40032
+ Action: x.Action,
40033
+ Resource: x.FunctionName
40034
+ };
40035
+ if (x.Principal !== void 0) {
40036
+ if (x.Principal === "*") statement.Principal = "*";
40037
+ else if (/^\d{12}$/.test(x.Principal)) statement.Principal = { AWS: `arn:aws:iam::${x.Principal}:root` };
40038
+ else statement.Principal = { Service: x.Principal };
40039
+ }
40040
+ if (x.SourceArn !== void 0) {
40041
+ statement.Condition ??= {};
40042
+ statement.Condition.ArnLike = { "AWS:SourceArn": x.SourceArn };
40043
+ }
40044
+ if (x.SourceAccount !== void 0) {
40045
+ statement.Condition ??= {};
40046
+ statement.Condition.StringEquals = { "AWS:SourceAccount": x.SourceAccount };
40047
+ }
40048
+ if (x.EventSourceToken !== void 0) {
40049
+ statement.Condition ??= {};
40050
+ statement.Condition.StringEquals = { "lambda:EventSourceToken": x.EventSourceToken };
40051
+ }
40052
+ return new Statement(statement);
40053
+ }
40054
+ function renderCondition(condition) {
40055
+ if (!condition || Object.keys(condition).length === 0) return "";
40056
+ const lines = JSON.stringify(condition, void 0, 2).split("\n");
40057
+ return lines.slice(1, lines.length - 1).map((s) => s.slice(2)).join("\n");
40058
+ }
40059
+ function defaultPrincipal(principal, statements) {
40060
+ statements.forEach((s) => s.principals.replaceEmpty(principal));
40061
+ statements.forEach((s) => s.principals.replaceStar(principal));
40062
+ return statements;
40063
+ }
40064
+ function defaultResource(resource, statements) {
40065
+ statements.forEach((s) => s.resources.replaceEmpty(resource));
40066
+ statements.forEach((s) => s.resources.replaceStar(resource));
40067
+ return statements;
40068
+ }
40069
+ var ManagedPolicyAttachment = class {
40070
+ identityArn;
40071
+ managedPolicyArn;
40072
+ constructor(identityArn, managedPolicyArn) {
40073
+ this.identityArn = identityArn;
40074
+ this.managedPolicyArn = managedPolicyArn;
40075
+ }
40076
+ equal(other) {
40077
+ return this.identityArn === other.identityArn && this.managedPolicyArn === other.managedPolicyArn;
40078
+ }
40079
+ };
40080
+ var SsoElement = class {
40081
+ fields;
40082
+ constructor(fields) {
40083
+ this.fields = fields;
40084
+ }
40085
+ equal(other) {
40086
+ return strictEqual(this.fields, other.fields);
40087
+ }
40088
+ };
40089
+ var SecurityGroupRule = class {
40090
+ ipProtocol;
40091
+ fromPort;
40092
+ toPort;
40093
+ groupId;
40094
+ peer;
40095
+ constructor(rule, groupRef) {
40096
+ this.ipProtocol = rule.IpProtocol?.toString() || "*unknown*";
40097
+ this.fromPort = rule.FromPort;
40098
+ this.toPort = rule.ToPort;
40099
+ this.groupId = rule.GroupId || groupRef || "*unknown*";
40100
+ this.peer = findFirst(rule, ["CidrIp", "CidrIpv6"], (ip) => ({
40101
+ kind: "cidr-ip",
40102
+ ip
40103
+ })) || findFirst(rule, ["DestinationSecurityGroupId", "SourceSecurityGroupId"], (id) => ({
40104
+ kind: "security-group",
40105
+ securityGroupId: id
40106
+ })) || findFirst(rule, ["DestinationPrefixListId", "SourcePrefixListId"], (id) => ({
40107
+ kind: "prefix-list",
40108
+ prefixListId: id
40109
+ }));
40110
+ }
40111
+ equal(other) {
40112
+ return this.ipProtocol === other.ipProtocol && this.fromPort === other.fromPort && this.toPort === other.toPort && peerEqual(this.peer, other.peer);
40113
+ }
40114
+ describeProtocol() {
40115
+ if (this.ipProtocol === "-1") return "Everything";
40116
+ const ipProtocol = this.ipProtocol.toUpperCase();
40117
+ if (this.fromPort === -1) return `All ${ipProtocol}`;
40118
+ if (this.fromPort === this.toPort) return `${ipProtocol} ${this.fromPort}`;
40119
+ return `${ipProtocol} ${this.fromPort}-${this.toPort}`;
40120
+ }
40121
+ describePeer() {
40122
+ switch (this.peer?.kind) {
40123
+ case "cidr-ip":
40124
+ if (this.peer.ip === "0.0.0.0/0") return "Everyone (IPv4)";
40125
+ if (this.peer.ip === "::/0") return "Everyone (IPv6)";
40126
+ return `${this.peer.ip}`;
40127
+ case "prefix-list": return `${this.peer.prefixListId}`;
40128
+ case "security-group": return `${this.peer.securityGroupId}`;
40129
+ default: return "?";
40130
+ }
40131
+ }
40132
+ };
40133
+ function peerEqual(a, b) {
40134
+ if (a === void 0 || b === void 0) return a === b;
40135
+ if (a.kind === "cidr-ip" && b.kind === "cidr-ip") return a.ip === b.ip;
40136
+ if (a.kind === "security-group" && b.kind === "security-group") return a.securityGroupId === b.securityGroupId;
40137
+ if (a.kind === "prefix-list" && b.kind === "prefix-list") return a.prefixListId === b.prefixListId;
40138
+ return false;
40139
+ }
40140
+ function findFirst(obj, keys, fn) {
40141
+ for (const key of keys) try {
40142
+ if (key in obj) return fn(obj[key]);
40143
+ } catch {}
40144
+ }
40145
+ var DiffableCollection = class {
40146
+ additions = [];
40147
+ removals = [];
40148
+ oldElements = [];
40149
+ newElements = [];
40150
+ addOld(...elements) {
40151
+ this.oldElements.push(...elements);
40152
+ }
40153
+ addNew(...elements) {
40154
+ this.newElements.push(...elements);
40155
+ }
40156
+ calculateDiff() {
40157
+ const contains = (x, xs) => xs.some((y) => y.equal(x));
40158
+ this.additions.push(...this.newElements.filter((x) => !contains(x, this.oldElements)));
40159
+ this.removals.push(...this.oldElements.filter((x) => !contains(x, this.newElements)));
40160
+ }
40161
+ get hasChanges() {
40162
+ return this.additions.length + this.removals.length > 0;
40163
+ }
40164
+ get hasAdditions() {
40165
+ return this.additions.length > 0;
40166
+ }
40167
+ };
40168
+ function resourceDiffers(oldValue, newValue) {
40169
+ if (oldValue === void 0 || newValue === void 0) return true;
40170
+ if (oldValue.Type !== newValue.Type) return true;
40171
+ const keyDiffers = (a, b, skip) => [.../* @__PURE__ */ new Set([...Object.keys(a ?? {}), ...Object.keys(b ?? {})])].some((key) => {
40172
+ if (key === skip) return false;
40173
+ const x = a?.[key];
40174
+ const y = b?.[key];
40175
+ return !(x === void 0 && y === void 0) && !cfnEqual(x, y);
40176
+ });
40177
+ return keyDiffers(oldValue.Properties, newValue.Properties) || keyDiffers(oldValue, newValue, "Properties");
40178
+ }
40179
+ var SecurityChanges = class {
40180
+ statements = new DiffableCollection();
40181
+ managedPolicies = new DiffableCollection();
40182
+ ssoPermissionSets = new DiffableCollection();
40183
+ ssoAssignments = new DiffableCollection();
40184
+ ssoInstanceACAConfigs = new DiffableCollection();
40185
+ ingress = new DiffableCollection();
40186
+ egress = new DiffableCollection();
40187
+ constructor(oldTemplate, newTemplate) {
40188
+ normalize(oldTemplate);
40189
+ normalize(newTemplate);
40190
+ const oldResources = oldTemplate.Resources ?? {};
40191
+ const newResources = newTemplate.Resources ?? {};
40192
+ const changed = [];
40193
+ for (const id of /* @__PURE__ */ new Set([...Object.keys(oldResources), ...Object.keys(newResources)])) {
40194
+ const oldValue = Object.hasOwn(oldResources, id) ? oldResources[id] : void 0;
40195
+ const newValue = Object.hasOwn(newResources, id) ? newResources[id] : void 0;
40196
+ if (oldValue === void 0 && newValue === void 0) continue;
40197
+ if (resourceDiffers(oldValue, newValue)) changed.push([id, {
40198
+ oldValue,
40199
+ newValue
40200
+ }]);
40201
+ }
40202
+ for (const change of this.propertyChanges(changed)) this.readPropertyChange(change);
40203
+ for (const change of this.resourceChanges(changed)) this.readResourceChange(change);
40204
+ for (const collection of this.collections()) collection.calculateDiff();
40205
+ }
40206
+ collections() {
40207
+ return [
40208
+ this.statements,
40209
+ this.managedPolicies,
40210
+ this.ssoPermissionSets,
40211
+ this.ssoAssignments,
40212
+ this.ssoInstanceACAConfigs,
40213
+ this.ingress,
40214
+ this.egress
40215
+ ];
40216
+ }
40217
+ propertyChanges(changed) {
40218
+ const ret = [];
40219
+ for (const [logicalId, { oldValue, newValue }] of changed) {
40220
+ const oldType = oldValue?.Type;
40221
+ const newType = newValue?.Type;
40222
+ if (oldType !== void 0 && newType !== void 0 && oldType !== newType) continue;
40223
+ const resourceType = oldType ?? newType;
40224
+ if (!resourceType) continue;
40225
+ for (const [propertyName, scrutiny] of Object.entries(propertyScrutinies(resourceType))) ret.push({
40226
+ logicalId,
40227
+ resourceType,
40228
+ scrutiny,
40229
+ oldValue: oldValue?.Properties?.[propertyName],
40230
+ newValue: newValue?.Properties?.[propertyName]
40231
+ });
40232
+ }
40233
+ return ret;
40234
+ }
40235
+ resourceChanges(changed) {
40236
+ const ret = [];
40237
+ for (const [logicalId, { oldValue, newValue }] of changed) {
40238
+ const oldType = oldValue?.Type;
40239
+ const newType = newValue?.Type;
40240
+ const common = {
40241
+ logicalId,
40242
+ oldProperties: oldValue?.Properties,
40243
+ newProperties: newValue?.Properties
40244
+ };
40245
+ if (oldType !== void 0 && newType !== void 0 && oldType !== newType) {
40246
+ const oldScrutiny = resourceScrutiny(oldType);
40247
+ if (oldScrutiny) ret.push({
40248
+ ...common,
40249
+ newProperties: void 0,
40250
+ scrutiny: oldScrutiny
40251
+ });
40252
+ const newScrutiny = resourceScrutiny(newType);
40253
+ if (newScrutiny) ret.push({
40254
+ ...common,
40255
+ oldProperties: void 0,
40256
+ scrutiny: newScrutiny
40257
+ });
40258
+ continue;
40259
+ }
40260
+ const type = oldType ?? newType;
40261
+ const scrutiny = type ? resourceScrutiny(type) : void 0;
40262
+ if (scrutiny) ret.push({
40263
+ ...common,
40264
+ scrutiny
40265
+ });
40266
+ }
40267
+ return ret;
40268
+ }
40269
+ get permissionsBroadened() {
40270
+ return this.statements.additions.some((s) => !s.isNegativeStatement) || this.statements.removals.some((s) => s.isNegativeStatement) || this.managedPolicies.hasAdditions || this.ssoPermissionSets.hasAdditions || this.ssoAssignments.hasAdditions || this.ssoInstanceACAConfigs.hasAdditions || this.ingress.hasAdditions || this.egress.hasAdditions;
40271
+ }
40272
+ get iamHasChanges() {
40273
+ return this.statements.hasChanges || this.managedPolicies.hasChanges || this.ssoPermissionSets.hasChanges || this.ssoAssignments.hasChanges || this.ssoInstanceACAConfigs.hasChanges;
40274
+ }
40275
+ get securityGroupsHaveChanges() {
40276
+ return this.ingress.hasChanges || this.egress.hasChanges;
40277
+ }
40278
+ get permissionsAnyChanges() {
40279
+ return this.iamHasChanges || this.securityGroupsHaveChanges;
40280
+ }
40281
+ readPropertyChange(change) {
40282
+ switch (change.scrutiny) {
40283
+ case "InlineIdentityPolicies":
40284
+ this.statements.addOld(...readIdentityPolicies(change.oldValue, change.logicalId));
40285
+ this.statements.addNew(...readIdentityPolicies(change.newValue, change.logicalId));
40286
+ break;
40287
+ case "InlineResourcePolicy":
40288
+ if (change.resourceType === "AWS::SSO::PermissionSet") {
40289
+ this.statements.addOld(...readPermissionSetInlinePolicy(change.oldValue, change.logicalId));
40290
+ this.statements.addNew(...readPermissionSetInlinePolicy(change.newValue, change.logicalId));
40291
+ } else {
40292
+ this.statements.addOld(...readResourceStatements(change.oldValue, change.logicalId));
40293
+ this.statements.addNew(...readResourceStatements(change.newValue, change.logicalId));
40294
+ }
40295
+ break;
40296
+ case "ManagedPolicies":
40297
+ this.managedPolicies.addOld(...readManagedPolicies(change.oldValue, change.logicalId));
40298
+ this.managedPolicies.addNew(...readManagedPolicies(change.newValue, change.logicalId));
40299
+ break;
40300
+ case "IngressRules":
40301
+ this.ingress.addOld(...readInlineRules(change.oldValue, change.logicalId));
40302
+ this.ingress.addNew(...readInlineRules(change.newValue, change.logicalId));
40303
+ break;
40304
+ case "EgressRules":
40305
+ this.egress.addOld(...readInlineRules(change.oldValue, change.logicalId));
40306
+ this.egress.addNew(...readInlineRules(change.newValue, change.logicalId));
40307
+ }
40308
+ }
40309
+ readResourceChange(change) {
40310
+ const id = change.logicalId;
40311
+ switch (change.scrutiny) {
40312
+ case "IdentityPolicyResource":
40313
+ this.statements.addOld(...readIdentityPolicyResource(change.oldProperties));
40314
+ this.statements.addNew(...readIdentityPolicyResource(change.newProperties));
40315
+ break;
40316
+ case "ResourcePolicyResource":
40317
+ this.statements.addOld(...readResourcePolicyResource(change.oldProperties));
40318
+ this.statements.addNew(...readResourcePolicyResource(change.newProperties));
40319
+ break;
40320
+ case "LambdaPermission":
40321
+ this.statements.addOld(...readLambdaStatements(change.oldProperties));
40322
+ this.statements.addNew(...readLambdaStatements(change.newProperties));
40323
+ break;
40324
+ case "SsoPermissionSet":
40325
+ this.ssoPermissionSets.addOld(...readSso(change.oldProperties, id, permissionSetFields));
40326
+ this.ssoPermissionSets.addNew(...readSso(change.newProperties, id, permissionSetFields));
40327
+ break;
40328
+ case "SsoAssignmentResource":
40329
+ this.ssoAssignments.addOld(...readSso(change.oldProperties, id, assignmentFields));
40330
+ this.ssoAssignments.addNew(...readSso(change.newProperties, id, assignmentFields));
40331
+ break;
40332
+ case "SsoInstanceACAConfigResource":
40333
+ this.ssoInstanceACAConfigs.addOld(...readSso(change.oldProperties, id, acaConfigFields));
40334
+ this.ssoInstanceACAConfigs.addNew(...readSso(change.newProperties, id, acaConfigFields));
40335
+ break;
40336
+ case "IngressRuleResource":
40337
+ this.ingress.addOld(...readRuleResource(change.oldProperties));
40338
+ this.ingress.addNew(...readRuleResource(change.newProperties));
40339
+ break;
40340
+ case "EgressRuleResource":
40341
+ this.egress.addOld(...readRuleResource(change.oldProperties));
40342
+ this.egress.addNew(...readRuleResource(change.newProperties));
40343
+ }
40344
+ }
40345
+ };
40346
+ function readIdentityPolicies(policies, logicalId) {
40347
+ if (policies === void 0 || !Array.isArray(policies)) return [];
40348
+ const appliesToPrincipal = "AWS:${" + logicalId + "}";
40349
+ return policies.flatMap((policy) => {
40350
+ const unparsed = policy.PolicyDocument?.Statement ? policy.PolicyDocument.Statement : policy;
40351
+ return defaultPrincipal(appliesToPrincipal, parseStatements(renderIntrinsics(unparsed)));
40352
+ });
40353
+ }
40354
+ function readIdentityPolicyResource(properties) {
40355
+ if (properties === void 0) return [];
40356
+ properties = renderIntrinsics(properties);
40357
+ return (properties.Groups || []).concat(properties.Users || []).concat(properties.Roles || []).flatMap((principal) => defaultPrincipal("AWS:" + principal, parseStatements(properties.PolicyDocument.Statement)));
40358
+ }
40359
+ function readPermissionSetInlinePolicy(policy, logicalId) {
40360
+ if (policy === void 0) return [];
40361
+ const statements = parseStatements(renderIntrinsics(policy.Statement));
40362
+ defaultResource("${" + logicalId + ".Arn}", statements);
40363
+ defaultPrincipal("AWS:${" + logicalId + "}", statements);
40364
+ return statements;
40365
+ }
40366
+ function readResourceStatements(policy, logicalId) {
40367
+ if (policy === void 0) return [];
40368
+ return defaultResource("${" + logicalId + ".Arn}", parseStatements(renderIntrinsics(policy.Statement)));
40369
+ }
40370
+ function readResourcePolicyResource(properties) {
40371
+ if (properties === void 0) return [];
40372
+ properties = renderIntrinsics(properties);
40373
+ const policyKeys = Object.keys(properties).filter((key) => key.indexOf("Policy") > -1);
40374
+ const resourceKeys = Object.keys(properties).filter((key) => !policyKeys.includes(key) && !key.endsWith("Name"));
40375
+ let resources = resourceKeys.length === 1 ? properties[resourceKeys[0]] : ["???"];
40376
+ if (!Array.isArray(resources)) resources = [resources];
40377
+ return resources.flatMap((resource) => defaultResource(resource, parseStatements(properties[policyKeys[0]].Statement)));
40378
+ }
40379
+ function readManagedPolicies(policyArns, logicalId) {
40380
+ if (!policyArns) return [];
40381
+ const identity = "${" + logicalId + "}";
40382
+ const arns = renderIntrinsics(policyArns);
40383
+ return typeof arns === "string" ? [new ManagedPolicyAttachment(identity, arns)] : arns.map((arn) => new ManagedPolicyAttachment(identity, arn));
40384
+ }
40385
+ function readLambdaStatements(properties) {
40386
+ if (!properties) return [];
40387
+ return [parseLambdaPermission(renderIntrinsics(properties))];
40388
+ }
40389
+ function readInlineRules(rules, logicalId) {
40390
+ if (!rules || !Array.isArray(rules)) return [];
40391
+ const ref = "${" + logicalId + ".GroupId}";
40392
+ return rules.flatMap((rule) => {
40393
+ const rendered = renderIntrinsics(rule);
40394
+ return typeof rendered === "object" ? [new SecurityGroupRule(rendered, ref)] : [];
40395
+ });
40396
+ }
40397
+ function readRuleResource(resource) {
40398
+ if (!resource) return [];
40399
+ return [new SecurityGroupRule(renderIntrinsics(resource))];
40400
+ }
40401
+ const permissionSetFields = (p) => ({
40402
+ name: p.Name,
40403
+ ssoInstanceArn: p.InstanceArn,
40404
+ ssoCustomerManagedPolicyReferences: p.CustomerManagedPolicyReferences,
40405
+ ssoPermissionsBoundary: p.PermissionsBoundary
40406
+ });
40407
+ const assignmentFields = (p) => ({
40408
+ ssoInstanceArn: p.InstanceArn,
40409
+ permissionSetArn: p.PermissionSetArn,
40410
+ principalId: p.PrincipalId,
40411
+ principalType: p.PrincipalType,
40412
+ targetId: p.TargetId,
40413
+ targetType: p.TargetType
40414
+ });
40415
+ const acaConfigFields = (p) => ({
40416
+ ssoInstanceArn: p.InstanceArn,
40417
+ accessControlAttributes: p.AccessControlAttributes
40418
+ });
40419
+ function readSso(properties, logicalId, fields) {
40420
+ if (properties === void 0) return [];
40421
+ const values = Object.fromEntries(Object.entries({
40422
+ cfnLogicalId: "${" + logicalId + "}",
40423
+ ...fields(renderIntrinsics(properties))
40424
+ }).filter(([, v]) => v !== void 0));
40425
+ return [new SsoElement(values)];
40426
+ }
40427
+ function withHeader(color, header, rows, then = () => 0) {
40428
+ rows.sort((a, b) => {
40429
+ const keyA = sortKey(a, color);
40430
+ const keyB = sortKey(b, color);
40431
+ if (keyA < keyB) return -1;
40432
+ if (keyB < keyA) return 1;
40433
+ return then(a) - then(b);
40434
+ });
40435
+ return [header, ...rows];
40436
+ }
40437
+ function sortKey(row, color) {
40438
+ const open = !color ? "" : row[0] === "-" ? "\x1B[31m" : row[0] === "+" ? "\x1B[32m" : "";
40439
+ if (open === "" || row[1] === "") return row[1];
40440
+ const close = "\x1B[39m";
40441
+ return open + row[1].replace(/\r?\n/g, (m) => close + m + open) + close;
40442
+ }
40443
+ function summarizeStatements(changes, color) {
40444
+ return withHeader(color, [
40445
+ "",
40446
+ "Resource",
40447
+ "Effect",
40448
+ "Action",
40449
+ "Principal",
40450
+ "Condition"
40451
+ ], [...changes.statements.additions.map((s) => ["+", ...s.render()]), ...changes.statements.removals.map((s) => ["-", ...s.render()])]);
40452
+ }
40453
+ function summarizeManagedPolicies(changes, color) {
40454
+ return withHeader(color, [
40455
+ "",
40456
+ "Resource",
40457
+ "Managed Policy ARN"
40458
+ ], [...changes.managedPolicies.additions.map((a) => [
40459
+ "+",
40460
+ a.identityArn,
40461
+ a.managedPolicyArn
40462
+ ]), ...changes.managedPolicies.removals.map((a) => [
40463
+ "-",
40464
+ a.identityArn,
40465
+ a.managedPolicyArn
40466
+ ])]);
40467
+ }
40468
+ function ssoRows(collection, cells) {
40469
+ return [...collection.additions.map((e) => ["+", ...cells(e.fields)]), ...collection.removals.map((e) => ["-", ...cells(e.fields)])];
40470
+ }
40471
+ function formatManagedPolicyRef(s) {
40472
+ return `Name: ${s?.Name || ""}, Path: ${s?.Path || ""}`;
40473
+ }
40474
+ function summarizeSsoPermissionSets(changes, color) {
40475
+ const boundary = (pb) => {
40476
+ if (pb?.ManagedPolicyArn !== void 0) return `ManagedPolicyArn: ${pb?.ManagedPolicyArn || ""}`;
40477
+ if (pb?.CustomerManagedPolicyReference !== void 0) return `CustomerManagedPolicyReference: {\n ${formatManagedPolicyRef(pb?.CustomerManagedPolicyReference)}\n}`;
40478
+ return "";
40479
+ };
40480
+ return withHeader(color, [
40481
+ "",
40482
+ "Resource",
40483
+ "InstanceArn",
40484
+ "PermissionSet name",
40485
+ "PermissionsBoundary",
40486
+ "CustomerManagedPolicyReferences"
40487
+ ], ssoRows(changes.ssoPermissionSets, (f) => [
40488
+ f.cfnLogicalId || "",
40489
+ f.ssoInstanceArn || "",
40490
+ f.name || "",
40491
+ boundary(f.ssoPermissionsBoundary),
40492
+ f.ssoCustomerManagedPolicyReferences?.map(formatManagedPolicyRef).join("\n") || ""
40493
+ ]));
40494
+ }
40495
+ function summarizeSsoInstanceACAConfigs(changes, color) {
40496
+ const attribute = (aca) => `Key: ${aca?.Key}, Values: [${aca?.Value?.Source.join(", ")}]`;
40497
+ return withHeader(color, [
40498
+ "",
40499
+ "Resource",
40500
+ "InstanceArn",
40501
+ "AccessControlAttributes"
40502
+ ], ssoRows(changes.ssoInstanceACAConfigs, (f) => [
40503
+ f.cfnLogicalId || "",
40504
+ f.ssoInstanceArn || "",
40505
+ f.accessControlAttributes?.map(attribute).join("\n") || ""
40506
+ ]));
40507
+ }
40508
+ function summarizeSsoAssignments(changes, color) {
40509
+ return withHeader(color, [
40510
+ "",
40511
+ "Resource",
40512
+ "InstanceArn",
40513
+ "PermissionSetArn",
40514
+ "PrincipalId",
40515
+ "PrincipalType",
40516
+ "TargetId",
40517
+ "TargetType"
40518
+ ], ssoRows(changes.ssoAssignments, (f) => [
40519
+ f.cfnLogicalId || "",
40520
+ f.ssoInstanceArn || "",
40521
+ f.permissionSetArn || "",
40522
+ f.principalId || "",
40523
+ f.principalType || "",
40524
+ f.targetId || "",
40525
+ f.targetType || ""
40526
+ ]));
40527
+ }
40528
+ function summarizeSecurityGroups(changes, color) {
40529
+ const render = (sign, dir) => (rule) => [
40530
+ sign,
40531
+ `${rule.groupId}`,
40532
+ dir,
40533
+ rule.describeProtocol(),
40534
+ rule.describePeer()
40535
+ ];
40536
+ return withHeader(color, [
40537
+ "",
40538
+ "Group",
40539
+ "Dir",
40540
+ "Protocol",
40541
+ "Peer"
40542
+ ], [
40543
+ ...changes.ingress.additions.map(render("+", "In")),
40544
+ ...changes.egress.additions.map(render("+", "Out")),
40545
+ ...changes.ingress.removals.map(render("-", "In")),
40546
+ ...changes.egress.removals.map(render("-", "Out"))
40547
+ ], (row) => row[2].indexOf("In") > -1 ? 0 : 1);
40548
+ }
40549
+ function displayWidth(text) {
40550
+ let width = 0;
40551
+ for (const ch of text.replace(/(?:\p{Regional_Indicator}{2}|\p{Emoji_Presentation}|\p{Extended_Pictographic}\uFE0F)\p{Emoji_Modifier}?(?:\u200D(?:\p{Emoji_Presentation}|\p{Extended_Pictographic}\uFE0F?)\p{Emoji_Modifier}?)*/gu, " ")) {
40552
+ const code = ch.codePointAt(0);
40553
+ if (code <= 31 || code >= 127 && code <= 159) continue;
40554
+ if (code >= 768 && code <= 879) continue;
40555
+ width += isFullwidth(code) ? 2 : 1;
40556
+ }
40557
+ return width;
40558
+ }
40559
+ function isFullwidth(c) {
40560
+ return c >= 4352 && (c <= 4447 || c === 9001 || c === 9002 || c >= 11904 && c <= 12871 && c !== 12351 || c >= 12880 && c <= 19903 || c >= 19968 && c <= 42182 || c >= 43360 && c <= 43388 || c >= 44032 && c <= 55203 || c >= 63744 && c <= 64255 || c >= 65040 && c <= 65049 || c >= 65072 && c <= 65131 || c >= 65281 && c <= 65376 || c >= 65504 && c <= 65510 || c >= 110592 && c <= 110593 || c >= 127488 && c <= 127569 || c >= 131072 && c <= 262141);
40561
+ }
40562
+ function formatTable(cells, color) {
40563
+ const paint = (fn) => color ? fn : (text) => text;
40564
+ const lines = cells.map((row) => row.map((cell) => String(cell).split("\n")));
40565
+ const widths = cells[0].map((_, i) => Math.max(...lines.map((row) => Math.max(...row[i].map(displayWidth)))));
40566
+ const rule = (left, join, right) => paint(gray)(left + widths.map((w) => "─".repeat(w + 2)).join(join) + right);
40567
+ const bar = paint(gray)("│");
40568
+ const out = [rule("┌", "┬", "┐")];
40569
+ lines.forEach((row, r) => {
40570
+ if (r > 0 && (r === 1 || sortKey(cells[r - 1], color) !== sortKey(cells[r], color))) out.push(rule("├", "┼", "┤"));
40571
+ const sign = r === 0 ? "" : cells[r][0];
40572
+ const tint = paint(sign === "+" ? green : sign === "-" ? red : (text) => text);
40573
+ const height = Math.max(...row.map((cell) => cell.length));
40574
+ for (let l = 0; l < height; l++) {
40575
+ const cellsOut = row.map((cell, i) => {
40576
+ const text = cell[l] ?? "";
40577
+ return " " + (text === "" ? "" : tint(text)) + " ".repeat(widths[i] - displayWidth(text)) + " ";
40578
+ });
40579
+ out.push(bar + cellsOut.join(bar) + bar);
40580
+ }
40581
+ });
40582
+ out.push(rule("└", "┴", "┘"));
40583
+ return out.join("\n");
40584
+ }
40585
+ function formatSecurityChanges(changes, logicalToPath = {}, color = stdoutSupportsColor()) {
40586
+ if (!changes.permissionsAnyChanges) return "";
40587
+ const paint = (fn) => color ? fn : (text) => text;
40588
+ const substitute = (source) => source.replace(/\$\{([^.}]+)(.[^}]+)?\}/gi, (_m, logId, suffix) => {
40589
+ const path = Object.hasOwn(logicalToPath, logId) ? logicalToPath[logId] : void 0;
40590
+ return "${" + (path && normalizePath(path) || logId) + (suffix || "") + "}";
40591
+ });
40592
+ let out = "";
40593
+ const section = (title) => {
40594
+ out += `${paint(bold)(title)}\n`;
40595
+ };
40596
+ const table = (rows) => {
40597
+ out += formatTable(rows.map((row) => row.map(substitute)), color) + "\n";
40598
+ };
40599
+ if (changes.statements.hasChanges) {
40600
+ section("IAM Statement Changes");
40601
+ table(summarizeStatements(changes, color));
40602
+ }
40603
+ if (changes.managedPolicies.hasChanges) {
40604
+ section("IAM Policy Changes");
40605
+ table(summarizeManagedPolicies(changes, color));
40606
+ }
40607
+ if (changes.ssoPermissionSets.hasChanges || changes.ssoInstanceACAConfigs.hasChanges || changes.ssoAssignments.hasChanges) {
40608
+ section("IAM Identity Center Changes");
40609
+ if (changes.ssoPermissionSets.hasChanges) table(summarizeSsoPermissionSets(changes, color));
40610
+ if (changes.ssoInstanceACAConfigs.hasChanges) table(summarizeSsoInstanceACAConfigs(changes, color));
40611
+ if (changes.ssoAssignments.hasChanges) table(summarizeSsoAssignments(changes, color));
40612
+ }
40613
+ if (changes.securityGroupsHaveChanges) {
40614
+ section("Security Group Changes");
40615
+ table(summarizeSecurityGroups(changes, color));
40616
+ }
40617
+ out += `${paint(yellow)("(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)")}\n`;
40618
+ out += "\n";
40619
+ return out;
40620
+ }
40621
+ function normalizePath(p) {
40622
+ if (p.startsWith("/")) p = p.slice(1);
40623
+ let parts = p.split("/");
40624
+ if (parts.length > 1) {
40625
+ parts = parts.slice(1);
40626
+ if (parts.length > 1) {
40627
+ const last = parts[parts.length - 1];
40628
+ if (last === "Resource" || last === "Default") parts = parts.slice(0, parts.length - 1);
40629
+ }
40630
+ p = parts.join("/");
40631
+ }
40632
+ return p;
40633
+ }
40634
+ function stdoutSupportsColor(env = process.env, argv = process.argv, isTTY = process.stdout.isTTY === true, platform = process.platform) {
40635
+ const terminator = argv.indexOf("--");
40636
+ const hasFlag = (flag) => {
40637
+ const position = argv.indexOf(`--${flag}`);
40638
+ return position !== -1 && (terminator === -1 || position < terminator);
40639
+ };
40640
+ let force;
40641
+ if ([
40642
+ "no-color",
40643
+ "no-colors",
40644
+ "color=false",
40645
+ "color=never"
40646
+ ].some(hasFlag)) force = 0;
40647
+ else if ([
40648
+ "color",
40649
+ "colors",
40650
+ "color=true",
40651
+ "color=always"
40652
+ ].some(hasFlag)) force = 1;
40653
+ const forceEnv = env["FORCE_COLOR"];
40654
+ if (forceEnv !== void 0) {
40655
+ if (forceEnv === "true") force = 1;
40656
+ else if (forceEnv === "false") force = 0;
40657
+ else force = forceEnv.length === 0 ? 1 : Math.min(parseInt(forceEnv, 10), 3);
40658
+ }
40659
+ if (force === 0) return false;
40660
+ if ([
40661
+ "color=16m",
40662
+ "color=full",
40663
+ "color=truecolor",
40664
+ "color=256"
40665
+ ].some(hasFlag)) return true;
40666
+ if (!isTTY && force === void 0) return false;
40667
+ const min = force || 0;
40668
+ if (env["TERM"] === "dumb") return min > 0;
40669
+ if (platform === "win32") return true;
40670
+ if ("CI" in env) return [
40671
+ "TRAVIS",
40672
+ "CIRCLECI",
40673
+ "APPVEYOR",
40674
+ "GITLAB_CI",
40675
+ "GITHUB_ACTIONS",
40676
+ "BUILDKITE"
40677
+ ].some((sign) => sign in env) || env["CI_NAME"] === "codeship" || min > 0;
40678
+ if ("TEAMCITY_VERSION" in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env["TEAMCITY_VERSION"] ?? "");
40679
+ if (env["COLORTERM"] === "truecolor") return true;
40680
+ if (env["TERM_PROGRAM"] === "iTerm.app" || env["TERM_PROGRAM"] === "Apple_Terminal") return true;
40681
+ const term = env["TERM"] ?? "";
40682
+ if (/-256(color)?$/i.test(term)) return true;
40683
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(term)) return true;
40684
+ if ("COLORTERM" in env) return true;
40685
+ return min > 0;
40686
+ }
40687
+
39637
40688
  //#endregion
39638
40689
  //#region src/analyzer/security-diff.ts
39639
40690
  function isSyntheticChange(pc) {
@@ -39709,21 +40760,6 @@ function securityDiffTemplates(changes, records) {
39709
40760
  maskedChanges
39710
40761
  };
39711
40762
  }
39712
- let cfnDiffModule;
39713
- function loadCfnDiff() {
39714
- cfnDiffModule ??= import("@aws-cdk/cloudformation-diff").then((mod) => mod.default ?? mod);
39715
- return cfnDiffModule;
39716
- }
39717
- let cfnDiffUtilModule;
39718
- function loadCfnDiffUtil() {
39719
- cfnDiffUtilModule ??= import("@aws-cdk/cloudformation-diff/lib/diff/util.js").then((mod) => mod.default ?? mod);
39720
- return cfnDiffUtilModule;
39721
- }
39722
- function isScrutinized(util, change) {
39723
- const model = util.loadResourceModel(change.resourceType);
39724
- const scrutinized = (value) => value !== void 0 && value !== "None";
39725
- return scrutinized(model?.scrutinizable) || scrutinized(model?.properties?.[change.path]?.scrutinizable);
39726
- }
39727
40763
  async function diffSecurity(args) {
39728
40764
  const templates = securityDiffTemplates(args.changes, args.records);
39729
40765
  const { oldTemplate, newTemplate } = templates;
@@ -39732,9 +40768,8 @@ async function diffSecurity(args) {
39732
40768
  rendered: ""
39733
40769
  };
39734
40770
  try {
39735
- const cfnDiff = await loadCfnDiff();
39736
- const unjudged = templates.maskedChanges.length === 0 ? [] : await loadCfnDiffUtil().then((util) => templates.maskedChanges.filter((c) => isScrutinized(util, c)));
39737
- const diff = cfnDiff.fullDiff(structuredClone(oldTemplate), structuredClone(newTemplate));
40771
+ const unjudged = templates.maskedChanges.filter((c) => isScrutinizedProperty(c.resourceType, c.path));
40772
+ const diff = new SecurityChanges(structuredClone(oldTemplate), structuredClone(newTemplate));
39738
40773
  const broadening = diff.permissionsBroadened || unjudged.length > 0;
39739
40774
  const unjudgedNote = unjudged.length === 0 ? "" : "These changed values are masked, so whether they broaden permissions could not be evaluated:\n" + unjudged.map((c) => ` ${c.logicalId} (${c.resourceType}): ${c.path}\n`).join("");
39740
40775
  if (!diff.permissionsBroadened && !diff.permissionsAnyChanges) return {
@@ -39744,12 +40779,8 @@ async function diffSecurity(args) {
39744
40779
  let table;
39745
40780
  try {
39746
40781
  const shown = args.secretMask === void 0 ? void 0 : withholdSecrets(templates, args.secretMask());
39747
- const shownDiff = shown === void 0 || shown.masked === 0 ? diff : cfnDiff.fullDiff(shown.templates.oldTemplate, shown.templates.newTemplate);
39748
- table = "";
39749
- cfnDiff.formatSecurityChanges({ write(chunk) {
39750
- table += String(chunk);
39751
- return true;
39752
- } }, shownDiff, logicalIdToPath(args.records, args.template));
40782
+ const shownDiff = shown === void 0 || shown.masked === 0 ? diff : new SecurityChanges(shown.templates.oldTemplate, shown.templates.newTemplate);
40783
+ table = formatSecurityChanges(shownDiff, logicalIdToPath(args.records, args.template));
39753
40784
  if (shown !== void 0 && shown.masked > 0) table += "(Values that hold a secret are shown as ***.)\n";
39754
40785
  } catch {
39755
40786
  table = "The security changes are not shown: they could not be checked for secrets.\n";
@@ -40246,9 +41277,11 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
40246
41277
  const createOnlyEvidence = acceptedCreateOnlyDropsOf(currentResource);
40247
41278
  const recordedAsWritten = currentResource.provisionedBy === "cc-api" ? currentProps : withoutUnwrittenSilentDropProperties(resourceType, currentProps, desiredForSkipCheck, allowedForRecord, createOnlyEvidence);
40248
41279
  const unmarkedRecord = noEchoLeavesOf(currentResource) === void 0;
40249
- const todayAsWritten = unmarkedRecord ? redactSecretsForState(markSameGenerationBag({ ...resolvedProps }), withoutNoEchoParameterEntries(updateSecrets), desiredProps) : void 0;
41280
+ const todayAsWritten = unmarkedRecord || witnessNormalize(recordedAsWritten, void 0, desiredForSkipCheckAsWritten).differing.length > 0 ? redactSecretsForState(markSameGenerationBag({ ...resolvedProps }), withoutNoEchoParameterEntries(updateSecrets), desiredProps) : void 0;
40250
41281
  const witness = todayAsWritten === void 0 ? void 0 : witnessNormalize(recordedAsWritten, todayAsWritten, desiredForSkipCheckAsWritten);
40251
41282
  const currentPropsAsWritten = witness === void 0 ? recordedAsWritten : witness.current;
41283
+ const witnessMigrates = unmarkedRecord || (witness?.confirmed.length ?? 0) > 0;
41284
+ if (!unmarkedRecord && witness !== void 0 && witness.confirmed.length > 0) this.witnessConfirmedLeaves.set(logicalId, witness.confirmed.map((coordinate) => [...coordinate]));
40252
41285
  for (const coordinate of witness?.differing ?? []) {
40253
41286
  const desiredAt = valueAtCoordinate(desiredForSkipCheckAsWritten, coordinate);
40254
41287
  recordPreviousNoEchoLeaves(this.secretNameBagFor(logicalId), valueAtCoordinate(recordedAsWritten, coordinate), scalarLeavesOf(desiredAt), updateSecrets, desiredAt !== "***");
@@ -40305,7 +41338,8 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
40305
41338
  this.logger.warn(cause === "parameter" ? safeMsg`${logicalId}.${key} is a create-only property, and a NoEcho parameter's value changed since the last deploy: ${logicalId} is replaced.` : safeMsg`${logicalId}.${key} is a create-only property, and the value at its NoEcho position changed since the last deploy: ${logicalId} is replaced.`);
40306
41339
  };
40307
41340
  const suppliesFreshMaskOnlyValue = pendingParameterLeaves.size > 0 || Object.keys(resolvedProps).some((key) => otherFreshAt(key).length > 0);
40308
- const recordMatchesDesired = movedMasked.size === 0 && keyOrderFreeJson(desiredForSkipCheckAsWritten) === keyOrderFreeJson(currentPropsAsWritten);
41341
+ const rewrittenPaths = readsProducerReplacedThisRun.call(this, template, logicalId, stateResources) ? redactionRewrittenPaths(resolvedProps, desiredForSkipCheck, comparisonCoordinates) : /* @__PURE__ */ new Set();
41342
+ const recordMatchesDesired = movedMasked.size === 0 && rewrittenPaths.size === 0 && keyOrderFreeJson(desiredForSkipCheckAsWritten) === keyOrderFreeJson(currentPropsAsWritten);
40309
41343
  const applyAttributeOnlyUpdate = (attributeChanges) => {
40310
41344
  const attrSummary = attributeChanges.map((a) => `${a.attribute}: ${a.oldValue ?? "(unset)"} → ${a.newValue ?? "(unset)"}`).join(", ");
40311
41345
  this.logger.info(safeMsg` ↻ ${logicalId} (${resourceType}) attribute update: ${attrSummary}`);
@@ -40321,7 +41355,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
40321
41355
  };
40322
41356
  const schemaCreateOnly = pendingParameterLeaves.size === 0 && parameterCoordinates.length === 0 ? [] : await getCreateOnlyPropertyPaths(resourceType).catch(() => []);
40323
41357
  const echoCandidates = echoFidelityCandidates(parameterCoordinates, resolvedProps, schemaCreateOnly);
40324
- const readbackRecord = unmarkedRecord && parameterCoordinates.length > 0 ? {
41358
+ const readbackRecord = witnessMigrates && parameterCoordinates.length > 0 ? {
40325
41359
  ...currentResource,
40326
41360
  properties: maskAtCoordinates(currentResource.properties, parameterCoordinates)
40327
41361
  } : currentResource;
@@ -40378,7 +41412,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
40378
41412
  };
40379
41413
  const lateReplacementDeclined = /* @__PURE__ */ new Set();
40380
41414
  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=${this.options.requireApproval ?? "never"})`;
40381
- if (unmarkedRecord && !typeChanged && echoCandidates.length > 0 && hasAddressablePhysicalId(currentResource)) await readOnce();
41415
+ if (witnessMigrates && !typeChanged && echoCandidates.length > 0 && hasAddressablePhysicalId(currentResource)) await readOnce();
40382
41416
  if (!typeChanged && !suppliesFreshMaskOnlyValue && lostChild === void 0 && this.recreateDirectionFor(stackName, logicalId) === void 0 && recordMatchesDesired) {
40383
41417
  if (change.attributeChanges && change.attributeChanges.length > 0) {
40384
41418
  applyAttributeOnlyUpdate(change.attributeChanges);
@@ -40409,7 +41443,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
40409
41443
  lowered.push(pc);
40410
41444
  continue;
40411
41445
  }
40412
- const moved = movedMasked.has(pc.path) || keyOrderFreeJson(desiredForSkipCheckAsWritten[pc.path]) !== keyOrderFreeJson(currentPropsAsWritten[pc.path]);
41446
+ const moved = movedMasked.has(pc.path) || rewrittenPaths.has(pc.path) || keyOrderFreeJson(desiredForSkipCheckAsWritten[pc.path]) !== keyOrderFreeJson(currentPropsAsWritten[pc.path]);
40413
41447
  const conditionalVerdict = moved && !typeChanged && isReplacementCeiling(pc) ? this.diffCalculator.conditionalReplacementVerdict?.(resourceType, pc.path, currentPropsAsWritten[pc.path], desiredForSkipCheckAsWritten[pc.path]) : void 0;
40414
41448
  if (moved && conditionalVerdict !== false) {
40415
41449
  warnWitnessReplacement(pc.path);
@@ -40463,7 +41497,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
40463
41497
  return liveHoldsFreshLeaves(read.live[key], pendingParameterLeaves.get(key) ?? []) ? "held" : "differs";
40464
41498
  };
40465
41499
  const lowered = [];
40466
- const movedAt = (path) => movedMasked.has(path) || keyOrderFreeJson(desiredForSkipCheckAsWritten[path]) !== keyOrderFreeJson(currentPropsAsWritten[path]);
41500
+ const movedAt = (path) => movedMasked.has(path) || rewrittenPaths.has(path) || keyOrderFreeJson(desiredForSkipCheckAsWritten[path]) !== keyOrderFreeJson(currentPropsAsWritten[path]);
40467
41501
  replacedAnyway = this.recreateDirectionFor(stackName, logicalId) !== void 0 || lostWithParent !== void 0 || (change.propertyChanges ?? []).some((other) => other.requiresReplacement && (!parameterCreateOnlyPaths.has(other.path) || movedAt(other.path)));
40468
41502
  for (const pc of change.propertyChanges ?? []) {
40469
41503
  if (!parameterCreateOnlyPaths.has(pc.path)) {
@@ -40613,11 +41647,16 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
40613
41647
  diffSawTokenChange: diffMovedServiceToken(change)
40614
41648
  });
40615
41649
  if (serviceTokenRefusal !== void 0) throw markRefusedBeforeApplying(markNonRetryable(new CdkdError(renderServiceTokenRefusal([serviceTokenRefusal], stackName, createSecretMasker(updateSecrets)), SERVICE_TOKEN_CHANGE_REFUSED)));
41650
+ let previousForProvider = currentPropsAsWritten;
41651
+ for (const coordinate of witness?.confirmed ?? []) {
41652
+ const value = valueAtCoordinate(resolvedProps, coordinate);
41653
+ if (value !== void 0) previousForProvider = setAtCoordinate(previousForProvider, coordinate, value);
41654
+ }
40616
41655
  return markRestored(await this.updateInPlace({
40617
41656
  conditions,
40618
41657
  counts,
40619
41658
  currentProps,
40620
- currentPropsAsWritten,
41659
+ currentPropsAsWritten: previousForProvider,
40621
41660
  currentResource,
40622
41661
  dependencies,
40623
41662
  desiredForSkipCheckAsWritten,
@@ -40669,6 +41708,18 @@ function recordHoldsEmbeddedReference(record) {
40669
41708
  };
40670
41709
  return walk(record.properties) || walk(record.attributes);
40671
41710
  }
41711
+ function redactionRewrittenPaths(resolvedProps, desiredForSkipCheck, comparisonCoordinates) {
41712
+ const masked = maskAtCoordinates({ ...resolvedProps }, comparisonCoordinates);
41713
+ return new Set(Object.keys(masked).filter((key) => keyOrderFreeJson(masked[key]) !== keyOrderFreeJson(desiredForSkipCheck[key])));
41714
+ }
41715
+ function readsProducerReplacedThisRun(template, logicalId, stateResources) {
41716
+ return (this.extractAllDependencies(template, logicalId) ?? []).some((id) => {
41717
+ const loaded = Object.hasOwn(this.healBaseline, id) ? this.healBaseline[id] : void 0;
41718
+ if (loaded === void 0) return false;
41719
+ const now = Object.hasOwn(stateResources, id) ? stateResources[id] : void 0;
41720
+ return now !== void 0 && now.physicalId !== loaded.physicalId;
41721
+ });
41722
+ }
40672
41723
 
40673
41724
  //#endregion
40674
41725
  //#region src/deployment/deploy-engine/update-replace.ts
@@ -43464,6 +44515,7 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
43464
44515
  };
43465
44516
  const currentEtag = currentStateData?.etag;
43466
44517
  this.healBaseline = currentState.resources ?? {};
44518
+ this.runProducerRegionEvidence = () => this.producerRegionEvidence(currentState);
43467
44519
  refuseMalformedOutputs(currentState, stackName, this.stackRegion, this.options.refusalRecovery);
43468
44520
  refuseMalformedResourcesForDeploy(currentState, stackName, this.stackRegion, this.options.refusalRecovery);
43469
44521
  refuseMalformedResourceEntriesForDeploy(currentState, stackName, this.stackRegion, this.options.refusalRecovery);
@@ -44075,6 +45127,7 @@ var DeployEngine = class {
44075
45127
  secretNameNeedles = /* @__PURE__ */ new Map();
44076
45128
  perResourceTemplateProps = /* @__PURE__ */ new Map();
44077
45129
  perResourceResolvedType = /* @__PURE__ */ new Map();
45130
+ witnessConfirmedLeaves = /* @__PURE__ */ new Map();
44078
45131
  fingerprintNoEchoValues = void 0;
44079
45132
  preDeploySecretNamedRecords = void 0;
44080
45133
  fingerprintParameters = void 0;
@@ -44098,6 +45151,7 @@ var DeployEngine = class {
44098
45151
  updateWasReplaced = /* @__PURE__ */ new Map();
44099
45152
  oldDeletedBeforeCreate = /* @__PURE__ */ new Set();
44100
45153
  healBaseline = {};
45154
+ runProducerRegionEvidence = void 0;
44101
45155
  deployChanges = /* @__PURE__ */ new Map();
44102
45156
  deployStateResources = {};
44103
45157
  stackRecordsView = void 0;
@@ -44145,6 +45199,7 @@ var DeployEngine = class {
44145
45199
  this.perResourceTemplateProps = /* @__PURE__ */ new Map();
44146
45200
  this.constructPathTemplate = void 0;
44147
45201
  this.perResourceResolvedType = /* @__PURE__ */ new Map();
45202
+ this.witnessConfirmedLeaves = /* @__PURE__ */ new Map();
44148
45203
  this.fingerprintNoEchoValues = void 0;
44149
45204
  this.preDeploySecretNamedRecords = void 0;
44150
45205
  this.fingerprintParameters = void 0;
@@ -44165,6 +45220,7 @@ var DeployEngine = class {
44165
45220
  this.updateWasReplaced = /* @__PURE__ */ new Map();
44166
45221
  this.oldDeletedBeforeCreate = /* @__PURE__ */ new Set();
44167
45222
  this.healBaseline = {};
45223
+ this.runProducerRegionEvidence = void 0;
44168
45224
  this.deployChanges = /* @__PURE__ */ new Map();
44169
45225
  this.deployStateResources = {};
44170
45226
  this.inlinePolicyWriters = /* @__PURE__ */ new Map();
@@ -44383,5 +45439,5 @@ DeployEngine.prototype.replacementNameOrigin = replacementNameOrigin;
44383
45439
  DeployEngine.prototype.orphanedNameCollisionAdvice = orphanedNameCollisionAdvice;
44384
45440
 
44385
45441
  //#endregion
44386
- export { isTruthyCfnBoolean as $, isStatefulRecreateTargetForReplace as $a, CFN_TEMPLATE_URL_LIMIT as $c, malformedOrphansRefusalMessage as $i, ledgerForStack as $n, markSameGenerationBag as $o, assertSendableRoleArn as $r, stringifyValue as $s, seedsDeleteFirstGuard as $t, noEchoComparisonForTemplate as A, refuseMalformedResourcesForDeploy as Aa, runDockerForeground as Ac, declaresNoEcho as Ai, journaledOrphanPrintingBag as An, maskWholeValue as Ao, deleteIndeterminateGuards as Ar, S3StateBackend as As, dropFailedHint as At, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as B, unpreviewableOrphanRecords as Ba, getLegacyStateBucketName as Bc, hasReadableOutputs as Bi, PRE_DELETE_SNAPSHOT_TYPES as Bn, carryLogOnlyValues as Bo, reDisableInstanceApiTermination as Br, describeRegionValueKind as Bs, getStackRecords as Bt, recordRetainedForReadoption as C, refuseMalformedResourceEntriesForImport as Ca, formatDockerLoginError as Cc, cfnRefValueFromPhysicalId as Ci, resolveBucketRegion as Cl, collectDeclaredOutputNames as Cn, sameLambdaFunctionAddress as Co, applyCustomResourceResponseExpiration as Cr, STATE_SOURCED_CROSS_GENERATION_RULES as Cs, revertNestedChildFromJournal as Ct, withResourceDeadline as D, refuseMalformedResourcePropertiesForDrift as Da, partitionSensitiveEnv as Dc, withSharedDrainBudget as Di, DEFAULT_RESOURCE_TIMEOUT_MS as Dn, isMarkedCoordinate as Do, unchangedBehindSecretReference as Dr, isSingleDynamicReferenceToken as Ds, getCurrentNestedStackContext as Dt, serviceTokenBlockingReason as E, refuseMalformedResourcePropertiesForDestroy as Ea, isMalformedEnvKey as Ec, parseWebACLArn as Ei, bindingSkippedOutputs as En, canonicalCoordinates as Eo, slowCcOperationTimeoutMs as Er, WHOLE_DYNAMIC_REFERENCE_PATTERN as Es, collectNestedChildUnaddressed as Et, PROTECTION_PROPERTY_BY_TYPE as F, repairMalformedOrphansForReadOnly as Fa, AssetManifestLoader as Fc, UNREADABLE_RESOURCES_MAP_ROW as Fi, secretNamedRecordNeedles as Fn, passedNoEchoParametersOf as Fo, markWaitAbandoned as Fr, crossPrefixDeniedWarning as Fs, sameJournaledOrphans as Ft, resolveDynamoDbDeleteBudgetMs as G, findSilentDropProperties as Ga, resolveSkipPrefix as Gc, malformedExportNamesWarning as Gi, isFinalSnapshotError as Gn, printingCorpusOf as Go, poisonRenderedSpellingsCollidingIn as Gr, importableOutputKeys as Gs, isJournaledOrphan as Gt, compensateRemovedDeletionProtection as H, unreadableResourceEntries as Ha, resolveApp as Hc, isReadableOrphanRecord as Hi, ccRoutedFinalSnapshotError as Hn, hasMaskableValues as Ho, DiffCalculator as Hr, hasReadableExportSet as Hs, removeProtectionTypeList as Ht, isProtectionValueActive as I, repairMalformedOutputsForReadOnly as Ia, getDockerImageBySourceHash as Ic, accountArgs as Ii, stateSecretNameNeedles as In, readbackPathFor as Io, disableInstanceApiTermination as Ir, isAccessDenied$1 as Is, replayFailedOperations as It, deleteTableWithIndexBusyRetry as J, NO_CC_HANDLERS_REASON as Ja, resolveUseCdkBootstrapAssets as Jc, malformedLocalResourceEntriesWarning as Ji, maskingRetryLogger as Jn, shareLogOnlyValues as Jo, regionLessSecretName as Jr, orphansAfterRollback as Js, planRollback as Jt, DELETE_INDEX_WAIT_PROCEED_NOTE as K, unwrittenCreateOnlyReplacement as Ka, resolveStateBucketWithDefault as Kc, malformedExportSourceWarning as Ki, refusesFinalSnapshot as Kn, recordLogOnlyParameterValue as Ko, classifyReplaySecretRegion as Kr, importableOutputs as Ks, isReplacementOrphan as Kt, perType as L, repairMalformedResourceEntriesForReadOnly as La, Synthesizer as Lc, deployRefusesOrphanRowsReason as Li, storedSecretNameNeedles as Ln, readsNoEchoSource as Lo, ec2InstanceProtectionSite as Lr, isNotImplemented as Ls, replayRollback as Lt, noEchoParameterNamesOf as M, refuseMalformedResourcesForExport as Ma, warnFinchArgvExposure as Mc, STATE_REGION_DIVERGED as Mi, orphanRecordsPrintingBag as Mn, noEchoCoordinatesOf as Mo, deleteSkipReason as Mr, CrossPrefixReadError as Ms, journaledOrphanLines as Mt, recordedProtectionEvidence as N, refuseMalformedState as Na, escapeRegExp$3 as Nc, STATE_RESOURCES_MALFORMED as Ni, secretNamePrintingBag as Nn, noEchoLeavesOf as No, withIndeterminateGuard as Nr, CrossPrefixScanCache as Ns, loadJournaledOrphans as Nt, diffSecurity as O, refuseMalformedResourcePropertiesForExport as Oa, redactDockerArgvValues as Oc, parameterInputsFor as Oi, DEFAULT_RESOURCE_WARN_AFTER_MS as On, maskAtCoordinates as Oo, RollbackInlinePolicyWriters as Or, LockManager as Os, withNestedStackContext as Ot, recordedProtectionNote as P, repairMalformedOrphanRecordsForReadOnly as Pa, stripControlChars as Pc, UNREADABLE_ORPHANS_CONTAINER_ROW as Pi, secretNamePrintingBags as Pn, noEchoOutputsComparison as Po, isWaitAbandonedError as Pr, applyCrossPrefixScan as Ps, makeForeignHolderScan as Pt, hasCdkAutoDeleteTag as Q, MULTI_REGION_RECREATE_BLOCKED_TYPES as Qa, CFN_TEMPLATE_BODY_LIMIT as Qc, malformedOrphanRowsKeptWarning as Qi, earliestDefined as Qn, maskSecretsInText as Qo, assertFlagRoleArn as Qr, isSensitiveAttributeName as Qs, resolveReplacementOldType as Qt, readProtection as R, repairMalformedResourcePropertiesForReadOnly as Ra, synthesisStatusMessage as Rc, displayLogicalId as Ri, extractDeploymentEventError as Rn, valueAtCoordinate as Ro, isTerminationProtectionPropagationError as Rr, splitImportedOps as Rs, awaitInFlightSibling as Rt, keptForReadoption as S, refuseMalformedResourceEntriesForDestroy as Sa, finchSecretArgvRefusal as Sc, AWS_NO_VALUE as Si, clearBucketRegionCache as Sl, noEchoParameterValueSeed as Sn, lambdaFunctionNameForMask as So, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Sr, STATE_SOURCED_BASELINE_RULES as Ss, recordDisplacedSkips as St, findServiceTokenRefusals as T, refuseMalformedResourceEntriesForOrphan as Ta, isDockerClientEnvKey as Tc, refStateLookupFromResource as Ti, isExportAliasCollision as Tn, TemplateParser as To, CloudControlProvider as Tr, TEMPLATE_SOURCED_RULES as Ts, withNestedRevertRun as Tt, deleteBudgetKey as U, withheldAccountClause as Ua, resolveAutoAssetStorage as Uc, isReadableResourceEntry as Ui, createPreDeleteFinalSnapshot as Un, literalSplitDelimitersOf as Uo, INTRINSIC_KEYS as Ur, hasReasonlessBaselineRefusal as Us, recordAfterRollbackUpdate as Ut, beginDeleteWait as V, unreadableOrphanRecords as Va, loadCdkJson as Vc, hasReadableResources as Vi, buildFinalSnapshotIdentifier as Vn, createUnionSecretMasker as Vo, reEnableInstanceApiTermination as Vr, exportNamesCarriedFrom as Vs, withStackRecords as Vt, resolveDynamoDbDeleteBudgetClock as W, findActionableSilentDrops as Wa, resolveCaptureObservedState as Wc, malformedDriftResourcePropertiesWarning as Wi, effectiveDeletionPolicy as Wn, logOnlyValueCount as Wo, IntrinsicFunctionResolver as Wr, hasUnverifiableParameterRefusal as Ws, demoteSupersededOrphans as Wt, ECR_AUTO_DELETE_IMAGES_TAG as X, findReplacedReadersOfRecreateTargets as Xa, warnDeprecatedNoPrefixCliFlag as Xc, malformedOrphanRecordsRefusalMessage as Xi, findDestructiveChanges as Xn, errorCauseChain as Xo, refuseUnreadableCdkCrossAccountRefs as Xr, shouldRetainResource as Xs, recordUnderIdIsNotOwn as Xt, waitForIndexesSettled as Y, hasNoCloudControlHandlers as Ya, stateBucketExistenceConfirmed as Yc, malformedLocalResourcesWarning as Yi, constructPathOf as Yn, createSecretMasker as Yo, producerLookupOver as Yr, orphansCarriedFrom as Ys, recheckFailedPlan as Yt, S3_AUTO_DELETE_OBJECTS_TAG as Z, shownType as Za, ssmResolvedValueType as Zc, malformedOrphanRecordsWarning as Zi, formatDestructiveChange as Zn, maskSecretsInError as Zo, applyRoleArnIfSet as Zr, AssetPublisher as Zs, replacementNeverSwapped as Zt, makeCanonicalizePropertiesFn as _, refuseMalformedOutputs as _a, resolveDockerContextDirectory as _c, isImpossibleEmptyStoredAttribute as _i, absoluteAssemblyPathEscape as _l, secretSafeKeyDisplay as _n, prefetchCreateOnlyPropertyPaths as _o, TemplateNoEchoReresolver as _r, recordMaskOnlyValuesIn as _s, displacedOpClause as _t, findNestedTemplateTreeDefect as a, malformedResourcePropertiesWarning as aa, AssetModeResolver as ac, callerEnvCredentials as ai, expectedOwnerParam as al, isRedactedRecordedValue as an, toCfnInteger as ao, planTagDiff as ar, DYNAMIC_REFERENCE_TOKEN_SCAN as as, cyan as at, lookupEachName as b, refuseMalformedResourceEntries as ba, describeDockerFailure as bc, isNamelessDynamicReferenceError as bi, renderAssemblyPathEscape as bl, exportNameSecretExposure as bn, withRetry as bo, getCurrentResourceSecrets as br, recordProvenPublicExpression as bs, getNestedRevertRun as bt, renderNestedTemplateTreeDefect as c, malformedStateRefusalMessage as ca, ensureAssetStorage as cc, s3BucketArn as ci, derivePartitionAndUrlSuffix as cl, updatePartialMessage as cn, coerceCfnInteger as co, tagMapAsList as cr, pathCrossesDottedKey as cs, red as ct, conditionInputsFrom as d, refuseMalformedNestedChildOutputs as da, parseBootstrapMarker as dc, s3BucketRegionalDomainName as di, processStackMessages as dl, DeploymentEventsStore as dn, configStringRefusal as do, stringifyIfAssigned as dr, recordNestedStackParameterExpressions as ds, namesAnyDeclaredParameter as dt, malformedOrphansWarning as ea, WorkGraph as ec, explicitRoleArnOrThrow as ei, MIGRATE_TMP_PREFIX as el, orphanDeleteNeedsIdentity as en, isStatefulRecreateTargetSync as eo, reserveStackCreateToken as er, redactSecretsForState as es, getPriorAttempts as et, parentSuppliedValues as f, refuseMalformedOrphanRecords as fa, readBootstrapMarkerBody as fc, s3BucketWebsiteUrl as fi, defineOwnKey as fl, WITHHELD_NAME_DISPLAY as fn, readConfigString as fo, CC_BROKEN_REASON as fr, recoverMaskedOutput as fs, reachableDivergentParameters as ft, mergeNoChangeOutputs as g, refuseMalformedOrphansForOrphan as ga, buildDockerImage as gc, getAccountInfo as gi, ownValue as gl, secretBearingStateKeyWarning as gn, requireConfigString as go, wouldReturnToSdkProvider as gr, recordMaskOnlyValue as gs, NESTED_PENDING_PARENT_REASON as gt, keptWholeReasonText as h, refuseMalformedOrphansForDestroy as ha, buildDenyExternalAccessPolicy as hc, parameterTypeMayLoseSecretIdentity as hi, nullPrototypeRecord as hl, secretBearing as hn, requireConfigObject as ho, isCustomResource as hr, provenPublicValue as hs, planOrphanAdoption as ht, childTemplateLoader as i, malformedResourceEntriesWarning as ia, rewriteTemplateAssetReferences as ic, applyCallerIdentityCredentials as ii, decodeListingKey as il, REDACTED_DELETE_ADDRESS_SKIP_REASON as in, isWarmThroughputDecrease as io, DBPROXY_TAG_OPTIONS as ir, recordPhysicalNameCopy as is, bold as it, noEchoExactEchoLeavesOf as j, refuseMalformedResourcesForDestroy as ja, runDockerStreaming as jc, JSON_LISTING_HOLE_VALUE as ji, maskEventTextWithBoundBags as jn, maskedLeafCoordinatesOf as jo, deleteLeftInPlace as jr, rebuildClientForBucketRegion as js, isHandledOrphan as jt, noEchoAttributeNamesOf as k, refuseMalformedResourcePropertiesForOrphan as ka, redactedDockerCause as kc, passedParameterClassesOf as ki, completedReplayEntries as kn, maskReadbackAtCoordinates as ko, UNSPECIFIED_SKIP_REASON as kr, isLockInfoExpired as ks, deleteJournaledOrphans as kt, templateIdentity as l, previewableOrphanRecords as la, getBootstrapMarkerKey as lc, s3BucketDomainName as li, AssemblyReader as ll, updatePartialReason as ln, configBooleanRefusal as lo, tagPlanWarning as lr, identityKeyFor as ls, yellow as lt, isSecretBearingReferenceString as m, refuseMalformedOrphans as ma, validateContainerRepoName as mc, isUnboundTemplateParameter as mi, hasPlainPrototype$1 as ml, exportAliasCollisionScrubWarning as mn, requireConfigArray as mo, ccBrokenReason as mr, carriesSecretMask as ms, makeSiblingClaimReader as mt, IMPLICIT_DELETE_DEPENDENCIES as n, malformedOutputsWarning as na, createAssetRedirectResolver as nc, sendableAssumeRoleCommand as ni, uploadCfnTemplate as nl, getCurrentProducerRegions as nn, WARM_THROUGHPUT_MEMBERS as no, acquireIdempotencyToken as nr, withPhysicalNameCopies as ns, formatResourceLine as nt, isAbsoluteAssetPath as o, malformedResourcesWarning as oa, BOOTSTRAP_MARKER_PREFIX as oc, envCredentialsAreAssumedRole as oi, PARTITION_TABLE as ol, redactedDeleteAddressFields as on, toFiniteNumber as oo, readTagList as or, dynamicReferenceTokens as os, gray as ot, readRecordedConditionVerdicts as p, refuseMalformedOrphanRecordsForDestroy as pa, validateAssetBucketName as pc, coerceParameterTypedValue as pi, hasOwnKey as pl, displayTextOrWithheld as pn, replayWarn as po, ProviderRegistry as pr, splitGetAttStringForm as ps, resourcesNamingDeclaredParameter as pt, INDEX_SETTLE_POLL_INTERVAL_MS as q, withoutSilentDropProperties as qa, resolveStateBucketWithDefaultAndSource as qc, malformedLocalOutputsWarning as qi, unsupportedFinalSnapshotError as qn, recordLogOnlyValue as qo, producerRegionsFromState as qr, isReadableBag as qs, planFailedOps as qt, computeImplicitDeleteEdges as r, malformedRenderedContainersWarning as ra, loadPublishableAssetManifest as rc, AWS_CREDENTIAL_ENV_KEYS as ri, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as rl, inheritProducerRegions as rn, coerceWarmThroughput as ro, DBPROXY_TAGS_WHAT as rr, withoutPhysicalNameCopies as rs, createReadOnlyAttributeHealerFactory as rt, listNestedTemplateRows as s, malformedScrubResourceEntriesRefusalMessage as sa, assertAssetBucketRegion as sc, isSettledInstanceState as si, canonicalizeRegion as sl, redactedDeleteAddressSkip as sn, coerceCfnBoolean as so, refuseMalformedDesiredTags as sr, isUncertifiedBaselineMaskPosition as ss, green as st, DeployEngine as t, malformedOutputsRefusalMessage as ta, buildAssetRedirectMap as tc, isIamRoleArn as ti, findLargeInlineResources as tl, findNestedStackTypeChanges as tn, renderStatefulReason as to, withCreateTokenLedger as tr, scrubResourceRecord as ts, markRefusedBeforeApplying as tt, conditionFingerprint as u, refuseDivergentRecordRegionForDestroy as ua, isCrossRegionRedirect as uc, s3BucketDualStackDomainName as ui, StageLoadError as ul, DeploymentEventsReader as un, configIntegerRefusal as uo, definedAttributes as ur, inheritNestedStackParameterAssociations as us, computeParameterTaint as ut, chunks as v, refuseMalformedOutputsForDestroy as va, describeDockerCapturedOutput as vc, carriesDynamicReference as vi, describeFileReadFailure as vl, carriedExportAliasExposure as vn, templateResourceTypes as vo, readsNoEchoDeleteValues as vr, recordNoEchoAttributeValues as vs, displacedPhysicalIdShown as vt, deferredServiceTokenWarning as w, refuseMalformedResourceEntriesForImportSave as wa, getDockerCmd as wc, isStalePlaceholderArnAttribute as wi, collectPublishedOutputNames as wn, DagBuilder as wo, customResourceResponseExpirationWarning as wr, STATE_SOURCED_READBACK_RULES as ws, revertedNestedRowIds as wt, withApiLimit as x, refuseMalformedResourceEntriesForDeploy as xa, dockerSpawnEnvWithSensitive as xc, keepsSecretReferenceToken as xi, resolveAssemblyPath as xl, isWholeDynamicReferenceValue as xn, canonicalLambdaFunctionName as xo, withPrintingSecrets as xr, wholeStringLeavesOf as xs, nestedChildStackName as xt, isAccessDeniedError as y, refuseMalformedResourceAttributesForOrphan as ya, describeDockerExecFailure as yc, carriesFetchableDynamicReference as yi, displayAssemblyPath as yl, exportNameNoEchoParameters as yn, describeTypeWithThrottleRetry as yo, isCustomResourceType as yr, recordNoEchoParameterFreshValue as ys, dropSettledNestedJournals as yt, DynamoDBGlobalTableProvider as z, repairMalformedResourcesForReadOnly as za, getDefaultStateBucketName as zc, hasReadableOrphans as zi, ATOMIC_FINAL_SNAPSHOT_TYPES as zn, liveMatchesUnresolvedTokenFrame as zo, observeThenDisableInstanceApiTermination as zr, acceptedCreateOnlyDropsOf as zs, destroyStackRecordsView as zt };
44387
- //# sourceMappingURL=deploy-engine-CJTG3tft.js.map
45442
+ export { isTruthyCfnBoolean as $, isStatefulRecreateTargetForReplace as $a, CFN_TEMPLATE_BODY_LIMIT as $c, malformedOrphansRefusalMessage as $i, ledgerForStack as $n, markSameGenerationBag as $o, sendableAssumeRoleCommand as $r, isSensitiveAttributeName as $s, seedsDeleteFirstGuard as $t, noEchoComparisonForTemplate as A, refuseMalformedResourcesForDeploy as Aa, redactedDockerCause as Ac, declaresNoEcho as Ai, journaledOrphanPrintingBag as An, maskWholeValue as Ao, deleteIndeterminateGuards as Ar, isLockInfoExpired as As, dropFailedHint as At, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as B, unpreviewableOrphanRecords as Ba, getDefaultStateBucketName as Bc, hasReadableOutputs as Bi, PRE_DELETE_SNAPSHOT_TYPES as Bn, carryLogOnlyValues as Bo, reDisableInstanceApiTermination as Br, acceptedCreateOnlyDropsOf as Bs, getStackRecords as Bt, recordRetainedForReadoption as C, refuseMalformedResourceEntriesForImport as Ca, finchSecretArgvRefusal as Cc, cfnRefValueFromPhysicalId as Ci, clearBucketRegionCache as Cl, collectDeclaredOutputNames as Cn, sameLambdaFunctionAddress as Co, applyCustomResourceResponseExpiration as Cr, STATE_SOURCED_BASELINE_RULES as Cs, revertNestedChildFromJournal as Ct, withResourceDeadline as D, refuseMalformedResourcePropertiesForDrift as Da, isMalformedEnvKey as Dc, withSharedDrainBudget as Di, DEFAULT_RESOURCE_TIMEOUT_MS as Dn, isMarkedCoordinate as Do, unchangedBehindSecretReference as Dr, WHOLE_DYNAMIC_REFERENCE_PATTERN as Ds, getCurrentNestedStackContext as Dt, serviceTokenBlockingReason as E, refuseMalformedResourcePropertiesForDestroy as Ea, isDockerClientEnvKey as Ec, parseWebACLArn as Ei, bindingSkippedOutputs as En, canonicalCoordinates as Eo, slowCcOperationTimeoutMs as Er, TEMPLATE_SOURCED_RULES as Es, collectNestedChildUnaddressed as Et, PROTECTION_PROPERTY_BY_TYPE as F, repairMalformedOrphansForReadOnly as Fa, stripControlChars as Fc, UNREADABLE_RESOURCES_MAP_ROW as Fi, secretNamedRecordNeedles as Fn, passedNoEchoParametersOf as Fo, markWaitAbandoned as Fr, applyCrossPrefixScan as Fs, sameJournaledOrphans as Ft, resolveDynamoDbDeleteBudgetMs as G, findSilentDropProperties as Ga, resolveCaptureObservedState as Gc, malformedExportNamesWarning as Gi, isFinalSnapshotError as Gn, printingCorpusOf as Go, poisonRenderedSpellingsCollidingIn as Gr, hasUnverifiableParameterRefusal as Gs, isJournaledOrphan as Gt, compensateRemovedDeletionProtection as H, unreadableResourceEntries as Ha, loadCdkJson as Hc, isReadableOrphanRecord as Hi, ccRoutedFinalSnapshotError as Hn, hasMaskableValues as Ho, DiffCalculator as Hr, exportNamesCarriedFrom as Hs, removeProtectionTypeList as Ht, isProtectionValueActive as I, repairMalformedOutputsForReadOnly as Ia, AssetManifestLoader as Ic, accountArgs as Ii, stateSecretNameNeedles as In, readbackPathFor as Io, disableInstanceApiTermination as Ir, crossPrefixDeniedWarning as Is, replayFailedOperations as It, deleteTableWithIndexBusyRetry as J, NO_CC_HANDLERS_REASON as Ja, resolveStateBucketWithDefaultAndSource as Jc, malformedLocalResourceEntriesWarning as Ji, maskingRetryLogger as Jn, shareLogOnlyValues as Jo, applyRoleArnIfSet as Jr, isReadableBag as Js, planRollback as Jt, DELETE_INDEX_WAIT_PROCEED_NOTE as K, unwrittenCreateOnlyReplacement as Ka, resolveSkipPrefix as Kc, malformedExportSourceWarning as Ki, refusesFinalSnapshot as Kn, recordLogOnlyParameterValue as Ko, producerLookupOver as Kr, importableOutputKeys as Ks, isReplacementOrphan as Kt, perType as L, repairMalformedResourceEntriesForReadOnly as La, getDockerImageBySourceHash as Lc, deployRefusesOrphanRowsReason as Li, storedSecretNameNeedles as Ln, readsNoEchoSource as Lo, ec2InstanceProtectionSite as Lr, isAccessDenied$1 as Ls, replayRollback as Lt, noEchoParameterNamesOf as M, refuseMalformedResourcesForExport as Ma, runDockerStreaming as Mc, STATE_REGION_DIVERGED as Mi, orphanRecordsPrintingBag as Mn, noEchoCoordinatesOf as Mo, deleteSkipReason as Mr, rebuildClientForBucketRegion as Ms, journaledOrphanLines as Mt, recordedProtectionEvidence as N, refuseMalformedState as Na, warnFinchArgvExposure as Nc, STATE_RESOURCES_MALFORMED as Ni, secretNamePrintingBag as Nn, noEchoLeavesOf as No, withIndeterminateGuard as Nr, CrossPrefixReadError as Ns, loadJournaledOrphans as Nt, diffSecurity as O, refuseMalformedResourcePropertiesForExport as Oa, partitionSensitiveEnv as Oc, parameterInputsFor as Oi, DEFAULT_RESOURCE_WARN_AFTER_MS as On, maskAtCoordinates as Oo, RollbackInlinePolicyWriters as Or, isSingleDynamicReferenceToken as Os, withNestedStackContext as Ot, recordedProtectionNote as P, repairMalformedOrphanRecordsForReadOnly as Pa, escapeRegExp$3 as Pc, UNREADABLE_ORPHANS_CONTAINER_ROW as Pi, secretNamePrintingBags as Pn, noEchoOutputsComparison as Po, isWaitAbandonedError as Pr, CrossPrefixScanCache as Ps, makeForeignHolderScan as Pt, hasCdkAutoDeleteTag as Q, MULTI_REGION_RECREATE_BLOCKED_TYPES as Qa, ssmResolvedValueType as Qc, malformedOrphanRowsKeptWarning as Qi, earliestDefined as Qn, maskSecretsInText as Qo, isIamRoleArn as Qr, AssetPublisher as Qs, resolveReplacementOldType as Qt, readProtection as R, repairMalformedResourcePropertiesForReadOnly as Ra, Synthesizer as Rc, displayLogicalId as Ri, extractDeploymentEventError as Rn, valueAtCoordinate as Ro, isTerminationProtectionPropagationError as Rr, isNotImplemented as Rs, awaitInFlightSibling as Rt, keptForReadoption as S, refuseMalformedResourceEntriesForDestroy as Sa, dockerSpawnEnvWithSensitive as Sc, AWS_NO_VALUE as Si, resolveAssemblyPath as Sl, noEchoParameterValueSeed as Sn, lambdaFunctionNameForMask as So, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Sr, wholeStringLeavesOf as Ss, recordDisplacedSkips as St, findServiceTokenRefusals as T, refuseMalformedResourceEntriesForOrphan as Ta, getDockerCmd as Tc, refStateLookupFromResource as Ti, isExportAliasCollision as Tn, TemplateParser as To, CloudControlProvider as Tr, STATE_SOURCED_READBACK_RULES as Ts, withNestedRevertRun as Tt, deleteBudgetKey as U, withheldAccountClause as Ua, resolveApp as Uc, isReadableResourceEntry as Ui, createPreDeleteFinalSnapshot as Un, literalSplitDelimitersOf as Uo, INTRINSIC_KEYS as Ur, hasReadableExportSet as Us, recordAfterRollbackUpdate as Ut, beginDeleteWait as V, unreadableOrphanRecords as Va, getLegacyStateBucketName as Vc, hasReadableResources as Vi, buildFinalSnapshotIdentifier as Vn, createUnionSecretMasker as Vo, reEnableInstanceApiTermination as Vr, describeRegionValueKind as Vs, withStackRecords as Vt, resolveDynamoDbDeleteBudgetClock as W, findActionableSilentDrops as Wa, resolveAutoAssetStorage as Wc, malformedDriftResourcePropertiesWarning as Wi, effectiveDeletionPolicy as Wn, logOnlyValueCount as Wo, IntrinsicFunctionResolver as Wr, hasReasonlessBaselineRefusal as Ws, demoteSupersededOrphans as Wt, ECR_AUTO_DELETE_IMAGES_TAG as X, findReplacedReadersOfRecreateTargets as Xa, stateBucketExistenceConfirmed as Xc, malformedOrphanRecordsRefusalMessage as Xi, findDestructiveChanges as Xn, errorCauseChain as Xo, assertSendableRoleArn as Xr, orphansCarriedFrom as Xs, recordUnderIdIsNotOwn as Xt, waitForIndexesSettled as Y, hasNoCloudControlHandlers as Ya, resolveUseCdkBootstrapAssets as Yc, malformedLocalResourcesWarning as Yi, constructPathOf as Yn, createSecretMasker as Yo, assertFlagRoleArn as Yr, orphansAfterRollback as Ys, recheckFailedPlan as Yt, S3_AUTO_DELETE_OBJECTS_TAG as Z, shownType as Za, warnDeprecatedNoPrefixCliFlag as Zc, malformedOrphanRecordsWarning as Zi, formatDestructiveChange as Zn, maskSecretsInError as Zo, explicitRoleArnOrThrow as Zr, shouldRetainResource as Zs, replacementNeverSwapped as Zt, makeCanonicalizePropertiesFn as _, refuseMalformedOutputs as _a, buildDockerImage as _c, isImpossibleEmptyStoredAttribute as _i, ownValue as _l, secretSafeKeyDisplay as _n, prefetchCreateOnlyPropertyPaths as _o, TemplateNoEchoReresolver as _r, recordMaskOnlyValue as _s, displacedOpClause as _t, findNestedTemplateTreeDefect as a, malformedResourcePropertiesWarning as aa, rewriteTemplateAssetReferences as ac, s3BucketArn as ai, decodeListingKey as al, isRedactedRecordedValue as an, toCfnInteger as ao, planTagDiff as ar, dynamicReferenceTokens as as, cyan as at, lookupEachName as b, refuseMalformedResourceEntries as ba, describeDockerExecFailure as bc, isNamelessDynamicReferenceError as bi, displayAssemblyPath as bl, exportNameSecretExposure as bn, withRetry as bo, getCurrentResourceSecrets as br, recordNoEchoParameterFreshValue as bs, getNestedRevertRun as bt, renderNestedTemplateTreeDefect as c, malformedStateRefusalMessage as ca, assertAssetBucketRegion as cc, s3BucketRegionalDomainName as ci, canonicalizeRegion as cl, updatePartialMessage as cn, coerceCfnInteger as co, tagMapAsList as cr, identityKeyFor as cs, red as ct, conditionInputsFrom as d, refuseMalformedNestedChildOutputs as da, isCrossRegionRedirect as dc, producerRegionsFromState as di, StageLoadError as dl, DeploymentEventsStore as dn, configStringRefusal as do, stringifyIfAssigned as dr, recoverMaskedOutput as ds, namesAnyDeclaredParameter as dt, malformedOrphansWarning as ea, stringifyValue as ec, AWS_CREDENTIAL_ENV_KEYS as ei, CFN_TEMPLATE_URL_LIMIT as el, orphanDeleteNeedsIdentity as en, isStatefulRecreateTargetSync as eo, reserveStackCreateToken as er, redactSecretsForState as es, getPriorAttempts as et, parentSuppliedValues as f, refuseMalformedOrphanRecords as fa, parseBootstrapMarker as fc, regionLessSecretName as fi, processStackMessages as fl, WITHHELD_NAME_DISPLAY as fn, readConfigString as fo, CC_BROKEN_REASON as fr, physicalNameCopiesOf as fs, reachableDivergentParameters as ft, mergeNoChangeOutputs as g, refuseMalformedOrphansForOrphan as ga, buildDenyExternalAccessPolicy as gc, getAccountInfo as gi, nullPrototypeRecord as gl, secretBearingStateKeyWarning as gn, requireConfigString as go, wouldReturnToSdkProvider as gr, provenPublicValue as gs, NESTED_PENDING_PARENT_REASON as gt, keptWholeReasonText as h, refuseMalformedOrphansForDestroy as ha, validateContainerRepoName as hc, parameterTypeMayLoseSecretIdentity as hi, hasPlainPrototype$1 as hl, secretBearing as hn, requireConfigObject as ho, isCustomResource as hr, carriesSecretMask as hs, planOrphanAdoption as ht, childTemplateLoader as i, malformedResourceEntriesWarning as ia, loadPublishableAssetManifest as ic, isSettledInstanceState as ii, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as il, REDACTED_DELETE_ADDRESS_SKIP_REASON as in, isWarmThroughputDecrease as io, DBPROXY_TAG_OPTIONS as ir, DYNAMIC_REFERENCE_TOKEN_SCAN as is, bold as it, noEchoExactEchoLeavesOf as j, refuseMalformedResourcesForDestroy as ja, runDockerForeground as jc, JSON_LISTING_HOLE_VALUE as ji, maskEventTextWithBoundBags as jn, maskedLeafCoordinatesOf as jo, deleteLeftInPlace as jr, S3StateBackend as js, isHandledOrphan as jt, noEchoAttributeNamesOf as k, refuseMalformedResourcePropertiesForOrphan as ka, redactDockerArgvValues as kc, passedParameterClassesOf as ki, completedReplayEntries as kn, maskReadbackAtCoordinates as ko, UNSPECIFIED_SKIP_REASON as kr, LockManager as ks, deleteJournaledOrphans as kt, templateIdentity as l, previewableOrphanRecords as la, ensureAssetStorage as lc, s3BucketWebsiteUrl as li, derivePartitionAndUrlSuffix as ll, updatePartialReason as ln, configBooleanRefusal as lo, tagPlanWarning as lr, inheritNestedStackParameterAssociations as ls, yellow as lt, isSecretBearingReferenceString as m, refuseMalformedOrphans as ma, validateAssetBucketName as mc, isUnboundTemplateParameter as mi, hasOwnKey as ml, exportAliasCollisionScrubWarning as mn, requireConfigArray as mo, ccBrokenReason as mr, splitGetAttStringForm as ms, makeSiblingClaimReader as mt, IMPLICIT_DELETE_DEPENDENCIES as n, malformedOutputsWarning as na, buildAssetRedirectMap as nc, callerEnvCredentials as ni, findLargeInlineResources as nl, getCurrentProducerRegions as nn, WARM_THROUGHPUT_MEMBERS as no, acquireIdempotencyToken as nr, withPhysicalNameCopies as ns, formatResourceLine as nt, isAbsoluteAssetPath as o, malformedResourcesWarning as oa, AssetModeResolver as oc, s3BucketDomainName as oi, expectedOwnerParam as ol, redactedDeleteAddressFields as on, toFiniteNumber as oo, readTagList as or, isUncertifiedBaselineMaskPosition as os, gray as ot, readRecordedConditionVerdicts as p, refuseMalformedOrphanRecordsForDestroy as pa, readBootstrapMarkerBody as pc, coerceParameterTypedValue as pi, defineOwnKey as pl, displayTextOrWithheld as pn, replayWarn as po, ProviderRegistry as pr, recordPhysicalNameCopy as ps, resourcesNamingDeclaredParameter as pt, INDEX_SETTLE_POLL_INTERVAL_MS as q, withoutSilentDropProperties as qa, resolveStateBucketWithDefault as qc, malformedLocalOutputsWarning as qi, unsupportedFinalSnapshotError as qn, recordLogOnlyValue as qo, refuseUnreadableCdkCrossAccountRefs as qr, importableOutputs as qs, planFailedOps as qt, computeImplicitDeleteEdges as r, malformedRenderedContainersWarning as ra, createAssetRedirectResolver as rc, envCredentialsAreAssumedRole as ri, uploadCfnTemplate as rl, inheritProducerRegions as rn, coerceWarmThroughput as ro, DBPROXY_TAGS_WHAT as rr, withoutPhysicalNameCopies as rs, createReadOnlyAttributeHealerFactory as rt, listNestedTemplateRows as s, malformedScrubResourceEntriesRefusalMessage as sa, BOOTSTRAP_MARKER_PREFIX as sc, s3BucketDualStackDomainName as si, PARTITION_TABLE as sl, redactedDeleteAddressSkip as sn, coerceCfnBoolean as so, refuseMalformedDesiredTags as sr, pathCrossesDottedKey as ss, green as st, DeployEngine as t, malformedOutputsRefusalMessage as ta, WorkGraph as tc, applyCallerIdentityCredentials as ti, MIGRATE_TMP_PREFIX as tl, findNestedStackTypeChanges as tn, renderStatefulReason as to, withCreateTokenLedger as tr, scrubResourceRecord as ts, markRefusedBeforeApplying as tt, conditionFingerprint as u, refuseDivergentRecordRegionForDestroy as ua, getBootstrapMarkerKey as uc, classifyReplaySecretRegion as ui, AssemblyReader as ul, DeploymentEventsReader as un, configIntegerRefusal as uo, definedAttributes as ur, recordNestedStackParameterExpressions as us, computeParameterTaint as ut, chunks as v, refuseMalformedOutputsForDestroy as va, resolveDockerContextDirectory as vc, carriesDynamicReference as vi, absoluteAssemblyPathEscape as vl, carriedExportAliasExposure as vn, templateResourceTypes as vo, readsNoEchoDeleteValues as vr, recordMaskOnlyValuesIn as vs, displacedPhysicalIdShown as vt, deferredServiceTokenWarning as w, refuseMalformedResourceEntriesForImportSave as wa, formatDockerLoginError as wc, isStalePlaceholderArnAttribute as wi, resolveBucketRegion as wl, collectPublishedOutputNames as wn, DagBuilder as wo, customResourceResponseExpirationWarning as wr, STATE_SOURCED_CROSS_GENERATION_RULES as ws, revertedNestedRowIds as wt, withApiLimit as x, refuseMalformedResourceEntriesForDeploy as xa, describeDockerFailure as xc, keepsSecretReferenceToken as xi, renderAssemblyPathEscape as xl, isWholeDynamicReferenceValue as xn, canonicalLambdaFunctionName as xo, withPrintingSecrets as xr, recordProvenPublicExpression as xs, nestedChildStackName as xt, isAccessDeniedError as y, refuseMalformedResourceAttributesForOrphan as ya, describeDockerCapturedOutput as yc, carriesFetchableDynamicReference as yi, describeFileReadFailure as yl, exportNameNoEchoParameters as yn, describeTypeWithThrottleRetry as yo, isCustomResourceType as yr, recordNoEchoAttributeValues as ys, dropSettledNestedJournals as yt, DynamoDBGlobalTableProvider as z, repairMalformedResourcesForReadOnly as za, synthesisStatusMessage as zc, hasReadableOrphans as zi, ATOMIC_FINAL_SNAPSHOT_TYPES as zn, liveMatchesUnresolvedTokenFrame as zo, observeThenDisableInstanceApiTermination as zr, splitImportedOps as zs, destroyStackRecordsView as zt };
45443
+ //# sourceMappingURL=deploy-engine-A-Ys_mhE.js.map