@go-to-k/cdkd 0.283.18 → 0.283.20

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.
@@ -5557,7 +5557,7 @@ var AssetModeResolver = class {
5557
5557
  * non-`u` pattern. `-` is deliberately absent: it is only special INSIDE a
5558
5558
  * character class, and no caller embeds into one.
5559
5559
  */
5560
- function escapeRegExp(value) {
5560
+ function escapeRegExp$1(value) {
5561
5561
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5562
5562
  }
5563
5563
 
@@ -5582,11 +5582,11 @@ function flattenAssetPlaceholders(value, accountId, region, partition = "aws") {
5582
5582
  * scope and left verbatim.
5583
5583
  */
5584
5584
  function isDefaultBootstrapBucketName(name, accountId, region) {
5585
- return new RegExp(`^cdk-[a-z0-9]+-assets-${accountId}-${escapeRegExp(region)}$`).test(name);
5585
+ return new RegExp(`^cdk-[a-z0-9]+-assets-${accountId}-${escapeRegExp$1(region)}$`).test(name);
5586
5586
  }
5587
5587
  /** §8 scope rule, container-image leg (`cdk-<qualifier>-container-assets-…`). */
5588
5588
  function isDefaultBootstrapRepoName(name, accountId, region) {
5589
- return new RegExp(`^cdk-[a-z0-9]+-container-assets-${accountId}-${escapeRegExp(region)}$`).test(name);
5589
+ return new RegExp(`^cdk-[a-z0-9]+-container-assets-${accountId}-${escapeRegExp$1(region)}$`).test(name);
5590
5590
  }
5591
5591
  /**
5592
5592
  * Build the §6 asset-location mapping table from a stack's asset manifest.
@@ -5613,7 +5613,7 @@ function buildAssetRedirectMap(manifest, marker, accountId, region, partition =
5613
5613
  const addForms = (rawName, flattened, target) => {
5614
5614
  sources.set(flattened, target);
5615
5615
  if (rawName !== flattened) sources.set(rawName, target);
5616
- const suffixRe = new RegExp(`-${accountId}-${escapeRegExp(region)}$`);
5616
+ const suffixRe = new RegExp(`-${accountId}-${escapeRegExp$1(region)}$`);
5617
5617
  for (const suffix of [
5618
5618
  "-${AWS::AccountId}-${AWS::Region}",
5619
5619
  `-\${AWS::AccountId}-${region}`,
@@ -5669,7 +5669,7 @@ function buildAssetRedirectMap(manifest, marker, accountId, region, partition =
5669
5669
  * with the deploy account+region bootstrap shape — accepted as pathological.
5670
5670
  */
5671
5671
  function buildBoundaryRegex(source) {
5672
- return new RegExp(`(?<![A-Za-z0-9_.-])${escapeRegExp(source)}(?![A-Za-z0-9_-])`, "g");
5672
+ return new RegExp(`(?<![A-Za-z0-9_.-])${escapeRegExp$1(source)}(?![A-Za-z0-9_-])`, "g");
5673
5673
  }
5674
5674
  function rewriteString(value, map, counter) {
5675
5675
  let result = value;
@@ -9816,6 +9816,95 @@ function s3BucketWebsiteUrl(bucketName, region) {
9816
9816
  return `http://${bucketName}.s3-website${S3_WEBSITE_ENDPOINT_LEGACY_DASH_REGIONS.has(folded) ? "-" : "."}${folded}.${urlSuffix}`;
9817
9817
  }
9818
9818
 
9819
+ //#endregion
9820
+ //#region src/deployment/secret-redaction.ts
9821
+ /** Fixed marker substituted for a secret value in log / error output. */
9822
+ const SECRET_MASK = "***";
9823
+ /**
9824
+ * A resolved secret value shorter than this is NOT used as a redaction needle:
9825
+ * a 1-2 character plaintext (e.g. a secret whose JSON key holds `"0"`) would
9826
+ * match incidental characters everywhere and mangle unrelated state. Such a
9827
+ * value is still masked at the exact leaf where it was the WHOLE value (handled
9828
+ * by the caller), but is not scanned for as a substring. Real secrets are far
9829
+ * longer than this, so the bound only excludes degenerate cases.
9830
+ */
9831
+ const MIN_NEEDLE_LENGTH = 4;
9832
+ function escapeRegExp(value) {
9833
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9834
+ }
9835
+ /**
9836
+ * Build a single alternation regex matching any recorded secret value, longest
9837
+ * first so an overlapping shorter secret cannot pre-empt a longer match. Returns
9838
+ * `undefined` when there is nothing worth scanning for.
9839
+ */
9840
+ function buildNeedleRegex(values) {
9841
+ const needles = Array.from(new Set(values)).filter((v) => v.length >= MIN_NEEDLE_LENGTH).sort((a, b) => b.length - a.length);
9842
+ if (needles.length === 0) return void 0;
9843
+ return new RegExp(needles.map(escapeRegExp).join("|"), "g");
9844
+ }
9845
+ /**
9846
+ * Deep-clone `bag`, replacing every occurrence of a recorded secret value with
9847
+ * the unresolved `{{resolve:...}}` expression it came from. A string whose WHOLE
9848
+ * value equals a secret is replaced by that secret's expression exactly; a
9849
+ * string that merely CONTAINS one (an `Fn::Join` / `Fn::Sub` result) has the
9850
+ * secret substring replaced in place. Returns the input by identity when there
9851
+ * is nothing to redact, so callers can persist the original object unchanged in
9852
+ * the common no-secret case.
9853
+ */
9854
+ function redactSecretsForState(bag, secrets) {
9855
+ if (secrets.size === 0) return bag;
9856
+ const regex = buildNeedleRegex(secrets.keys());
9857
+ const wholeValueExpr = (s) => s === "" ? void 0 : secrets.get(s);
9858
+ const walk = (value) => {
9859
+ if (typeof value === "string") {
9860
+ const whole = wholeValueExpr(value);
9861
+ if (whole !== void 0) return whole;
9862
+ if (!regex) return value;
9863
+ regex.lastIndex = 0;
9864
+ if (!regex.test(value)) return value;
9865
+ regex.lastIndex = 0;
9866
+ return value.replace(regex, (m) => secrets.get(m) ?? "***");
9867
+ }
9868
+ if (Array.isArray(value)) return value.map(walk);
9869
+ if (value !== null && typeof value === "object") {
9870
+ const out = {};
9871
+ for (const [k, v] of Object.entries(value)) out[k] = walk(v);
9872
+ return out;
9873
+ }
9874
+ return value;
9875
+ };
9876
+ return walk(bag);
9877
+ }
9878
+ /**
9879
+ * Redact resolved secret plaintext out of one resource state record's
9880
+ * `properties` / `attributes` / `observedProperties`, replacing each secret
9881
+ * value with its unresolved expression. Returns a NEW record when any field
9882
+ * changed, or the input by identity when there are no secrets — so callers can
9883
+ * detect a no-op cheaply. Shared by the deploy engine's save choke point and
9884
+ * the `cdkd scrub` command so both scrub the same three fields identically.
9885
+ */
9886
+ function scrubResourceRecord(record, secrets) {
9887
+ if (secrets.size === 0) return record;
9888
+ const next = { ...record };
9889
+ next.properties = redactSecretsForState(record.properties, secrets);
9890
+ if (record.attributes) next.attributes = redactSecretsForState(record.attributes, secrets);
9891
+ if (record.observedProperties) next.observedProperties = redactSecretsForState(record.observedProperties, secrets);
9892
+ return next;
9893
+ }
9894
+ /**
9895
+ * Replace every recorded secret value inside `text` with {@link SECRET_MASK}.
9896
+ * Used on log lines and error messages where a resolved secret could otherwise
9897
+ * be echoed. Whole-value and embedded matches are both masked. Returns `text`
9898
+ * unchanged when there is nothing to mask.
9899
+ */
9900
+ function maskSecretsInText(text, secrets) {
9901
+ if (secrets.size === 0) return text;
9902
+ if (text !== "" && secrets.has(text)) return "***";
9903
+ const regex = buildNeedleRegex(secrets.keys());
9904
+ if (!regex) return text;
9905
+ return text.replace(regex, "***");
9906
+ }
9907
+
9819
9908
  //#endregion
9820
9909
  //#region src/provisioning/config-shape.ts
9821
9910
  /**
@@ -11770,7 +11859,7 @@ var IntrinsicFunctionResolver = class {
11770
11859
  */
11771
11860
  async resolveValue(value, context) {
11772
11861
  if (typeof value !== "object" || value === null) {
11773
- if (typeof value === "string" && value.includes("{{resolve:")) return await this.resolveDynamicReferences(value);
11862
+ if (typeof value === "string" && value.includes("{{resolve:")) return await this.resolveDynamicReferences(value, context);
11774
11863
  return value;
11775
11864
  }
11776
11865
  if (Array.isArray(value)) return (await Promise.all(value.map((v) => this.resolveValue(v, context)))).filter((v) => v !== AWS_NO_VALUE);
@@ -12373,8 +12462,8 @@ var IntrinsicFunctionResolver = class {
12373
12462
  const resolved = await this.resolveValue(v, context);
12374
12463
  return String(resolved);
12375
12464
  }))).join(delimiter);
12376
- if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result);
12377
- this.logger.debug(`Resolved Fn::Join: ${result}`);
12465
+ if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result, context);
12466
+ this.logger.debug(`Resolved Fn::Join: ${this.maskSecretsForLog(result, context)}`);
12378
12467
  return result;
