@go-to-k/cdkd 0.284.62 → 0.284.64

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.
@@ -1,5 +1,6 @@
1
1
  import { a as getLiveRenderer, d as generateResourceNameWithFallback, f as getCurrentStackName, h as withStackName, l as applyDefaultNameForFallback, n as getLogger, p as looksLikeCdkdGeneratedName, u as generateResourceName } from "./logger-zRrlbaQt.js";
2
- import { t as getCdkdVersion } from "./version-DoW7XkO0.js";
2
+ import { t as getCdkdVersion } from "./version-BtSUTHs5.js";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
3
4
  import { randomUUID } from "node:crypto";
4
5
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
5
6
  import { CloudControlClient, CreateResourceCommand, DeleteResourceCommand, GetResourceCommand, GetResourceRequestStatusCommand, ListResourcesCommand, UpdateResourceCommand } from "@aws-sdk/client-cloudcontrol";
@@ -11709,6 +11710,10 @@ function literalStringOrUndefined(value) {
11709
11710
  * (`(producer X / Y)`), so it is neither derivable from the source leaf nor
11710
11711
  * stable.
11711
11712
  *
11713
+ * THREE arms answer: `Fn::ImportValue`, `Fn::GetStackOutput`, and the
11714
+ * `Fn::GetAtt` on a nested-stack OUTPUT that issue #2055's read site
11715
+ * re-resolves. Every other leaf refuses.
11716
+ *
11712
11717
  * `Region` and `RoleArn` are OPTIONAL slots, and an ABSENT one keys as empty
11713
11718
  * while a PRESENT-but-non-literal one refuses. Absent has to be its own key
11714
11719
  * rather than being filled in with the resolver's own region: the persist path
@@ -11767,6 +11772,26 @@ function crossStackSourceKey(source) {
11767
11772
  }
11768
11773
  return slots.join(CROSS_STACK_KEY_SEPARATOR);
11769
11774
  }
11775
+ if (key === "Fn::GetAtt") {
11776
+ const raw = source[key];
11777
+ let logicalId;
11778
+ let attributeName;
11779
+ if (typeof raw === "string") {
11780
+ const parts = raw.split(".");
11781
+ if (parts.length !== 2) return void 0;
11782
+ logicalId = literalStringOrUndefined(parts[0]);
11783
+ attributeName = literalStringOrUndefined(parts[1]);
11784
+ } else if (Array.isArray(raw) && raw.length === 2) {
11785
+ logicalId = literalStringOrUndefined(raw[0]);
11786
+ attributeName = literalStringOrUndefined(raw[1]);
11787
+ }
11788
+ if (logicalId === void 0 || attributeName === void 0) return void 0;
11789
+ return [
11790
+ "Fn::GetAtt",
11791
+ logicalId,
11792
+ attributeName
11793
+ ].join(CROSS_STACK_KEY_SEPARATOR);
11794
+ }
11770
11795
  }
11771
11796
  /**
11772
11797
  * Remember, FOR THE PASS THAT OWNS `secrets`, that the cross-stack source leaf
@@ -12335,7 +12360,7 @@ function plaintextIndexOf(secrets) {
12335
12360
  * bag could not be vouched for, because it rewrote a `{Name: '', Value:
12336
12361
  * 'an-unrelated-literal'}` pair. Nothing here can do that: the answer is never
12337
12362
  * the source subtree, it is an expression a WRITER recorded against this exact
12338
- * leaf identity; the arm fires for exactly two intrinsic spellings; and
12363
+ * leaf identity; the arm fires for exactly three intrinsic spellings; and
12339
12364
  * condition 1 still demands that the bag leaf be a plaintext this pass
12340
12365
  * resolved. Every rejection degrades to {@link positionByIntrinsicSkeleton} and
12341
12366
  * then to the value scan, i.e. to today's behavior.
@@ -14868,6 +14893,36 @@ function carriesDynamicReference(value) {
14868
14893
  if (value !== null && typeof value === "object") return Object.values(value).some(carriesDynamicReference);
14869
14894
  return false;
14870
14895
  }
14896
+ /** The nested-stack resource type, whose `Outputs.<Name>` attributes are re-resolved (issue #2055). */
14897
+ const NESTED_STACK_RESOURCE_TYPE = "AWS::CloudFormation::Stack";
14898
+ /** Prefix `NestedStackProvider` records a child stack output under. */
14899
+ const NESTED_STACK_OUTPUT_ATTRIBUTE_PREFIX = "Outputs.";
14900
+ /**
14901
+ * `arn:cdkd-local:<childRegion>:<accountId>:nested-stack/<parent>/<logicalId>` —
14902
+ * the synthesized physicalId `NestedStackProvider.synthesizeArn` records on the
14903
+ * parent's `AWS::CloudFormation::Stack` row.
14904
+ */
14905
+ const NESTED_STACK_LOCAL_ARN = /^arn:cdkd-local:([a-z0-9-]+):[^:]*:nested-stack\//i;
14906
+ /**
14907
+ * The CHILD stack's region, read off the parent row's synthesized physicalId
14908
+ * (issue [#2055](https://github.com/go-to-k/cdkd/issues/2055)).
14909
+ *
14910
+ * WHY THE ARN AND NOT A STATE READ. The child's own record carries `region`,
14911
+ * but its state KEY is `cdkd/<parent>~<logicalId>/<region>/state.json` — the
14912
+ * region is part of the key, so reading the record to learn the region is
14913
+ * circular. The synthesized physicalId is the SAME provider's durable record of
14914
+ * the region it deployed the child into, it sits on the resource row the
14915
+ * resolver already holds, and reading it costs no I/O on a path that is
14916
+ * otherwise hot.
14917
+ *
14918
+ * Returns `undefined` for anything that is not that shape (a hand-edited state
14919
+ * file, a record written before this provider existed), which the caller reads
14920
+ * as "use this resolver's own region".
14921
+ */
14922
+ function nestedStackChildRegionFromLocalArn(physicalId) {
14923
+ if (typeof physicalId !== "string") return void 0;
14924
+ return NESTED_STACK_LOCAL_ARN.exec(physicalId)?.[1];
14925
+ }
14871
14926
  let cachedAccountIdentity = null;
