@go-to-k/cdkd 0.284.80 → 0.284.82

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,5 @@
1
1
  import { d as generateResourceName, f as generateResourceNameWithFallback, g as withStackName, m as looksLikeCdkdGeneratedName, n as getLogger, o as getLiveRenderer, p as getCurrentStackName, u as applyDefaultNameForFallback } from "./logger-C9-E73FI.js";
2
- import { t as getCdkdVersion } from "./version-CdU_rRxd.js";
2
+ import { t as getCdkdVersion } from "./version-D_b3uJus.js";
3
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -4008,6 +4008,83 @@ function findLargeInlineResources(template, threshold = LARGE_INLINE_RESOURCE_TH
4008
4008
  return result;
4009
4009
  }
4010
4010
 
4011
+ //#endregion
4012
+ //#region src/utils/parameter-types.ts
4013
+ /**
4014
+ * ONE definition of "is this CloudFormation Parameter `Type` LIST-shaped?".
4015
+ *
4016
+ * cdkd used to hold TWO independent answers to this question (issue
4017
+ * [#2347](https://github.com/go-to-k/cdkd/issues/2347)):
4018
+ *
4019
+ * - `coerceParameterTypedValue` in `src/deployment/intrinsic-function-resolver.ts`
4020
+ * named exactly two list types (`List<Number>`, `CommaDelimitedList`) in a
4021
+ * `switch`, so every other `List<...>` spelling fell to `default` and a
4022
+ * `Ref` to it resolved to the raw comma-joined STRING;
4023
+ * - `stringifyParamDefault` in `src/synthesis/macro-expander.ts` tested
4024
+ * `inner.startsWith('List<') || inner === 'CommaDelimitedList'` when choosing
4025
+ * the placeholder shape for an `AWS::SSM::Parameter::Value<...>` parameter,
4026
+ * i.e. the WIDER, correct view.
4027
+ *
4028
+ * The two disagreeing is what let a `List<AWS::EC2::Subnet::Id>` child
4029
+ * parameter be handed to a nested stack as a string. They now share this
4030
+ * predicate, so a third spelling cannot appear without deleting this file.
4031
+ *
4032
+ * This lives in `src/utils/` rather than beside either consumer because it has
4033
+ * TWO, in different layers -- `src/deployment/intrinsic-function-resolver.ts`
4034
+ * and `src/synthesis/macro-expander.ts`. Hosting it in `src/deployment/` gave
4035
+ * the tree its FIRST `src/synthesis/**` -> `src/deployment/**` import, which
4036
+ * inverts the documented layer order (synthesis runs before deployment); every
4037
+ * other synthesis import goes to `../types`, `../utils` or `../cli`.
4038
+ * `src/utils/ip-protocol.ts` is the precedent, hosted here for the same reason
4039
+ * and stating it in the same place. `src/types/` was the other candidate and is
4040
+ * wrong for this: it carries type declarations plus the constants and helpers
4041
+ * that read them, not a standalone runtime predicate with no type of its own.
4042
+ *
4043
+ * ## What CloudFormation actually defines
4044
+ *
4045
+ * Measured 2026-08-28 against the AWS-published enumerations, NOT against a
4046
+ * library:
4047
+ *
4048
+ * - `parameters-section-structure.html` lists the base types as `String`,
4049
+ * `Number`, `List<Number>`, `CommaDelimitedList`, plus "AWS-specific
4050
+ * parameter types" and "Systems Manager parameter types". **A bare
4051
+ * `List<String>` is NOT in that enumeration.**
4052
+ * - `cloudformation-supplied-parameter-types.html` enumerates ten AWS-specific
4053
+ * SCALAR types and nine `List<AWS::...>` types (`List<AWS::EC2::Subnet::Id>`,
4054
+ * `List<AWS::EC2::SecurityGroup::Id>`, ...). `List<String>` appears only as
4055
+ * the INNER shape of the Systems Manager form
4056
+ * `AWS::SSM::Parameter::Value<List<String>>`.
4057
+ *
4058
+ * `List<String>` is nevertheless accepted here, because `aws-cdk-lib`'s own
4059
+ * `CfnParameter` accepts it (`isListType` in
4060
+ * `node_modules/aws-cdk-lib/core/lib/cfn-parameter.js` is a substring test) and
4061
+ * `valueAsList()` on such a parameter synthesizes a template cdkd will deploy
4062
+ * WITHOUT CloudFormation ever seeing it. Treating it as a list is the reading
4063
+ * that agrees with the app that produced it; the alternative silently hands a
4064
+ * string to something the CDK typed as a string list.
4065
+ *
4066
+ * ## Why this is `startsWith`, not `aws-cdk-lib`'s `indexOf`
4067
+ *
4068
+ * `indexOf('List<') >= 0` also matches `MyList<String>` and, load-bearing here,
4069
+ * the Systems Manager OUTER form `AWS::SSM::Parameter::Value<List<String>>`.
4070
+ * That outer form must NOT be list-shaped for the coercion: the VALUE supplied
4071
+ * for an SSM-typed parameter is a Parameter Store KEY, not the resolved list,
4072
+ * so splitting it on `,` would shred a key rather than build a list. The
4073
+ * macro-expander asks this question of the INNER shape it has already peeled
4074
+ * out of `Value<...>`, so the same predicate serves both sites unchanged.
4075
+ *
4076
+ * A closing `>` is required, so `List<`, `List<>` and `List<String` are NOT
4077
+ * list-shaped. That is the whole of the claim: this predicate is a test of the
4078
+ * SPELLING, not a validator. Measured, `List< >`, `List<a>`, `List<<>>` and
4079
+ * `List<X>>` all return `true` -- nothing here rejects a nonsense inner type,
4080
+ * and cdkd deploys without CloudFormation ever seeing the template, so no
4081
+ * service-side validation stands behind it either.
4082
+ */
4083
+ function isListParameterType(type) {
4084
+ if (type === "CommaDelimitedList") return true;
4085
+ return type.length > 6 && type.startsWith("List<") && type.endsWith(">");
4086
+ }
4087
+
4011
4088
  //#endregion
4012
4089
  //#region src/synthesis/macro-expander.ts
4013
4090
  /** 600 seconds = 10 minutes. SDK waiter's `maxWaitTime` is in seconds. */
