@go-to-k/cdkd 0.284.11 → 0.284.13

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.
@@ -11095,6 +11095,159 @@ function maskSecretsInText(text, secrets) {
11095
11095
  return text.replace(regex, "***");
11096
11096
  }
11097
11097
  /**
11098
+ * How deep {@link maskSecretsInError} follows a `cause` chain. A CYCLE is
11099
+ * already handled by the visited-set, so this bounds only a pathologically long
11100
+ * chain; the same bounded-walk shape `extractDeploymentEventError` (depth 10)
11101
+ * and the retry classifiers (depth 5) use. A link BEYOND the cap keeps its
11102
+ * original, UNMASKED message, and the last cloned link points at it.
11103
+ */
11104
+ const ERROR_CAUSE_MASK_MAX_DEPTH = 20;
11105
+ /**
11106
+ * The `cause` chain of `root`, root first, stopping at the first non-`Error`
11107
+ * link, at a link already visited (so a cycle terminates instead of hanging),
11108
+ * or at {@link ERROR_CAUSE_MASK_MAX_DEPTH}.
11109
+ */
11110
+ function errorCauseChain(root) {
11111
+ const chain = [];
11112
+ const seen = /* @__PURE__ */ new Set();
11113
+ let current = root;
11114
+ while (current instanceof Error && !seen.has(current) && chain.length < ERROR_CAUSE_MASK_MAX_DEPTH) {
11115
+ seen.add(current);
11116
+ chain.push(current);
11117
+ current = current.cause;
11118
+ }
11119
+ return chain;
11120
+ }
11121
+ /**
11122
+ * Return `error` with {@link maskSecretsInText} applied to the `message` AND the
11123
+ * `stack` of every link in its `cause` chain, with everything else about each
11124
+ * link preserved (issue [#2038](https://github.com/go-to-k/cdkd/issues/2038)
11125
+ * review).
11126
+ *
11127
+ * Two bounds on that "every link", both stated here because the PUBLIC contract
11128
+ * is what a caller reads and neither is visible from the call site:
11129
+ * - The walk stops at {@link ERROR_CAUSE_MASK_MAX_DEPTH}. A chain longer than
11130
+ * that keeps its remaining links' ORIGINAL, UNMASKED messages, and the last
11131
+ * cloned link points straight at them.
11132
+ * - A `cause` that is not an `Error` (a string, a plain object) is carried
11133
+ * through VERBATIM and is never masked — the walk has nothing to clone. No
11134
+ * cdkd or AWS SDK site constructs one today, so this is a documented residual
11135
+ * rather than a reachable leak, but a caller attaching arbitrary data as a
11136
+ * `cause` must mask it itself. `src/cli/index.ts`'s `console.error` renders
11137
+ * such a cause via `util.inspect`, so it WOULD reach the terminal.
11138
+ *
11139
+ * **Why an error and not just its text.** `formatError` (`src/utils/error-handler.ts`)
11140
+ * renders a `CdkdError`'s CAUSE as `Caused by: <cause.message>`, and `handleError`
11141
+ * logs that at `error` level for any failure that escapes a command — so a raw
11142
+ * provider error attached as a `ProvisioningError`'s cause reaches the terminal
11143
+ * verbatim, at DEFAULT verbosity, even when every log site that INTERPOLATED
11144
+ * the message masked it. Masking the string at each log site cannot close that:
11145
+ * the sink reads the error OBJECT.
11146
+ *
11147
+ * `formatError` is not the only such sink, and the second one is what makes the
11148
+ * CHAIN argument below concrete rather than hypothetical: `src/cli/index.ts`'s
11149
+ * top-level `main().catch(...)` does `console.error('Fatal error:', error)`,
11150
+ * which renders the whole object through `util.inspect` — every `[cause]` link
11151
+ * AND every link's `stack`. Measured: an outer `Error('top')` wrapping
11152
+ * `Error("Value 'hunter2' failed")` prints as
11153
+ * `Error: top ... { [cause]: Error: Value 'hunter2' failed ... }`. So a
11154
+ * multi-level sink exists TODAY, and it is why `stack` is masked below rather
11155
+ * than merely preserved.
11156
+ *
11157
+ * **Why the whole CHAIN and not just the top link.** Masking only `error.message`
11158
+ * looks sufficient because `formatError` renders one level — and it is not, in
11159
+ * two ways that a top-level-only fix gets exactly backwards. A provider that
11160
+ * wraps an AWS failure in a generic sentence (`new Error('the call failed',
11161
+ * { cause: awsError })`) leaves the plaintext ONE link down, where the
11162
+ * identity-return below then reports "nothing to mask" and hands back an object
11163
+ * still carrying it — the function's own contract says the returned error is
11164
+ * safe to render, and every later reader believes it. And `formatError`
11165
+ * rendering a single level is an implementation detail: one edit there (walking
11166
+ * the chain is the obvious improvement) re-opens the hole with nothing failing.
11167
+ * So the invariant is about the OBJECT, not about today's renderer.
11168
+ *
11169
+ * **Why a clone rather than assigning to `error.message`.** The argument is an
11170
+ * error cdkd did not create — usually the AWS SDK's — and mutating a caller's
11171
+ * object is visible to every other holder of it, including a retry loop that
11172
+ * may still classify it. Each link's clone copies the prototype and EVERY own
11173
+ * property descriptor, symbols included, so the three things that read a cause
11174
+ * chain keep working: `isMarkedNonRetryable` (a non-enumerable `Symbol.for`
11175
+ * marker), `extractDeploymentEventError` / `isThrottlingError` /
11176
+ * `isTransientServerError` (`$metadata`, `Code`, `name`), and the chain itself.
11177
+ * `Object.assign` would have dropped the marker, which is why the descriptors
11178
+ * form is used.
11179
+ *
11180
+ * `message`, `cause` and `stack` are the three descriptors deliberately NOT
11181
+ * copied through: each is re-defined per link, and copying a NON-CONFIGURABLE
11182
+ * original would make that re-definition throw. `cause` is rewired to the CLONE
11183
+ * of whatever it pointed at, in a second pass over the already-built clone map —
11184
+ * which is what makes a cyclic chain terminate rather than recurse. A `cause`
11185
+ * that is not an `Error` (a string, a plain object) keeps its original
11186
+ * descriptor verbatim.
11187
+ *
11188
+ * **Why `stack` is re-defined as DATA rather than copied.** V8 installs `stack`
11189
+ * as an own ACCESSOR whose getter reads a slot the engine attaches to an error
11190
+ * IT created, so copying that descriptor onto an `Object.create` clone yields a
11191
+ * getter with nothing behind it and `clone.stack` reads `undefined` (measured).
11192
+ * That is not a leak today — the clone is only ever reached as a `cause`, and
11193
+ * `handleError` prints the TOP-level error's stack — but this function is
11194
+ * exported and generic, so a future top-level caller would get back an error
11195
+ * with no trace at all. The clone therefore carries a masked COPY of the
11196
+ * original's stack text, which both preserves the trace and closes the sink the
11197
+ * copy would otherwise open: a stack's first line embeds the message, so an
11198
+ * unmasked stack re-exposes exactly the plaintext the `message` mask removed —
11199
+ * and `util.inspect` prints it. An original with no readable string `stack`
11200
+ * (not an engine-created error) simply gets no own `stack`, as before.
11201
+ *
11202
+ * Returns the ORIGINAL object by identity when NOTHING ANYWHERE IN THE CHAIN
11203
+ * changed, so a non-secret failure keeps referential equality and the common
11204
+ * path allocates nothing.
11205
+ */
11206
+ function maskSecretsInError(error, secrets) {
11207
+ if (secrets.size === 0 || !(error instanceof Error)) return error;
11208
+ const chain = errorCauseChain(error);
11209
+ const maskedMessages = chain.map((link) => maskSecretsInText(link.message, secrets));
11210
+ if (maskedMessages.every((masked, i) => masked === chain[i].message)) return error;
11211
+ const clones = /* @__PURE__ */ new Map();
11212
+ for (const [i, original] of chain.entries()) {
11213
+ const descriptors = {};
11214
+ for (const key of Reflect.ownKeys(original)) {
11215
+ if (key === "message" || key === "cause" || key === "stack") continue;
11216
+ const descriptor = Object.getOwnPropertyDescriptor(original, key);
11217
+ if (descriptor) descriptors[key] = descriptor;
11218
+ }
11219
+ const clone = Object.create(Object.getPrototypeOf(original), descriptors);
11220
+ Object.defineProperty(clone, "message", {
11221
+ value: maskedMessages[i],
11222
+ writable: true,
11223
+ enumerable: false,
11224
+ configurable: true
11225
+ });
11226
+ const originalStack = original.stack;
11227
+ if (typeof originalStack === "string") Object.defineProperty(clone, "stack", {
11228
+ value: maskSecretsInText(originalStack, secrets),
11229
+ writable: true,
11230
+ enumerable: false,
11231
+ configurable: true
11232
+ });
11233
+ clones.set(original, clone);
11234
+ }
11235
+ for (const original of chain) {
11236
+ const causeDescriptor = Object.getOwnPropertyDescriptor(original, "cause");
11237
+ if (!causeDescriptor) continue;
11238
+ const clone = clones.get(original);
11239
+ const causeValue = original.cause;
11240
+ const replacement = causeValue instanceof Error ? clones.get(causeValue) : void 0;
11241
+ Object.defineProperty(clone, "cause", replacement ? {
11242
+ value: replacement,
11243
+ writable: true,
11244
+ enumerable: causeDescriptor.enumerable === true,
11245
+ configurable: true
11246
+ } : causeDescriptor);
11247
+ }
11248
+ return clones.get(error);
11249
+ }
11250
+ /**
11098
11251
  * Bind a {@link RecordedSecretValues} bag into a {@link SecretMasker} for a
11099
11252
  * caller to hand to a provider.
11100
11253
  *
@@ -16053,7 +16206,7 @@ var CloudControlProvider = class {
16053
16206
  if (context?.finalSnapshotIdentifier !== void 0) throw new ProvisioningError(`${logicalId} (${resourceType}) requires a final snapshot (DeletionPolicy: Snapshot), but the Cloud Control API delete route has no final-snapshot parameter. Re-run with --skip-final-snapshot after snapshotting manually, or retain the resource.`, resourceType, logicalId, physicalId);
16054
16207
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
16055
16208
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
16056
- const { ASGProvider } = await import("./asg-provider-C9OlqHee.js").then((n) => n.n);
16209
+ const { ASGProvider } = await import("./asg-provider-H-Dl8qng.js").then((n) => n.n);
16057
16210
  return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
16058
16211
  }
16059
16212
  const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
@@ -22877,6 +23030,22 @@ function computeImplicitDeleteEdges(resources) {
22877
23030
  return edges;
22878
23031
  }
22879
23032
 
23033
+ //#endregion
23034
+ //#region src/deployment/masking-retry-logger.ts
23035
+ /**
23036
+ * Bind `logger` to `secrets`, masking every line the retry loop emits.
23037
+ *
23038
+ * No-op when the caller resolved no secret ({@link maskSecretsInText} returns
23039
+ * the text unchanged for an empty bag), so a non-secret resource's output is
23040
+ * byte-identical to threading the raw logger.
23041
+ */
23042
+ function maskingRetryLogger(logger, secrets) {
23043
+ return {
23044
+ debug: (msg) => logger.debug(maskSecretsInText(msg, secrets)),
23045
+ warn: (msg) => logger.warn(maskSecretsInText(msg, secrets))
23046
+ };
23047
+ }
23048
+
22880
23049
  //#endregion
