@go-to-k/cdkd 0.283.19 → 0.283.21

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
  /**
@@ -11405,6 +11494,29 @@ const cachedAvailabilityZones = {};
11405
11494
  */
11406
11495
  const cachedDynamicReferences = {};
11407
11496
  /**
11497
+ * The `{{resolve:ssm:...}}` expressions this process has PROVEN point at a
11498
+ * `SecureString` parameter (issue #1901).
11499
+ *
11500
+ * A plain `ssm` reference is not a secret by SPELLING the way `secretsmanager`
11501
+ * is — whether it resolves to public config or to a decrypted secret depends on
11502
+ * the parameter's `Type`, which is only knowable from the `GetParameter`
11503
+ * response. So secret-ness is discovered on the first resolution and remembered
11504
+ * here, keyed by the full `{{resolve:...}}` expression, for the same lifetime as
11505
+ * {@link cachedDynamicReferences}.
11506
+ *
11507
+ * Two consumers need it AFTER the lookup that populated it: the cache-hit arm
11508
+ * (which must re-record the value as a secret for the current resolution pass)
11509
+ * and the diff / no-op path (which must leave a SecureString reference
11510
+ * unresolved without paying a lookup at all once the type is known). A
11511
+ * reference NOT in this set is only "not known to be secure" — never "proven
11512
+ * public" — so every arm that would leak still asks AWS for the type first.
11513
+ *
11514
+ * Only the TYPE is remembered, never the decrypted value: on the diff path the
11515
+ * lookup is made with `WithDecryption: false`, so the plaintext is never
11516
+ * fetched at all there.
11517
+ */
11518
+ const secureStringSsmReferences = /* @__PURE__ */ new Set();
11519
+ /**
11408
11520
  * Cache for EC2 instance attributes that require a live DescribeInstances
11409
11521
  * lookup (PrivateIp / PublicIp / PrivateDnsName / PublicDnsName /
11410
11522
  * AvailabilityZone). Keyed by `${physicalId}#${attributeName}`. The IP /
@@ -11770,7 +11882,7 @@ var IntrinsicFunctionResolver = class {
11770
11882
  */
11771
11883
  async resolveValue(value, context) {
11772
11884
  if (typeof value !== "object" || value === null) {
11773
- if (typeof value === "string" && value.includes("{{resolve:")) return await this.resolveDynamicReferences(value);
11885
+ if (typeof value === "string" && value.includes("{{resolve:")) return await this.resolveDynamicReferences(value, context);
11774
11886
  return value;
11775
11887
  }
11776
11888
  if (Array.isArray(value)) return (await Promise.all(value.map((v) => this.resolveValue(v, context)))).filter((v) => v !== AWS_NO_VALUE);
@@ -12373,8 +12485,8 @@ var IntrinsicFunctionResolver = class {
12373
12485
  const resolved = await this.resolveValue(v, context);
12374
12486
  return String(resolved);
12375
12487
  }))).join(delimiter);
12376
- if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result);
12377
- this.logger.debug(`Resolved Fn::Join: ${result}`);
12488
+ if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result, context);
12489
+ this.logger.debug(`Resolved Fn::Join: ${this.maskSecretsForLog(result, context)}`);
12378
12490
  return result;
12379
12491
  }
12380
12492
  /**
@@ -12459,8 +12571,8 @@ var IntrinsicFunctionResolver = class {
12459
12571
  const entry = replacements[cursor++];
12460
12572
  return entry ? entry.replacement : whole;
12461
12573
  });
12462
- if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result);
12463
- this.logger.debug(`Resolved Fn::Sub: ${result}`);
12574
+ if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result, context);
12575
+ this.logger.debug(`Resolved Fn::Sub: ${this.maskSecretsForLog(result, context)}`);
12464
12576
  return result;
12465
12577
  }
12466
12578
  /**
@@ -12478,7 +12590,7 @@ var IntrinsicFunctionResolver = class {
12478
12590
  return `{{Fn::Select:${index}:OutOfBounds}}`;
12479
12591
  }
12480
12592
  const result = resolvedList[index];
12481
- this.logger.debug(`Resolved Fn::Select: index ${index} -> ${JSON.stringify(result)}`);
12593
+ this.logger.debug(`Resolved Fn::Select: index ${index} -> ${this.maskSecretsForLog(JSON.stringify(result), context)}`);
12482
12594
  return result;
12483
12595
  }
12484
12596
  /**
@@ -12620,7 +12732,7 @@ var IntrinsicFunctionResolver = class {
12620
12732
  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
12733
  }
12622
12734
  const result = resolvedValue.split(delimiter);
12623
- this.logger.debug(`Resolved Fn::Split: split by "${delimiter}" -> ${JSON.stringify(result)}`);
12735
+ this.logger.debug(`Resolved Fn::Split: split by "${delimiter}" -> ${this.maskSecretsForLog(JSON.stringify(result), context)}`);
12624
12736
  return result;
12625
12737
  }
12626
12738
  /**
@@ -13128,7 +13240,7 @@ var IntrinsicFunctionResolver = class {
13128
13240
  const resolvedValue = await this.resolveValue(value, context);
13129
13241
  if (typeof resolvedValue !== "string") throw new Error(`Fn::Base64: value must resolve to a string, got ${typeof resolvedValue}`);
13130
13242
  const result = Buffer.from(resolvedValue).toString("base64");
13131
- this.logger.debug(`Resolved Fn::Base64: ${resolvedValue} -> ${result}`);
13243
+ this.logger.debug(`Resolved Fn::Base64: ${this.maskSecretsForLog(resolvedValue, context)} -> ${this.maskSecretsForLog(result, context)}`);
13132
13244
  return result;
13133
13245
  }
13134
13246
  /**
@@ -13195,7 +13307,16 @@ var IntrinsicFunctionResolver = class {
13195
13307
  *
13196
13308
  * Results are cached to avoid repeated API calls.
13197
13309
  */
