@go-to-k/cdkd 0.289.3 → 0.289.4

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
- import { 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 } from "./logger-D2Md1kTq.js";
1
+ import { 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, y as displaySafe } from "./logger-CecsQ1UT.js";
2
2
  import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
3
- import { t as getCdkdVersion } from "./version-DPykgdNN.js";
3
+ import { t as getCdkdVersion } from "./version-C3wRsCF2.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";
@@ -1554,7 +1554,10 @@ function isCdkdError(error) {
1554
1554
  function formatError(error) {
1555
1555
  if (isCdkdError(error)) {
1556
1556
  let message = `${error.name}: ${error.message}`;
1557
- if (error.cause) message += `\nCaused by: ${error.cause.message}`;
1557
+ if (error.cause) {
1558
+ const cause = displaySafe(error.cause.message);
1559
+ if (cause) message += `\nCaused by: ${cause}`;
1560
+ }
1558
1561
  return message;
1559
1562
  }
1560
1563
  if (error instanceof Error) return `${error.name}: ${error.message}`;
@@ -3987,56 +3990,6 @@ async function expectedOwnerParam(client) {
3987
3990
  return owner ? { ExpectedBucketOwner: owner } : {};
3988
3991
  }
3989
3992
 
3990
- //#endregion
3991
- //#region src/utils/display-safe.ts
3992
- /**
3993
- * Make an untrusted value safe to render in a terminal or persist into a log.
3994
- *
3995
- * A LEAF module with no imports, and deliberately in `src/utils/` rather than
3996
- * beside its first caller: issue [#2170](https://github.com/go-to-k/cdkd/issues/2170)'s
3997
- * review found the same rule being widened BY HAND one module at a time and
3998
- * missing an instance every round — the change sanitized 1 of 5 readers of
3999
- * `LockInfo.owner`. One shared definition, imported by everything that renders
4000
- * such a value, is what stops the next reader from inheriting nothing.
4001
- *
4002
- * The stripped class is wider than C0 + DEL, which a first cut used and which
4003
- * misses every mechanism that actually forges a line:
4004
- *
4005
- * - `U+0085` (NEL) and the C1 range — xterm reads `U+009B` as CSI in UTF-8;
4006
- * - `U+2028` / `U+2029` — this text is PERSISTED and re-rendered by JSON and
4007
- * web log viewers, where both are line terminators;
4008
- * - `U+202A`-`U+202E` / `U+2066`-`U+2069` — the Trojan-Source bidi overrides
4009
- * and isolates, which visually REORDER the command being pasted.
4010
- *
4011
- * Known residual, recorded rather than implied away: the invisible formatters
4012
- * (`U+200B`-`U+200D`, `U+FEFF`) and the bidi MARKS (`U+200E` / `U+200F` /
4013
- * `U+061C`) survive, as do bare RTL letters, which no denylist can reach. All
4014
- * of them can only make a rendered name differ visually from its bytes — the
4015
- * command a user pastes still acts on exactly what is shown, and the blast
4016
- * radius stays the attacker's own stack name.
4017
- *
4018
- * A caller whose value has a KNOWN ASCII charset (a stack name, an AWS region)
4019
- * should pass `asciiOnly`, which is a positive allowlist and therefore has no
4020
- * such residual at all.
4021
- *
4022
- * ONE CALLER DELIBERATELY GOES WIDER, and it is recorded here so an editor of
4023
- * the residual note above knows a second module now disagrees with it.
4024
- * `src/deployment/outputs-export-alias.ts` deletes a class derived from
4025
- * `\p{Cc}` / `\p{Cf}` / `\p{Zl}` / `\p{Zp}` /
4026
- * `\p{Default_Ignorable_Code_Point}`, because on THAT path the subject is a possibly
4027
- * secret-bearing name in an operator's log: a plaintext split by a zero-width
4028
- * character is READ as if it were contiguous, so it is disclosed without any
4029
- * paste, and the command-forgery reasoning above does not transfer (issue
4030
- * [#2874](https://github.com/go-to-k/cdkd/issues/2874)). Nothing here changes
4031
- * -- widening this helper would alter every caller that merely wants a
4032
- * terminal-safe string.
4033
- */
4034
- function displaySafe(value, opts) {
4035
- if (value === void 0 || value === null) return "";
4036
- const text = String(value);
4037
- return (opts?.asciiOnly ? text.replace(/[^ -~]/g, " ") : text.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029\u202a-\u202e\u2066-\u2069]/g, " ")).trim();
4038
- }
4039
-
4040
3993
  //#endregion
4041
3994
  //#region src/state/s3-replication-purge-gap.ts
4042
3995
  /**
@@ -9656,18 +9609,20 @@ var S3StateBackend = class {
9656
9609
  async getState(stackName, region) {
9657
9610
  await this.ensureClientForBucket();
9658
9611
  const newKey = this.getStateKey(stackName, region);
9612
+ const shownStackName = this.displayName(stackName);
9613
+ const shownRegionName = displaySafe(region, { asciiOnly: true }) || "<unrenderable>";
9659
9614
  try {
9660
- this.logger.debug(`Getting state for stack: ${stackName} (${region})`);
9615
+ this.logger.debug(`Getting state for stack: ${shownStackName} (${shownRegionName})`);
9661
9616
  const response = await this.s3Client.send(new GetObjectCommand({
9662
9617
  Bucket: this.config.bucket,
9663
9618
  ...await this.ownerParam(),
9664
9619
  Key: newKey
9665
9620
  }));
9666
- if (!response.Body) throw new StateError(`State file for stack '${stackName}' (${region}) has no body`);
9667
- if (!response.ETag) throw new StateError(`State file for stack '${stackName}' (${region}) has no ETag`);
9621
+ if (!response.Body) throw new StateError(`State file for stack '${shownStackName}' (${shownRegionName}) has no body`);
9622
+ if (!response.ETag) throw new StateError(`State file for stack '${shownStackName}' (${shownRegionName}) has no ETag`);
9668
9623
  const bodyString = await response.Body.transformToString();
9669
9624
  const state = this.parseStateBody(bodyString, stackName);
9670
- this.logger.debug(`Retrieved state: ${stackName} (${region}), ETag: ${response.ETag}`);
9625
+ this.logger.debug(`Retrieved state: ${shownStackName} (${shownRegionName}), ETag: ${response.ETag}`);
9671
9626
  return {
9672
9627
  state,
9673
9628
  etag: response.ETag
@@ -9675,13 +9630,15 @@ var S3StateBackend = class {
9675
9630
  } catch (error) {
9676
9631
  if (!isNoSuchKey(error)) {
9677
9632
  if (error instanceof StateError) throw error;
9678
- throw new StateError(`Failed to get state for stack '${stackName}' (${region}): ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
9633
+ const detail = displaySafe(error instanceof Error ? error.message : String(error), { asciiOnly: true }) || "<unrenderable>";
9634
+ throw new StateError(`Failed to get state for stack '${shownStackName}' (${shownRegionName}): ${detail}`, error instanceof Error ? error : void 0);
9679
9635
  }
9680
- this.logger.debug(`No state at new key for stack: ${stackName} (${region})`);
9636
+ this.logger.debug(`No state at new key for stack: ${shownStackName} (${shownRegionName})`);
9681
9637
  }
9682
9638
  const legacy = await this.tryGetLegacy(stackName, region);
9683
9639
  if (legacy) {
9684
- this.logger.warn(`Loaded legacy state for stack '${stackName}' from '${this.getLegacyStateKey(stackName)}'. It will be migrated to the region-scoped layout on next save.`);
9640
+ const shownKey = displaySafe(this.getLegacyStateKey(stackName), { asciiOnly: true }) || "<unrenderable>";
9641
+ this.logger.warn(`Loaded legacy state for stack '${shownStackName}' from '${shownKey}'. It will be migrated to the region-scoped layout on next save.`);
9685
9642
  return {
9686
9643
  ...legacy,
9687
9644
  migrationPending: true
@@ -10309,7 +10266,7 @@ var S3StateBackend = class {
10309
10266
  const bodyString = await response.Body.transformToString();
10310
10267
  const state = this.parseStateBody(bodyString, stackName);
10311
10268
  if (state.region && state.region !== region) {
10312
- this.logger.debug(`Legacy state for stack '${stackName}' has region '${state.region}', not '${region}' — skipping legacy fallback.`);
10269
+ this.logger.debug(`Legacy state for stack '${this.displayName(stackName)}' has region '${displaySafe(state.region, { asciiOnly: true }) || "<unrenderable>"}', not '${displaySafe(region, { asciiOnly: true }) || "<unrenderable>"}' — skipping legacy fallback.`);
10313
10270
  return null;
10314
10271
  }
10315
10272
  return {
@@ -10318,7 +10275,8 @@ var S3StateBackend = class {
10318
10275
  };
10319
10276
  } catch (error) {
10320
10277
  if (isNoSuchKey(error)) return null;
10321
- throw new StateError(`Failed to get legacy state for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
10278
+ const detail = displaySafe(error instanceof Error ? error.message : String(error), { asciiOnly: true }) || "<unrenderable>";
10279
+ throw new StateError(`Failed to get legacy state for stack '${this.displayName(stackName)}': ${detail}`, error instanceof Error ? error : void 0);
10322
10280
  }
10323
10281
  }
10324
10282
  /**
@@ -10332,10 +10290,15 @@ var S3StateBackend = class {
10332
10290
  try {
10333
10291
  parsed = JSON.parse(bodyString);
10334
10292
  } catch (error) {
10335
- throw new StateError(`State file for stack '${stackName}' is not valid JSON: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
10293
+ const raw = error instanceof Error ? error.message : String(error);
10294
+ const detail = displaySafe(raw, { asciiOnly: true }) || "<unrenderable>";
10295
+ throw new StateError(`State file for stack '${this.displayName(stackName)}' is not valid JSON: ${detail}`, error instanceof Error ? error : void 0);
10336
10296
  }
10337
10297
  const v = parsed.version;
10338
- if (v !== void 0 && !STATE_SCHEMA_VERSIONS_READABLE.includes(v)) throw new StateError(`Unsupported state schema version ${String(v)} for stack '${stackName}'. This cdkd binary supports versions ${STATE_SCHEMA_VERSIONS_READABLE.join(", ")}. Upgrade cdkd to a version that supports schema ${String(v)}.`);
10298
+ if (v !== void 0 && !STATE_SCHEMA_VERSIONS_READABLE.includes(v)) {
10299
+ const shown = displaySafe(String(v), { asciiOnly: true }) || "<unrenderable>";
10300
+ throw new StateError(`Unsupported state schema version ${shown} for stack '${this.displayName(stackName)}'. This cdkd binary supports versions ${STATE_SCHEMA_VERSIONS_READABLE.join(", ")}. Upgrade cdkd to a version that supports schema ${shown}.`);
10301
+ }
10339
10302
  return parsed;
10340
10303
  }
10341
10304
  };
@@ -10381,6 +10344,20 @@ const MIN_RENEWAL_INTERVAL_MS = 1e3;
10381
10344
  */