22881
23050
  //#region src/deployment/resource-deadline.ts
22882
23051
  /**
@@ -23156,6 +23325,38 @@ function replayingStateCreateContext(secrets) {
23156
23325
  };
23157
23326
  }
23158
23327
  /**
23328
+ * The {@link DeploymentEventError} a failed replay records, with this op's
23329
+ * re-resolved secrets masked out of its message (issue
23330
+ * [#2031](https://github.com/go-to-k/cdkd/issues/2031) acceptance item 2).
23331
+ *
23332
+ * `extractDeploymentEventError` copies `err.message` VERBATIM, and the events
23333
+ * store is a DURABLE sink — `deployments/{runId}.jsonl` in S3 outlives the
23334
+ * terminal the `logger.warn` beside it scrolls past, and `cdkd events` replays
23335
+ * it later. The standalone `cdkd rollback` command wires
23336
+ * `recordEvent: (e) => eventRecorder.record(e)` (`src/cli/commands/rollback.ts`)
23337
+ * with NO masking of its own, so without this the plaintext the terminal line
23338
+ * masks is persisted one statement later.
23339
+ *
23340
+ * The in-process caller (`DeployEngine.rollbackExecutorContext`) routes through
23341
+ * `maskSecretsInEvent`, but that masks with the DEPLOY's `perResourceSecrets`
23342
+ * for the resource — a different bag from the one this replay re-resolved from
23343
+ * the JOURNAL, which can name a different secret version or a reference the
23344
+ * deploy never resolved. Masking here is what makes both callers equal, and
23345
+ * double-masking is a no-op (the mask is not a key of either bag).
23346
+ *
23347
+ * `name` / `awsErrorCode` / `requestId` are deliberately left alone: they are
23348
+ * AWS-authored identifiers, not message text, and #2038 traced all three as
23349
+ * non-sensitive.
23350
+ */
23351
+ function maskedRollbackEventError(error, secrets) {
23352
+ const extracted = extractDeploymentEventError(error);
23353
+ if (secrets.size === 0) return extracted;
23354
+ return {
23355
+ ...extracted,
23356
+ message: maskSecretsInText(extracted.message, secrets)
23357
+ };
23358
+ }
23359
+ /**
23159
23360
  * Which provisioning layer a delete must be judged against: the CURRENT
23160
23361
  * state record wins (it is what state says AWS holds right now), with the
23161
23362
  * journaled op's routing as the legacy-state fallback. Shared by both
@@ -23514,10 +23715,10 @@ function redactRollbackRecord(record, secrets, journaledProps) {
23514
23715
  properties: redactSecretsForState(record.properties, secrets, journaledProps, STATE_DERIVED_RULES)
23515
23716
  }, secrets);
23516
23717
  }
23517
- async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted) {
23718
+ async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted, secrets) {
23518
23719
  if (provider.disableOuterRetry) return await provider.update(...args);
23519
23720
  return await withRetry(() => provider.update(...args), logicalId, {
23520
- logger,
23721
+ logger: maskingRetryLogger(logger, secrets),
23521
23722
  ...isInterrupted && {
23522
23723
  isInterrupted,
23523
23724
  onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while retrying a resource update")
@@ -23572,6 +23773,21 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23572
23773
  const action = classifyRollbackOp(op, stateResources, orphanLogicalIds);
23573
23774
  const { logger } = ctx;
23574
23775
  /**
23776
+ * This op's `plaintext -> {{resolve:...}}expression` bag, filled by
23777
+ * {@link resolveReplayProps} on whichever arm runs (issues
23778
+ * [#2038](https://github.com/go-to-k/cdkd/issues/2038) /
23779
+ * [#2031](https://github.com/go-to-k/cdkd/issues/2031)).
23780
+ *
23781
+ * HOISTED above the `try` rather than declared per arm, which is what the
23782
+ * two arms used to do: the shared catch below logs the thrown AWS message and
23783
+ * persists it to the events store, and it cannot see a binding scoped to the
23784
+ * arm that threw. Exactly one arm runs per call, so a single per-op bag is
23785
+ * equivalent to the per-arm ones for every existing reader (`secrets.size`
23786
+ * stays 0 on the arms that resolve nothing, so `redactRollbackRecord` and the
23787
+ * maskers keep their identity behavior).
23788
+ */
23789
+ const secrets = /* @__PURE__ */ new Map();
23790
+ /**
23575
23791
  * The route a CREATE-rollback arm resolved for this op (issue #1366) —
23576
23792
  * hoisted so the shared catch's ROLLBACK_RESOURCE_FAILED reports the route
23577
23793
  * the delete was going to take, which is the one a refusal is about. Stays
@@ -23695,7 +23911,6 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23695
23911
  case "reverse-replacement": {
23696
23912
  const current = stateResources[op.logicalId];
23697
23913
  const prev = op.previousState;
23698
- const secrets = /* @__PURE__ */ new Map();
23699
23914
  const resolvedPrevProps = await resolveReplayProps(prev.properties, resolver, secrets) ?? {};