13198
- async resolveDynamicReferences(value) {
13310
+ /**
13311
+ * Mask any resolved secret value out of a string bound for a log line, using
13312
+ * the secrets recorded on the resolution pass (GHSA fix). No-op when the pass
13313
+ * recorded no secrets.
13314
+ */
13315
+ maskSecretsForLog(text, context) {
13316
+ const secrets = context?.recordedSecretValues;
13317
+ return secrets ? maskSecretsInText(text, secrets) : text;
13318
+ }
13319
+ async resolveDynamicReferences(value, context) {
13199
13320
  const pattern = /\{\{resolve:([^}]+)\}\}/g;
13200
13321
  let result = value;
13201
13322
  let match;
@@ -13205,21 +13326,36 @@ var IntrinsicFunctionResolver = class {
13205
13326
  inner: match[1]
13206
13327
  });
13207
13328
  for (const { fullMatch, inner } of matches) {
13329
+ const service = inner.split(":")[0];
13330
+ const isKnownSecret = service === "secretsmanager" || secureStringSsmReferences.has(fullMatch);
13331
+ if (isKnownSecret && context?.skipDynamicReferences) continue;
13208
13332
  if (fullMatch in cachedDynamicReferences) {
13209
- result = result.replace(fullMatch, cachedDynamicReferences[fullMatch]);
13333
+ const cached = cachedDynamicReferences[fullMatch];
13334
+ if (isKnownSecret && cached) context?.recordedSecretValues?.set(cached, fullMatch);
13335
+ result = result.replace(fullMatch, () => cached);
13210
13336
  continue;
13211
13337
  }
13212
13338
  const parts = inner.split(":");
13213
- const service = parts[0];
13214
13339
  let resolved;
13340
+ let isSecret = isKnownSecret;
13215
13341
  if (service === "secretsmanager") resolved = await this.resolveSecretsManagerReference(inner);
13216
- else if (service === "ssm") resolved = await this.resolveSSMReference(parts);
13217
- else {
13342
+ else if (service === "ssm") {
13343
+ const decrypt = context?.skipDynamicReferences !== true;
13344
+ const param = await this.resolveSSMReference(parts, decrypt);
13345
+ if (param.type === "SecureString") secureStringSsmReferences.add(fullMatch);
13346
+ else if (!param.secure) secureStringSsmReferences.delete(fullMatch);
13347
+ isSecret = param.secure;
13348
+ if (param.secure) {
13349
+ if (!decrypt) continue;
13350
+ }
13351
+ resolved = param.value;
13352
+ } else {
13218
13353
  this.logger.warn(`Unsupported dynamic reference service: ${service}`);
13219
13354
  continue;
13220
13355
  }
13221
13356
  cachedDynamicReferences[fullMatch] = resolved;
13222
- result = result.replace(fullMatch, resolved);
13357
+ if (isSecret && resolved) context?.recordedSecretValues?.set(resolved, fullMatch);
13358
+ result = result.replace(fullMatch, () => resolved);
13223
13359
  }
13224
13360
  return result;
13225
13361
  }
@@ -13372,18 +13508,44 @@ var IntrinsicFunctionResolver = class {
13372
13508
  for (let i = 7; i >= 0; i--) parts.push((n >> BigInt(i * 16) & BigInt(65535)).toString(16));
13373
13509
  return parts.join(":");
13374
13510
  }