10382
10345
  const LOCK_OBJECT_DESCRIPTION = "a stack lock heartbeat, which records the lock owner, its acquisition timestamp, its deadline and the operation name — no secret, but one row per renewal";
10383
10346
  /**
10347
+ * One spelling of "this value came from an S3 key or a lock record, and is
10348
+ * about to be interpolated into a message a terminal will render". A stack
10349
+ * name and an AWS region both have a known charset, so the ASCII allowlist is
10350
+ * a no-op on every legitimate input while an S3 key admits any UTF-8.
10351
+ *
10352
+ * Call it for a stack name or a region. Not every value in this file goes
10353
+ * through it, and this comment does not say which do: three revisions of that
10354
+ * sentence carried a count or a scope claim and each was wrong.
10355
+ * `grep safeSegment` answers it exactly.
10356
+ */
10357
+ function safeSegment(value) {
10358
+ return displaySafe(value, { asciiOnly: true }) || "<unrenderable>";
10359
+ }
10360
+ /**
10384
10361
  * S3-based lock manager using conditional writes (If-None-Match)
10385
10362
  *
10386
10363
  * Implements distributed locking using S3's If-None-Match: "*" condition
@@ -10585,7 +10562,7 @@ var LockManager = class {
10585
10562
  }
10586
10563
  return false;
10587
10564
  }
10588
- throw new LockError(`Failed to acquire lock for stack '${displaySafe(stackName, { asciiOnly: true }) || "<unrenderable>"}' (${displaySafe(region, { asciiOnly: true }) || "<unrenderable>"}): ${displaySafe(error instanceof Error ? error.message : String(error))}`, error instanceof Error ? error : void 0);
10565
+ throw new LockError(`Failed to acquire lock for stack '${safeSegment(stackName)}' (${safeSegment(region)}): ${displaySafe(error instanceof Error ? error.message : String(error), { asciiOnly: true }) || "<unrenderable>"}`, error instanceof Error ? error : void 0);
10589
10566
  }
10590
10567
  }
10591
10568
  /**
@@ -10628,18 +10605,19 @@ var LockManager = class {
10628
10605
  async getLockRecord(stackName, region) {
10629
10606
  await this.ensureClientForBucket();
10630
10607
  const key = this.getLockKey(stackName, region);
10608
+ const shownStack = safeSegment(stackName);
10631
10609
  try {
10632
- this.logger.debug(`Getting lock info for stack: ${stackName}`);
10610
+ this.logger.debug(`Getting lock info for stack: ${shownStack}`);
10633
10611
  const response = await this.s3Client.send(new GetObjectCommand({
10634
10612
  Bucket: this.config.bucket,
10635
10613
  ...await this.ownerParam(),
10636
10614
  Key: key
10637
10615
  }));
10638
- if (!response.Body) throw new LockError(`Lock file for stack '${stackName}' has no body`);
10616
+ if (!response.Body) throw new LockError(`Lock file for stack '${shownStack}' has no body`);
10639
10617
  const bodyString = await response.Body.transformToString();
10640
10618
  const raw = JSON.parse(bodyString);
10641
10619
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
10642
- this.logger.debug(`Lock file for stack ${stackName} is not an object; treating as absent`);
10620
+ this.logger.debug(`Lock file for stack ${shownStack} is not an object; treating as absent`);
10643
10621
  return null;
10644
10622
  }
10645
10623
  const parsed = raw;
@@ -10648,18 +10626,19 @@ var LockManager = class {
10648
10626
  owner: displaySafe(parsed.owner),
10649
10627
  ...parsed.operation !== void 0 && { operation: displaySafe(parsed.operation) }
10650
10628
  };
10651
- this.logger.debug(`Lock info for stack: ${stackName}:`, lockInfo);
10629
+ this.logger.debug(`Lock info for stack: ${shownStack}:`, lockInfo);
10652
10630
  return {
10653
10631
  info: lockInfo,
10654
10632
  etag: response.ETag
10655
10633
  };
10656
10634
  } catch (error) {
10657
10635
  if (error instanceof NoSuchKey) {
10658
- this.logger.debug(`No lock exists for stack: ${stackName}`);
10636
+ this.logger.debug(`No lock exists for stack: ${shownStack}`);
10659
10637
  return null;
10660
10638
  }
10661
10639
  if (error instanceof LockError) throw error;
10662
- throw new LockError(`Failed to get lock info for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
10640
+ const detail = displaySafe(error instanceof Error ? error.message : String(error), { asciiOnly: true }) || "<unrenderable>";
10641
+ throw new LockError(`Failed to get lock info for stack '${shownStack}': ${detail}`, error instanceof Error ? error : void 0);
10663
10642
  }
10664
10643
  }
10665
10644
  /**
@@ -11156,7 +11135,7 @@ var LockManager = class {
11156
11135
  if (lockInfo) {
11157
11136
  const remainingMs = lockInfo.expiresAt - Date.now();
11158
11137
  if (attempt < maxRetries) {
11159
- this.logger.info(`Stack '${displaySafe(stackName, { asciiOnly: true }) || "<unrenderable>"}' (${displaySafe(region, { asciiOnly: true }) || "<unrenderable>"}) is locked by ${lockInfo.owner}${lockInfo.operation ? ` (operation: ${lockInfo.operation})` : ""}. Lock expires in ${this.formatDuration(remainingMs)}. Retrying in ${this.formatDuration(retryDelay)}... (attempt ${attempt + 1}/${maxRetries})`);
11138
+ this.logger.info(`Stack '${safeSegment(stackName)}' (${safeSegment(region)}) is locked by ${lockInfo.owner}${lockInfo.operation ? ` (operation: ${lockInfo.operation})` : ""}. Lock expires in ${this.formatDuration(remainingMs)}. Retrying in ${this.formatDuration(retryDelay)}... (attempt ${attempt + 1}/${maxRetries})`);
11160
11139
  await new Promise((resolve) => setTimeout(resolve, retryDelay));
11161
11140
  continue;
11162
11141
  }
@@ -11166,8 +11145,8 @@ var LockManager = class {
11166
11145
  const expiresIn = lockInfo ? this.formatDuration(lockInfo.expiresAt - Date.now()) : "unknown";
11167
11146
  const forceUnlockCommand = buildForceUnlockCommand(stackName, region);
11168
11147
  const recovery = forceUnlockCommand ? `If you are certain no other process is active, run: ${forceUnlockCommand}` : `If you are certain no other process is active, ${UNREPRODUCIBLE_LOCK_CLAUSE.charAt(0).toLowerCase()}${UNREPRODUCIBLE_LOCK_CLAUSE.slice(1)}`;
11169
- const safeStack = displaySafe(stackName, { asciiOnly: true }) || "<unrenderable>";
11170
- const safeRegion = displaySafe(region, { asciiOnly: true }) || "<unrenderable>";
11148
+ const safeStack = safeSegment(stackName);
11149
+ const safeRegion = safeSegment(region);
11171
11150
  throw new LockError(`Failed to acquire lock for stack '${safeStack}' (${safeRegion}) after ${maxRetries + 1} attempts. ` + (lockInfo ? `Locked by: ${lockInfo.owner}${lockInfo.operation ? `, operation: ${lockInfo.operation}` : ""}, expires in: ${expiresIn}. ` + recovery : `Lock exists but could not read lock info. ${recovery}`));
11172
11151
  }
11173
11152
  };
@@ -20533,11 +20512,15 @@ const drainDeadlines = new AsyncLocalStorage();
20533
20512
  *
20534
20513
  * THE TRADE, stated because it is real: iterations that actually WAIT spend
20535
20514
  * the shared budget, so a later one can find it exhausted and its drain get
20536
- * no grace. That is the same exposure issue
20515
+ * no grace. That is the exposure issue
20537
20516
  * [#2814](https://github.com/go-to-k/cdkd/issues/2814) records for nesting,
20538
- * now reachable across a loop as well -- and on the `Export.Name` leg the
20539
- * cost is a DROPPED write rather than a late one, since that block's
20540
- * `nameSecrets` is a per-iteration local. What bounds it is that only real
20517
+ * reachable across a loop as well: a part such a drain stops waiting for
20518
+ * records LATE. Late, not lost -- the engine's `Export.Name` block writes each
20519
+ * recording through to the pass map (it used to copy a per-iteration local,
20520
+ * which DROPPED a late one), and the outputs readers after the pass redact
20521
+ * against the pass map at the moment they read -- but a reader that already
20522
+ * took its copy does not see it, and the resolver warns when a drain stops
20523
+ * waiting. What bounds it is that only real
20541
20524
  * waiting spends the budget: reaching zero takes a full cap of drain wait
20542
20525
  * inside one pass, not merely a slow pass. It is taken deliberately -- an
20543
20526
  * unbounded hold on a deploy's state save costs a first deploy every
@@ -21373,9 +21356,12 @@ const NAMEABLE_INTRINSIC_KEYS = /* @__PURE__ */ new Set([
21373
21356
  * now throw on an intrinsic — `route53-provider.ts` (`HostedZoneConfig`),
21374
21357
  * `cloudfront-oai-provider.ts` (`CloudFrontOriginAccessIdentityConfig`),
21375
21358
  * `kinesis-provider.ts` (`StreamModeDetails`), `ecs-provider.ts`
21376
- * (`DeploymentController`), `secretsmanager-secret-provider.ts`
21377
- * (`GenerateSecretString`, via `generateSecretString`) and `codebuild-provider.ts`
21378
- * (reached from `update()` through `mapProperties`). Not a count, for the same
21359
+ * (`DeploymentController`) and `codebuild-provider.ts` (reached from `update()`
21360
+ * through `mapProperties`). `secretsmanager-secret-provider.ts` was on this
21361
+ * list until issue #3048 moved its update path to a SKIP (the container is
21362
+ * refused by `requireConfigObject` before `generateSecretString` reads it;
21363
+ * `create()` still throws, and so does the MEMBER-level `ExcludeCharacters`
21364
+ * read inside a well-formed container -- issue #3056). Not a count, for the same
21379
21365
  * reason as the near-copy list below: two successive reviews each found
21380
21366
  * another. Re-derive with
21381
21367
  * `grep -rn 'readConfigString(' src/provisioning/providers/`.
@@ -23033,6 +23019,13 @@ const CAP_EXPIRED = Symbol("drain-cap-expired");
23033
23019
  */
23034
23020
  const concurrentDrainCap = {};
23035
23021
  /**
23022
+ * The budgets whose drain has already reported abandoned inputs (issue
23023
+ * [#2814](https://github.com/go-to-k/cdkd/issues/2814)). A `WeakSet` so a
23024
+ * budget's entry dies with the budget, as the budget itself does with the
23025
+ * async context that opened it.
23026
+ */
23027
+ const abandonReported = /* @__PURE__ */ new WeakSet();
23028
+ /**
23036
23029
  * `Promise.all`'s RESULT and its choice of error, with `Promise.allSettled`'s
23037
23030
  * TIMING: every promise started here has settled before this returns, and
23038
23031
  * before it throws unless the cap below expires first (issue
@@ -23110,8 +23103,25 @@ const concurrentDrainCap = {};
23110
23103
  * require the "healthy work slower than 60 s" shape the sizing paragraph
23111
23104
  * describes; that shape is the cheapest way to reach it with no nesting and
23112
23105
  * no wrapped loop, not the floor.
23113
- * Residual: issue
23114
- * [#2814](https://github.com/go-to-k/cdkd/issues/2814).
23106
+ *
23107
+ * WHAT HAPPENS TO A PART THE CAP STOPS WAITING FOR (issue
23108
+ * [#2814](https://github.com/go-to-k/cdkd/issues/2814)). It keeps running, and
23109
+ * its recording still lands in the context's map whenever it arrives -- the
23110
+ * cap costs it ORDER, not the write. So the answer sits with the READERS: one
23111
+ * that runs after the recording arrives must see it, which `DeployEngine`'s
23112
+ * outputs pass arranges for its `Export.Name` block (a map that writes each
23113
+ * recording through to the pass map at once, where a local copied in a
23114
+ * `finally` used to drop it) and for the persisted outputs, the exports index
23115
+ * and the deploy summary (each redacting against the pass map as it stands
23116
+ * at the moment it is written). A reader that took its
23117
+ * copy BEFORE the recording arrived -- a failure message already printed, a
23118
+ * state save already sent -- cannot be helped without waiting, and the wait
23119
+ * is what the cap bounds. Cancelling the
23120
+ * part would not close that either: a cancelled part never records, so its
23121
+ * plaintext would be missing for EVERY reader rather than for the early ones.
23122
+ * What this helper adds is the report: releasing a rejection with inputs
23123
+ * still running calls `onAbandoned` with how many, at most once per budget,
23124
+ * and the resolver turns that into a warning.
23115
23125
  *
23116
23126
  * ONE REMAINING CONSEQUENCE, deliberate and pinned by a case rather than only
23117
23127
  * described: the earliest-in-time rule holds PER INVOCATION, not across
@@ -23129,11 +23139,16 @@ const concurrentDrainCap = {};
23129
23139
  * failure where the old race was arbitrary. Residual: issue
23130
23140
  * [#2805](https://github.com/go-to-k/cdkd/issues/2805).
23131
23141
  */
23132
- async function allSettledKeepingFirstRejection(promises) {
23142
+ async function allSettledKeepingFirstRejection(promises, onAbandoned) {
23133
23143
  let rejection;
23134
23144
  const shared = drainDeadlines.getStore();
23135
23145
  let armCap;
23136
- const guarded = promises.map((promise) => promise.catch((error) => {
23146
+ let settled = 0;
23147
+ const guarded = promises.map((promise) => promise.then((value) => {
23148
+ settled += 1;
23149
+ return value;
23150
+ }, (error) => {
23151
+ settled += 1;
23137
23152
  if (rejection === void 0) {
23138
23153
  rejection = { error };
23139
23154
  armCap?.();
@@ -23158,7 +23173,17 @@ async function allSettledKeepingFirstRejection(promises) {
23158
23173
  });
23159
23174
  try {
23160
23175
  const outcome = await Promise.race([Promise.all(guarded), capped]);
23161
- if (rejection !== void 0) throw rejection.error;
23176
+ if (rejection !== void 0) {
23177
+ const pending = promises.length - settled;
23178
+ if (pending > 0) {
23179
+ if (shared === void 0) onAbandoned(pending);
23180
+ else if (!abandonReported.has(shared)) {
23181
+ abandonReported.add(shared);
23182
+ onAbandoned(pending);
23183
+ }
23184
+ }
23185
+ throw rejection.error;
23186
+ }
23162
23187
  if (outcome === CAP_EXPIRED) throw markNonRetryable(/* @__PURE__ */ new Error("drain cap expired with no rejection recorded"));
23163
23188
  return outcome;
23164
23189
  } finally {
@@ -24126,6 +24151,17 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
24126
24151
  return conditions;
24127
24152
  }
24128
24153
  /**
24154
+ * Warn that a drain stopped waiting for `pending` inputs of a failed
24155
+ * resolution (issue [#2814](https://github.com/go-to-k/cdkd/issues/2814)).
24156
+ * The helper calls this at most once per budget. The text carries a count
24157
+ * and the cap, nothing the template or AWS supplied, so it needs no masking.
24158
+ */
24159
+ warnAbandonedParts(pending) {
24160
+ const capSeconds = (concurrentDrainCap.ms ?? DRAIN_AFTER_REJECTION_MS) / 1e3;
24161
+ const parts = pending === 1 ? "1 concurrent part was" : `${pending} concurrent parts were`;
24162
+ this.logger.warn(`A resolution failed while ${parts} still running, and cdkd stopped waiting because the wait after a failure (capped at ${capSeconds}s) was used up. A secret such a part resolves from now on is still recorded, but only what runs after it arrives can mask it: output already printed or saved is not revisited.`);
24163
+ }
24164
+ /**
24129
24165
  * Recursively resolve a value
24130
24166
  */
24131
24167
  async resolveValue(value, context) {
@@ -24133,7 +24169,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
24133
24169
  if (typeof value === "string" && value.includes("{{resolve:")) return await this.resolveDynamicReferences(value, context);
24134
24170
  return value;
24135
24171
  }
24136
- if (Array.isArray(value)) return (await allSettledKeepingFirstRejection(value.map((v) => this.resolveValue(v, context)))).filter((v) => v !== AWS_NO_VALUE);
24172
+ if (Array.isArray(value)) return (await allSettledKeepingFirstRejection(value.map((v) => this.resolveValue(v, context)), (pending) => this.warnAbandonedParts(pending))).filter((v) => v !== AWS_NO_VALUE);
24137
24173
  const obj = value;
24138
24174
  if ("Ref" in obj) return await this.resolveRef(obj["Ref"], context);
24139
24175
  if ("Fn::GetAtt" in obj) return await this.resolveGetAtt(obj["Fn::GetAtt"], context);
@@ -25040,7 +25076,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
25040
25076
  let result = (await allSettledKeepingFirstRejection(values.map(async (v) => {
25041
25077
  const resolved = await this.resolveValue(v, context);
25042
25078
  return String(resolved);
25043
- }))).join(delimiter);
25079
+ }), (pending) => this.warnAbandonedParts(pending))).join(delimiter);
25044
25080
  if (result.includes("{{resolve:")) result = await this.resolveDynamicReferences(result, context);
25045
25081
  this.logger.debug(`Resolved Fn::Join: ${this.maskSecretsForLog(result, context)}`);
25046
25082
  return result;
@@ -28005,7 +28041,7 @@ var CloudControlProvider = class {
28005
28041
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
28006
28042
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
28007
28043
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
28008
- const { ASGProvider } = await import("./asg-provider-rQ1BW281.js").then((n) => n.n);
28044
+ const { ASGProvider } = await import("./asg-provider-CpxZ9sVH.js").then((n) => n.n);
28009
28045
  const asgProvider = new ASGProvider();
28010
28046
  return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
28011
28047
  }
@@ -37316,6 +37352,47 @@ var DeploymentEventsReader = class {
37316
37352
  */
37317
37353
  const EMPTY_SECRETS = /* @__PURE__ */ new Map();
37318
37354
  /**
37355
+ * A secrets map that keeps its OWN entries and also writes each one through
37356
+ * to `target` the moment it is recorded (issue
37357
+ * [#2814](https://github.com/go-to-k/cdkd/issues/2814)).
37358
+ *
37359
+ * The outputs pass resolves each intrinsic `Export.Name` through one of these.
37360
+ * Its own entries are what `exportNameSecretExposure` reads as "substituted
37361
+ * into THIS name", which must stay exact -- a view of the whole pass map
37362
+ * (`cdkd scrub`'s `SharedEntriesSecrets`) would report every secret the pass
37363
+ * has recorded as one the name holds, and refuse every alias. The write-through
37364
+ * is what a copy could not give: a part the drain cap stopped waiting for
37365
+ * records AFTER the name's block has ended, and when this was a local copied
37366
+ * into the pass map in a `finally`, such a record reached nothing.
37367
+ *
37368
+ * Only `set` writes through: it is the one operation the resolver performs on
37369
+ * a recording map (grepped -- no resolver path calls `delete` or `clear` on
37370
+ * one). `cdkd scrub`'s `SharedEntriesSecrets` overrides those too, and the
37371
+ * asymmetry is deliberate: that one is a VIEW holding no entries of its own,
37372
+ * while a `delete` here would leave the pass map carrying an entry this map
37373
+ * dropped -- one needle too many, which over-redacts rather than leaks.
37374
+ * The ENTRIES only, never the resolved pairs beside them
37375
+ * (issue #2485): those are keyed by map INSTANCE (`recordResolvedPair`), so
37376
+ * they stay on this one. A name never positions a leaf, and a value re-using
37377
+ * the same token records its own pair at the seam, so carrying them could add
37378
+ * nothing -- what it COULD do is mark a pair conflicting (an `ssm` reference
37379
+ * whose `Type` came back unclassifiable is never cached, so a name resolving
37380
+ * it re-asks AWS and can see a value that moved since the value pass) and
37381
+ * destroy the positioning the value pass had earned.
37382
+ */
37383
+ var ForwardingSecrets = class extends Map {
37384
+ target;
37385
+ constructor(target) {
37386
+ super();
37387
+ this.target = target;
37388
+ }
37389
+ set(plaintext, expression) {
37390
+ super.set(plaintext, expression);
37391
+ this.target?.set(plaintext, expression);
37392
+ return this;
37393
+ }
37394
+ };
37395
+ /**
37319
37396
  * Default per-resource warn threshold: warn the user when a single
37320
37397
  * resource has been in flight for 5 minutes. Most CC API resources
37321
37398
  * complete in under a minute; 5m is the agreed elbow.
@@ -37590,6 +37667,16 @@ var DeployEngine = class DeployEngine {
37590
37667
  */
37591
37668
  outputSecrets = /* @__PURE__ */ new Map();
37592
37669
  /**
37670
+ * The outputs pass's own recording map(s), one per `resolveOutputs` call
37671
+ * this deploy, so every redaction of the outputs bag re-reads them rather
37672
+ * than trusting the copy taken when the pass ended (issue
37673
+ * [#2814](https://github.com/go-to-k/cdkd/issues/2814)): a part the drain
37674
+ * cap stopped waiting for records into its pass map LATE, and the final
37675
+ * save, the exports index and the deploy summary all run after that copy.
37676
+ * Reset per `deploy()`.
37677
+ */
37678
+ outputsPassSecretMaps = [];
37679
+ /**
37593
37680
  * UNRESOLVED template `Outputs` values, keyed by output name (issue #1910) —
37594
37681
  * the outputs' POSITION source, the sibling of `perResourceTemplateProps` for
37595
37682
  * the bag `resolveOutputs` produces. Without it two outputs resolving one
@@ -37718,6 +37805,7 @@ var DeployEngine = class DeployEngine {
37718
37805
  this.perResourceResolvedType = /* @__PURE__ */ new Map();
37719
37806
  this.attemptedResolvedProps = /* @__PURE__ */ new Map();
37720
37807
  this.outputSecrets = /* @__PURE__ */ new Map();
37808
+ this.outputsPassSecretMaps = [];
37721
37809
  this.outputsTemplateSource = Object.create(null);
37722
37810
  this.outputsSourceUsable = true;
37723
37811
  this.skippedOutputs = void 0;
@@ -37789,12 +37877,16 @@ var DeployEngine = class DeployEngine {
37789
37877
  * Redact the resolved stack OUTPUTS bag, positioned by the unresolved
37790
37878
  * template `Outputs` values (issue #1910).
37791
37879
  *
37792
- * A single entry point because THREE call sites redact this same bag — the
37793
- * state-persist choke point, the no-change re-check, and the post-deploy
37794
- * publish that feeds the exports index / deploy summary — and before this
37795
- * they each spelled the value-only redaction separately. Two outputs
37796
- * resolving one secret collapsed onto whichever expression was recorded last
37797
- * at all three.
37880
+ * A single entry point because SEVEN call sites redact this same bag — the
37881
+ * state-persist choke point, the no-change re-check, that path's exports
37882
+ * index and deploy summary, the changes path's index and summary, and the
37883
+ * outputs pass itself. THREE of those are the ones issue #1910 unified —
37884
+ * the persist choke point, the re-check, and the outputs pass, which the
37885
+ * list above ends on rather than opens with: before it they each spelled
37886
+ * the value-only redaction separately, and two outputs resolving one secret
37887
+ * collapsed onto whichever expression was recorded last at all three. The
37888
+ * other FOUR are issue #2814's, both paths' index and summary: each read
37889
+ * the bag unredacted until then, and now redacts at the moment it reads.
37798
37890
  */
37799
37891
  /**
37800
37892
  * Record the plaintext behind every output {@link redactOutputs} just masked,
@@ -37807,9 +37899,18 @@ var DeployEngine = class DeployEngine {
37807
37899
  * value read back out of a previous run's state — is skipped, because there
37808
37900
  * is no plaintext behind it to remember.
37809
37901
  *
37810
- * Called only from the REAL-DEPLOY outputs pass. The other two `redactOutputs`
37811
- * callers hand it a bag from a previous generation, where a mask is already
37812
- * unrecoverable and pretending otherwise would serve a stale value.
37902
+ * Called only from the REAL-DEPLOY outputs pass. Of the six other
37903
+ * `redactOutputs` callers, three CAN hand it a bag from a previous
37904
+ * generation — the persist walk always may, and the no-change path's
37905
+ * exports index and summary do on the arms where that path keeps the
37906
+ * previous bag — and there a mask is already unrecoverable, so pretending
37907
+ * otherwise would
37908
+ * serve a stale value. The other three are not this pass either: the
37909
+ * no-change path performs the FIRST redaction of its own resolution there,
37910
+ * and the changes path's index and summary re-redact the bag this pass
37911
+ * already produced. (The "other two" this replaces counted the base's three
37912
+ * callers correctly; what was wrong was calling both of the others
37913
+ * previous-generation, when only the persist walk was one.)
37813
37914
  */
37814
37915
  rememberRecoverableMaskedOutputs(stackName, resolved, redacted) {
37815
37916
  if (resolved === redacted) return;
@@ -37820,7 +37921,51 @@ var DeployEngine = class DeployEngine {
37820
37921
  recordRecoverableMaskedOutput(stackName, this.stackRegion, key, plaintext);
37821
37922
  }
37822
37923
  }
37924
+ /**
37925
+ * Fold every outputs-pass recording map into `outputSecrets` — the entries,
37926
+ * and the uncollapsed evidence beside them (issue #2485: without it a
37927
+ * literal Output embedding one of two same-plaintext references would lose
37928
+ * its span positioning and persist the sibling's expression). Only what the
37929
+ * outputs pass itself resolved, so the outputs redaction (GHSA fix) uses
37930
+ * only outputs-substituted references: a literal output equal to a secret
37931
+ * nothing resolved is not recorded, and is not touched.
37932
+ *
37933
+ * Run by every {@link redactOutputs} (issue
37934
+ * [#2814](https://github.com/go-to-k/cdkd/issues/2814)), because a part the
37935
+ * drain cap stopped waiting for records into its pass map LATE: a secret
37936
+ * that arrives between the pass and the final save is then still a needle
37937
+ * for the save, the exports index and the deploy summary. Repeating it is
37938
+ * safe for the ENTRIES — re-setting one the bag holds changes nothing, and
37939
+ * `Map.set` on an existing key keeps its insertion order, so last-wins
37940
+ * cannot be reordered by a refold.
37941
+ *
37942
+ * The PAIRS are where repeating is not merely a no-op, stated because the
37943
+ * end-of-pass copy could not see it: a part the cap stopped waiting for can
37944
+ * record a pair LATE, and a second value for one expression marks it
37945
+ * `CONFLICTING_PLAINTEXT` (a non-cacheable `{{resolve:ssm:X}}` re-resolved
37946
+ * to a moved value). A later refold then carries that conflict into
37947
+ * `outputSecrets`, the leaf loses its positioning and falls to the value
37948
+ * scan, which can persist a sibling's expression (the issue #2485 class).
37949
+ * The plaintext stays MASKED either way, so the cost is which expression
37950
+ * is stored, not a disclosure — and the alternative, dropping the late
37951
+ * pair, would keep a positioning the pass itself no longer vouches for.
37952
+ */
37953
+ absorbOutputsPassSecrets() {
37954
+ for (const passSecrets of this.outputsPassSecretMaps) {
37955
+ for (const [value, expr] of passSecrets) this.outputSecrets.set(value, expr);
37956
+ mergeResolvedPairs(passSecrets, this.outputSecrets);
37957
+ }
37958
+ }
37959
+ /**
37960
+ * Redact the outputs bag. NOT a pure transform: it folds the outputs pass
37961
+ * map into `outputSecrets` first (issue #2814), so every call can grow that
37962
+ * bag. Its KEY set only grows, and the bag has no other reader, which is
37963
+ * what makes calling this on every save, index write and summary safe. The
37964
+ * resolved PAIRS beside those keys are not equally free to refold — see
37965
+ * {@link absorbOutputsPassSecrets}, which states what a late one costs.
37966
+ */
37823
37967
  redactOutputs(outputs) {
37968
+ this.absorbOutputsPassSecrets();
37824
37969
  if (this.outputSecrets.size === 0) return outputs;
37825
37970
  return redactSecretsForState(outputs, this.outputSecrets, this.outputsSourceUsable ? this.outputsTemplateSource : void 0, TEMPLATE_SOURCED_RULES);
37826
37971
  }
@@ -38453,7 +38598,10 @@ var DeployEngine = class DeployEngine {
38453
38598
  persistedOutputs = refreshedState.outputs;
38454
38599
  if (outputsChanged) this.logger.info("Persisted Outputs-only change (no resource diff).");
38455
38600
  else this.logger.debug("Persisted export-set change (no outputs-value diff, no-change path, #2193)");
38456
- if (this.exportIndexStore) await this.exportIndexStore.updateForStack(stackName, this.stackRegion, importableOutputs(refreshedState));
38601
+ if (this.exportIndexStore) await this.exportIndexStore.updateForStack(stackName, this.stackRegion, importableOutputs({
38602
+ ...refreshedState,
38603
+ outputs: this.redactOutputs(refreshedState.outputs)
38604
+ }));
38457
38605
  } else if (observedRefresh) this.logger.debug("Persisted refreshed observedProperties (no-change path)");
38458
38606
  else this.logger.debug("Persisted skipped-outputs record (no outputs-value diff, no-change path, #2740)");
38459
38607
  } catch (saveError) {
@@ -38470,7 +38618,7 @@ var DeployEngine = class DeployEngine {
38470
38618
  updatePartial: 0,
38471
38619
  unchanged: Object.keys(currentState.resources).length,
38472
38620
  durationMs: Date.now() - startTime,
38473
- outputs: this.buildDisplayOutputs(template, persistedOutputs),
38621
+ outputs: this.buildDisplayOutputs(template, this.redactOutputs(persistedOutputs)),
38474
38622
  attributeFallbackCount: this.resolver.getPhysicalIdFallbackCount()
38475
38623
  };
38476
38624
  }
@@ -38501,7 +38649,10 @@ var DeployEngine = class DeployEngine {
38501
38649
  await this.drainObservedCaptures(newState.resources);
38502
38650
  const newEtag = await this.stateBackend.saveState(stackName, this.stackRegion, this.withParentInfo(newState));
38503
38651
  this.logger.debug(`State saved (ETag: ${newEtag})`);
38504
- await Promise.all([this.deleteRollbackJournalBestEffort(stackName), this.exportIndexStore ? this.exportIndexStore.updateForStack(stackName, this.stackRegion, importableOutputs(newState)) : Promise.resolve()]);
38652
+ await Promise.all([this.deleteRollbackJournalBestEffort(stackName), this.exportIndexStore ? this.exportIndexStore.updateForStack(stackName, this.stackRegion, importableOutputs({
38653
+ ...newState,
38654
+ outputs: this.redactOutputs(newState.outputs)
38655
+ })) : Promise.resolve()]);
38505
38656
  const durationMs = Date.now() - startTime;
38506
38657
  const unchangedCount = this.diffCalculator.filterByType(changes, "NO_CHANGE").length + actualCounts.skipped;
38507
38658
  return {
@@ -38513,7 +38664,7 @@ var DeployEngine = class DeployEngine {
38513
38664
  updatePartial: actualCounts.updatePartial,
38514
38665
  unchanged: unchangedCount,
38515
38666
  durationMs,
38516
- outputs: this.buildDisplayOutputs(template, newState.outputs ?? {}),
38667
+ outputs: this.buildDisplayOutputs(template, this.redactOutputs(newState.outputs ?? {})),
38517
38668
  attributeFallbackCount: this.resolver.getPhysicalIdFallbackCount()
38518
38669
  };
38519
38670
  } finally {
@@ -40125,8 +40276,10 @@ var DeployEngine = class DeployEngine {
40125
40276
  * defense in depth here — but two masking sites in one flow must not argue
40126
40277
  * opposite sides of the same question. `secrets` is the outputs pass's own
40127
40278
  * map: everything recorded before this handler runs, an `Export.Name`
40128
- * resolution's entries included (its `finally` merges them back before the
40129
- * `catch` reaches here). Since issue #2563 a still-pending concurrent part
40279
+ * resolution's entries included (its map writes each one through to the
40280
+ * pass map as the resolver records it, so they are here before the `catch`
40281
+ * is; issue #2814 replaced the `finally` that copied them at the end of
40282
+ * the block). Since issue #2563 a still-pending concurrent part
40130
40283
  * is in the PASS bag before this handler runs: the resolver drains every
40131
40284
  * part it started before a rejection reaches a caller. Not
40132
40285
  * unconditionally, and the weaker claim is the true one -- the drain is
@@ -40261,6 +40414,7 @@ var DeployEngine = class DeployEngine {
40261
40414
  };
40262
40415
  const outputsPassSecrets = context.recordedSecretValues ?? EMPTY_SECRETS;
40263
40416
  const outputsPassInherited = context.inheritedSecrets ?? EMPTY_SECRETS;
40417
+ if (context.recordedSecretValues) this.outputsPassSecretMaps.push(context.recordedSecretValues);
40264
40418
  const publishedOutputNames = collectPublishedOutputNames(template.Outputs, conditions);
40265
40419
  let outputsPassCompleted = false;
40266
40420
  try {
@@ -40286,20 +40440,16 @@ var DeployEngine = class DeployEngine {
40286
40440
  if (!output.Export?.Name) continue;
40287
40441
  const value = outputs[outputKey];
40288
40442
  if (value === void 0) continue;
40289
- const nameSecrets = /* @__PURE__ */ new Map();
40443
+ const nameSecrets = new ForwardingSecrets(context.recordedSecretValues);
40290
40444
  const nameReads = [];
40291
40445
  let exportName;
40292
40446
  try {
40293
- try {
40294
- exportName = typeof output.Export.Name === "string" ? output.Export.Name : await this.resolver.resolve(output.Export.Name, {
40295
- ...context,
40296
- recordedSecretValues: nameSecrets,
40297
- redactedAttributeReads: nameReads
40298
- });
40299
- refuseMaskedOutputReads(outputKey, nameReads);
40300
- } finally {
40301
- for (const [plaintext, expression] of nameSecrets) context.recordedSecretValues?.set(plaintext, expression);
40302
- }
40447
+ exportName = typeof output.Export.Name === "string" ? output.Export.Name : await this.resolver.resolve(output.Export.Name, {
40448
+ ...context,
40449
+ recordedSecretValues: nameSecrets,
40450
+ redactedAttributeReads: nameReads
40451
+ });
40452
+ refuseMaskedOutputReads(outputKey, nameReads);
40303
40453
  } catch (error) {
40304
40454
  this.handleOutputResolutionFailure(error, outputKey, outputs, outputsPassSecrets, outputsPassInherited);
40305
40455
  continue;
@@ -40316,10 +40466,6 @@ var DeployEngine = class DeployEngine {
40316
40466
  }
40317
40467
  outputsPassCompleted = true;
40318
40468
  } finally {
40319
- if (context.recordedSecretValues) {
40320
- for (const [value, expr] of context.recordedSecretValues) this.outputSecrets.set(value, expr);
40321
- mergeResolvedPairs(context.recordedSecretValues, this.outputSecrets);
40322
- }
40323
40469
  if (!outputsPassCompleted) this.outputsSourceUsable = false;
40324
40470
  }
40325
40471
  for (const [outputKey, output] of Object.entries(template.Outputs)) {
@@ -40341,5 +40487,5 @@ var DeployEngine = class DeployEngine {
40341
40487
  };
40342
40488
 
40343
40489
  //#endregion
40344
- export { collectInlinePolicyNamesManagedBySiblings as $, buildDockerImage as $n, IntrinsicResolutionRefusalError as $r, DagBuilder as $t, isStatefulRecreateTargetForReplace as A, importableOutputs as An, findLargeInlineResources as Ar, coerceCfnBoolean as At, gray as B, rewriteTemplateAssetReferences as Bn, clearBucketRegionCache as Br, withSharedDrainBudget as Bt, refusesFinalSnapshot as C, __exportAll as Ci, buildLockContentionMessage as Cn, resolveStateBucketWithDefaultAndSource as Cr, isUnboundTemplateParameter as Ct, makeSiblingClaimReader as D, DEFAULT_STATE_PREFIX as Dn, CFN_TEMPLATE_BODY_LIMIT as Dr, normalizeAwsTagsToCfn as Dt, extractDeploymentEventError as E, CUSTOM_RESOURCE_RESPONSE_PREFIX as En, warnDeprecatedNoPrefixCliFlag as Er, WAFv2WebACLProvider as Et, isWarmThroughputDecrease as F, stringifyValue as Fn, PARTITION_TABLE as Fr, requireConfigArray as Ft, collectPublishedOutputNames as G, getBootstrapMarkerKey as Gn, setAwsClients as Gr, s3BucketWebsiteUrl as Gt, red as H, BOOTSTRAP_MARKER_PREFIX as Hn, AwsClients as Hr, s3BucketDomainName as Ht, toFiniteNumber as I, WorkGraph as In, canonicalizeRegion as Ir, requireConfigObject as It, secretBearing as J, readBootstrapMarkerBody as Jn, ConfigError as Jr, INTRINSIC_KEYS as Jt, exportAliasCollisionScrubWarning as K, isCrossRegionRedirect as Kn, AssetError as Kr, applyRoleArnIfSet as Kt, formatResourceLine as L, buildAssetRedirectMap as Ln, derivePartitionAndUrlSuffix as Lr, requireConfigString as Lt, renderStatefulReason as M, orphansCarriedFrom as Mn, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Mr, configStringRefusal as Mt, WARM_THROUGHPUT_MEMBERS as N, shouldRetainResource as Nn, displaySafe as Nr, readConfigString as Nt, planOrphanAdoption as O, exportNamesCarriedFrom as On, CFN_TEMPLATE_URL_LIMIT as Or, resolveExplicitPhysicalId as Ot, coerceWarmThroughput as P, AssetPublisher as Pn, expectedOwnerParam as Pr, replayWarn as Pt, IAMRoleProvider as Q, describeAwsFailure as Qn, DynamicReferenceRegionAmbiguousError as Qr, withRetry as Qt, bold as R, createAssetRedirectResolver as Rn, AssemblyReader as Rr, classifyReplaySecretRegion as Rt, isFinalSnapshotError as S, retryClassificationText as Si, buildForceUnlockCommand as Sn, resolveStateBucketWithDefault as Sr, getAccountInfo as St, makeCanonicalizePropertiesFn as T, shellQuote as Tn, stateBucketExistenceConfirmed as Tr, refStateLookupFromResource as Tt, yellow as U, assertAssetBucketRegion as Un, getAwsClients as Ur, s3BucketDualStackDomainName as Ut, green as V, AssetModeResolver as Vn, resolveBucketRegion as Vr, s3BucketArn as Vt, collectDeclaredOutputNames as W, ensureAssetStorage as Wn, resetAwsClients as Wr, s3BucketRegionalDomainName as Wt, secretSafeKeyDisplay as X, validateContainerRepoName as Xn, DependencyError as Xr, findSilentDropProperties as Xt, secretBearingStateKeyWarning as Y, validateAssetBucketName as Yn, CrossAccountSecretRefusalError as Yr, findActionableSilentDrops as Yt, getCurrentResourceSecrets as Z, buildDenyExternalAccessPolicy as Zn, DeployCancelledError as Zr, describeTypeWithThrottleRetry as Zt, ATOMIC_FINAL_SNAPSHOT_TYPES as _, isRetryableTransientError as _i, scrubResourceRecord as _n, getLegacyStateBucketName as _r, isTerminationProtectionPropagationError as _t, DeploymentEventsStore as a, ProvisioningError as ai, carriesSecretMask as an, getDockerCmd as ar, maskerOrIdentity as at, ccRoutedFinalSnapshotError as b, markNonRetryable as bi, rebuildClientForBucketRegion as bn, resolveCaptureObservedState as br, cfnRefValueFromPhysicalId as bt, replayFailedOperations as c, StackHasActiveImportsError as ci, errorCauseChain as cn, runDockerForeground as cr, interruptWatchListenerCount as ct, updatePartialReason as d, SynthesisError as di, markSameGenerationBag as dn, stripControlChars as dr, CloudControlProvider as dt, LocalInvokeBuildError as ei, TemplateParser as en, describeDockerCapturedOutput as er, clearOnUpdateRemoval as et, withResourceDeadline as f, formatError as fi, maskSecretsInError as fn, AssetManifestLoader as fr, slowCcOperationTimeoutMs as ft, bindingSkippedOutputs as g, isMarkedNonRetryable as gi, redactSecretsForState as gn, getDefaultStateBucketName as gr, disableInstanceApiTermination as gt, computeImplicitDeleteEdges as h, withErrorHandling as hi, recoverMaskedOutput as hn, synthesisStatusMessage as hr, deleteSkipReason as ht, DeploymentEventsReader as i, PartialFailureError as ii, TEMPLATE_SOURCED_RULES as in, formatDockerLoginError as ir, maskDeep as it, isStatefulRecreateTargetSync as j, orphansAfterRollback as jn, uploadCfnTemplate as jr, configBooleanRefusal as jt, MULTI_REGION_RECREATE_BLOCKED_TYPES as k, importableOutputKeys as kn, MIGRATE_TMP_PREFIX as kr, assertRegionMatch as kt, replayRollback as l, StackTerminationProtectionError as li, identityKeyFor as ln, runDockerStreaming as lr, isInterruptedWaitError as lt, IMPLICIT_DELETE_DEPENDENCIES as m, normalizeAwsError as mi, recordMaskOnlyValue as mn, Synthesizer as mr, deleteIndeterminateGuards as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, LockError as ni, STATE_SOURCED_CROSS_GENERATION_RULES as nn, describeDockerFailure as nr, wouldReturnToSdkProvider as nt, planFailedOps as o, ResourceTimeoutError as oi, createSecretMasker as on, partitionSensitiveEnv as or, beginCommandInterruptScope as ot, maskingRetryLogger as p, isCdkdError as pi, maskSecretsInText as pn, getDockerImageBySourceHash as pr, UNSPECIFIED_SKIP_REASON as pt, isExportAliasCollision as q, parseBootstrapMarker as qn, CdkdError as qr, DiffCalculator as qt, DeployEngine as r, NestedStackChildDirectDestroyError as ri, STATE_SOURCED_READBACK_RULES as rn, dockerSpawnEnvWithSensitive as rr, createMaskedRetryLogger as rt, planRollback as s, ResourceUpdateNotSupportedError as si, dynamicReferenceTokens as sn, redactDockerArgvValues as sr, endCommandInterruptScope as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, LocalStartServiceError as ti, STATE_SOURCED_BASELINE_RULES as tn, describeDockerExecFailure as tr, ProviderRegistry as tt, updatePartialMessage as u, StateError as ui, isSingleDynamicReferenceToken as un, escapeRegExp$1 as ur, startInterruptWatch as ut, PRE_DELETE_SNAPSHOT_TYPES as v, isThrottlingError as vi, LockManager as vn, resolveApp as vr, IntrinsicFunctionResolver as vt, unsupportedFinalSnapshotError as w, forceQuitRecoveryClause as wn, resolveUseCdkBootstrapAssets as wr, parameterTypeMayLoseSecretIdentity as wt, createPreDeleteFinalSnapshot as x, markRedactedCause as xi, UNRENDERABLE as xn, resolveSkipPrefix as xr, coerceParameterTypedValue as xt, buildFinalSnapshotIdentifier as y, isTransientServerError as yi, S3StateBackend as yn, resolveAutoAssetStorage as yr, carriesDynamicReference as yt, cyan as z, loadPublishableAssetManifest as zn, processStackMessages as zr, producerRegionsFromState as zt };
40345
- //# sourceMappingURL=deploy-engine-DAykhfpV.js.map
40490
+ export { collectInlinePolicyNamesManagedBySiblings as $, buildDockerImage as $n, LocalInvokeBuildError as $r, DagBuilder as $t, isStatefulRecreateTargetForReplace as A, importableOutputs as An, findLargeInlineResources as Ar, coerceCfnBoolean as At, gray as B, rewriteTemplateAssetReferences as Bn, resolveBucketRegion as Br, withSharedDrainBudget as Bt, refusesFinalSnapshot as C, buildLockContentionMessage as Cn, resolveStateBucketWithDefaultAndSource as Cr, isUnboundTemplateParameter as Ct, makeSiblingClaimReader as D, DEFAULT_STATE_PREFIX as Dn, CFN_TEMPLATE_BODY_LIMIT as Dr, normalizeAwsTagsToCfn as Dt, extractDeploymentEventError as E, CUSTOM_RESOURCE_RESPONSE_PREFIX as En, warnDeprecatedNoPrefixCliFlag as Er, WAFv2WebACLProvider as Et, isWarmThroughputDecrease as F, stringifyValue as Fn, canonicalizeRegion as Fr, requireConfigArray as Ft, collectPublishedOutputNames as G, getBootstrapMarkerKey as Gn, AssetError as Gr, s3BucketWebsiteUrl as Gt, red as H, BOOTSTRAP_MARKER_PREFIX as Hn, getAwsClients as Hr, s3BucketDomainName as Ht, toFiniteNumber as I, WorkGraph as In, derivePartitionAndUrlSuffix as Ir, requireConfigObject as It, secretBearing as J, readBootstrapMarkerBody as Jn, CrossAccountSecretRefusalError as Jr, INTRINSIC_KEYS as Jt, exportAliasCollisionScrubWarning as K, isCrossRegionRedirect as Kn, CdkdError as Kr, applyRoleArnIfSet as Kt, formatResourceLine as L, buildAssetRedirectMap as Ln, AssemblyReader as Lr, requireConfigString as Lt, renderStatefulReason as M, orphansCarriedFrom as Mn, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Mr, configStringRefusal as Mt, WARM_THROUGHPUT_MEMBERS as N, shouldRetainResource as Nn, expectedOwnerParam as Nr, readConfigString as Nt, planOrphanAdoption as O, exportNamesCarriedFrom as On, CFN_TEMPLATE_URL_LIMIT as Or, resolveExplicitPhysicalId as Ot, coerceWarmThroughput as P, AssetPublisher as Pn, PARTITION_TABLE as Pr, replayWarn as Pt, IAMRoleProvider as Q, describeAwsFailure as Qn, IntrinsicResolutionRefusalError as Qr, withRetry as Qt, bold as R, createAssetRedirectResolver as Rn, processStackMessages as Rr, classifyReplaySecretRegion as Rt, isFinalSnapshotError as S, __exportAll as Si, buildForceUnlockCommand as Sn, resolveStateBucketWithDefault as Sr, getAccountInfo as St, makeCanonicalizePropertiesFn as T, shellQuote as Tn, stateBucketExistenceConfirmed as Tr, refStateLookupFromResource as Tt, yellow as U, assertAssetBucketRegion as Un, resetAwsClients as Ur, s3BucketDualStackDomainName as Ut, green as V, AssetModeResolver as Vn, AwsClients as Vr, s3BucketArn as Vt, collectDeclaredOutputNames as W, ensureAssetStorage as Wn, setAwsClients as Wr, s3BucketRegionalDomainName as Wt, secretSafeKeyDisplay as X, validateContainerRepoName as Xn, DeployCancelledError as Xr, findSilentDropProperties as Xt, secretBearingStateKeyWarning as Y, validateAssetBucketName as Yn, DependencyError as Yr, findActionableSilentDrops as Yt, getCurrentResourceSecrets as Z, buildDenyExternalAccessPolicy as Zn, DynamicReferenceRegionAmbiguousError as Zr, describeTypeWithThrottleRetry as Zt, ATOMIC_FINAL_SNAPSHOT_TYPES as _, isThrottlingError as _i, scrubResourceRecord as _n, getLegacyStateBucketName as _r, isTerminationProtectionPropagationError as _t, DeploymentEventsStore as a, ResourceTimeoutError as ai, carriesSecretMask as an, getDockerCmd as ar, maskerOrIdentity as at, ccRoutedFinalSnapshotError as b, markRedactedCause as bi, rebuildClientForBucketRegion as bn, resolveCaptureObservedState as br, cfnRefValueFromPhysicalId as bt, replayFailedOperations as c, StackTerminationProtectionError as ci, errorCauseChain as cn, runDockerForeground as cr, interruptWatchListenerCount as ct, updatePartialReason as d, formatError as di, markSameGenerationBag as dn, stripControlChars as dr, CloudControlProvider as dt, LocalStartServiceError as ei, TemplateParser as en, describeDockerCapturedOutput as er, clearOnUpdateRemoval as et, withResourceDeadline as f, isCdkdError as fi, maskSecretsInError as fn, AssetManifestLoader as fr, slowCcOperationTimeoutMs as ft, bindingSkippedOutputs as g, isRetryableTransientError as gi, redactSecretsForState as gn, getDefaultStateBucketName as gr, disableInstanceApiTermination as gt, computeImplicitDeleteEdges as h, isMarkedNonRetryable as hi, recoverMaskedOutput as hn, synthesisStatusMessage as hr, deleteSkipReason as ht, DeploymentEventsReader as i, ProvisioningError as ii, TEMPLATE_SOURCED_RULES as in, formatDockerLoginError as ir, maskDeep as it, isStatefulRecreateTargetSync as j, orphansAfterRollback as jn, uploadCfnTemplate as jr, configBooleanRefusal as jt, MULTI_REGION_RECREATE_BLOCKED_TYPES as k, importableOutputKeys as kn, MIGRATE_TMP_PREFIX as kr, assertRegionMatch as kt, replayRollback as l, StateError as li, identityKeyFor as ln, runDockerStreaming as lr, isInterruptedWaitError as lt, IMPLICIT_DELETE_DEPENDENCIES as m, withErrorHandling as mi, recordMaskOnlyValue as mn, Synthesizer as mr, deleteIndeterminateGuards as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, NestedStackChildDirectDestroyError as ni, STATE_SOURCED_CROSS_GENERATION_RULES as nn, describeDockerFailure as nr, wouldReturnToSdkProvider as nt, planFailedOps as o, ResourceUpdateNotSupportedError as oi, createSecretMasker as on, partitionSensitiveEnv as or, beginCommandInterruptScope as ot, maskingRetryLogger as p, normalizeAwsError as pi, maskSecretsInText as pn, getDockerImageBySourceHash as pr, UNSPECIFIED_SKIP_REASON as pt, isExportAliasCollision as q, parseBootstrapMarker as qn, ConfigError as qr, DiffCalculator as qt, DeployEngine as r, PartialFailureError as ri, STATE_SOURCED_READBACK_RULES as rn, dockerSpawnEnvWithSensitive as rr, createMaskedRetryLogger as rt, planRollback as s, StackHasActiveImportsError as si, dynamicReferenceTokens as sn, redactDockerArgvValues as sr, endCommandInterruptScope as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, LockError as ti, STATE_SOURCED_BASELINE_RULES as tn, describeDockerExecFailure as tr, ProviderRegistry as tt, updatePartialMessage as u, SynthesisError as ui, isSingleDynamicReferenceToken as un, escapeRegExp$1 as ur, startInterruptWatch as ut, PRE_DELETE_SNAPSHOT_TYPES as v, isTransientServerError as vi, LockManager as vn, resolveApp as vr, IntrinsicFunctionResolver as vt, unsupportedFinalSnapshotError as w, forceQuitRecoveryClause as wn, resolveUseCdkBootstrapAssets as wr, parameterTypeMayLoseSecretIdentity as wt, createPreDeleteFinalSnapshot as x, retryClassificationText as xi, UNRENDERABLE as xn, resolveSkipPrefix as xr, coerceParameterTypedValue as xt, buildFinalSnapshotIdentifier as y, markNonRetryable as yi, S3StateBackend as yn, resolveAutoAssetStorage as yr, carriesDynamicReference as yt, cyan as z, loadPublishableAssetManifest as zn, clearBucketRegionCache as zr, producerRegionsFromState as zt };
40491
+ //# sourceMappingURL=deploy-engine-BEpYvI14.js.map