23700
23915
  logger.info(` Rollback: Reversing replacement of ${op.logicalId} (${op.resourceType}) — re-creating the old resource and deleting the new one`);
23701
23916
  if (STATEFUL_TYPES.has(op.resourceType)) logger.warn(` ⚠ ${op.logicalId} (${op.resourceType}) is a stateful type — the old physical resource's data was destroyed by the replacement and CANNOT be recovered; the re-created resource starts empty.`);
@@ -23712,7 +23927,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23712
23927
  try {
23713
23928
  createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, {
23714
23929
  ...RECREATE_RETRY_SCHEDULE,
23715
- logger,
23930
+ logger: maskingRetryLogger(logger, secrets),
23716
23931
  ...isInterrupted && {
23717
23932
  isInterrupted,
23718
23933
  onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while waiting out the name cooldown")
@@ -23735,7 +23950,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23735
23950
  try {
23736
23951
  createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, {
23737
23952
  ...RECREATE_RETRY_SCHEDULE,
23738
- logger,
23953
+ logger: maskingRetryLogger(logger, secrets),
23739
23954
  ...isInterrupted && {
23740
23955
  isInterrupted,
23741
23956
  onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while waiting for the old name to release")
@@ -23743,7 +23958,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23743
23958
  isRetryable: isRecreateRetryableError
23744
23959
  });
23745
23960
  } catch (recreateError) {
23746
- throw new Error(`Failed to re-create the old ${op.logicalId} after the new resource (${current.physicalId}) was already deleted: ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. The resource is now absent — fix forward with 'cdkd deploy'.`);
23961
+ throw new Error(maskSecretsInText(`Failed to re-create the old ${op.logicalId} after the new resource (${current.physicalId}) was already deleted: ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. The resource is now absent — fix forward with 'cdkd deploy'.`, secrets));
23747
23962
  }
23748
23963
  }
23749
23964
  const adoptedLiveNewResource = !deletedNewFirst && createResult.physicalId === current.physicalId;
@@ -23766,7 +23981,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23766
23981
  ...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier }
23767
23982
  }), op.logicalId, current.physicalId, "while deleting the new resource after re-creating the old one");
23768
23983
  } catch (deleteError) {
23769
- logger.warn(` Rollback: old ${op.logicalId} re-created, but deleting the new resource (${current.physicalId}) failed: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}. Delete it manually — it is no longer tracked in state.`);
23984
+ logger.warn(maskSecretsInText(` Rollback: old ${op.logicalId} re-created, but deleting the new resource (${current.physicalId}) failed: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}. Delete it manually — it is no longer tracked in state.`, secrets));
23770
23985
  result.warnings++;
23771
23986
  }
23772
23987
  logger.info(adoptedLiveNewResource ? ` Rollback: ${op.logicalId} adopted the live resource (${createResult.physicalId}) — replacement NOT fully reversed (name-idempotent Create API)` : ` Rollback: ${op.logicalId} replacement reversed (old resource re-created as ${createResult.physicalId})`);
@@ -23798,7 +24013,6 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23798
24013
  resourceType: op.resourceType,
23799
24014
  provisionedBy: op.provisionedBy
23800
24015
  });
23801
- const secrets = /* @__PURE__ */ new Map();
23802
24016
  const desiredProps = await resolveReplayProps(previousState.properties, resolver, secrets);
23803
24017
  const currentProps = await resolveReplayProps(current.properties, resolver, secrets);