13375
- async resolveSSMReference(parts) {
13511
+ /**
13512
+ * Resolve an `{{resolve:ssm:...}}` dynamic reference, reporting whether the
13513
+ * parameter is a `SecureString` (issue #1901).
13514
+ *
13515
+ * `secure` is read off the SAME `GetParameter` response that carries the
13516
+ * value, so classifying a reference costs no extra API call — which is what
13517
+ * makes it affordable on the comparison path too.
13518
+ *
13519
+ * `decrypt` maps straight to `WithDecryption`. SSM ignores it for `String` /
13520
+ * `StringList` (their `Value` is identical either way), so the only thing it
13521
+ * changes is whether a `SecureString`'s `Value` comes back as plaintext or as
13522
+ * its encrypted blob. Callers that only need the TYPE pass `false` and MUST
13523
+ * discard the value when `secure` is set — it is ciphertext, not the resolved
13524
+ * reference.
13525
+ */
13526
+ async resolveSSMReference(parts, decrypt = true) {
13376
13527
  const parameterName = parts.slice(1).join(":");
13377
13528
  if (!parameterName) throw new Error("Dynamic reference: ssm PARAMETER_NAME is required");
13378
13529
  this.logger.debug(`Resolving dynamic reference: ssm:${parameterName}`);
13379
13530
  const client = getAwsClients().ssm;
13380
13531
  const command = new GetParameterCommand({
13381
13532
  Name: parameterName,
13382
- WithDecryption: true
13533
+ WithDecryption: decrypt
13383
13534
  });
13384
- const paramValue = (await client.send(command)).Parameter?.Value;
13535
+ const response = await client.send(command);
13536
+ const paramValue = response.Parameter?.Value;
13385
13537
  if (paramValue === void 0 || paramValue === null) throw new Error(`Dynamic reference: SSM parameter '${parameterName}' not found or has no value`);
13386
- return paramValue;
13538
+ const paramType = response.Parameter?.Type;
13539
+ const secure = paramType !== "String" && paramType !== "StringList";
13540
+ if (secure && paramType !== "SecureString") {
13541
+ const reported = paramType === void 0 ? "(absent)" : `'${String(paramType)}'`;
13542
+ this.logger.warn(`SSM parameter '${parameterName}' reported an unrecognized Type ${reported} — treating its value as a secret, so cdkd will persist the {{resolve:ssm:...}} expression rather than the resolved value. Declare the parameter as String / StringList if it is public config.`);
13543
+ }
13544
+ return {
13545
+ value: paramValue,
13546
+ secure,
13547
+ type: paramType
13548
+ };
13387
13549
  }
13388
13550
  };
13389
13551
 
@@ -14182,7 +14344,13 @@ var CloudControlProvider = class {
14182
14344
  };
14183
14345
  }
14184
14346
  }