@@ -4281,8 +4358,7 @@ function stringifyParamDefault(value, type, paramKey, logger) {
4281
4358
  const known = PARAMETER_TYPE_PLACEHOLDERS[type];
4282
4359
  if (known !== void 0) return known;
4283
4360
  if (type.startsWith("AWS::SSM::Parameter::Value<")) {
4284
- const inner = type.slice(27, -1);
4285
- if (inner.startsWith("List<") || inner === "CommaDelimitedList") return "placeholder,placeholder";
4361
+ if (isListParameterType(type.slice(27, -1))) return "placeholder,placeholder";
4286
4362
  return "placeholder";
4287
4363
  }
4288
4364
  logger.warn(`Parameter '${paramKey}' has unrecognized CFn Type '${type}'; using a generic string placeholder for the transient macro-expansion changeset. If CFn rejects the changeset with a type error, file an issue with the offending Type.`);
@@ -9646,6 +9722,8 @@ function recordNestedStackParameterExpressions(secrets, resourceType, resolvedPr
9646
9722
  const sourceLeaf = sourceParameters[name];
9647
9723
  if (typeof sourceLeaf === "string" && expression !== sourceLeaf) continue;
9648
9724
  if (expression === resolvedValue) continue;
9725
+ const seenResolvingTo = plaintextIndexOf(secrets).get(expression);
9726
+ if (seenResolvingTo !== void 0 && seenResolvingTo !== resolvedValue) continue;
9649
9727
  if (table === void 0) {
9650
9728
  table = /* @__PURE__ */ new Map();
9651
9729
  nestedStackParameterExpressions.set(secrets, table);
@@ -9705,19 +9783,35 @@ function inheritNestedStackParameterAssociations(childSecrets, parentSecrets) {
9705
9783
  * `parentSecrets` is the INHERITED bag — the parent's own per-resource map, the
9706
9784
  * object this table is keyed by — not the child resource's bag.
9707
9785
  *
9708
- * The same THREE conditions {@link positionByCrossStackSource} applies, for the
9709
- * same reasons; see that function's own notes for why condition 3 is not
9710
- * subsumed by condition 2.
9786
+ * The same THREE conditions the persist side applies, because it is literally
9787
+ * the same code: {@link certifiedExpressionForLeaf} OWNS the question and both
9788
+ * halves call it. See that function for why condition 3 is not subsumed by
9789
+ * condition 2.
9790
+ *
9791
+ * RETURNS AN ARRAY for a LIST-typed parameter (issue
9792
+ * [#2327](https://github.com/go-to-k/cdkd/issues/2327)), through the same
9793
+ * {@link certifiedListForLeaf} the persist side reaches from
9794
+ * {@link positionListByCrossStackSource}. `coerceParameterTypedValue` splits a
9795
+ * `CommaDelimitedList` parameter's STRING into an array before either side sees
9796
+ * it, so a scalar answer here would be compared against an array in state and
9797
+ * report a change forever — this function's own failure mode, one shape over.
9798
+ *
9799
+ * TWO CALLERS, and the widened return type is why the second one asks a
9800
+ * different question. `redactParametersForDiff` assigns the result into a
9801
+ * `Record<string, unknown>` and needs the whole parameter's answer, array
9802
+ * included. `IntrinsicFunctionResolver.recordInheritedParameterSecrets` writes
9803
+ * into a `Map<string, string>` keyed by PLAINTEXT, so it asks this per
9804
+ * PLAINTEXT — passing the carried plaintext rather than the parameter's value —
9805
+ * and keeps only a `string` answer. That is not a workaround for the type: a
9806
+ * plaintext-keyed bag has one slot per plaintext, and the question it needs
9807
+ * answered is "does THIS parameter certify THIS plaintext", which is the same
9808
+ * question for a scalar and for an element of a list.
9711
9809
  */
9712
9810
  function inheritedParameterExpression(parentSecrets, parameterName, resolvedValue) {
9713
- if (typeof resolvedValue !== "string" || resolvedValue === "") return void 0;
9714
- if (!parentSecrets.has(resolvedValue)) return void 0;
9715
9811
  const association = nestedStackParameterExpressions.get(parentSecrets)?.get(parameterName);
9716
9812
  if (association === void 0 || typeof association === "symbol") return void 0;
9717
- if (association.plaintext !== resolvedValue) return void 0;
9718
- const recordedPlaintext = plaintextIndexOf(parentSecrets).get(association.expression);
9719
- if (recordedPlaintext !== void 0 && recordedPlaintext !== resolvedValue) return void 0;
9720
- return association.expression;
9813
+ if (Array.isArray(resolvedValue)) return certifiedListForLeaf(parentSecrets, association, resolvedValue);
9814
+ return certifiedExpressionForLeaf(parentSecrets, association, resolvedValue);
9721
9815
  }
9722
9816
  /**
9723
9817
  * A resolved secret value shorter than this is NOT used as a redaction needle:
@@ -10206,6 +10300,103 @@ function plaintextIndexOf(secrets) {
10206
10300
  return plaintextOf;
10207
10301
  }
10208
10302
  /**
10303
+ * THE THREE CONDITIONS, in ONE place, over one bag and one already-resolved
10304
+ * association (issue [#2327](https://github.com/go-to-k/cdkd/issues/2327)).
10305
+ *
10306
+ * Three call sites ask this same question and every one of them must answer it
10307
+ * identically or the PERSIST side and the DIFF side disagree — which is not a
10308
+ * hypothetical: the two halves must produce the same expression for the same
10309
+ * leaf, or the desired side of the next diff never matches what was persisted
10310
+ * and the resource reports a change on every deploy (issue #2087's symptom,
10311
+ * arriving through a second spelling of one predicate). The sites are
10312
+ * {@link positionByCrossStackSource} (persist, string leaf),
10313
+ * {@link certifiedListForLeaf} (persist and diff, list leaf) and
10314
+ * {@link inheritedParameterExpression} (diff, whole parameter). THIS FUNCTION
10315
+ * OWNS THE QUESTION; none of them re-spells it.
10316
+ *
10317
+ * 1. The leaf's WHOLE value is a recorded secret plaintext. A leaf that merely
10318
+ * EMBEDS a secret is not this shape and must keep going to the value scan,
10319
+ * which rewrites just the substring. This is also what keeps a PUBLIC
10320
+ * reference out (issue #1901): the resolver records a plaintext only on a
10321
+ * proven-secret verdict, so a public parameter's value is not a key here.
10322
+ * The empty string is excluded for the reason the value pass excludes it: it
10323
+ * is not a distinguishing value.
10324
+ * 2. The association is ABOUT THIS LEAF — the plaintext the WRITER recorded
10325
+ * beside the expression equals the leaf. Within one pass this is the only
10326
+ * guard against a bag/source MISALIGNMENT: a readback bag can hold a
10327
+ * DIFFERENT resource's secret while the source leaf still spells this
10328
+ * import, and condition 3 cannot refuse that (it must ACCEPT an expression
10329
+ * absent from the pass's map, since the collapsed loser is absent too).
10330
+ * 3. The match is not DEMONSTRABLY another value's expression, over the
10331
+ * {@link plaintextIndexOf} index. NOT subsumed by condition 2: that one
10332
+ * compares what the WRITER recorded, this one what THIS pass's own map
10333
+ * holds, and they can disagree when one reference answers differently in two
10334
+ * regions (issue #1933). The collapsed LOSER is absent from the index, so it
10335
+ * passes — which is the case this whole mechanism exists to serve.
10336
+ */
10337
+ function certifiedExpressionForLeaf(secrets, association, leaf) {
10338
+ if (typeof leaf !== "string" || leaf === "") return void 0;
10339
+ if (!secrets.has(leaf)) return void 0;
10340
+ if (association.plaintext !== leaf) return void 0;
10341
+ const recordedPlaintext = plaintextIndexOf(secrets).get(association.expression);
10342
+ if (recordedPlaintext !== void 0 && recordedPlaintext !== leaf) return void 0;
10343
+ return association.expression;
10344
+ }
10345
+ /**
10346
+ * Apply {@link certifiedExpressionForLeaf} to every ELEMENT of a list leaf
10347
+ * (issue [#2327](https://github.com/go-to-k/cdkd/issues/2327)).
10348
+ *
10349
+ * WHAT "POSITION" MEANS FOR A LIST ELEMENT, which is the question that killed
10350
+ * the earlier attempt in issue #2012 and has to be answered before any array
10351
+ * may be certified: **it is not the index.** There is no source ARRAY to align
10352
+ * against — a list leaf's source is ONE intrinsic standing for the whole list —
10353
+ * so an index-based pairing would have nothing on the other side to pair WITH,
10354
+ * and inventing one is exactly the fabrication issue #2012 refused. What
10355
+ * certifies an element is its OWN VALUE, through condition 1 and condition 2
10356
+ * above. Order is therefore irrelevant: a reordered array certifies
10357
+ * identically, and an element the conditions do not reach is left exactly where
10358
+ * the value scan would have left it.
10359
+ *
10360
+ * NOTHING IS FABRICATED. The output array has the SAME length and the SAME
10361
+ * element ORDER as the input; every element is either an expression certified
10362
+ * from that element's own recorded plaintext, or the value-scan answer this
10363
+ * module already produces for it. No element is added, dropped, reordered, or
10364
+ * copied from the source — so there is no baseline content here that
10365
+ * `cdkd drift --revert` could push to AWS but AWS never reported. That is the
10366
+ * constraint the issue #2012 review imposed, satisfied structurally rather than
10367
+ * argued around.
10368
+ *
10369
+ * SHARED BY BOTH HALVES, and that sharing is load-bearing rather than tidy: the
10370
+ * persist side reaches it through {@link positionListByCrossStackSource} and
10371
+ * the diff side through {@link inheritedParameterExpression}, with the same
10372
+ * association content on either side ({@link inheritNestedStackParameterAssociations}
10373
+ * copies the parent's rows onto the child bag). Two spellings that agreed on
10374
+ * every case but one would reintroduce the perpetual UPDATE at that one case.
10375
+ *
10376
+ * Returns `undefined` when NO element was certified, so every caller falls
10377
+ * through to the value scan and keeps its identity-return: with an empty
10378
+ * secrets map (the issue #1900 unchanged-resource path) condition 1 refuses
10379
+ * every element, so this costs one walk and changes nothing.
10380
+ */
10381
+ function certifiedListForLeaf(secrets, association, bag) {
10382
+ const certified = bag.map((element) => certifiedExpressionForLeaf(secrets, association, element));
10383
+ if (certified.every((expression) => expression === void 0)) return void 0;
10384
+ return bag.map((element, i) => certified[i] ?? redactSecretsForState(element, secrets));
10385
+ }
10386
+ /**
10387
+ * The association {@link crossStackAssociations} holds for a SOURCE leaf, or
10388
+ * `undefined` when this pass has none (or a poisoned one) for it.
10389
+ */
10390
+ function associationForSource(source, secrets) {
10391
+ const key = crossStackSourceKey(source);
10392
+ if (key === void 0) return void 0;
10393
+ const associations = crossStackAssociations.get(secrets);
10394
+ if (associations === void 0) return void 0;
10395
+ const association = associations.get(key);
10396
+ if (association === void 0 || typeof association === "symbol") return void 0;
10397
+ return association;
10398
+ }
10399
+ /**
10209
10400
  * Position a leaf whose SOURCE is a CROSS-STACK intrinsic object
10210
10401
  * (`Fn::ImportValue` / `Fn::GetStackOutput`), by looking its identity up in the
10211
10402
  * association the RESOLVER recorded while it read the producer (issue
@@ -10224,27 +10415,14 @@ function plaintextIndexOf(secrets) {
10224
10415
  * has to come from the one place that holds both halves at once, which is
10225
10416
  * {@link crossStackAssociations}.
10226
10417
  *
10227
- * Three conditions, mirroring the ones next door, and each removing a different
10228
- * way of being wrong:
10229
- *
10230
- * 1. The bag leaf's WHOLE value is a recorded secret plaintext verbatim
10231
- * condition 1 of {@link positionByIntrinsicSkeleton}. A leaf that merely
10232
- * EMBEDS a secret is not this shape and must keep going to the value scan,
10233
- * which rewrites just the substring. This is also what keeps a PUBLIC
10234
- * reference out (issue #1901): the resolver records a plaintext only on a
10235
- * proven-secret verdict, so a public parameter's value is not a key here.
10236
- * 2. The association is ABOUT THIS BAG — the plaintext the WRITER recorded
10237
- * beside the expression equals the bag leaf. Against another pass this is
10238
- * belt-and-braces, since {@link crossStackAssociations} is scoped to the
10239
- * pass and a foreign entry cannot be reached; within one pass it is the only
10240
- * guard against a bag/source MISALIGNMENT.
10241
- * 3. The match is not DEMONSTRABLY another value's expression — verbatim
10242
- * condition 3 next door, over the same {@link plaintextIndexOf} index. It is
10243
- * what fences a bag/source MISALIGNMENT: on a readback walk the bag leaf can
10244
- * hold a different resource's secret while the source leaf still spells this
10245
- * import, and an association recorded against a plaintext that is not this
10246
- * bag is refused outright. The collapsed LOSER is absent from that index, so
10247
- * it passes — which is the case this whole function exists to serve.
10418
+ * THE THREE CONDITIONS ARE {@link certifiedExpressionForLeaf}'s and are stated
10419
+ * ONLY there. They were re-enumerated here until issue #2327 extracted the
10420
+ * owner, and the copy had already drifted from it three ways within the same
10421
+ * change -- it dropped the empty-string clause, it explained condition 2 by a
10422
+ * scoping story ({@link crossStackAssociations} being per-pass) that is not the
10423
+ * owner's OTHER caller's, and it said "three intrinsic spellings" when
10424
+ * {@link crossStackSourceKey} answers for five. A rationale that drifts inside
10425
+ * one PR is the argument against duplicating it.
10248
10426
  *
10249
10427
  * There is deliberately NO "exactly one candidate" test (the neighbour's
10250
10428
  * condition 2): this is a LOOKUP rather than a search, so the ambiguity that
@@ -10257,23 +10435,16 @@ function plaintextIndexOf(secrets) {
10257
10435
  * bag could not be vouched for, because it rewrote a `{Name: '', Value:
10258
10436
  * 'an-unrelated-literal'}` pair. Nothing here can do that: the answer is never
10259
10437
  * the source subtree, it is an expression a WRITER recorded against this exact
10260
- * leaf identity; the arm fires for exactly three intrinsic spellings; and
10438
+ * leaf identity; the arm fires only for the spellings
10439
+ * {@link crossStackSourceKey} can key; and
10261
10440
  * condition 1 still demands that the bag leaf be a plaintext this pass
10262
10441
  * resolved. Every rejection degrades to {@link positionByIntrinsicSkeleton} and
10263
10442
  * then to the value scan, i.e. to today's behavior.
10264
10443
  */
10265
10444
  function positionByCrossStackSource(bag, source, secrets) {
10266
- if (bag === "" || !secrets.has(bag)) return void 0;
10267
- const key = crossStackSourceKey(source);
10268
- if (key === void 0) return void 0;
10269
- const associations = crossStackAssociations.get(secrets);
10270
- if (associations === void 0) return void 0;
10271
- const association = associations.get(key);
10272
- if (association === void 0 || typeof association === "symbol") return void 0;
10273
- if (association.plaintext !== bag) return void 0;
10274
- const recordedPlaintext = plaintextIndexOf(secrets).get(association.expression);
10275
- if (recordedPlaintext !== void 0 && recordedPlaintext !== bag) return void 0;
10276
- return association.expression;
10445
+ const association = associationForSource(source, secrets);
10446
+ if (association === void 0) return void 0;
10447
+ return certifiedExpressionForLeaf(secrets, association, bag);
10277
10448
  }
10278
10449
  /**
10279
10450
  * Position a leaf whose SOURCE is an intrinsic OBJECT, by matching the shape of
@@ -10457,6 +10628,49 @@ function identityKeyFor(bag, source) {
10457
10628
  for (const key of ARRAY_IDENTITY_KEYS) if (isUniquelyKeyedBy(bag, key) && isUniquelyKeyedBy(source, key)) return key;
10458
10629
  }
10459
10630
  /**
10631
+ * Position the ELEMENTS of an array leaf whose SOURCE is an intrinsic OBJECT,
10632
+ * by the same leaf-identity lookup {@link positionByCrossStackSource} performs
10633
+ * for a string leaf (issue
10634
+ * [#2327](https://github.com/go-to-k/cdkd/issues/2327)).
10635
+ *
10636
+ * A child parameter declared `CommaDelimitedList` is coerced by
10637
+ * `coerceParameterTypedValue` into an ARRAY before any of this runs, so a
10638
+ * leaf the child template spells `{Ref: <Param>}` arrives beside an intrinsic
10639
+ * OBJECT as an array — a shape NO arm matched, which dropped it to the
10640
+ * plaintext-keyed value scan and handed BOTH members of a coinciding pair the
10641
+ * survivor's expression. `docs/cli-reference.md` names `CommaDelimitedList` as
10642
+ * an ALLOWED spelling for a secret-bearing nested-stack parameter, so it is
10643
+ * reachable rather than theoretical.
10644
+ *
10645
+ * The element rule, what it refuses and why nothing is fabricated all live on
10646
+ * {@link certifiedListForLeaf}, which the DIFF side calls too. TWO further
10647
+ * refusals belong to THIS site rather than to the shared rule:
10648
+ *
10649
+ * 1. REFUSAL — a source leaf {@link crossStackSourceKey} cannot key, or one
10650
+ * this pass recorded no association for. Both fall to the value scan, i.e.
10651
+ * to today's behaviour.
10652
+ * 2. REFUSAL — {@link positionByIntrinsicSkeleton} is deliberately NOT tried
10653
+ * element-wise, and the asymmetry with the string arm is structural rather
10654
+ * than caution. {@link intrinsicSkeletonPattern} accepts exactly `Fn::Join`
10655
+ * and `Fn::Sub`, both of which produce a STRING; an array bag beside one of
10656
+ * them is a SHAPE DIVERGENCE, not a position. Matching a per-element pattern
10657
+ * built from text that describes the whole joined string would be a guess of
10658
+ * precisely the kind condition 2 of that function exists to refuse.
10659
+ *
10660
+ * NOT GATED ON `rules`, for the reason the string arm next door is not: the
10661
+ * certification rests on the element being a plaintext THIS pass recorded,
10662
+ * which a previous generation's persisted expression can never be, and it never
10663
+ * depends on the two sides being positionally aligned. In practice only the
10664
+ * TEMPLATE-sourced walks can reach it at all — every STATE-sourced source leaf
10665
+ * is a persisted value, not an intrinsic object — but the safety does not rest
10666
+ * on that.
10667
+ */
10668
+ function positionListByCrossStackSource(bag, source, secrets) {
10669
+ const association = associationForSource(source, secrets);
10670
+ if (association === void 0) return void 0;
10671
+ return certifiedListForLeaf(secrets, association, bag);
10672
+ }
10673
+ /**
10460
10674
  * PATH-based redaction: walk `bag` alongside a SOURCE bag that still carries the
10461
10675
  * unresolved `{{resolve:...}}` expressions, and wherever the source leaf is such
10462
10676
  * a string, persist THAT string verbatim.
@@ -10488,6 +10702,14 @@ function identityKeyFor(bag, source) {
10488
10702
  * recorded secret expressions, THAT is persisted. This is the dominant CDK
10489
10703
  * shape — an L2 secret token renders the ARN as a `Ref`, hence a join.
10490
10704
  *
10705
+ * An ARRAY leaf beside such an intrinsic OBJECT — the shape a
10706
+ * `CommaDelimitedList` nested-stack parameter produces once the child has
10707
+ * coerced it — is positioned ELEMENT-WISE by
10708
+ * {@link positionListByCrossStackSource} (issue #2327). What certifies an
10709
+ * element there is its own recorded plaintext rather than its index, so nothing
10710
+ * is aligned against a source array that does not exist; see that function for
10711
+ * the two shapes it refuses.
10712
+ *
10491
10713
  * The value scan is still applied wherever none can answer: a leaf that merely
10492
10714
  * EMBEDS a secret inside surrounding text, an intrinsic whose skeleton matches
10493
10715
  * zero or several candidates, a cross-stack leaf whose identity is not
@@ -10510,6 +10732,10 @@ function redactByPath(bag, source, secrets, rules, secretExpressions) {
10510
10732
  const positioned = positionByIntrinsicSkeleton(bag, source, secrets, secretExpressions);
10511
10733
  if (positioned !== void 0) return positioned;
10512
10734
  }
10735
+ if (Array.isArray(bag) && isPlainObject$2(source)) {
10736
+ const positionedList = positionListByCrossStackSource(bag, source, secrets);
10737
+ if (positionedList !== void 0) return positionedList;
10738
+ }
10513
10739
  if (Array.isArray(bag) && Array.isArray(source)) {
10514
10740
  const key = identityKeyFor(bag, source);
10515
10741
  if (key !== void 0) {
@@ -16409,14 +16635,26 @@ function parameterTypeMayLoseSecretIdentity(type) {
16409
16635
  * ONE definition of parameter-type coercion, at module scope so
16410
16636
  * {@link parameterTypeMayLoseSecretIdentity} probes the same code the resolver
16411
16637
  * runs rather than a copy of it.
16638
+ *
16639
+ * WHICH TYPES ARE LISTS is asked of the SHARED {@link isListParameterType}
16640
+ * rather than enumerated in the `switch` (issue #2347). The `switch` named only
16641
+ * `List<Number>` and `CommaDelimitedList`, so the nine `List<AWS::...>` types
16642
+ * CloudFormation defines -- `List<AWS::EC2::Subnet::Id>` and its siblings --
16643
+ * fell to `default` and a `Ref` to such a parameter resolved to the raw
16644
+ * comma-joined STRING, while `src/synthesis/macro-expander.ts` held the wider,
16645
+ * correct view of the very same question. Both sites now read one predicate.
16646
+ *
16647
+ * `List<Number>` keeps its own arm because it is the only list type whose
16648
+ * ELEMENTS are not strings; every other list type produces trimmed strings,
16649
+ * which is what CloudFormation says a `Ref` to one returns.
16412
16650
  */
16413
16651
  function coerceParameterTypedValue(value, type) {
16414
16652
  switch (type) {
16415
16653
  case "Number": return Number(value);
16416
16654
  case "List<Number>": return value.split(",").map((v) => Number(v.trim()));
16417
- case "CommaDelimitedList": return value.split(",").map((v) => v.trim());
16418
- default: return value;
16419
16655
  }
16656
+ if (isListParameterType(type)) return value.split(",").map((v) => v.trim());
16657
+ return value;
16420
16658
  }
16421
16659
  /**
16422
16660
  * The inherited `plaintext -> expression` pairs that `value` CARRIES.
@@ -16437,8 +16675,8 @@ function coerceParameterTypedValue(value, type) {
16437
16675
  * for the same reason the redactor excludes them: a 3-character secret
16438
16676
  * matches half the alphabet's worth of ordinary identifiers.
16439
16677
  *
16440
- * A `CommaDelimitedList` parameter arrives as an array, so the scan walks
16441
- * string elements too.
16678
+ * A LIST-TYPED parameter — any `List<...>` type or `CommaDelimitedList` arrives as an
16679
+ * array, so the scan walks string elements too.
16442
16680
  */
16443
16681
  function inheritedSecretsCarriedBy(value, inherited) {
16444
16682
  const candidates = [];
@@ -17149,8 +17387,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
17149
17387
  const inherited = context.inheritedSecrets;
17150
17388
  const recorded = context.recordedSecretValues;
17151
17389
  if (!inherited || inherited.size === 0 || !recorded) return;
17152
- const own = inheritedParameterExpression(inherited, parameterName, value);
17153
- for (const [plaintext, expression] of inheritedSecretsCarriedBy(value, inherited)) recorded.set(plaintext, own !== void 0 && plaintext === value ? own : expression);
17390
+ for (const [plaintext, expression] of inheritedSecretsCarriedBy(value, inherited)) {
17391
+ const own = inheritedParameterExpression(inherited, parameterName, plaintext);
17392
+ recorded.set(plaintext, typeof own === "string" ? own : expression);
17393
+ }
17154
17394
  }
17155
17395
  /**
17156
17396
  * Refuse a child parameter whose declared `Type` would COERCE an inherited
@@ -17767,7 +18007,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
17767
18007
  const [delimiter, rawValues] = joinArgs;
17768
18008
  let values = rawValues;
17769
18009
  if (!Array.isArray(values)) values = await this.resolveValue(values, context);
17770
- if (!Array.isArray(values)) throw new Error(`Fn::Join's second argument must be a list (an array literal or a list-returning intrinsic such as Fn::Cidr / Fn::GetAZs / Fn::Split / a Ref to a CommaDelimitedList parameter), but resolved to ${typeof values}`);
18010
+ if (!Array.isArray(values)) throw new Error(`Fn::Join's second argument must be a list (an array literal or a list-returning intrinsic such as Fn::Cidr / Fn::GetAZs / Fn::Split / a Ref to a list-typed parameter — any List<...> type or CommaDelimitedList), but resolved to ${typeof values}`);
17771
18011
  let result = (await Promise.all(values.map(async (v) => {
17772
18012
  const resolved = await this.resolveValue(v, context);
17773
18013
  return String(resolved);
@@ -18024,9 +18264,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
18024
18264
  *
18025
18265
  * - a list-valued `Fn::GetAtt` renders as `Fn::GetAtt [Zone, NameServers]`,
18026
18266
  * naming both the resource and the attribute;
18027
- * - a `Ref` to a `CommaDelimitedList` / `List<Number>` parameter the
18028
- * SECOND genuinely reachable array source, via `coerceParameterValue` —
18029
- * renders as `Ref MyListParam`, naming the parameter.
18267
+ * - a `Ref` to a LIST-TYPED parameter — any `List<...>` type or `CommaDelimitedList`, per the
18268
+ * shared `isListParameterType` — the SECOND genuinely reachable array
18269
+ * source, via `coerceParameterValue` — renders as `Ref MyListParam`,
18270
+ * naming the parameter.
18030
18271
  *
18031
18272
  * Anything else degrades to its bare intrinsic key, or to `undefined` for a
18032
18273
  * literal (which the message then simply omits).
@@ -18131,7 +18372,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
18131
18372
  const source = this.describeSplitValueSource(value);
18132
18373
  const sourceClause = source ? ` (from ${source.label})` : "";
18133
18374
  if (Array.isArray(resolvedValue)) {
18134
- const remedy = source?.kind === "ref" ? `A CommaDelimitedList / List<Number> parameter is already a list.` : source?.kind === "getatt" ? "A list-valued Fn::GetAtt (for example AWS::Route53::HostedZone.NameServers or AWS::EC2::VPC.Ipv6CidrBlocks) already returns a list. If you wrote the Fn::Split as a workaround for cdkd resolving that attribute to a comma-delimited string, that bug is fixed (PR #1868) and the workaround is no longer needed." : "Several intrinsics already return a list — among them a list-valued Fn::GetAtt, a Ref to a CommaDelimitedList / List<Number> parameter, Fn::GetAZs, Fn::Cidr, and Fn::Split itself.";
18375
+ const remedy = source?.kind === "ref" ? "A list-typed parameter — any List<...> type (List<AWS::EC2::Subnet::Id>, List<Number>, …) or CommaDelimitedList — is already a list." : source?.kind === "getatt" ? "A list-valued Fn::GetAtt (for example AWS::Route53::HostedZone.NameServers or AWS::EC2::VPC.Ipv6CidrBlocks) already returns a list. If you wrote the Fn::Split as a workaround for cdkd resolving that attribute to a comma-delimited string, that bug is fixed (PR #1868) and the workaround is no longer needed." : "Several intrinsics already return a list — among them a list-valued Fn::GetAtt, a Ref to a list-typed parameter (any List<...> type or CommaDelimitedList), Fn::GetAZs, Fn::Cidr, and Fn::Split itself.";
18135
18376
  throw markNonRetryable(new IntrinsicResolutionRefusalError(`Fn::Split: the value to split${sourceClause} is ALREADY a list (an array of ${resolvedValue.length} item${resolvedValue.length === 1 ? "" : "s"}), not a string. CloudFormation rejects Fn::Split over a list too, so this template is not valid CloudFormation either. Remove the Fn::Split and use the value directly. ${remedy}`));
18136
18377
  }
18137
18378
  throw markNonRetryable(new IntrinsicResolutionRefusalError(`Fn::Split: the value to split${sourceClause} must be a string, got ${resolvedValue === null ? "null" : typeof resolvedValue}. Fn::Split accepts only a string; check the value or the intrinsic that produced it.`));
@@ -20235,7 +20476,7 @@ var CloudControlProvider = class {
20235
20476
  await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
20236
20477
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
20237
20478
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
20238
- const { ASGProvider } = await import("./asg-provider-lbqsxGkM.js").then((n) => n.n);
20479
+ const { ASGProvider } = await import("./asg-provider-BoJz-x3Q.js").then((n) => n.n);
20239
20480
  return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
20240
20481
  }
20241
20482
  const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
@@ -32149,5 +32390,5 @@ var DeployEngine = class {
32149
32390
  };
32150
32391
 
32151
32392
  //#endregion
32152
- export { maskerOrIdentity as $, CFN_TEMPLATE_URL_LIMIT as $n, redactSecretsForState as $t, renderStatefulReason as A, buildDockerImage as An, ResourceTimeoutError as Ar, classifyReplaySecretRegion as At, exportAliasCollisionScrubWarning as B, synthesisStatusMessage as Bn, isMarkedNonRetryable as Br, describeTypeWithThrottleRetry as Bt, isFinalSnapshotError as C, isCrossRegionRedirect as Cn, LocalMigrateError as Cr, configBooleanRefusal as Ct, extractDeploymentEventError as D, validateContainerRepoName as Dn, NestedStackChildDirectDestroyError as Dr, requireConfigArray as Dt, makeCanonicalizePropertiesFn as E, validateAssetBucketName as En, MissingCdkCliError as Er, replayWarn as Et, green as F, runDockerForeground as Fn, SynthesisError as Fr, s3BucketRegionalDomainName as Ft, IAMRoleProvider as G, resolveCaptureObservedState as Gn, retryClassificationText as Gr, STATE_SOURCED_READBACK_RULES as Gt, secretBearingStateKeyWarning as H, getLegacyStateBucketName as Hn, isThrottlingError as Hr, DagBuilder as Ht, red as I, runDockerStreaming as In, formatError as Ir, s3BucketWebsiteUrl as It, ProviderRegistry as J, resolveStateBucketWithDefaultAndSource as Jn, dynamicReferenceTokens as Jt, collectInlinePolicyNamesManagedBySiblings as K, resolveSkipPrefix as Kn, __exportAll as Kr, TEMPLATE_SOURCED_RULES as Kt, yellow as L, AssetManifestLoader as Ln, isCdkdError as Lr, applyRoleArnIfSet as Lt, bold as M, formatDockerLoginError as Mn, StackHasActiveImportsError as Mr, s3BucketArn as Mt, cyan as N, getDockerCmd as Nn, StackTerminationProtectionError as Nr, s3BucketDomainName as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, buildDenyExternalAccessPolicy as On, PartialFailureError as Or, requireConfigObject as Ot, gray as P, partitionSensitiveEnv as Pn, StateError as Pr, s3BucketDualStackDomainName as Pt, maskDeep as Q, CFN_TEMPLATE_BODY_LIMIT as Qn, maskSecretsInText as Qt, collectDeclaredOutputNames as R, getDockerImageBySourceHash as Rn, normalizeAwsError as Rr, DiffCalculator as Rt, createPreDeleteFinalSnapshot as S, getBootstrapMarkerKey as Sn, LocalInvokeBuildError as Sr, coerceCfnBoolean as St, unsupportedFinalSnapshotError as T, readBootstrapMarkerBody as Tn, LockError as Tr, readConfigString as Tt, stateKeySecretExposure as U, resolveApp as Un, markNonRetryable as Ur, TemplateParser as Ut, isExportAliasCollision as V, getDefaultStateBucketName as Vn, isRetryableTransientError as Vr, withRetry as Vt, getCurrentResourceSecrets as W, resolveAutoAssetStorage as Wn, markRedactedCause as Wr, STATE_SOURCED_CROSS_GENERATION_RULES as Wt, findSilentDropProperties as X, stateBucketExistenceConfirmed as Xn, isSingleDynamicReferenceToken as Xt, findActionableSilentDrops as Y, resolveUseCdkBootstrapAssets as Yn, errorCauseChain as Yt, createMaskedRetryLogger as Z, warnDeprecatedNoPrefixCliFlag as Zn, maskSecretsInError as Zt, computeImplicitDeleteEdges as _, stripControlChars as _n, ConfigError as _r, refStateLookupFromResource as _t, DeploymentEventsStore as a, exportNamesCarriedFrom as an, canonicalizeRegion as ar, isInterruptedWaitError as at, buildFinalSnapshotIdentifier as b, assertAssetBucketRegion as bn, DeployCancelledError as br, resolveExplicitPhysicalId as bt, replayFailedOperations as c, shouldRetainResource as cn, processStackMessages as cr, slowCcOperationTimeoutMs as ct, updatePartialReason as d, WorkGraph as dn, AwsClients as dr, IntrinsicFunctionResolver as dt, scrubResourceRecord as en, MIGRATE_TMP_PREFIX as er, CUSTOM_RESOURCE_RESPONSE_PREFIX as et, UNSPECIFIED_SKIP_REASON as f, buildAssetRedirectMap as fn, getAwsClients as fr, carriesDynamicReference as ft, IMPLICIT_DELETE_DEPENDENCIES as g, escapeRegExp$1 as gn, CdkdError as gr, parameterTypeMayLoseSecretIdentity as gt, maskingRetryLogger as h, rewriteTemplateAssetReferences as hn, AssetError as hr, isUnboundTemplateParameter as ht, DeploymentEventsReader as i, rebuildClientForBucketRegion as in, PARTITION_TABLE as ir, interruptWatchListenerCount as it, formatResourceLine as j, dockerSpawnEnvWithSensitive as jn, ResourceUpdateNotSupportedError as jr, producerRegionsFromState as jt, isStatefulRecreateTargetSync as k, describeAwsFailure as kn, ProvisioningError as kr, requireConfigString as kt, replayRollback as l, AssetPublisher as ln, clearBucketRegionCache as lr, disableInstanceApiTermination as lt, withResourceDeadline as m, loadPublishableAssetManifest as mn, setAwsClients as mr, getAccountInfo as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, displaySafe as nn, uploadCfnTemplate as nr, beginCommandInterruptScope as nt, planFailedOps as o, importableOutputKeys as on, derivePartitionAndUrlSuffix as or, startInterruptWatch as ot, deleteSkipReason as p, createAssetRedirectResolver as pn, resetAwsClients as pr, cfnRefValueFromPhysicalId as pt, clearOnUpdateRemoval as q, resolveStateBucketWithDefault as qn, createSecretMasker as qt, DeployEngine as r, S3StateBackend as rn, expectedOwnerParam as rr, endCommandInterruptScope as rt, planRollback as s, importableOutputs as sn, AssemblyReader as sr, CloudControlProvider as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, LockManager as tn, findLargeInlineResources as tr, DEFAULT_STATE_PREFIX as tt, updatePartialMessage as u, stringifyValue as un, resolveBucketRegion as ur, isTerminationProtectionPropagationError as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, AssetModeResolver as vn, CrossAccountSecretRefusalError as vr, WAFv2WebACLProvider as vt, refusesFinalSnapshot as w, parseBootstrapMarker as wn, LocalStartServiceError as wr, configStringRefusal as wt, ccRoutedFinalSnapshotError as x, ensureAssetStorage as xn, DynamicReferenceRegionAmbiguousError as xr, assertRegionMatch as xt, PRE_DELETE_SNAPSHOT_TYPES as y, BOOTSTRAP_MARKER_PREFIX as yn, DependencyError as yr, normalizeAwsTagsToCfn as yt, collectPublishedOutputNames as z, Synthesizer as zn, withErrorHandling as zr, INTRINSIC_KEYS as zt };
32153
- //# sourceMappingURL=deploy-engine-Dsd8oL2h.js.map
32393
+ export { maskerOrIdentity as $, CFN_TEMPLATE_BODY_LIMIT as $n, maskSecretsInText as $t, renderStatefulReason as A, describeAwsFailure as An, ProvisioningError as Ar, requireConfigString as At, exportAliasCollisionScrubWarning as B, Synthesizer as Bn, withErrorHandling as Br, INTRINSIC_KEYS as Bt, isFinalSnapshotError as C, getBootstrapMarkerKey as Cn, LocalInvokeBuildError as Cr, coerceCfnBoolean as Ct, extractDeploymentEventError as D, validateAssetBucketName as Dn, MissingCdkCliError as Dr, replayWarn as Dt, makeCanonicalizePropertiesFn as E, readBootstrapMarkerBody as En, LockError as Er, readConfigString as Et, green as F, partitionSensitiveEnv as Fn, StateError as Fr, s3BucketDualStackDomainName as Ft, IAMRoleProvider as G, resolveAutoAssetStorage as Gn, markRedactedCause as Gr, STATE_SOURCED_CROSS_GENERATION_RULES as Gt, secretBearingStateKeyWarning as H, getDefaultStateBucketName as Hn, isRetryableTransientError as Hr, withRetry as Ht, red as I, runDockerForeground as In, SynthesisError as Ir, s3BucketRegionalDomainName as It, ProviderRegistry as J, resolveStateBucketWithDefault as Jn, createSecretMasker as Jt, collectInlinePolicyNamesManagedBySiblings as K, resolveCaptureObservedState as Kn, retryClassificationText as Kr, STATE_SOURCED_READBACK_RULES as Kt, yellow as L, runDockerStreaming as Ln, formatError as Lr, s3BucketWebsiteUrl as Lt, bold as M, dockerSpawnEnvWithSensitive as Mn, ResourceUpdateNotSupportedError as Mr, producerRegionsFromState as Mt, cyan as N, formatDockerLoginError as Nn, StackHasActiveImportsError as Nr, s3BucketArn as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, validateContainerRepoName as On, NestedStackChildDirectDestroyError as Or, requireConfigArray as Ot, gray as P, getDockerCmd as Pn, StackTerminationProtectionError as Pr, s3BucketDomainName as Pt, maskDeep as Q, warnDeprecatedNoPrefixCliFlag as Qn, maskSecretsInError as Qt, collectDeclaredOutputNames as R, AssetManifestLoader as Rn, isCdkdError as Rr, applyRoleArnIfSet as Rt, createPreDeleteFinalSnapshot as S, ensureAssetStorage as Sn, DynamicReferenceRegionAmbiguousError as Sr, assertRegionMatch as St, unsupportedFinalSnapshotError as T, parseBootstrapMarker as Tn, LocalStartServiceError as Tr, configStringRefusal as Tt, stateKeySecretExposure as U, getLegacyStateBucketName as Un, isThrottlingError as Ur, DagBuilder as Ut, isExportAliasCollision as V, synthesisStatusMessage as Vn, isMarkedNonRetryable as Vr, describeTypeWithThrottleRetry as Vt, getCurrentResourceSecrets as W, resolveApp as Wn, markNonRetryable as Wr, TemplateParser as Wt, findSilentDropProperties as X, resolveUseCdkBootstrapAssets as Xn, errorCauseChain as Xt, findActionableSilentDrops as Y, resolveStateBucketWithDefaultAndSource as Yn, dynamicReferenceTokens as Yt, createMaskedRetryLogger as Z, stateBucketExistenceConfirmed as Zn, isSingleDynamicReferenceToken as Zt, computeImplicitDeleteEdges as _, escapeRegExp$1 as _n, CdkdError as _r, parameterTypeMayLoseSecretIdentity as _t, DeploymentEventsStore as a, rebuildClientForBucketRegion as an, PARTITION_TABLE as ar, isInterruptedWaitError as at, buildFinalSnapshotIdentifier as b, BOOTSTRAP_MARKER_PREFIX as bn, DependencyError as br, normalizeAwsTagsToCfn as bt, replayFailedOperations as c, importableOutputs as cn, AssemblyReader as cr, slowCcOperationTimeoutMs as ct, updatePartialReason as d, stringifyValue as dn, resolveBucketRegion as dr, IntrinsicFunctionResolver as dt, redactSecretsForState as en, CFN_TEMPLATE_URL_LIMIT as er, CUSTOM_RESOURCE_RESPONSE_PREFIX as et, UNSPECIFIED_SKIP_REASON as f, WorkGraph as fn, AwsClients as fr, carriesDynamicReference as ft, IMPLICIT_DELETE_DEPENDENCIES as g, rewriteTemplateAssetReferences as gn, AssetError as gr, isUnboundTemplateParameter as gt, maskingRetryLogger as h, loadPublishableAssetManifest as hn, setAwsClients as hr, getAccountInfo as ht, DeploymentEventsReader as i, S3StateBackend as in, expectedOwnerParam as ir, interruptWatchListenerCount as it, formatResourceLine as j, buildDockerImage as jn, ResourceTimeoutError as jr, classifyReplaySecretRegion as jt, isStatefulRecreateTargetSync as k, buildDenyExternalAccessPolicy as kn, PartialFailureError as kr, requireConfigObject as kt, replayRollback as l, shouldRetainResource as ln, processStackMessages as lr, disableInstanceApiTermination as lt, withResourceDeadline as m, createAssetRedirectResolver as mn, resetAwsClients as mr, coerceParameterTypedValue as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, LockManager as nn, findLargeInlineResources as nr, beginCommandInterruptScope as nt, planFailedOps as o, exportNamesCarriedFrom as on, canonicalizeRegion as or, startInterruptWatch as ot, deleteSkipReason as p, buildAssetRedirectMap as pn, getAwsClients as pr, cfnRefValueFromPhysicalId as pt, clearOnUpdateRemoval as q, resolveSkipPrefix as qn, __exportAll as qr, TEMPLATE_SOURCED_RULES as qt, DeployEngine as r, displaySafe as rn, uploadCfnTemplate as rr, endCommandInterruptScope as rt, planRollback as s, importableOutputKeys as sn, derivePartitionAndUrlSuffix as sr, CloudControlProvider as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, scrubResourceRecord as tn, MIGRATE_TMP_PREFIX as tr, DEFAULT_STATE_PREFIX as tt, updatePartialMessage as u, AssetPublisher as un, clearBucketRegionCache as ur, isTerminationProtectionPropagationError as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, stripControlChars as vn, ConfigError as vr, refStateLookupFromResource as vt, refusesFinalSnapshot as w, isCrossRegionRedirect as wn, LocalMigrateError as wr, configBooleanRefusal as wt, ccRoutedFinalSnapshotError as x, assertAssetBucketRegion as xn, DeployCancelledError as xr, resolveExplicitPhysicalId as xt, PRE_DELETE_SNAPSHOT_TYPES as y, AssetModeResolver as yn, CrossAccountSecretRefusalError as yr, WAFv2WebACLProvider as yt, collectPublishedOutputNames as z, getDockerImageBySourceHash as zn, normalizeAwsError as zr, DiffCalculator as zt };
32394
+ //# sourceMappingURL=deploy-engine-Dh4Jid_H.js.map