14872
14927
  /**
14873
14928
  * Cache for availability zones per region
@@ -15224,6 +15279,79 @@ function collectReferencedParameterNames(template) {
15224
15279
  return referenced;
15225
15280
  }
15226
15281
  /**
15282
+ * Does coercing to `type` risk destroying the plaintext cdkd redacts against?
15283
+ *
15284
+ * DERIVED from {@link coerceParameterTypedValue}, never enumerated beside it.
15285
+ * The previous shape was a hand-kept set naming `Number` / `List<Number>`,
15286
+ * whose doc cleared `CommaDelimitedList` as safe because it "produces an array
15287
+ * of strings (both of which the recording scan and the redactor handle)". That
15288
+ * holds only for a comma-FREE secret -- and the dominant Secrets Manager shape
15289
+ * is a JSON blob, which is nothing but commas, so `,`-splitting shreds the
15290
+ * plaintext into fragments matching neither arm of
15291
+ * {@link inheritedSecretsCarriedBy}. An audited allow-list was wrong about one
15292
+ * of its own three entries, which is why this is now measured, not listed.
15293
+ *
15294
+ * Probe the REAL coercion with a canary carrying the separators the arms use --
15295
+ * a comma and surrounding whitespace -- and call the type risky when the canary
15296
+ * does not survive as one string. A `Type` added to the switch is covered the
15297
+ * day it is added, with nothing to keep in sync.
15298
+ *
15299
+ * The DEPLOY path does better: `refuseCoercedInheritedSecret` measures the loss
15300
+ * on the ACTUAL value, so a comma-free secret in a `CommaDelimitedList` still
15301
+ * works. This coarser predicate is for `cdkd diff`, which holds no secrets bag
15302
+ * and therefore cannot measure.
15303
+ */
15304
+ const SECRET_IDENTITY_CANARY = "a, b";
15305
+ function parameterTypeMayLoseSecretIdentity(type) {
15306
+ return coerceParameterTypedValue(SECRET_IDENTITY_CANARY, type) !== SECRET_IDENTITY_CANARY;
15307
+ }
15308
+ /**
15309
+ * ONE definition of parameter-type coercion, at module scope so
15310
+ * {@link parameterTypeMayLoseSecretIdentity} probes the same code the resolver
15311
+ * runs rather than a copy of it.
15312
+ */
15313
+ function coerceParameterTypedValue(value, type) {
15314
+ switch (type) {
15315
+ case "Number": return Number(value);
15316
+ case "List<Number>": return value.split(",").map((v) => Number(v.trim()));
15317
+ case "CommaDelimitedList": return value.split(",").map((v) => v.trim());
15318
+ default: return value;
15319
+ }
15320
+ }
15321
+ /**
15322
+ * The inherited `plaintext -> expression` pairs that `value` CARRIES.
15323
+ *
15324
+ * ONE definition, shared by the RECORDING side
15325
+ * (`recordInheritedParameterSecrets`) and the REFUSAL side
15326
+ * (`refuseCoercedInheritedSecret`), because a refusal narrower than the
15327
+ * recording would let exactly the values it exists to catch through — and the
15328
+ * two drifting apart is how this class of bug reappears.
15329
+ *
15330
+ * TWO ARMS, mirroring the two `redactSecretsForState` performs, so the
15331
+ * recording side cannot be narrower than the redaction side:
15332
+ *
15333
+ * - WHOLE VALUE at any length — `{Ref: Param}` returning exactly the secret.
15334
+ * - SUBSTRING at or above {@link MIN_NEEDLE_LENGTH} — the parent built the
15335
+ * parameter with an `Fn::Sub`, so the value is `postgres://u:<secret>@host`
15336
+ * and only part of it is the secret. Short needles are excluded on this arm
15337
+ * for the same reason the redactor excludes them: a 3-character secret
15338
+ * matches half the alphabet's worth of ordinary identifiers.
15339
+ *
15340
+ * A `CommaDelimitedList` parameter arrives as an array, so the scan walks
15341
+ * string elements too.
15342
+ */
15343
+ function inheritedSecretsCarriedBy(value, inherited) {
15344
+ const candidates = [];
15345
+ if (typeof value === "string") candidates.push(value);
15346
+ else if (Array.isArray(value)) {
15347
+ for (const element of value) if (typeof element === "string") candidates.push(element);
15348
+ }
15349
+ if (candidates.length === 0) return [];
15350
+ const carried = [];
15351
+ for (const [plaintext, expression] of inherited) if (candidates.some((candidate) => candidate === plaintext || plaintext.length >= 4 && candidate.includes(plaintext))) carried.push([plaintext, expression]);
15352
+ return carried;
15353
+ }
15354
+ /**
15227
15355
  * Render a parameter VALUE for a debug log line, honoring the definition's
15228
15356
  * `NoEcho` flag (issue #1329). `NoEcho: true` is the template author's
15229
15357
  * explicit "this value is sensitive" declaration — CloudFormation masks such
@@ -15669,7 +15797,9 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
15669
15797
  * @param userParameters User-provided parameter values (e.g., from CLI)
15670
15798
  * @returns Record of parameter names to resolved values
15671
15799
  */
15672
- async resolveParameters(template, userParameters) {
15800
+ async resolveParameters(template, userParameters, options) {
15801
+ const inheritedSecrets = options?.inheritedSecrets;
15802
+ const maskInherited = (text) => inheritedSecrets && inheritedSecrets.size > 0 ? maskSecretsInText(text, inheritedSecrets) : text;
15673
15803
  const parameters = {};
15674
15804
  const templateParameters = template.Parameters;
15675
15805
  if (!templateParameters || typeof templateParameters !== "object") return parameters;
@@ -15679,8 +15809,9 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
15679
15809
  if (userParameters && name in userParameters) {
15680
15810
  const userValue = userParameters[name];
15681
15811
  if (userValue !== void 0) {
15812
+ this.refuseCoercedInheritedSecret(name, paramDef, userValue, inheritedSecrets);
15682
15813
  parameters[name] = this.coerceParameterValue(userValue, paramDef.Type);
15683
- this.logger.debug(`Parameter ${name}: using user-provided value ${stringifyParameterForLog(paramDef, userValue)}`);
15814
+ this.logger.debug(`Parameter ${name}: using user-provided value ${maskInherited(stringifyParameterForLog(paramDef, userValue))}`);
15684
15815
  continue;
15685
15816
  }
15686
15817
  }
@@ -15695,11 +15826,11 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
15695
15826
  this.logger.debug(`Parameter ${name}: resolving SSM parameter path ${ssmPath}`);
15696
15827
  const resolved = await this.resolveSSMParameter(ssmPath);
15697
15828
  parameters[name] = resolved;
15698
- this.logger.debug(`Parameter ${name}: resolved SSM value ${stringifyParameterForLog(paramDef, resolved)}`);
15829
+ this.logger.debug(`Parameter ${name}: resolved SSM value ${maskInherited(stringifyParameterForLog(paramDef, resolved))}`);
15699
15830
  continue;
15700
15831
  }
15701
15832
  parameters[name] = paramDef.Default;
15702
- this.logger.debug(`Parameter ${name}: using default value ${stringifyParameterForLog(paramDef, paramDef.Default)}`);
15833
+ this.logger.debug(`Parameter ${name}: using default value ${maskInherited(stringifyParameterForLog(paramDef, paramDef.Default))}`);
15703
15834
  continue;
15704
15835
  }
15705
15836
  throw new Error(`Parameter ${name} is required but no value was provided and no default exists`);
@@ -15717,12 +15848,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
15717
15848
  * Coerce parameter value to the correct type based on parameter definition
15718
15849
  */
15719
15850
  coerceParameterValue(value, type) {
15720
- switch (type) {
15721
- case "Number": return Number(value);
15722
- case "List<Number>": return value.split(",").map((v) => Number(v.trim()));
15723
- case "CommaDelimitedList": return value.split(",").map((v) => v.trim());
15724
- default: return value;
15725
- }
15851
+ return coerceParameterTypedValue(value, type);
15726
15852
  }