23804
24018
  const revertResult = await updateWithRollbackRetry(provider, [
@@ -23808,10 +24022,10 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23808
24022
  desiredProps ?? {},
23809
24023
  currentProps ?? {},
23810
24024
  { maskSecrets: createSecretMasker(secrets) }
23811
- ], op.logicalId, logger, isInterrupted);
24025
+ ], op.logicalId, logger, isInterrupted, secrets);
23812
24026
  stateResources[op.logicalId] = redactRollbackRecord(recordAfterRollbackUpdate(previousState, revertResult), secrets, previousState.properties);
23813
24027
  const rollbackPartial = updatePartialReason(revertResult);
23814
- if (rollbackPartial !== void 0) logger.warn(` Rollback: ${op.logicalId} restored, ${updatePartialMessage(rollbackPartial)}`);
24028
+ if (rollbackPartial !== void 0) logger.warn(maskSecretsInText(` Rollback: ${op.logicalId} restored, ${updatePartialMessage(rollbackPartial)}`, secrets));
23815
24029
  else logger.info(` Rollback: ${op.logicalId} restored successfully`);
23816
24030
  await afterOp?.(op.logicalId);
23817
24031
  ctx.recordEvent?.({
@@ -23821,13 +24035,13 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23821
24035
  logicalId: op.logicalId,
23822
24036
  resourceType: op.resourceType,
23823
24037
  ...op.provisionedBy && { provisionedBy: op.provisionedBy },
23824
- ...rollbackPartial !== void 0 && { reason: rollbackPartial }
24038
+ ...rollbackPartial !== void 0 && { reason: maskSecretsInText(rollbackPartial, secrets) }
23825
24039
  });
23826
24040
  return;
23827
24041
  }
23828
24042
  }
23829
24043
  } catch (rollbackError) {
23830
- logger.warn(` Rollback failed for ${op.logicalId} (${op.changeType}): ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`);
24044
+ logger.warn(maskSecretsInText(` Rollback failed for ${op.logicalId} (${op.changeType}): ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`, secrets));
23831
24045
  logger.warn(" Continuing with remaining rollback operations...");
23832
24046
  result.failures++;
23833
24047
  const failedRoute = createRollbackRoute ?? op.provisionedBy;
@@ -23838,7 +24052,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
23838
24052
  logicalId: op.logicalId,
23839
24053
  resourceType: op.resourceType,
23840
24054
  ...failedRoute && { provisionedBy: failedRoute },
23841
- error: extractDeploymentEventError(rollbackError)
24055
+ error: maskedRollbackEventError(rollbackError, secrets)
23842
24056
  });
23843
24057
  }
23844
24058
  }
@@ -23875,6 +24089,15 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
23875
24089
  }
23876
24090
  const op = failedOps[i];
23877
24091
  const action = classifyFailedOp(op, stateResources);
24092
+ /**
24093
+ * This op's re-resolved secret bag — the twin of `replaySingle`'s, and
24094
+ * hoisted above this iteration's `try` for the same reason (issues #2038 /
24095
+ * #2031): the shared catch below logs the thrown AWS message and persists it
24096
+ * to the events store, and could not see a binding scoped to the arm that
24097
+ * threw. Re-created per ITERATION, so one op's secrets can never mask
24098
+ * another's text.
24099
+ */
24100
+ const secrets = /* @__PURE__ */ new Map();
23878
24101
  let createRollbackRoute;
23879
24102
  try {
23880
24103
  switch (action) {
@@ -23942,7 +24165,6 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
23942
24165
  resourceType: op.resourceType,
23943
24166
  provisionedBy: op.provisionedBy ?? current.provisionedBy
23944
24167
  });
23945
- const secrets = /* @__PURE__ */ new Map();
23946
24168
  const desiredProps = await resolveReplayProps(prev.properties, resolver, secrets);
23947
24169
  const attemptedProps = await resolveReplayProps(op.attemptedProperties ?? current.properties, resolver, secrets);
23948
24170
  const revertFailedResult = await updateWithRollbackRetry(provider, [
@@ -23952,10 +24174,10 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
23952
24174
  desiredProps ?? {},
23953
24175
  attemptedProps ?? {},
23954
24176
  { maskSecrets: createSecretMasker(secrets) }
23955
- ], op.logicalId, logger, options.isInterrupted);
24177
+ ], op.logicalId, logger, options.isInterrupted, secrets);
23956
24178
  stateResources[op.logicalId] = redactRollbackRecord(recordAfterRollbackUpdate(prev, revertFailedResult), secrets, prev.properties);
23957
24179
  const revertFailedPartial = updatePartialReason(revertFailedResult);
23958
- if (revertFailedPartial !== void 0) logger.warn(` Rollback: ${op.logicalId} reverted, ${updatePartialMessage(revertFailedPartial)}`);
24180
+ if (revertFailedPartial !== void 0) logger.warn(maskSecretsInText(` Rollback: ${op.logicalId} reverted, ${updatePartialMessage(revertFailedPartial)}`, secrets));
23959
24181
  else logger.info(` Rollback: ${op.logicalId} reverted successfully`);
23960
24182
  await options.afterOp?.(op.logicalId);
23961
24183
  ctx.recordEvent?.({
@@ -23965,13 +24187,13 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
23965
24187
  logicalId: op.logicalId,
23966
24188
  resourceType: op.resourceType,
23967
24189
  ...op.provisionedBy && { provisionedBy: op.provisionedBy },
23968
- ...revertFailedPartial !== void 0 && { reason: revertFailedPartial }
24190
+ ...revertFailedPartial !== void 0 && { reason: maskSecretsInText(revertFailedPartial, secrets) }
23969
24191
  });
23970
24192
  break;
23971
24193
  }
23972
24194
  }
23973
24195
  } catch (revertError) {
23974
- logger.warn(` Rollback failed for failed-op ${op.logicalId} (${op.changeType}): ${revertError instanceof Error ? revertError.message : String(revertError)}`);
24196
+ logger.warn(maskSecretsInText(` Rollback failed for failed-op ${op.logicalId} (${op.changeType}): ${revertError instanceof Error ? revertError.message : String(revertError)}`, secrets));
23975
24197
  result.failures++;
23976
24198
  pending.add(op);
23977
24199
  const failedRoute = createRollbackRoute ?? op.provisionedBy;
@@ -23982,7 +24204,7 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
23982
24204
  logicalId: op.logicalId,
23983
24205
  resourceType: op.resourceType,
23984
24206
  ...failedRoute && { provisionedBy: failedRoute },
23985
- error: extractDeploymentEventError(revertError)
24207
+ error: maskedRollbackEventError(revertError, secrets)
23986
24208
  });
23987
24209
  }
23988
24210
  }
@@ -24082,7 +24304,7 @@ const FLUSH_INTERVAL_MS = 2e3;
24082
24304
  const FLUSH_EVENT_THRESHOLD = 50;