14185
- this.logger.debug(`Generated ${patch.length} patch operations for ${logicalId}: ${JSON.stringify(patch)}`);
14347
+ this.logger.debug(`Generated ${patch.length} patch operations for ${logicalId}: ${JSON.stringify(patch.map((op) => {
14348
+ const anyOp = op;
14349
+ return {
14350
+ op: anyOp.op,
14351
+ path: anyOp.path
14352
+ };
14353
+ }))}`);
14186
14354
  const updateResponse = await this.cloudControlClient.send(new UpdateResourceCommand({
14187
14355
  TypeName: resourceType,
14188
14356
  Identifier: physicalId,
@@ -14212,7 +14380,7 @@ var CloudControlProvider = class {
14212
14380
  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
14381
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
14214
14382
  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-B260vt0k.js").then((n) => n.n);
14383
+ const { ASGProvider } = await import("./asg-provider-DKjoomrX.js").then((n) => n.n);
14216
14384
  return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
14217
14385
  }
14218
14386
  const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
@@ -20765,6 +20933,65 @@ async function replayRollback(operations, stateResources, stackName, ctx, option
20765
20933
  * just announced and leaving the record describing something AWS does not
20766
20934
  * hold.
20767
20935
  */
20936
+ /**
20937
+ * Re-resolve dynamic-reference SECRET expressions
20938
+ * (`{{resolve:secretsmanager:...}}`) in a property bag being REPLAYED to a
20939
+ * provider during rollback (GHSA fix, issue #1899 review).
20940
+ *
20941
+ * The rollback journal — and the state record the replay writes — store the
20942
+ * redacted EXPRESSION, never the plaintext. But a `provider.update()` /
20943
+ * `create()` / `delete()` call must receive the concrete secret value the
20944
+ * reference points at, exactly as the forward deploy did; replaying the literal
20945
+ * `{{resolve:...}}` string would corrupt the resource (e.g. a Lambda env var or
20946
+ * Cognito `client_secret`). Rollback is synth-free, so re-resolve straight from
20947
+ * the expression string here.
20948
+ *
20949
+ * Records each `plaintext -> expression` into `secrets` so the caller can redact
20950
+ * the persisted state record back to the expression — the same
20951
+ * resolve-for-provider + redact-for-state split the deploy engine applies at its
20952
+ * save choke point. A bag with no `{{resolve:...}}` string resolves to a
20953
+ * structural copy of itself (secrets stays empty), so the non-secret rollback
20954
+ * path is behaviourally unchanged. Which references are RECORDED is the
20955
+ * resolver's own secret gate: every `secretsmanager` one, plus an `ssm` one
20956
+ * whose parameter is a `SecureString` (issue #1901 — that form decrypts to a
20957
+ * real secret, so it is redacted into the journal and must be re-resolved here
20958
+ * exactly like a secretsmanager reference). An ssm reference to a `String` /
20959
+ * `StringList` parameter is public config, stored resolved, and never appears
20960
+ * as an expression in the journal.
20961
+ */
20962
+ async function resolveReplayProps(props, resolver, secrets) {
20963
+ if (props === void 0) return void 0;
20964
+ const ctx = {
20965
+ template: { Resources: {} },
20966
+ resources: {},
20967
+ recordedSecretValues: secrets
20968
+ };
20969
+ const walk = async (v) => {
20970
+ if (typeof v === "string") return v.includes("{{resolve:") ? await resolver.resolveDynamicReferences(v, ctx) : v;
20971
+ if (Array.isArray(v)) {
20972
+ const out = new Array(v.length);
20973
+ for (let i = 0; i < v.length; i++) out[i] = await walk(v[i]);
20974
+ return out;
20975
+ }
20976
+ if (v !== null && typeof v === "object") {
20977
+ const out = {};
20978
+ for (const [k, val] of Object.entries(v)) out[k] = await walk(val);
20979
+ return out;
20980
+ }
20981
+ return v;
20982
+ };
20983
+ return await walk(props);
20984
+ }
20985
+ /**
20986
+ * Redact resolved secret plaintext back out of a post-rollback state record
20987
+ * (GHSA fix). The record's `properties` may be the provider's
20988
+ * `effectiveProperties`, which can echo the value we just resolved for the
20989
+ * provider call — so scrub it with the same per-op secrets map before it is
20990
+ * persisted. No-op when the op resolved no secret.
20991
+ */
20992
+ function redactRollbackRecord(record, secrets) {
20993
+ return secrets.size > 0 ? scrubResourceRecord(record, secrets) : record;
20994
+ }
20768
20995
  async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted) {
20769
20996
  if (provider.disableOuterRetry) return await provider.update(...args);
20770
20997
  return await withRetry(() => provider.update(...args), logicalId, {
@@ -20822,6 +21049,7 @@ function recordedPropertiesAfterReplayCreate(restored, result) {
20822
21049
  async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds, result, afterOp, isInterrupted) {
20823
21050
  const action = classifyRollbackOp(op, stateResources, orphanLogicalIds);
20824
21051
  const { logger } = ctx;
21052
+ const resolver = new IntrinsicFunctionResolver(ctx.region);
20825
21053
  /**
20826
21054
  * The route a CREATE-rollback arm resolved for this op (issue #1366) —
20827
21055
  * hoisted so the shared catch's ROLLBACK_RESOURCE_FAILED reports the route
@@ -20946,6 +21174,8 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
20946
21174
  case "reverse-replacement": {
20947
21175
  const current = stateResources[op.logicalId];
20948
21176
  const prev = op.previousState;
21177
+ const secrets = /* @__PURE__ */ new Map();
21178
+ const resolvedPrevProps = await resolveReplayProps(prev.properties, resolver, secrets) ?? {};
20949
21179
  logger.info(` Rollback: Reversing replacement of ${op.logicalId} (${op.resourceType}) — re-creating the old resource and deleting the new one`);
20950
21180
  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
21181
  const { provider: createProvider } = ctx.providerRegistry.getProviderFor({
@@ -20959,7 +21189,7 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
20959
21189
  let deletedNewFirst = false;
20960
21190
  let createResult;
20961
21191
  try {
20962
- createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
21192
+ createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
20963
21193
  ...RECREATE_RETRY_SCHEDULE,
20964
21194
  logger,
20965
21195
  ...isInterrupted && {
@@ -20982,7 +21212,7 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
20982
21212
  delete stateResources[op.logicalId];
20983
21213
  await afterOp?.(op.logicalId);
20984
21214
  try {
20985
- createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...prev.properties }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
21215
+ createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, REPLAYING_STATE_CREATE_CONTEXT), op.logicalId, {
20986
21216
  ...RECREATE_RETRY_SCHEDULE,
20987
21217
  logger,
20988
21218
  ...isInterrupted && {
@@ -21001,12 +21231,12 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
21001
21231
  result.warnings++;
21002
21232
  }
21003
21233
  const { observedProperties: _staleObserved, ...prevRecord } = prev;
21004
- stateResources[op.logicalId] = {
21234
+ stateResources[op.logicalId] = redactRollbackRecord({
21005
21235
  ...prevRecord,
21006
21236
  physicalId: createResult.physicalId,
21007
21237
  attributes: createResult.attributes ?? {},
21008
21238
  properties: recordedPropertiesAfterReplayCreate(prevRecord, createResult)
21009
- };
21239
+ }, secrets);
21010
21240
  await afterOp?.(op.logicalId);
21011
21241
  if (!deletedNewFirst && !adoptedLiveNewResource) try {
21012
21242
  const finalSnapshotIdentifier = rollbackFinalSnapshotId(op.resourceType, current, op.provisionedBy);
@@ -21047,14 +21277,17 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
21047
21277
  resourceType: op.resourceType,
21048
21278
  provisionedBy: op.provisionedBy
21049
21279
  });
21280
+ const secrets = /* @__PURE__ */ new Map();
21281
+ const desiredProps = await resolveReplayProps(previousState.properties, resolver, secrets);
21282
+ const currentProps = await resolveReplayProps(current.properties, resolver, secrets);
21050
21283
  const revertResult = await updateWithRollbackRetry(provider, [
21051
21284
  op.logicalId,
21052
21285
  current.physicalId,
21053
21286
  op.resourceType,
21054
- previousState.properties,
21055
- current.properties
21287
+ desiredProps ?? {},
21288
+ currentProps ?? {}
21056
21289
  ], op.logicalId, logger, isInterrupted);
21057
- stateResources[op.logicalId] = recordAfterRollbackUpdate(previousState, revertResult);
21290
+ stateResources[op.logicalId] = redactRollbackRecord(recordAfterRollbackUpdate(previousState, revertResult), secrets);
21058
21291
  logger.info(` Rollback: ${op.logicalId} restored successfully`);
21059
21292
  await afterOp?.(op.logicalId);
21060
21293
  ctx.recordEvent?.({
@@ -21102,6 +21335,7 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
21102
21335
  remainingFailedOps: []
21103
21336
  };
21104
21337
  const { logger } = ctx;
21338
+ const resolver = new IntrinsicFunctionResolver(ctx.region);
21105
21339
  const emitEnvelope = options.emitEnvelope === true && failedOps.length > 0;
21106
21340
  if (emitEnvelope) ctx.recordEvent?.({
21107
21341
  eventType: "ROLLBACK_STARTED",
@@ -21183,14 +21417,17 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
21183
21417
  resourceType: op.resourceType,
21184
21418
  provisionedBy: op.provisionedBy ?? current.provisionedBy
21185
21419
  });
21420
+ const secrets = /* @__PURE__ */ new Map();
21421
+ const desiredProps = await resolveReplayProps(prev.properties, resolver, secrets);
21422
+ const attemptedProps = await resolveReplayProps(op.attemptedProperties ?? current.properties, resolver, secrets);
21186
21423
  const revertFailedResult = await updateWithRollbackRetry(provider, [
21187
21424
  op.logicalId,
21188
21425
  current.physicalId,
21189
21426
  op.resourceType,
21190
- prev.properties,
21191
- op.attemptedProperties ?? current.properties
21427
+ desiredProps ?? {},
21428
+ attemptedProps ?? {}
21192
21429
  ], op.logicalId, logger, options.isInterrupted);
21193
- stateResources[op.logicalId] = recordAfterRollbackUpdate(prev, revertFailedResult);
21430
+ stateResources[op.logicalId] = redactRollbackRecord(recordAfterRollbackUpdate(prev, revertFailedResult), secrets);
21194
21431
  logger.info(` Rollback: ${op.logicalId} reverted successfully`);
21195
21432
  await options.afterOp?.(op.logicalId);
21196
21433
  ctx.recordEvent?.({
@@ -21316,7 +21553,7 @@ const FLUSH_INTERVAL_MS = 2e3;
21316
21553
  const FLUSH_EVENT_THRESHOLD = 50;
21317
21554
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
21318
21555
  function getCdkdVersion() {
21319
- return "0.283.19";
21556
+ return "0.283.21";
21320
21557
  }
21321
21558
  /**
21322
21559
  * Generate a time-sortable unique run id, e.g.
@@ -21913,6 +22150,30 @@ var DeployEngine = class {
21913
22150
  */
21914
22151
  recordedOutputReads = [];
21915
22152
  /**
22153
+ * PER-RESOURCE map of resolved SECRET dynamic-reference values
22154
+ * (plaintext -> `{{resolve:...}}` expression) the resolver records for each
22155
+ * resource's own resolution (GHSA fix). Keyed by logicalId. Per-resource, NOT
22156
+ * session-wide, because a session-wide map cross-contaminates: if resource A
22157
+ * resolves a `{{resolve:...:SecretString}}` whole-secret reference to value V,
22158
+ * and resource B (e.g. the `AWS::SecretsManager::Secret` that OWNS the secret)
22159
+ * carries V as its own LITERAL property, a session-wide value scan would
22160
+ * wrongly rewrite B's literal to A's expression — a false positive that shows
22161
+ * up as a permanent spurious diff. Redacting each resource only with the
22162
+ * secrets substituted during ITS OWN resolution scopes the value match
22163
+ * correctly. Kept on the engine (not just the resolver context) so the async
22164
+ * observed-property capture — which drains after the context is gone — can
22165
+ * still redact an AWS-readback secret (Cognito `client_secret`). Reset per
22166
+ * `deploy()`. See `secret-redaction.ts`.
22167
+ */
22168
+ perResourceSecrets = /* @__PURE__ */ new Map();
22169
+ /**
22170
+ * Resolved secrets recorded while resolving the stack OUTPUTS (a `CfnOutput`
22171
+ * whose Value resolves a `{{resolve:...}}` reference). Separate from the
22172
+ * per-resource maps for the same anti-cross-contamination reason. Reset per
22173
+ * `deploy()`.
22174
+ */
22175
+ outputSecrets = /* @__PURE__ */ new Map();
22176
+ /**
21916
22177
  * Per-logical-id snapshot of the intrinsic-RESOLVED desired properties
21917
22178
  * each CREATE / UPDATE attempted (issue #1198). Written just before the
21918
22179
  * provider call; read only when the op FAILS, to journal the failed op's
@@ -21953,6 +22214,8 @@ var DeployEngine = class {
21953
22214
  async deploy(stackName, template) {
21954
22215
  this.recordedImports = [];
21955
22216
  this.recordedOutputReads = [];
22217
+ this.perResourceSecrets = /* @__PURE__ */ new Map();
22218
+ this.outputSecrets = /* @__PURE__ */ new Map();
21956
22219
  this.resolver.resetPhysicalIdFallbackCount();
21957
22220
  return withStackName(stackName, () => this.doDeploy(stackName, template));
21958
22221
  }
@@ -21972,7 +22235,63 @@ var DeployEngine = class {
21972
22235
  stackName,
21973
22236
  ...this.exportIndexStore && { exportIndex: this.exportIndexStore },
21974
22237
  recordedImports: this.recordedImports,
21975
- recordedOutputReads: this.recordedOutputReads
22238
+ recordedOutputReads: this.recordedOutputReads,
22239
+ recordedSecretValues: /* @__PURE__ */ new Map()
22240
+ };
22241
+ }
22242
+ /**
22243
+ * Redact resolved secret plaintext out of a bag about to be PERSISTED to
22244
+ * state, replacing each secret value with the unresolved `{{resolve:...}}`
22245
+ * expression it came from (GHSA fix; see `secret-redaction.ts`). No-op when
22246
+ * the deploy recorded no secrets. The bag sent to the AWS API is the
22247
+ * un-redacted resolved bag; only the persisted copy is rewritten.
22248
+ */
22249
+ /**
22250
+ * Bag-level redaction of a single properties bag against a specific secrets
22251
+ * map (GHSA fix). Used by the UPDATE no-op re-check so a resolved-plaintext
22252
+ * bag is compared against the expression-bearing stored bag on equal footing.
22253
+ */
22254
+ redactPropsWith(props, secrets) {
22255
+ if (secrets.size === 0) return props;
22256
+ return redactSecretsForState(props, secrets);
22257
+ }
22258
+ /**
22259
+ * Redact resolved secret plaintext out of rollback-journal operations (GHSA
22260
+ * fix). Each op may carry resolved `properties` / `attemptedProperties` and a
22261
+ * `previousState` snapshot (whose `properties` / `attributes` /
22262
+ * `observedProperties` also hold resolved values). Each op is redacted with
22263
+ * the secrets recorded for ITS OWN resource (`perResourceSecrets`), so a
22264
+ * whole-secret value from one resource cannot rewrite another's literal.
22265
+ * Preserves ops that carry none of those fields, or whose resource recorded
22266
+ * no secret.
22267
+ */
22268
+ redactOperationsForJournal(operations) {
22269
+ return operations.map((op) => {
22270
+ const secrets = this.perResourceSecrets.get(op.logicalId);
22271
+ if (!secrets || secrets.size === 0) return op;
22272
+ const next = { ...op };
22273
+ if (next.properties) next.properties = redactSecretsForState(next.properties, secrets);
22274
+ if (next.attemptedProperties) next.attemptedProperties = redactSecretsForState(next.attemptedProperties, secrets);
22275
+ if (next.previousState) {
22276
+ const prev = { ...next.previousState };
22277
+ prev.properties = redactSecretsForState(prev.properties, secrets);
22278
+ if (prev.attributes) prev.attributes = redactSecretsForState(prev.attributes, secrets);
22279
+ if (prev.observedProperties) prev.observedProperties = redactSecretsForState(prev.observedProperties, secrets);
22280
+ next.previousState = prev;
22281
+ }
22282
+ return next;
22283
+ });
22284
+ }
22285
+ redactStateForPersist(state) {
22286
+ const resources = {};
22287
+ for (const [logicalId, record] of Object.entries(state.resources)) {
22288
+ const secrets = this.perResourceSecrets.get(logicalId);
22289
+ resources[logicalId] = secrets ? scrubResourceRecord(record, secrets) : record;
22290
+ }
22291
+ return {
22292
+ ...state,
22293
+ resources,
22294
+ outputs: this.outputSecrets.size > 0 ? redactSecretsForState(state.outputs, this.outputSecrets) : state.outputs
21976
22295
  };
21977
22296
  }
21978
22297
  /**
@@ -21981,12 +22300,21 @@ var DeployEngine = class {
21981
22300
  * constructed with `options.parentStackInfo` (= it's deploying a
21982
22301
  * nested-stack child). Returns the state unchanged for top-level
21983
22302
  * deploys so the three v6 fields stay absent from non-child state files.
22303
+ *
22304
+ * ALSO the single choke point where resolved SECRET plaintext is redacted out
22305
+ * of the persisted state (GHSA fix): every `stateBackend.saveState` call in
22306
+ * this engine wraps its state through here, so redacting `resources` once here
22307
+ * covers `properties` / `attributes` / `observedProperties` across every
22308
+ * create / update / replacement / rollback / observed-capture path uniformly —
22309
+ * including the async observed-capture drain that runs after the resolver
22310
+ * context is gone (which is why the secret map is session-wide).
21984
22311
  */
21985
22312
  withParentInfo(state) {
21986
- if (!this.options.parentStackInfo) return state;
22313
+ const redacted = this.redactStateForPersist(state);
22314
+ if (!this.options.parentStackInfo) return redacted;
21987
22315
  const { parentStack, parentLogicalId, parentRegion } = this.options.parentStackInfo;
21988
22316
  return {
21989
- ...state,
22317
+ ...redacted,
21990
22318
  parentStack,
21991
22319
  parentLogicalId,
21992
22320
  parentRegion
@@ -22241,13 +22569,14 @@ var DeployEngine = class {
22241
22569
  conditions
22242
22570
  }, stackName);
22243
22571
  diffResolverContext.bestEffort = true;
22572
+ diffResolverContext.skipDynamicReferences = true;
22244
22573
  const diffResolveFn = (value) => this.resolver.resolve(value, diffResolverContext);
22245
22574
  const changes = await this.diffCalculator.calculateDiff(currentState, effectiveTemplate, diffResolveFn, makeCanonicalizePropertiesFn(this.providerRegistry));
22246
22575
  if (!this.diffCalculator.hasChanges(changes)) {
22247
22576
  this.logger.info("No changes detected. Stack is up to date.");
22248
22577
  let persistedOutputs = currentState.outputs ?? {};
22249
22578
  if (!this.options.dryRun) {
22250
- const resolvedOutputs = await this.resolveOutputs(effectiveTemplate, currentState.resources, stackName, parameterValues, conditions);
22579
+ const resolvedOutputs = this.redactPropsWith(await this.resolveOutputs(effectiveTemplate, currentState.resources, stackName, parameterValues, conditions), this.outputSecrets);
22251
22580
  const resolutionFailed = Object.values(resolvedOutputs).some((v) => v === void 0);
22252
22581
  const outputsChanged = !resolutionFailed && !outputMapsEqual(persistedOutputs, resolvedOutputs);
22253
22582
  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 +22904,7 @@ var DeployEngine = class {
22575
22904
  let outputs;
22576
22905
  try {
22577
22906
  outputs = await this.resolveOutputs(template, newResources, stackName, parameterValues, conditions);
22907
+ outputs = this.redactPropsWith(outputs, this.outputSecrets);
22578
22908
  } catch (outputError) {
22579
22909
  await this.persistStateAfterOutputFailure(stackName, currentState, newResources, currentEtag, pendingMigration);
22580
22910
  await this.writeRollbackJournalSegment(stackName, completedOperations, failedOperations, "no-rollback-failure", currentEtag === void 0);
@@ -22730,6 +23060,8 @@ var DeployEngine = class {
22730
23060
  */
22731
23061
  async writeRollbackJournalSegment(stackName, completedOperations, failedOperations, reason, initialDeploy) {
22732
23062
  if (completedOperations.length === 0 && failedOperations.length === 0) return;
23063
+ const redactedCompleted = this.redactOperationsForJournal(completedOperations);
23064
+ const redactedFailed = this.redactOperationsForJournal(failedOperations);
22733
23065
  try {
22734
23066
  const segment = {
22735
23067
  ...this.options.eventRecorder?.runId !== void 0 && { runId: this.options.eventRecorder.runId },
@@ -22738,8 +23070,8 @@ var DeployEngine = class {
22738
23070
  initialDeploy,
22739
23071
  ...this.options.roleArn && { roleArn: this.options.roleArn },
22740
23072
  cdkdVersion: getCdkdVersion(),
22741
- operations: completedOperations,
22742
- ...failedOperations.length > 0 && { failedOperations }
23073
+ operations: redactedCompleted,
23074
+ ...redactedFailed.length > 0 && { failedOperations: redactedFailed }
22743
23075
  };
22744
23076
  await this.stateBackend.appendRollbackJournalSegment(stackName, this.stackRegion, segment);
22745
23077
  this.logger.debug(`Rollback journal segment written (${reason})`);
@@ -22846,10 +23178,29 @@ var DeployEngine = class {
22846
23178
  recordEvent(event) {
22847
23179
  if (!this.options.eventRecorder) return;
22848
23180
  try {
22849
- this.options.eventRecorder.record(event);
23181
+ this.options.eventRecorder.record(this.maskSecretsInEvent(event));
22850
23182
  } catch {}
22851
23183
  }
22852
23184
  /**
23185
+ * Mask any resolved secret value out of an event's human-authored text before
23186
+ * it is persisted to `deployments/*.jsonl` (which outlives `cdkd destroy`)
23187
+ * — GHSA fix. An AWS validation error can quote the offending property value
23188
+ * (`Value '<secret>' at 'X' failed to satisfy ...`), and a provider `reason`
23189
+ * is provider-authored prose; both reach the event store as `error.message` /
23190
+ * `reason`. No-op when the deploy recorded no secrets.
23191
+ */
23192
+ maskSecretsInEvent(event) {
23193
+ const secrets = event.logicalId ? this.perResourceSecrets.get(event.logicalId) : void 0;
23194
+ if (!secrets || secrets.size === 0) return event;
23195
+ const next = { ...event };
23196
+ if (next.error?.message) next.error = {
23197
+ ...next.error,
23198
+ message: maskSecretsInText(next.error.message, secrets)
23199
+ };
23200
+ if (next.reason) next.reason = maskSecretsInText(next.reason, secrets);
23201
+ return next;
23202
+ }
23203
+ /**
22853
23204
  * Issue #1002 PR 2 — §7 step 3 post-resolution audit (defense in depth).
22854
23205
  * No-op in legacy mode (`options.assetRedirect` unset). In cdkd-assets
22855
23206
  * mode, a resolved property still naming a mapped SOURCE (CDK bootstrap)
@@ -22949,6 +23300,7 @@ var DeployEngine = class {
22949
23300
  ...conditions && { conditions }
22950
23301
  }, stackName);
22951
23302
  const resolvedProps = await this.resolver.resolve(desiredProps, context);
23303
+ if (context.recordedSecretValues) this.perResourceSecrets.set(logicalId, context.recordedSecretValues);
22952
23304
  this.auditResolvedAssetReferences(logicalId, resourceType, resolvedProps);
22953
23305
  this.attemptedResolvedProps.set(logicalId, resolvedProps);
22954
23306
  const createDecision = this.providerRegistry.getProviderFor({
@@ -22990,9 +23342,11 @@ var DeployEngine = class {
22990
23342
  ...conditions && { conditions }
22991
23343
  }, stackName);
22992
23344
  const resolvedProps = await this.resolver.resolve(desiredProps, context);
23345
+ const updateSecrets = context.recordedSecretValues ?? /* @__PURE__ */ new Map();
23346
+ this.perResourceSecrets.set(logicalId, updateSecrets);
22993
23347
  this.auditResolvedAssetReferences(logicalId, resourceType, resolvedProps);
22994
23348
  this.attemptedResolvedProps.set(logicalId, resolvedProps);
22995
- if (JSON.stringify(resolvedProps) === JSON.stringify(currentProps)) {
23349
+ if (JSON.stringify(this.redactPropsWith(resolvedProps, updateSecrets)) === JSON.stringify(currentProps)) {
22996
23350
  if (change.attributeChanges && change.attributeChanges.length > 0) {
22997
23351
  const attrSummary = change.attributeChanges.map((a) => `${a.attribute}: ${a.oldValue ?? "(unset)"} → ${a.newValue ?? "(unset)"}`).join(", ");
22998
23352
  this.logger.info(` ↻ ${logicalId} (${resourceType}) attribute update: ${attrSummary}`);
@@ -23518,6 +23872,7 @@ var DeployEngine = class {
23518
23872
  outputs[outputKey] = void 0;
23519
23873
  }
23520
23874
  }
23875
+ if (context.recordedSecretValues) for (const [value, expr] of context.recordedSecretValues) this.outputSecrets.set(value, expr);
23521
23876
  return outputs;
23522
23877
  }
23523
23878
  buildDisplayOutputs(template, resolvedOutputs) {
@@ -23532,5 +23887,5 @@ var DeployEngine = class {
23532
23887
  };
23533
23888
 
23534
23889
  //#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-UVLw029j.js.map
23890
+ 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 };
23891
+ //# sourceMappingURL=deploy-engine-ISSt01TI.js.map