15727
15853
  /**
15728
15854
  * Resolve all intrinsic functions in a value
@@ -15812,6 +15938,101 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
15812
15938
  return resolved;
15813
15939
  }
15814
15940
  /**
15941
+ * Copy any {@link ResolverContext.inheritedSecrets} pair whose PLAINTEXT is
15942
+ * present in a just-resolved parameter value into this context's
15943
+ * `recordedSecretValues` (issues #1903 / #2087).
15944
+ *
15945
+ * WHY AT RESOLUTION TIME. This is the whole of the #2087 fix. The parent
15946
+ * hands a nested child already-resolved plaintext, so the child's own
15947
+ * resolution never sees a `{{resolve:` and cannot record the pair itself; the
15948
+ * first cut pre-SEEDED every child resource's map with the parent's bag,
15949
+ * which restored the redaction but destroyed the per-resource scoping
15950
+ * `perResourceSecrets` exists for. `redactSecretsForState` substring-matches
15951
+ * at or above {@link MIN_NEEDLE_LENGTH}, so a child resource that never
15952
+ * referenced the parameter but happens to spell `my-production-bucket` while
15953
+ * the secret is `production` had its state persisted as
15954
+ * `my-{{resolve:...}}-bucket` — which `redactParametersForDiff` does NOT
15955
+ * mirror on the desired side (it rewrites only the PARAMETERS), so every
15956
+ * later deploy saw a change: a perpetual UPDATE, or a perpetual REPLACEMENT
15957
+ * on a create-only property.
15958
+ *
15959
+ * Recording here binds the pair to exactly the resources whose resolution
15960
+ * consumed the parameter — which are exactly the ones that can carry the
15961
+ * plaintext into their persisted state — so the child gets the SAME scoping
15962
+ * RULE the PARENT already has, where `perResourceSecrets` is keyed by logical
15963
+ * id.
15964
+ *
15965
+ * That is PARITY with the parent, not a claim of exactness. Once a pair is in
15966
+ * a resource's bag, `redactSecretsForState` substring-matches every leaf of
15967
+ * THAT resource, so a resource which both `Ref`s the parameter and carries an
15968
+ * unrelated literal spelling the plaintext has the literal rewritten too. The
15969
+ * parent has precisely this residual for any resource that resolves a
15970
+ * `{{resolve:...}}`; what #2087 removed was the much wider version, where
15971
+ * every resource in the child got the bag whether it consumed the parameter
15972
+ * or not.
15973
+ *
15974
+ * The TWO ARMS of the match live in {@link inheritedSecretsCarriedBy}, shared
15975
+ * with the refusal below so the two can never drift apart.
15976
+ *
15977
+ * Covers every consumption shape, because `Fn::Sub` / `Fn::Join` /
15978
+ * `Fn::Select` / `Fn::FindInMap` all re-enter `resolveValue` and reach the
15979
+ * parameter through this same `Ref` branch.
15980
+ *
15981
+ * Substituting is deliberately NOT done here — the resolved value is what
15982
+ * reaches AWS, and an `Fn::Equals` over a parameter must compare the real
15983
+ * value or the condition flips.
15984
+ */
15985
+ recordInheritedParameterSecrets(value, context) {
15986
+ const inherited = context.inheritedSecrets;
15987
+ const recorded = context.recordedSecretValues;
15988
+ if (!inherited || inherited.size === 0 || !recorded) return;
15989
+ for (const [plaintext, expression] of inheritedSecretsCarriedBy(value, inherited)) recorded.set(plaintext, expression);
15990
+ }
15991
+ /**
15992
+ * Refuse a child parameter whose declared `Type` would COERCE an inherited
15993
+ * secret out of cdkd's string-keyed secret model (issue #1903, review round
15994
+ * 2).
15995
+ *
15996
+ * THE MODEL IS STRING-KEYED END TO END. `RecordedSecretValues` is keyed by
15997
+ * plaintext STRING, {@link recordInheritedParameterSecrets} scans strings and
15998
+ * string array elements, and `redactSecretsForState` rewrites string LEAVES.
15999
+ * `coerceParameterValue` turns a `Number` / `List<Number>` parameter into a JS
16000
+ * number before any of that runs, so the pair was never recorded, the leaf was
16001
+ * never rewritten, and the child's `state.json` persisted the DECRYPTED value
16002
+ * verbatim — the exact disclosure this issue closes for `String` parameters —
16003
+ * with `cdkd diff --recursive` then reporting a change on every run.
16004
+ *
16005
+ * WHY A REFUSAL RATHER THAN RECORDING ON THE PRE-COERCION STRING. Recording
16006
+ * the pair is not enough on its own: the persisted leaf is a NUMBER, so the
16007
+ * redactor would additionally have to rewrite a number leaf into an
16008
+ * expression STRING, matched by `String(n) === plaintext`. That comparison
16009
+ * both UNDER-covers (`"007"` coerces to `7` and stringifies back to `"7"`, so
16010
+ * a zero-padded secret silently stays plaintext) and OVER-covers (a numeric
16011
+ * secret like `8080` whole-value-matches every unrelated port in the bag —
16012
+ * issue #2087's class, on a path where `MIN_NEEDLE_LENGTH` does not apply).
16013
+ * A remedy that can silently under-cover is the wrong one for a disclosure
16014
+ * path, so this refuses and NAMES the parameter instead.
16015
+ *
16016
+ * The blast radius is nil for CDK-authored apps: CDK synthesizes every
16017
+ * nested-stack cross-reference parameter as `Type: String`. A hand-authored
16018
+ * template that really wants a numeric secret can declare the parameter
16019
+ * `String` and keep the value a string, which is what CloudFormation's own
16020
+ * `NoEcho` / dynamic-reference handling assumes anyway.
16021
+ *
16022
+ * SCOPED TO THE INHERITED BAG, which is non-empty only on a nested-stack
16023
+ * child engine, and only for a value that actually carries a pair the parent
16024
+ * PROVED secret. An ordinary `Type: Number` parameter is untouched.
16025
+ *
16026
+ * The message never quotes the value.
16027
+ */
16028
+ refuseCoercedInheritedSecret(name, paramDef, userValue, inherited) {
16029
+ if (!inherited || inherited.size === 0) return;
16030
+ const carriedBefore = inheritedSecretsCarriedBy(userValue, inherited).length;
16031
+ if (carriedBefore === 0) return;
16032
+ if (inheritedSecretsCarriedBy(this.coerceParameterValue(userValue, paramDef.Type), inherited).length >= carriedBefore) return;
16033
+ throw markNonRetryable(new IntrinsicResolutionRefusalError(`Nested-stack parameter '${name}' is declared 'Type: ${paramDef.Type}', but the parent stack resolved a SECRET dynamic reference into it. cdkd keeps a resolved secret out of persisted state by rewriting STRING leaves back to their {{resolve:...}} expression; coercing this value to '${paramDef.Type}' destroys the plaintext cdkd would have matched on, so the DECRYPTED secret would be left in the child stack's state.json with nothing to redact it back to. Declare '${name}' as 'Type: String' in the nested stack's template (CDK does this by default for cross-stack references), or stop passing a secret reference into it.`, void 0, "NESTED_STACK_SECRET_PARAMETER_TYPE"));
16034
+ }
16035
+ /**
15815
16036
  * Resolve Ref intrinsic function
15816
16037
  *
15817
16038
  * Ref can reference:
@@ -15829,7 +16050,8 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
15829
16050
  if (context.parameters && logicalId in context.parameters) {
15830
16051
  const value = context.parameters[logicalId];
15831
16052
  const paramDef = context.template.Parameters?.[logicalId];
15832
- this.logger.debug(`Resolved Ref to parameter: ${logicalId} -> ${stringifyParameterForLog(paramDef, value)}`);
16053
+ this.logger.debug(`Resolved Ref to parameter: ${logicalId} -> ${this.maskSecretsForLog(stringifyParameterForLog(paramDef, value), context)}`);
16054
+ this.recordInheritedParameterSecrets(value, context);
15833
16055
  return value;
15834
16056
  }
15835
16057
  const pseudoValue = await this.resolvePseudoParameter(logicalId, context);
@@ -15934,6 +16156,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
15934
16156
  return nameServers;
15935
16157
  }
15936
16158
  this.logger.debug(`Resolved Fn::GetAtt from attributes: ${logicalId}.${attributeName} -> ${stringifyAttributeForLog(attributeName, flatValue)}`);
16159
+ if (resource.resourceType === NESTED_STACK_RESOURCE_TYPE && attributeName.startsWith(NESTED_STACK_OUTPUT_ATTRIBUTE_PREFIX) && carriesDynamicReference(flatValue)) return await this.reresolveCrossStackValue(flatValue, nestedStackChildRegionFromLocalArn(resource.physicalId), context, `nested stack ${logicalId} ${attributeName}`, crossStackSourceKey({ "Fn::GetAtt": getAtt }));
15937
16160
  return flatValue;
15938
16161
  }
15939
16162
  if (attributeName.includes(".")) {
@@ -17453,8 +17676,12 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
17453
17676
  * recorded no secrets.
17454
17677
  */