12379
12468
  }
12380
12469
  /**
@@ -12459,8 +12548,8 @@ var IntrinsicFunctionResolver = class {
12459
12548
  const entry = replacements[cursor++];
12460
12549
  return entry ? entry.replacement : whole;
12461
12550
  });
12462
- if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result);
12463
- this.logger.debug(`Resolved Fn::Sub: ${result}`);
12551
+ if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result, context);
12552
+ this.logger.debug(`Resolved Fn::Sub: ${this.maskSecretsForLog(result, context)}`);
12464
12553
  return result;
12465
12554
  }
12466
12555
  /**
@@ -12478,7 +12567,7 @@ var IntrinsicFunctionResolver = class {
12478
12567
  return `{{Fn::Select:${index}:OutOfBounds}}`;
12479
12568
  }
12480
12569
  const result = resolvedList[index];
12481
- this.logger.debug(`Resolved Fn::Select: index ${index} -> ${JSON.stringify(result)}`);
12570
+ this.logger.debug(`Resolved Fn::Select: index ${index} -> ${this.maskSecretsForLog(JSON.stringify(result), context)}`);
12482
12571
  return result;
12483
12572
  }
12484
12573
  /**
@@ -12620,7 +12709,7 @@ var IntrinsicFunctionResolver = class {
12620
12709
  throw markNonRetryable(new IntrinsicResolutionRefusalError(`Fn::Split: the value to split${sourceClause} must be a string, got ${resolvedValue === null ? "null" : typeof resolvedValue}. Fn::Split accepts only a string; check the value or the intrinsic that produced it.`));
12621
12710
  }
12622
12711
  const result = resolvedValue.split(delimiter);
12623
- this.logger.debug(`Resolved Fn::Split: split by "${delimiter}" -> ${JSON.stringify(result)}`);
12712
+ this.logger.debug(`Resolved Fn::Split: split by "${delimiter}" -> ${this.maskSecretsForLog(JSON.stringify(result), context)}`);
12624
12713
  return result;
12625
12714
  }
12626
12715
  /**
@@ -13128,7 +13217,7 @@ var IntrinsicFunctionResolver = class {
13128
13217
  const resolvedValue = await this.resolveValue(value, context);
13129
13218
  if (typeof resolvedValue !== "string") throw new Error(`Fn::Base64: value must resolve to a string, got ${typeof resolvedValue}`);
13130
13219
  const result = Buffer.from(resolvedValue).toString("base64");
13131
- this.logger.debug(`Resolved Fn::Base64: ${resolvedValue} -> ${result}`);
13220
+ this.logger.debug(`Resolved Fn::Base64: ${this.maskSecretsForLog(resolvedValue, context)} -> ${this.maskSecretsForLog(result, context)}`);
13132
13221
  return result;
13133
13222
  }
13134
13223
  /**
@@ -13195,7 +13284,16 @@ var IntrinsicFunctionResolver = class {
13195
13284
  *
13196
13285
  * Results are cached to avoid repeated API calls.
13197
13286
  */
13198
- async resolveDynamicReferences(value) {
13287
+ /**
13288
+ * Mask any resolved secret value out of a string bound for a log line, using
13289
+ * the secrets recorded on the resolution pass (GHSA fix). No-op when the pass
13290
+ * recorded no secrets.
13291
+ */
13292
+ maskSecretsForLog(text, context) {
13293
+ const secrets = context?.recordedSecretValues;
13294
+ return secrets ? maskSecretsInText(text, secrets) : text;
13295
+ }
13296
+ async resolveDynamicReferences(value, context) {
13199
13297
  const pattern = /\{\{resolve:([^}]+)\}\}/g;
13200
13298
  let result = value;
13201
13299
  let match;
@@ -13205,12 +13303,16 @@ var IntrinsicFunctionResolver = class {
13205
13303
  inner: match[1]
13206
13304
  });
