@go-to-k/cdkd 0.291.3 → 0.291.5

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,6 +1,6 @@
1
1
  import { C as displayAwsMessage, D as truncateCodePoints, E as isPasteableIdent, S as UNRENDERABLE, T as displaySafe, d as applyDefaultNameForFallback, f as explicitNamePropertyFor, g as looksLikeCdkdGeneratedName, h as getCurrentStackName, m as generateResourceNameWithFallback, n as getLogger, p as generateResourceName, r as isStdoutReservedForPayload, s as getLiveRenderer, v as withStackName, w as displayIdent, x as STACK_REF_MAX_CODE_POINTS, y as withoutGeneratedFallbackName } from "./logger-GASr9bAF.js";
2
- import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-BoIxyCir.js";
3
- import { t as getCdkdVersion } from "./version-BKm47b9j.js";
2
+ import { a as setAssumedRoleCredentials, c as currentStackAwsScope, i as getPreAssumeEnvCredentials, l as runInStackAwsScope, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as ambientRegion, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-jISU4PHo.js";
3
+ import { t as getCdkdVersion } from "./version-DVA14XyG.js";
4
4
  import { AsyncLocalStorage } from "node:async_hooks";
5
5
  import { createHash, randomUUID } from "node:crypto";
6
6
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -1436,14 +1436,20 @@ function formatDuration$1(ms) {
1436
1436
  * the attribute and the live read finds nothing or fails), plus the
1437
1437
  * read-less `AWS::RDS::DBProxy` / `DBProxyEndpoint` `VpcId` refusal beside
1438
1438
  * them — each replacing a physical id the attribute's value type can never
1439
- * accept.
1439
+ * accept; and `lookupResourceRecord`'s refusal of a state record whose
1440
+ * `physicalId` is not a string
1441
+ * ([#3576](https://github.com/go-to-k/cdkd/issues/3576)), which both `Ref`
1442
+ * and `Fn::GetAtt` reach, and so both `${...}` forms.
1440
1443
  * 2. NOT reachable from it, and thrown as this class only so that "deliberate
1441
1444
  * refusal" is a property of the THROW rather than of the one catch that
1442
1445
  * inspects it: `resolveSplit`'s two refusals of a non-string value (#1874),
1446
+ * `resolveSelect`'s refusal of an index that does not resolve to a
1447
+ * non-negative integer ([#3574](https://github.com/go-to-k/cdkd/issues/3574)),
1443
1448
  * and `refuseCoercedInheritedSecret`, which refuses an already-resolved
1444
1449
  * value whose type cannot be coerced. Their non-reachability has two
1445
- * DIFFERENT reasons, so do not collapse them: `Fn::Sub` cannot syntactically
1446
- * contain an `Fn::Split`, while `refuseCoercedInheritedSecret` runs in the
1450
+ * DIFFERENT reasons, so do not collapse them: a `${...}` placeholder cannot
1451
+ * syntactically contain an `Fn::Split` or `Fn::Select`, while
1452
+ * `refuseCoercedInheritedSecret` runs in the
1447
1453
  * nested-stack PARAMETER pre-pass, before any `Fn::Sub` is resolved. Neither
1448
1454
  * changes behavior by being this class.
1449
1455
  * 3. PERMANENT — the one site where no user action and no re-run can make the
@@ -1453,7 +1459,8 @@ function formatDuration$1(ms) {
1453
1459
  * {@link CrossAccountSecretRefusalError} rather than this class, because
1454
1460
  * every site in groups 1 and 2 is USER-FIXABLE (correct the stale
1455
1461
  * placeholder ARN, deploy the producer so STS resolves, enrich the
1456
- * `Fn::GetAtt`, drop `--strict-getatt`, fix the malformed `Fn::Split`,
1462
+ * `Fn::GetAtt`, drop `--strict-getatt`, fix the malformed `Fn::Split` or
1463
+ * `Fn::Select` index, repair the record's `physicalId`,
1457
1464
  * correct the nested stack's output name, declare the nested-stack parameter
1458
1465
  * `Type: String`) and a
1459
1466
  * consumer that treats "permanent" as a property of the CLASS silently
@@ -1983,6 +1990,7 @@ var aws_clients_exports = /* @__PURE__ */ __exportAll({
1983
1990
  AwsClients: () => AwsClients,
1984
1991
  getAwsClients: () => getAwsClients,
1985
1992
  resetAwsClients: () => resetAwsClients,
1993
+ runWithStackAwsClients: () => runWithStackAwsClients,
1986
1994
  setAwsClients: () => setAwsClients
1987
1995
  });
1988
1996
  /**
@@ -2063,18 +2071,21 @@ var AwsClients = class AwsClients {
2063
2071
  * incomplete, it is UNSTABLE in the one direction that is dangerous: the SDK
2064
2072
  * memoizes a region-less client's region at its first resolution
2065
2073
  * (`@smithy/node-config-provider`'s `loadConfig` wraps the provider chain in
2066
- * `memoize`), while `deploy.ts`'s `switchRegion` keeps mutating
2067
- * `process.env.AWS_REGION` per stack and restores it in each stack's
2068
- * `finally`. So an env-derived answer can report region X for a client that
2069
- * long ago pinned itself to region P — letting a caller conclude "these
2074
+ * `memoize`), while a per-stack region switch (`destroy-runner.ts` today;
2075
+ * `deploy.ts` until issue #1981 moved it into a stack scope) mutates
2076
+ * `process.env.AWS_REGION` and restores it in each stack's `finally`. So
2077
+ * an env-derived answer can report region X for a client that long ago
2078
+ * pinned itself to region P — letting a caller conclude "these
2070
2079
  * clients already point at my region" and use the WRONG ones, which is worse
2071
2080
  * than not knowing.
2072
2081
  *
2073
2082
  * When this returns `undefined` the region is not merely unknown to us, it is
2074
- * NOT YET DECIDED — and that is the important part. {@link clientOptions}
2075
- * omits `region` entirely in that case, so each service client resolves and
2083
+ * NOT YET DECIDED — and that is the important part. Outside a stack scope
2084
+ * (`runWithStackAwsClients`, which makes `awsClientDefaults()` supply the
2085
+ * scope's region), {@link clientOptions} omits `region` entirely in that
2086
+ * case, so each service client resolves and
2076
2087
  * MEMOIZES its own region independently, at its own first construction, from
2077
- * an environment `deploy.ts`'s `switchRegion` is actively mutating. The
2088
+ * an environment a per-stack region switch may be actively mutating. The
2078
2089
  * members of one region-less bag can therefore disagree with each other:
2079
2090
  * `ssm` can pin `us-west-2` and `secretsManager` pin `us-east-1` a moment
2080
2091
  * later, because the getters are lazy and each samples a different instant.
@@ -2491,14 +2502,44 @@ var AwsClients = class AwsClients {
2491
2502
  */
2492
2503
  let globalClients = null;
2493
2504
  /**
2494
- * Get or create global AWS clients
2505
+ * The AWS clients for the code running now: the active per-stack scope's
2506
+ * clients when one is entered ({@link runWithStackAwsClients}), else the
2507
+ * process-global instance, created on first use.
2508
+ *
2509
+ * The scope comes FIRST so that a stack deploying concurrently with a stack in
2510
+ * another region can never read the other stack's clients (issue
2511
+ * go-to-k/cdkd#1981). `config` only matters when the global is created.
2495
2512
  */
2496
2513
  function getAwsClients(config) {
2514
+ const scoped = currentStackAwsScope();
2515
+ if (scoped) return scoped.clients;
2497
2516
  if (!globalClients) globalClients = new AwsClients(config);
2498
2517
  return globalClients;
2499
2518
  }
2500
2519
  /**
2501
- * Set global AWS clients instance
2520
+ * Run `fn` with `clients` as the AWS clients, and their configured region as
2521
+ * the ambient region, of everything it calls — across `await`s, and without
2522
+ * touching the process-global instance or `process.env.AWS_REGION`, which
2523
+ * concurrently running stacks would otherwise overwrite for each other
2524
+ * (issue go-to-k/cdkd#1981). See `stack-aws-scope.ts`.
2525
+ *
2526
+ * `clients` must be configured with a region: the scope's whole job is to name
2527
+ * one, and a region-less bag resolves its region from the very environment
2528
+ * this replaces.
2529
+ */
2530
+ function runWithStackAwsClients(clients, fn) {
2531
+ const region = clients.configuredRegion;
2532
+ if (region === void 0) throw new Error("runWithStackAwsClients requires AwsClients configured with a region");
2533
+ return runInStackAwsScope({
2534
+ region,
2535
+ clients
2536
+ }, fn);
2537
+ }
2538
+ /**
2539
+ * Set global AWS clients instance.
2540
+ *
2541
+ * Inside a {@link runWithStackAwsClients} scope, `getAwsClients()` keeps
2542
+ * returning the scope's clients: the global this sets is only seen outside it.
2502
2543
  */
2503
2544
  function setAwsClients(clients) {
2504
2545
  globalClients = clients;
@@ -3330,6 +3371,53 @@ function processStackMessages(stacks, logger, options = {}) {
3330
3371
  if (hasWarnings && failAt === "warn") throw new SynthesisError("Found warnings (--strict mode)");
3331
3372
  }
3332
3373
 
3374
+ //#endregion
3375
+ //#region src/utils/glob-match.ts
3376
+ /**
3377
+ * Whether `subject` matches the glob `pattern`, where `*` matches any run of
3378
+ * characters (the empty run included) and EVERY other character is literal.
3379
+ *
3380
+ * The one answer to "what does a stack-selection pattern mean", shared by
3381
+ * `stackMatchesPattern` (`src/cli/stack-matcher.ts`) and the failed-Stage
3382
+ * attribution in `src/synthesis/failed-stages.ts`, so the two cannot disagree
3383
+ * ([#3508](https://github.com/go-to-k/cdkd/issues/3508)). An import-free LEAF,
3384
+ * so both layers may import it.
3385
+ *
3386
+ * **Never a RegExp.** Both sites used to expand `*` into `.*` and compile the
3387
+ * result, which had two defects: a pattern with several `*` separated by
3388
+ * literals backtracked EXPONENTIALLY in the length of the subject (a stack
3389
+ * name or Stage path from the Cloud Assembly), and the other characters were
3390
+ * live regex syntax only when the pattern held a `*` — `My.Stage*` matched
3391
+ * `MyXStage1` while `My.Stage` matched only itself, and `My(Stage*` threw a
3392
+ * `SyntaxError`.
3393
+ *
3394
+ * The walk anchors the text before the first `*` at the start and the text
3395
+ * after the last `*` at the end, then places each middle segment at its
3396
+ * LEFTMOST occurrence after the previous one. Leftmost placement is optimal
3397
+ * when `*` is the only wildcard — any later placement leaves strictly less room
3398
+ * for the segments after it — so no backtracking is needed. The cost is one
3399
+ * `indexOf` per segment, O(|subject| x |pattern|) in the worst case:
3400
+ * polynomial, where the RegExp was exponential.
3401
+ */
3402
+ function globMatches(pattern, subject) {
3403
+ const segments = pattern.split("*");
3404
+ if (segments.length === 1) return pattern === subject;
3405
+ const head = segments[0];
3406
+ const tail = segments[segments.length - 1];
3407
+ if (subject.length < head.length + tail.length) return false;
3408
+ if (!subject.startsWith(head) || !subject.endsWith(tail)) return false;
3409
+ const end = subject.length - tail.length;
3410
+ let cursor = head.length;
3411
+ for (let i = 1; i < segments.length - 1; i++) {
3412
+ const segment = segments[i];
3413
+ if (segment === "") continue;
3414
+ const at = subject.indexOf(segment, cursor);
3415
+ if (at === -1 || at + segment.length > end) return false;
3416
+ cursor = at + segment.length;
3417
+ }
3418
+ return true;
3419
+ }
3420
+
3333
3421
  //#endregion
3334
3422
  //#region src/synthesis/failed-stages.ts
3335
3423
  /**
@@ -3431,29 +3519,7 @@ function patternTargetsStage(pattern, stagePath) {
3431
3519
  const patternSegments = pattern.split("/");
3432
3520
  const stageSegments = stagePath.split("/");
3433
3521
  if (patternSegments.length < stageSegments.length) return false;
3434
- return stageSegments.every((segment, i) => segmentMatches(patternSegments[i], segment));
3435
- }
3436
- /**
3437
- * Wildcard-aware comparison of ONE path segment, matching how
3438
- * `stackMatchesPattern` expands `*` in `src/cli/stack-matcher.ts`. The pattern
3439
- * is the USER's own input, not an assembly-supplied value, so it is expanded
3440
- * there the same way — metacharacters and all, so the two cannot disagree
3441
- * about what a pattern means.
3442
- *
3443
- * The construction is guarded because SPLITTING on `/` can make an invalid
3444
- * segment out of a valid pattern (`'(*x/y*)'` splits into `'(*x'`), and this
3445
- * helper runs when the stack list is EMPTY, which is exactly when
3446
- * `stackMatchesPattern` never evaluates and therefore never raises first. An
3447
- * unusable pattern is simply not attributed: the note still prints, hedged,
3448
- * instead of a `SyntaxError` replacing the message the user needed.
3449
- */
3450
- function segmentMatches(patternSegment, segment) {
3451
- if (!patternSegment.includes("*")) return patternSegment === segment;
3452
- try {
3453
- return new RegExp("^" + patternSegment.replace(/\*/g, ".*") + "$").test(segment);
3454
- } catch {
3455
- return false;
3456
- }
3522
+ return stageSegments.every((segment, i) => globMatches(patternSegments[i], segment));
3457
3523
  }
3458
3524
 
3459
3525
  //#endregion
@@ -3750,7 +3816,7 @@ var ContextStore = class {
3750
3816
  this.logger.debug(`Skipping transient context value for key: ${key}`);
3751
3817
  continue;
3752
3818
  }
3753
- existing[key] = value;
3819
+ defineOwnKey(existing, key, value);
3754
3820
  }
3755
3821
  writeFileSync(filePath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
3756
3822
  this.logger.debug(`Saved ${Object.keys(updates).length} context value(s) to cdk.context.json`);
@@ -4450,7 +4516,7 @@ var ContextProviderRegistry = class {
4450
4516
  * @returns Map of context key → resolved value
4451
4517
  */
4452
4518
  async resolve(missing) {
4453
- const results = {};
4519
+ const results = nullPrototypeRecord();
4454
4520
  for (const entry of missing) {
4455
4521
  const provider = this.providers.get(entry.provider);
4456
4522
  const shownProvider = displaySafe(entry.provider);
@@ -18325,12 +18391,12 @@ var TemplateParser = class {
18325
18391
  const resources = t["Resources"];
18326
18392
  for (const [logicalId, resource] of Object.entries(resources)) {
18327
18393
  if (typeof resource !== "object" || resource === null) {
18328
- this.logger.error(`Resource ${logicalId} is not an object`);
18394
+ this.logger.error(`Resource ${displaySafe(logicalId)} is not an object`);
18329
18395
  return false;
18330
18396
  }
18331
18397
  const r = resource;
18332
18398
  if (!("Type" in r) || typeof r["Type"] !== "string") {
18333
- this.logger.error(`Resource ${logicalId} missing Type or Type is not a string`);
18399
+ this.logger.error(`Resource ${displaySafe(logicalId)} missing Type or Type is not a string`);
18334
18400
  return false;
18335
18401
  }
18336
18402
  }
@@ -18387,7 +18453,7 @@ var TemplateParser = class {
18387
18453
  for (const [logicalId, resource] of Object.entries(template.Resources)) {
18388
18454
  const conditionName = resource.Condition;
18389
18455
  if (conditionName !== void 0 && Object.hasOwn(conditions, conditionName) && conditions[conditionName] === false) {
18390
- this.logger.debug(`Excluding resource ${logicalId} — condition ${conditionName} is false`);
18456
+ this.logger.debug(`Excluding resource ${displaySafe(logicalId)} — condition ${displaySafe(conditionName)} is false`);
18391
18457
  continue;
18392
18458
  }
18393
18459
  if (logicalId === "__proto__") Object.defineProperty(filteredResources, logicalId, {
@@ -20383,14 +20449,11 @@ const PROPERTY_COVERAGE_BY_TYPE = /* @__PURE__ */ new Map([
20383
20449
  "UserPoolTags",
20384
20450
  "UserPoolTier",
20385
20451
  "VerificationMessageTemplate",
20452
+ "WebAuthnFactorConfiguration",
20386
20453
  "WebAuthnRelyingPartyID",
20387
20454
  "WebAuthnUserVerification"
20388
20455
  ]),
20389
- silentDrop: /* @__PURE__ */ new Map([
20390
- ["IssuerConfiguration", "not yet implemented by cdkd"],
20391
- ["KeyConfiguration", "not yet implemented by cdkd"],
20392
- ["WebAuthnFactorConfiguration", "No wire path in the PINNED SDK (@aws-sdk/client-cognito-identity-provider 3.1018.0): WebAuthnConfigurationType is {RelyingPartyId?, UserVerification?} and no CreateUserPool/UpdateUserPool field accepts SINGLE_FACTOR | MULTI_FACTOR_WITH_USER_VERIFICATION. This is an SDK-VERSION limit, NOT an API one -- the live API does honour FactorConfiguration (measured us-east-1 2026-08-20: SetUserPoolMfaConfig(ON) on a pool allowing WEB_AUTHN as a first auth factor is rejected with \"Cannot set WebAuthn factor configuration to SINGLE_FACTOR if MFA is required and WebAuthn is an allowed first auth factor\", i.e. the service reads a field the SDK cannot send). RE-EVALUATE THIS ENTRY ON AN SDK BUMP: if WebAuthnConfigurationType gains FactorConfiguration, the property becomes handleable and this entry must go"]
20393
- ]),
20456
+ silentDrop: /* @__PURE__ */ new Map([["IssuerConfiguration", "not yet implemented by cdkd"], ["KeyConfiguration", "not yet implemented by cdkd"]]),
20394
20457
  createOnlyDrops: /* @__PURE__ */ new Set()
20395
20458
  }],
20396
20459
  ["AWS::DLM::LifecyclePolicy", {
@@ -22698,10 +22761,31 @@ function repairMalformedResourcesForReadOnly(state) {
22698
22761
  * documents `2` as "PARTIAL — journal kept, idempotent re-run", so a `2` here
22699
22762
  * would tell an operator to re-run a command that attempted nothing.
22700
22763
  */
22701
- function malformedStateRefusalMessage(rawStackName, rawRegion) {
22764
+ function malformedStateRefusalMessage(rawStackName, rawRegion, recovery) {
22702
22765
  const stackName = absentIfEmpty(rawStackName);
22703
22766
  const region = absentIfEmpty(rawRegion);
22704
- return `${malformedStateDiagnosis(stackName, region)} This command can WRITE state, so it refuses rather than continuing: saving over a record whose resource map could not be read would replace the evidence with a well-formed empty one and lose it permanently. Repair or remove the record first. Inspect it with: ${inspectCommand(stackName, region)}`;
22767
+ return inspectTail(`${malformedStateDiagnosis(stackName, region)} This command can WRITE state, so it refuses rather than continuing: saving over a record whose resource map could not be read would replace the evidence with a well-formed empty one and lose it permanently. Repair or remove the record first.`, stackName, region, recovery);
22768
+ }
22769
+ /**
22770
+ * How a READ-ONLY remedy ends a single-command message: on
22771
+ * `Inspect it with: <inspectCommand>` — unless the record is a region-less
22772
+ * LEGACY one, which that command cannot read (go-to-k/cdkd#3388).
22773
+ *
22774
+ * A KNOWN stack with NO region is what `cdkd orphan` hands for a legacy
22775
+ * `<prefix>/<stack>/state.json` listed with no region, and `cdkd state show`
22776
+ * refuses such a record with or without `--stack-region`, so ending on it hands
22777
+ * the operator a dead end. That arm names the S3 object instead, through
22778
+ * {@link orphanInspectClause}, which already owns the shape (the object path
22779
+ * gated on the name rendering exactly, the real prefix and bucket when
22780
+ * `recovery` carries them, one location per trailing line).
22781
+ *
22782
+ * Every other identity keeps the command, so a region-keyed record's text is
22783
+ * byte-identical to what it was.
22784
+ */
22785
+ function inspectTail(prose, stackName, region, recovery) {
22786
+ if (stackName === void 0 || region !== void 0) return `${prose} Inspect it with: ${inspectCommand(stackName, region)}`;
22787
+ const legacy = orphanInspectClause(stackName, void 0, recovery);
22788
+ return [`${prose} ${legacy.sentence ?? ""}`.trimEnd(), ...legacy.locations ?? []].join("\n");
22705
22789
  }
22706
22790
  /**
22707
22791
  * The destructive template, in the three messages that offer one.
@@ -22746,7 +22830,7 @@ const DROP_RECORD_LINE = `Drop the record: ${DROP_RECORD_TEMPLATE}`;
22746
22830
  * identity here.
22747
22831
  */
22748
22832
  function mayNameTargetWithDestructiveRemedy(stackName, region) {
22749
- return safeStackName(stackName) === stackName && safeRegion(region) === region && isPasteableIdent(stackName) && isPasteableIdent(region);
22833
+ return rendersExactly(stackName) && rendersExactly(region, SHORT_NAME_MAX_CODE_POINTS) && isPasteableIdent(stackName) && isPasteableIdent(region);
22750
22834
  }
22751
22835
  /**
22752
22836
  * The DESTROY refusal text for the `resources` bag (issue
@@ -22955,7 +23039,7 @@ const STATE_REGION_DIVERGED = "STATE_REGION_DIVERGED";
22955
23039
  */
22956
23040
  function divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBodyRegion, resourceCount) {
22957
23041
  const cap = STACK_REF_MAX_CODE_POINTS;
22958
- const exact = safeIdentifier(stackName, cap) === stackName && safeIdentifier(keyRegion, cap) === keyRegion && isPasteableIdent(stackName) && isPasteableIdent(keyRegion);
23042
+ const exact = rendersExactly(stackName, cap) && rendersExactly(keyRegion, cap) && isPasteableIdent(stackName) && isPasteableIdent(keyRegion);
22959
23043
  const lists = resourceCount === void 0 ? "its resources map cannot be read" : `it still lists ${resourceCount} resource${resourceCount === 1 ? "" : "s"}`;
22960
23044
  const kind = describeRegionValueKind(divergentBodyRegion);
22961
23045
  const opening = exact ? `cdkd will not destroy stack ${shellQuote(safeIdentifier(stackName, cap))} (${shellQuote(safeIdentifier(keyRegion, cap))}): the state record read from that region's key carries a 'region' of its own (${kind}) that is not the key's, and ${lists}` : `cdkd will not destroy the state record this command loaded: it carries a 'region' of its own (${kind}) that is not the region of the key it was read from, and ${lists}`;
@@ -23252,9 +23336,9 @@ function malformedOutputsWarning(rawStackName, rawRegion) {
23252
23336
  * this names the stack, the region, the defect and the remedy, and exits on a
23253
23337
  * code rather than on a stack trace.
23254
23338
  */
23255
- function refuseMalformedState(state, stackName, region) {
23339
+ function refuseMalformedState(state, stackName, region, recovery) {
23256
23340
  if (hasReadableResources(state)) return;
23257
- throw new CdkdError(malformedStateRefusalMessage(stackName, region), STATE_RESOURCES_MALFORMED);
23341
+ throw new CdkdError(malformedStateRefusalMessage(stackName, region, recovery), STATE_RESOURCES_MALFORMED);
23258
23342
  }
23259
23343
  /**
23260
23344
  * The `outputs` half of {@link malformedStateRefusalMessage}, for the same
@@ -23273,10 +23357,10 @@ function refuseMalformedState(state, stackName, region) {
23273
23357
  * Identifiers are sanitized and THEN shell-quoted and the command is emitted
23274
23358
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
23275
23359
  */
23276
- function malformedOutputsRefusalMessage(rawStackName, rawRegion) {
23360
+ function malformedOutputsRefusalMessage(rawStackName, rawRegion, recovery) {
23277
23361
  const stackName = absentIfEmpty(rawStackName);
23278
23362
  const region = absentIfEmpty(rawRegion);
23279
- return `${stackClause(stackName, region)} has no readable 'outputs' map — the record is malformed or truncated. This command can WRITE state, so it refuses rather than continuing: it REBUILDS the bag before saving, and 'Object.entries' walks a string or a list as readily as a map, so a six-character value would be saved back as a well-formed six-key map (a null one as an empty map). That replaces the only signal anything is wrong with a legitimate-looking record, permanently — and the next deploy republishes it into the shared exports index every other stack's Fn::ImportValue resolves against. Repair or remove the record first. Inspect it with: ` + inspectCommand(stackName, region);
23363
+ return inspectTail(`${stackClause(stackName, region)} has no readable 'outputs' map — the record is malformed or truncated. This command can WRITE state, so it refuses rather than continuing: it REBUILDS the bag before saving, and 'Object.entries' walks a string or a list as readily as a map, so a six-character value would be saved back as a well-formed six-key map (a null one as an empty map). That replaces the only signal anything is wrong with a legitimate-looking record, permanently — and the next deploy republishes it into the shared exports index every other stack's Fn::ImportValue resolves against. Repair or remove the record first.`, stackName, region, recovery);
23280
23364
  }
23281
23365
  /**
23282
23366
  * The line `ExportIndexStore`'s rebuild emits for a producer record whose
@@ -23360,9 +23444,9 @@ function malformedExportNamesWarning(rawStackName, rawRegion) {
23360
23444
  * records: a guard written at the rebuild leaves every earlier dereference in
23361
23445
  * front of it.
23362
23446
  */
23363
- function refuseMalformedOutputs(state, stackName, region) {
23447
+ function refuseMalformedOutputs(state, stackName, region, recovery) {
23364
23448
  if (hasReadableOutputs(state)) return;
23365
- throw markNonRetryable(new CdkdError(malformedOutputsRefusalMessage(stackName, region), STATE_RESOURCES_MALFORMED));
23449
+ throw markNonRetryable(new CdkdError(malformedOutputsRefusalMessage(stackName, region, recovery), STATE_RESOURCES_MALFORMED));
23366
23450
  }
23367
23451
  /**
23368
23452
  * The stand-in row a read-only view lists in its `unreadable` set for an
@@ -23393,9 +23477,9 @@ const UNREADABLE_ORPHANS_CONTAINER_ROW = "(orphans container)";
23393
23477
  * ones it cannot see.
23394
23478
  *
23395
23479
  * The ENTRIES are a separate question with a separate answer —
23396
- * `orphans[<i>].properties` is go-to-k/cdkd#3344, and
23397
- * {@link refuseMalformedResourcePropertiesForOrphan} is the guard there. This
23398
- * one says only that the container is a list.
23480
+ * {@link unreadableOrphanRecords}, which `cdkd orphan` refuses on through
23481
+ * {@link refuseMalformedOrphansForOrphan} (go-to-k/cdkd#3344). This one says
23482
+ * only that the container is a list.
23399
23483
  */
23400
23484
  function hasReadableOrphans(state) {
23401
23485
  return state.orphans === void 0 || Array.isArray(state.orphans);
@@ -23766,15 +23850,26 @@ function dropRecordCommand(stackName, region, recovery) {
23766
23850
  * drop command from a legacy record whose name merely needs quoting — the very
23767
23851
  * path go-to-k/cdkd#3359 built, where `cdkd state show` refuses outright and
23768
23852
  * this command is the way out. Measured: `It's Legacy` loses it.
23853
+ *
23854
+ * **The ONE spelling of the exactness test in this module** (go-to-k/cdkd#3388).
23855
+ * The two DESTROY gates measure through it too, each at the cap its own clause
23856
+ * renders at: {@link mayNameTargetWithDestructiveRemedy} passes a region's
23857
+ * `SHORT_NAME_MAX_CODE_POINTS`, and `divergentRecordRegionRefusalMessage`
23858
+ * this default for both identities. `safeStackName(x) === x` and
23859
+ * `safeRegion(x) === x` are this predicate at those two caps, so a site
23860
+ * wanting either says so here instead of re-spelling the comparison —
23861
+ * `tests/unit/state/malformed-resources-bag.test.ts` refuses a second inline
23862
+ * spelling.
23769
23863
  */
23770
- function rendersExactly(value) {
23771
- return safeIdentifier(value, STACK_REF_MAX_CODE_POINTS) === value;
23864
+ function rendersExactly(value, maxCodePoints = STACK_REF_MAX_CODE_POINTS) {
23865
+ return safeIdentifier(value, maxCodePoints) === value;
23772
23866
  }
23773
23867
  /**
23774
23868
  * The remedy command a message ends ON — unless the message also offers the
23775
23869
  * destructive template, in which case it ends the READ's own LINE and
23776
- * {@link DROP_RECORD_LINE} is last (go-to-k/cdkd#3516). Two of the eight call
23777
- * sites are that shape; the rest close their string with it.
23870
+ * {@link DROP_RECORD_LINE} is last (go-to-k/cdkd#3516) — the two DESTROY
23871
+ * refusals; the rest close their string with it, directly or through
23872
+ * {@link inspectTail}.
23778
23873
  */
23779
23874
  function inspectCommand(stackName, region) {
23780
23875
  if (stackName === void 0) return `cdkd state show ${commandHole("stack")} --stack-region ${commandHole("region")} --json`;
@@ -24094,6 +24189,32 @@ function malformedResourcePropertiesRefusalMessage(rawStackName, rawRegion, logi
24094
24189
  function malformedOrphanResourcePropertiesRefusalMessage(rawStackName, rawRegion, logicalIds, recovery) {
24095
24190
  const stackName = absentIfEmpty(rawStackName);
24096
24191
  const region = absentIfEmpty(rawRegion);
24192
+ return orphanRefusal(stackName, region, recovery, `${namedPropertyBagsClause(stackName, region, logicalIds)} 'cdkd orphan' REWRITES and SAVES every record it keeps, so it refuses rather than continuing — under '--dry-run' too, because the rewrite audit table a dry run prints is the wrong one. It is not that the save would fabricate a map: an unreadable bag is carried through VERBATIM. It is that this command exists to leave the record deployable by rewriting every reference to an orphaned resource, and a map it cannot read hides whichever references it holds — a string or a number presents none to find, and a list is walked, so its rewrites are recorded into a container that is still not a map. Continuing would rewrite, save, and report success over a record 'cdkd deploy' then REFUSES.`, SURVIVOR_THIRD_WAY_OUT);
24193
+ }
24194
+ /**
24195
+ * The third way out every `cdkd orphan` refusal over a `resources` ENTRY
24196
+ * offers, conditioned as {@link malformedOrphanResourcePropertiesRefusalMessage}'s
24197
+ * note requires. One spelling for the three refusals scoped to the survivors
24198
+ * (the entry, its `properties` and its `attributes`), which make the same
24199
+ * promise for the same reason: each subtracts the orphan set.
24200
+ */
24201
+ const SURVIVOR_THIRD_WAY_OUT = "A third works only while the CDK app STILL DECLARES the named resource — this refusal covers just the records that would SURVIVE the save, so 'cdkd orphan <its construct path>' removes it and repairs the rest; construct paths come from the synthesized template, so a resource the app no longer declares has none and must take one of the first two.";
24202
+ /**
24203
+ * What every `cdkd orphan` refusal shares after its own diagnosis: the two
24204
+ * template-free ways out, the caller's third, and the pasteable lines.
24205
+ *
24206
+ * `lead` is the diagnosis AND the harm, which is what differs per container —
24207
+ * the rule this module follows for every text. The remedy half does not
24208
+ * differ, and a second copy of it is what would drift: it carries the
24209
+ * substitution gate, the withheld-identity clause and the per-line commands
24210
+ * go-to-k/cdkd#3363 settled. `thirdWayOut` is a full sentence; the ones naming
24211
+ * a record outside `resources` cannot offer `cdkd orphan <construct path>` and
24212
+ * say so instead.
24213
+ *
24214
+ * Takes identities ALREADY normalised by the exported builder's
24215
+ * {@link absentIfEmpty}, which is where that floor lives.
24216
+ */
24217
+ function orphanRefusal(stackName, region, recovery, lead, thirdWayOut, dropCaveat = "") {
24097
24218
  const inspect = orphanInspectClause(stackName, region, recovery);
24098
24219
  const listCommand = withheldIdentityListCommand(stackName, region, recovery);
24099
24220
  const commands = [
@@ -24102,7 +24223,7 @@ function malformedOrphanResourcePropertiesRefusalMessage(rawStackName, rawRegion
24102
24223
  ...inspect.command === void 0 ? [] : [`Inspect the record: ${inspect.command}`]
24103
24224
  ];
24104
24225
  return [
24105
- `${namedPropertyBagsClause(stackName, region, logicalIds)} 'cdkd orphan' REWRITES and SAVES every record it keeps, so it refuses rather than continuing — under '--dry-run' too, because the rewrite audit table a dry run prints is the wrong one. It is not that the save would fabricate a map: an unreadable bag is carried through VERBATIM. It is that this command exists to leave the record deployable by rewriting every reference to an orphaned resource, and a map it cannot read hides whichever references it holds — a string or a number presents none to find, and a list is walked, so its rewrites are recorded into a container that is still not a map. Continuing would rewrite, save, and report success over a record 'cdkd deploy' then REFUSES. No state was written. Two ways out need no CDK app: repair the record by hand, or drop it whole with the 'Drop the record' command below, which leaves the live AWS resources standing${withheldIdentityClause(stackName, region)}${withheldRecoveryClause(recovery)}. A third works only while the CDK app STILL DECLARES the named resource — this refusal covers just the records that would SURVIVE the save, so 'cdkd orphan <its construct path>' removes it and repairs the rest; construct paths come from the synthesized template, so a resource the app no longer declares has none and must take one of the first two.` + (inspect.sentence === void 0 ? "" : ` ${inspect.sentence}`),
24226
+ `${lead} No state was written. Two ways out need no CDK app: repair the record by hand, or drop it whole with the 'Drop the record' command below, which leaves the live AWS resources standing${dropCaveat}${withheldIdentityClause(stackName, region)}${withheldRecoveryClause(recovery)}. ` + thirdWayOut + (inspect.sentence === void 0 ? "" : ` ${inspect.sentence}`),
24106
24227
  ...commands,
24107
24228
  ...inspect.locations ?? []
24108
24229
  ].join("\n");
@@ -24210,6 +24331,9 @@ function orphanInspectCommand(stackName, region, recovery) {
24210
24331
  * With `recovery` the path carries the REAL prefix and names the bucket, the
24211
24332
  * way the drop remedy above it is qualified; without it the prefix is a
24212
24333
  * placeholder and the sentence says how to fill it.
24334
+ *
24335
+ * Its region-less arm is also {@link inspectTail}'s, for the state and outputs
24336
+ * refusals `cdkd orphan` raises over the same legacy record (go-to-k/cdkd#3388).
24213
24337
  */
24214
24338
  function orphanInspectClause(stackName, region, recovery) {
24215
24339
  if (stackName === void 0 || stackName === "") return { command: [`cdkd state show ${commandHole("stack")} --stack-region ${commandHole("region")} --json`, ...recoveryCommandFlags(recovery).flags].join(" ") };
@@ -24247,34 +24371,18 @@ function orphanInspectClause(stackName, region, recovery) {
24247
24371
  * cannot persist a record it is deleting, and because refusing on one would
24248
24372
  * break the recovery path the refusal is otherwise meant to preserve.
24249
24373
  *
24250
- * **It covers `state.resources` ONLY, and the save keeps more than that.**
24251
- * `rewriteResourceReferences` spreads `carriedState`, so `state.orphans[]` —
24252
- * rollback-orphaned records each holding a whole `ResourceState`
24253
- * (go-to-k/cdkd#2934) — rides through untouched, and
24254
- * {@link unreadableResourcePropertyBags} never walks it. A torn bag parked
24255
- * there is therefore still saved, and `computeStackDiff` splices those records
24256
- * into `state.resources` on the next preview. Stated rather than implied,
24257
- * because "the records the save would KEEP" reads wider than what this scans:
24258
- * the gap is go-to-k/cdkd#3344, filed rather than folded in because the remedy
24259
- * differs — an entry in that container has no construct path, so the message's
24260
- * third way out is meaningless for it.
24261
- *
24262
- * **A surviving ENTRY that is not a map is the other gap, and it DOES launder.**
24263
- * This scan asks whether a resource's `properties` is readable; it never asks
24264
- * whether the resource RECORD is. `isReadableBag('abcdef')` is false, so a
24265
- * string entry is skipped here, and then `rewriteResourceReferences`'s
24266
- * `{ ...resource }` spreads it into per-character keys — the record is SAVED as
24267
- * `{"0":"a",…,"dependencies":[]}` and the run reports success. A number entry
24268
- * saves as `{"dependencies":[]}`, a record with no `physicalId`. So the
24269
- * refusal's own text, which says a torn `properties` map is persisted verbatim
24270
- * rather than reshaped, is true of the container it scans and NOT of the one
24271
- * above it.
24272
- *
24273
- * That gap is NOT go-to-k/cdkd#3202's as filed — that issue records only the
24274
- * `null`-entry `TypeError` — and NOT open PR go-to-k/cdkd#3226's, whose file
24275
- * list carries neither `orphan.ts` nor `orphan-rewriter.ts`. A lane closing
24276
- * either one leaves this open, which is why it is named here rather than
24277
- * deferred to them by reference. Filed as go-to-k/cdkd#3350.
24374
+ * **It covers the `properties` map of a `state.resources` entry ONLY, and the
24375
+ * save keeps more than that.** Three siblings answer for the rest, each its
24376
+ * own call because each is its own container with its own consequence:
24377
+ * {@link refuseMalformedResourceEntriesForOrphan} for an entry that is not a
24378
+ * record at all — the one shape the save RESHAPES rather than carries
24379
+ * (go-to-k/cdkd#3350) — {@link refuseMalformedResourceAttributesForOrphan} for
24380
+ * the entry's `attributes` map (go-to-k/cdkd#3345), and
24381
+ * {@link refuseMalformedOrphansForOrphan} for `state.orphans[]`, which the
24382
+ * rewrite spreads through `carriedState` without reading (go-to-k/cdkd#3344).
24383
+ * This scan skips an entry that is not an object, which is why the first of
24384
+ * them has to exist: its "carried through VERBATIM" sentence is true of the
24385
+ * container it scans and false of the one above it.
24278
24386
  *
24279
24387
  * CALL IT AT THE LOAD, beside {@link refuseMalformedState} and
24280
24388
  * {@link refuseMalformedOutputs}, above `rewriteResourceReferences` — the
@@ -24362,8 +24470,9 @@ function isReadableResourceEntry(entry) {
24362
24470
  * and refusing would stop the command documented as the way to UNWIND a stack
24363
24471
  * whose state is already suspect. The other callers (`cdkd import`,
24364
24472
  * `cdkd orphan`, `cdkd scrub`) each owe their own classification; `cdkd orphan`
24365
- * does still throw on an unreadable sibling, which is why that one is tracked on
24366
- * go-to-k/cdkd#3202 rather than answered here by a shared refusal.
24473
+ * answers through its own entry point on this class,
24474
+ * {@link refuseMalformedResourceEntriesForOrphan}, scoped to the records its
24475
+ * save keeps (go-to-k/cdkd#3350).
24367
24476
  *
24368
24477
  * So the entry rule is OPT-IN, taken by a flow that dereferences EVERY entry and
24369
24478
  * writes the record back.
@@ -24503,6 +24612,171 @@ function malformedResourceEntriesRefusalMessage(rawStackName, rawRegion, logical
24503
24612
  const region = absentIfEmpty(rawRegion);
24504
24613
  return `${namedEntriesClause(stackName, region, logicalIds)} This command can WRITE state, so it refuses rather than skipping them: saving over the record would report a clean run for entries nothing could read, and would leave the next command to fail on them with no more to go on. Nothing was locked, read from AWS or written FOR THIS STACK. Inspect it with: ` + inspectCommand(stackName, region);
24505
24614
  }
24615
+ /**
24616
+ * For `cdkd orphan`: refuse a record whose SURVIVING `resources` entries are
24617
+ * not readable resource records (go-to-k/cdkd#3350).
24618
+ *
24619
+ * The ENTRY class's predicate ({@link unreadableResourceEntries}), scoped to
24620
+ * the survivors exactly as the `properties` refusal is: an entry this run
24621
+ * DROPS is never saved, and `cdkd orphan` over the damaged record is the way
24622
+ * out of it, so the orphan set is subtracted. The drop is safe because the
24623
+ * rewriter will not RESOLVE a reference through an unreadable orphaned record —
24624
+ * it reports the site as unresolvable instead (`src/analyzer/orphan-rewriter.ts`).
24625
+ *
24626
+ * A second entry point on the class rather than a widening of
24627
+ * {@link refuseMalformedResourceEntries}, whose text says nothing was LOCKED —
24628
+ * false here, where the lock is taken before the load — and names no way out.
24629
+ */
24630
+ function refuseMalformedResourceEntriesForOrphan(state, removedLogicalIds, stackName, region, recovery) {
24631
+ const removed = new Set(removedLogicalIds);
24632
+ const unreadable = unreadableResourceEntries(state).filter((id) => !removed.has(id));
24633
+ if (unreadable.length === 0) return;
24634
+ throw new CdkdError(malformedOrphanResourceEntriesRefusalMessage(stackName, region, unreadable, recovery), STATE_RESOURCES_MALFORMED);
24635
+ }
24636
+ /**
24637
+ * The text {@link refuseMalformedResourceEntriesForOrphan} raises.
24638
+ *
24639
+ * **This is the one container the save RESHAPES**, so the `properties`
24640
+ * refusal's "carried through VERBATIM" must not be borrowed. Measured through
24641
+ * the real rewrite, which rebuilds each kept record as
24642
+ * `{ ...resource, properties, dependencies }`: `"abcdef"` saved as
24643
+ * `{"0":"a",…,"5":"f","dependencies":[]}`, `5` and `true` as
24644
+ * `{"dependencies":[]}` (no `physicalId` at all), `[{"Ref":"O"}]` as
24645
+ * `{"0":{"Ref":"O"},"dependencies":[]}` with the reference to the orphan left
24646
+ * UNREWRITTEN — the failure this command exists to prevent — and `null` threw
24647
+ * `Cannot read properties of null`. An object with no `resourceType` is the
24648
+ * one shape carried as it stands.
24649
+ */
24650
+ function malformedOrphanResourceEntriesRefusalMessage(rawStackName, rawRegion, logicalIds, recovery) {
24651
+ const stackName = absentIfEmpty(rawStackName);
24652
+ const region = absentIfEmpty(rawRegion);
24653
+ return orphanRefusal(stackName, region, recovery, `${namedEntriesClause(stackName, region, logicalIds)} 'cdkd orphan' REWRITES and SAVES every record it keeps, so it refuses rather than continuing — under '--dry-run' too, so a dry run never prints a plan the real run refuses. The rewrite rebuilds each kept record by copying its fields, and a value that is not an object does not survive the copy: a string or a list is saved as one key per character or element — a list's references to an orphaned resource left UNREWRITTEN — a number or a boolean as a record with no physical id, and null stops the run on a bare TypeError. An object with no resource type is saved as it stands. Continuing would save a record no cdkd command wrote and report success.`, SURVIVOR_THIRD_WAY_OUT);
24654
+ }
24655
+ /**
24656
+ * Whether an ENTRY's `attributes` map — the `Fn::GetAtt` cache — can be read.
24657
+ *
24658
+ * ABSENT IS READABLE: the field is optional on `ResourceState` and plenty of
24659
+ * records carry none. `null` is NOT, the split {@link hasReadableOutputs}
24660
+ * draws for its own container: the resolver's cached-attribute read gates on
24661
+ * `!== undefined` and then indexes the map, so a `null` passes the gate and a
24662
+ * string or a list answers for keys it does not hold.
24663
+ */
24664
+ function hasReadableAttributes(entry) {
24665
+ const attributes = entry.attributes;
24666
+ return attributes === void 0 || isReadableBag(attributes);
24667
+ }
24668
+ /**
24669
+ * The logical ids whose `resources` entry carries an `attributes` map that
24670
+ * cannot be read (go-to-k/cdkd#3345). Like {@link unreadableResourcePropertyBags}
24671
+ * it skips an entry that is not an object — that is the ENTRY class's to name —
24672
+ * and returns `[]` for an unreadable bag.
24673
+ */
24674
+ function unreadableResourceAttributeBags(state) {
24675
+ if (!hasReadableResources(state)) return [];
24676
+ return Object.entries(state.resources).filter(([, entry]) => isReadableBag(entry) && !hasReadableAttributes(entry)).map(([logicalId]) => logicalId);
24677
+ }
24678
+ /**
24679
+ * For `cdkd orphan`: refuse a record whose SURVIVING entries carry an
24680
+ * unreadable `attributes` map (go-to-k/cdkd#3345). Scoped to the survivors for
24681
+ * the reason {@link refuseMalformedResourceEntriesForOrphan} is; an ORPHANED
24682
+ * entry's map is the `--force` cache, and the rewriter reads that one as
24683
+ * holding nothing instead of indexing it.
24684
+ */
24685
+ function refuseMalformedResourceAttributesForOrphan(state, removedLogicalIds, stackName, region, recovery) {
24686
+ const removed = new Set(removedLogicalIds);
24687
+ const unreadable = unreadableResourceAttributeBags(state).filter((id) => !removed.has(id));
24688
+ if (unreadable.length === 0) return;
24689
+ throw new CdkdError(malformedOrphanResourceAttributesRefusalMessage(stackName, region, unreadable, recovery), STATE_RESOURCES_MALFORMED);
24690
+ }
24691
+ /**
24692
+ * The text {@link refuseMalformedResourceAttributesForOrphan} raises.
24693
+ *
24694
+ * Measured through the real rewrite: `"abcdef"`, `5`, `0`, `""`, `false` and
24695
+ * `null` are carried into the save byte for byte (the falsy ones skip
24696
+ * `rewriteValue` and survive through the spread), and `[{"Ref":"O"}]` is
24697
+ * WALKED, coming back `["<physical id>"]` — a rewrite recorded into a container
24698
+ * that is still not a map, the `properties` refusal's list case one field over.
24699
+ */
24700
+ function malformedOrphanResourceAttributesRefusalMessage(rawStackName, rawRegion, logicalIds, recovery) {
24701
+ const stackName = absentIfEmpty(rawStackName);
24702
+ const region = absentIfEmpty(rawRegion);
24703
+ const named = logicalIds.slice(0, NAMED_UNREADABLE_ENTRIES).map((id) => displayLogicalId(id)).join(", ");
24704
+ const rest = logicalIds.length - NAMED_UNREADABLE_ENTRIES;
24705
+ const more = rest > 0 ? ` and ${rest} more` : "";
24706
+ return orphanRefusal(stackName, region, recovery, `${stackClause(stackName, region)} holds ${logicalIds.length} resource record(s) whose 'attributes' map cannot be read — ${named}${more} — because it is null or not an object. The record is malformed or truncated. 'cdkd orphan' REWRITES and SAVES every record it keeps, so it refuses rather than continuing — under '--dry-run' too, so a dry run never prints a plan the real run refuses. The map is carried into the save VERBATIM, and a list is walked, so its rewrites are recorded into a container that is still not a map. It is the cache a later 'cdkd deploy' reads another resource's 'Fn::GetAtt' of this one from, so continuing would report success over the one map that read depends on.`, SURVIVOR_THIRD_WAY_OUT);
24707
+ }
24708
+ /**
24709
+ * The `orphans[]` records a reader cannot use: a record that is not an object
24710
+ * or has no string `logicalId`, whose `state` is not a readable resource entry,
24711
+ * or whose `state` carries an unreadable `properties` or `attributes` map
24712
+ * (go-to-k/cdkd#3344). The `logicalId` half is go-to-k/cdkd#3500's row
24713
+ * predicate: rows with none all key one map entry, and `orphansAfterRollback`
24714
+ * collapses them into one.
24715
+ *
24716
+ * Every `ResourceState` question the `resources` side answers in separate
24717
+ * predicates, asked in ONE here: a rollback-orphan record is reached only as a
24718
+ * whole — `computeStackDiff` and the deploy's adoption pass splice the record
24719
+ * into `resources` — so which part of it is torn does not change what a caller
24720
+ * can do with it. Returns `[]` for a container that is not a list, which is
24721
+ * {@link hasReadableOrphans}'s to report. Each record is named by its
24722
+ * `logicalId`, or `''` (rendered as the `UNRENDERABLE` stand-in) when it has
24723
+ * no string one — the convention {@link malformedOrphanRecordsWarning} takes.
24724
+ */
24725
+ function unreadableOrphanRecords(state) {
24726
+ if (!Array.isArray(state.orphans)) return [];
24727
+ return state.orphans.filter((record) => {
24728
+ if (!isReadableBag(record)) return true;
24729
+ if (typeof record.logicalId !== "string") return true;
24730
+ const entry = record.state;
24731
+ return !isReadableResourceEntry(entry) || !isReadableBag(entry.properties) || !hasReadableAttributes(entry);
24732
+ }).map((record) => {
24733
+ const id = isReadableBag(record) ? record.logicalId : void 0;
24734
+ return typeof id === "string" ? id : "";
24735
+ });
24736
+ }
24737
+ /**
24738
+ * For `cdkd orphan`: refuse a record whose `orphans` list, or any record in
24739
+ * it, cannot be read (go-to-k/cdkd#3344).
24740
+ *
24741
+ * A THIRD entry point on the `orphans` container, beside
24742
+ * {@link refuseMalformedOrphans} and its destroy twin, because neither text is
24743
+ * true here. The rewrite neither walks nor rebuilds this container — it
24744
+ * spreads it through `carriedState` VERBATIM (measured: `"abc"` comes back
24745
+ * `"abc"`, a record whose `state.properties` is `"abcdef"` comes back byte for
24746
+ * byte) — so the rollback text's "written back as a list of character-shaped
24747
+ * orphan records" would be false. What this command does is SAVE it, report
24748
+ * success, and leave the damage for the next deploy or diff to meet.
24749
+ *
24750
+ * NOT scoped by the orphan set: these records are not in `resources`, so
24751
+ * `cdkd orphan` cannot name one, and its save keeps every one of them.
24752
+ */
24753
+ function refuseMalformedOrphansForOrphan(state, stackName, region, recovery) {
24754
+ if (!hasReadableOrphans(state)) throw new CdkdError(malformedOrphansForOrphanRefusalMessage(stackName, region, void 0, recovery), STATE_RESOURCES_MALFORMED);
24755
+ const unreadable = unreadableOrphanRecords(state);
24756
+ if (unreadable.length === 0) return;
24757
+ throw new CdkdError(malformedOrphansForOrphanRefusalMessage(stackName, region, unreadable, recovery), STATE_RESOURCES_MALFORMED);
24758
+ }
24759
+ /** See {@link orphanRefusal}'s `dropCaveat`. */
24760
+ const ORPHANS_DROP_CAVEAT = "; it also discards the 'orphans' list, the only record of resources an earlier failed deploy left live in AWS";
24761
+ /**
24762
+ * The text {@link refuseMalformedOrphansForOrphan} raises: the CONTAINER arm
24763
+ * when `logicalIds` is `undefined`, the RECORDS arm otherwise.
24764
+ *
24765
+ * Its third way out is not {@link SURVIVOR_THIRD_WAY_OUT}: a record in
24766
+ * `orphans` has no construct path, so `cdkd orphan` cannot remove it, and the
24767
+ * hand repair that remains must not be a deletion — the record is the only
24768
+ * evidence that an earlier failed deploy left its resource live in AWS.
24769
+ */
24770
+ function malformedOrphansForOrphanRefusalMessage(rawStackName, rawRegion, logicalIds, recovery) {
24771
+ const stackName = absentIfEmpty(rawStackName);
24772
+ const region = absentIfEmpty(rawRegion);
24773
+ const verbatim = "'cdkd orphan' carries it into the record it saves VERBATIM, without reading it, so it refuses rather than continuing — under '--dry-run' too, so a dry run never prints a plan the real run refuses.";
24774
+ if (logicalIds === void 0) return orphanRefusal(stackName, region, recovery, `${stackClause(stackName, region)} has no readable 'orphans' list — the record is malformed or truncated. ${verbatim} The next 'cdkd deploy' refuses the same record, so continuing would only report success over it and leave that refusal one command later.`, "'cdkd orphan' cannot address this list at all, and rewriting it to [] by hand discards the only record of resources an earlier failed deploy left live in AWS.", ORPHANS_DROP_CAVEAT);
24775
+ const named = logicalIds.slice(0, NAMED_UNREADABLE_ENTRIES).map((id) => displayLogicalId(id)).join(", ");
24776
+ const rest = logicalIds.length - NAMED_UNREADABLE_ENTRIES;
24777
+ const more = rest > 0 ? ` and ${rest} more` : "";
24778
+ return orphanRefusal(stackName, region, recovery, `${stackClause(stackName, region)} holds ${logicalIds.length} rollback-orphan record(s) in 'orphans' that cannot be read — ${named}${more} — because the record has no string 'logicalId', its 'state' is not an object or names no resource type, or that state's 'properties' or 'attributes' map is not one. The record is malformed or truncated. ${verbatim} Those records are not inert: they are what the next 'cdkd deploy' may re-adopt into 'resources' and what 'cdkd diff' previews for adoption, so continuing would report success over damage the next command meets.`, "'cdkd orphan' cannot remove such a record itself: it is not in 'resources', so it has no construct path. Repair the record by hand rather than deleting it — it is the only record that an earlier failed deploy left its resource live in AWS.", ORPHANS_DROP_CAVEAT);
24779
+ }
24506
24780
 
24507
24781
  //#endregion
24508
24782
  //#region src/analyzer/diff-calculator.ts
@@ -27288,7 +27562,7 @@ function parseWebACLArn(arn) {
27288
27562
  */
27289
27563
  var WAFv2WebACLProvider = class {
27290
27564
  wafv2Client;
27291
- providerRegion = process.env["AWS_REGION"];
27565
+ providerRegion = ambientRegion();
27292
27566
  logger = getLogger().child("WAFv2WebACLProvider");
27293
27567
  handledProperties = /* @__PURE__ */ new Map([["AWS::WAFv2::WebACL", /* @__PURE__ */ new Set([
27294
27568
  "Name",
@@ -28218,6 +28492,19 @@ function nestedStackChildRegionFromLocalArn(physicalId) {
28218
28492
  return NESTED_STACK_LOCAL_ARN.exec(physicalId)?.[1];
28219
28493
  }
28220
28494
  /**
28495
+ * The array position a RESOLVED `Fn::Select` index names, or `undefined` when
28496
+ * it names none (issue #3574): a non-negative safe integer, or its canonical
28497
+ * decimal string (CloudFormation accepts `"1"`, and a `Ref` to a parameter the
28498
+ * resolver did not coerce is still a string). No `Number()` on anything else:
28499
+ * it trims whitespace and maps `""` / `null` / `[]` to `0`. No leading zero
28500
+ * either, so `String(position)` IS the resolved text and masks like it — the
28501
+ * same shape `import.ts`'s `isStaticSelectIndex` vouches for.
28502
+ */
28503
+ function selectIndexPosition(value) {
28504
+ const n = typeof value === "number" ? value : typeof value === "string" && /^(0|[1-9][0-9]*)$/.test(value) ? Number(value) : void 0;
28505
+ return n !== void 0 && Number.isSafeInteger(n) && n >= 0 ? n : void 0;
28506
+ }
28507
+ /**
28221
28508
  * The prefix every dynamic-reference diagnostic this resolver spells carries.
28222
28509
  *
28223
28510
  * Exported because `cdkd scrub` applies the SAME partition on its side and must
@@ -29973,7 +30260,35 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
29973
30260
  if (carriedBefore === 0) return;
29974
30261
  if (inheritedSecretsCarriedBy(this.coerceParameterValue(userValue, paramDef.Type), inherited).length >= carriedBefore) return;
29975
30262
  const loggedName = this.displayMasked(name);
29976
- throw markNonRetryable(new IntrinsicResolutionRefusalError(`Nested-stack parameter '${loggedName}' 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 '${loggedName}' 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"));
30263
+ const loggedType = this.displayMasked(paramDef.Type);
30264
+ throw markNonRetryable(new IntrinsicResolutionRefusalError(`Nested-stack parameter '${loggedName}' is declared 'Type: ${loggedType}', 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 '${loggedType}' 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 '${loggedName}' 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"));
30265
+ }
30266
+ /**
30267
+ * The ONE read of a state record by logical id, shared by `Ref` and
30268
+ * `Fn::GetAtt` (the only two arms that take a record out of
30269
+ * `context.resources`; every other method receives it from them).
30270
+ *
30271
+ * - `Object.hasOwn`, never a bare read (issue #2767): the logical id is
30272
+ * template text, and a plain-object read walks the prototype chain.
30273
+ * - A record whose `physicalId` is not a string, or that is not an object at
30274
+ * all, is REFUSED here, above every reader (issue #3576). Nothing in
30275
+ * `src/state/` checks the type, so a hand edit or a foreign writer can
30276
+ * leave a number, and the arms below call `.startsWith` / `.replace` on
30277
+ * it (a bare `TypeError`) or build an ARN from it. cdkd never writes such
30278
+ * a record, so no answer derived from it is honest. `markNonRetryable`:
30279
+ * the verdict is a function of the persisted record, and the message
30280
+ * carries a template-controlled id. A NULL record keeps missing as before.
30281
+ */
30282
+ lookupResourceRecord(logicalId, via, context) {
30283
+ const resource = Object.hasOwn(context.resources, logicalId) ? context.resources[logicalId] : void 0;
30284
+ if (!resource) return void 0;
30285
+ const isObject = typeof resource === "object" && !Array.isArray(resource);
30286
+ const physicalId = isObject ? resource.physicalId : void 0;
30287
+ if (typeof physicalId !== "string") {
30288
+ const loggedId = this.displayMasked(logicalId, context);
30289
+ throw markNonRetryable(new IntrinsicResolutionRefusalError(`${via} ${loggedId}: ${isObject ? `the state record's physical id is ${physicalId === null ? "null" : typeof physicalId}, not a string` : `the state record is ${Array.isArray(resource) ? "an array" : typeof resource}, not an object`}. cdkd always records an object with a string id, so this record was edited by hand or written by another tool. ${isObject ? `Set the resource's "physicalId" in the stack's state.json back to the id AWS knows the resource by.` : `Restore the resource's record in the stack's state.json, or remove it and re-import the resource.`}`, void 0, "STATE_PHYSICAL_ID_NOT_STRING"));
30290
+ }
30291
+ return resource;
29977
30292
  }
29978
30293
  /**
29979
30294
  * Resolve Ref intrinsic function
@@ -29984,10 +30299,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
29984
30299
  * 3. Pseudo parameters (AWS::Region, AWS::AccountId, etc.)
29985
30300
  */
29986
30301
  async resolveRef(logicalId, context) {
29987
- const resource = Object.hasOwn(context.resources, logicalId) ? context.resources[logicalId] : void 0;
30302
+ const resource = this.lookupResourceRecord(logicalId, "Ref", context);
29988
30303
  if (resource) {
29989
30304
  const refValue = this.resolveRefValue(logicalId, resource, context);
29990
- this.logger.debug(`Resolved Ref to resource: ${this.displayMasked(logicalId, context)} -> ${refValue}`);
30305
+ this.logger.debug(`Resolved Ref to resource: ${this.displayMasked(logicalId, context)} -> ${this.displayMasked(String(refValue), context)}`);
29991
30306
  return refValue;
29992
30307
  }
29993
30308
  if (context.parameters && Object.hasOwn(context.parameters, logicalId)) {
@@ -30001,7 +30316,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30001
30316
  const pseudoValue = await this.resolvePseudoParameter(logicalId, context);
30002
30317
  if (pseudoValue !== void 0) {
30003
30318
  const valueStr = typeof pseudoValue === "symbol" ? pseudoValue.toString() : String(pseudoValue);
30004
- this.logger.debug(`Resolved Ref to pseudo parameter: ${logicalId} -> ${valueStr}`);
30319
+ this.logger.debug(`Resolved Ref to pseudo parameter: ${logicalId} -> ${this.displayMasked(valueStr, context)}`);
30005
30320
  return pseudoValue;
30006
30321
  }
30007
30322
  const loggedLogicalId = this.displayMasked(logicalId, context);
@@ -30174,11 +30489,11 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30174
30489
  attributeName = resolvedAttributeName;
30175
30490
  } else {
30176
30491
  const split = splitGetAttStringForm(getAtt);
30177
- if (split === void 0) throw markNonRetryable(/* @__PURE__ */ new Error(`Invalid Fn::GetAtt format: ${getAtt}`));
30492
+ if (split === void 0) throw markNonRetryable(/* @__PURE__ */ new Error(`Invalid Fn::GetAtt format: ${this.displayMasked(getAtt, context)}`));
30178
30493
  logicalId = split.logicalId;
30179
30494
  attributeName = split.attributeName;
30180
30495
  }
30181
- const resource = Object.hasOwn(context.resources, logicalId) ? context.resources[logicalId] : void 0;
30496
+ const resource = this.lookupResourceRecord(logicalId, "Fn::GetAtt", context);
30182
30497
  if (!resource) throw markNonRetryable(/* @__PURE__ */ new Error(`Resource ${this.displayMasked(logicalId, context)} not found for Fn::GetAtt`));
30183
30498
  if (!(resource.resourceType === "AWS::EC2::VPC" && attributeName === "Ipv6CidrBlocks") && resource.attributes !== void 0) {
30184
30499
  const storedValue = Object.hasOwn(resource.attributes, attributeName) ? resource.attributes[attributeName] : void 0;
@@ -30259,8 +30574,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30259
30574
  * which reads the SAME persisted `attributes` bag and shipped without the
30260
30575
  * note (it takes it now). The rule the note actually needs is about the
30261
30576
  * SOURCE of the value — every branch serving one out of a PERSISTED
30262
- * `attributes` bag must call this — and that is not a shape a compiler can
30263
- * enforce. `constructGuardedAttribute`'s return is deliberately outside it:
30577
+ * `attributes` bag must call this, and so must one serving (or embedding) a
30578
+ * persisted `properties` leaf, which a mask-only needle masks whole
30579
+ * (go-to-k/cdkd#2936: the VPC `CidrBlock` and Events rule `Arn` arms) — and
30580
+ * that is not a shape a compiler can enforce. `constructGuardedAttribute`'s return is deliberately outside it:
30264
30581
  * that value is fetched from AWS in this run, not read back from state, so
30265
30582
  * it can be neither a stale mask nor a value a provider declared `NoEcho`.
30266
30583
  *
@@ -30348,7 +30665,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30348
30665
  * predate the enrichment and `cdkd deploy` is what heals it.
30349
30666
  */
30350
30667
  unenrichedRemedy(resourceType, attributeName, outcome, context) {
30351
- const fileIssue = `Avoid this Fn::GetAtt, or file an issue at https://github.com/go-to-k/cdkd/issues so cdkd can enrich ${resourceType}.${this.displayMasked(attributeName, context)}.`;
30668
+ const fileIssue = `Avoid this Fn::GetAtt, or file an issue at https://github.com/go-to-k/cdkd/issues so cdkd can enrich ${this.displayMasked(resourceType, context)}.${this.displayMasked(attributeName, context)}.`;
30352
30669
  if (outcome === void 0) return `If this record was written by an older cdkd that did not record the attribute yet, 'cdkd deploy' re-reads it from AWS and heals the record. ${fileIssue}`;
30353
30670
  if (outcome.kind === "read") {
30354
30671
  if (this.healWithheld(outcome, attributeName)) return this.withheldRemedy();
@@ -30491,7 +30808,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30491
30808
  async constructGuardedAttribute(resource, attributeName, context, logicalId) {
30492
30809
  const accountInfo = await getAccountInfo(this.resolverRegion);
30493
30810
  const value = await this.constructAttribute(resource, attributeName, context, logicalId, accountInfo);
30494
- if (accountInfo.fabricated && embedsAccountId(value, accountInfo.accountId)) throw new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${resource.resourceType}: STS did not report this deploy's account id, so cdkd would build the value from the placeholder account ${accountInfo.accountId} — structurally valid, naming a different account, and indistinguishable downstream from a real one. Fix the AWS credentials (or set AWS_ACCOUNT_ID to this deploy's account) and deploy again.`);
30811
+ if (accountInfo.fabricated && embedsAccountId(value, accountInfo.accountId)) throw new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${this.displayMasked(resource.resourceType, context)}: STS did not report this deploy's account id, so cdkd would build the value from the placeholder account ${accountInfo.accountId} — structurally valid, naming a different account, and indistinguishable downstream from a real one. Fix the AWS credentials (or set AWS_ACCOUNT_ID to this deploy's account) and deploy again.`);
30495
30812
  return value;
30496
30813
  }
30497
30814
  /**
@@ -30528,28 +30845,29 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30528
30845
  }
30529
30846
  if (resourceType === "AWS::EC2::VPC") switch (attributeName) {
30530
30847
  case "VpcId": return physicalId;
30531
- case "CidrBlock": return resource.attributes?.["CidrBlock"] || resource.properties?.["CidrBlock"];
30848
+ case "CidrBlock": return this.noteAttributeSecrecy(logicalId, attributeName, resource.attributes?.["CidrBlock"] || resource.properties?.["CidrBlock"], context);
30532
30849
  case "Ipv6CidrBlocks": try {
30533
30850
  const ec2 = this.clientsForRegion(this.explicitRegion).ec2;
30534
30851
  const maxAttempts = 15;
30852
+ const loggedId = this.displayMasked(physicalId, context);
30535
30853
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
30536
30854
  const associations = (await ec2.send(new DescribeVpcsCommand({ VpcIds: [physicalId] }))).Vpcs?.[0]?.Ipv6CidrBlockAssociationSet || [];
30537
30855
  const blocks = associations.filter((a) => a.Ipv6CidrBlockState?.State === "associated").map((a) => a.Ipv6CidrBlock);
30538
30856
  if (blocks.length > 0) {
30539
- this.logger.debug(`Resolved VPC Ipv6CidrBlocks for ${physicalId}: ${this.displayMasked(JSON.stringify(this.maskValueLeaves(blocks, context)), context)}`);
30857
+ this.logger.debug(`Resolved VPC Ipv6CidrBlocks for ${loggedId}: ${this.displayMasked(JSON.stringify(this.maskValueLeaves(blocks, context)), context)}`);
30540
30858
  return blocks;
30541
30859
  }
30542
30860
  if (associations.filter((a) => a.Ipv6CidrBlockState?.State === "associating").length === 0) {
30543
- this.logger.debug(`No IPv6 CIDR associations found for VPC ${physicalId}`);
30861
+ this.logger.debug(`No IPv6 CIDR associations found for VPC ${loggedId}`);
30544
30862
  return [];
30545
30863
  }
30546
- this.logger.debug(`VPC ${physicalId} IPv6 CIDR still associating (attempt ${attempt}/${maxAttempts}), waiting...`);
30864
+ this.logger.debug(`VPC ${loggedId} IPv6 CIDR still associating (attempt ${attempt}/${maxAttempts}), waiting...`);
30547
30865
  await new Promise((resolve) => setTimeout(resolve, 2e3));
30548
30866
  }
30549
- this.logger.warn(`VPC ${physicalId} IPv6 CIDR did not reach 'associated' state after ${maxAttempts} attempts`);
30867
+ this.logger.warn(`VPC ${loggedId} IPv6 CIDR did not reach 'associated' state after ${maxAttempts} attempts`);
30550
30868
  return [];
30551
30869
  } catch (error) {
30552
- this.logger.warn(`Failed to fetch VPC Ipv6CidrBlocks for ${physicalId}: ${error instanceof Error ? error.message : String(error)}`);
30870
+ this.logger.warn(`Failed to fetch VPC Ipv6CidrBlocks for ${this.displayMasked(physicalId, context)}: ${this.displayMasked(error instanceof Error ? error.message : String(error), context)}`);
30553
30871
  return [];
30554
30872
  }
30555
30873
  case "DefaultSecurityGroup": {
@@ -30626,7 +30944,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30626
30944
  if (resourceType === "AWS::Events::Rule") switch (attributeName) {
30627
30945
  case "Arn": {
30628
30946
  if (physicalId.startsWith("arn:")) return physicalId;
30629
- const busRaw = resource.properties?.["EventBusName"];
30947
+ const busRaw = this.noteAttributeSecrecy(logicalId, attributeName, resource.properties?.["EventBusName"], context);
30630
30948
  const bus = typeof busRaw === "string" && busRaw && busRaw !== "default" ? busRaw : "";
30631
30949
  const busName = bus.startsWith("arn:") ? bus.split("/").pop() || "" : bus;
30632
30950
  return busName ? `arn:${partition}:events:${region}:${accountId}:rule/${busName}/${physicalId}` : `arn:${partition}:events:${region}:${accountId}:rule/${physicalId}`;
@@ -30674,7 +30992,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30674
30992
  const { GetNamespaceCommand } = await import("@aws-sdk/client-servicediscovery");
30675
30993
  return (await (await this.serviceDiscoveryClient()).send(new GetNamespaceCommand({ Id: physicalId }))).Namespace?.Properties?.DnsProperties?.HostedZoneId;
30676
30994
  } catch (error) {
30677
- this.logger.warn(`Failed to fetch HostedZoneId for namespace ${physicalId}: ${error instanceof Error ? error.message : String(error)}`);
30995
+ this.logger.warn(`Failed to fetch HostedZoneId for namespace ${this.displayMasked(physicalId, context)}: ${this.displayMasked(error instanceof Error ? error.message : String(error), context)}`);
30678
30996
  return;
30679
30997
  }
30680
30998
  default: return this.guardedPhysicalIdFallback(logicalId, attributeName, resourceType, physicalId, context);
@@ -30875,7 +31193,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30875
31193
  const value = attributeName === "LatestVersionNumber" ? lt?.LatestVersionNumber : lt?.DefaultVersionNumber;
30876
31194
  if (value !== void 0 && value !== null) return String(value);
30877
31195
  } catch (err) {
30878
- this.logger.warn(`DescribeLaunchTemplates(${physicalId}) failed for ${this.displayMasked(attributeName, context)}: ${this.displayMasked(err instanceof Error ? err.message : String(err), context)}`);
31196
+ this.logger.warn(`DescribeLaunchTemplates(${this.displayMasked(physicalId, context)}) failed for ${this.displayMasked(attributeName, context)}: ${this.displayMasked(err instanceof Error ? err.message : String(err), context)}`);
30879
31197
  }
30880
31198
  return attributeName === "LatestVersionNumber" ? "$Latest" : "$Default";
30881
31199
  }
@@ -30982,7 +31300,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
30982
31300
  */
30983
31301
  refuseUnservedAttribute(site) {
30984
31302
  const { logicalId, attributeName, resourceType, physicalId, context, observed, remedy } = site;
30985
- throw new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${resourceType}: ${observed}. The physical id "${this.displayMasked(physicalId, context)}" is not a usable ${this.displayMasked(attributeName, context)}, so cdkd refuses to substitute it. ${remedy}`);
31303
+ throw new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${this.displayMasked(resourceType, context)}: ${observed}. The physical id "${this.displayMasked(physicalId, context)}" is not a usable ${this.displayMasked(attributeName, context)}, so cdkd refuses to substitute it. ${remedy}`);
30986
31304
  }
30987
31305
  /**
30988
31306
  * The `observed` clause of {@link refuseUnservedAttribute} for a live read
@@ -31028,20 +31346,21 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
31028
31346
  if (context?.staleAttributeHeal?.phase === "probe") throw new StaleAttributeMissSignal();
31029
31347
  const healOutcome = context?.staleAttributeHeal?.phase === "settled" ? context.staleAttributeHeal.outcome : void 0;
31030
31348
  const recordMayBeStale = healOutcome?.kind === "failed" || healOutcome?.kind === "not-found";
31349
+ const loggedType = this.displayMasked(resourceType, context);
31031
31350
  const expectsArnShape = attributeName.endsWith("Arn") && !physicalId.startsWith("arn:");
31032
31351
  const expectsUrlShape = attributeName.endsWith("Url") && !/^https?:\/\//.test(physicalId);
31033
31352
  if (expectsArnShape || expectsUrlShape) {
31034
31353
  const expectedShape = expectsArnShape ? "an ARN (arn:...)" : "a URL (http(s)://...)";
31035
- throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${resourceType}: ` + (recordMayBeStale ? `the state record holds no value for it, and the physical ID ` : `attributes are not enriched for this resource type, and the physical ID `) + `fallback "${this.displayMasked(physicalId, context)}" is not ${expectedShape}. CloudFormation would return a different value here, so falling back to the physical ID would silently produce a wrong value (e.g. in stack Outputs). ` + (recordMayBeStale ? this.staleRecordRemedy(healOutcome, context) : this.unenrichedRemedy(resourceType, attributeName, healOutcome, context))));
31354
+ throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${loggedType}: ` + (recordMayBeStale ? `the state record holds no value for it, and the physical ID ` : `attributes are not enriched for this resource type, and the physical ID `) + `fallback "${this.displayMasked(physicalId, context)}" is not ${expectedShape}. CloudFormation would return a different value here, so falling back to the physical ID would silently produce a wrong value (e.g. in stack Outputs). ` + (recordMayBeStale ? this.staleRecordRemedy(healOutcome, context) : this.unenrichedRemedy(resourceType, attributeName, healOutcome, context))));
31036
31355
  }
31037
- if (this.strictGetAtt) throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${resourceType}: ` + (recordMayBeStale ? `the state record holds no value for it, and --strict-getatt ` : `attributes are not enriched for this resource type, and --strict-getatt `) + `rejects the physical ID fallback "${this.displayMasked(physicalId, context)}" (which may not be the value CloudFormation would return). Drop --strict-getatt to fall back with a warning. ` + (recordMayBeStale ? this.staleRecordRemedy(healOutcome, context) : this.unenrichedRemedy(resourceType, attributeName, healOutcome, context))));
31356
+ if (this.strictGetAtt) throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${this.displayMasked(logicalId, context)}, ${this.displayMasked(attributeName, context)}] for ${loggedType}: ` + (recordMayBeStale ? `the state record holds no value for it, and --strict-getatt ` : `attributes are not enriched for this resource type, and --strict-getatt `) + `rejects the physical ID fallback "${this.displayMasked(physicalId, context)}" (which may not be the value CloudFormation would return). Drop --strict-getatt to fall back with a warning. ` + (recordMayBeStale ? this.staleRecordRemedy(healOutcome, context) : this.unenrichedRemedy(resourceType, attributeName, healOutcome, context))));
31038
31357
  this.physicalIdFallbackCount++;
31039
31358
  if (recordMayBeStale) {
31040
- this.logger.warn(`The state record for ${this.displayMasked(logicalId, context)} (${resourceType}) holds no ${this.displayMasked(attributeName, context)}, returning physical ID. ` + this.staleRecordRemedy(healOutcome, context));
31359
+ this.logger.warn(`The state record for ${this.displayMasked(logicalId, context)} (${loggedType}) holds no ${this.displayMasked(attributeName, context)}, returning physical ID. ` + this.staleRecordRemedy(healOutcome, context));
31041
31360
  return physicalId;
31042
31361
  }
31043
31362
  const withheld = healOutcome?.kind === "read" && this.healWithheld(healOutcome, attributeName) ? `. ${this.withheldRemedy()}` : "";
31044
- this.logger.warn(`Unknown attribute ${this.displayMasked(attributeName, context)} for resource type ${resourceType}, returning physical ID${withheld}`);
31363
+ this.logger.warn(`Unknown attribute ${this.displayMasked(attributeName, context)} for resource type ${loggedType}, returning physical ID${withheld}`);
31045
31364
  return physicalId;
31046
31365
  }
31047
31366
  /**
@@ -31368,18 +31687,29 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
31368
31687
  * Resolve Fn::Select intrinsic function
31369
31688
  *
31370
31689
  * Fn::Select: [index, [value1, value2, ...]]
31371
- * Returns the value at the specified index in the list
31690
+ * Returns the value at the specified index in the list. The index may be an
31691
+ * intrinsic; it is resolved, then must name a position (issue #3574).
31372
31692
  */
31373
31693
  async resolveSelect(selectArgs, context) {
31694
+ if (!Array.isArray(selectArgs) || selectArgs.length !== 2) throw markNonRetryable(new IntrinsicResolutionRefusalError(`Fn::Select takes a two-element list [index, list], got ${this.describeOperandShape(selectArgs, context)}`));
31374
31695
  const [index, list] = selectArgs;
31696
+ const resolvedIndex = await this.resolveValue(index, context);
31697
+ const position = selectIndexPosition(resolvedIndex);
31698
+ if (position === void 0) {
31699
+ const source = this.describeSplitValueSource(index);
31700
+ const sourceClause = source ? ` (from ${this.displayMasked(source.label, context)})` : "";
31701
+ throw markNonRetryable(new IntrinsicResolutionRefusalError(`Fn::Select: the index${sourceClause} must resolve to a non-negative integer (a number, or its decimal string with no leading zero), got ${this.describeOperandShape(resolvedIndex, context)}. Use a literal, a Ref to a parameter or an Fn::FindInMap that yields one.`));
31702
+ }
31375
31703
  const resolvedList = await this.resolveValue(list, context);
31376
31704
  if (!Array.isArray(resolvedList)) throw new Error(`Fn::Select: list must be an array, got ${typeof resolvedList}`);
31377
- if (index < 0 || index >= resolvedList.length) {
31378
- this.logger.warn(`Fn::Select: index ${index} out of bounds (array length: ${resolvedList.length})`);
31379
- return `{{Fn::Select:${index}:OutOfBounds}}`;
31380
- }
31381
- const result = resolvedList[index];
31382
- this.logger.debug(`Resolved Fn::Select: index ${index} -> ${JSON.stringify(this.maskValueLeaves(result, context))}`);
31705
+ const loggedPosition = this.displayMasked(String(position), context);
31706
+ if (position >= resolvedList.length) {
31707
+ if (loggedPosition !== String(position)) throw markNonRetryable(new IntrinsicResolutionRefusalError(`Fn::Select: the index ${loggedPosition} is out of bounds (array length: ${resolvedList.length}), and it resolves from a secret value, so cdkd will not write it into the OutOfBounds placeholder.`));
31708
+ this.logger.warn(`Fn::Select: index ${position} out of bounds (array length: ${resolvedList.length})`);
31709
+ return `{{Fn::Select:${position}:OutOfBounds}}`;
31710
+ }
31711
+ const result = resolvedList[position];
31712
+ this.logger.debug(`Resolved Fn::Select: index ${loggedPosition} -> ${JSON.stringify(this.maskValueLeaves(result, context))}`);
31383
31713
  return result;
31384
31714
  }
31385
31715
  /**
@@ -31398,6 +31728,18 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
31398
31728
  return "<intrinsic>";
31399
31729
  }
31400
31730
  /**
31731
+ * Name a malformed operand's type, and its value when that is a scalar, for
31732
+ * a refusal message. The value is template text or a resolution product, so
31733
+ * it goes through the builder (issue #3479).
31734
+ */
31735
+ describeOperandShape(value, context) {
31736
+ if (value === null) return "null";
31737
+ if (Array.isArray(value)) return `an array of ${value.length}`;
31738
+ if (typeof value === "string") return `string "${this.displayMasked(value, context)}"`;
31739
+ if (typeof value === "number" || typeof value === "boolean") return `${typeof value} ${this.displayMasked(String(value), context)}`;
31740
+ return typeof value;
31741
+ }
31742
+ /**
31401
31743
  * Name the UNRESOLVED value argument of an `Fn::Split` for its refusal
31402
31744
  * message (issue [#1874](https://github.com/go-to-k/cdkd/issues/1874)).
31403
31745
  *
@@ -31415,7 +31757,8 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
31415
31757
  * naming the parameter.
31416
31758
  *
31417
31759
  * Anything else degrades to its bare intrinsic key, or to `undefined` for a
31418
- * literal (which the message then simply omits).
31760
+ * literal (which the message then simply omits). `resolveSelect` borrows the
31761
+ * label for its index refusal (issue #3574); only `kind` is Split-specific.
31419
31762
  *
31420
31763
  * `kind` is not decoration: the caller uses it to pick the remedy, since the
31421
31764
  * `Fn::GetAtt` remedy (drop the `Fn::Split`, and the #1868 note for the
@@ -31524,7 +31867,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
31524
31867
  }
31525
31868
  const result = resolvedValue.split(delimiter);
31526
31869
  const pieceTwins = this.splitLogTwins(resolvedValue, delimiter, result, context);
31527
- this.logger.debug(`Resolved Fn::Split: split by "${delimiter}" -> ${JSON.stringify(this.maskValueLeaves(pieceTwins, context))}`);
31870
+ this.logger.debug(`Resolved Fn::Split: split by "${this.displayMasked(String(delimiter), context)}" -> ${JSON.stringify(this.maskValueLeaves(pieceTwins, context))}`);
31528
31871
  return result;
31529
31872
  }
31530
31873
  /**
@@ -32121,7 +32464,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
32121
32464
  let roleArn;
32122
32465
  if ("RoleArn" in args && args["RoleArn"] !== void 0 && args["RoleArn"] !== null) {
32123
32466
  const raw = args["RoleArn"];
32124
- if (typeof raw !== "string" || raw === "") throw new Error(`Fn::GetStackOutput: RoleArn must be a literal string in the template (no Ref / Fn::GetAtt / Fn::Sub allowed for cross-account references). Got ${raw === null ? "null" : Array.isArray(raw) ? "array" : typeof raw}${typeof raw === "object" ? ` (intrinsic shape: ${JSON.stringify(raw).slice(0, 80)})` : ""}.`);
32467
+ if (typeof raw !== "string" || raw === "") throw new Error(`Fn::GetStackOutput: RoleArn must be a literal string in the template (no Ref / Fn::GetAtt / Fn::Sub allowed for cross-account references). Got ${raw === null ? "null" : Array.isArray(raw) ? "array" : typeof raw}${typeof raw === "object" ? ` (intrinsic shape: ${this.displayMasked(JSON.stringify(raw).slice(0, 80), context)})` : ""}.`);
32125
32468
  roleArn = raw;
32126
32469
  }
32127
32470
  if (!roleArn && context.stackName && context.stackName === stackName && canonicalizeRegion(region) === canonicalizeRegion(this.resolverRegion)) throw new Error(`Fn::GetStackOutput: cannot reference own stack '${this.displayMasked(stackName, context)}' in the same region '${this.displayMasked(loggedRegionText, context)}'`);
@@ -32265,7 +32608,15 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
32265
32608
  * {@link positionalNameMask} turns them into the transform and owns why.
32266
32609
  */
32267
32610
  maskStateReadError(error, pairs, context) {
32268
- const extraMask = this.positionalNameMask(pairs);
32611
+ throw this.maskNamedError(error, this.positionalNameMask(pairs), context);
32612
+ }
32613
+ /**
32614
+ * {@link maskStateReadError}'s body, RETURNING the masked clone rather than
32615
+ * throwing it, so {@link namedRequestMasks} can hand the same answer to an
32616
+ * SDK call site (go-to-k/cdkd#3171). `extraMask` is a
32617
+ * {@link positionalNameMask} transform, or `undefined` for none.
32618
+ */
32619
+ maskNamedError(error, extraMask, context) {
32269
32620
  let masked = error;
32270
32621
  let positional = extraMask;
32271
32622
  for (const bag of [context?.inheritedSecrets, context?.recordedSecretValues]) {
@@ -32274,7 +32625,57 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
32274
32625
  positional = void 0;
32275
32626
  }
32276
32627
  if (positional) masked = maskSecretsInError(masked, /* @__PURE__ */ new Map(), positional);
32277
- throw masked;
32628
+ return masked;
32629
+ }
32630
+ /**
32631
+ * The three masks an AWS SDK call site owes the text the SDK produces about a
32632
+ * request that carried template-derived NAMES (go-to-k/cdkd#3171).
32633
+ *
32634
+ * The resolver masks every name it prints ITSELF through the name's log text
32635
+ * (go-to-k/cdkd#3150), but an SDK rejection QUOTES the name it refused back —
32636
+ * `ParameterNotFound: <name>`, a region in a describe failure — and that
32637
+ * text reached only the needle mask, whose substring arm has the
32638
+ * {@link MIN_NEEDLE_LENGTH} floor. A name an `Fn::Sub` assembled around a
32639
+ * 1-3 character secret printed masked in the resolver's own words and in the
32640
+ * clear a few characters later, in the SDK's.
32641
+ *
32642
+ * `pairs` are (raw name as SENT, that name's log text), the same shape
32643
+ * {@link positionalNameMask} takes and for the same reason; an unmasked pair
32644
+ * is dropped there. ONE helper returning all three, so a call site cannot
32645
+ * adopt one and miss the others:
32646
+ *
32647
+ * - `error` — a masked CLONE of the whole cause chain
32648
+ * ({@link maskNamedError}), which keeps the class and every own descriptor,
32649
+ * so `isThrottlingError` / `isMarkedNonRetryable` still classify it;
32650
+ * - `text` — a caught message about to be interpolated into a line or a
32651
+ * throw, positional pass first, then {@link displayMasked};
32652
+ * - `retryLogger` — for `withRetry`, whose per-attempt `debug` line and
32653
+ * give-up `warn` interpolate the SDK message verbatim.
32654
+ *
32655
+ * THE WHOLE NAME is the key, never its secret span alone: the substitution
32656
+ * rewrites every occurrence of the raw name wherever the SDK put it (inside
32657
+ * an ARN, after a colon). That is what reaches a sub-floor secret — the
32658
+ * whole name is longer than the secret — and it is also the bound: a name
32659
+ * the SDK re-encodes or truncates before quoting it is not matched, and a
32660
+ * masked name of 1-3 characters is matched only where the SDK quotes it
32661
+ * exactly, which may over-mask unrelated text (the SAFE direction
32662
+ * {@link positionalNameMask} documents).
32663
+ */
32664
+ namedRequestMasks(pairs, context) {
32665
+ const positional = this.positionalNameMask(this.explicitRegion !== void 0 && this.explicitRegionLogText !== void 0 ? [...pairs, [this.explicitRegion, this.explicitRegionLogText]] : pairs);
32666
+ const text = (message) => this.displayMasked(positional ? positional(message) : message, context);
32667
+ const line = (message) => {
32668
+ const indent = /^ */.exec(message)?.[0] ?? "";
32669
+ return indent + text(message.slice(indent.length));
32670
+ };
32671
+ return {
32672
+ error: (error) => this.maskNamedError(error, positional, context),
32673
+ text,
32674
+ retryLogger: {
32675
+ debug: (message) => this.logger.debug(line(message)),
32676
+ warn: (message) => this.logger.warn(line(message))
32677
+ }
32678
+ };
32278
32679
  }
32279
32680
  /**
32280
32681
  * Read the producer's state from the SAME AWS account (no RoleArn).
@@ -32453,7 +32854,9 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
32453
32854
  Values: ["available"]
32454
32855
  }] }))).AvailabilityZones || []).map((az) => az.ZoneName).filter((name) => name !== void 0).sort();
32455
32856
  } catch (error) {
32456
- throw new Error(`Fn::GetAZs: failed to describe availability zones for region '${this.displayMasked(loggedRegionText ?? region, context)}': ${this.displayMasked(error instanceof Error ? error.message : String(error), context)}`);
32857
+ const loggedRegion = this.displayMasked(loggedRegionText ?? region, context);
32858
+ const masks = this.namedRequestMasks([[region, loggedRegion]], context);
32859
+ throw new Error(`Fn::GetAZs: failed to describe availability zones for region '${loggedRegion}': ${masks.text(error instanceof Error ? error.message : String(error))}`);
32457
32860
  }
32458
32861
  if (azNames.length === 0) throw new Error(`Fn::GetAZs: no availability zones returned for region '${this.displayMasked(loggedRegionText ?? region, context)}'. Either the region is not enabled on this account (opt-in regions must be enabled before use), or the request was answered by a different region's endpoint.`);
32459
32862
  cachedAvailabilityZones[region] = azNames;
@@ -32562,9 +32965,10 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
32562
32965
  * One constructor for both walks so neither can grow a second masking rule:
32563
32966
  * `subject` and `message` are the only fields a consumer may render, and each
32564
32967
  * carries its own route to a plaintext — an assembled reference puts one in
32565
- * the raw token (issue #2827), and an SDK rejection arrives RAW through
32566
- * `sendWithThrottleRetry` echoing the `Name` it was handed. `error` is kept
32567
- * unmasked on purpose and is documented as classification-only.
32968
+ * the raw token (issue #2827), and an SDK rejection echoes the `Name` it was
32969
+ * handed — which `sendWithThrottleRetry` now masks by position before it
32970
+ * rethrows (go-to-k/cdkd#3171), so this is the second layer on that route.
32971
+ * `error` is not re-masked here and is documented as classification-only.
32568
32972
  */
32569
32973
  abandonedUnit(unit, subject, error, context, rawInput, preRedact) {
32570
32974
  const raw = error instanceof Error ? error.message : String(error);
@@ -33320,7 +33724,11 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
33320
33724
  ...versionStage && versionStage !== "" && { VersionStage: versionStage },
33321
33725
  ...versionId && versionId !== "" && { VersionId: versionId }
33322
33726
  });
33323
- const secretString = (await this.sendWithThrottleRetry(() => client.send(command), `secretsmanager:${loggedSecretId}`)).SecretString;
33727
+ const secretString = (await this.sendWithThrottleRetry(() => client.send(command), `secretsmanager:${loggedSecretId}`, this.namedRequestMasks([
33728
+ [secretId, loggedSecretId],
33729
+ [versionStage, this.displayMasked(nameLogText(versionStage), context)],
33730
+ [versionId, this.displayMasked(nameLogText(versionId), context)]
33731
+ ], context))).SecretString;
33324
33732
  if (!secretString) throw new Error(`Dynamic reference: secret '${loggedSecretId}' does not contain a SecretString value`);
33325
33733
  if (jsonKey) try {
33326
33734
  const parsed = JSON.parse(secretString);
@@ -33355,7 +33763,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
33355
33763
  const count = Number(await this.resolveValue(rawCount, context));
33356
33764
  const cidrBits = Number(await this.resolveValue(rawCidrBits, context));
33357
33765
  if (!ipBlock || typeof ipBlock !== "string") throw new Error(`Fn::Cidr: ipBlock must be a string, got ${typeof ipBlock}: ${JSON.stringify(this.maskValueLeaves(ipBlock, context))}`);
33358
- this.logger.debug(`Resolving Fn::Cidr: ipBlock=${this.displayMasked(JSON.stringify(this.maskValueLeaves(ipBlock, context)), context)}, count=${count}, cidrBits=${cidrBits}`);
33766
+ this.logger.debug(`Resolving Fn::Cidr: ipBlock=${this.displayMasked(JSON.stringify(this.maskValueLeaves(ipBlock, context)), context)}, count=${this.displayMasked(String(count), context)}, cidrBits=${this.displayMasked(String(cidrBits), context)}`);
33359
33767
  const isIpv6 = ipBlock.includes(":");
33360
33768
  const results = [];
33361
33769
  if (isIpv6) {
@@ -33451,13 +33859,17 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
33451
33859
  * sibling in the SAME region still shares the ambient instance, so the
33452
33860
  * window survives exactly where the two stacks agree on the region.
33453
33861
  */
33454
- sendWithThrottleRetry(operation, label) {
33455
- return withRetry(operation, label, {
33456
- maxRetries: MAX_DYNAMIC_REFERENCE_THROTTLE_RETRIES,
33457
- isRetryable: (_message, error) => isThrottlingError(error),
33458
- logger: this.logger,
33459
- ...dynamicReferenceRetryDelays.sleep ? { sleep: dynamicReferenceRetryDelays.sleep } : {}
33460
- });
33862
+ async sendWithThrottleRetry(operation, label, masks) {
33863
+ try {
33864
+ return await withRetry(operation, label, {
33865
+ maxRetries: MAX_DYNAMIC_REFERENCE_THROTTLE_RETRIES,
33866
+ isRetryable: (_message, error) => isThrottlingError(error),
33867
+ logger: masks.retryLogger,
33868
+ ...dynamicReferenceRetryDelays.sleep ? { sleep: dynamicReferenceRetryDelays.sleep } : {}
33869
+ });
33870
+ } catch (error) {
33871
+ throw masks.error(error);
33872
+ }
33461
33873
  }
33462
33874
  /**
33463
33875
  * Resolve an `{{resolve:ssm:...}}` dynamic reference, reporting whether the
@@ -33484,14 +33896,14 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
33484
33896
  Name: parameterName,
33485
33897
  WithDecryption: decrypt
33486
33898
  });
33487
- const response = await this.sendWithThrottleRetry(() => client.send(command), `${service}:${loggedParameterName}`);
33899
+ const response = await this.sendWithThrottleRetry(() => client.send(command), `${service}:${loggedParameterName}`, this.namedRequestMasks([[parameterName, loggedParameterName]], context));
33488
33900
  const paramValue = response.Parameter?.Value;
33489
33901
  if (paramValue === void 0 || paramValue === null) throw new Error(`Dynamic reference: SSM parameter '${loggedParameterName}' not found or has no value`);
33490
33902
  const paramType = response.Parameter?.Type;
33491
33903
  const secure = paramType !== "String" && paramType !== "StringList";
33492
33904
  if (secure && paramType !== "SecureString" && !this.warnedUnrecognizedSsmTypes.has(injectiveKey(parameterName, String(paramType)))) {
33493
33905
  this.warnedUnrecognizedSsmTypes.add(injectiveKey(parameterName, String(paramType)));
33494
- const reported = paramType === void 0 ? "(absent)" : `'${String(paramType)}'`;
33906
+ const reported = paramType === void 0 ? "(absent)" : `'${this.displayMasked(String(paramType), context)}'`;
33495
33907
  this.logger.warn(`SSM parameter '${loggedParameterName}' reported an unrecognized Type ${reported} — treating its value as a secret, so cdkd will persist the {{resolve:${service}:...}} expression rather than the resolved value. Declare the parameter as String / StringList if it is public config.`);
33496
33908
  }
33497
33909
  return {
@@ -35175,7 +35587,7 @@ var CloudControlProvider = class {
35175
35587
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
35176
35588
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
35177
35589
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
35178
- const { ASGProvider } = await import("./asg-provider-CLqajoRp.js").then((n) => n.n);
35590
+ const { ASGProvider } = await import("./asg-provider-CZTUKQnY.js").then((n) => n.n);
35179
35591
  const asgProvider = new ASGProvider();
35180
35592
  return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
35181
35593
  }
@@ -38598,7 +39010,7 @@ const MUTUALLY_EXCLUSIVE_PROPERTIES = /* @__PURE__ */ new Map([["AWS::EC2::Route
38598
39010
  * different questions about the shape and should not drift into one another's
38599
39011
  * behavior by accident.
38600
39012
  */
38601
- function isUnresolvedIntrinsic(value) {
39013
+ function isUnresolvedIntrinsic$1(value) {
38602
39014
  if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
38603
39015
  const keys = Object.keys(value);
38604
39016
  return keys.length === 1 && (keys[0] === "Ref" || keys[0].startsWith("Fn::"));
@@ -38615,7 +39027,7 @@ function isUnresolvedIntrinsic(value) {
38615
39027
  * NOT yet known, so it is excluded ahead of the truthiness test.
38616
39028
  */
38617
39029
  function isDeclared(value) {
38618
- if (isUnresolvedIntrinsic(value)) return false;
39030
+ if (isUnresolvedIntrinsic$1(value)) return false;
38619
39031
  return Boolean(value);
38620
39032
  }
38621
39033
  /**
@@ -38643,7 +39055,7 @@ function findViolationsForRules(resourceType, rules, templateProperties) {
38643
39055
  for (const rule of rules) {
38644
39056
  const declared = rule.properties.filter((property) => isDeclared(templateProperties[property]));
38645
39057
  if (declared.length <= 1) continue;
38646
- const winnerCertain = !rule.properties.slice(0, rule.properties.indexOf(declared[0])).some((property) => isUnresolvedIntrinsic(templateProperties[property]));
39058
+ const winnerCertain = !rule.properties.slice(0, rule.properties.indexOf(declared[0])).some((property) => isUnresolvedIntrinsic$1(templateProperties[property]));
38647
39059
  violations.push({
38648
39060
  resourceType,
38649
39061
  rule,
@@ -38677,6 +39089,1526 @@ function buildMutuallyExclusiveMessage(logicalId, violation) {
38677
39089
  return ` - ${logicalId} (${resourceType}) declares ${declared.join(" and ")}\n ${rule.rationale}${winnerNote}\n Declare at most one of: ${rule.properties.join(" / ")}`;
38678
39090
  }
38679
39091
 
39092
+ //#endregion
39093
+ //#region src/provisioning/nested-required.generated.ts
39094
+ /**
39095
+ * AUTO-GENERATED by scripts/gen-nested-required.ts — DO NOT EDIT BY HAND.
39096
+ * Source: the `nestedRequired` section of tests/fixtures/cfn-schemas/*.json.
39097
+ * Regenerate: `vp run gen:nested-required`.
39098
+ *
39099
+ * Per resource type, each nested property PATH (dotted, arrays transparent)
39100
+ * mapped to the members its schema definition lists as `required`. What the
39101
+ * SCHEMA says, not what CloudFormation enforces: the pre-flight refusal in
39102
+ * `nested-required.ts` reads it only for types measured to be enforced.
39103
+ */
39104
+ const NESTED_REQUIRED = /* @__PURE__ */ new Map([
39105
+ ["AWS::ApiGateway::Deployment", /* @__PURE__ */ new Map([["StageDescription.Tags", ["Key", "Value"]]])],
39106
+ ["AWS::ApiGateway::Method", /* @__PURE__ */ new Map([
39107
+ ["Integration", ["Type"]],
39108
+ ["Integration.IntegrationResponses", ["StatusCode"]],
39109
+ ["MethodResponses", ["StatusCode"]]
39110
+ ])],
39111
+ ["AWS::ApiGateway::Stage", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39112
+ ["AWS::ApiGatewayV2::Route", /* @__PURE__ */ new Map([["RequestParameters", ["Required"]]])],
39113
+ ["AWS::AppSync::DataSource", /* @__PURE__ */ new Map([
39114
+ ["DynamoDBConfig", ["AwsRegion", "TableName"]],
39115
+ ["DynamoDBConfig.DeltaSyncConfig", [
39116
+ "BaseTableTTL",
39117
+ "DeltaSyncTableName",
39118
+ "DeltaSyncTableTTL"
39119
+ ]],
39120
+ ["ElasticsearchConfig", ["AwsRegion", "Endpoint"]],
39121
+ ["EventBridgeConfig", ["EventBusArn"]],
39122
+ ["HttpConfig", ["Endpoint"]],
39123
+ ["HttpConfig.AuthorizationConfig", ["AuthorizationType"]],
39124
+ ["LambdaConfig", ["LambdaFunctionArn"]],
39125
+ ["OpenSearchServiceConfig", ["AwsRegion", "Endpoint"]],
39126
+ ["RelationalDatabaseConfig", ["RelationalDatabaseSourceType"]],
39127
+ ["RelationalDatabaseConfig.RdsHttpEndpointConfig", [
39128
+ "AwsRegion",
39129
+ "AwsSecretStoreArn",
39130
+ "DbClusterIdentifier"
39131
+ ]]
39132
+ ])],
39133
+ ["AWS::AppSync::GraphQLApi", /* @__PURE__ */ new Map([
39134
+ ["AdditionalAuthenticationProviders", ["AuthenticationType"]],
39135
+ ["EnhancedMetricsConfig", [
39136
+ "DataSourceLevelMetricsBehavior",
39137
+ "OperationLevelMetricsConfig",
39138
+ "ResolverLevelMetricsBehavior"
39139
+ ]],
39140
+ ["LogConfig", ["CloudWatchLogsRoleArn", "FieldLogLevel"]],
39141
+ ["Tags", ["Key", "Value"]]
39142
+ ])],
39143
+ ["AWS::AppSync::Resolver", /* @__PURE__ */ new Map([
39144
+ ["CachingConfig", ["Ttl"]],
39145
+ ["Runtime", ["Name", "RuntimeVersion"]],
39146
+ ["SyncConfig", ["ConflictDetection"]]
39147
+ ])],
39148
+ ["AWS::AutoScaling::AutoScalingGroup", /* @__PURE__ */ new Map([
39149
+ ["AvailabilityZoneImpairmentPolicy", ["ImpairedZoneHealthCheckBehavior", "ZonalShiftEnabled"]],
39150
+ ["CapacityReservationSpecification", ["CapacityReservationPreference"]],
39151
+ ["LaunchTemplate", ["Version"]],
39152
+ ["LifecycleHookSpecificationList", ["LifecycleHookName", "LifecycleTransition"]],
39153
+ ["MetricsCollection", ["Granularity"]],
39154
+ ["MixedInstancesPolicy", ["LaunchTemplate"]],
39155
+ ["MixedInstancesPolicy.InstancesDistribution.DistributionSegments", ["TargetCapacityTypes"]],
39156
+ ["MixedInstancesPolicy.LaunchTemplate", ["LaunchTemplateSpecification"]],
39157
+ ["MixedInstancesPolicy.LaunchTemplate.LaunchTemplateSpecification", ["Version"]],
39158
+ ["MixedInstancesPolicy.LaunchTemplate.Overrides.InstanceRequirements", ["MemoryMiB", "VCpuCount"]],
39159
+ ["MixedInstancesPolicy.LaunchTemplate.Overrides.LaunchTemplateSpecification", ["Version"]],
39160
+ ["NotificationConfiguration", ["TopicARN"]],
39161
+ ["NotificationConfigurations", ["TopicARN"]],
39162
+ ["Tags", [
39163
+ "Key",
39164
+ "PropagateAtLaunch",
39165
+ "Value"
39166
+ ]],
39167
+ ["TrafficSources", ["Identifier", "Type"]]
39168
+ ])],
39169
+ ["AWS::BedrockAgentCore::Evaluator", /* @__PURE__ */ new Map([
39170
+ ["EvaluatorConfig.CodeBased", ["LambdaConfig"]],
39171
+ ["EvaluatorConfig.CodeBased.LambdaConfig", ["LambdaArn"]],
39172
+ ["EvaluatorConfig.LlmAsAJudge", [
39173
+ "Instructions",
39174
+ "ModelConfig",
39175
+ "RatingScale"
39176
+ ]],
39177
+ ["EvaluatorConfig.LlmAsAJudge.ModelConfig.BedrockEvaluatorModelConfig", ["ModelId"]],
39178
+ ["EvaluatorConfig.LlmAsAJudge.ModelConfig.ResponsesEvaluatorModelConfig", ["ModelId"]],
39179
+ ["EvaluatorConfig.LlmAsAJudge.RatingScale.Categorical", ["Definition", "Label"]],
39180
+ ["EvaluatorConfig.LlmAsAJudge.RatingScale.Numerical", [
39181
+ "Definition",
39182
+ "Label",
39183
+ "Value"
39184
+ ]],
39185
+ ["Tags", ["Key", "Value"]]
39186
+ ])],
39187
+ ["AWS::BedrockAgentCore::Runtime", /* @__PURE__ */ new Map([
39188
+ ["AgentRuntimeArtifact.CodeConfiguration", [
39189
+ "Code",
39190
+ "EntryPoint",
39191
+ "Runtime"
39192
+ ]],
39193
+ ["AgentRuntimeArtifact.CodeConfiguration.Code.S3", ["Bucket", "Prefix"]],
39194
+ ["AgentRuntimeArtifact.ContainerConfiguration", ["ContainerUri"]],
39195
+ ["AuthorizerConfiguration.CustomJWTAuthorizer", ["DiscoveryUrl"]],
39196
+ ["AuthorizerConfiguration.CustomJWTAuthorizer.AllowedWorkloadConfiguration.HostingEnvironments", ["Arn"]],
39197
+ ["AuthorizerConfiguration.CustomJWTAuthorizer.CustomClaims", [
39198
+ "AuthorizingClaimMatchValue",
39199
+ "InboundTokenClaimName",
39200
+ "InboundTokenClaimValueType"
39201
+ ]],
39202
+ ["AuthorizerConfiguration.CustomJWTAuthorizer.CustomClaims.AuthorizingClaimMatchValue", ["ClaimMatchOperator", "ClaimMatchValue"]],
39203
+ ["AuthorizerConfiguration.CustomJWTAuthorizer.PrivateEndpointOverrides", ["Domain", "PrivateEndpoint"]],
39204
+ ["CapacityProviderConfiguration", ["CapacityProviderArn"]],
39205
+ ["FilesystemConfigurations.CapacityProviderVolume", ["MountPath", "VolumeName"]],
39206
+ ["FilesystemConfigurations.EfsAccessPoint", ["AccessPointArn", "MountPath"]],
39207
+ ["FilesystemConfigurations.S3FilesAccessPoint", ["AccessPointArn", "MountPath"]],
39208
+ ["FilesystemConfigurations.SessionStorage", ["MountPath"]],
39209
+ ["NetworkConfiguration", ["NetworkMode"]],
39210
+ ["NetworkConfiguration.NetworkModeConfig", ["SecurityGroups", "Subnets"]],
39211
+ ["WorkloadIdentityDetails", ["WorkloadIdentityArn"]]
39212
+ ])],
39213
+ ["AWS::Budgets::Budget", /* @__PURE__ */ new Map([
39214
+ ["Budget", ["BudgetType", "TimeUnit"]],
39215
+ ["Budget.AutoAdjustData", ["AutoAdjustType"]],
39216
+ ["Budget.AutoAdjustData.HistoricalOptions", ["BudgetAdjustmentPeriod"]],
39217
+ ["Budget.BudgetLimit", ["Amount", "Unit"]],
39218
+ ["NotificationsWithSubscribers", ["Notification", "Subscribers"]],
39219
+ ["NotificationsWithSubscribers.Notification", [
39220
+ "ComparisonOperator",
39221
+ "NotificationType",
39222
+ "Threshold"
39223
+ ]],
39224
+ ["NotificationsWithSubscribers.Subscribers", ["Address", "SubscriptionType"]],
39225
+ ["ResourceTags", ["Key"]]
39226
+ ])],
39227
+ ["AWS::CertificateManager::Certificate", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39228
+ ["AWS::CloudFormation::Stack", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39229
+ ["AWS::CloudFront::CloudFrontOriginAccessIdentity", /* @__PURE__ */ new Map([["CloudFrontOriginAccessIdentityConfig", ["Comment"]]])],
39230
+ ["AWS::CloudFront::Distribution", /* @__PURE__ */ new Map([
39231
+ ["DistributionConfig", ["DefaultCacheBehavior", "Enabled"]],
39232
+ ["DistributionConfig.CacheBehaviors", [
39233
+ "PathPattern",
39234
+ "TargetOriginId",
39235
+ "ViewerProtocolPolicy"
39236
+ ]],
39237
+ ["DistributionConfig.CacheBehaviors.ForwardedValues", ["QueryString"]],
39238
+ ["DistributionConfig.CacheBehaviors.ForwardedValues.Cookies", ["Forward"]],
39239
+ ["DistributionConfig.CacheBehaviors.GrpcConfig", ["Enabled"]],
39240
+ ["DistributionConfig.CacheTagConfig", ["HeaderName"]],
39241
+ ["DistributionConfig.ConnectionFunctionAssociation", ["Id"]],
39242
+ ["DistributionConfig.CustomErrorResponses", ["ErrorCode"]],
39243
+ ["DistributionConfig.CustomOrigin", [
39244
+ "DNSName",
39245
+ "OriginProtocolPolicy",
39246
+ "OriginSSLProtocols"
39247
+ ]],
39248
+ ["DistributionConfig.DefaultCacheBehavior", ["TargetOriginId", "ViewerProtocolPolicy"]],
39249
+ ["DistributionConfig.DefaultCacheBehavior.ForwardedValues", ["QueryString"]],
39250
+ ["DistributionConfig.DefaultCacheBehavior.ForwardedValues.Cookies", ["Forward"]],
39251
+ ["DistributionConfig.DefaultCacheBehavior.GrpcConfig", ["Enabled"]],
39252
+ ["DistributionConfig.OriginGroups", ["Quantity"]],
39253
+ ["DistributionConfig.OriginGroups.Items", [
39254
+ "FailoverCriteria",
39255
+ "Id",
39256
+ "Members"
39257
+ ]],
39258
+ ["DistributionConfig.OriginGroups.Items.FailoverCriteria", ["StatusCodes"]],
39259
+ ["DistributionConfig.OriginGroups.Items.FailoverCriteria.StatusCodes", ["Items", "Quantity"]],
39260
+ ["DistributionConfig.OriginGroups.Items.Members", ["Items", "Quantity"]],
39261
+ ["DistributionConfig.OriginGroups.Items.Members.Items", ["OriginId"]],
39262
+ ["DistributionConfig.Origins", ["DomainName", "Id"]],
39263
+ ["DistributionConfig.Origins.CustomOriginConfig", ["OriginProtocolPolicy"]],
39264
+ ["DistributionConfig.Origins.CustomOriginConfig.OriginMtlsConfig", ["ClientCertificateArn"]],
39265
+ ["DistributionConfig.Origins.OriginCustomHeaders", ["HeaderName", "HeaderValue"]],
39266
+ ["DistributionConfig.Origins.VpcOriginConfig", ["VpcOriginId"]],
39267
+ ["DistributionConfig.Restrictions", ["GeoRestriction"]],
39268
+ ["DistributionConfig.Restrictions.GeoRestriction", ["RestrictionType"]],
39269
+ ["DistributionConfig.S3Origin", ["DNSName"]],
39270
+ ["DistributionConfig.TenantConfig.ParameterDefinitions", ["Definition", "Name"]],
39271
+ ["DistributionConfig.TenantConfig.ParameterDefinitions.Definition.StringSchema", ["Required"]],
39272
+ ["DistributionConfig.ViewerMtlsConfig.TrustStoreConfig", ["TrustStoreId"]],
39273
+ ["Tags", ["Key", "Value"]]
39274
+ ])],
39275
+ ["AWS::CloudFront::OriginAccessControl", /* @__PURE__ */ new Map([["OriginAccessControlConfig", [
39276
+ "Name",
39277
+ "OriginAccessControlOriginType",
39278
+ "SigningBehavior",
39279
+ "SigningProtocol"
39280
+ ]]])],
39281
+ ["AWS::CloudTrail::Trail", /* @__PURE__ */ new Map([
39282
+ ["AdvancedEventSelectors", ["FieldSelectors"]],
39283
+ ["AdvancedEventSelectors.FieldSelectors", ["Field"]],
39284
+ ["AggregationConfigurations", ["EventCategory", "Templates"]],
39285
+ ["EventSelectors.DataResources", ["Type"]],
39286
+ ["Tags", ["Key", "Value"]]
39287
+ ])],
39288
+ ["AWS::CloudWatch::Alarm", /* @__PURE__ */ new Map([
39289
+ ["Dimensions", ["Name", "Value"]],
39290
+ ["Metrics", ["Id"]],
39291
+ ["Metrics.MetricStat", [
39292
+ "Metric",
39293
+ "Period",
39294
+ "Stat"
39295
+ ]],
39296
+ ["Metrics.MetricStat.Metric.Dimensions", ["Name", "Value"]],
39297
+ ["Tags", ["Key", "Value"]]
39298
+ ])],
39299
+ ["AWS::CloudWatch::AnomalyDetector", /* @__PURE__ */ new Map([
39300
+ ["Configuration.ExcludedTimeRanges", ["EndTime", "StartTime"]],
39301
+ ["Dimensions", ["Name", "Value"]],
39302
+ ["MetricMathAnomalyDetector.MetricDataQueries", ["Id"]],
39303
+ ["MetricMathAnomalyDetector.MetricDataQueries.MetricStat", [
39304
+ "Metric",
39305
+ "Period",
39306
+ "Stat"
39307
+ ]],
39308
+ ["MetricMathAnomalyDetector.MetricDataQueries.MetricStat.Metric", ["MetricName", "Namespace"]],
39309
+ ["MetricMathAnomalyDetector.MetricDataQueries.MetricStat.Metric.Dimensions", ["Name", "Value"]],
39310
+ ["SingleMetricAnomalyDetector.Dimensions", ["Name", "Value"]]
39311
+ ])],
39312
+ ["AWS::CodeBuild::Project", /* @__PURE__ */ new Map([
39313
+ ["Artifacts", ["Type"]],
39314
+ ["Cache", ["Type"]],
39315
+ ["Environment", [
39316
+ "ComputeType",
39317
+ "Image",
39318
+ "Type"
39319
+ ]],
39320
+ ["Environment.DockerServer", ["ComputeType"]],
39321
+ ["Environment.EnvironmentVariables", ["Name", "Value"]],
39322
+ ["Environment.RegistryCredential", ["Credential", "CredentialProvider"]],
39323
+ ["FileSystemLocations", [
39324
+ "Identifier",
39325
+ "Location",
39326
+ "MountPoint",
39327
+ "Type"
39328
+ ]],
39329
+ ["LogsConfig.CloudWatchLogs", ["Status"]],
39330
+ ["LogsConfig.S3Logs", ["Status"]],
39331
+ ["SecondaryArtifacts", ["Type"]],
39332
+ ["SecondarySourceVersions", ["SourceIdentifier"]],
39333
+ ["SecondarySources", ["Type"]],
39334
+ ["SecondarySources.Auth", ["Type"]],
39335
+ ["SecondarySources.GitSubmodulesConfig", ["FetchSubmodules"]],
39336
+ ["Source", ["Type"]],
39337
+ ["Source.Auth", ["Type"]],
39338
+ ["Source.GitSubmodulesConfig", ["FetchSubmodules"]],
39339
+ ["Tags", ["Key", "Value"]],
39340
+ ["Triggers.PullRequestBuildPolicy", ["RequiresCommentApproval"]],
39341
+ ["Triggers.ScopeConfiguration", ["Name"]]
39342
+ ])],
39343
+ ["AWS::CodeCommit::Repository", /* @__PURE__ */ new Map([
39344
+ ["Code", ["S3"]],
39345
+ ["Code.S3", ["Bucket", "Key"]],
39346
+ ["Tags", ["Key", "Value"]],
39347
+ ["Triggers", [
39348
+ "DestinationArn",
39349
+ "Events",
39350
+ "Name"
39351
+ ]]
39352
+ ])],
39353
+ ["AWS::Cognito::UserPool", /* @__PURE__ */ new Map([["SmsConfiguration.EumsSms", ["CallerArn"]], ["UserAttributeUpdateSettings", ["AttributesRequireVerificationBeforeUpdate"]]])],
39354
+ ["AWS::DLM::LifecyclePolicy", /* @__PURE__ */ new Map([
39355
+ ["Exclusions.ExcludeTags", ["Key", "Value"]],
39356
+ ["PolicyDetails.Actions", ["CrossRegionCopy", "Name"]],
39357
+ ["PolicyDetails.Actions.CrossRegionCopy", ["EncryptionConfiguration", "Target"]],
39358
+ ["PolicyDetails.Actions.CrossRegionCopy.EncryptionConfiguration", ["Encrypted"]],
39359
+ ["PolicyDetails.Actions.CrossRegionCopy.RetainRule", ["Interval", "IntervalUnit"]],
39360
+ ["PolicyDetails.EventSource", ["Type"]],
39361
+ ["PolicyDetails.EventSource.Parameters", ["EventType", "SnapshotOwner"]],
39362
+ ["PolicyDetails.Exclusions.ExcludeTags", ["Key", "Value"]],
39363
+ ["PolicyDetails.Parameters.ExcludeDataVolumeTags", ["Key", "Value"]],
39364
+ ["PolicyDetails.Schedules.ArchiveRule", ["RetainRule"]],
39365
+ ["PolicyDetails.Schedules.ArchiveRule.RetainRule", ["RetentionArchiveTier"]],
39366
+ ["PolicyDetails.Schedules.CrossRegionCopyRules", ["Encrypted"]],
39367
+ ["PolicyDetails.Schedules.CrossRegionCopyRules.DeprecateRule", ["Interval", "IntervalUnit"]],
39368
+ ["PolicyDetails.Schedules.CrossRegionCopyRules.RetainRule", ["Interval", "IntervalUnit"]],
39369
+ ["PolicyDetails.Schedules.TagsToAdd", ["Key", "Value"]],
39370
+ ["PolicyDetails.Schedules.VariableTags", ["Key", "Value"]],
39371
+ ["PolicyDetails.TargetTags", ["Key", "Value"]],
39372
+ ["Tags", ["Key", "Value"]]
39373
+ ])],
39374
+ ["AWS::DocDB::DBCluster", /* @__PURE__ */ new Map([["ServerlessV2ScalingConfiguration", ["MaxCapacity", "MinCapacity"]], ["Tags", ["Key", "Value"]]])],
39375
+ ["AWS::DocDB::DBInstance", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39376
+ ["AWS::DocDB::DBSubnetGroup", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39377
+ ["AWS::DynamoDB::GlobalTable", /* @__PURE__ */ new Map([
39378
+ ["AttributeDefinitions", ["AttributeName", "AttributeType"]],
39379
+ ["GlobalSecondaryIndexes", [
39380
+ "IndexName",
39381
+ "KeySchema",
39382
+ "Projection"
39383
+ ]],
39384
+ ["GlobalSecondaryIndexes.KeySchema", ["AttributeName", "KeyType"]],
39385
+ ["GlobalSecondaryIndexes.WriteProvisionedThroughputSettings.WriteCapacityAutoScalingSettings", [
39386
+ "MaxCapacity",
39387
+ "MinCapacity",
39388
+ "TargetTrackingScalingPolicyConfiguration"
39389
+ ]],
39390
+ ["GlobalSecondaryIndexes.WriteProvisionedThroughputSettings.WriteCapacityAutoScalingSettings.TargetTrackingScalingPolicyConfiguration", ["TargetValue"]],
39391
+ ["KeySchema", ["AttributeName", "KeyType"]],
39392
+ ["LocalSecondaryIndexes", [
39393
+ "IndexName",
39394
+ "KeySchema",
39395
+ "Projection"
39396
+ ]],
39397
+ ["LocalSecondaryIndexes.KeySchema", ["AttributeName", "KeyType"]],
39398
+ ["Replicas", ["Region"]],
39399
+ ["Replicas.ContributorInsightsSpecification", ["Enabled"]],
39400
+ ["Replicas.GlobalSecondaryIndexes", ["IndexName"]],
39401
+ ["Replicas.GlobalSecondaryIndexes.ContributorInsightsSpecification", ["Enabled"]],
39402
+ ["Replicas.GlobalSecondaryIndexes.ReadProvisionedThroughputSettings.ReadCapacityAutoScalingSettings", [
39403
+ "MaxCapacity",
39404
+ "MinCapacity",
39405
+ "TargetTrackingScalingPolicyConfiguration"
39406
+ ]],
39407
+ ["Replicas.GlobalSecondaryIndexes.ReadProvisionedThroughputSettings.ReadCapacityAutoScalingSettings.TargetTrackingScalingPolicyConfiguration", ["TargetValue"]],
39408
+ ["Replicas.KinesisStreamSpecification", ["StreamArn"]],
39409
+ ["Replicas.ReadProvisionedThroughputSettings.ReadCapacityAutoScalingSettings", [
39410
+ "MaxCapacity",
39411
+ "MinCapacity",
39412
+ "TargetTrackingScalingPolicyConfiguration"
39413
+ ]],
39414
+ ["Replicas.ReadProvisionedThroughputSettings.ReadCapacityAutoScalingSettings.TargetTrackingScalingPolicyConfiguration", ["TargetValue"]],
39415
+ ["Replicas.ReplicaStreamSpecification.ResourcePolicy", ["PolicyDocument"]],
39416
+ ["Replicas.ReplicaStreamSpecification.Tags", ["Key", "Value"]],
39417
+ ["Replicas.ResourcePolicy", ["PolicyDocument"]],
39418
+ ["Replicas.SSESpecification", ["KMSMasterKeyId"]],
39419
+ ["Replicas.Tags", ["Key", "Value"]],
39420
+ ["SSESpecification", ["SSEEnabled"]],
39421
+ ["StreamSpecification", ["StreamViewType"]],
39422
+ ["TimeToLiveSpecification", ["Enabled"]],
39423
+ ["VectorIndexes", [
39424
+ "Dimensions",
39425
+ "DistanceFunction",
39426
+ "IndexName",
39427
+ "Projection",
39428
+ "VectorAttribute"
39429
+ ]],
39430
+ ["VectorIndexes.SearchSchema", ["AttributeName", "SearchSchemaElementType"]],
39431
+ ["VectorIndexes.VectorAttribute", ["AttributeName"]],
39432
+ ["WriteProvisionedThroughputSettings.WriteCapacityAutoScalingSettings", [
39433
+ "MaxCapacity",
39434
+ "MinCapacity",
39435
+ "TargetTrackingScalingPolicyConfiguration"
39436
+ ]],
39437
+ ["WriteProvisionedThroughputSettings.WriteCapacityAutoScalingSettings.TargetTrackingScalingPolicyConfiguration", ["TargetValue"]]
39438
+ ])],
39439
+ ["AWS::DynamoDB::Table", /* @__PURE__ */ new Map([
39440
+ ["AttributeDefinitions", ["AttributeName", "AttributeType"]],
39441
+ ["ContributorInsightsSpecification", ["Enabled"]],
39442
+ ["GlobalSecondaryIndexes", [
39443
+ "IndexName",
39444
+ "KeySchema",
39445
+ "Projection"
39446
+ ]],
39447
+ ["GlobalSecondaryIndexes.ContributorInsightsSpecification", ["Enabled"]],
39448
+ ["GlobalSecondaryIndexes.KeySchema", ["AttributeName", "KeyType"]],
39449
+ ["GlobalSecondaryIndexes.ProvisionedThroughput", ["ReadCapacityUnits", "WriteCapacityUnits"]],
39450
+ ["ImportSourceSpecification", ["InputFormat", "S3BucketSource"]],
39451
+ ["ImportSourceSpecification.S3BucketSource", ["S3Bucket"]],
39452
+ ["KinesisStreamSpecification", ["StreamArn"]],
39453
+ ["LocalSecondaryIndexes", [
39454
+ "IndexName",
39455
+ "KeySchema",
39456
+ "Projection"
39457
+ ]],
39458
+ ["LocalSecondaryIndexes.KeySchema", ["AttributeName", "KeyType"]],
39459
+ ["ProvisionedThroughput", ["ReadCapacityUnits", "WriteCapacityUnits"]],
39460
+ ["ResourcePolicy", ["PolicyDocument"]],
39461
+ ["SSESpecification", ["SSEEnabled"]],
39462
+ ["StreamSpecification", ["StreamViewType"]],
39463
+ ["StreamSpecification.ResourcePolicy", ["PolicyDocument"]],
39464
+ ["StreamSpecification.Tags", ["Key", "Value"]],
39465
+ ["Tags", ["Key", "Value"]],
39466
+ ["TimeToLiveSpecification", ["Enabled"]],
39467
+ ["VectorIndexes", [
39468
+ "Dimensions",
39469
+ "DistanceFunction",
39470
+ "IndexName",
39471
+ "Projection",
39472
+ "VectorAttribute"
39473
+ ]],
39474
+ ["VectorIndexes.SearchSchema", ["AttributeName", "SearchSchemaElementType"]],
39475
+ ["VectorIndexes.VectorAttribute", ["AttributeName"]]
39476
+ ])],
39477
+ ["AWS::EC2::EIP", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39478
+ ["AWS::EC2::Instance", /* @__PURE__ */ new Map([
39479
+ ["BlockDeviceMappings", ["DeviceName"]],
39480
+ ["ElasticGpuSpecifications", ["Type"]],
39481
+ ["ElasticInferenceAccelerators", ["Type"]],
39482
+ ["Ipv6Addresses", ["Ipv6Address"]],
39483
+ ["LicenseSpecifications", ["LicenseConfigurationArn"]],
39484
+ ["NetworkInterfaces", ["DeviceIndex"]],
39485
+ ["NetworkInterfaces.Ipv6Addresses", ["Ipv6Address"]],
39486
+ ["NetworkInterfaces.PrivateIpAddresses", ["Primary", "PrivateIpAddress"]],
39487
+ ["SsmAssociations", ["DocumentName"]],
39488
+ ["SsmAssociations.AssociationParameters", ["Key", "Value"]],
39489
+ ["Tags", ["Key", "Value"]],
39490
+ ["Volumes", ["Device", "VolumeId"]]
39491
+ ])],
39492
+ ["AWS::EC2::InternetGateway", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39493
+ ["AWS::EC2::NatGateway", /* @__PURE__ */ new Map([["AvailabilityZoneAddresses", ["AllocationIds"]], ["Tags", ["Key", "Value"]]])],
39494
+ ["AWS::EC2::NetworkAcl", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39495
+ ["AWS::EC2::RouteTable", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39496
+ ["AWS::EC2::SecurityGroup", /* @__PURE__ */ new Map([
39497
+ ["SecurityGroupEgress", ["IpProtocol"]],
39498
+ ["SecurityGroupIngress", ["IpProtocol"]],
39499
+ ["Tags", ["Key", "Value"]]
39500
+ ])],
39501
+ ["AWS::EC2::Subnet", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39502
+ ["AWS::EC2::VPC", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39503
+ ["AWS::ECR::Repository", /* @__PURE__ */ new Map([
39504
+ ["EncryptionConfiguration", ["EncryptionType"]],
39505
+ ["ImageTagMutabilityExclusionFilters", ["ImageTagMutabilityExclusionFilterType", "ImageTagMutabilityExclusionFilterValue"]],
39506
+ ["Tags", ["Key", "Value"]]
39507
+ ])],
39508
+ ["AWS::ECS::Service", /* @__PURE__ */ new Map([
39509
+ ["DeploymentConfiguration.Alarms", [
39510
+ "AlarmNames",
39511
+ "Enable",
39512
+ "Rollback"
39513
+ ]],
39514
+ ["DeploymentConfiguration.DeploymentCircuitBreaker", ["Enable", "Rollback"]],
39515
+ ["DeploymentConfiguration.DeploymentCircuitBreaker.ThresholdConfiguration", ["Type", "Value"]],
39516
+ ["DeploymentConfiguration.LifecycleHooks", ["LifecycleStages"]],
39517
+ ["ForceNewDeployment", ["EnableForceNewDeployment"]],
39518
+ ["LoadBalancers.AdvancedConfiguration", ["AlternateTargetGroupArn"]],
39519
+ ["Monitoring", ["MetricConfigurations"]],
39520
+ ["Monitoring.MetricConfigurations", ["MetricNames", "ResolutionSeconds"]],
39521
+ ["PlacementConstraints", ["Type"]],
39522
+ ["PlacementStrategies", ["Type"]],
39523
+ ["ServiceConnectConfiguration", ["Enabled"]],
39524
+ ["ServiceConnectConfiguration.AccessLogConfiguration", ["Format"]],
39525
+ ["ServiceConnectConfiguration.LogConfiguration.SecretOptions", ["Name", "ValueFrom"]],
39526
+ ["ServiceConnectConfiguration.Services", ["PortName"]],
39527
+ ["ServiceConnectConfiguration.Services.ClientAliases", ["Port"]],
39528
+ ["ServiceConnectConfiguration.Services.ClientAliases.TestTrafficRules", ["Header"]],
39529
+ ["ServiceConnectConfiguration.Services.ClientAliases.TestTrafficRules.Header", ["Name"]],
39530
+ ["ServiceConnectConfiguration.Services.ClientAliases.TestTrafficRules.Header.Value", ["Exact"]],
39531
+ ["ServiceConnectConfiguration.Services.Tls", ["IssuerCertificateAuthority"]],
39532
+ ["VolumeConfigurations", ["Name"]],
39533
+ ["VolumeConfigurations.ManagedEBSVolume", ["RoleArn"]],
39534
+ ["VolumeConfigurations.ManagedEBSVolume.TagSpecifications", ["ResourceType"]],
39535
+ ["VpcLatticeConfigurations", [
39536
+ "PortName",
39537
+ "RoleArn",
39538
+ "TargetGroupArn"
39539
+ ]]
39540
+ ])],
39541
+ ["AWS::ECS::TaskDefinition", /* @__PURE__ */ new Map([
39542
+ ["ContainerDefinitions", ["Image", "Name"]],
39543
+ ["ContainerDefinitions.LinuxParameters.Tmpfs", ["Size"]],
39544
+ ["ContainerDefinitions.LogConfiguration", ["LogDriver"]],
39545
+ ["ContainerDefinitions.LogConfiguration.SecretOptions", ["Name", "ValueFrom"]],
39546
+ ["ContainerDefinitions.ResourceRequirements", ["Type", "Value"]],
39547
+ ["ContainerDefinitions.Secrets", ["Name", "ValueFrom"]],
39548
+ ["ContainerDefinitions.Ulimits", [
39549
+ "HardLimit",
39550
+ "Name",
39551
+ "SoftLimit"
39552
+ ]],
39553
+ ["PlacementConstraints", ["Type"]],
39554
+ ["ProxyConfiguration", ["ContainerName"]],
39555
+ ["Volumes.EFSVolumeConfiguration", ["FilesystemId"]],
39556
+ ["Volumes.FSxWindowsFileServerVolumeConfiguration", ["FileSystemId", "RootDirectory"]],
39557
+ ["Volumes.FSxWindowsFileServerVolumeConfiguration.AuthorizationConfig", ["CredentialsParameter", "Domain"]],
39558
+ ["Volumes.S3FilesVolumeConfiguration", ["FileSystemArn"]]
39559
+ ])],
39560
+ ["AWS::EFS::AccessPoint", /* @__PURE__ */ new Map([["PosixUser", ["Gid", "Uid"]], ["RootDirectory.CreationInfo", [
39561
+ "OwnerGid",
39562
+ "OwnerUid",
39563
+ "Permissions"
39564
+ ]]])],
39565
+ ["AWS::EFS::FileSystem", /* @__PURE__ */ new Map([["BackupPolicy", ["Status"]], ["FileSystemTags", ["Key", "Value"]]])],
39566
+ ["AWS::ElastiCache::CacheCluster", /* @__PURE__ */ new Map([
39567
+ ["LogDeliveryConfigurations", [
39568
+ "DestinationDetails",
39569
+ "DestinationType",
39570
+ "LogFormat",
39571
+ "LogType"
39572
+ ]],
39573
+ ["LogDeliveryConfigurations.DestinationDetails.CloudWatchLogsDetails", ["LogGroup"]],
39574
+ ["LogDeliveryConfigurations.DestinationDetails.KinesisFirehoseDetails", ["DeliveryStream"]],
39575
+ ["Tags", ["Key", "Value"]]
39576
+ ])],
39577
+ ["AWS::ElastiCache::SubnetGroup", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39578
+ ["AWS::ElasticLoadBalancingV2::Listener", /* @__PURE__ */ new Map([
39579
+ ["DefaultActions", ["Type"]],
39580
+ ["DefaultActions.AuthenticateCognitoConfig", [
39581
+ "UserPoolArn",
39582
+ "UserPoolClientId",
39583
+ "UserPoolDomain"
39584
+ ]],
39585
+ ["DefaultActions.AuthenticateOidcConfig", [
39586
+ "AuthorizationEndpoint",
39587
+ "ClientId",
39588
+ "Issuer",
39589
+ "TokenEndpoint",
39590
+ "UserInfoEndpoint"
39591
+ ]],
39592
+ ["DefaultActions.FixedResponseConfig", ["StatusCode"]],
39593
+ ["DefaultActions.JwtValidationConfig", ["Issuer", "JwksEndpoint"]],
39594
+ ["DefaultActions.JwtValidationConfig.AdditionalClaims", [
39595
+ "Format",
39596
+ "Name",
39597
+ "Values"
39598
+ ]],
39599
+ ["DefaultActions.RedirectConfig", ["StatusCode"]],
39600
+ ["Tags", ["Key", "Value"]]
39601
+ ])],
39602
+ ["AWS::ElasticLoadBalancingV2::LoadBalancer", /* @__PURE__ */ new Map([
39603
+ ["MinimumLoadBalancerCapacity", ["CapacityUnits"]],
39604
+ ["SubnetMappings", ["SubnetId"]],
39605
+ ["Tags", ["Key"]]
39606
+ ])],
39607
+ ["AWS::ElasticLoadBalancingV2::TargetGroup", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]], ["Targets", ["Id"]]])],
39608
+ ["AWS::EMR::Cluster", /* @__PURE__ */ new Map([
39609
+ ["BootstrapActions", ["Name", "ScriptBootstrapAction"]],
39610
+ ["BootstrapActions.ScriptBootstrapAction", ["Path"]],
39611
+ ["Instances.CoreInstanceFleet.InstanceTypeConfigs", ["InstanceType"]],
39612
+ ["Instances.CoreInstanceFleet.InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39613
+ ["Instances.CoreInstanceFleet.InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]],
39614
+ ["Instances.CoreInstanceFleet.LaunchSpecifications.OnDemandSpecification", ["AllocationStrategy"]],
39615
+ ["Instances.CoreInstanceFleet.LaunchSpecifications.SpotSpecification", ["TimeoutAction", "TimeoutDurationMinutes"]],
39616
+ ["Instances.CoreInstanceGroup", ["InstanceCount", "InstanceType"]],
39617
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy", ["Constraints", "Rules"]],
39618
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy.Constraints", ["MaxCapacity", "MinCapacity"]],
39619
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy.Rules", [
39620
+ "Action",
39621
+ "Name",
39622
+ "Trigger"
39623
+ ]],
39624
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy.Rules.Action", ["SimpleScalingPolicyConfiguration"]],
39625
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy.Rules.Action.SimpleScalingPolicyConfiguration", ["ScalingAdjustment"]],
39626
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy.Rules.Trigger", ["CloudWatchAlarmDefinition"]],
39627
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition", [
39628
+ "ComparisonOperator",
39629
+ "MetricName",
39630
+ "Period",
39631
+ "Threshold"
39632
+ ]],
39633
+ ["Instances.CoreInstanceGroup.AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition.Dimensions", ["Key", "Value"]],
39634
+ ["Instances.CoreInstanceGroup.EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39635
+ ["Instances.CoreInstanceGroup.EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]],
39636
+ ["Instances.MasterInstanceFleet.InstanceTypeConfigs", ["InstanceType"]],
39637
+ ["Instances.MasterInstanceFleet.InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39638
+ ["Instances.MasterInstanceFleet.InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]],
39639
+ ["Instances.MasterInstanceFleet.LaunchSpecifications.OnDemandSpecification", ["AllocationStrategy"]],
39640
+ ["Instances.MasterInstanceFleet.LaunchSpecifications.SpotSpecification", ["TimeoutAction", "TimeoutDurationMinutes"]],
39641
+ ["Instances.MasterInstanceGroup", ["InstanceCount", "InstanceType"]],
39642
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy", ["Constraints", "Rules"]],
39643
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy.Constraints", ["MaxCapacity", "MinCapacity"]],
39644
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy.Rules", [
39645
+ "Action",
39646
+ "Name",
39647
+ "Trigger"
39648
+ ]],
39649
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy.Rules.Action", ["SimpleScalingPolicyConfiguration"]],
39650
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy.Rules.Action.SimpleScalingPolicyConfiguration", ["ScalingAdjustment"]],
39651
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy.Rules.Trigger", ["CloudWatchAlarmDefinition"]],
39652
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition", [
39653
+ "ComparisonOperator",
39654
+ "MetricName",
39655
+ "Period",
39656
+ "Threshold"
39657
+ ]],
39658
+ ["Instances.MasterInstanceGroup.AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition.Dimensions", ["Key", "Value"]],
39659
+ ["Instances.MasterInstanceGroup.EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39660
+ ["Instances.MasterInstanceGroup.EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]],
39661
+ ["Instances.Placement", ["AvailabilityZone"]],
39662
+ ["Instances.TaskInstanceFleets.InstanceTypeConfigs", ["InstanceType"]],
39663
+ ["Instances.TaskInstanceFleets.InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39664
+ ["Instances.TaskInstanceFleets.InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]],
39665
+ ["Instances.TaskInstanceFleets.LaunchSpecifications.OnDemandSpecification", ["AllocationStrategy"]],
39666
+ ["Instances.TaskInstanceFleets.LaunchSpecifications.SpotSpecification", ["TimeoutAction", "TimeoutDurationMinutes"]],
39667
+ ["Instances.TaskInstanceGroups", ["InstanceCount", "InstanceType"]],
39668
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy", ["Constraints", "Rules"]],
39669
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy.Constraints", ["MaxCapacity", "MinCapacity"]],
39670
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy.Rules", [
39671
+ "Action",
39672
+ "Name",
39673
+ "Trigger"
39674
+ ]],
39675
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy.Rules.Action", ["SimpleScalingPolicyConfiguration"]],
39676
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy.Rules.Action.SimpleScalingPolicyConfiguration", ["ScalingAdjustment"]],
39677
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy.Rules.Trigger", ["CloudWatchAlarmDefinition"]],
39678
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition", [
39679
+ "ComparisonOperator",
39680
+ "MetricName",
39681
+ "Period",
39682
+ "Threshold"
39683
+ ]],
39684
+ ["Instances.TaskInstanceGroups.AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition.Dimensions", ["Key", "Value"]],
39685
+ ["Instances.TaskInstanceGroups.EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39686
+ ["Instances.TaskInstanceGroups.EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]],
39687
+ ["KerberosAttributes", ["KdcAdminPassword", "Realm"]],
39688
+ ["ManagedScalingPolicy.ComputeLimits", [
39689
+ "MaximumCapacityUnits",
39690
+ "MinimumCapacityUnits",
39691
+ "UnitType"
39692
+ ]],
39693
+ ["PlacementGroupConfigs", ["InstanceRole"]],
39694
+ ["Steps", ["HadoopJarStep", "Name"]],
39695
+ ["Steps.HadoopJarStep", ["Jar"]],
39696
+ ["Tags", ["Key", "Value"]]
39697
+ ])],
39698
+ ["AWS::EMR::InstanceFleetConfig", /* @__PURE__ */ new Map([
39699
+ ["InstanceTypeConfigs", ["InstanceType"]],
39700
+ ["InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39701
+ ["InstanceTypeConfigs.EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]],
39702
+ ["LaunchSpecifications.OnDemandSpecification", ["AllocationStrategy"]],
39703
+ ["LaunchSpecifications.SpotSpecification", ["TimeoutAction", "TimeoutDurationMinutes"]]
39704
+ ])],
39705
+ ["AWS::EMR::InstanceGroupConfig", /* @__PURE__ */ new Map([
39706
+ ["AutoScalingPolicy", ["Constraints", "Rules"]],
39707
+ ["AutoScalingPolicy.Constraints", ["MaxCapacity", "MinCapacity"]],
39708
+ ["AutoScalingPolicy.Rules", [
39709
+ "Action",
39710
+ "Name",
39711
+ "Trigger"
39712
+ ]],
39713
+ ["AutoScalingPolicy.Rules.Action", ["SimpleScalingPolicyConfiguration"]],
39714
+ ["AutoScalingPolicy.Rules.Action.SimpleScalingPolicyConfiguration", ["ScalingAdjustment"]],
39715
+ ["AutoScalingPolicy.Rules.Trigger", ["CloudWatchAlarmDefinition"]],
39716
+ ["AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition", [
39717
+ "ComparisonOperator",
39718
+ "MetricName",
39719
+ "Period",
39720
+ "Threshold"
39721
+ ]],
39722
+ ["AutoScalingPolicy.Rules.Trigger.CloudWatchAlarmDefinition.Dimensions", ["Key", "Value"]],
39723
+ ["EbsConfiguration.EbsBlockDeviceConfigs", ["VolumeSpecification"]],
39724
+ ["EbsConfiguration.EbsBlockDeviceConfigs.VolumeSpecification", ["SizeInGB", "VolumeType"]]
39725
+ ])],
39726
+ ["AWS::Events::EventBus", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39727
+ ["AWS::Events::Rule", /* @__PURE__ */ new Map([
39728
+ ["Targets", ["Arn", "Id"]],
39729
+ ["Targets.AppSyncParameters", ["GraphQLOperation"]],
39730
+ ["Targets.BatchParameters", ["JobDefinition", "JobName"]],
39731
+ ["Targets.EcsParameters", ["TaskDefinitionArn"]],
39732
+ ["Targets.EcsParameters.CapacityProviderStrategy", ["CapacityProvider"]],
39733
+ ["Targets.EcsParameters.NetworkConfiguration.AwsVpcConfiguration", ["Subnets"]],
39734
+ ["Targets.InputTransformer", ["InputTemplate"]],
39735
+ ["Targets.KinesisParameters", ["PartitionKeyPath"]],
39736
+ ["Targets.RedshiftDataParameters", ["Database"]],
39737
+ ["Targets.RunCommandParameters", ["RunCommandTargets"]],
39738
+ ["Targets.RunCommandParameters.RunCommandTargets", ["Key", "Values"]],
39739
+ ["Targets.SageMakerPipelineParameters.PipelineParameterList", ["Name", "Value"]],
39740
+ ["Targets.SqsParameters", ["MessageGroupId"]]
39741
+ ])],
39742
+ ["AWS::FSx::FileSystem", /* @__PURE__ */ new Map([
39743
+ ["LustreConfiguration.LogConfiguration", ["Level"]],
39744
+ ["OntapConfiguration", ["DeploymentType"]],
39745
+ ["OpenZFSConfiguration", ["DeploymentType"]],
39746
+ ["Tags", ["Key", "Value"]],
39747
+ ["WindowsConfiguration", ["ThroughputCapacity"]],
39748
+ ["WindowsConfiguration.AuditLogConfiguration", ["FileAccessAuditLogLevel", "FileShareAccessAuditLogLevel"]],
39749
+ ["WindowsConfiguration.FsrmConfiguration", ["FsrmServiceEnabled"]]
39750
+ ])],
39751
+ ["AWS::Glue::Connection", /* @__PURE__ */ new Map([["ConnectionInput", ["ConnectionType"]], ["ConnectionInput.AuthenticationConfiguration", ["AuthenticationType"]]])],
39752
+ ["AWS::Glue::Table", /* @__PURE__ */ new Map([
39753
+ ["OpenTableFormatInput.IcebergInput.IcebergTableInput", ["Location", "Schema"]],
39754
+ ["OpenTableFormatInput.IcebergInput.IcebergTableInput.PartitionSpec", ["Fields"]],
39755
+ ["OpenTableFormatInput.IcebergInput.IcebergTableInput.PartitionSpec.Fields", [
39756
+ "Name",
39757
+ "SourceId",
39758
+ "Transform"
39759
+ ]],
39760
+ ["OpenTableFormatInput.IcebergInput.IcebergTableInput.Schema", ["Fields"]],
39761
+ ["OpenTableFormatInput.IcebergInput.IcebergTableInput.Schema.Fields", [
39762
+ "Id",
39763
+ "Name",
39764
+ "Required",
39765
+ "Type"
39766
+ ]],
39767
+ ["OpenTableFormatInput.IcebergInput.IcebergTableInput.WriteOrder", ["Fields", "OrderId"]],
39768
+ ["OpenTableFormatInput.IcebergInput.IcebergTableInput.WriteOrder.Fields", [
39769
+ "Direction",
39770
+ "NullOrder",
39771
+ "SourceId",
39772
+ "Transform"
39773
+ ]],
39774
+ ["TableInput.PartitionKeys", ["Name"]],
39775
+ ["TableInput.StorageDescriptor.Columns", ["Name"]],
39776
+ ["TableInput.StorageDescriptor.SortColumns", ["Column", "SortOrder"]]
39777
+ ])],
39778
+ ["AWS::Glue::Trigger", /* @__PURE__ */ new Map([["EventBatchingCondition", ["BatchSize"]]])],
39779
+ ["AWS::IAM::Group", /* @__PURE__ */ new Map([["Policies", ["PolicyDocument", "PolicyName"]]])],
39780
+ ["AWS::IAM::Role", /* @__PURE__ */ new Map([["Policies", ["PolicyDocument", "PolicyName"]], ["Tags", ["Key", "Value"]]])],
39781
+ ["AWS::IAM::User", /* @__PURE__ */ new Map([
39782
+ ["LoginProfile", ["Password"]],
39783
+ ["Policies", ["PolicyDocument", "PolicyName"]],
39784
+ ["Tags", ["Key", "Value"]]
39785
+ ])],
39786
+ ["AWS::Kinesis::Stream", /* @__PURE__ */ new Map([
39787
+ ["StreamEncryption", ["EncryptionType", "KeyId"]],
39788
+ ["StreamModeDetails", ["StreamMode"]],
39789
+ ["Tags", ["Key", "Value"]]
39790
+ ])],
39791
+ ["AWS::Kinesis::StreamConsumer", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39792
+ ["AWS::KinesisFirehose::DeliveryStream", /* @__PURE__ */ new Map([
39793
+ ["AmazonOpenSearchServerlessDestinationConfiguration", [
39794
+ "IndexName",
39795
+ "RoleARN",
39796
+ "S3Configuration"
39797
+ ]],
39798
+ ["AmazonOpenSearchServerlessDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39799
+ ["AmazonOpenSearchServerlessDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39800
+ ["AmazonOpenSearchServerlessDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39801
+ ["AmazonOpenSearchServerlessDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39802
+ ["AmazonOpenSearchServerlessDestinationConfiguration.VpcConfiguration", [
39803
+ "RoleARN",
39804
+ "SecurityGroupIds",
39805
+ "SubnetIds"
39806
+ ]],
39807
+ ["AmazonopensearchserviceDestinationConfiguration", [
39808
+ "IndexName",
39809
+ "RoleARN",
39810
+ "S3Configuration"
39811
+ ]],
39812
+ ["AmazonopensearchserviceDestinationConfiguration.DocumentIdOptions", ["DefaultDocumentIdFormat"]],
39813
+ ["AmazonopensearchserviceDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39814
+ ["AmazonopensearchserviceDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39815
+ ["AmazonopensearchserviceDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39816
+ ["AmazonopensearchserviceDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39817
+ ["AmazonopensearchserviceDestinationConfiguration.VpcConfiguration", [
39818
+ "RoleARN",
39819
+ "SecurityGroupIds",
39820
+ "SubnetIds"
39821
+ ]],
39822
+ ["DatabaseSourceConfiguration", [
39823
+ "DatabaseSourceAuthenticationConfiguration",
39824
+ "DatabaseSourceVPCConfiguration",
39825
+ "Databases",
39826
+ "Endpoint",
39827
+ "Port",
39828
+ "SnapshotWatermarkTable",
39829
+ "Tables",
39830
+ "Type"
39831
+ ]],
39832
+ ["DatabaseSourceConfiguration.DatabaseSourceAuthenticationConfiguration", ["SecretsManagerConfiguration"]],
39833
+ ["DatabaseSourceConfiguration.DatabaseSourceAuthenticationConfiguration.SecretsManagerConfiguration", ["Enabled"]],
39834
+ ["DatabaseSourceConfiguration.DatabaseSourceVPCConfiguration", ["VpcEndpointServiceName"]],
39835
+ ["DeliveryStreamEncryptionConfigurationInput", ["KeyType"]],
39836
+ ["ElasticsearchDestinationConfiguration", [
39837
+ "IndexName",
39838
+ "RoleARN",
39839
+ "S3Configuration"
39840
+ ]],
39841
+ ["ElasticsearchDestinationConfiguration.DocumentIdOptions", ["DefaultDocumentIdFormat"]],
39842
+ ["ElasticsearchDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39843
+ ["ElasticsearchDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39844
+ ["ElasticsearchDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39845
+ ["ElasticsearchDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39846
+ ["ElasticsearchDestinationConfiguration.VpcConfiguration", [
39847
+ "RoleARN",
39848
+ "SecurityGroupIds",
39849
+ "SubnetIds"
39850
+ ]],
39851
+ ["ExtendedS3DestinationConfiguration", ["BucketARN", "RoleARN"]],
39852
+ ["ExtendedS3DestinationConfiguration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39853
+ ["ExtendedS3DestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39854
+ ["ExtendedS3DestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39855
+ ["ExtendedS3DestinationConfiguration.S3BackupConfiguration", ["BucketARN", "RoleARN"]],
39856
+ ["ExtendedS3DestinationConfiguration.S3BackupConfiguration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39857
+ ["HttpEndpointDestinationConfiguration", ["EndpointConfiguration", "S3Configuration"]],
39858
+ ["HttpEndpointDestinationConfiguration.EndpointConfiguration", ["Url"]],
39859
+ ["HttpEndpointDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39860
+ ["HttpEndpointDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39861
+ ["HttpEndpointDestinationConfiguration.RequestConfiguration.CommonAttributes", ["AttributeName", "AttributeValue"]],
39862
+ ["HttpEndpointDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39863
+ ["HttpEndpointDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39864
+ ["HttpEndpointDestinationConfiguration.SecretsManagerConfiguration", ["Enabled"]],
39865
+ ["IcebergDestinationConfiguration", [
39866
+ "CatalogConfiguration",
39867
+ "RoleARN",
39868
+ "S3Configuration"
39869
+ ]],
39870
+ ["IcebergDestinationConfiguration.DestinationTableConfigurationList", ["DestinationDatabaseName", "DestinationTableName"]],
39871
+ ["IcebergDestinationConfiguration.DestinationTableConfigurationList.PartitionSpec.Identity", ["SourceName"]],
39872
+ ["IcebergDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39873
+ ["IcebergDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39874
+ ["IcebergDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39875
+ ["IcebergDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39876
+ ["KinesisStreamSourceConfiguration", ["KinesisStreamARN", "RoleARN"]],
39877
+ ["MSKSourceConfiguration", [
39878
+ "AuthenticationConfiguration",
39879
+ "MSKClusterARN",
39880
+ "TopicName"
39881
+ ]],
39882
+ ["MSKSourceConfiguration.AuthenticationConfiguration", ["Connectivity", "RoleARN"]],
39883
+ ["RedshiftDestinationConfiguration", [
39884
+ "ClusterJDBCURL",
39885
+ "CopyCommand",
39886
+ "RoleARN",
39887
+ "S3Configuration"
39888
+ ]],
39889
+ ["RedshiftDestinationConfiguration.CopyCommand", ["DataTableName"]],
39890
+ ["RedshiftDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39891
+ ["RedshiftDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39892
+ ["RedshiftDestinationConfiguration.S3BackupConfiguration", ["BucketARN", "RoleARN"]],
39893
+ ["RedshiftDestinationConfiguration.S3BackupConfiguration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39894
+ ["RedshiftDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39895
+ ["RedshiftDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39896
+ ["RedshiftDestinationConfiguration.SecretsManagerConfiguration", ["Enabled"]],
39897
+ ["S3DestinationConfiguration", ["BucketARN", "RoleARN"]],
39898
+ ["S3DestinationConfiguration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39899
+ ["SnowflakeDestinationConfiguration", [
39900
+ "AccountUrl",
39901
+ "Database",
39902
+ "RoleARN",
39903
+ "S3Configuration",
39904
+ "Schema",
39905
+ "Table"
39906
+ ]],
39907
+ ["SnowflakeDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39908
+ ["SnowflakeDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39909
+ ["SnowflakeDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39910
+ ["SnowflakeDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39911
+ ["SnowflakeDestinationConfiguration.SecretsManagerConfiguration", ["Enabled"]],
39912
+ ["SnowflakeDestinationConfiguration.SnowflakeVpcConfiguration", ["PrivateLinkVpceId"]],
39913
+ ["SplunkDestinationConfiguration", [
39914
+ "HECEndpoint",
39915
+ "HECEndpointType",
39916
+ "S3Configuration"
39917
+ ]],
39918
+ ["SplunkDestinationConfiguration.ProcessingConfiguration.Processors", ["Type"]],
39919
+ ["SplunkDestinationConfiguration.ProcessingConfiguration.Processors.Parameters", ["ParameterName", "ParameterValue"]],
39920
+ ["SplunkDestinationConfiguration.S3Configuration", ["BucketARN", "RoleARN"]],
39921
+ ["SplunkDestinationConfiguration.S3Configuration.EncryptionConfiguration.KMSEncryptionConfig", ["AWSKMSKeyARN"]],
39922
+ ["SplunkDestinationConfiguration.SecretsManagerConfiguration", ["Enabled"]],
39923
+ ["Tags", ["Key"]]
39924
+ ])],
39925
+ ["AWS::KMS::Key", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39926
+ ["AWS::Lambda::EventInvokeConfig", /* @__PURE__ */ new Map([["DestinationConfig.OnFailure", ["Destination"]], ["DestinationConfig.OnSuccess", ["Destination"]]])],
39927
+ ["AWS::Lambda::EventSourceMapping", /* @__PURE__ */ new Map([["Tags", ["Key"]]])],
39928
+ ["AWS::Lambda::Function", /* @__PURE__ */ new Map([
39929
+ ["CapacityProviderConfig", ["LambdaManagedInstancesCapacityProviderConfig"]],
39930
+ ["CapacityProviderConfig.LambdaManagedInstancesCapacityProviderConfig", ["CapacityProviderArn"]],
39931
+ ["DurableConfig", ["ExecutionTimeout"]],
39932
+ ["EphemeralStorage", ["Size"]],
39933
+ ["FileSystemConfigs", ["Arn", "LocalMountPath"]],
39934
+ ["RuntimeManagementConfig", ["UpdateRuntimeOn"]],
39935
+ ["SnapStart", ["ApplyOn"]],
39936
+ ["Tags", ["Key"]],
39937
+ ["TenancyConfig", ["TenantIsolationMode"]]
39938
+ ])],
39939
+ ["AWS::Lambda::LayerVersion", /* @__PURE__ */ new Map([["Content", ["S3Bucket", "S3Key"]]])],
39940
+ ["AWS::Lambda::MicrovmImage", /* @__PURE__ */ new Map([
39941
+ ["CodeArtifact", ["Uri"]],
39942
+ ["CpuConfigurations", ["Architecture"]],
39943
+ ["EnvironmentVariables", ["Key", "Value"]],
39944
+ ["Resources", ["MinimumMemoryInMiB"]],
39945
+ ["Tags", ["Key"]]
39946
+ ])],
39947
+ ["AWS::Logs::LogGroup", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39948
+ ["AWS::Neptune::DBCluster", /* @__PURE__ */ new Map([
39949
+ ["AssociatedRoles", ["RoleArn"]],
39950
+ ["ServerlessScalingConfiguration", ["MaxCapacity", "MinCapacity"]],
39951
+ ["Tags", ["Key"]]
39952
+ ])],
39953
+ ["AWS::Neptune::DBInstance", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39954
+ ["AWS::Neptune::DBSubnetGroup", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
39955
+ ["AWS::RDS::DBCluster", /* @__PURE__ */ new Map([["AssociatedRoles", ["RoleArn"]], ["Tags", ["Key"]]])],
39956
+ ["AWS::RDS::DBInstance", /* @__PURE__ */ new Map([["AssociatedRoles", ["FeatureName", "RoleArn"]], ["Tags", ["Key"]]])],
39957
+ ["AWS::RDS::DBSubnetGroup", /* @__PURE__ */ new Map([["Tags", ["Key"]]])],
39958
+ ["AWS::Route53::HostedZone", /* @__PURE__ */ new Map([
39959
+ ["HostedZoneTags", ["Key", "Value"]],
39960
+ ["QueryLoggingConfig", ["CloudWatchLogsLogGroupArn"]],
39961
+ ["VPCs", ["VPCId", "VPCRegion"]]
39962
+ ])],
39963
+ ["AWS::Route53::RecordSet", /* @__PURE__ */ new Map([["AliasTarget", ["DNSName", "HostedZoneId"]], ["CidrRoutingConfig", ["CollectionId", "LocationName"]]])],
39964
+ ["AWS::S3::Bucket", /* @__PURE__ */ new Map([
39965
+ ["AccelerateConfiguration", ["AccelerationStatus"]],
39966
+ ["AnalyticsConfigurations", ["Id", "StorageClassAnalysis"]],
39967
+ ["AnalyticsConfigurations.StorageClassAnalysis.DataExport", ["Destination", "OutputSchemaVersion"]],
39968
+ ["AnalyticsConfigurations.StorageClassAnalysis.DataExport.Destination", ["BucketArn", "Format"]],
39969
+ ["AnalyticsConfigurations.TagFilters", ["Key", "Value"]],
39970
+ ["BucketEncryption", ["ServerSideEncryptionConfiguration"]],
39971
+ ["BucketEncryption.ServerSideEncryptionConfiguration.ServerSideEncryptionByDefault", ["SSEAlgorithm"]],
39972
+ ["CorsConfiguration", ["CorsRules"]],
39973
+ ["CorsConfiguration.CorsRules", ["AllowedMethods", "AllowedOrigins"]],
39974
+ ["IntelligentTieringConfigurations", [
39975
+ "Id",
39976
+ "Status",
39977
+ "Tierings"
39978
+ ]],
39979
+ ["IntelligentTieringConfigurations.TagFilters", ["Key", "Value"]],
39980
+ ["IntelligentTieringConfigurations.Tierings", ["AccessTier", "Days"]],
39981
+ ["InventoryConfigurations", [
39982
+ "Destination",
39983
+ "Enabled",
39984
+ "Id",
39985
+ "IncludedObjectVersions",
39986
+ "ScheduleFrequency"
39987
+ ]],
39988
+ ["InventoryConfigurations.Destination", ["BucketArn", "Format"]],
39989
+ ["LifecycleConfiguration", ["Rules"]],
39990
+ ["LifecycleConfiguration.Rules", ["Status"]],
39991
+ ["LifecycleConfiguration.Rules.AbortIncompleteMultipartUpload", ["DaysAfterInitiation"]],
39992
+ ["LifecycleConfiguration.Rules.NoncurrentVersionExpiration", ["NoncurrentDays"]],
39993
+ ["LifecycleConfiguration.Rules.NoncurrentVersionTransition", ["StorageClass", "TransitionInDays"]],
39994
+ ["LifecycleConfiguration.Rules.NoncurrentVersionTransitions", ["StorageClass", "TransitionInDays"]],
39995
+ ["LifecycleConfiguration.Rules.TagFilters", ["Key", "Value"]],
39996
+ ["LifecycleConfiguration.Rules.Transition", ["StorageClass"]],
39997
+ ["LifecycleConfiguration.Rules.Transitions", ["StorageClass"]],
39998
+ ["MetadataConfiguration", ["JournalTableConfiguration"]],
39999
+ ["MetadataConfiguration.AnnotationTableConfiguration", ["ConfigurationState"]],
40000
+ ["MetadataConfiguration.AnnotationTableConfiguration.EncryptionConfiguration", ["SseAlgorithm"]],
40001
+ ["MetadataConfiguration.Destination", ["TableBucketType"]],
40002
+ ["MetadataConfiguration.InventoryTableConfiguration", ["ConfigurationState"]],
40003
+ ["MetadataConfiguration.InventoryTableConfiguration.EncryptionConfiguration", ["SseAlgorithm"]],
40004
+ ["MetadataConfiguration.JournalTableConfiguration", ["RecordExpiration"]],
40005
+ ["MetadataConfiguration.JournalTableConfiguration.EncryptionConfiguration", ["SseAlgorithm"]],
40006
+ ["MetadataConfiguration.JournalTableConfiguration.RecordExpiration", ["Expiration"]],
40007
+ ["MetadataTableConfiguration", ["S3TablesDestination"]],
40008
+ ["MetadataTableConfiguration.S3TablesDestination", ["TableBucketArn", "TableName"]],
40009
+ ["MetricsConfigurations", ["Id"]],
40010
+ ["MetricsConfigurations.TagFilters", ["Key", "Value"]],
40011
+ ["NotificationConfiguration.EventBridgeConfiguration", ["EventBridgeEnabled"]],
40012
+ ["NotificationConfiguration.LambdaConfigurations", ["Event", "Function"]],
40013
+ ["NotificationConfiguration.LambdaConfigurations.Filter", ["S3Key"]],
40014
+ ["NotificationConfiguration.LambdaConfigurations.Filter.S3Key", ["Rules"]],
40015
+ ["NotificationConfiguration.LambdaConfigurations.Filter.S3Key.Rules", ["Name", "Value"]],
40016
+ ["NotificationConfiguration.QueueConfigurations", ["Event", "Queue"]],
40017
+ ["NotificationConfiguration.QueueConfigurations.Filter", ["S3Key"]],
40018
+ ["NotificationConfiguration.QueueConfigurations.Filter.S3Key", ["Rules"]],
40019
+ ["NotificationConfiguration.QueueConfigurations.Filter.S3Key.Rules", ["Name", "Value"]],
40020
+ ["NotificationConfiguration.TopicConfigurations", ["Event", "Topic"]],
40021
+ ["NotificationConfiguration.TopicConfigurations.Filter", ["S3Key"]],
40022
+ ["NotificationConfiguration.TopicConfigurations.Filter.S3Key", ["Rules"]],
40023
+ ["NotificationConfiguration.TopicConfigurations.Filter.S3Key.Rules", ["Name", "Value"]],
40024
+ ["OwnershipControls", ["Rules"]],
40025
+ ["ReplicationConfiguration", ["Role", "Rules"]],
40026
+ ["ReplicationConfiguration.Rules", ["Destination", "Status"]],
40027
+ ["ReplicationConfiguration.Rules.Destination", ["Bucket"]],
40028
+ ["ReplicationConfiguration.Rules.Destination.AccessControlTranslation", ["Owner"]],
40029
+ ["ReplicationConfiguration.Rules.Destination.EncryptionConfiguration", ["ReplicaKmsKeyID"]],
40030
+ ["ReplicationConfiguration.Rules.Destination.Metrics", ["Status"]],
40031
+ ["ReplicationConfiguration.Rules.Destination.Metrics.EventThreshold", ["Minutes"]],
40032
+ ["ReplicationConfiguration.Rules.Destination.ReplicationTime", ["Status", "Time"]],
40033
+ ["ReplicationConfiguration.Rules.Destination.ReplicationTime.Time", ["Minutes"]],
40034
+ ["ReplicationConfiguration.Rules.Filter.And.TagFilters", ["Key", "Value"]],
40035
+ ["ReplicationConfiguration.Rules.Filter.TagFilter", ["Key", "Value"]],
40036
+ ["ReplicationConfiguration.Rules.SourceSelectionCriteria.ReplicaModifications", ["Status"]],
40037
+ ["ReplicationConfiguration.Rules.SourceSelectionCriteria.SseKmsEncryptedObjects", ["Status"]],
40038
+ ["Tags", ["Key", "Value"]],
40039
+ ["VersioningConfiguration", ["Status"]],
40040
+ ["WebsiteConfiguration.RedirectAllRequestsTo", ["HostName"]],
40041
+ ["WebsiteConfiguration.RoutingRules", ["RedirectRule"]]
40042
+ ])],
40043
+ ["AWS::S3Express::DirectoryBucket", /* @__PURE__ */ new Map([
40044
+ ["BucketEncryption", ["ServerSideEncryptionConfiguration"]],
40045
+ ["BucketEncryption.ServerSideEncryptionConfiguration.ServerSideEncryptionByDefault", ["SSEAlgorithm"]],
40046
+ ["InventoryConfigurations", [
40047
+ "Destination",
40048
+ "Enabled",
40049
+ "Id",
40050
+ "IncludedObjectVersions",
40051
+ "ScheduleFrequency"
40052
+ ]],
40053
+ ["InventoryConfigurations.Destination", ["BucketArn", "Format"]],
40054
+ ["LifecycleConfiguration", ["Rules"]],
40055
+ ["LifecycleConfiguration.Rules", ["Status"]],
40056
+ ["LifecycleConfiguration.Rules.AbortIncompleteMultipartUpload", ["DaysAfterInitiation"]],
40057
+ ["MetricsConfigurations", ["Id"]],
40058
+ ["Tags", ["Key", "Value"]]
40059
+ ])],
40060
+ ["AWS::S3Tables::Table", /* @__PURE__ */ new Map([
40061
+ ["IcebergMetadata.IcebergPartitionSpec", ["Fields"]],
40062
+ ["IcebergMetadata.IcebergPartitionSpec.Fields", [
40063
+ "Name",
40064
+ "SourceId",
40065
+ "Transform"
40066
+ ]],
40067
+ ["IcebergMetadata.IcebergSchema", ["SchemaFieldList"]],
40068
+ ["IcebergMetadata.IcebergSchema.SchemaFieldList", ["Name", "Type"]],
40069
+ ["IcebergMetadata.IcebergSchemaV2", ["SchemaV2FieldList", "SchemaV2FieldType"]],
40070
+ ["IcebergMetadata.IcebergSchemaV2.SchemaV2FieldList", [
40071
+ "Id",
40072
+ "Name",
40073
+ "Required",
40074
+ "Type"
40075
+ ]],
40076
+ ["IcebergMetadata.IcebergSortOrder", ["Fields"]],
40077
+ ["IcebergMetadata.IcebergSortOrder.Fields", [
40078
+ "Direction",
40079
+ "NullOrder",
40080
+ "SourceId",
40081
+ "Transform"
40082
+ ]],
40083
+ ["Tags", ["Key", "Value"]]
40084
+ ])],
40085
+ ["AWS::S3Tables::TableBucket", /* @__PURE__ */ new Map([
40086
+ ["ReplicationConfiguration", ["Role", "Rules"]],
40087
+ ["ReplicationConfiguration.Rules", ["Destinations"]],
40088
+ ["ReplicationConfiguration.Rules.Destinations", ["DestinationTableBucketARN"]],
40089
+ ["Tags", ["Key", "Value"]]
40090
+ ])],
40091
+ ["AWS::S3Vectors::VectorBucket", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
40092
+ ["AWS::Scheduler::Schedule", /* @__PURE__ */ new Map([
40093
+ ["FlexibleTimeWindow", ["Mode"]],
40094
+ ["Target", ["Arn", "RoleArn"]],
40095
+ ["Target.EcsParameters", ["TaskDefinitionArn"]],
40096
+ ["Target.EcsParameters.CapacityProviderStrategy", ["CapacityProvider"]],
40097
+ ["Target.EcsParameters.NetworkConfiguration.AwsvpcConfiguration", ["Subnets"]],
40098
+ ["Target.EventBridgeParameters", ["DetailType", "Source"]],
40099
+ ["Target.KinesisParameters", ["PartitionKey"]],
40100
+ ["Target.SageMakerPipelineParameters.PipelineParameterList", ["Name", "Value"]]
40101
+ ])],
40102
+ ["AWS::SecretsManager::Secret", /* @__PURE__ */ new Map([["ReplicaRegions", ["Region"]], ["Tags", ["Key", "Value"]]])],
40103
+ ["AWS::ServiceDiscovery::HttpNamespace", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
40104
+ ["AWS::ServiceDiscovery::PrivateDnsNamespace", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
40105
+ ["AWS::ServiceDiscovery::PublicDnsNamespace", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
40106
+ ["AWS::ServiceDiscovery::Service", /* @__PURE__ */ new Map([
40107
+ ["DnsConfig", ["DnsRecords"]],
40108
+ ["DnsConfig.DnsRecords", ["TTL", "Type"]],
40109
+ ["HealthCheckConfig", ["Type"]],
40110
+ ["Tags", ["Key", "Value"]]
40111
+ ])],
40112
+ ["AWS::SNS::Topic", /* @__PURE__ */ new Map([
40113
+ ["DeliveryStatusLogging", ["Protocol"]],
40114
+ ["Subscription", ["Endpoint", "Protocol"]],
40115
+ ["Tags", ["Key", "Value"]]
40116
+ ])],
40117
+ ["AWS::SQS::Queue", /* @__PURE__ */ new Map([["Tags", ["Key", "Value"]]])],
40118
+ ["AWS::StepFunctions::StateMachine", /* @__PURE__ */ new Map([
40119
+ ["DefinitionS3Location", ["Bucket", "Key"]],
40120
+ ["EncryptionConfiguration", ["Type"]],
40121
+ ["Tags", ["Key", "Value"]]
40122
+ ])],
40123
+ ["AWS::WAFv2::WebACL", /* @__PURE__ */ new Map([
40124
+ ["ApplicationConfig", ["Attributes"]],
40125
+ ["ApplicationConfig.Attributes", ["Name", "Values"]],
40126
+ ["CaptchaConfig.ImmunityTimeProperty", ["ImmunityTime"]],
40127
+ ["ChallengeConfig.ImmunityTimeProperty", ["ImmunityTime"]],
40128
+ ["DataProtectionConfig", ["DataProtections"]],
40129
+ ["DataProtectionConfig.DataProtections", ["Action", "Field"]],
40130
+ ["DataProtectionConfig.DataProtections.Field", ["FieldType"]],
40131
+ ["DefaultAction.Allow.CustomRequestHandling", ["InsertHeaders"]],
40132
+ ["DefaultAction.Allow.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40133
+ ["DefaultAction.Block.CustomResponse", ["ResponseCode"]],
40134
+ ["DefaultAction.Block.CustomResponse.ResponseHeaders", ["Name", "Value"]],
40135
+ ["MonetizationConfig.CryptoConfig", ["PaymentNetworks"]],
40136
+ ["MonetizationConfig.CryptoConfig.PaymentNetworks", [
40137
+ "Chain",
40138
+ "Prices",
40139
+ "WalletAddress"
40140
+ ]],
40141
+ ["MonetizationConfig.CryptoConfig.PaymentNetworks.Prices", ["Amount", "Currency"]],
40142
+ ["OnSourceDDoSProtectionConfig", ["ALBLowReputationMode"]],
40143
+ ["Rules", [
40144
+ "Name",
40145
+ "Priority",
40146
+ "Statement",
40147
+ "VisibilityConfig"
40148
+ ]],
40149
+ ["Rules.Action.Allow.CustomRequestHandling", ["InsertHeaders"]],
40150
+ ["Rules.Action.Allow.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40151
+ ["Rules.Action.Block.CustomResponse", ["ResponseCode"]],
40152
+ ["Rules.Action.Block.CustomResponse.ResponseHeaders", ["Name", "Value"]],
40153
+ ["Rules.Action.Captcha.CustomRequestHandling", ["InsertHeaders"]],
40154
+ ["Rules.Action.Captcha.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40155
+ ["Rules.Action.Challenge.CustomRequestHandling", ["InsertHeaders"]],
40156
+ ["Rules.Action.Challenge.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40157
+ ["Rules.Action.Count.CustomRequestHandling", ["InsertHeaders"]],
40158
+ ["Rules.Action.Count.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40159
+ ["Rules.CaptchaConfig.ImmunityTimeProperty", ["ImmunityTime"]],
40160
+ ["Rules.ChallengeConfig.ImmunityTimeProperty", ["ImmunityTime"]],
40161
+ ["Rules.RuleLabels", ["Name"]],
40162
+ ["Rules.Statement.AndStatement", ["Statements"]],
40163
+ ["Rules.Statement.AsnMatchStatement.ForwardedIPConfig", ["FallbackBehavior", "HeaderName"]],
40164
+ ["Rules.Statement.ByteMatchStatement", [
40165
+ "FieldToMatch",
40166
+ "PositionalConstraint",
40167
+ "TextTransformations"
40168
+ ]],
40169
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.Cookies", [
40170
+ "MatchPattern",
40171
+ "MatchScope",
40172
+ "OversizeHandling"
40173
+ ]],
40174
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.HeaderOrder", ["OversizeHandling"]],
40175
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.Headers", [
40176
+ "MatchPattern",
40177
+ "MatchScope",
40178
+ "OversizeHandling"
40179
+ ]],
40180
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.JA3Fingerprint", ["FallbackBehavior"]],
40181
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.JA4Fingerprint", ["FallbackBehavior"]],
40182
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.JsonBody", ["MatchPattern", "MatchScope"]],
40183
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.SingleHeader", ["Name"]],
40184
+ ["Rules.Statement.ByteMatchStatement.FieldToMatch.SingleQueryArgument", ["Name"]],
40185
+ ["Rules.Statement.ByteMatchStatement.PreParseTextTransformations", ["Priority", "Type"]],
40186
+ ["Rules.Statement.ByteMatchStatement.TextTransformations", ["Priority", "Type"]],
40187
+ ["Rules.Statement.GeoMatchStatement.ForwardedIPConfig", ["FallbackBehavior", "HeaderName"]],
40188
+ ["Rules.Statement.IPSetReferenceStatement", ["Arn"]],
40189
+ ["Rules.Statement.IPSetReferenceStatement.IPSetForwardedIPConfig", [
40190
+ "FallbackBehavior",
40191
+ "HeaderName",
40192
+ "Position"
40193
+ ]],
40194
+ ["Rules.Statement.LabelMatchStatement", ["Key", "Scope"]],
40195
+ ["Rules.Statement.ManagedRuleGroupStatement", ["Name", "VendorName"]],
40196
+ ["Rules.Statement.ManagedRuleGroupStatement.ExcludedRules", ["Name"]],
40197
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet", [
40198
+ "CreationPath",
40199
+ "RegistrationPagePath",
40200
+ "RequestInspection"
40201
+ ]],
40202
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.RequestInspection", ["PayloadType"]],
40203
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.RequestInspection.AddressFields", ["Identifier"]],
40204
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.RequestInspection.EmailField", ["Identifier"]],
40205
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.RequestInspection.PasswordField", ["Identifier"]],
40206
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.RequestInspection.PhoneNumberFields", ["Identifier"]],
40207
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.RequestInspection.UsernameField", ["Identifier"]],
40208
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.ResponseInspection.BodyContains", ["FailureStrings", "SuccessStrings"]],
40209
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.ResponseInspection.Header", [
40210
+ "FailureValues",
40211
+ "Name",
40212
+ "SuccessValues"
40213
+ ]],
40214
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.ResponseInspection.Json", [
40215
+ "FailureValues",
40216
+ "Identifier",
40217
+ "SuccessValues"
40218
+ ]],
40219
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesACFPRuleSet.ResponseInspection.StatusCode", ["FailureCodes", "SuccessCodes"]],
40220
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet", ["LoginPath"]],
40221
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet.RequestInspection", [
40222
+ "PasswordField",
40223
+ "PayloadType",
40224
+ "UsernameField"
40225
+ ]],
40226
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet.RequestInspection.PasswordField", ["Identifier"]],
40227
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet.RequestInspection.UsernameField", ["Identifier"]],
40228
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet.ResponseInspection.BodyContains", ["FailureStrings", "SuccessStrings"]],
40229
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet.ResponseInspection.Header", [
40230
+ "FailureValues",
40231
+ "Name",
40232
+ "SuccessValues"
40233
+ ]],
40234
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet.ResponseInspection.Json", [
40235
+ "FailureValues",
40236
+ "Identifier",
40237
+ "SuccessValues"
40238
+ ]],
40239
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesATPRuleSet.ResponseInspection.StatusCode", ["FailureCodes", "SuccessCodes"]],
40240
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesAntiDDoSRuleSet", ["ClientSideActionConfig"]],
40241
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesAntiDDoSRuleSet.ClientSideActionConfig", ["Challenge"]],
40242
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesAntiDDoSRuleSet.ClientSideActionConfig.Challenge", ["UsageOfAction"]],
40243
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.AWSManagedRulesBotControlRuleSet", ["InspectionLevel"]],
40244
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.PasswordField", ["Identifier"]],
40245
+ ["Rules.Statement.ManagedRuleGroupStatement.ManagedRuleGroupConfigs.UsernameField", ["Identifier"]],
40246
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides", ["ActionToUse", "Name"]],
40247
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Allow.CustomRequestHandling", ["InsertHeaders"]],
40248
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Allow.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40249
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Block.CustomResponse", ["ResponseCode"]],
40250
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Block.CustomResponse.ResponseHeaders", ["Name", "Value"]],
40251
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Captcha.CustomRequestHandling", ["InsertHeaders"]],
40252
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Captcha.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40253
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Challenge.CustomRequestHandling", ["InsertHeaders"]],
40254
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Challenge.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40255
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Count.CustomRequestHandling", ["InsertHeaders"]],
40256
+ ["Rules.Statement.ManagedRuleGroupStatement.RuleActionOverrides.ActionToUse.Count.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40257
+ ["Rules.Statement.NotStatement", ["Statement"]],
40258
+ ["Rules.Statement.OrStatement", ["Statements"]],
40259
+ ["Rules.Statement.RateBasedStatement", ["AggregateKeyType", "Limit"]],
40260
+ ["Rules.Statement.RateBasedStatement.CustomKeys.Cookie", ["Name", "TextTransformations"]],
40261
+ ["Rules.Statement.RateBasedStatement.CustomKeys.Cookie.TextTransformations", ["Priority", "Type"]],
40262
+ ["Rules.Statement.RateBasedStatement.CustomKeys.Header", ["Name", "TextTransformations"]],
40263
+ ["Rules.Statement.RateBasedStatement.CustomKeys.Header.TextTransformations", ["Priority", "Type"]],
40264
+ ["Rules.Statement.RateBasedStatement.CustomKeys.JA3Fingerprint", ["FallbackBehavior"]],
40265
+ ["Rules.Statement.RateBasedStatement.CustomKeys.JA4Fingerprint", ["FallbackBehavior"]],
40266
+ ["Rules.Statement.RateBasedStatement.CustomKeys.LabelNamespace", ["Namespace"]],
40267
+ ["Rules.Statement.RateBasedStatement.CustomKeys.QueryArgument", ["Name", "TextTransformations"]],
40268
+ ["Rules.Statement.RateBasedStatement.CustomKeys.QueryArgument.TextTransformations", ["Priority", "Type"]],
40269
+ ["Rules.Statement.RateBasedStatement.CustomKeys.QueryString", ["TextTransformations"]],
40270
+ ["Rules.Statement.RateBasedStatement.CustomKeys.QueryString.TextTransformations", ["Priority", "Type"]],
40271
+ ["Rules.Statement.RateBasedStatement.CustomKeys.UriPath", ["TextTransformations"]],
40272
+ ["Rules.Statement.RateBasedStatement.CustomKeys.UriPath.TextTransformations", ["Priority", "Type"]],
40273
+ ["Rules.Statement.RateBasedStatement.ForwardedIPConfig", ["FallbackBehavior", "HeaderName"]],
40274
+ ["Rules.Statement.RegexMatchStatement", [
40275
+ "FieldToMatch",
40276
+ "RegexString",
40277
+ "TextTransformations"
40278
+ ]],
40279
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.Cookies", [
40280
+ "MatchPattern",
40281
+ "MatchScope",
40282
+ "OversizeHandling"
40283
+ ]],
40284
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.HeaderOrder", ["OversizeHandling"]],
40285
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.Headers", [
40286
+ "MatchPattern",
40287
+ "MatchScope",
40288
+ "OversizeHandling"
40289
+ ]],
40290
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.JA3Fingerprint", ["FallbackBehavior"]],
40291
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.JA4Fingerprint", ["FallbackBehavior"]],
40292
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.JsonBody", ["MatchPattern", "MatchScope"]],
40293
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.SingleHeader", ["Name"]],
40294
+ ["Rules.Statement.RegexMatchStatement.FieldToMatch.SingleQueryArgument", ["Name"]],
40295
+ ["Rules.Statement.RegexMatchStatement.PreParseTextTransformations", ["Priority", "Type"]],
40296
+ ["Rules.Statement.RegexMatchStatement.TextTransformations", ["Priority", "Type"]],
40297
+ ["Rules.Statement.RegexPatternSetReferenceStatement", [
40298
+ "Arn",
40299
+ "FieldToMatch",
40300
+ "TextTransformations"
40301
+ ]],
40302
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.Cookies", [
40303
+ "MatchPattern",
40304
+ "MatchScope",
40305
+ "OversizeHandling"
40306
+ ]],
40307
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.HeaderOrder", ["OversizeHandling"]],
40308
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.Headers", [
40309
+ "MatchPattern",
40310
+ "MatchScope",
40311
+ "OversizeHandling"
40312
+ ]],
40313
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.JA3Fingerprint", ["FallbackBehavior"]],
40314
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.JA4Fingerprint", ["FallbackBehavior"]],
40315
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.JsonBody", ["MatchPattern", "MatchScope"]],
40316
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.SingleHeader", ["Name"]],
40317
+ ["Rules.Statement.RegexPatternSetReferenceStatement.FieldToMatch.SingleQueryArgument", ["Name"]],
40318
+ ["Rules.Statement.RegexPatternSetReferenceStatement.PreParseTextTransformations", ["Priority", "Type"]],
40319
+ ["Rules.Statement.RegexPatternSetReferenceStatement.TextTransformations", ["Priority", "Type"]],
40320
+ ["Rules.Statement.RuleGroupReferenceStatement", ["Arn"]],
40321
+ ["Rules.Statement.RuleGroupReferenceStatement.ExcludedRules", ["Name"]],
40322
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides", ["ActionToUse", "Name"]],
40323
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Allow.CustomRequestHandling", ["InsertHeaders"]],
40324
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Allow.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40325
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Block.CustomResponse", ["ResponseCode"]],
40326
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Block.CustomResponse.ResponseHeaders", ["Name", "Value"]],
40327
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Captcha.CustomRequestHandling", ["InsertHeaders"]],
40328
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Captcha.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40329
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Challenge.CustomRequestHandling", ["InsertHeaders"]],
40330
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Challenge.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40331
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Count.CustomRequestHandling", ["InsertHeaders"]],
40332
+ ["Rules.Statement.RuleGroupReferenceStatement.RuleActionOverrides.ActionToUse.Count.CustomRequestHandling.InsertHeaders", ["Name", "Value"]],
40333
+ ["Rules.Statement.SizeConstraintStatement", [
40334
+ "ComparisonOperator",
40335
+ "FieldToMatch",
40336
+ "Size",
40337
+ "TextTransformations"
40338
+ ]],
40339
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.Cookies", [
40340
+ "MatchPattern",
40341
+ "MatchScope",
40342
+ "OversizeHandling"
40343
+ ]],
40344
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.HeaderOrder", ["OversizeHandling"]],
40345
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.Headers", [
40346
+ "MatchPattern",
40347
+ "MatchScope",
40348
+ "OversizeHandling"
40349
+ ]],
40350
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.JA3Fingerprint", ["FallbackBehavior"]],
40351
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.JA4Fingerprint", ["FallbackBehavior"]],
40352
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.JsonBody", ["MatchPattern", "MatchScope"]],
40353
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.SingleHeader", ["Name"]],
40354
+ ["Rules.Statement.SizeConstraintStatement.FieldToMatch.SingleQueryArgument", ["Name"]],
40355
+ ["Rules.Statement.SizeConstraintStatement.PreParseTextTransformations", ["Priority", "Type"]],
40356
+ ["Rules.Statement.SizeConstraintStatement.TextTransformations", ["Priority", "Type"]],
40357
+ ["Rules.Statement.SqliMatchStatement", ["FieldToMatch", "TextTransformations"]],
40358
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.Cookies", [
40359
+ "MatchPattern",
40360
+ "MatchScope",
40361
+ "OversizeHandling"
40362
+ ]],
40363
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.HeaderOrder", ["OversizeHandling"]],
40364
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.Headers", [
40365
+ "MatchPattern",
40366
+ "MatchScope",
40367
+ "OversizeHandling"
40368
+ ]],
40369
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.JA3Fingerprint", ["FallbackBehavior"]],
40370
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.JA4Fingerprint", ["FallbackBehavior"]],
40371
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.JsonBody", ["MatchPattern", "MatchScope"]],
40372
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.SingleHeader", ["Name"]],
40373
+ ["Rules.Statement.SqliMatchStatement.FieldToMatch.SingleQueryArgument", ["Name"]],
40374
+ ["Rules.Statement.SqliMatchStatement.PreParseTextTransformations", ["Priority", "Type"]],
40375
+ ["Rules.Statement.SqliMatchStatement.TextTransformations", ["Priority", "Type"]],
40376
+ ["Rules.Statement.XssMatchStatement", ["FieldToMatch", "TextTransformations"]],
40377
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.Cookies", [
40378
+ "MatchPattern",
40379
+ "MatchScope",
40380
+ "OversizeHandling"
40381
+ ]],
40382
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.HeaderOrder", ["OversizeHandling"]],
40383
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.Headers", [
40384
+ "MatchPattern",
40385
+ "MatchScope",
40386
+ "OversizeHandling"
40387
+ ]],
40388
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.JA3Fingerprint", ["FallbackBehavior"]],
40389
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.JA4Fingerprint", ["FallbackBehavior"]],
40390
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.JsonBody", ["MatchPattern", "MatchScope"]],
40391
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.SingleHeader", ["Name"]],
40392
+ ["Rules.Statement.XssMatchStatement.FieldToMatch.SingleQueryArgument", ["Name"]],
40393
+ ["Rules.Statement.XssMatchStatement.PreParseTextTransformations", ["Priority", "Type"]],
40394
+ ["Rules.Statement.XssMatchStatement.TextTransformations", ["Priority", "Type"]],
40395
+ ["Rules.VisibilityConfig", [
40396
+ "CloudWatchMetricsEnabled",
40397
+ "MetricName",
40398
+ "SampledRequestsEnabled"
40399
+ ]],
40400
+ ["VisibilityConfig", [
40401
+ "CloudWatchMetricsEnabled",
40402
+ "MetricName",
40403
+ "SampledRequestsEnabled"
40404
+ ]]
40405
+ ])]
40406
+ ]);
40407
+
40408
+ //#endregion
40409
+ //#region src/provisioning/nested-required.ts
40410
+ /**
40411
+ * Pre-flight rule: a PRESENT nested property block must carry every member its
40412
+ * schema definition lists as `required` (issue
40413
+ * [#1802](https://github.com/go-to-k/cdkd/issues/1802)).
40414
+ *
40415
+ * CloudFormation refuses such a block before it touches AWS. cdkd forwarded
40416
+ * it, and where the service API replaces the nested struct wholesale the
40417
+ * result was a silent change to a live setting: a kept
40418
+ * `AWS::ECS::Service.DeploymentConfiguration.DeploymentCircuitBreaker` without
40419
+ * `Rollback` flipped the live `rollback` from true to false. Cloud Control
40420
+ * validates against the same schema server-side, so the gap is SDK-provider
40421
+ * scoped; running the check for every resource is correct-but-redundant on the
40422
+ * Cloud Control route. Same layer and same reasons as
40423
+ * {@link ./mutually-exclusive-properties}: pre-flight runs on every deploy, not
40424
+ * only when the provider is called.
40425
+ *
40426
+ * ## Refuse only what CloudFormation refuses
40427
+ *
40428
+ * - An ABSENT block is never a violation — only a present one missing a member.
40429
+ * - Pre-flight runs BEFORE intrinsic resolution, so any value along the path
40430
+ * that is an unresolved intrinsic (`Fn::If`, `Ref`, ...) is UNKNOWN and its
40431
+ * subtree is skipped. A member is present when its KEY is, whatever the value
40432
+ * (`false`, `0`, `null`, or an intrinsic that may resolve to
40433
+ * `AWS::NoValue`). Every doubt passes through: a false refusal blocks a valid
40434
+ * deploy with no escape hatch, a missed one reaches AWS as it did before.
40435
+ * - {@link CFN_ENFORCED_TYPES} gates the whole check. A schema's `required`
40436
+ * list is NOT evidence that CloudFormation enforces it: measured, CFn accepted
40437
+ * an `AWS::Logs::LogGroup` tag with neither `Key` nor `Value`, and sent an
40438
+ * `AWS::EC2::SecurityGroup` ingress rule without `IpProtocol` to the EC2 API.
40439
+ *
40440
+ * ## No override flag, by design
40441
+ *
40442
+ * The violation is in the TEMPLATE, CloudFormation rejects it too, and the
40443
+ * remedy (declare the missing member) is always available.
40444
+ */
40445
+ /**
40446
+ * Types whose nested `required` lists CloudFormation was MEASURED to enforce.
40447
+ * One template per type declared
40448
+ * every nested block of `NESTED_REQUIRED` empty; a type is listed only when
40449
+ * CloudFormation refused EVERY missing member the table predicts:
40450
+ *
40451
+ * - 64 types by early validation of a CREATE change set (nothing provisioned):
40452
+ * `PROPERTY_VALIDATION` / "Required property [X] not found".
40453
+ * - 7 types early validation passed, refused at execution before any API call:
40454
+ * `Model validation failed` / `Properties validation failed` /
40455
+ * `Property validation failure` (ECS Service + TaskDefinition, EFS
40456
+ * AccessPoint, Lambda EventSourceMapping, Step Functions StateMachine,
40457
+ * API Gateway Method, AppSync GraphQLApi).
40458
+ * - 7 types with no registry handler, refused at execution by CloudFormation's
40459
+ * own `Property validation failure` list (Budgets Budget, CloudWatch
40460
+ * AnomalyDetector, CodeBuild Project, DocDB DBCluster + DBInstance, FSx
40461
+ * FileSystem, Glue Table).
40462
+ *
40463
+ * Measured NOT enforced by a schema check (a handler or service error instead,
40464
+ * or an accepted create): ApiGatewayV2 Route, CloudFormation Stack, EC2
40465
+ * SecurityGroup, ECR Repository, EFS FileSystem, ELBv2 Listener, KMS Key,
40466
+ * KinesisFirehose DeliveryStream, Logs LogGroup, Route53 HostedZone, WAFv2
40467
+ * WebACL. Left out because CloudFormation reports only the FIRST missing member
40468
+ * (`Property X cannot be empty.`), so the rest of the table was not confirmed:
40469
+ * EMR Cluster, InstanceFleetConfig, InstanceGroupConfig. A type in none of
40470
+ * these lists (added later) is not checked until it is measured.
40471
+ */
40472
+ const CFN_ENFORCED_TYPES = /* @__PURE__ */ new Set([
40473
+ "AWS::ApiGateway::Deployment",
40474
+ "AWS::ApiGateway::Method",
40475
+ "AWS::ApiGateway::Stage",
40476
+ "AWS::AppSync::DataSource",
40477
+ "AWS::AppSync::GraphQLApi",
40478
+ "AWS::AppSync::Resolver",
40479
+ "AWS::AutoScaling::AutoScalingGroup",
40480
+ "AWS::BedrockAgentCore::Evaluator",
40481
+ "AWS::BedrockAgentCore::Runtime",
40482
+ "AWS::Budgets::Budget",
40483
+ "AWS::CertificateManager::Certificate",
40484
+ "AWS::CloudFront::CloudFrontOriginAccessIdentity",
40485
+ "AWS::CloudFront::Distribution",
40486
+ "AWS::CloudFront::OriginAccessControl",
40487
+ "AWS::CloudTrail::Trail",
40488
+ "AWS::CloudWatch::Alarm",
40489
+ "AWS::CloudWatch::AnomalyDetector",
40490
+ "AWS::CodeBuild::Project",
40491
+ "AWS::CodeCommit::Repository",
40492
+ "AWS::Cognito::UserPool",
40493
+ "AWS::DLM::LifecyclePolicy",
40494
+ "AWS::DocDB::DBCluster",
40495
+ "AWS::DocDB::DBInstance",
40496
+ "AWS::DocDB::DBSubnetGroup",
40497
+ "AWS::DynamoDB::GlobalTable",
40498
+ "AWS::DynamoDB::Table",
40499
+ "AWS::EC2::EIP",
40500
+ "AWS::EC2::Instance",
40501
+ "AWS::EC2::InternetGateway",
40502
+ "AWS::EC2::NatGateway",
40503
+ "AWS::EC2::NetworkAcl",
40504
+ "AWS::EC2::RouteTable",
40505
+ "AWS::EC2::Subnet",
40506
+ "AWS::EC2::VPC",
40507
+ "AWS::ECS::Service",
40508
+ "AWS::ECS::TaskDefinition",
40509
+ "AWS::EFS::AccessPoint",
40510
+ "AWS::ElastiCache::CacheCluster",
40511
+ "AWS::ElastiCache::SubnetGroup",
40512
+ "AWS::ElasticLoadBalancingV2::LoadBalancer",
40513
+ "AWS::ElasticLoadBalancingV2::TargetGroup",
40514
+ "AWS::Events::EventBus",
40515
+ "AWS::Events::Rule",
40516
+ "AWS::FSx::FileSystem",
40517
+ "AWS::Glue::Connection",
40518
+ "AWS::Glue::Table",
40519
+ "AWS::Glue::Trigger",
40520
+ "AWS::IAM::Group",
40521
+ "AWS::IAM::Role",
40522
+ "AWS::IAM::User",
40523
+ "AWS::Kinesis::Stream",
40524
+ "AWS::Kinesis::StreamConsumer",
40525
+ "AWS::Lambda::EventInvokeConfig",
40526
+ "AWS::Lambda::EventSourceMapping",
40527
+ "AWS::Lambda::Function",
40528
+ "AWS::Lambda::LayerVersion",
40529
+ "AWS::Lambda::MicrovmImage",
40530
+ "AWS::Neptune::DBCluster",
40531
+ "AWS::Neptune::DBInstance",
40532
+ "AWS::Neptune::DBSubnetGroup",
40533
+ "AWS::RDS::DBCluster",
40534
+ "AWS::RDS::DBInstance",
40535
+ "AWS::RDS::DBSubnetGroup",
40536
+ "AWS::Route53::RecordSet",
40537
+ "AWS::S3::Bucket",
40538
+ "AWS::S3Express::DirectoryBucket",
40539
+ "AWS::S3Tables::Table",
40540
+ "AWS::S3Tables::TableBucket",
40541
+ "AWS::S3Vectors::VectorBucket",
40542
+ "AWS::SNS::Topic",
40543
+ "AWS::SQS::Queue",
40544
+ "AWS::Scheduler::Schedule",
40545
+ "AWS::SecretsManager::Secret",
40546
+ "AWS::ServiceDiscovery::HttpNamespace",
40547
+ "AWS::ServiceDiscovery::PrivateDnsNamespace",
40548
+ "AWS::ServiceDiscovery::PublicDnsNamespace",
40549
+ "AWS::ServiceDiscovery::Service",
40550
+ "AWS::StepFunctions::StateMachine"
40551
+ ]);
40552
+ /**
40553
+ * True for a single-key object whose key is `Ref` or `Fn::*`. The same
40554
+ * predicate as `mutually-exclusive-properties.ts` keeps local, for the same
40555
+ * reason: the modules answer different questions about the shape.
40556
+ */
40557
+ function isUnresolvedIntrinsic(value) {
40558
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
40559
+ const keys = Object.keys(value);
40560
+ return keys.length === 1 && (keys[0] === "Ref" || keys[0].startsWith("Fn::"));
40561
+ }
40562
+ /** A plain object whose members can be checked: not an array, not an intrinsic. */
40563
+ function isConcreteObject(value) {
40564
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !isUnresolvedIntrinsic(value);
40565
+ }
40566
+ /**
40567
+ * Find every present nested block of this resource that lacks a required
40568
+ * member. `table` defaults to the generated one gated by
40569
+ * {@link CFN_ENFORCED_TYPES}; tests pass their own to reach every shape.
40570
+ */
40571
+ function findNestedRequiredViolations(resourceType, templateProperties, table = CFN_ENFORCED_TYPES.has(resourceType) ? NESTED_REQUIRED.get(resourceType) : void 0) {
40572
+ if (!table || !isConcreteObject(templateProperties)) return [];
40573
+ const violations = [];
40574
+ for (const [path, required] of table) {
40575
+ const segments = path.split(".");
40576
+ const check = (value, display) => {
40577
+ if (Array.isArray(value)) {
40578
+ value.forEach((element, i) => check(element, `${display}[${i}]`));
40579
+ return;
40580
+ }
40581
+ if (!isConcreteObject(value)) return;
40582
+ const missing = required.filter((member) => !hasOwnKey(value, member));
40583
+ if (missing.length > 0) violations.push({
40584
+ resourceType,
40585
+ path: display,
40586
+ missing
40587
+ });
40588
+ };
40589
+ const visit = (value, depth, display) => {
40590
+ if (depth === segments.length) {
40591
+ check(value, display);
40592
+ return;
40593
+ }
40594
+ if (Array.isArray(value)) {
40595
+ value.forEach((element, i) => visit(element, depth, `${display}[${i}]`));
40596
+ return;
40597
+ }
40598
+ if (!isConcreteObject(value)) return;
40599
+ const segment = segments[depth];
40600
+ if (!hasOwnKey(value, segment)) return;
40601
+ visit(value[segment], depth + 1, display ? `${display}.${segment}` : segment);
40602
+ };
40603
+ visit(templateProperties, 0, "");
40604
+ }
40605
+ return violations;
40606
+ }
40607
+ /** Render one violation as a per-resource error line. */
40608
+ function buildNestedRequiredMessage(logicalId, violation) {
40609
+ return ` - ${logicalId} (${violation.resourceType}): ${violation.path} is missing required ${violation.missing.length === 1 ? "member" : "members"} ${violation.missing.join(", ")}`;
40610
+ }
40611
+
38680
40612
  //#endregion
38681
40613
  //#region src/provisioning/provider-registry.ts
38682
40614
  /**
@@ -39003,7 +40935,10 @@ var ProviderRegistry = class {
39003
40935
  * ALSO runs the mutually-exclusive-property check
39004
40936
  * ({@link validateMutuallyExclusiveProperties}), which throws BEFORE any
39005
40937
  * routing decision is logged — a template CloudFormation itself rejects
39006
- * should not first produce a page of routing chatter.
40938
+ * should not first produce a page of routing chatter. Issue
40939
+ * [#1802](https://github.com/go-to-k/cdkd/issues/1802) adds the nested
40940
+ * `required` check ({@link validateNestedRequiredProperties}) at the same
40941
+ * point, for the same reason.
39007
40942
  *
39008
40943
  * @see findAutoRouteHits for the pure-functional pre-deploy plan-builder
39009
40944
  * that returns the same information without logging.
@@ -39011,6 +40946,7 @@ var ProviderRegistry = class {
39011
40946
  validateResourceProperties(resources) {
39012
40947
  const materialized = [...resources];
39013
40948
  this.validateMutuallyExclusiveProperties(materialized);
40949
+ this.validateNestedRequiredProperties(materialized);
39014
40950
  this.reportSilentDropDecisions(materialized);
39015
40951
  }
39016
40952
  /**
@@ -39036,6 +40972,23 @@ var ProviderRegistry = class {
39036
40972
  throw new Error(`The following resources declare mutually exclusive properties:\n` + lines.join("\n") + "\n\nCloudFormation rejects these combinations too — edit the template to declare only one of each set.");
39037
40973
  }
39038
40974
  /**
40975
+ * Reject a template whose PRESENT nested property block lacks a member the
40976
+ * type's schema requires there, for the types CloudFormation was measured to
40977
+ * enforce that on (issue [#1802](https://github.com/go-to-k/cdkd/issues/1802);
40978
+ * the rule, its fail-safe bias and the measurement live in
40979
+ * `nested-required.ts`).
40980
+ *
40981
+ * Aggregated into ONE error, like {@link validateMutuallyExclusiveProperties},
40982
+ * and with no `--allow-*` escape hatch for the same reason: CloudFormation
40983
+ * rejects the template too, and declaring the member is always possible.
40984
+ */
40985
+ validateNestedRequiredProperties(resources) {
40986
+ const lines = [];
40987
+ for (const { logicalId, resourceType, properties } of resources) for (const violation of findNestedRequiredViolations(resourceType, properties)) lines.push(buildNestedRequiredMessage(logicalId, violation));
40988
+ if (lines.length === 0) return;
40989
+ throw new Error(`The following resources declare a nested property block without a member it requires:\n` + lines.join("\n") + "\n\nCloudFormation rejects these blocks too. Declare the missing members; leaving a whole block out is not a violation.");
40990
+ }
40991
+ /**
39039
40992
  * Info-log every silent-drop routing decision (auto-route via CC API) and
39040
40993
  * warn-log every silent drop the user explicitly opted into via
39041
40994
  * `--allow-unsupported-properties` (forced SDK path, the property will
@@ -48884,5 +50837,5 @@ var DeployEngine = class DeployEngine {
48884
50837
  };
48885
50838
 
48886
50839
  //#endregion
48887
- export { yellow as $, derivePartitionAndUrlSuffix as $i, safeStackName as $n, assertAssetBucketRegion as $r, requireConfigObject as $t, createPreDeleteFinalSnapshot as A, PartialFailureError as Aa, resolveAutoAssetStorage as Ai, malformedOutputsRefusalMessage as An, formatLockExpiry as Ar, carriesDynamicReference as At, isStatefulRecreateTargetSync as B, normalizeAwsError as Ba, CFN_TEMPLATE_URL_LIMIT as Bi, refuseMalformedOrphansForDestroy as Bn, isReadableBag as Br, isSettledInstanceState as Bt, namesAnyDeclaredParameter as C, DynamicReferenceRegionAmbiguousError as Ca, AssetManifestLoader as Ci, isReadableResourceEntry as Cn, LockManager as Cr, slowCcOperationTimeoutMs as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, LockError as Da, getDefaultStateBucketName as Di, malformedOrphanRecordsWarning as Dn, buildForceUnlockCommand as Dr, disableInstanceApiTermination as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, LocalStartServiceError as Ea, synthesisStatusMessage as Ei, malformedLocalOutputsWarning as En, UNREPRODUCIBLE_LOCK_CLAUSE as Er, deleteSkipReason as Et, extractDeploymentEventError as F, StackTerminationProtectionError as Fa, resolveUseCdkBootstrapAssets as Fi, malformedResourcesWarning as Fn, hasReadableExportSet as Fr, isImpossibleEmptyStoredAttribute as Ft, toCfnInteger as G, isTransientServerError as Ga, injectiveKey as Gi, refuseMalformedResourcesForDestroy as Gn, stringifyValue as Gr, coerceCfnBoolean as Gt, WARM_THROUGHPUT_MEMBERS as H, isMarkedNonRetryable as Ha, findLargeInlineResources as Hi, refuseMalformedOutputsForDestroy as Hn, orphansCarriedFrom as Hr, normalizeAwsTagsToCfn as Ht, makeSiblingClaimReader as I, StateError as Ia, stateBucketExistenceConfirmed as Ii, malformedStateRefusalMessage as In, hasReasonlessBaselineRefusal as Ir, isNamelessDynamicReferenceError as It, bold as J, retryClassificationText as Ja, producerRecordKey as Ji, repairMalformedOutputsForReadOnly as Jn, createAssetRedirectResolver as Jr, configIntegerRefusal as Jt, toFiniteNumber as K, markNonRetryable as Ka, injectiveKeyPrefix as Ki, refuseMalformedState as Kn, WorkGraph as Kr, coerceCfnInteger as Kt, planOrphanAdoption as L, SynthesisError as La, warnDeprecatedNoPrefixCliFlag as Li, refuseDivergentRecordRegionForDestroy as Ln, hasUnverifiableParameterRefusal as Lr, isUnboundTemplateParameter as Lt, refusesFinalSnapshot as M, ResourceTimeoutError as Ma, resolveSkipPrefix as Mi, malformedRenderedContainersWarning as Mn, CUSTOM_RESOURCE_RESPONSE_PREFIX as Mr, cfnRefValueFromPhysicalId as Mt, unsupportedFinalSnapshotError as N, ResourceUpdateNotSupportedError as Na, resolveStateBucketWithDefault as Ni, malformedResourceEntriesWarning as Nn, DEFAULT_STATE_PREFIX as Nr, coerceParameterTypedValue as Nt, buildFinalSnapshotIdentifier as O, MalformedProducerRecordRefusalError as Oa, getLegacyStateBucketName as Oi, malformedOrphansRefusalMessage as On, buildLockContentionMessage as Or, isTerminationProtectionPropagationError as Ot, makeCanonicalizePropertiesFn as P, StackHasActiveImportsError as Pa, resolveStateBucketWithDefaultAndSource as Pi, malformedResourcePropertiesWarning as Pn, exportNamesCarriedFrom as Pr, getAccountInfo as Pt, red as Q, canonicalizeRegion as Qi, safeRegion as Qn, BOOTSTRAP_MARKER_PREFIX as Qr, requireConfigArray as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, formatError as Ra, ssmResolvedValueType as Ri, refuseMalformedNestedChildOutputs as Rn, importableOutputKeys as Rr, parameterTypeMayLoseSecretIdentity as Rt, computeParameterTaint as S, DeployCancelledError as Sa, stripControlChars as Si, hasReadableResources as Sn, scrubResourceRecord as Sr, isWaitAbandonedError as St, resourcesNamingDeclaredParameter as T, LocalInvokeBuildError as Ta, Synthesizer as Ti, malformedExportSourceWarning as Tn, rebuildClientForBucketRegion as Tr, deleteIndeterminateGuards as Tt, coerceWarmThroughput as U, isRetryableTransientError as Ua, uploadCfnTemplate as Ui, refuseMalformedResourceEntries as Un, shouldRetainResource as Ur, resolveExplicitPhysicalId as Ut, renderStatefulReason as V, withErrorHandling as Va, MIGRATE_TMP_PREFIX as Vi, refuseMalformedOutputs as Vn, orphansAfterRollback as Vr, WAFv2WebACLProvider as Vt, isWarmThroughputDecrease as W, isThrottlingError as Wa, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Wi, refuseMalformedResourcePropertiesForOrphan as Wn, AssetPublisher as Wr, assertRegionMatch as Wt, gray as X, safeStringify$1 as Xa, expectedOwnerParam as Xi, repairMalformedResourcePropertiesForReadOnly as Xn, rewriteTemplateAssetReferences as Xr, readConfigString as Xt, cyan as Y, describeAwsFailure as Ya, decodeListingKey as Yi, repairMalformedResourceEntriesForReadOnly as Yn, loadPublishableAssetManifest as Yr, configStringRefusal as Yt, green as Z, __exportAll as Za, PARTITION_TABLE as Zi, repairMalformedResourcesForReadOnly as Zn, AssetModeResolver as Zr, replayWarn as Zt, bagHoldsSecretExpression as _, AssetError as _a, partitionSensitiveEnv as _i, UNREADABLE_ORPHANS_CONTAINER_ROW as _n, maskSecretsInError as _r, endCommandInterruptScope as _t, DeploymentEventsStore as a, hasPlainPrototype$1 as aa, validateAssetBucketName as ai, s3BucketDomainName as an, TemplateParser as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, CrossAccountSecretRefusalError as ba, runDockerStreaming as bi, hasReadableOrphans as bn, recoverMaskedOutput as br, startInterruptWatch as bt, replayFailedOperations as c, absoluteAssemblyPathEscape as ca, buildDockerImage as ci, s3BucketWebsiteUrl as cn, STATE_SOURCED_READBACK_RULES as cr, IAMRoleProvider as ct, updatePartialMessage as d, clearBucketRegionCache as da, describeDockerCapturedOutput as di, applyCallerIdentityCredentials as dn, createSecretMasker as dr, ProviderRegistry as dt, AssemblyReader as ea, ensureAssetStorage as ei, requireConfigString as en, findActionableSilentDrops as er, collectDeclaredOutputNames as et, updatePartialReason as f, resolveBucketRegion as fa, describeDockerExecFailure as fi, callerEnvCredentials as fn, dynamicReferenceTokens as fr, wouldReturnToSdkProvider as ft, computeImplicitDeleteEdges as g, setAwsClients as ga, getDockerCmd as gi, STATE_RESOURCES_MALFORMED as gn, markSameGenerationBag as gr, beginCommandInterruptScope as gt, IMPLICIT_DELETE_DEPENDENCIES as h, resetAwsClients as ha, formatDockerLoginError as hi, INTRINSIC_KEYS as hn, isSingleDynamicReferenceToken as hr, maskerOrIdentity as ht, DeploymentEventsReader as i, hasOwnKey as ia, readBootstrapMarkerBody as ii, s3BucketArn as in, DagBuilder as ir, secretBearing as it, isFinalSnapshotError as j, ProvisioningError as ja, resolveCaptureObservedState as ji, malformedOutputsWarning as jn, shellQuote as jr, carriesFetchableDynamicReference as jt, ccRoutedFinalSnapshotError as k, NestedStackChildDirectDestroyError as ka, resolveApp as ki, malformedOrphansWarning as kn, forceQuitRecoveryClause as kr, IntrinsicFunctionResolver as kt, replayRollback as l, renderAssemblyPathEscape as la, resolveDockerContextDirectory as li, applyRoleArnIfSet as ln, TEMPLATE_SOURCED_RULES as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, getAwsClients as ma, dockerSpawnEnvWithSensitive as mi, DiffCalculator as mn, identityKeyFor as mr, maskDeep as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, processStackMessages as na, isCrossRegionRedirect as ni, producerRegionsFromState as nn, describeTypeWithThrottleRetry as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, nullPrototypeRecord as oa, validateContainerRepoName as oi, s3BucketDualStackDomainName as on, STATE_SOURCED_BASELINE_RULES as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, AwsClients as pa, describeDockerFailure as pi, envCredentialsAreAssumedRole as pn, errorCauseChain as pr, createMaskedRetryLogger as pt, formatResourceLine as q, markRedactedCause as qa, producerCoordinateKey as qi, repairMalformedOrphansForReadOnly as qn, buildAssetRedirectMap as qr, configBooleanRefusal as qt, DeployEngine as r, defineOwnKey as ra, parseBootstrapMarker as ri, withSharedDrainBudget as rn, withRetry as rr, isExportAliasCollision as rt, planRollback as s, ownValue as sa, buildDenyExternalAccessPolicy as si, s3BucketRegionalDomainName as sn, STATE_SOURCED_CROSS_GENERATION_RULES as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, failedStageNote as ta, getBootstrapMarkerKey as ti, classifyReplaySecretRegion as tn, findSilentDropProperties as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, resolveAssemblyPath as ua, warnManifestExecutable as ui, AWS_CREDENTIAL_ENV_KEYS as un, carriesSecretMask as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, CdkdError as va, redactDockerArgvValues as vi, UNREADABLE_RESOURCES_MAP_ROW as vn, maskSecretsInText as vr, interruptWatchListenerCount as vt, reachableDivergentParameters as w, IntrinsicResolutionRefusalError as wa, getDockerImageBySourceHash as wi, malformedExportNamesWarning as wn, S3StateBackend as wr, UNSPECIFIED_SKIP_REASON as wt, bindingSkippedOutputs as x, DependencyError as xa, escapeRegExp$1 as xi, hasReadableOutputs as xn, redactSecretsForState as xr, CloudControlProvider as xt, keptWholeReasonText as y, ConfigError as ya, runDockerForeground as yi, displayLogicalId as yn, recordMaskOnlyValue as yr, isInterruptedWaitError as yt, isStatefulRecreateTargetForReplace as z, isCdkdError as za, CFN_TEMPLATE_BODY_LIMIT as zi, refuseMalformedOrphans as zn, importableOutputs as zr, refStateLookupFromResource as zt };
48888
- //# sourceMappingURL=deploy-engine-5fdODHji.js.map
50840
+ export { yellow as $, retryClassificationText as $a, expectedOwnerParam as $i, repairMalformedResourcePropertiesForReadOnly as $n, rewriteTemplateAssetReferences as $r, requireConfigObject as $t, createPreDeleteFinalSnapshot as A, LocalInvokeBuildError as Aa, getDefaultStateBucketName as Ai, malformedOutputsRefusalMessage as An, buildForceUnlockCommand as Ar, carriesDynamicReference as At, isStatefulRecreateTargetSync as B, StackTerminationProtectionError as Ba, warnDeprecatedNoPrefixCliFlag as Bi, refuseMalformedOrphansForDestroy as Bn, hasUnverifiableParameterRefusal as Br, isSettledInstanceState as Bt, namesAnyDeclaredParameter as C, CdkdError as Ca, runDockerStreaming as Ci, isReadableResourceEntry as Cn, recoverMaskedOutput as Cr, slowCcOperationTimeoutMs as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, DeployCancelledError as Da, getDockerImageBySourceHash as Di, malformedOrphanRecordsWarning as Dn, S3StateBackend as Dr, disableInstanceApiTermination as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, DependencyError as Ea, AssetManifestLoader as Ei, malformedLocalOutputsWarning as En, LockManager as Er, deleteSkipReason as Et, extractDeploymentEventError as F, PartialFailureError as Fa, resolveSkipPrefix as Fi, malformedResourcesWarning as Fn, CUSTOM_RESOURCE_RESPONSE_PREFIX as Fr, isImpossibleEmptyStoredAttribute as Ft, toCfnInteger as G, normalizeAwsError as Ga, findLargeInlineResources as Gi, refuseMalformedResourceEntries as Gn, orphansCarriedFrom as Gr, coerceCfnBoolean as Gt, WARM_THROUGHPUT_MEMBERS as H, SynthesisError as Ha, CFN_TEMPLATE_BODY_LIMIT as Hi, refuseMalformedOutputs as Hn, importableOutputs as Hr, normalizeAwsTagsToCfn as Ht, makeSiblingClaimReader as I, ProvisioningError as Ia, resolveStateBucketWithDefault as Ii, malformedStateRefusalMessage as In, DEFAULT_STATE_PREFIX as Ir, isNamelessDynamicReferenceError as It, bold as J, isRetryableTransientError as Ja, injectiveKey as Ji, refuseMalformedResourcesForDestroy as Jn, stringifyValue as Jr, configIntegerRefusal as Jt, toFiniteNumber as K, withErrorHandling as Ka, uploadCfnTemplate as Ki, refuseMalformedResourceEntriesForOrphan as Kn, shouldRetainResource as Kr, coerceCfnInteger as Kt, planOrphanAdoption as L, ResourceTimeoutError as La, resolveStateBucketWithDefaultAndSource as Li, refuseDivergentRecordRegionForDestroy as Ln, exportNamesCarriedFrom as Lr, isUnboundTemplateParameter as Lt, refusesFinalSnapshot as M, LockError as Ma, resolveApp as Mi, malformedRenderedContainersWarning as Mn, forceQuitRecoveryClause as Mr, cfnRefValueFromPhysicalId as Mt, unsupportedFinalSnapshotError as N, MalformedProducerRecordRefusalError as Na, resolveAutoAssetStorage as Ni, malformedResourceEntriesWarning as Nn, formatLockExpiry as Nr, coerceParameterTypedValue as Nt, buildFinalSnapshotIdentifier as O, DynamicReferenceRegionAmbiguousError as Oa, Synthesizer as Oi, malformedOrphansRefusalMessage as On, rebuildClientForBucketRegion as Or, isTerminationProtectionPropagationError as Ot, makeCanonicalizePropertiesFn as P, NestedStackChildDirectDestroyError as Pa, resolveCaptureObservedState as Pi, malformedResourcePropertiesWarning as Pn, shellQuote as Pr, getAccountInfo as Pt, red as Q, markRedactedCause as Qa, decodeListingKey as Qi, repairMalformedResourceEntriesForReadOnly as Qn, loadPublishableAssetManifest as Qr, requireConfigArray as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, ResourceUpdateNotSupportedError as Ra, resolveUseCdkBootstrapAssets as Ri, refuseMalformedNestedChildOutputs as Rn, hasReadableExportSet as Rr, parameterTypeMayLoseSecretIdentity as Rt, computeParameterTaint as S, AssetError as Sa, runDockerForeground as Si, hasReadableResources as Sn, recordMaskOnlyValue as Sr, isWaitAbandonedError as St, resourcesNamingDeclaredParameter as T, CrossAccountSecretRefusalError as Ta, stripControlChars as Ti, malformedExportSourceWarning as Tn, scrubResourceRecord as Tr, deleteIndeterminateGuards as Tt, coerceWarmThroughput as U, formatError as Ua, CFN_TEMPLATE_URL_LIMIT as Ui, refuseMalformedOutputsForDestroy as Un, isReadableBag as Ur, resolveExplicitPhysicalId as Ut, renderStatefulReason as V, StateError as Va, ssmResolvedValueType as Vi, refuseMalformedOrphansForOrphan as Vn, importableOutputKeys as Vr, WAFv2WebACLProvider as Vt, isWarmThroughputDecrease as W, isCdkdError as Wa, MIGRATE_TMP_PREFIX as Wi, refuseMalformedResourceAttributesForOrphan as Wn, orphansAfterRollback as Wr, assertRegionMatch as Wt, gray as X, isTransientServerError as Xa, producerCoordinateKey as Xi, repairMalformedOrphansForReadOnly as Xn, buildAssetRedirectMap as Xr, readConfigString as Xt, cyan as Y, isThrottlingError as Ya, injectiveKeyPrefix as Yi, refuseMalformedState as Yn, WorkGraph as Yr, configStringRefusal as Yt, green as Z, markNonRetryable as Za, producerRecordKey as Zi, repairMalformedOutputsForReadOnly as Zn, createAssetRedirectResolver as Zr, replayWarn as Zt, bagHoldsSecretExpression as _, AwsClients as _a, dockerSpawnEnvWithSensitive as _i, UNREADABLE_ORPHANS_CONTAINER_ROW as _n, identityKeyFor as _r, endCommandInterruptScope as _t, DeploymentEventsStore as a, globMatches as aa, isCrossRegionRedirect as ai, s3BucketDomainName as an, describeTypeWithThrottleRetry as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, runWithStackAwsClients as ba, partitionSensitiveEnv as bi, hasReadableOrphans as bn, maskSecretsInError as br, startInterruptWatch as bt, replayFailedOperations as c, hasOwnKey as ca, validateAssetBucketName as ci, s3BucketWebsiteUrl as cn, TemplateParser as cr, IAMRoleProvider as ct, updatePartialMessage as d, ownValue as da, buildDockerImage as di, applyCallerIdentityCredentials as dn, STATE_SOURCED_READBACK_RULES as dr, ProviderRegistry as dt, PARTITION_TABLE as ea, AssetModeResolver as ei, requireConfigString as en, describeAwsFailure as eo, repairMalformedResourcesForReadOnly as er, collectDeclaredOutputNames as et, updatePartialReason as f, absoluteAssemblyPathEscape as fa, resolveDockerContextDirectory as fi, callerEnvCredentials as fn, TEMPLATE_SOURCED_RULES as fr, wouldReturnToSdkProvider as ft, computeImplicitDeleteEdges as g, resolveBucketRegion as ga, describeDockerFailure as gi, STATE_RESOURCES_MALFORMED as gn, errorCauseChain as gr, beginCommandInterruptScope as gt, IMPLICIT_DELETE_DEPENDENCIES as h, clearBucketRegionCache as ha, describeDockerExecFailure as hi, INTRINSIC_KEYS as hn, dynamicReferenceTokens as hr, maskerOrIdentity as ht, DeploymentEventsReader as i, failedStageNote as ia, getBootstrapMarkerKey as ii, s3BucketArn as in, findSilentDropProperties as ir, secretBearing as it, isFinalSnapshotError as j, LocalStartServiceError as ja, getLegacyStateBucketName as ji, malformedOutputsWarning as jn, buildLockContentionMessage as jr, carriesFetchableDynamicReference as jt, ccRoutedFinalSnapshotError as k, IntrinsicResolutionRefusalError as ka, synthesisStatusMessage as ki, malformedOrphansWarning as kn, UNREPRODUCIBLE_LOCK_CLAUSE as kr, IntrinsicFunctionResolver as kt, replayRollback as l, hasPlainPrototype$1 as la, validateContainerRepoName as li, applyRoleArnIfSet as ln, STATE_SOURCED_BASELINE_RULES as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, resolveAssemblyPath as ma, describeDockerCapturedOutput as mi, DiffCalculator as mn, createSecretMasker as mr, maskDeep as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, derivePartitionAndUrlSuffix as na, assertAssetBucketRegion as ni, producerRegionsFromState as nn, __exportAll as no, safeStackName as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, processStackMessages as oa, parseBootstrapMarker as oi, s3BucketDualStackDomainName as on, withRetry as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, renderAssemblyPathEscape as pa, warnManifestExecutable as pi, envCredentialsAreAssumedRole as pn, carriesSecretMask as pr, createMaskedRetryLogger as pt, formatResourceLine as q, isMarkedNonRetryable as qa, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as qi, refuseMalformedResourcePropertiesForOrphan as qn, AssetPublisher as qr, configBooleanRefusal as qt, DeployEngine as r, AssemblyReader as ra, ensureAssetStorage as ri, withSharedDrainBudget as rn, findActionableSilentDrops as rr, isExportAliasCollision as rt, planRollback as s, defineOwnKey as sa, readBootstrapMarkerBody as si, s3BucketRegionalDomainName as sn, DagBuilder as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, canonicalizeRegion as ta, BOOTSTRAP_MARKER_PREFIX as ti, classifyReplaySecretRegion as tn, safeStringify$1 as to, safeRegion as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, nullPrototypeRecord as ua, buildDenyExternalAccessPolicy as ui, AWS_CREDENTIAL_ENV_KEYS as un, STATE_SOURCED_CROSS_GENERATION_RULES as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, getAwsClients as va, formatDockerLoginError as vi, UNREADABLE_RESOURCES_MAP_ROW as vn, isSingleDynamicReferenceToken as vr, interruptWatchListenerCount as vt, reachableDivergentParameters as w, ConfigError as wa, escapeRegExp$1 as wi, malformedExportNamesWarning as wn, redactSecretsForState as wr, UNSPECIFIED_SKIP_REASON as wt, bindingSkippedOutputs as x, setAwsClients as xa, redactDockerArgvValues as xi, hasReadableOutputs as xn, maskSecretsInText as xr, CloudControlProvider as xt, keptWholeReasonText as y, resetAwsClients as ya, getDockerCmd as yi, displayLogicalId as yn, markSameGenerationBag as yr, isInterruptedWaitError as yt, isStatefulRecreateTargetForReplace as z, StackHasActiveImportsError as za, stateBucketExistenceConfirmed as zi, refuseMalformedOrphans as zn, hasReasonlessBaselineRefusal as zr, refStateLookupFromResource as zt };
50841
+ //# sourceMappingURL=deploy-engine-BtJocpRR.js.map