17455
17678
  maskSecretsForLog(text, context) {
17679
+ let masked = text;
17680
+ const inherited = context?.inheritedSecrets;
17681
+ if (inherited && inherited.size > 0) masked = maskSecretsInText(masked, inherited);
17456
17682
  const secrets = context?.recordedSecretValues;
17457
- return secrets ? maskSecretsInText(text, secrets) : text;
17683
+ if (secrets && secrets.size > 0) masked = maskSecretsInText(masked, secrets);
17684
+ return masked;
17458
17685
  }
17459
17686
  async resolveDynamicReferences(value, context) {
17460
17687
  const pattern = /\{\{resolve:([^}]+)\}\}/g;
@@ -18617,7 +18844,7 @@ var CloudControlProvider = class {
18617
18844
  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);
18618
18845
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
18619
18846
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
18620
- const { ASGProvider } = await import("./asg-provider-BfX7AwFi.js").then((n) => n.n);
18847
+ const { ASGProvider } = await import("./asg-provider-DGJz_iFy.js").then((n) => n.n);
18621
18848
  return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
18622
18849
  }
18623
18850
  const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
@@ -24609,6 +24836,67 @@ function collectInlinePolicyNamesManagedBySiblings(targetPhysicalId, context, at
24609
24836
  return result;
24610
24837
  }
24611
24838
 
24839
+ //#endregion
24840
+ //#region src/deployment/resource-secrets-scope.ts
24841
+ /**
24842
+ * The secrets THIS process substituted into the property bag of the resource
24843
+ * currently being provisioned, scoped to that provider call's async chain
24844
+ * (issue [#1903](https://github.com/go-to-k/cdkd/issues/1903)).
24845
+ *
24846
+ * WHY AN ASYNC-LOCAL STORE RATHER THAN A FIELD ON `CreateContext`. Exactly ONE
24847
+ * provider needs the pairs — `NestedStackProvider`, which must SEED them into
24848
+ * the child `DeployEngine` it builds (see
24849
+ * `DeployEngineOptions.inheritedSecrets`) — and a `RecordedSecretValues` is
24850
+ * keyed by PLAINTEXT. `.claude/rules/providers.md` already records the rule
24851
+ * this follows: the reason `SecretMaskingContext` carries a masking FUNCTION
24852
+ * and not the bag is that putting the bag on the shared context makes every one
24853
+ * of the ~130 registered providers a place a `[...secrets.keys()]` can leak
24854
+ * from. A function cannot substitute here — seeding needs the pairs, not the
24855
+ * ability to mask — so the bag is handed through a channel only this one
24856
+ * provider reads, instead of widening the type every provider sees.
24857
+ *
24858
+ * It is also the idiom this particular provider already lives in:
24859
+ * `NestedStackProvider` reads its whole world out of
24860
+ * `getCurrentNestedStackContext()`, another `AsyncLocalStorage`.
24861
+ *
24862
+ * WHY ITS OWN LEAF MODULE rather than living in `deploy-engine.ts`, where it
24863
+ * started. Both BINDERS need it — the deploy engine and
24864
+ * `rollback-executor.ts`, whose replay arms re-resolve the journal's
24865
+ * `{{resolve:...}}` back to plaintext and drive the very same providers (issue
24866
+ * [#2086](https://github.com/go-to-k/cdkd/issues/2086)) — and
24867
+ * `deploy-engine.ts` already imports `rollback-executor.ts`, so keeping the
24868
+ * store there would have made the two modules a cycle. A leaf that imports one
24869
+ * TYPE cannot participate in one.
24870
+ *
24871
+ * SCOPE. {@link withCurrentResourceSecrets} wraps the provider CREATE / UPDATE
24872
+ * call itself, so the store is bound per resource and per retry attempt, and
24873
+ * two resources provisioned concurrently under `--concurrency` cannot see each
24874
+ * other's bag. Absent (every caller that binds nothing — `cdkd drift --revert`,
24875
+ * the import path, tests) reads as `undefined`, which the provider treats as
24876
+ * "no secrets to inherit" — the pre-#1903 behaviour.
24877
+ */
24878
+ const currentResourceSecretsStore = new AsyncLocalStorage();
24879
+ /**
24880
+ * Run `fn` with `secrets` visible to {@link getCurrentResourceSecrets}. Used by
24881
+ * the deploy engine and the rollback executor around a provider CREATE / UPDATE
24882
+ * call; see the store's own doc for why the bag travels this way rather than on
24883
+ * `CreateContext`.
24884
+ */
24885
+ function withCurrentResourceSecrets(secrets, fn) {
24886
+ return currentResourceSecretsStore.run(secrets, fn);
24887
+ }
24888
+ /**
24889
+ * The bag {@link withCurrentResourceSecrets} bound for the provider call
24890
+ * currently in flight, or `undefined` when no binder is on the stack.
24891
+ *
24892
+ * Read by `NestedStackProvider` alone. A provider reading this MUST NOT
24893
+ * enumerate or log its KEYS — they are secret plaintext; the only sanctioned
24894
+ * use is handing the map on as a redaction seed.
24895
+ */
24896
+ function getCurrentResourceSecrets() {
24897
+ return currentResourceSecretsStore.getStore();
24898
+ }
24899
+
24612
24900
  //#endregion
24613
24901
  //#region src/deployment/outputs-export-alias.ts