13207
13305
  for (const { fullMatch, inner } of matches) {
13306
+ const service = inner.split(":")[0];
13307
+ const isSecret = service === "secretsmanager";
13308
+ if (isSecret && context?.skipDynamicReferences) continue;
13208
13309
  if (fullMatch in cachedDynamicReferences) {
13209
- result = result.replace(fullMatch, cachedDynamicReferences[fullMatch]);
13310
+ const cached = cachedDynamicReferences[fullMatch];
13311
+ if (isSecret && cached) context?.recordedSecretValues?.set(cached, fullMatch);
13312
+ result = result.replace(fullMatch, cached);
13210
13313
  continue;
13211
13314
  }
13212
13315
  const parts = inner.split(":");
13213
- const service = parts[0];
13214
13316
  let resolved;
13215
13317
  if (service === "secretsmanager") resolved = await this.resolveSecretsManagerReference(inner);
13216
13318
  else if (service === "ssm") resolved = await this.resolveSSMReference(parts);
@@ -13219,6 +13321,7 @@ var IntrinsicFunctionResolver = class {
13219
13321
  continue;
13220
13322
  }
13221
13323
  cachedDynamicReferences[fullMatch] = resolved;
13324
+ if (isSecret && resolved) context?.recordedSecretValues?.set(resolved, fullMatch);
13222
13325
  result = result.replace(fullMatch, resolved);
13223
13326
  }
13224
13327
  return result;
@@ -14182,7 +14285,13 @@ var CloudControlProvider = class {
14182
14285
  };
14183
14286
  }
14184
14287
  }
