@go-to-k/cdkd 0.284.61 → 0.284.63

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-iXYxz3AH.js";
2
+ import { t as getCdkdVersion } from "./version-Cmw63bLc.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-DTolzTHQ.js").then((n) => n.n);
18847
+ const { ASGProvider } = await import("./asg-provider-B9V61Fbq.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";
@@ -19345,8 +19572,10 @@ var CloudControlProvider = class {
19345
19572
  * at command start. It is deliberately NOT
19346
19573
  * `process.listenerCount('SIGINT') > 0`, which was the first cut and is
19347
19574
  * defeated by the very case it was meant to catch: `cdkd drift` runs
19348
- * `provider.update` at concurrency 4, and a concurrent CloudFront / ACM /
19349
- * Route53 wait installs a TRANSIENT SIGINT listener of its own — so an ELBv2
19575
+ * `provider.update` at concurrency 4, and a concurrent CustomResource /
19576
+ * CloudFront / ACM wait (`grep -rn "process.on('SIGINT'"
19577
+ * src/provisioning/providers/` for the closed set — Route53's provider
19578
+ * registers none) installs a TRANSIENT SIGINT listener of its own — so an ELBv2
19350
19579
  * update starting inside that window saw a non-zero count, armed, and then
19351
19580
  * kept the listener for the rest of the command after the transient one was
19352
19581
  * removed. A count answers "is anyone listening right now"; the question is
@@ -19379,9 +19608,29 @@ var CloudControlProvider = class {
19379
19608
  * graceful owner, that watch must NOT treat its presence as "someone else
19380
19609
  * will handle this" (it subtracts `interruptWatchListenerCount()` for
19381
19610
  * exactly that reason), or the swallow above returns one window inward.
19382
- * The remaining population here is the commands that register no handler at
19383
- * all `import` / `export` / `scrub` / `orphan` / `drift` /
19384
- * `state refresh-observed`.
19611
+ *
19612
+ * **That leaves this force-quit with NO population among today's commands,
19613
+ * and it is worth being exact about why**, because the obvious guess — the
19614
+ * commands that register no handler at all, `import` / `export` / `scrub` /
19615
+ * `orphan` / `drift` / `state refresh-observed` — is wrong in a way an
19616
+ * earlier version of this note shipped. Property 3 gates ARMING on the
19617
+ * command scope, and those commands never open one (only
19618
+ * `forwardSigtermToSigint()` does, and only `deploy` / `destroy` /
19619
+ * `rollback` / `state destroy` call it), so this handler is never installed
19620
+ * during them and cannot force-quit there. See the scope note below, which
19621
+ * says the same thing from the lock's side and is what this contradicted.
19622
+ * Among the four commands that DO open a scope, each holds a graceful
19623
+ * SIGINT handler across the whole of it — `deploy.ts`'s top-level handler,
19624
+ * `rollback.ts`'s (removed adjacent to, and synchronously with, its
19625
+ * `unforwardSigterm()`), and now `watchCommandInterrupt` in both destroy
19626
+ * commands — so `others.length` is never 0 while armed.
19627
+ *
19628
+ * The branch is therefore a STRUCTURAL guarantee rather than a live code
19629
+ * path: it becomes reachable again the moment a command opens the interrupt
19630
+ * scope without holding a SIGINT handler across it, or an existing one tears
19631
+ * its handler down before closing the scope. That is a one-line mistake in a
19632
+ * command file, and the failure it produces — a swallowed Ctrl-C during a
19633
+ * provider wait — is silent, which is exactly why the branch stays.
19385
19634
  *
19386
19635
  * So when no other listener remains, the handler restores exactly what Node
19387
19636
  * would have done with no listener at all. That is deliberately not a second
@@ -19458,8 +19707,12 @@ let sigintLatched = false;
19458
19707
  * default terminate, and a swallowed Ctrl-C in a multi-stack destroy really is
19459
19708
  * a blocker. `cdkd drift --revert` is the live instance of the first. The second
19460
19709
  * was `cdkd destroy`, until issue #2117 gave both destroy commands a
19461
- * command-scoped handler of their own; the force-quit's remaining population is
19462
- * the commands that register none at all (see property 4).
19710
+ * command-scoped handler of their own — which leaves the force-quit with no
19711
+ * live population among today's commands at all. Property 4 works through why,
19712
+ * including why the commands that register no handler are NOT it: they never
19713
+ * open the interrupt scope, so this handler never arms for them. The seam is
19714
+ * what keeps the branch testable now that only a future command shape reaches
19715
+ * it.
19463
19716
  *
19464
19717
  * `commandOwnsInterrupts` exists because a provider suite never runs a COMMAND,
19465
19718
  * so every interrupt test would otherwise exercise the UNARMED path while
@@ -24583,6 +24836,67 @@ function collectInlinePolicyNamesManagedBySiblings(targetPhysicalId, context, at
24583
24836
  return result;
24584
24837
  }
24585
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
+
24586
24900
  //#endregion
24587
24901
  //#region src/deployment/outputs-export-alias.ts
24588
24902
  /**
@@ -26482,6 +26796,29 @@ async function replayRollback(operations, stateResources, stackName, ctx, option
26482
26796
  * backoff schedule per op — ~47s on the generic grid, or ~64s if the op
26483
26797
  * hits a name cooldown, which rides its own longer grid since issue #2116.
26484
26798
  *
26799
+ * A FOURTH thing since issue
26800
+ * [#2086](https://github.com/go-to-k/cdkd/issues/2086): the call is bound in
26801
+ * {@link withCurrentResourceSecrets}, the async-local channel
26802
+ * `NestedStackProvider` reads to seed a nested CHILD engine with the pairs the
26803
+ * parent already resolved (issue #1903). `resolveReplayProps` has just
26804
+ * re-resolved the journal's `{{resolve:...}}` expressions back to PLAINTEXT
26805
+ * into `secrets`, so the bag in hand here is exactly the one the deploy engine
26806
+ * would have bound — and without the binding a rollback that reverts a
26807
+ * nested-stack row calls `NestedStackProvider.update`, the child engine seeds
26808
+ * nothing, and the child's `state.json` is rewritten with the DECRYPTED secret.
26809
+ * A recovery path that restores the pre-fix behaviour re-opens the very
26810
+ * disclosure the fix closes, so "absent reads as undefined, the pre-#1903
26811
+ * baseline" is not an acceptable answer HERE, however it reads elsewhere.
26812
+ *
26813
+ * `NestedStackProvider` is reachable on this path by construction, not in
26814
+ * theory: it is one of the two `disableOuterRetry` providers named above that
26815
+ * also implement `update()`, and `cdkd deploy`'s in-process auto-rollback runs
26816
+ * inside a DEPLOY-mode `withNestedStackContext` (`deploy.ts` passes
26817
+ * `nestedTemplates` / `dagBuilder` / `diffCalculator`). Standalone `cdkd
26818
+ * rollback` is NOT affected — `rollback.ts` builds a destroy-mode context with
26819
+ * none of those three fields, so `requireDeployContext` throws loudly before
26820
+ * any child engine is built.
26821
+ *
26485
26822
  * Returns the provider's result so the caller can honour
26486
26823
  * `effectiveProperties` (issue #1644) — both revert arms used to write the
26487
26824
  * previous state record back verbatim, dropping a narrowing the provider had
@@ -26714,8 +27051,8 @@ function redactRollbackRecord(record, secrets, journaledProps) {
26714
27051
  }, secrets);
26715
27052
  }
26716
27053
  async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted, secrets) {
26717
- if (provider.disableOuterRetry) return await provider.update(...args);
26718
- return await withRetry(() => provider.update(...args), logicalId, {
27054
+ if (provider.disableOuterRetry) return await withCurrentResourceSecrets(secrets, () => provider.update(...args));
27055
+ return await withRetry(() => withCurrentResourceSecrets(secrets, () => provider.update(...args)), logicalId, {
26719
27056
  logger: maskingRetryLogger(logger, secrets),
26720
27057
  ...isInterrupted && {
26721
27058
  isInterrupted,
@@ -26793,6 +27130,16 @@ async function updateWithRollbackRetry(provider, args, logicalId, logger, isInte
26793
27130
  * now earns its place by ALSO covering the late name release that the inner
26794
27131
  * default classifier rejects. The two compound — measured at 640s of total
26795
27132
  * sleep on a cooldown, inside the 30-minute per-resource deadline.
27133
+ *
27134
+ * ## The secrets scope, on both call sites (issue #2086)
27135
+ *
27136
+ * Each caller's `create` thunk binds {@link withCurrentResourceSecrets} around
27137
+ * `createProvider.create(...)`, for the same reason
27138
+ * {@link updateWithRollbackRetry} does around `update(...)`: a
27139
+ * reverse-replacement replay of an `AWS::CloudFormation::Stack` row re-CREATES
27140
+ * the child, and an unbound store makes the child engine persist the parent's
27141
+ * plaintext. It sits INSIDE the thunk, so it is re-established on every
27142
+ * attempt of both loops rather than once around them.
26796
27143
  */
26797
27144
  async function createWithRollbackRetry(provider, create, logicalId, logger, isInterrupted, secrets, outer) {
26798
27145
  if (provider.disableOuterRetry) return await create();
@@ -27013,7 +27360,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
27013
27360
  let deletedNewFirst = false;
27014
27361
  let createResult;
27015
27362
  try {
27016
- createResult = await createWithRollbackRetry(createProvider, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, logger, isInterrupted, secrets, {
27363
+ createResult = await createWithRollbackRetry(createProvider, () => withCurrentResourceSecrets(secrets, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets))), op.logicalId, logger, isInterrupted, secrets, {
27017
27364
  isRetryable: isNameCooldownError,
27018
27365
  interruptedMessage: "Rollback interrupted while waiting out the name cooldown"
27019
27366
  });
@@ -27031,7 +27378,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
27031
27378
  delete stateResources[op.logicalId];
27032
27379
  await afterOp?.(op.logicalId);
27033
27380
  try {
27034
- createResult = await createWithRollbackRetry(createProvider, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, logger, isInterrupted, secrets, {
27381
+ createResult = await createWithRollbackRetry(createProvider, () => withCurrentResourceSecrets(secrets, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets))), op.logicalId, logger, isInterrupted, secrets, {
27035
27382
  isRetryable: isRecreateRetryableError,
27036
27383
  interruptedMessage: "Rollback interrupted while waiting for the old name to release"
27037
27384
  });
@@ -28197,10 +28544,37 @@ var DeployEngine = class {
28197
28544
  ...this.exportIndexStore && { exportIndex: this.exportIndexStore },
28198
28545
  recordedImports: this.recordedImports,
28199
28546
  recordedOutputReads: this.recordedOutputReads,
28547
+ ...this.options.inheritedSecrets && this.options.inheritedSecrets.size > 0 && { inheritedSecrets: this.options.inheritedSecrets },
28200
28548
  recordedSecretValues: /* @__PURE__ */ new Map()
28201
28549
  };
28202
28550
  }
28203
28551
  /**
28552
+ * The parameter bag the DIFF resolver context binds, with any inherited
28553
+ * secret plaintext rewritten back to its `{{resolve:...}}` expression (issue
28554
+ * #1903).
28555
+ *
28556
+ * The provisioning pass must keep the REAL values — that is what actually
28557
+ * reaches AWS — but the child's persisted state holds the expression, so the
28558
+ * comparison side has to hold it too or every deploy of a secret-bearing
28559
+ * nested stack reports a spurious UPDATE and re-issues an AWS call that
28560
+ * changes nothing. This is the child-stack twin of the
28561
+ * `skipDynamicReferences` flag the parent's own diff sets: same goal
28562
+ * (expression-vs-expression), reached differently because the child's
28563
+ * template carries `{Ref: Param}` rather than a `{{resolve:` string, so
28564
+ * there is no reference for that flag to decline to resolve.
28565
+ *
28566
+ * `redactSecretsForState` rather than a `Map.get` lookup so an EMBEDDED
28567
+ * secret — a parameter whose value is `postgres://u:<secret>@host` because
28568
+ * the parent built it with `Fn::Sub` — is rewritten the same way the
28569
+ * state-save choke point rewrites it, keeping the two sides byte-identical.
28570
+ * Identity-returns when nothing was inherited.
28571
+ */
28572
+ redactParametersForDiff(parameterValues) {
28573
+ const inherited = this.options.inheritedSecrets;
28574
+ if (!inherited || inherited.size === 0) return parameterValues;
28575
+ return redactSecretsForState(parameterValues, inherited);
28576
+ }
28577
+ /**
28204
28578
  * Redact resolved secret plaintext out of a bag about to be PERSISTED to
28205
28579
  * state, replacing each secret value with the unresolved `{{resolve:...}}`
28206
28580
  * expression it came from (GHSA fix; see `secret-redaction.ts`). No-op when
@@ -28520,7 +28894,7 @@ var DeployEngine = class {
28520
28894
  } catch {}
28521
28895
  this.kickOffAutoRefreshObservedProperties(currentState.resources);
28522
28896
  this.logger.debug(`Template has ${Object.keys(template.Resources || {}).length} resources`);
28523
- const parameterValues = await this.resolver.resolveParameters(template, this.options.parameters);
28897
+ const parameterValues = await this.resolver.resolveParameters(template, this.options.parameters, { ...this.options.inheritedSecrets && this.options.inheritedSecrets.size > 0 && { inheritedSecrets: this.options.inheritedSecrets } });
28524
28898
  this.logger.debug(`Resolved ${Object.keys(parameterValues).length} parameters: ${Object.keys(parameterValues).join(", ")}`);
28525
28899
  const context = this.buildResolverContext({
28526
28900
  template,
@@ -28547,7 +28921,7 @@ var DeployEngine = class {
28547
28921
  const diffResolverContext = this.buildResolverContext({
28548
28922
  template: effectiveTemplate,
28549
28923
  resources: currentState.resources,
28550
- parameters: parameterValues,
28924
+ parameters: this.redactParametersForDiff(parameterValues),
28551
28925
  conditions
28552
28926
  }, stackName);
28553
28927
  diffResolverContext.bestEffort = true;
@@ -29278,7 +29652,7 @@ var DeployEngine = class {
29278
29652
  this.logger.info(` ${green("✓")} Old resource deleted`);
29279
29653
  this.logger.info(` Re-creating ${logicalId}...`);
29280
29654
  try {
29281
- return await withRetry(() => this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps, createContext), logicalId, void 0, void 0, replaceProvider), logicalId, {
29655
+ return await withRetry(() => this.withRetry(() => withCurrentResourceSecrets(secrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, createContext)), logicalId, void 0, void 0, replaceProvider), logicalId, {
29282
29656
  maxRetries: 8,
29283
29657
  initialDelayMs: 2e3,
29284
29658
  maxDelayMs: 1e4,
@@ -29322,7 +29696,7 @@ var DeployEngine = class {
29322
29696
  });
29323
29697
  const createProvider = createDecision.provider;
29324
29698
  const createProps = createDecision.provisionedBy === "cc-api" ? this.preparePropertiesForCcApi(resourceType, resolvedProps, logicalId) : resolvedProps;
29325
- const result = await this.withRetry(() => createProvider.create(logicalId, resourceType, createProps, { maskSecrets: createSecretMasker(createSecrets) }), logicalId, void 0, void 0, createProvider);
29699
+ const result = await this.withRetry(() => withCurrentResourceSecrets(createSecrets, () => createProvider.create(logicalId, resourceType, createProps, { maskSecrets: createSecretMasker(createSecrets) })), logicalId, void 0, void 0, createProvider);
29326
29700
  const dependencies = this.extractAllDependencies(template, logicalId);
29327
29701
  const templateAttrs = this.extractTemplateAttributes(template, logicalId);
29328
29702
  stateResources[logicalId] = {
@@ -29433,7 +29807,7 @@ var DeployEngine = class {
29433
29807
  this.logger.info(` ${green("✓")} Old resource deleted`);
29434
29808
  }
29435
29809
  this.logger.info(` Creating new ${logicalId}...`);
29436
- createResult = await withRetry(() => this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, replaceProvider), logicalId, {
29810
+ createResult = await withRetry(() => this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider), logicalId, {
29437
29811
  maxRetries: 8,
29438
29812
  initialDelayMs: 2e3,
29439
29813
  maxDelayMs: 1e4,
@@ -29447,7 +29821,7 @@ var DeployEngine = class {
29447
29821
  this.logger.info(` Creating new ${logicalId}...`);
29448
29822
  let deletedOldFirst = false;
29449
29823
  try {
29450
- createResult = await this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, replaceProvider);
29824
+ createResult = await this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider);
29451
29825
  } catch (createError) {
29452
29826
  const createMsg = createError instanceof Error ? createError.message : String(createError);
29453
29827
  if (!isNameCollisionError(createMsg)) throw createError;
@@ -29524,7 +29898,7 @@ var DeployEngine = class {
29524
29898
  let result;
29525
29899
  let resultProvisionedBy = updateDecision.provisionedBy;
29526
29900
  try {
29527
- result = await this.withRetry(() => updateProvider.update(logicalId, currentResource.physicalId, resourceType, updateProps, currentProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, updateProvider);
29901
+ result = await this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => updateProvider.update(logicalId, currentResource.physicalId, resourceType, updateProps, currentProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, updateProvider);
29528
29902
  } catch (updateError) {
29529
29903
  const msg = updateError instanceof Error ? updateError.message : String(updateError);
29530
29904
  const ccUnsupported = msg.includes("UnsupportedActionException") || msg.includes("does not support UPDATE");
@@ -29556,7 +29930,7 @@ var DeployEngine = class {
29556
29930
  });
29557
29931
  const replProvider = replDecision.provider;
29558
29932
  const replProps = replDecision.provisionedBy === "cc-api" ? this.preparePropertiesForCcApi(resourceType, resolvedProps, logicalId) : resolvedProps;
29559
- const createResult = await this.withRetry(() => replProvider.create(logicalId, resourceType, replProps, { maskSecrets: createSecretMasker(updateSecrets) }), logicalId, void 0, void 0, replProvider);
29933
+ const createResult = await this.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replProvider.create(logicalId, resourceType, replProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replProvider);
29560
29934
  const replacementResult = {
29561
29935
  physicalId: createResult.physicalId,
29562
29936
  wasReplaced: true,
@@ -30025,5 +30399,5 @@ var DeployEngine = class {
30025
30399
  };
30026
30400
 
30027
30401
  //#endregion
30028
- 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 };
30029
- //# sourceMappingURL=deploy-engine-0d-g0TT4.js.map
30402
+ 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 };
30403
+ //# sourceMappingURL=deploy-engine-B-RuozdO.js.map