24083
24305
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
24084
24306
  function getCdkdVersion() {
24085
- return "0.284.11";
24307
+ return "0.284.13";
24086
24308
  }
24087
24309
  /**
24088
24310
  * Generate a time-sortable unique run id, e.g.
@@ -24547,6 +24769,14 @@ var DeploymentEventsReader = class {
24547
24769
  //#endregion
24548
24770
  //#region src/deployment/deploy-engine.ts
24549
24771
  /**
24772
+ * The bag a resource with no recorded secret masks against (issue #2038).
24773
+ * Shared so the "no entry" path allocates nothing and — more usefully — so
24774
+ * every masking site takes the SAME branch: `maskSecretsInText` /
24775
+ * `maskSecretsInError` both return their input unchanged for an empty bag, so
24776
+ * an absent entry and an empty one cannot behave differently. Never written to.
24777
+ */
24778
+ const EMPTY_SECRETS = /* @__PURE__ */ new Map();
24779
+ /**
24550
24780
  * Default per-resource warn threshold: warn the user when a single
24551
24781
  * resource has been in flight for 5 minutes. Most CC API resources
24552
24782
  * complete in under a minute; 5m is the agreed elbow.
@@ -25750,7 +25980,7 @@ var DeployEngine = class {
25750
25980
  } catch (error) {
25751
25981
  renderer.removeTask(logicalId);
25752
25982
  const message = error instanceof Error ? error.message : String(error);
25753
- this.logger.error(`Failed to ${change.changeType.toLowerCase()} ${logicalId}: ${message}`);
25983
+ this.logger.error(this.maskForResource(logicalId, `Failed to ${change.changeType.toLowerCase()} ${logicalId}: ${message}`));
25754
25984
  this.recordEvent({
25755
25985
  eventType: "RESOURCE_FAILED",
25756
25986
  stackName,
@@ -25761,7 +25991,7 @@ var DeployEngine = class {
25761
25991
  durationMs: Date.now() - resourceStartedAt,
25762
25992
  error: extractDeploymentEventError(error)
25763
25993
  });
25764
- throw new ProvisioningError(`Failed to ${change.changeType.toLowerCase()} resource ${logicalId}`, resourceType, logicalId, stateResources[logicalId]?.physicalId, error instanceof Error ? error : void 0);
25994
+ throw new ProvisioningError(`Failed to ${change.changeType.toLowerCase()} resource ${logicalId}`, resourceType, logicalId, stateResources[logicalId]?.physicalId, error instanceof Error ? maskSecretsInError(error, this.perResourceSecrets.get(logicalId) ?? EMPTY_SECRETS) : void 0);
25765
25995
  } finally {
25766
25996
  renderer.removeTask(logicalId);
25767
25997
  }
@@ -25850,7 +26080,8 @@ var DeployEngine = class {
25850
26080
  * #960 follow-up) and the name-idempotent same-id guard (issue #1238) so
25851
26081
  * the two --replace escape hatches cannot drift apart.
25852
26082
  */
25853
- async replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, createContext, updateReplacePolicy) {
26083
+ async replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, secrets, updateReplacePolicy) {
26084
+ const createContext = { maskSecrets: createSecretMasker(secrets) };
25854
26085
  const finalSnapshotIdentifier = await this.prepareFinalSnapshotForDelete(logicalId, resourceType, currentResource, updateReplacePolicy);
25855
26086
  let deleteResult;
25856
26087
  try {
@@ -25860,7 +26091,7 @@ var DeployEngine = class {
25860
26091
  ...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier }
25861
26092
  });
25862
26093
  } catch (deleteError) {
25863
- throw new Error(`Failed to delete old resource ${logicalId} (${currentResource.physicalId}) during the --replace delete-first fallback: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`);
26094
+ throw new Error(maskSecretsInText(`Failed to delete old resource ${logicalId} (${currentResource.physicalId}) during the --replace delete-first fallback: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`, secrets));
25864
26095
  }
25865
26096
  const replaceSkipReason = deleteSkipReason(deleteResult);
25866
26097
  if (replaceSkipReason !== void 0) throw new Error(deleteSkippedMessage(logicalId, currentResource.physicalId, replaceSkipReason, "during the --replace delete-first fallback"));
@@ -25871,13 +26102,13 @@ var DeployEngine = class {
25871
26102
  maxRetries: 8,
25872
26103
  initialDelayMs: 2e3,
25873
26104
  maxDelayMs: 1e4,
25874
- logger: this.logger,
26105
+ logger: this.maskingRetryLoggerFor(secrets),
25875
26106
  isInterrupted: () => this.interrupted,
25876
26107
  onInterrupted: () => new InterruptedError(this.interruptCause ?? "user"),
25877
26108
  isRetryable: isRecreateRetryableError
25878
26109
  });
25879
26110
  } catch (recreateError) {
25880
- throw new Error(`Failed to re-create ${logicalId} after the --replace delete-first fallback already deleted the old resource (${currentResource.physicalId}): ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. Re-run the deploy to create it fresh.`);
26111
+ throw new Error(maskSecretsInText(`Failed to re-create ${logicalId} after the --replace delete-first fallback already deleted the old resource (${currentResource.physicalId}): ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. Re-run the deploy to create it fresh.`, secrets));
25881
26112
  }
25882
26113
  }
25883
26114
  /**
@@ -25899,10 +26130,10 @@ var DeployEngine = class {
25899
26130
  ...parameterValues && { parameters: parameterValues },
25900
26131
  ...conditions && { conditions }
25901
26132
  }, stackName);
26133
+ if (context.recordedSecretValues) this.perResourceSecrets.set(logicalId, context.recordedSecretValues);
25902
26134
  const resolvedProps = await this.resolver.resolve(desiredProps, context);
25903
26135
  this.perResourceTemplateProps.set(logicalId, desiredProps);
25904
26136
  const createSecrets = context.recordedSecretValues ?? /* @__PURE__ */ new Map();
25905
- if (context.recordedSecretValues) this.perResourceSecrets.set(logicalId, context.recordedSecretValues);
25906
26137
  this.auditResolvedAssetReferences(logicalId, resourceType, resolvedProps);
25907
26138
  this.attemptedResolvedProps.set(logicalId, resolvedProps);