14185
- this.logger.debug(`Generated ${patch.length} patch operations for ${logicalId}: ${JSON.stringify(patch)}`);
14288
+ this.logger.debug(`Generated ${patch.length} patch operations for ${logicalId}: ${JSON.stringify(patch.map((op) => {
14289
+ const anyOp = op;
14290
+ return {
14291
+ op: anyOp.op,
14292
+ path: anyOp.path
14293
+ };
14294
+ }))}`);
14186
14295
  const updateResponse = await this.cloudControlClient.send(new UpdateResourceCommand({
14187
14296
  TypeName: resourceType,
14188
14297
  Identifier: physicalId,
@@ -14212,7 +14321,7 @@ var CloudControlProvider = class {
14212
14321
  if (context?.finalSnapshotIdentifier !== void 0) throw new ProvisioningError(`${logicalId} (${resourceType}) requires a final snapshot (DeletionPolicy: Snapshot), but the Cloud Control API delete route has no final-snapshot parameter. Re-run with --skip-final-snapshot after snapshotting manually, or retain the resource.`, resourceType, logicalId, physicalId);
14213
14322
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
14214
14323
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
14215
- const { ASGProvider } = await import("./asg-provider-D8Ln3-ij.js").then((n) => n.n);
14324
+ const { ASGProvider } = await import("./asg-provider-k-TEX_Ej.js").then((n) => n.n);
14216
14325
  return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
14217
14326
  }
14218
14327
  const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
@@ -20765,6 +20874,61 @@ async function replayRollback(operations, stateResources, stackName, ctx, option
20765
20874
  * just announced and leaving the record describing something AWS does not
20766
20875
  * hold.
20767
20876
  */
20877
+ /**
20878
+ * Re-resolve dynamic-reference SECRET expressions
20879
+ * (`{{resolve:secretsmanager:...}}`) in a property bag being REPLAYED to a
20880
+ * provider during rollback (GHSA fix, issue #1899 review).
20881
+ *
20882
+ * The rollback journal — and the state record the replay writes — store the
20883
+ * redacted EXPRESSION, never the plaintext. But a `provider.update()` /
20884
+ * `create()` / `delete()` call must receive the concrete secret value the
20885
+ * reference points at, exactly as the forward deploy did; replaying the literal
20886
+ * `{{resolve:...}}` string would corrupt the resource (e.g. a Lambda env var or
20887
+ * Cognito `client_secret`). Rollback is synth-free, so re-resolve straight from
20888
+ * the expression string here.
20889
+ *
20890
+ * Records each `plaintext -> expression` into `secrets` so the caller can redact
20891
+ * the persisted state record back to the expression — the same
20892
+ * resolve-for-provider + redact-for-state split the deploy engine applies at its
20893
+ * save choke point. A bag with no `{{resolve:...}}` string resolves to a
20894
+ * structural copy of itself (secrets stays empty), so the non-secret rollback
20895
+ * path is behaviourally unchanged. Only secretsmanager references are recorded
20896
+ * (plain `ssm` is public config, stored resolved — it never appears as an
20897
+ * expression in the journal), matching the resolver's own `isSecret` gate.
20898
+ */
20899
+ async function resolveReplayProps(props, resolver, secrets) {
20900
+ if (props === void 0) return void 0;
20901
+ const ctx = {
20902
+ template: { Resources: {} },
20903
+ resources: {},
20904
+ recordedSecretValues: secrets
20905
+ };
20906
+ const walk = async (v) => {
20907
+ if (typeof v === "string") return v.includes("{{resolve:") ? await resolver.resolveDynamicReferences(v, ctx) : v;
20908
+ if (Array.isArray(v)) {
20909
+ const out = new Array(v.length);
20910
+ for (let i = 0; i < v.length; i++) out[i] = await walk(v[i]);
20911
+ return out;
20912
+ }
20913
+ if (v !== null && typeof v === "object") {
20914
+ const out = {};
20915
+ for (const [k, val] of Object.entries(v)) out[k] = await walk(val);
20916
+ return out;
20917
+ }
20918
+ return v;
20919
+ };
20920
+ return await walk(props);
20921
+ }
20922
+ /**
20923
+ * Redact resolved secret plaintext back out of a post-rollback state record
20924
+ * (GHSA fix). The record's `properties` may be the provider's
20925
+ * `effectiveProperties`, which can echo the value we just resolved for the
20926
+ * provider call — so scrub it with the same per-op secrets map before it is
20927
+ * persisted. No-op when the op resolved no secret.
20928
+ */
20929
+ function redactRollbackRecord(record, secrets) {
20930
+ return secrets.size > 0 ? scrubResourceRecord(record, secrets) : record;
20931
+ }
20768
20932
  async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted) {
20769
20933
  if (provider.disableOuterRetry) return await provider.update(...args);
20770
20934
  return await withRetry(() => provider.update(...args), logicalId, {
@@ -20822,6 +20986,7 @@ function recordedPropertiesAfterReplayCreate(restored, result) {
20822
20986
  async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds, result, afterOp, isInterrupted) {
20823
20987
  const action = classifyRollbackOp(op, stateResources, orphanLogicalIds);
20824
20988
  const { logger } = ctx;
20989
+ const resolver = new IntrinsicFunctionResolver(ctx.region);
20825
20990
  /**
20826
20991
  * The route a CREATE-rollback arm resolved for this op (issue #1366) —
20827
20992
  * hoisted so the shared catch's ROLLBACK_RESOURCE_FAILED reports the route
@@ -20946,6 +21111,8 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
20946
21111
  case "reverse-replacement": {
20947
21112
  const current = stateResources[op.logicalId];
20948
21113
  const prev = op.previousState;
21114
+ const secrets = /* @__PURE__ */ new Map();
21115
+ const resolvedPrevProps = await resolveReplayProps(prev.properties, resolver, secrets) ?? {};
20949
21116
  logger.info(` Rollback: Reversing replacement of ${op.logicalId} (${op.resourceType}) — re-creating the old resource and deleting the new one`);
20950
21117
  if (STATEFUL_TYPES.has(op.resourceType)) logger.warn(` ⚠ ${op.logicalId} (${op.resourceType}) is a stateful type — the old physical resource's data was destroyed by the replacement and CANNOT be recovered; the re-created resource starts empty.`);
20951
21118
  const { provider: createProvider } = ctx.providerRegistry.getProviderFor({
@@ -20959,7 +21126,7 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
20959
21126
  let deletedNewFirst = false;
20960
21127
  let createResult;
20961
21128
  try {
20962
- createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
21129
+ createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
20963
21130
  ...RECREATE_RETRY_SCHEDULE,
20964
21131
  logger,
20965
21132
  ...isInterrupted && {
@@ -20982,7 +21149,7 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
20982
21149
  delete stateResources[op.logicalId];
20983
21150
  await afterOp?.(op.logicalId);
20984
21151
  try {
20985
- createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
21152
+ createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
20986
21153
  ...RECREATE_RETRY_SCHEDULE,
20987
21154
  logger,
20988
21155
  ...isInterrupted && {
@@ -21001,12 +21168,12 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
21001
21168
  result.warnings++;
21002
21169
  }
21003
21170
  const { observedProperties: _staleObserved, ...prevRecord } = prev;
21004
- stateResources[op.logicalId] = {
21171
+ stateResources[op.logicalId] = redactRollbackRecord({
21005
21172
  ...prevRecord,
21006
21173
  physicalId: createResult.physicalId,
21007
21174
  attributes: createResult.attributes ?? {},
21008
21175
  properties: recordedPropertiesAfterReplayCreate(prevRecord, createResult)
21009
- };
21176
+ }, secrets);
21010
21177
  await afterOp?.(op.logicalId);
21011
21178
  if (!deletedNewFirst && !adoptedLiveNewResource) try {
21012
21179
  const finalSnapshotIdentifier = rollbackFinalSnapshotId(op.resourceType, current, op.provisionedBy);
@@ -21047,14 +21214,17 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
21047
21214
  resourceType: op.resourceType,
21048
21215
  provisionedBy: op.provisionedBy
21049
21216
  });
21217
+ const secrets = /* @__PURE__ */ new Map();
21218
+ const desiredProps = await resolveReplayProps(previousState.properties, resolver, secrets);
21219
+ const currentProps = await resolveReplayProps(current.properties, resolver, secrets);
21050
21220
  const revertResult = await updateWithRollbackRetry(provider, [
21051
21221
  op.logicalId,
21052
21222
  current.physicalId,
21053
21223
  op.resourceType,
21054
- previousState.properties,
21055
- current.properties
21224
+ desiredProps ?? {},
21225
+ currentProps ?? {}
21056
21226
  ], op.logicalId, logger, isInterrupted);
21057
- stateResources[op.logicalId] = recordAfterRollbackUpdate(previousState, revertResult);
21227
+ stateResources[op.logicalId] = redactRollbackRecord(recordAfterRollbackUpdate(previousState, revertResult), secrets);
21058
21228
  logger.info(` Rollback: ${op.logicalId} restored successfully`);
21059
21229
  await afterOp?.(op.logicalId);
21060
21230
  ctx.recordEvent?.({
@@ -21102,6 +21272,7 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
21102
21272
  remainingFailedOps: []
21103
21273
  };
21104
21274
  const { logger } = ctx;
21275
+ const resolver = new IntrinsicFunctionResolver(ctx.region);
21105
21276
  const emitEnvelope = options.emitEnvelope === true && failedOps.length > 0;
21106
21277
  if (emitEnvelope) ctx.recordEvent?.({
21107
21278
  eventType: "ROLLBACK_STARTED",
@@ -21183,14 +21354,17 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
21183
21354
  resourceType: op.resourceType,
21184
21355
  provisionedBy: op.provisionedBy ?? current.provisionedBy
21185
21356
  });
21357
+ const secrets = /* @__PURE__ */ new Map();
21358
+ const desiredProps = await resolveReplayProps(prev.properties, resolver, secrets);
21359
+ const attemptedProps = await resolveReplayProps(op.attemptedProperties ?? current.properties, resolver, secrets);
21186
21360
  const revertFailedResult = await updateWithRollbackRetry(provider, [
21187
21361
  op.logicalId,
21188
21362
  current.physicalId,
21189
21363
  op.resourceType,
21190
- prev.properties,
21191
- op.attemptedProperties ?? current.properties
21364
+ desiredProps ?? {},
21365
+ attemptedProps ?? {}
21192
21366
  ], op.logicalId, logger, options.isInterrupted);
21193
- stateResources[op.logicalId] = recordAfterRollbackUpdate(prev, revertFailedResult);
21367
+ stateResources[op.logicalId] = redactRollbackRecord(recordAfterRollbackUpdate(prev, revertFailedResult), secrets);
21194
21368
  logger.info(` Rollback: ${op.logicalId} reverted successfully`);
21195
21369
  await options.afterOp?.(op.logicalId);
21196
21370
  ctx.recordEvent?.({
@@ -21316,7 +21490,7 @@ const FLUSH_INTERVAL_MS = 2e3;
21316
21490
  const FLUSH_EVENT_THRESHOLD = 50;
21317
21491
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
21318
21492
  function getCdkdVersion() {
21319
- return "0.283.18";
21493
+ return "0.283.20";
21320
21494
  }
21321
21495
  /**
21322
21496
  * Generate a time-sortable unique run id, e.g.
@@ -21913,6 +22087,30 @@ var DeployEngine = class {
21913
22087
  */
21914
22088
  recordedOutputReads = [];
21915
22089
  /**
22090
+ * PER-RESOURCE map of resolved SECRET dynamic-reference values
22091
+ * (plaintext -> `{{resolve:...}}` expression) the resolver records for each
22092
+ * resource's own resolution (GHSA fix). Keyed by logicalId. Per-resource, NOT
22093
+ * session-wide, because a session-wide map cross-contaminates: if resource A
22094
+ * resolves a `{{resolve:...:SecretString}}` whole-secret reference to value V,
22095
+ * and resource B (e.g. the `AWS::SecretsManager::Secret` that OWNS the secret)
22096
+ * carries V as its own LITERAL property, a session-wide value scan would
22097
+ * wrongly rewrite B's literal to A's expression — a false positive that shows
22098
+ * up as a permanent spurious diff. Redacting each resource only with the
22099
+ * secrets substituted during ITS OWN resolution scopes the value match
22100
+ * correctly. Kept on the engine (not just the resolver context) so the async
22101
+ * observed-property capture — which drains after the context is gone — can
22102
+ * still redact an AWS-readback secret (Cognito `client_secret`). Reset per
22103
+ * `deploy()`. See `secret-redaction.ts`.
22104
+ */
22105
+ perResourceSecrets = /* @__PURE__ */ new Map();
22106
+ /**
22107
+ * Resolved secrets recorded while resolving the stack OUTPUTS (a `CfnOutput`
22108
+ * whose Value resolves a `{{resolve:...}}` reference). Separate from the
22109
+ * per-resource maps for the same anti-cross-contamination reason. Reset per
22110
+ * `deploy()`.
22111
+ */
22112
+ outputSecrets = /* @__PURE__ */ new Map();
22113
+ /**
21916
22114
  * Per-logical-id snapshot of the intrinsic-RESOLVED desired properties
21917
22115
  * each CREATE / UPDATE attempted (issue #1198). Written just before the
21918
22116
  * provider call; read only when the op FAILS, to journal the failed op's
@@ -21953,6 +22151,8 @@ var DeployEngine = class {
21953
22151
  async deploy(stackName, template) {
21954
22152
  this.recordedImports = [];
21955
22153
  this.recordedOutputReads = [];
22154
+ this.perResourceSecrets = /* @__PURE__ */ new Map();
22155
+ this.outputSecrets = /* @__PURE__ */ new Map();
21956
22156
  this.resolver.resetPhysicalIdFallbackCount();
21957
22157
  return withStackName(stackName, () => this.doDeploy(stackName, template));
21958
22158
  }
@@ -21972,7 +22172,63 @@ var DeployEngine = class {
21972
22172
  stackName,
21973
22173
  ...this.exportIndexStore && { exportIndex: this.exportIndexStore },
21974
22174
  recordedImports: this.recordedImports,
21975
- recordedOutputReads: this.recordedOutputReads
22175
+ recordedOutputReads: this.recordedOutputReads,
22176
+ recordedSecretValues: /* @__PURE__ */ new Map()
22177
+ };
22178
+ }
22179
+ /**
22180
+ * Redact resolved secret plaintext out of a bag about to be PERSISTED to
22181
+ * state, replacing each secret value with the unresolved `{{resolve:...}}`
22182
+ * expression it came from (GHSA fix; see `secret-redaction.ts`). No-op when
22183
+ * the deploy recorded no secrets. The bag sent to the AWS API is the
22184
+ * un-redacted resolved bag; only the persisted copy is rewritten.
22185
+ */
22186
+ /**
22187
+ * Bag-level redaction of a single properties bag against a specific secrets
22188
+ * map (GHSA fix). Used by the UPDATE no-op re-check so a resolved-plaintext
22189
+ * bag is compared against the expression-bearing stored bag on equal footing.
22190
+ */
22191
+ redactPropsWith(props, secrets) {
22192
+ if (secrets.size === 0) return props;
22193
+ return redactSecretsForState(props, secrets);
22194
+ }
22195
+ /**
22196
+ * Redact resolved secret plaintext out of rollback-journal operations (GHSA
22197
+ * fix). Each op may carry resolved `properties` / `attemptedProperties` and a
22198
+ * `previousState` snapshot (whose `properties` / `attributes` /
22199
+ * `observedProperties` also hold resolved values). Each op is redacted with
22200
+ * the secrets recorded for ITS OWN resource (`perResourceSecrets`), so a
22201
+ * whole-secret value from one resource cannot rewrite another's literal.
22202
+ * Preserves ops that carry none of those fields, or whose resource recorded
22203
+ * no secret.
22204
+ */
22205
+ redactOperationsForJournal(operations) {
22206
+ return operations.map((op) => {
22207
+ const secrets = this.perResourceSecrets.get(op.logicalId);
22208
+ if (!secrets || secrets.size === 0) return op;
22209
+ const next = { ...op };
22210
+ if (next.properties) next.properties = redactSecretsForState(next.properties, secrets);
22211
+ if (next.attemptedProperties) next.attemptedProperties = redactSecretsForState(next.attemptedProperties, secrets);
22212
+ if (next.previousState) {
22213
+ const prev = { ...next.previousState };
22214
+ prev.properties = redactSecretsForState(prev.properties, secrets);
22215
+ if (prev.attributes) prev.attributes = redactSecretsForState(prev.attributes, secrets);
22216
+ if (prev.observedProperties) prev.observedProperties = redactSecretsForState(prev.observedProperties, secrets);
22217
+ next.previousState = prev;
22218
+ }
22219
+ return next;
22220
+ });
22221
+ }
22222
+ redactStateForPersist(state) {
22223
+ const resources = {};
22224
+ for (const [logicalId, record] of Object.entries(state.resources)) {
22225
+ const secrets = this.perResourceSecrets.get(logicalId);
22226
+ resources[logicalId] = secrets ? scrubResourceRecord(record, secrets) : record;
22227
+ }
22228
+ return {
22229
+ ...state,
22230
+ resources,
22231
+ outputs: this.outputSecrets.size > 0 ? redactSecretsForState(state.outputs, this.outputSecrets) : state.outputs
21976
22232
  };
21977
22233
  }
21978
22234
  /**
@@ -21981,12 +22237,21 @@ var DeployEngine = class {
21981
22237
  * constructed with `options.parentStackInfo` (= it's deploying a
21982
22238
  * nested-stack child). Returns the state unchanged for top-level
21983
22239
  * deploys so the three v6 fields stay absent from non-child state files.
22240
+ *
22241
+ * ALSO the single choke point where resolved SECRET plaintext is redacted out
22242
+ * of the persisted state (GHSA fix): every `stateBackend.saveState` call in
22243
+ * this engine wraps its state through here, so redacting `resources` once here
22244
+ * covers `properties` / `attributes` / `observedProperties` across every
22245
+ * create / update / replacement / rollback / observed-capture path uniformly —
22246
+ * including the async observed-capture drain that runs after the resolver
22247
+ * context is gone (which is why the secret map is session-wide).
21984
22248
  */
21985
22249
  withParentInfo(state) {
21986
- if (!this.options.parentStackInfo) return state;
22250
+ const redacted = this.redactStateForPersist(state);
22251
+ if (!this.options.parentStackInfo) return redacted;
21987
22252
  const { parentStack, parentLogicalId, parentRegion } = this.options.parentStackInfo;
21988
22253
  return {
21989
- ...state,
22254
+ ...redacted,
21990
22255
  parentStack,
21991
22256
  parentLogicalId,
21992
22257
  parentRegion
@@ -22241,13 +22506,14 @@ var DeployEngine = class {
22241
22506
  conditions
22242
22507
  }, stackName);
22243
22508
  diffResolverContext.bestEffort = true;
22509
+ diffResolverContext.skipDynamicReferences = true;
22244
22510
  const diffResolveFn = (value) => this.resolver.resolve(value, diffResolverContext);
22245
22511
  const changes = await this.diffCalculator.calculateDiff(currentState, effectiveTemplate, diffResolveFn, makeCanonicalizePropertiesFn(this.providerRegistry));
22246
22512
  if (!this.diffCalculator.hasChanges(changes)) {
22247
22513
  this.logger.info("No changes detected. Stack is up to date.");
22248
22514
  let persistedOutputs = currentState.outputs ?? {};
22249
22515
  if (!this.options.dryRun) {
22250
- const resolvedOutputs = await this.resolveOutputs(effectiveTemplate, currentState.resources, stackName, parameterValues, conditions);
22516
+ const resolvedOutputs = this.redactPropsWith(await this.resolveOutputs(effectiveTemplate, currentState.resources, stackName, parameterValues, conditions), this.outputSecrets);
22251
22517
  const resolutionFailed = Object.values(resolvedOutputs).some((v) => v === void 0);
22252
22518
  const outputsChanged = !resolutionFailed && !outputMapsEqual(persistedOutputs, resolvedOutputs);
22253
22519
  if (resolutionFailed && !outputMapsEqual(persistedOutputs, resolvedOutputs)) this.logger.warn("Outputs changed but one or more could not be resolved; keeping the previously persisted outputs. A downstream Fn::ImportValue may fail until the next deploy.");
@@ -22575,6 +22841,7 @@ var DeployEngine = class {
22575
22841
  let outputs;
22576
22842
  try {
22577
22843
  outputs = await this.resolveOutputs(template, newResources, stackName, parameterValues, conditions);
22844
+ outputs = this.redactPropsWith(outputs, this.outputSecrets);
22578
22845
  } catch (outputError) {
22579
22846
  await this.persistStateAfterOutputFailure(stackName, currentState, newResources, currentEtag, pendingMigration);
22580
22847
  await this.writeRollbackJournalSegment(stackName, completedOperations, failedOperations, "no-rollback-failure", currentEtag === void 0);
@@ -22730,6 +22997,8 @@ var DeployEngine = class {
22730
22997
  */
22731
22998
  async writeRollbackJournalSegment(stackName, completedOperations, failedOperations, reason, initialDeploy) {
22732
22999
  if (completedOperations.length === 0 && failedOperations.length === 0) return;
23000
+ const redactedCompleted = this.redactOperationsForJournal(completedOperations);
23001
+ const redactedFailed = this.redactOperationsForJournal(failedOperations);
22733
23002
  try {
22734
23003
  const segment = {
22735
23004
  ...this.options.eventRecorder?.runId !== void 0 && { runId: this.options.eventRecorder.runId },
@@ -22738,8 +23007,8 @@ var DeployEngine = class {
22738
23007
  initialDeploy,
22739
23008
  ...this.options.roleArn && { roleArn: this.options.roleArn },
22740
23009
  cdkdVersion: getCdkdVersion(),
22741
- operations: completedOperations,
22742
- ...failedOperations.length > 0 && { failedOperations }
23010
+ operations: redactedCompleted,
23011
+ ...redactedFailed.length > 0 && { failedOperations: redactedFailed }
22743
23012
  };
22744
23013
  await this.stateBackend.appendRollbackJournalSegment(stackName, this.stackRegion, segment);
22745
23014
  this.logger.debug(`Rollback journal segment written (${reason})`);
@@ -22846,10 +23115,29 @@ var DeployEngine = class {
22846
23115
  recordEvent(event) {
22847
23116
  if (!this.options.eventRecorder) return;
22848
23117
  try {
22849
- this.options.eventRecorder.record(event);
23118
+ this.options.eventRecorder.record(this.maskSecretsInEvent(event));
22850
23119
  } catch {}
22851
23120
  }
22852
23121
  /**
23122
+ * Mask any resolved secret value out of an event's human-authored text before
23123
+ * it is persisted to `deployments/*.jsonl` (which outlives `cdkd destroy`)
23124
+ * — GHSA fix. An AWS validation error can quote the offending property value
23125
+ * (`Value '<secret>' at 'X' failed to satisfy ...`), and a provider `reason`
23126
+ * is provider-authored prose; both reach the event store as `error.message` /
23127
+ * `reason`. No-op when the deploy recorded no secrets.
23128
+ */
23129
+ maskSecretsInEvent(event) {
23130
+ const secrets = event.logicalId ? this.perResourceSecrets.get(event.logicalId) : void 0;
23131
+ if (!secrets || secrets.size === 0) return event;
23132
+ const next = { ...event };
23133
+ if (next.error?.message) next.error = {
23134
+ ...next.error,
23135
+ message: maskSecretsInText(next.error.message, secrets)
23136
+ };
23137
+ if (next.reason) next.reason = maskSecretsInText(next.reason, secrets);
23138
+ return next;
23139
+ }
23140
+ /**
22853
23141
  * Issue #1002 PR 2 — §7 step 3 post-resolution audit (defense in depth).
22854
23142
  * No-op in legacy mode (`options.assetRedirect` unset). In cdkd-assets
22855
23143
  * mode, a resolved property still naming a mapped SOURCE (CDK bootstrap)
@@ -22949,6 +23237,7 @@ var DeployEngine = class {
22949
23237
  ...conditions && { conditions }
22950
23238
  }, stackName);
22951
23239
  const resolvedProps = await this.resolver.resolve(desiredProps, context);
23240
+ if (context.recordedSecretValues) this.perResourceSecrets.set(logicalId, context.recordedSecretValues);
22952
23241
  this.auditResolvedAssetReferences(logicalId, resourceType, resolvedProps);
22953
23242
  this.attemptedResolvedProps.set(logicalId, resolvedProps);
22954
23243
  const createDecision = this.providerRegistry.getProviderFor({
@@ -22990,9 +23279,11 @@ var DeployEngine = class {
22990
23279
  ...conditions && { conditions }
22991
23280
  }, stackName);
22992
23281
  const resolvedProps = await this.resolver.resolve(desiredProps, context);
23282
+ const updateSecrets = context.recordedSecretValues ?? /* @__PURE__ */ new Map();
23283
+ this.perResourceSecrets.set(logicalId, updateSecrets);
22993
23284
  this.auditResolvedAssetReferences(logicalId, resourceType, resolvedProps);
22994
23285
  this.attemptedResolvedProps.set(logicalId, resolvedProps);
22995
- if (JSON.stringify(resolvedProps) === JSON.stringify(currentProps)) {
23286
+ if (JSON.stringify(this.redactPropsWith(resolvedProps, updateSecrets)) === JSON.stringify(currentProps)) {
22996
23287
  if (change.attributeChanges && change.attributeChanges.length > 0) {
22997
23288
  const attrSummary = change.attributeChanges.map((a) => `${a.attribute}: ${a.oldValue ?? "(unset)"} → ${a.newValue ?? "(unset)"}`).join(", ");
22998
23289
  this.logger.info(` ↻ ${logicalId} (${resourceType}) attribute update: ${attrSummary}`);
@@ -23518,6 +23809,7 @@ var DeployEngine = class {
23518
23809
  outputs[outputKey] = void 0;
23519
23810
  }
23520
23811
  }
23812
+ if (context.recordedSecretValues) for (const [value, expr] of context.recordedSecretValues) this.outputSecrets.set(value, expr);
23521
23813
  return outputs;
23522
23814
  }
23523
23815
  buildDisplayOutputs(template, resolvedOutputs) {
@@ -23532,5 +23824,5 @@ var DeployEngine = class {
23532
23824
  };
23533
23825
 
23534
23826
  //#endregion
23535
- export { coerceCfnBoolean as $, resolveStateBucketWithDefault as $t, cyan as A, MissingCdkCliError as An, AssetModeResolver as At, findSilentDropProperties as B, formatError as Bn, getDockerCmd as Bt, makeCanonicalizePropertiesFn as C, ConfigError as Cn, stringifyValue as Ct, renderStatefulReason as D, LocalMigrateError as Dn, loadPublishableAssetManifest as Dt, isStatefulRecreateTargetSync as E, LocalInvokeBuildError as En, createAssetRedirectResolver as Et, IAMRoleProvider as F, ResourceUpdateNotSupportedError as Fn, validateAssetBucketName as Ft, IntrinsicFunctionResolver as G, isRetryableTransientError as Gn, Synthesizer as Gt, slowCcOperationTimeoutMs as H, normalizeAwsError as Hn, runDockerStreaming as Ht, collectInlinePolicyNamesManagedBySiblings as I, StackHasActiveImportsError as In, validateContainerRepoName as It, refStateLookupFromResource as J, __exportAll as Jn, getLegacyStateBucketName as Jt, cfnRefValueFromPhysicalId as K, isThrottlingError as Kn, synthesisStatusMessage as Kt, clearOnUpdateRemoval as L, StackTerminationProtectionError as Ln, buildDenyExternalAccessPolicy as Lt, green as M, PartialFailureError as Mn, ensureAssetStorage as Mt, red as N, ProvisioningError as Nn, getBootstrapMarkerKey as Nt, formatResourceLine as O, LocalStartServiceError as On, rewriteTemplateAssetReferences as Ot, yellow as P, ResourceTimeoutError as Pn, parseBootstrapMarker as Pt, assertRegionMatch as Q, resolveSkipPrefix as Qt, ProviderRegistry as R, StateError as Rn, buildDockerImage as Rt, unsupportedFinalSnapshotError as S, CdkdError as Sn, AssetPublisher as St, MULTI_REGION_RECREATE_BLOCKED_TYPES as T, DeployCancelledError as Tn, buildAssetRedirectMap as Tt, disableInstanceApiTermination as U, withErrorHandling as Un, AssetManifestLoader as Ut, CloudControlProvider as V, isCdkdError as Vn, runDockerForeground as Vt, isTerminationProtectionPropagationError as W, isMarkedNonRetryable as Wn, getDockerImageBySourceHash as Wt, normalizeAwsTagsToCfn as X, resolveAutoAssetStorage as Xt, WAFv2WebACLProvider as Y, resolveApp as Yt, resolveExplicitPhysicalId as Z, resolveCaptureObservedState as Zt, buildFinalSnapshotIdentifier as _, AwsClients as _n, TemplateParser as _t, DeploymentEventsStore as a, CFN_TEMPLATE_URL_LIMIT as an, requireConfigObject as at, isFinalSnapshotError as b, setAwsClients as bn, rebuildClientForBucketRegion as bt, replayFailedOperations as c, uploadCfnTemplate as cn, s3BucketDomainName as ct, deleteSkipReason as d, canonicalizeRegion as dn, s3BucketWebsiteUrl as dt, resolveStateBucketWithDefaultAndSource as en, configBooleanRefusal as et, withResourceDeadline as f, derivePartitionAndUrlSuffix as fn, applyRoleArnIfSet as ft, PRE_DELETE_SNAPSHOT_TYPES as g, resolveBucketRegion as gn, DagBuilder as gt, ATOMIC_FINAL_SNAPSHOT_TYPES as h, clearBucketRegionCache as hn, withRetry as ht, DeploymentEventsReader as i, CFN_TEMPLATE_BODY_LIMIT as in, requireConfigArray as it, gray as j, NestedStackChildDirectDestroyError as jn, BOOTSTRAP_MARKER_PREFIX as jt, bold as k, LockError as kn, escapeRegExp as kt, replayRollback as l, expectedOwnerParam as ln, s3BucketDualStackDomainName as lt, computeImplicitDeleteEdges as m, processStackMessages as mn, describeTypeWithThrottleRetry as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, stateBucketExistenceConfirmed as nn, readConfigString as nt, planFailedOps as o, MIGRATE_TMP_PREFIX as on, requireConfigString as ot, IMPLICIT_DELETE_DEPENDENCIES as p, AssemblyReader as pn, DiffCalculator as pt, getAccountInfo as q, markNonRetryable as qn, getDefaultStateBucketName as qt, DeployEngine as r, warnDeprecatedNoPrefixCliFlag as rn, replayWarn as rt, planRollback as s, findLargeInlineResources as sn, s3BucketArn as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, resolveUseCdkBootstrapAssets as tn, configStringRefusal as tt, UNSPECIFIED_SKIP_REASON as u, PARTITION_TABLE as un, s3BucketRegionalDomainName as ut, ccRoutedFinalSnapshotError as v, getAwsClients as vn, LockManager as vt, extractDeploymentEventError as w, DependencyError as wn, WorkGraph as wt, refusesFinalSnapshot as x, AssetError as xn, shouldRetainResource as xt, createPreDeleteFinalSnapshot as y, resetAwsClients as yn, S3StateBackend as yt, findActionableSilentDrops as z, SynthesisError as zn, formatDockerLoginError as zt };
23536
- //# sourceMappingURL=deploy-engine-B-0iA5XV.js.map
23827
+ export { coerceCfnBoolean as $, resolveCaptureObservedState as $t, cyan as A, LocalStartServiceError as An, rewriteTemplateAssetReferences as At, findSilentDropProperties as B, StateError as Bn, buildDockerImage as Bt, makeCanonicalizePropertiesFn as C, AssetError as Cn, shouldRetainResource as Ct, renderStatefulReason as D, DeployCancelledError as Dn, buildAssetRedirectMap as Dt, isStatefulRecreateTargetSync as E, DependencyError as En, WorkGraph as Et, IAMRoleProvider as F, ProvisioningError as Fn, getBootstrapMarkerKey as Ft, IntrinsicFunctionResolver as G, withErrorHandling as Gn, AssetManifestLoader as Gt, slowCcOperationTimeoutMs as H, formatError as Hn, getDockerCmd as Ht, collectInlinePolicyNamesManagedBySiblings as I, ResourceTimeoutError as In, parseBootstrapMarker as It, refStateLookupFromResource as J, isThrottlingError as Jn, synthesisStatusMessage as Jt, cfnRefValueFromPhysicalId as K, isMarkedNonRetryable as Kn, getDockerImageBySourceHash as Kt, clearOnUpdateRemoval as L, ResourceUpdateNotSupportedError as Ln, validateAssetBucketName as Lt, green as M, MissingCdkCliError as Mn, AssetModeResolver as Mt, red as N, NestedStackChildDirectDestroyError as Nn, BOOTSTRAP_MARKER_PREFIX as Nt, formatResourceLine as O, LocalInvokeBuildError as On, createAssetRedirectResolver as Ot, yellow as P, PartialFailureError as Pn, ensureAssetStorage as Pt, assertRegionMatch as Q, resolveAutoAssetStorage as Qt, ProviderRegistry as R, StackHasActiveImportsError as Rn, validateContainerRepoName as Rt, unsupportedFinalSnapshotError as S, setAwsClients as Sn, rebuildClientForBucketRegion as St, MULTI_REGION_RECREATE_BLOCKED_TYPES as T, ConfigError as Tn, stringifyValue as Tt, disableInstanceApiTermination as U, isCdkdError as Un, runDockerForeground as Ut, CloudControlProvider as V, SynthesisError as Vn, formatDockerLoginError as Vt, isTerminationProtectionPropagationError as W, normalizeAwsError as Wn, runDockerStreaming as Wt, normalizeAwsTagsToCfn as X, __exportAll as Xn, getLegacyStateBucketName as Xt, WAFv2WebACLProvider as Y, markNonRetryable as Yn, getDefaultStateBucketName as Yt, resolveExplicitPhysicalId as Z, resolveApp as Zt, buildFinalSnapshotIdentifier as _, clearBucketRegionCache as _n, withRetry as _t, DeploymentEventsStore as a, warnDeprecatedNoPrefixCliFlag as an, requireConfigObject as at, isFinalSnapshotError as b, getAwsClients as bn, LockManager as bt, replayFailedOperations as c, MIGRATE_TMP_PREFIX as cn, scrubResourceRecord as ct, deleteSkipReason as d, expectedOwnerParam as dn, s3BucketDualStackDomainName as dt, resolveSkipPrefix as en, configBooleanRefusal as et, withResourceDeadline as f, PARTITION_TABLE as fn, s3BucketRegionalDomainName as ft, PRE_DELETE_SNAPSHOT_TYPES as g, processStackMessages as gn, describeTypeWithThrottleRetry as gt, ATOMIC_FINAL_SNAPSHOT_TYPES as h, AssemblyReader as hn, DiffCalculator as ht, DeploymentEventsReader as i, stateBucketExistenceConfirmed as in, requireConfigArray as it, gray as j, LockError as jn, escapeRegExp$1 as jt, bold as k, LocalMigrateError as kn, loadPublishableAssetManifest as kt, replayRollback as l, findLargeInlineResources as ln, s3BucketArn as lt, computeImplicitDeleteEdges as m, derivePartitionAndUrlSuffix as mn, applyRoleArnIfSet as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, resolveStateBucketWithDefaultAndSource as nn, readConfigString as nt, planFailedOps as o, CFN_TEMPLATE_BODY_LIMIT as on, requireConfigString as ot, IMPLICIT_DELETE_DEPENDENCIES as p, canonicalizeRegion as pn, s3BucketWebsiteUrl as pt, getAccountInfo as q, isRetryableTransientError as qn, Synthesizer as qt, DeployEngine as r, resolveUseCdkBootstrapAssets as rn, replayWarn as rt, planRollback as s, CFN_TEMPLATE_URL_LIMIT as sn, redactSecretsForState as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, resolveStateBucketWithDefault as tn, configStringRefusal as tt, UNSPECIFIED_SKIP_REASON as u, uploadCfnTemplate as un, s3BucketDomainName as ut, ccRoutedFinalSnapshotError as v, resolveBucketRegion as vn, DagBuilder as vt, extractDeploymentEventError as w, CdkdError as wn, AssetPublisher as wt, refusesFinalSnapshot as x, resetAwsClients as xn, S3StateBackend as xt, createPreDeleteFinalSnapshot as y, AwsClients as yn, TemplateParser as yt, findActionableSilentDrops as z, StackTerminationProtectionError as zn, buildDenyExternalAccessPolicy as zt };
23828
+ //# sourceMappingURL=deploy-engine-ISOKkuun.js.map