24614
24902
  /**
@@ -24860,9 +25148,12 @@ function exportAliasCollisionWarning(outputKey, exportName) {
24860
25148
  * {@link collectDeclaredOutputNames}.
24861
25149
  */
24862
25150
  function exportAliasCollisionScrubWarning(outputKey, exportName, secrets) {
24863
- const exposure = secretsPresentIn(exportName, secrets);
24864
- const shown = stripControlChars(exposure ? maskEveryOccurrence(exportName, exposure) : exportName);
24865
- return `Output ${stripControlChars(outputKey)} exports as "${shown}", which is also the name of another output in this stack — state cannot say which of the two the stored value under "${shown}" came from, so that key is redacted by value match instead of by template position, and two references resolving to the same value could still collapse there. Rename the export, or the colliding output, and redeploy.`;
25151
+ const mask = (name) => {
25152
+ const exposure = secretsPresentIn(name, secrets);
25153
+ return stripControlChars(exposure ? maskEveryOccurrence(name, exposure) : name);
25154
+ };
25155
+ const shown = mask(exportName);
25156
+ return `Output ${mask(outputKey)} exports as "${shown}", which is also the name of another output in this stack — state cannot say which of the two the stored value under "${shown}" came from, so that key is redacted by value match instead of by template position, and two references resolving to the same value could still collapse there. Rename the export, or the colliding output, and redeploy.`;
24866
25157
  }
24867
25158
 
24868
25159
  //#endregion