25908
26139
  const createDecision = this.providerRegistry.getProviderFor({
@@ -25943,9 +26174,9 @@ var DeployEngine = class {
25943
26174
  ...parameterValues && { parameters: parameterValues },
25944
26175
  ...conditions && { conditions }
25945
26176
  }, stackName);
25946
- const resolvedProps = await this.resolver.resolve(desiredProps, context);
25947
26177
  const updateSecrets = context.recordedSecretValues ?? /* @__PURE__ */ new Map();
25948
26178
  this.perResourceSecrets.set(logicalId, updateSecrets);
26179
+ const resolvedProps = await this.resolver.resolve(desiredProps, context);
25949
26180
  this.perResourceTemplateProps.set(logicalId, desiredProps);
25950
26181
  this.auditResolvedAssetReferences(logicalId, resourceType, resolvedProps);
25951
26182
  this.attemptedResolvedProps.set(logicalId, resolvedProps);
@@ -26026,7 +26257,7 @@ var DeployEngine = class {
26026
26257
  maxRetries: 8,
26027
26258
  initialDelayMs: 2e3,
26028
26259
  maxDelayMs: 1e4,
26029
- logger: this.logger,
26260
+ logger: this.maskingRetryLoggerFor(updateSecrets),
26030
26261
  isInterrupted: () => this.interrupted,
26031
26262
  onInterrupted: () => new InterruptedError(this.interruptCause ?? "user"),
26032
26263
  isRetryable: isRecreateRetryableError
@@ -26045,7 +26276,7 @@ var DeployEngine = class {
26045
26276
  if (this.options.replace !== true) throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but the create-first attempt collided with the existing resource: ${createMsg}. ${nameOrigin.descriptor}, so the CloudFormation-style safe replacement order (create the new resource before deleting the old) cannot reuse the occupied name — CloudFormation refuses this shape with "cannot update a stack when a custom-named resource requires replacing". ${nameOrigin.remedy}, or re-run with \`cdkd deploy --replace\` to delete the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated).`, "NAMED_REPLACEMENT_COLLISION");
26046
26277
  this.logger.info(` Create-first collided with the existing resource's name and --replace is set — deleting old ${logicalId} (${currentResource.physicalId}) first...`);
26047
26278
  deletedOldFirst = true;
26048
- createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) }, updateReplacePolicy);
26279
+ createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, updateSecrets, updateReplacePolicy);
26049
26280
  }
26050
26281
  if (!deletedOldFirst && createResult.physicalId === currentResource.physicalId) {
26051
26282
  const idempotentNameOrigin = this.replacementNameOrigin(logicalId, currentResource.physicalId);
@@ -26053,7 +26284,7 @@ var DeployEngine = class {
26053
26284
  if (this.options.replace !== true) throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its Create API is name-idempotent: the create-first attempt returned the EXISTING resource (${currentResource.physicalId}) instead of creating a new one, so deleting the "old" resource would silently destroy the resource the deploy just reported as created. ${idempotentNameOrigin.descriptor}; ${idempotentNameOrigin.remedy}, or re-run with \`cdkd deploy --replace\` to delete the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated). Note: this branch is also reached when the old resource was deleted out-of-band and the physical id is name-derived — there the create was a genuine fresh create; \`--replace\` converges that case too.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE");
26054
26285
  this.logger.info(` Create-first returned the existing resource (name-idempotent Create API) and --replace is set — deleting old ${logicalId} (${currentResource.physicalId}) first...`);
26055
26286
  deletedOldFirst = true;
26056
- createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) }, updateReplacePolicy);
26287
+ createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, updateSecrets, updateReplacePolicy);
26057
26288
  }
26058
26289
  if (deletedOldFirst) {} else if (updateReplacePolicy === "Retain") this.logger.info(` Retaining old ${logicalId} (${currentResource.physicalId}) - UpdateReplacePolicy: Retain`);
26059
26290
  else {
@@ -26444,12 +26675,74 @@ var DeployEngine = class {
26444
26675
  return withRetry(operation, logicalId, {
26445
26676
  ...maxRetries !== void 0 && { maxRetries },
26446
26677
  ...initialDelayMs !== void 0 && { initialDelayMs },
26447
- logger: this.logger,
26678
+ logger: this.maskingRetryLogger(logicalId),
26448
26679
  isInterrupted: () => this.interrupted,
26449
26680
  onInterrupted: () => new InterruptedError(this.interruptCause ?? "user")
26450
26681
  });
26451
26682
  }
26452
26683
  /**
26684
+ * Mask one line of engine-authored text with a resource's OWN recorded
26685
+ * secrets (issue [#2038](https://github.com/go-to-k/cdkd/issues/2038)).
26686
+ *
26687
+ * Per-resource, never session-wide — see the `perResourceSecrets` field doc
26688
+ * for why one resource's secret must not rewrite another's literal. A
26689
+ * `logicalId` with no entry (or an empty bag) forwards verbatim, so every
26690
+ * non-secret resource is byte-identical to before.
26691
+ */
26692
+ maskForResource(logicalId, text) {
26693
+ return maskSecretsInText(text, this.perResourceSecrets.get(logicalId) ?? EMPTY_SECRETS);
26694
+ }
26695
+ /**
26696
+ * The LAZY `RetryLogger` the engine's generic `withRetry` wrapper threads
26697
+ * (issue [#2038](https://github.com/go-to-k/cdkd/issues/2038) acceptance
26698
+ * item 1) — the same masking shape `drift.ts` and `rollback-executor.ts`
26699
+ * install, bound to the resource's OWN recorded secrets.
26700
+ *
26701
+ * `retry.ts` interpolates the AWS message verbatim into both the per-attempt
26702
+ * `debug` line and the give-up `warn` summary, and the bag this engine hands
26703
+ * a provider is RESOLVED — `perResourceSecrets` is populated immediately after
26704
+ * `resolver.resolve` and BEFORE the create / update call, so a secret is in
26705
+ * scope at every retried provider call. An AWS validation error routinely
26706
+ * quotes the offending value back, so the give-up summary could print it at
26707
+ * DEFAULT verbosity: the same hole #2038 found on the rollback path, one
26708
+ * caller over.
26709
+ *
26710
+ * The bag is resolved PER LINE rather than captured, because `withRetry`
26711
+ * (the private wrapper below) is reached from call sites that hold no bag —
26712
+ * DELETE, the observed-capture drain, the Outputs pass — and a
26713
+ * `logicalId`-keyed read is the only thing available there. The two
26714
+ * `--replace` sites do hold their caller's bag and use
26715
+ * {@link maskingRetryLoggerFor} instead; see the note on
26716
+ * {@link replaceDeleteFirstAndRecreate}'s `secrets` parameter for why binding
26717
+ * the bag beats looking it up whenever the bag is in scope.
26718
+ *
26719
+ * Do NOT restate that the engine "already masked its own error text" — an
26720
+ * earlier revision of this comment did, and it was FALSE: `provisionResource`
26721
+ * logged the raw AWS message at `error` level (a HIGHER level than this
26722
+ * summary) until #2038's review round. Only the EVENT store was masked.
26723
+ */
26724
+ maskingRetryLogger(logicalId) {
26725
+ return {
26726
+ debug: (msg) => this.logger.debug(this.maskForResource(logicalId, msg)),
26727
+ warn: (msg) => this.logger.warn(this.maskForResource(logicalId, msg))
26728
+ };
26729
+ }
26730
+ /**
26731
+ * The EAGER `RetryLogger`, bound to the bag the caller actually resolved
26732
+ * with (issue [#2038](https://github.com/go-to-k/cdkd/issues/2038)).
26733
+ *
26734
+ * Preferred over {@link maskingRetryLogger} wherever the resolution pass's
26735
+ * own `RecordedSecretValues` is in scope, for the reason
26736
+ * {@link replaceDeleteFirstAndRecreate}'s parameter list already states about
26737
+ * the masker it threads: a map looked up by logical id is a DIFFERENT thing
26738
+ * from the bag this call resolved with, and one file must not argue both
26739
+ * sides. It delegates to the shared `masking-retry-logger.ts` so the deploy
26740
+ * engine, `rollback-executor.ts` and `drift.ts` cannot drift apart.
26741
+ */
26742
+ maskingRetryLoggerFor(secrets) {
26743
+ return maskingRetryLogger(this.logger, secrets);
26744
+ }
26745
+ /**
26453
26746
  * What a failed Output resolution does, shared by both passes of
26454
26747
  * {@link resolveOutputs} so they cannot drift — the alias pass reports the
26455
26748
  * SAME failure for a name it could not resolve as the value pass does for a
@@ -26550,5 +26843,5 @@ var DeployEngine = class {
26550
26843
  };
26551
26844
 
26552
26845
  //#endregion
26553
- export { IntrinsicFunctionResolver as $, StackHasActiveImportsError as $n, validateContainerRepoName as $t, formatResourceLine as A, AssemblyReader as An, describeTypeWithThrottleRetry as At, isExportAliasCollision as B, ConfigError as Bn, WorkGraph as Bt, refusesFinalSnapshot as C, MIGRATE_TMP_PREFIX as Cn, s3BucketDomainName as Ct, MULTI_REGION_RECREATE_BLOCKED_TYPES as D, PARTITION_TABLE as Dn, applyRoleArnIfSet as Dt, extractDeploymentEventError as E, expectedOwnerParam as En, s3BucketWebsiteUrl as Et, red as F, getAwsClients as Fn, S3StateBackend as Ft, clearOnUpdateRemoval as G, LocalStartServiceError as Gn, escapeRegExp$1 as Gt, stateKeySecretExposure as H, DeployCancelledError as Hn, createAssetRedirectResolver as Ht, yellow as I, resetAwsClients as In, rebuildClientForBucketRegion as It, findSilentDropProperties as J, NestedStackChildDirectDestroyError as Jn, BOOTSTRAP_MARKER_PREFIX as Jt, ProviderRegistry as K, LockError as Kn, stripControlChars as Kt, collectDeclaredOutputNames as L, setAwsClients as Ln, shouldRetainResource as Lt, cyan as M, clearBucketRegionCache as Mn, DagBuilder as Mt, gray as N, resolveBucketRegion as Nn, TemplateParser as Nt, isStatefulRecreateTargetSync as O, canonicalizeRegion as On, DiffCalculator as Ot, green as P, AwsClients as Pn, LockManager as Pt, isTerminationProtectionPropagationError as Q, ResourceUpdateNotSupportedError as Qn, validateAssetBucketName as Qt, collectPublishedOutputNames as R, AssetError as Rn, AssetPublisher as Rt, isFinalSnapshotError as S, CFN_TEMPLATE_URL_LIMIT as Sn, s3BucketArn as St, makeCanonicalizePropertiesFn as T, uploadCfnTemplate as Tn, s3BucketRegionalDomainName as Tt, IAMRoleProvider as U, LocalInvokeBuildError as Un, loadPublishableAssetManifest as Ut, secretBearingStateKeyWarning as V, DependencyError as Vn, buildAssetRedirectMap as Vt, collectInlinePolicyNamesManagedBySiblings as W, LocalMigrateError as Wn, rewriteTemplateAssetReferences as Wt, slowCcOperationTimeoutMs as X, ProvisioningError as Xn, getBootstrapMarkerKey as Xt, CloudControlProvider as Y, PartialFailureError as Yn, ensureAssetStorage as Yt, disableInstanceApiTermination as Z, ResourceTimeoutError as Zn, parseBootstrapMarker as Zt, ATOMIC_FINAL_SNAPSHOT_TYPES as _, resolveStateBucketWithDefaultAndSource as _n, TEMPLATE_SOURCED_RULES as _t, DeploymentEventsStore as a, runDockerStreaming as an, normalizeAwsError as ar, resolveExplicitPhysicalId as at, ccRoutedFinalSnapshotError as b, warnDeprecatedNoPrefixCliFlag as bn, redactSecretsForState as bt, replayFailedOperations as c, Synthesizer as cn, isRetryableTransientError as cr, configBooleanRefusal as ct, updatePartialReason as d, getLegacyStateBucketName as dn, __exportAll as dr, replayWarn as dt, buildDenyExternalAccessPolicy as en, StackTerminationProtectionError as er, cfnRefValueFromPhysicalId as et, UNSPECIFIED_SKIP_REASON as f, resolveApp as fn, requireConfigArray as ft, computeImplicitDeleteEdges as g, resolveStateBucketWithDefault as gn, STATE_SOURCED_READBACK_RULES as gt, IMPLICIT_DELETE_DEPENDENCIES as h, resolveSkipPrefix as hn, STATE_SOURCED_CROSS_GENERATION_RULES as ht, DeploymentEventsReader as i, runDockerForeground as in, isCdkdError as ir, normalizeAwsTagsToCfn as it, bold as j, processStackMessages as jn, withRetry as jt, renderStatefulReason as k, derivePartitionAndUrlSuffix as kn, INTRINSIC_KEYS as kt, replayRollback as l, synthesisStatusMessage as ln, isThrottlingError as lr, configStringRefusal as lt, withResourceDeadline as m, resolveCaptureObservedState as mn, requireConfigString as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, formatDockerLoginError as nn, SynthesisError as nr, refStateLookupFromResource as nt, planFailedOps as o, AssetManifestLoader as on, withErrorHandling as or, assertRegionMatch as ot, deleteSkipReason as p, resolveAutoAssetStorage as pn, requireConfigObject as pt, findActionableSilentDrops as q, MissingCdkCliError as qn, AssetModeResolver as qt, DeployEngine as r, getDockerCmd as rn, formatError as rr, WAFv2WebACLProvider as rt, planRollback as s, getDockerImageBySourceHash as sn, isMarkedNonRetryable as sr, coerceCfnBoolean as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, buildDockerImage as tn, StateError as tr, getAccountInfo as tt, updatePartialMessage as u, getDefaultStateBucketName as un, markNonRetryable as ur, readConfigString as ut, PRE_DELETE_SNAPSHOT_TYPES as v, resolveUseCdkBootstrapAssets as vn, createSecretMasker as vt, unsupportedFinalSnapshotError as w, findLargeInlineResources as wn, s3BucketDualStackDomainName as wt, createPreDeleteFinalSnapshot as x, CFN_TEMPLATE_BODY_LIMIT as xn, scrubResourceRecord as xt, buildFinalSnapshotIdentifier as y, stateBucketExistenceConfirmed as yn, maskSecretsInText as yt, exportAliasCollisionScrubWarning as z, CdkdError as zn, stringifyValue as zt };
26554
- //# sourceMappingURL=deploy-engine-K5kHzsB-.js.map
26846
+ export { isTerminationProtectionPropagationError as $, ResourceUpdateNotSupportedError as $n, validateAssetBucketName as $t, renderStatefulReason as A, derivePartitionAndUrlSuffix as An, INTRINSIC_KEYS as At, exportAliasCollisionScrubWarning as B, CdkdError as Bn, stringifyValue as Bt, isFinalSnapshotError as C, CFN_TEMPLATE_URL_LIMIT as Cn, s3BucketArn as Ct, extractDeploymentEventError as D, expectedOwnerParam as Dn, s3BucketWebsiteUrl as Dt, makeCanonicalizePropertiesFn as E, uploadCfnTemplate as En, s3BucketRegionalDomainName as Et, green as F, AwsClients as Fn, LockManager as Ft, collectInlinePolicyNamesManagedBySiblings as G, LocalMigrateError as Gn, rewriteTemplateAssetReferences as Gt, secretBearingStateKeyWarning as H, DependencyError as Hn, buildAssetRedirectMap as Ht, red as I, getAwsClients as In, S3StateBackend as It, findActionableSilentDrops as J, MissingCdkCliError as Jn, AssetModeResolver as Jt, clearOnUpdateRemoval as K, LocalStartServiceError as Kn, escapeRegExp$1 as Kt, yellow as L, resetAwsClients as Ln, rebuildClientForBucketRegion as Lt, bold as M, processStackMessages as Mn, withRetry as Mt, cyan as N, clearBucketRegionCache as Nn, DagBuilder as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, PARTITION_TABLE as On, applyRoleArnIfSet as Ot, gray as P, resolveBucketRegion as Pn, TemplateParser as Pt, disableInstanceApiTermination as Q, ResourceTimeoutError as Qn, parseBootstrapMarker as Qt, collectDeclaredOutputNames as R, setAwsClients as Rn, shouldRetainResource as Rt, createPreDeleteFinalSnapshot as S, CFN_TEMPLATE_BODY_LIMIT as Sn, scrubResourceRecord as St, unsupportedFinalSnapshotError as T, findLargeInlineResources as Tn, s3BucketDualStackDomainName as Tt, stateKeySecretExposure as U, DeployCancelledError as Un, createAssetRedirectResolver as Ut, isExportAliasCollision as V, ConfigError as Vn, WorkGraph as Vt, IAMRoleProvider as W, LocalInvokeBuildError as Wn, loadPublishableAssetManifest as Wt, CloudControlProvider as X, PartialFailureError as Xn, ensureAssetStorage as Xt, findSilentDropProperties as Y, NestedStackChildDirectDestroyError as Yn, BOOTSTRAP_MARKER_PREFIX as Yt, slowCcOperationTimeoutMs as Z, ProvisioningError as Zn, getBootstrapMarkerKey as Zt, computeImplicitDeleteEdges as _, resolveStateBucketWithDefault as _n, STATE_SOURCED_READBACK_RULES as _t, DeploymentEventsStore as a, runDockerForeground as an, isCdkdError as ar, normalizeAwsTagsToCfn as at, buildFinalSnapshotIdentifier as b, stateBucketExistenceConfirmed as bn, maskSecretsInText as bt, replayFailedOperations as c, getDockerImageBySourceHash as cn, isMarkedNonRetryable as cr, coerceCfnBoolean as ct, updatePartialReason as d, getDefaultStateBucketName as dn, markNonRetryable as dr, readConfigString as dt, validateContainerRepoName as en, StackHasActiveImportsError as er, IntrinsicFunctionResolver as et, UNSPECIFIED_SKIP_REASON as f, getLegacyStateBucketName as fn, __exportAll as fr, replayWarn as ft, IMPLICIT_DELETE_DEPENDENCIES as g, resolveSkipPrefix as gn, STATE_SOURCED_CROSS_GENERATION_RULES as gt, maskingRetryLogger as h, resolveCaptureObservedState as hn, requireConfigString as ht, DeploymentEventsReader as i, getDockerCmd as in, formatError as ir, WAFv2WebACLProvider as it, formatResourceLine as j, AssemblyReader as jn, describeTypeWithThrottleRetry as jt, isStatefulRecreateTargetSync as k, canonicalizeRegion as kn, DiffCalculator as kt, replayRollback as l, Synthesizer as ln, isRetryableTransientError as lr, configBooleanRefusal as lt, withResourceDeadline as m, resolveAutoAssetStorage as mn, requireConfigObject as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, buildDockerImage as nn, StateError as nr, getAccountInfo as nt, planFailedOps as o, runDockerStreaming as on, normalizeAwsError as or, resolveExplicitPhysicalId as ot, deleteSkipReason as p, resolveApp as pn, requireConfigArray as pt, ProviderRegistry as q, LockError as qn, stripControlChars as qt, DeployEngine as r, formatDockerLoginError as rn, SynthesisError as rr, refStateLookupFromResource as rt, planRollback as s, AssetManifestLoader as sn, withErrorHandling as sr, assertRegionMatch as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, buildDenyExternalAccessPolicy as tn, StackTerminationProtectionError as tr, cfnRefValueFromPhysicalId as tt, updatePartialMessage as u, synthesisStatusMessage as un, isThrottlingError as ur, configStringRefusal as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, resolveStateBucketWithDefaultAndSource as vn, TEMPLATE_SOURCED_RULES as vt, refusesFinalSnapshot as w, MIGRATE_TMP_PREFIX as wn, s3BucketDomainName as wt, ccRoutedFinalSnapshotError as x, warnDeprecatedNoPrefixCliFlag as xn, redactSecretsForState as xt, PRE_DELETE_SNAPSHOT_TYPES as y, resolveUseCdkBootstrapAssets as yn, createSecretMasker as yt, collectPublishedOutputNames as z, AssetError as zn, AssetPublisher as zt };
26847
+ //# sourceMappingURL=deploy-engine-4Eh5Qqlm.js.map