@@ -26508,6 +26799,29 @@ async function replayRollback(operations, stateResources, stackName, ctx, option
26508
26799
  * backoff schedule per op — ~47s on the generic grid, or ~64s if the op
26509
26800
  * hits a name cooldown, which rides its own longer grid since issue #2116.
26510
26801
  *
26802
+ * A FOURTH thing since issue
26803
+ * [#2086](https://github.com/go-to-k/cdkd/issues/2086): the call is bound in
26804
+ * {@link withCurrentResourceSecrets}, the async-local channel
26805
+ * `NestedStackProvider` reads to seed a nested CHILD engine with the pairs the
26806
+ * parent already resolved (issue #1903). `resolveReplayProps` has just
26807
+ * re-resolved the journal's `{{resolve:...}}` expressions back to PLAINTEXT
26808
+ * into `secrets`, so the bag in hand here is exactly the one the deploy engine
26809
+ * would have bound — and without the binding a rollback that reverts a
26810
+ * nested-stack row calls `NestedStackProvider.update`, the child engine seeds
26811
+ * nothing, and the child's `state.json` is rewritten with the DECRYPTED secret.
26812
+ * A recovery path that restores the pre-fix behaviour re-opens the very
26813
+ * disclosure the fix closes, so "absent reads as undefined, the pre-#1903
26814
+ * baseline" is not an acceptable answer HERE, however it reads elsewhere.
26815
+ *
26816
+ * `NestedStackProvider` is reachable on this path by construction, not in
26817
+ * theory: it is one of the two `disableOuterRetry` providers named above that
26818
+ * also implement `update()`, and `cdkd deploy`'s in-process auto-rollback runs
26819
+ * inside a DEPLOY-mode `withNestedStackContext` (`deploy.ts` passes
26820
+ * `nestedTemplates` / `dagBuilder` / `diffCalculator`). Standalone `cdkd
26821
+ * rollback` is NOT affected — `rollback.ts` builds a destroy-mode context with
26822
+ * none of those three fields, so `requireDeployContext` throws loudly before
26823
+ * any child engine is built.
26824
+ *
26511
26825
  * Returns the provider's result so the caller can honour
26512
26826
  * `effectiveProperties` (issue #1644) — both revert arms used to write the
26513
26827
  * previous state record back verbatim, dropping a narrowing the provider had
@@ -26740,8 +27054,8 @@ function redactRollbackRecord(record, secrets, journaledProps) {
26740
27054
  }, secrets);
26741
27055
  }
26742
27056
  async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted, secrets) {
26743
- if (provider.disableOuterRetry) return await provider.update(...args);
26744
- return await withRetry(() => provider.update(...args), logicalId, {
27057
+ if (provider.disableOuterRetry) return await withCurrentResourceSecrets(secrets, () => provider.update(...args));
27058
+ return await withRetry(() => withCurrentResourceSecrets(secrets, () => provider.update(...args)), logicalId, {
26745
27059
  logger: maskingRetryLogger(logger, secrets),
26746
27060
  ...isInterrupted && {
26747
27061
  isInterrupted,
@@ -26819,6 +27133,16 @@ async function updateWithRollbackRetry(provider, args, logicalId, logger, isInte
26819
27133
  * now earns its place by ALSO covering the late name release that the inner
26820
27134
  * default classifier rejects. The two compound — measured at 640s of total
26821
27135
  * sleep on a cooldown, inside the 30-minute per-resource deadline.
27136
+ *
27137
+ * ## The secrets scope, on both call sites (issue #2086)
27138
+ *
27139
+ * Each caller's `create` thunk binds {@link withCurrentResourceSecrets} around
27140
+ * `createProvider.create(...)`, for the same reason
27141
+ * {@link updateWithRollbackRetry} does around `update(...)`: a
27142
+ * reverse-replacement replay of an `AWS::CloudFormation::Stack` row re-CREATES
27143
+ * the child, and an unbound store makes the child engine persist the parent's
27144
+ * plaintext. It sits INSIDE the thunk, so it is re-established on every
27145
+ * attempt of both loops rather than once around them.
26822
27146
  */
26823
27147
  async function createWithRollbackRetry(provider, create, logicalId, logger, isInterrupted, secrets, outer) {
26824
27148
  if (provider.disableOuterRetry) return await create();
@@ -27039,7 +27363,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
27039
27363
  let deletedNewFirst = false;
27040
27364
  let createResult;
27041
27365
  try {
27042
- createResult = await createWithRollbackRetry(createProvider, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, logger, isInterrupted, secrets, {
27366
+ createResult = await createWithRollbackRetry(createProvider, () => withCurrentResourceSecrets(secrets, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets))), op.logicalId, logger, isInterrupted, secrets, {
27043
27367
  isRetryable: isNameCooldownError,
27044
27368
  interruptedMessage: "Rollback interrupted while waiting out the name cooldown"
27045
27369
  });
@@ -27057,7 +27381,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
27057
27381
  delete stateResources[op.logicalId];
27058
27382
  await afterOp?.(op.logicalId);
27059
27383
  try {
27060
- createResult = await createWithRollbackRetry(createProvider, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, logger, isInterrupted, secrets, {
27384
+ createResult = await createWithRollbackRetry(createProvider, () => withCurrentResourceSecrets(secrets, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets))), op.logicalId, logger, isInterrupted, secrets, {
27061
27385
  isRetryable: isRecreateRetryableError,
27062
27386
  interruptedMessage: "Rollback interrupted while waiting for the old name to release"
27063
27387
  });
@@ -28223,10 +28547,37 @@ var DeployEngine = class {
28223
28547
  ...this.exportIndexStore && { exportIndex: this.exportIndexStore },
28224
28548
  recordedImports: this.recordedImports,
28225
28549
  recordedOutputReads: this.recordedOutputReads,
28550
+ ...this.options.inheritedSecrets && this.options.inheritedSecrets.size > 0 && { inheritedSecrets: this.options.inheritedSecrets },
28226
28551
  recordedSecretValues: /* @__PURE__ */ new Map()
28227
28552
  };
28228
28553
  }
28229
28554
  /**
28555
+ * The parameter bag the DIFF resolver context binds, with any inherited
28556
+ * secret plaintext rewritten back to its `{{resolve:...}}` expression (issue
28557
+ * #1903).
28558
+ *
28559
+ * The provisioning pass must keep the REAL values — that is what actually
28560
+ * reaches AWS — but the child's persisted state holds the expression, so the
28561
+ * comparison side has to hold it too or every deploy of a secret-bearing
28562
+ * nested stack reports a spurious UPDATE and re-issues an AWS call that
28563
+ * changes nothing. This is the child-stack twin of the
28564
+ * `skipDynamicReferences` flag the parent's own diff sets: same goal
28565
+ * (expression-vs-expression), reached differently because the child's
28566
+ * template carries `{Ref: Param}` rather than a `{{resolve:` string, so
28567
+ * there is no reference for that flag to decline to resolve.
28568
+ *
28569
+ * `redactSecretsForState` rather than a `Map.get` lookup so an EMBEDDED
28570
+ * secret — a parameter whose value is `postgres://u:<secret>@host` because
28571
+ * the parent built it with `Fn::Sub` — is rewritten the same way the
28572
+ * state-save choke point rewrites it, keeping the two sides byte-identical.
28573
+ * Identity-returns when nothing was inherited.
28574
+ */
28575
+ redactParametersForDiff(parameterValues) {
28576
+ const inherited = this.options.inheritedSecrets;
28577
+ if (!inherited || inherited.size === 0) return parameterValues;
28578
+ return redactSecretsForState(parameterValues, inherited);
28579
+ }
28580
+ /**
28230
28581
  * Redact resolved secret plaintext out of a bag about to be PERSISTED to
28231
28582
  * state, replacing each secret value with the unresolved `{{resolve:...}}`
28232
28583
  * expression it came from (GHSA fix; see `secret-redaction.ts`). No-op when
@@ -28546,7 +28897,7 @@ var DeployEngine = class {
28546
28897
  } catch {}
28547
28898
  this.kickOffAutoRefreshObservedProperties(currentState.resources);
28548
28899
  this.logger.debug(`Template has ${Object.keys(template.Resources || {}).length} resources`);
28549
- const parameterValues = await this.resolver.resolveParameters(template, this.options.parameters);
28900
+ const parameterValues = await this.resolver.resolveParameters(template, this.options.parameters, { ...this.options.inheritedSecrets && this.options.inheritedSecrets.size > 0 && { inheritedSecrets: this.options.inheritedSecrets } });
28550
28901
  this.logger.debug(`Resolved ${Object.keys(parameterValues).length} parameters: ${Object.keys(parameterValues).join(", ")}`);
28551
28902
  const context = this.buildResolverContext({
28552
28903
  template,
@@ -28573,7 +28924,7 @@ var DeployEngine = class {
28573
28924
  const diffResolverContext = this.buildResolverContext({
28574
28925
  template: effectiveTemplate,
28575
28926
  resources: currentState.resources,
28576
- parameters: parameterValues,
28927
+ parameters: this.redactParametersForDiff(parameterValues),
28577
28928
  conditions
28578
28929
  }, stackName);
28579
28930
  diffResolverContext.bestEffort = true;
@@ -29304,7 +29655,7 @@ var DeployEngine = class {
29304
29655
  this.logger.info(` ${green("✓")} Old resource deleted`);
29305
29656
  this.logger.info(` Re-creating ${logicalId}...`);
29306
29657
  try {
29307
- return await withRetry(() => this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps, createContext), logicalId, void 0, void 0, replaceProvider), logicalId, {
29658
+ return await withRetry(() => this.withRetry(() => withCurrentResourceSecrets(secrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, createContext)), logicalId, void 0, void 0, replaceProvider), logicalId, {
29308
29659
  maxRetries: 8,
29309
29660
  initialDelayMs: 2e3,
29310
29661
  maxDelayMs: 1e4,
@@ -29348,7 +29699,7 @@ var DeployEngine = class {
29348
29699
  });
29349
29700
  const createProvider = createDecision.provider;
29350
29701
  const createProps = createDecision.provisionedBy === "cc-api" ? this.preparePropertiesForCcApi(resourceType, resolvedProps, logicalId) : resolvedProps;
29351
- const result = await this.withRetry(() => createProvider.create(logicalId, resourceType, createProps, { maskSecrets: createSecretMasker(createSecrets) }), logicalId, void 0, void 0, createProvider);
29702
+ const result = await this.withRetry(() => withCurrentResourceSecrets(createSecrets, () => createProvider.create(logicalId, resourceType, createProps, { maskSecrets: createSecretMasker(createSecrets) })), logicalId, void 0, void 0, createProvider);
29352
29703
  const dependencies = this.extractAllDependencies(template, logicalId);
29353
29704
  const templateAttrs = this.extractTemplateAttributes(template, logicalId);
29354
29705
  stateResources[logicalId] = {
@@ -29459,7 +29810,7 @@ var DeployEngine = class {
29459
29810
  this.logger.info(` ${green("✓")} Old resource deleted`);
29460
29811
  }
29461
29812
  this.logger.info(` Creating new ${logicalId}...`);
29462
- createResult = await withRetry(() => this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, replaceProvider), logicalId, {
29813
+ createResult = await withRetry(() => this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider), logicalId, {
29463
29814
  maxRetries: 8,
29464
29815
  initialDelayMs: 2e3,
29465
29816
  maxDelayMs: 1e4,
@@ -29473,7 +29824,7 @@ var DeployEngine = class {
29473
29824
  this.logger.info(` Creating new ${logicalId}...`);
29474
29825
  let deletedOldFirst = false;
29475
29826
  try {
29476
- createResult = await this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, replaceProvider);
29827
+ createResult = await this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider);
29477
29828
  } catch (createError) {
29478
29829
  const createMsg = createError instanceof Error ? createError.message : String(createError);
29479
29830
  if (!isNameCollisionError(createMsg)) throw createError;
@@ -29550,7 +29901,7 @@ var DeployEngine = class {
29550
29901
  let result;
29551
29902
  let resultProvisionedBy = updateDecision.provisionedBy;
29552
29903
  try {
29553
- result = await this.withRetry(() => updateProvider.update(logicalId, currentResource.physicalId, resourceType, updateProps, currentProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, updateProvider);
29904
+ result = await this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => updateProvider.update(logicalId, currentResource.physicalId, resourceType, updateProps, currentProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, updateProvider);
29554
29905
  } catch (updateError) {
29555
29906
  const msg = updateError instanceof Error ? updateError.message : String(updateError);
29556
29907
  const ccUnsupported = msg.includes("UnsupportedActionException") || msg.includes("does not support UPDATE");
@@ -29582,7 +29933,7 @@ var DeployEngine = class {
29582
29933
  });
29583
29934
  const replProvider = replDecision.provider;
29584
29935
  const replProps = replDecision.provisionedBy === "cc-api" ? this.preparePropertiesForCcApi(resourceType, resolvedProps, logicalId) : resolvedProps;
29585
- const createResult = await this.withRetry(() => replProvider.create(logicalId, resourceType, replProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, replProvider);
29936
+ const createResult = await this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replProvider.create(logicalId, resourceType, replProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replProvider);
29586
29937
  const replacementResult = {
29587
29938
  physicalId: createResult.physicalId,
29588
29939
  wasReplaced: true,
@@ -30051,5 +30402,5 @@ var DeployEngine = class {
30051
30402
  };
30052
30403
 
30053
30404
  //#endregion
30054
- export { endCommandInterruptScope as $, derivePartitionAndUrlSuffix as $n, exportNamesCarriedFrom as $t, renderStatefulReason as A, AssetManifestLoader as An, isCdkdError as Ar, isSingleDynamicReferenceToken as At, exportAliasCollisionScrubWarning as B, resolveStateBucketWithDefault as Bn, s3BucketRegionalDomainName as Bt, isFinalSnapshotError as C, buildDockerImage as Cn, ResourceTimeoutError as Cr, requireConfigString as Ct, extractDeploymentEventError as D, partitionSensitiveEnv as Dn, StateError as Dr, createSecretMasker as Dt, makeCanonicalizePropertiesFn as E, getDockerCmd as En, StackTerminationProtectionError as Er, TEMPLATE_SOURCED_RULES as Et, green as F, getLegacyStateBucketName as Fn, isThrottlingError as Fr, classifyReplaySecretRegion as Ft, collectInlinePolicyNamesManagedBySiblings as G, CFN_TEMPLATE_BODY_LIMIT as Gn, describeTypeWithThrottleRetry as Gt, secretBearingStateKeyWarning as H, resolveUseCdkBootstrapAssets as Hn, applyRoleArnIfSet as Ht, red as I, resolveApp as In, markNonRetryable as Ir, producerRegionsFromState as It, findActionableSilentDrops as J, findLargeInlineResources as Jn, TemplateParser as Jt, clearOnUpdateRemoval as K, CFN_TEMPLATE_URL_LIMIT as Kn, withRetry as Kt, yellow as L, resolveAutoAssetStorage as Ln, __exportAll as Lr, s3BucketArn as Lt, bold as M, Synthesizer as Mn, withErrorHandling as Mr, maskSecretsInText as Mt, cyan as N, synthesisStatusMessage as Nn, isMarkedNonRetryable as Nr, redactSecretsForState as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, runDockerForeground as On, SynthesisError as Or, dynamicReferenceTokens as Ot, gray as P, getDefaultStateBucketName as Pn, isRetryableTransientError as Pr, scrubResourceRecord as Pt, beginCommandInterruptScope as Q, canonicalizeRegion as Qn, rebuildClientForBucketRegion as Qt, collectDeclaredOutputNames as R, resolveCaptureObservedState as Rn, s3BucketDomainName as Rt, createPreDeleteFinalSnapshot as S, buildDenyExternalAccessPolicy as Sn, ProvisioningError as Sr, requireConfigObject as St, unsupportedFinalSnapshotError as T, formatDockerLoginError as Tn, StackHasActiveImportsError as Tr, STATE_SOURCED_READBACK_RULES as Tt, stateKeySecretExposure as U, stateBucketExistenceConfirmed as Un, DiffCalculator as Ut, isExportAliasCollision as V, resolveStateBucketWithDefaultAndSource as Vn, s3BucketWebsiteUrl as Vt, IAMRoleProvider as W, warnDeprecatedNoPrefixCliFlag as Wn, INTRINSIC_KEYS as Wt, CUSTOM_RESOURCE_RESPONSE_PREFIX as X, expectedOwnerParam as Xn, displaySafe as Xt, findSilentDropProperties as Y, uploadCfnTemplate as Yn, LockManager as Yt, DEFAULT_STATE_PREFIX as Z, PARTITION_TABLE as Zn, S3StateBackend as Zt, computeImplicitDeleteEdges as _, isCrossRegionRedirect as _n, LocalStartServiceError as _r, configBooleanRefusal as _t, DeploymentEventsStore as a, WorkGraph as an, getAwsClients as ar, disableInstanceApiTermination as at, buildFinalSnapshotIdentifier as b, validateAssetBucketName as bn, NestedStackChildDirectDestroyError as br, replayWarn as bt, replayFailedOperations as c, loadPublishableAssetManifest as cn, AssetError as cr, carriesDynamicReference as ct, updatePartialReason as d, stripControlChars as dn, CrossAccountSecretRefusalError as dr, refStateLookupFromResource as dt, importableOutputKeys as en, AssemblyReader as er, interruptWatchListenerCount as et, UNSPECIFIED_SKIP_REASON as f, AssetModeResolver as fn, DependencyError as fr, WAFv2WebACLProvider as ft, IMPLICIT_DELETE_DEPENDENCIES as g, getBootstrapMarkerKey as gn, LocalMigrateError as gr, coerceCfnBoolean as gt, maskingRetryLogger as h, ensureAssetStorage as hn, LocalInvokeBuildError as hr, assertRegionMatch as ht, DeploymentEventsReader as i, stringifyValue as in, AwsClients as ir, slowCcOperationTimeoutMs as it, formatResourceLine as j, getDockerImageBySourceHash as jn, normalizeAwsError as jr, maskSecretsInError as jt, isStatefulRecreateTargetSync as k, runDockerStreaming as kn, formatError as kr, errorCauseChain as kt, replayRollback as l, rewriteTemplateAssetReferences as ln, CdkdError as lr, cfnRefValueFromPhysicalId as lt, withResourceDeadline as m, assertAssetBucketRegion as mn, DynamicReferenceRegionAmbiguousError as mr, resolveExplicitPhysicalId as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, shouldRetainResource as nn, clearBucketRegionCache as nr, startInterruptWatch as nt, planFailedOps as o, buildAssetRedirectMap as on, resetAwsClients as or, isTerminationProtectionPropagationError as ot, deleteSkipReason as p, BOOTSTRAP_MARKER_PREFIX as pn, DeployCancelledError as pr, normalizeAwsTagsToCfn as pt, ProviderRegistry as q, MIGRATE_TMP_PREFIX as qn, DagBuilder as qt, DeployEngine as r, AssetPublisher as rn, resolveBucketRegion as rr, CloudControlProvider as rt, planRollback as s, createAssetRedirectResolver as sn, setAwsClients as sr, IntrinsicFunctionResolver as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, importableOutputs as tn, processStackMessages as tr, isInterruptedWaitError as tt, updatePartialMessage as u, escapeRegExp$1 as un, ConfigError as ur, getAccountInfo as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, parseBootstrapMarker as vn, LockError as vr, configStringRefusal as vt, refusesFinalSnapshot as w, dockerSpawnEnvWithSensitive as wn, ResourceUpdateNotSupportedError as wr, STATE_SOURCED_CROSS_GENERATION_RULES as wt, ccRoutedFinalSnapshotError as x, validateContainerRepoName as xn, PartialFailureError as xr, requireConfigArray as xt, PRE_DELETE_SNAPSHOT_TYPES as y, readBootstrapMarkerBody as yn, MissingCdkCliError as yr, readConfigString as yt, collectPublishedOutputNames as z, resolveSkipPrefix as zn, s3BucketDualStackDomainName as zt };
30055
- //# sourceMappingURL=deploy-engine-D8AIgkwy.js.map
30405
+ export { beginCommandInterruptScope as $, PARTITION_TABLE as $n, S3StateBackend as $t, renderStatefulReason as A, runDockerForeground as An, SynthesisError as Ar, dynamicReferenceTokens as At, exportAliasCollisionScrubWarning as B, resolveCaptureObservedState as Bn, s3BucketDomainName as Bt, isFinalSnapshotError as C, validateContainerRepoName as Cn, PartialFailureError as Cr, requireConfigArray as Ct, extractDeploymentEventError as D, formatDockerLoginError as Dn, StackHasActiveImportsError as Dr, STATE_SOURCED_READBACK_RULES as Dt, makeCanonicalizePropertiesFn as E, dockerSpawnEnvWithSensitive as En, ResourceUpdateNotSupportedError as Er, STATE_SOURCED_CROSS_GENERATION_RULES as Et, green as F, synthesisStatusMessage as Fn, isMarkedNonRetryable as Fr, redactSecretsForState as Ft, IAMRoleProvider as G, stateBucketExistenceConfirmed as Gn, DiffCalculator as Gt, secretBearingStateKeyWarning as H, resolveStateBucketWithDefault as Hn, s3BucketRegionalDomainName as Ht, red as I, getDefaultStateBucketName as In, isRetryableTransientError as Ir, scrubResourceRecord as It, ProviderRegistry as J, CFN_TEMPLATE_URL_LIMIT as Jn, withRetry as Jt, collectInlinePolicyNamesManagedBySiblings as K, warnDeprecatedNoPrefixCliFlag as Kn, INTRINSIC_KEYS as Kt, yellow as L, getLegacyStateBucketName as Ln, isThrottlingError as Lr, classifyReplaySecretRegion as Lt, bold as M, AssetManifestLoader as Mn, isCdkdError as Mr, isSingleDynamicReferenceToken as Mt, cyan as N, getDockerImageBySourceHash as Nn, normalizeAwsError as Nr, maskSecretsInError as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, getDockerCmd as On, StackTerminationProtectionError as Or, TEMPLATE_SOURCED_RULES as Ot, gray as P, Synthesizer as Pn, withErrorHandling as Pr, maskSecretsInText as Pt, DEFAULT_STATE_PREFIX as Q, expectedOwnerParam as Qn, displaySafe as Qt, collectDeclaredOutputNames as R, resolveApp as Rn, markNonRetryable as Rr, producerRegionsFromState as Rt, createPreDeleteFinalSnapshot as S, validateAssetBucketName as Sn, NestedStackChildDirectDestroyError as Sr, replayWarn as St, unsupportedFinalSnapshotError as T, buildDockerImage as Tn, ResourceTimeoutError as Tr, requireConfigString as Tt, stateKeySecretExposure as U, resolveStateBucketWithDefaultAndSource as Un, s3BucketWebsiteUrl as Ut, isExportAliasCollision as V, resolveSkipPrefix as Vn, s3BucketDualStackDomainName as Vt, getCurrentResourceSecrets as W, resolveUseCdkBootstrapAssets as Wn, applyRoleArnIfSet as Wt, findSilentDropProperties as X, findLargeInlineResources as Xn, TemplateParser as Xt, findActionableSilentDrops as Y, MIGRATE_TMP_PREFIX as Yn, DagBuilder as Yt, CUSTOM_RESOURCE_RESPONSE_PREFIX as Z, uploadCfnTemplate as Zn, LockManager as Zt, computeImplicitDeleteEdges as _, ensureAssetStorage as _n, LocalInvokeBuildError as _r, assertRegionMatch as _t, DeploymentEventsStore as a, AssetPublisher as an, resolveBucketRegion as ar, slowCcOperationTimeoutMs as at, buildFinalSnapshotIdentifier as b, parseBootstrapMarker as bn, LockError as br, configStringRefusal as bt, replayFailedOperations as c, buildAssetRedirectMap as cn, resetAwsClients as cr, IntrinsicFunctionResolver as ct, updatePartialReason as d, rewriteTemplateAssetReferences as dn, CdkdError as dr, getAccountInfo as dt, rebuildClientForBucketRegion as en, canonicalizeRegion as er, endCommandInterruptScope as et, UNSPECIFIED_SKIP_REASON as f, escapeRegExp$1 as fn, ConfigError as fr, parameterTypeMayLoseSecretIdentity as ft, IMPLICIT_DELETE_DEPENDENCIES as g, assertAssetBucketRegion as gn, DynamicReferenceRegionAmbiguousError as gr, resolveExplicitPhysicalId as gt, maskingRetryLogger as h, BOOTSTRAP_MARKER_PREFIX as hn, DeployCancelledError as hr, normalizeAwsTagsToCfn as ht, DeploymentEventsReader as i, shouldRetainResource as in, clearBucketRegionCache as ir, CloudControlProvider as it, formatResourceLine as j, runDockerStreaming as jn, formatError as jr, errorCauseChain as jt, isStatefulRecreateTargetSync as k, partitionSensitiveEnv as kn, StateError as kr, createSecretMasker as kt, replayRollback as l, createAssetRedirectResolver as ln, setAwsClients as lr, carriesDynamicReference as lt, withResourceDeadline as m, AssetModeResolver as mn, DependencyError as mr, WAFv2WebACLProvider as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, importableOutputKeys as nn, AssemblyReader as nr, isInterruptedWaitError as nt, planFailedOps as o, stringifyValue as on, AwsClients as or, disableInstanceApiTermination as ot, deleteSkipReason as p, stripControlChars as pn, CrossAccountSecretRefusalError as pr, refStateLookupFromResource as pt, clearOnUpdateRemoval as q, CFN_TEMPLATE_BODY_LIMIT as qn, describeTypeWithThrottleRetry as qt, DeployEngine as r, importableOutputs as rn, processStackMessages as rr, startInterruptWatch as rt, planRollback as s, WorkGraph as sn, getAwsClients as sr, isTerminationProtectionPropagationError as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, exportNamesCarriedFrom as tn, derivePartitionAndUrlSuffix as tr, interruptWatchListenerCount as tt, updatePartialMessage as u, loadPublishableAssetManifest as un, AssetError as ur, cfnRefValueFromPhysicalId as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, getBootstrapMarkerKey as vn, LocalMigrateError as vr, coerceCfnBoolean as vt, refusesFinalSnapshot as w, buildDenyExternalAccessPolicy as wn, ProvisioningError as wr, requireConfigObject as wt, ccRoutedFinalSnapshotError as x, readBootstrapMarkerBody as xn, MissingCdkCliError as xr, readConfigString as xt, PRE_DELETE_SNAPSHOT_TYPES as y, isCrossRegionRedirect as yn, LocalStartServiceError as yr, configBooleanRefusal as yt, collectPublishedOutputNames as z, resolveAutoAssetStorage as zn, __exportAll as zr, s3BucketArn as zt };
30406
+ //# sourceMappingURL=deploy-engine-BtqjWvh5.js.map