@go-to-k/cdkd 0.300.2 → 0.301.0

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.
Files changed (26) hide show
  1. package/dist/{asg-provider-DJdNNqDe.js → asg-provider-CK2nZE6B.js} +2 -2
  2. package/dist/{asg-provider-DJdNNqDe.js.map → asg-provider-CK2nZE6B.js.map} +1 -1
  3. package/dist/aws-failure-text-BEQfs6za.js.map +1 -1
  4. package/dist/cli.js +2 -2
  5. package/dist/{deploy-engine-DOBzE5TD.js → deploy-engine-DEvS2r2M.js} +1238 -765
  6. package/dist/deploy-engine-DEvS2r2M.js.map +1 -0
  7. package/dist/{iam-role-provider-C8gNXG1G.js → iam-role-provider-s7oQ_V1d.js} +3 -9
  8. package/dist/iam-role-provider-s7oQ_V1d.js.map +1 -0
  9. package/dist/index.d.ts +25 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -2
  12. package/dist/{neptune-provider-UDy6HC5O.js → neptune-provider-BWESr5fm.js} +2 -2
  13. package/dist/{neptune-provider-UDy6HC5O.js.map → neptune-provider-BWESr5fm.js.map} +1 -1
  14. package/dist/{program-BDm58Wc8.js → program-C_kDHyxY.js} +107 -82
  15. package/dist/program-C_kDHyxY.js.map +1 -0
  16. package/dist/{provider-classes-DzoIZFZK.js → provider-classes-C1xbZd9k.js} +141 -94
  17. package/dist/provider-classes-C1xbZd9k.js.map +1 -0
  18. package/dist/{rds-provider-C-lGTdAb.js → rds-provider-BfwQbYRR.js} +2 -2
  19. package/dist/{rds-provider-C-lGTdAb.js.map → rds-provider-BfwQbYRR.js.map} +1 -1
  20. package/dist/{version-CZbKGFSS.js → version-BdWNHoO2.js} +2 -2
  21. package/dist/{version-CZbKGFSS.js.map → version-BdWNHoO2.js.map} +1 -1
  22. package/package.json +2 -2
  23. package/dist/deploy-engine-DOBzE5TD.js.map +0 -1
  24. package/dist/iam-role-provider-C8gNXG1G.js.map +0 -1
  25. package/dist/program-BDm58Wc8.js.map +0 -1
  26. package/dist/provider-classes-DzoIZFZK.js.map +0 -1
@@ -2,7 +2,7 @@ import { r as getAwsClients, s as __exportAll } from "./aws-clients-B_CEQGE1.js"
2
2
  import { A as UNRENDERABLE, B as safeMsg, C as looksLikeCdkdGeneratedName, D as SAFE_MSG_ALTERED_CHAR, E as withoutGeneratedFallbackName, F as displaySafe, H as terminalSafe, I as displayStackName, L as isPasteableIdent, N as displayAwsMessage, O as SECRET_REF_MAX_CODE_POINTS, P as displayIdent, S as getCurrentStackName, T as withStackName, U as truncateCodePoints, a as getLogger, b as generateResourceNameWithFallback, d as installLogLineMaskerSource, f as getLiveRenderer, g as applyDefaultNameForFallback, j as asIsMessage, k as STACK_REF_MAX_CODE_POINTS, o as isStdoutReservedForPayload, r as safeStringify$1, t as describeAwsFailure, u as currentLogLineMasker, v as explicitNamePropertyFor, w as withSkipPrefix, x as getCurrentSkipPrefix, y as generateResourceName, z as plainIdentOr } from "./aws-failure-text-BEQfs6za.js";
3
3
  import { $ as protectedReplacementAdvice, $t as ambientCredentialConfig, A as isQuotableImportValue, An as SHELL_ACTIVE, At as isAuxiliaryMarkOf, B as isTerminalDeleteFailure, Bn as shellBoundedDisplay, Bt as formatLockOperation, Cn as StateError, Ct as RETRY_AUXILIARY_OWNER, Dn as normalizeAwsError, Dt as createdResourceIdentityBeforeFailure, E as assertRegionMatch, Et as createdBeforeFailure, F as resolveExplicitPhysicalId, Fn as isInertUnquoted, Ft as UNREPRODUCIBLE_LOCK_CLAUSE, G as runDeleteAttempt, Gn as isUpdateUnsupportedError, Gt as DEFAULT_STATE_PREFIX, H as observeThenDisableProtection, Hn as withheldTargetClause, Ht as recoveryCommandFlags, In as pasteableCommand, It as buildForceUnlockCommand, J as DELETION_PROTECTION_DOC_POINTER, Jn as isNameCooldownError, Kn as hasReplayMayCollide, Kt as injectiveKey, L as ProtectionFlipRegistry, Ln as physicalIdShownBesideCommand, M as quotedRemedyLogicalId, Mn as UNSHOWABLE_VALUE, Mt as markCreatedBeforeFailure, N as refusalTypeShown, Nn as commandHole, Ot as hasCreatedBeforeFailure, Pt as replayMadeAnotherResource, Q as pasteableAwsCommand, Qn as markReplayMayCollide, Qt as ambientClientDefaults, R as compensateProtectionFlip, Rn as plainOrDescribed, St as withDerivedNameMasks, T as RESOURCE_NOT_FOUND, U as protectionFlipKey, Ut as sanitizeRecoveryValue, Vn as shellQuote, Vt as formatLockOwner, Wt as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xn as isReplayedNameCollisionFrom, Yn as isRecreateRetryableError, Yt as producerRecordKey, Zt as withPasteableAwsProfile, _t as createMaskedLogSinks, ar as isRetryableTransientError, at as startInterruptWatch, bn as ResourceUpdateNotSupportedError, bt as maskDeep, ct as canonicalizeRoute53QueryName, d as prepareRemovalForUpdate, dr as markNonRetryable, en as clientDefaultsFor, er as formatRetryClassificationSignals, f as removalWarning, fr as markRedactedCause, ft as logicalIdShown, gt as stateOrphanRecordRemedy, hn as MalformedProducerRecordRefusalError, ht as segmentAfterAnchor, i as holdsSecretDerivedEntry, in as CdkdError, ir as isIamPropagationError, it as isInterruptedWaitError, j as normalizeAwsTagsToCfn, jn as SHELL_ACTIVE_WHY, jt as markAuxiliaryFailure, kt as isAuxiliaryFailure, l as withUnchangedSecretPrincipalLists, ln as DynamicReferenceRegionAmbiguousError, lr as isMarkedNonRetryable, m as withoutInjectedRemovals, mn as MacroExpansionError, mt as resourceTypeShown, nn as AccountIdUnavailableError, nr as isAmbiguousOutcomeError, on as CrossAccountSecretRefusalError, or as isTransientServerError, ot as ElapsedBudgetRegistry, pn as LockError, pr as wrapMaskedAwsError, qn as isNameCollisionErrorFrom, rn as AssetError, sn as DependencyError, sr as retryClassificationText, st as monotonicNowMs, tn as credentialFingerprint, tr as isAmbiguousCcHandlerErrorCode, un as IntrinsicResolutionRefusalError, ur as isThrottlingError, ut as compositeIdSeparatorRefusal, vn as ProvisioningError, vt as createMaskedRetryLogger, w as withoutServerErrorRetries, wn as SynthesisError, wt as carryCreatedBeforeFailure, xt as maskerOrIdentity, yn as ResourceTimeoutError, yt as isSecretDerivedValue, z as deleteWithProtectionCompensation, zn as quotedOrDescribed, zt as formatLockExpiry } from "./iam-policy-targets-DFk7zr0Q.js";
4
4
  import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as ambientRegion, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-DBXBcg0J.js";
5
- import { t as getCdkdVersion } from "./version-CZbKGFSS.js";
5
+ import { t as getCdkdVersion } from "./version-BdWNHoO2.js";
6
6
  import { createHash, randomUUID } from "node:crypto";
7
7
  import { AsyncLocalStorage } from "node:async_hooks";
8
8
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketLifecycleConfigurationCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -4958,11 +4958,22 @@ function refuseMalformedOperation(shownStack, where, op) {
4958
4958
  if (o["oldResourceMaySurvive"] !== void 0 && !["kept", "unconfirmed"].includes(o["oldResourceMaySurvive"])) fail("oldResourceMaySurvive", o["oldResourceMaySurvive"], "kept or unconfirmed when present");
4959
4959
  if (o["physicalIdRecoveredFromError"] !== void 0 && typeof o["physicalIdRecoveredFromError"] !== "boolean") fail("physicalIdRecoveredFromError", o["physicalIdRecoveredFromError"], "a boolean when present");
4960
4960
  if (o["physicalIdRecoveredFromError"] !== void 0 && o["changeType"] !== "CREATE") refuseMalformed(shownStack, `${where}.physicalIdRecoveredFromError is only valid on a CREATE (got changeType ${kind(o["changeType"])}).`);
4961
+ const pending = o["pendingCloudControlRequest"];
4962
+ if (pending !== void 0) {
4963
+ const p = pending;
4964
+ if (typeof pending !== "object" || pending === null || Array.isArray(pending) || typeof p["requestToken"] !== "string" || !/^[-A-Za-z0-9+/=]{1,128}$/.test(p["requestToken"]) || typeof p["abandonedAt"] !== "number" || !Number.isFinite(p["abandonedAt"])) fail("pendingCloudControlRequest", pending, "an object with a Cloud Control requestToken and a numeric abandonedAt when present");
4965
+ if (o["changeType"] !== "CREATE" || o["physicalId"] !== void 0 || o["physicalIdRecoveredFromError"] !== void 0) refuseMalformed(shownStack, `${where}.pendingCloudControlRequest is only valid on a CREATE with no physicalId.`);
4966
+ }
4961
4967
  const identity = o["createdResourceIdentity"];
4962
4968
  if (identity !== void 0) {
4963
4969
  if (typeof identity !== "string" || identity === "") fail("createdResourceIdentity", identity, "a non-empty string when present");
4964
4970
  if (typeof o["physicalIdRecoveredFromError"] !== "boolean") refuseMalformed(shownStack, `${where}.createdResourceIdentity is only valid on a CREATE carrying physicalIdRecoveredFromError.`);
4965
4971
  }
4972
+ const unique = o["createdIdentifierUnique"];
4973
+ if (unique !== void 0) {
4974
+ if (typeof unique !== "boolean") fail("createdIdentifierUnique", unique, "a boolean when present");
4975
+ if (typeof o["physicalIdRecoveredFromError"] !== "boolean" || o["provisionedBy"] !== "cc-api") refuseMalformed(shownStack, `${where}.createdIdentifierUnique is only valid on a Cloud Control CREATE carrying physicalIdRecoveredFromError.`);
4976
+ }
4966
4977
  if (o["deletionPolicy"] !== void 0 && ![
4967
4978
  "Delete",
4968
4979
  "Retain",
@@ -6458,6 +6469,25 @@ var S3StateBackend = class S3StateBackend {
6458
6469
  await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
6459
6470
  return removed;
6460
6471
  }
6472
+ async rewriteRollbackJournalFailedOperations(stackName, region, rewrite) {
6473
+ const journal = await this.loadRollbackJournal(stackName, region);
6474
+ if (!journal) return 0;
6475
+ let changed = 0;
6476
+ for (const segment of journal.segments) {
6477
+ if (!segment.failedOperations) continue;
6478
+ const next = [];
6479
+ for (const op of segment.failedOperations) {
6480
+ const out = rewrite(op, segment);
6481
+ if (out !== op) changed++;
6482
+ if (out !== null) next.push(out);
6483
+ }
6484
+ if (next.length === 0) delete segment.failedOperations;
6485
+ else segment.failedOperations = next;
6486
+ }
6487
+ if (changed === 0) return 0;
6488
+ await this.putRawObject(this.getRollbackJournalKey(stackName, region), JSON.stringify(journal, null, 2));
6489
+ return changed;
6490
+ }
6461
6491
  async reduceRollbackJournalToFailedOperations(stackName, region, keep, supersededLogicalIds = [], demote = () => false) {
6462
6492
  const journal = await this.loadRollbackJournal(stackName, region);
6463
6493
  if (!journal) return 0;
@@ -8183,6 +8213,34 @@ function positionByInheritedParameter(bag, source, secrets) {
8183
8213
  if (!deepEqualJsonValue(redactSecretsForState(answer, secrets), answer)) return void 0;
8184
8214
  return answer;
8185
8215
  }
8216
+ const REREAD_PSEUDO_PARAMETERS = /* @__PURE__ */ new Set([
8217
+ "AWS::Region",
8218
+ "AWS::Partition",
8219
+ "AWS::URLSuffix"
8220
+ ]);
8221
+ const inheritedPseudoParameters = /* @__PURE__ */ new WeakMap();
8222
+ const POISONED_PSEUDO_PARAMETERS = Symbol("cdkd.inherited-pseudo-parameters.poisoned");
8223
+ function recordInheritedPseudoParameters(inheritedSecrets, values) {
8224
+ let table = inheritedPseudoParameters.get(inheritedSecrets);
8225
+ if (table === POISONED_PSEUDO_PARAMETERS) return;
8226
+ if (table === void 0) {
8227
+ table = /* @__PURE__ */ new Map();
8228
+ inheritedPseudoParameters.set(inheritedSecrets, table);
8229
+ }
8230
+ for (const [name, value] of values) {
8231
+ if (!REREAD_PSEUDO_PARAMETERS.has(name) || typeof value !== "string") continue;
8232
+ const known = table.get(name);
8233
+ if (known !== void 0 && known !== value) {
8234
+ inheritedPseudoParameters.set(inheritedSecrets, POISONED_PSEUDO_PARAMETERS);
8235
+ return;
8236
+ }
8237
+ table.set(name, value);
8238
+ }
8239
+ }
8240
+ function pseudoBindingOf(parentSecrets) {
8241
+ const table = inheritedPseudoParameters.get(parentSecrets);
8242
+ return (name) => table instanceof Map && table.has(name) ? { value: table.get(name) } : void 0;
8243
+ }
8186
8244
  const REREAD_TRIGGERS = /* @__PURE__ */ new Set([
8187
8245
  "Fn::Select",
8188
8246
  "Fn::Split",
@@ -8221,9 +8279,9 @@ function standsForInheritedSecret(parentSecrets, token) {
8221
8279
  return parentSecrets !== void 0 && resolvedPlaintextOf(parentSecrets, token) !== void 0;
8222
8280
  }
8223
8281
  const plainSplit = (text, delimiter) => text.split(delimiter);
8224
- function evaluatePureRead(node, bind, split, choose, depth = 0) {
8282
+ function evaluatePureRead(node, bind, pseudo, split, choose, depth = 0) {
8225
8283
  if (depth > MAX_REREAD_DEPTH) return void 0;
8226
- const evaluate = (child) => evaluatePureRead(child, bind, split, choose, depth + 1);
8284
+ const evaluate = (child) => evaluatePureRead(child, bind, pseudo, split, choose, depth + 1);
8227
8285
  if (typeof node === "string") return node.includes("{{resolve:") ? void 0 : { value: node };
8228
8286
  if (Array.isArray(node)) {
8229
8287
  const out = [];
@@ -8241,7 +8299,7 @@ function evaluatePureRead(node, bind, split, choose, depth = 0) {
8241
8299
  const args = node[key];
8242
8300
  if (key === "Ref") {
8243
8301
  if (args === "AWS::NoValue") return { value: REREAD_NO_VALUE };
8244
- return typeof args === "string" ? bind(args) : void 0;
8302
+ return typeof args === "string" ? bindReadName(args, bind, pseudo) : void 0;
8245
8303
  }
8246
8304
  if (key === "Fn::If") {
8247
8305
  if (!Array.isArray(args) || args.length !== 3 || typeof args[0] !== "string") return void 0;
@@ -8249,7 +8307,7 @@ function evaluatePureRead(node, bind, split, choose, depth = 0) {
8249
8307
  if (tookTrue === void 0) return void 0;
8250
8308
  return evaluate(tookTrue ? args[1] : args[2]);
8251
8309
  }
8252
- if (key === "Fn::Sub") return evaluatePureSub(args, bind, evaluate);
8310
+ if (key === "Fn::Sub") return evaluatePureSub(args, bind, pseudo, evaluate);
8253
8311
  if (!Array.isArray(args) || args.length !== 2) return void 0;
8254
8312
  if (key === "Fn::Select") {
8255
8313
  const index = args[0];
@@ -8273,7 +8331,7 @@ function evaluatePureRead(node, bind, split, choose, depth = 0) {
8273
8331
  return { value: parts.value.join(delimiter) };
8274
8332
  }
8275
8333
  }
8276
- function evaluatePureSub(args, bind, evaluate) {
8334
+ function evaluatePureSub(args, bind, pseudo, evaluate) {
8277
8335
  const [text, variables] = typeof args === "string" ? [args, {}] : Array.isArray(args) && args.length === 2 ? [args[0], args[1]] : [void 0, void 0];
8278
8336
  if (typeof text !== "string" || text.includes("{{resolve:") || !isPlainObject$7(variables)) return;
8279
8337
  const bound = /* @__PURE__ */ new Map();
@@ -8291,8 +8349,8 @@ function evaluatePureSub(args, bind, evaluate) {
8291
8349
  else if (name === "") replacement = match[0];
8292
8350
  else if (bound.has(name)) replacement = bound.get(name);
8293
8351
  else {
8294
- if (name.startsWith("AWS::") || name.includes(".")) return void 0;
8295
- const value = bind(name);
8352
+ if (name.includes(".")) return void 0;
8353
+ const value = bindReadName(name, bind, pseudo);
8296
8354
  if (value === void 0 || typeof value.value !== "string") return void 0;
8297
8355
  replacement = value.value;
8298
8356
  }
@@ -8301,6 +8359,10 @@ function evaluatePureSub(args, bind, evaluate) {
8301
8359
  }
8302
8360
  return { value: out + text.slice(cursor) };
8303
8361
  }
8362
+ function bindReadName(name, bind, pseudo) {
8363
+ if (!name.startsWith("AWS::")) return bind(name);
8364
+ return bind(name) === void 0 ? pseudo(name) : void 0;
8365
+ }
8304
8366
  function collectRereadConditions(node, names, depth = 0) {
8305
8367
  if (depth > MAX_REREAD_DEPTH) return false;
8306
8368
  if (Array.isArray(node)) return node.every((element) => collectRereadConditions(element, names, depth + 1));
@@ -8338,10 +8400,11 @@ function diffSideReading(bind, parentSecrets) {
8338
8400
  };
8339
8401
  }
8340
8402
  function rereadUnder(source, bind, parentSecrets, choose) {
8341
- const resolved = evaluatePureRead(source, bind, plainSplit, choose);
8403
+ const pseudo = pseudoBindingOf(parentSecrets);
8404
+ const resolved = evaluatePureRead(source, bind, pseudo, plainSplit, choose);
8342
8405
  if (resolved === void 0) return void 0;
8343
8406
  const diffSide = diffSideReading(bind, parentSecrets);
8344
- const redacted = evaluatePureRead(source, diffSide.bind, diffSide.split, choose);
8407
+ const redacted = evaluatePureRead(source, diffSide.bind, pseudo, diffSide.split, choose);
8345
8408
  if (redacted === void 0) return void 0;
8346
8409
  if (resolved.value === REREAD_NO_VALUE || redacted.value === REREAD_NO_VALUE) return resolved.value === redacted.value ? REREAD_NO_VALUE : void 0;
8347
8410
  if (!rendersReadTo(redacted.value, parentSecrets, resolved.value)) return void 0;
@@ -23097,6 +23160,16 @@ function recordInheritedParameterSecrets(parameterName, value, context) {
23097
23160
  carryFreshNoEchoMark(inherited, recorded, plaintext);
23098
23161
  }
23099
23162
  }
23163
+ async function recordInheritedPseudoParameterValues(resolver, inherited) {
23164
+ if (inherited.size === 0) return;
23165
+ const values = /* @__PURE__ */ new Map();
23166
+ for (const name of [
23167
+ "AWS::Region",
23168
+ "AWS::Partition",
23169
+ "AWS::URLSuffix"
23170
+ ]) values.set(name, await resolver.resolvePseudoParameter(name));
23171
+ recordInheritedPseudoParameters(inherited, values);
23172
+ }
23100
23173
  function declaredParameterNames(context) {
23101
23174
  const declared = context.template?.Parameters;
23102
23175
  if (declared === null || typeof declared !== "object") return void 0;
@@ -23814,6 +23887,7 @@ function displayLeaf(value, context) {
23814
23887
  //#region src/deployment/intrinsic-resolver/params-conditions.ts
23815
23888
  async function resolveParameters(template, userParameters, options) {
23816
23889
  const inheritedSecrets = options?.inheritedSecrets;
23890
+ if (inheritedSecrets) await recordInheritedPseudoParameterValues(this, inheritedSecrets);
23817
23891
  const maskInherited = (text) => {
23818
23892
  const mask = (value) => inheritedSecrets && hasMaskableValues(inheritedSecrets) ? maskSecretsInText(value, inheritedSecrets) : value;
23819
23893
  return displaySafe(mask(stripControlChars(mask(text))));
@@ -25096,8 +25170,9 @@ function ec2InstanceProtectionSite(instanceId, region) {
25096
25170
  //#endregion
25097
25171
  //#region src/provisioning/wait-abandoned.ts
25098
25172
  const WAIT_ABANDONED_MARKER = Symbol.for("cdkd.waitAbandoned");
25173
+ const ABANDONED_REQUEST = Symbol.for("cdkd.waitAbandoned.request");
25099
25174
  const MAX_CAUSE_CHAIN_DEPTH = 5;
25100
- function markWaitAbandoned(error) {
25175
+ function markWaitAbandoned(error, request) {
25101
25176
  if (!Object.isExtensible(error)) return error;
25102
25177
  Object.defineProperty(error, WAIT_ABANDONED_MARKER, {
25103
25178
  value: true,
@@ -25105,6 +25180,12 @@ function markWaitAbandoned(error) {
25105
25180
  configurable: true,
25106
25181
  writable: false
25107
25182
  });
25183
+ if (request !== void 0) Object.defineProperty(error, ABANDONED_REQUEST, {
25184
+ value: Object.freeze({ ...request }),
25185
+ enumerable: false,
25186
+ configurable: true,
25187
+ writable: false
25188
+ });
25108
25189
  return error;
25109
25190
  }
25110
25191
  function isWaitAbandonedError(error) {
@@ -25115,6 +25196,14 @@ function isWaitAbandonedError(error) {
25115
25196
  }
25116
25197
  return false;
25117
25198
  }
25199
+ function abandonedRequestOf(error) {
25200
+ let current = error;
25201
+ for (let depth = 0; depth < MAX_CAUSE_CHAIN_DEPTH && current != null; depth++) {
25202
+ const request = current[ABANDONED_REQUEST];
25203
+ if (request !== void 0) return request;
25204
+ current = current.cause;
25205
+ }
25206
+ }
25118
25207
 
25119
25208
  //#endregion
25120
25209
  //#region src/provisioning/ec2-volume-delete.ts
@@ -26372,9 +26461,18 @@ var CloudControlWaitAbandonedError = class CloudControlWaitAbandonedError extend
26372
26461
  this.lastSeenIdentifier = lastSeenIdentifier;
26373
26462
  this.name = "CloudControlWaitAbandonedError";
26374
26463
  Object.setPrototypeOf(this, CloudControlWaitAbandonedError.prototype);
26375
- markWaitAbandoned(this);
26464
+ markWaitAbandoned(this, {
26465
+ requestToken,
26466
+ operation: ccOperation
26467
+ });
26376
26468
  }
26377
26469
  };
26470
+ function failedOutcome$1(errorCode, identifier) {
26471
+ return identifier && errorCode !== "AlreadyExists" && errorCode !== "ResourceConflict" ? {
26472
+ status: "failed",
26473
+ remnant: identifier
26474
+ } : { status: "failed" };
26475
+ }
26378
26476
  const POLL_TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
26379
26477
  "ECONNRESET",
26380
26478
  "ECONNREFUSED",
@@ -26702,7 +26800,7 @@ var CloudControlProvider = class {
26702
26800
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
26703
26801
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
26704
26802
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
26705
- const { ASGProvider } = await import("./asg-provider-DJdNNqDe.js");
26803
+ const { ASGProvider } = await import("./asg-provider-CK2nZE6B.js");
26706
26804
  const delegateRegion = ambientRegion();
26707
26805
  let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
26708
26806
  if (asgProvider === void 0) {
@@ -26808,7 +26906,7 @@ var CloudControlProvider = class {
26808
26906
  const family = SDK_DELETE_FAMILIES.get(resourceType);
26809
26907
  const cached = this.sdkDeleteDelegates.get(family);
26810
26908
  if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
26811
- const provider = family === "rds" ? new (await (import("./rds-provider-C-lGTdAb.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-UDy6HC5O.js"))).NeptuneProvider({ region: ccRegion });
26909
+ const provider = family === "rds" ? new (await (import("./rds-provider-BfwQbYRR.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-BWESr5fm.js"))).NeptuneProvider({ region: ccRegion });
26812
26910
  this.sdkDeleteDelegates.set(family, {
26813
26911
  region: ccRegion,
26814
26912
  provider
@@ -27016,9 +27114,10 @@ var CloudControlProvider = class {
27016
27114
  const failureMessage = progressEvent.StatusMessage || "Unknown error";
27017
27115
  throw new CloudControlOperationFailedError(`${operation} failed for ${logicalId}: ${failureMessage}${handlerAuthFailureHint(failureMessage)}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier, progressEvent.ErrorCode, operation);
27018
27116
  }
27019
- case "CANCEL_COMPLETE": throw new ProvisioningError(`${operation} cancelled for ${logicalId}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier);
27117
+ case "CANCEL_COMPLETE": throw Object.assign(new ProvisioningError(`${operation} cancelled for ${logicalId}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier), { ccOperationCancelled: true });
27020
27118
  case "IN_PROGRESS":
27021
27119
  case "PENDING":
27120
+ case "CANCEL_IN_PROGRESS":
27022
27121
  await this.sleep(pollInterval);
27023
27122
  pollInterval = Math.min(Math.ceil(pollInterval * 1.5), this.MAX_POLL_INTERVAL_MS);
27024
27123
  break;
@@ -27030,13 +27129,90 @@ var CloudControlProvider = class {
27030
27129
  }
27031
27130
  throw await this.abandonWait(requestToken, logicalId, operation, resourceType, lastSeenIdentifier, `${operation} timeout for ${logicalId} after ${maxWaitMs / 1e3}s`, lastTransientError);
27032
27131
  }
27132
+ async resumeCreatedResource(logicalId, resourceType, identifier, properties, context) {
27133
+ const mask = maskerOrIdentity(context?.maskSecrets);
27134
+ const attributeNamesLookup = getTopLevelDeployAttributeNames(resourceType);
27135
+ let raw;
27136
+ try {
27137
+ raw = (await this.cloudControlClient.send(new GetResourceCommand({
27138
+ TypeName: resourceType,
27139
+ Identifier: identifier
27140
+ }))).ResourceDescription?.Properties;
27141
+ } catch (error) {
27142
+ if (error.name === "ResourceNotFoundException") throw Object.assign(new ProvisioningError(`${logicalId}'s resource that an earlier CREATE made no longer exists`, resourceType, logicalId, identifier, error instanceof Error ? error : void 0), { resumedResourceGone: true });
27143
+ throw error;
27144
+ }
27145
+ const model = typeof raw === "string" && raw !== "" ? this.parseResourceModel(raw) : {};
27146
+ const modelKeys = Object.keys(model);
27147
+ const enriched = await this.enrichResourceAttributes(resourceType, identifier, model);
27148
+ return {
27149
+ physicalId: identifier,
27150
+ attributes: await this.maskDeployedNonAttributeKeys(enriched, modelKeys, resourceType, identifier, attributeNamesLookup, properties, mask)
27151
+ };
27152
+ }
27153
+ async resumeAbandonedRequest(requestToken, logicalId, resourceType) {
27154
+ let first;
27155
+ try {
27156
+ first = await this.cloudControlClient.send(new GetResourceRequestStatusCommand({ RequestToken: requestToken }));
27157
+ } catch (error) {
27158
+ if (error.name === "RequestTokenNotFoundException") return { status: "not-found" };
27159
+ return {
27160
+ status: "unresolved",
27161
+ error
27162
+ };
27163
+ }
27164
+ let event = first.ProgressEvent;
27165
+ if (event?.TypeName !== void 0 && event.TypeName !== resourceType || event?.Operation !== void 0 && event.Operation !== "CREATE") return {
27166
+ status: "unresolved",
27167
+ error: /* @__PURE__ */ new Error("the request is not a CREATE of the type the journal records")
27168
+ };
27169
+ if (event !== void 0 && ![
27170
+ "SUCCESS",
27171
+ "FAILED",
27172
+ "CANCEL_COMPLETE"
27173
+ ].includes(String(event.OperationStatus))) try {
27174
+ event = await this.waitForOperation(requestToken, logicalId, "CREATE", resourceType);
27175
+ } catch (error) {
27176
+ if (error instanceof CloudControlOperationFailedError) return failedOutcome$1(error.ccErrorCode, error.physicalId);
27177
+ if (error.ccOperationCancelled === true) {
27178
+ const made = error.physicalId;
27179
+ return made ? {
27180
+ status: "cancelled",
27181
+ remnant: made
27182
+ } : { status: "cancelled" };
27183
+ }
27184
+ if (isInterruptedWaitError(error)) throw error;
27185
+ return {
27186
+ status: "unresolved",
27187
+ error
27188
+ };
27189
+ }
27190
+ switch (event?.OperationStatus) {
27191
+ case "SUCCESS": return event.Identifier ? {
27192
+ status: "succeeded",
27193
+ identifier: event.Identifier
27194
+ } : {
27195
+ status: "unresolved",
27196
+ error: /* @__PURE__ */ new Error("the SUCCESS event named no Identifier")
27197
+ };
27198
+ case "FAILED": return failedOutcome$1(event.ErrorCode, event.Identifier);
27199
+ case "CANCEL_COMPLETE": return event.Identifier ? {
27200
+ status: "cancelled",
27201
+ remnant: event.Identifier
27202
+ } : { status: "cancelled" };
27203
+ default: return {
27204
+ status: "unresolved",
27205
+ error: /* @__PURE__ */ new Error(`unexpected operation status ${String(event?.OperationStatus)}`)
27206
+ };
27207
+ }
27208
+ }
27033
27209
  async abandonWait(requestToken, logicalId, operation, resourceType, lastSeenIdentifier, reason, cause) {
27034
27210
  const described = describePollFailure(cause);
27035
27211
  const safeDisplay = displaySafe(described.display);
27036
27212
  const causeText = safeDisplay === "" ? "" : `: ${safeDisplay}`;
27037
27213
  if (described.detail !== "") this.logger.debug(`${operation} ${logicalId}: the abandoned operation's underlying failure was: ${displaySafe(described.detail)}`);
27038
27214
  const identifierClause = lastSeenIdentifier === void 0 ? "" : ` The last status cdkd read named the resource ${displaySafe(lastSeenIdentifier, { asciiOnly: true })}.`;
27039
- const consequence = operation === "CREATE" ? "cdkd has NO state record for it, so any resource it creates is untracked by rollback and by cdkd destroy" : operation === "DELETE" ? "the resource may or may not have been removed; its state record is kept so a re-run can finish the delete" : "its state record still holds the PREVIOUS properties, so the record may no longer describe the live resource";
27215
+ const consequence = operation === "CREATE" ? "cdkd has NO state record for it: when the failed deploy records the request in the stack's rollback journal, the next cdkd deploy, destroy or rollback checks how it ended, and otherwise any resource it creates is untracked" : operation === "DELETE" ? "the resource may or may not have been removed; its state record is kept so a re-run can finish the delete" : "its state record still holds the PREVIOUS properties, so the record may no longer describe the live resource";
27040
27216
  const error = new CloudControlWaitAbandonedError(safeMsg`${operation} of ${logicalId} was accepted by Cloud Control API, but cdkd stopped waiting for it ` + safeMsg`(${reason}${causeText}). The operation may still be running in AWS, and ${consequence}.` + `${identifierClause} Check what it did with:\n ${await this.buildResumeCommand(requestToken)}`, resourceType, logicalId, requestToken, operation, lastSeenIdentifier, cause instanceof Error ? cause : void 0);
27041
27217
  if (described.marker) markRedactedCause(error);
27042
27218
  return operation === "CREATE" ? markNonRetryable(error) : error;
@@ -33443,343 +33619,95 @@ function seedOnlyAliasRefusal(seed) {
33443
33619
  }
33444
33620
 
33445
33621
  //#endregion
33446
- //#region src/state/deployment-events-store.ts
33447
- const DEPLOYMENT_EVENTS_MAX_INDEX_RUNS = 20;
33448
- const FLUSH_INTERVAL_MS = 2e3;
33449
- const FLUSH_EVENT_THRESHOLD = 50;
33450
- function newDeploymentRunId(now = /* @__PURE__ */ new Date()) {
33451
- return `${now.toISOString().replace(/[-:.]/g, "")}-${randomUUID().slice(0, 8)}`;
33452
- }
33453
- function deploymentEventsKey(prefix, stackName, region, runId) {
33454
- return `${prefix}/${stackName}/${region}/deployments/${runId}.jsonl`;
33455
- }
33456
- function deploymentEventsIndexKey(prefix, stackName, region) {
33457
- return `${prefix}/${stackName}/${region}/deployments/index.json`;
33622
+ //#region src/deployment/rollback-executor/orphan-identity.ts
33623
+ const UNIQUE_PHYSICAL_ID_TYPES = /* @__PURE__ */ new Set([
33624
+ "AWS::EC2::VPC",
33625
+ "AWS::EC2::Subnet",
33626
+ "AWS::EC2::EIP",
33627
+ "AWS::EC2::NatGateway",
33628
+ "AWS::EC2::SecurityGroup",
33629
+ "AWS::EC2::Instance",
33630
+ "AWS::EFS::FileSystem",
33631
+ "AWS::EFS::MountTarget",
33632
+ "AWS::FSx::FileSystem",
33633
+ "AWS::KMS::Key",
33634
+ "AWS::CertificateManager::Certificate",
33635
+ "AWS::ElasticLoadBalancingV2::LoadBalancer",
33636
+ "AWS::ElasticLoadBalancingV2::TargetGroup",
33637
+ "AWS::ElasticLoadBalancingV2::Listener",
33638
+ "AWS::EMR::Cluster",
33639
+ "AWS::EMR::InstanceGroupConfig",
33640
+ "AWS::EMR::InstanceFleetConfig",
33641
+ "AWS::Cognito::UserPool",
33642
+ "AWS::Route53::HostedZone",
33643
+ "AWS::ServiceDiscovery::PrivateDnsNamespace",
33644
+ "AWS::ServiceDiscovery::PublicDnsNamespace",
33645
+ "AWS::ServiceDiscovery::HttpNamespace",
33646
+ "AWS::ServiceDiscovery::Service",
33647
+ "AWS::AppSync::GraphQLApi",
33648
+ "AWS::IAM::AccessKey",
33649
+ "AWS::Kinesis::StreamConsumer"
33650
+ ]);
33651
+ const CONTENT_COMPARED_DELETE_TYPES = /* @__PURE__ */ new Set(["AWS::SQS::QueuePolicy", "AWS::SNS::TopicPolicy"]);
33652
+ const CDKD_NAMESPACE_ID_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::Stack"]);
33653
+ function orphanDeleteNeedsIdentity(resourceType) {
33654
+ return !UNIQUE_PHYSICAL_ID_TYPES.has(resourceType) && !CONTENT_COMPARED_DELETE_TYPES.has(resourceType) && !CDKD_NAMESPACE_ID_TYPES.has(resourceType);
33458
33655
  }
33459
- function deploymentsDirPrefix(prefix, stackName, region) {
33460
- return `${prefix}/${stackName}/${region}/deployments/`;
33656
+ function orphanNeedsIdentity(op) {
33657
+ if (op.provisionedBy === "cc-api") return op.createdIdentifierUnique !== true;
33658
+ return orphanDeleteNeedsIdentity(op.resourceType);
33461
33659
  }
33462
- const DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION = "deployment-event streams and their index, whose recorded error messages can quote values the secret mask does not catch";
33463
- async function deleteAndPurgeEventObjects(backend, keys, dirPrefix, scope = "deleted-keys") {
33464
- if (keys.length === 0) return void 0;
33465
- let swept;
33660
+ const RESOURCE_IDENTITY_TIMEOUT_MS = 1e4;
33661
+ async function readResourceIdentity(providerRegistry, target, region, timeoutMs = RESOURCE_IDENTITY_TIMEOUT_MS) {
33662
+ let timer;
33663
+ const timedOut = new Promise((resolve) => {
33664
+ timer = setTimeout(() => resolve(void 0), timeoutMs);
33665
+ });
33466
33666
  try {
33467
- await backend.deleteRawObjects(keys);
33667
+ return await Promise.race([askResourceIdentity(providerRegistry, target, region), timedOut]);
33468
33668
  } finally {
33469
- if (scope === "whole-dir") swept = await backend.purgeNoncurrentVersionsUnderPrefix(dirPrefix, { objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION });
33470
- else await backend.purgeNoncurrentVersions(keys, {
33471
- ...keys.length > 1 && { listPrefix: dirPrefix },
33472
- objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION
33473
- });
33669
+ clearTimeout(timer);
33474
33670
  }
33475
- return swept;
33476
33671
  }
33477
- function runIdTimestampMs(runId) {
33478
- const m = /^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})Z/.exec(runId);
33479
- if (!m) return null;
33480
- const iso = `${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}.${m[7]}Z`;
33481
- const ms = Date.parse(iso);
33482
- return Number.isNaN(ms) ? null : ms;
33483
- }
33484
- function runIdFromJsonlKey(key, dirPrefix) {
33485
- if (!key.startsWith(dirPrefix) || !key.endsWith(".jsonl")) return null;
33486
- return key.slice(dirPrefix.length, -6);
33487
- }
33488
- var DeploymentEventsStore = class {
33489
- logger = getLogger().child("DeploymentEvents");
33490
- backend;
33491
- stackName;
33492
- region;
33493
- command;
33494
- runId;
33495
- cdkdVersion;
33496
- startedAt;
33497
- events = [];
33498
- persistedCount = 0;
33499
- flushTimer;
33500
- writeChain = Promise.resolve();
33501
- warnedOnce = false;
33502
- finalized = false;
33503
- constructor(backend, options) {
33504
- this.backend = backend;
33505
- this.stackName = options.stackName;
33506
- this.region = options.region;
33507
- this.command = options.command;
33508
- this.runId = options.runId ?? newDeploymentRunId();
33509
- this.cdkdVersion = options.cdkdVersion ?? getCdkdVersion();
33510
- this.startedAt = (/* @__PURE__ */ new Date()).toISOString();
33511
- }
33512
- record(event) {
33513
- try {
33514
- if (this.finalized) return;
33515
- this.events.push({
33516
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
33517
- ...event
33518
- });
33519
- if (this.events.length - this.persistedCount >= FLUSH_EVENT_THRESHOLD) this.scheduleFlush(0);
33520
- else this.scheduleFlush(FLUSH_INTERVAL_MS);
33521
- } catch {}
33522
- }
33523
- async finalize(result) {
33524
- if (this.finalized) return;
33525
- this.finalized = true;
33526
- if (this.flushTimer) {
33527
- clearTimeout(this.flushTimer);
33528
- this.flushTimer = void 0;
33529
- }
33530
- if (this.events.length === 0) return;
33531
- await this.enqueueWrite(async () => {
33532
- const indexRead = this.readIndexRuns();
33533
- indexRead.catch(() => {});
33534
- await this.doFlush();
33535
- await this.writeIndexAndPrune(result, await indexRead);
33536
- });
33537
- }
33538
- async writeIndexAndPrune(result, existingRuns) {
33539
- const { key, file, runs } = this.buildIndexUpdate(result, existingRuns);
33540
- const keptRunIds = runs.map((r) => r.runId);
33541
- const willPrune = keptRunIds.length >= 20;
33542
- const dirPrefix = deploymentsDirPrefix(this.backend.prefix, this.stackName, this.region);
33543
- const staleKeysRead = willPrune ? this.backend.listRawKeys(dirPrefix) : void 0;
33544
- staleKeysRead?.catch(() => {});
33545
- await this.backend.putRawObject(key, JSON.stringify(file, null, 2));
33546
- if (!staleKeysRead) return;
33547
- await this.pruneSupersededRunFiles(keptRunIds, dirPrefix, await staleKeysRead);
33548
- }
33549
- async drain() {
33550
- await this.writeChain;
33551
- }
33552
- scheduleFlush(delayMs) {
33553
- if (this.flushTimer) {
33554
- if (delayMs > 0) return;
33555
- clearTimeout(this.flushTimer);
33556
- }
33557
- this.flushTimer = setTimeout(() => {
33558
- this.flushTimer = void 0;
33559
- this.enqueueWrite(() => this.doFlush());
33560
- }, delayMs);
33561
- this.flushTimer.unref?.();
33562
- }
33563
- enqueueWrite(op) {
33564
- const next = this.writeChain.then(op).catch((err) => {
33565
- this.warnOnce(`Failed to persist deployment events for run ${this.runId}: ${describeAwsFailure(err).detail}`);
33566
- });
33567
- this.writeChain = next;
33568
- return next;
33569
- }
33570
- async doFlush() {
33571
- if (this.events.length === 0 || this.events.length === this.persistedCount) return;
33572
- const snapshotCount = this.events.length;
33573
- const body = this.events.slice(0, snapshotCount).map((e) => JSON.stringify(e)).join("\n");
33574
- await this.backend.putRawObject(deploymentEventsKey(this.backend.prefix, this.stackName, this.region, this.runId), body + "\n", "application/x-ndjson");
33575
- this.persistedCount = snapshotCount;
33576
- }
33577
- async readIndexRuns() {
33578
- const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
33579
- try {
33580
- const raw = await this.backend.getRawObject(key);
33581
- if (raw !== null) {
33582
- const parsed = JSON.parse(raw);
33583
- if (Array.isArray(parsed.runs)) return parsed.runs;
33584
- }
33585
- } catch (err) {
33586
- this.logger.debug(`Deployment-events index unreadable, rewriting: ${describeAwsFailure(err).detail}`);
33587
- }
33588
- return [];
33589
- }
33590
- buildIndexUpdate(result, existingRuns) {
33591
- const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
33592
- const runs = [{
33593
- runId: this.runId,
33594
- command: this.command,
33595
- cdkdVersion: this.cdkdVersion,
33596
- startedAt: this.startedAt,
33597
- finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
33598
- result,
33599
- eventCount: this.persistedCount
33600
- }, ...existingRuns.filter((r) => r.runId !== this.runId)].slice(0, 20);
33601
- return {
33602
- key,
33603
- file: {
33604
- indexVersion: 1,
33605
- stackName: this.stackName,
33606
- region: this.region,
33607
- runs,
33608
- lastModified: Date.now()
33609
- },
33610
- runs
33611
- };
33612
- }
33613
- async pruneSupersededRunFiles(keptRunIds, dirPrefix, keys) {
33614
- if (keptRunIds.length < 20) return;
33615
- const cutoff = keptRunIds.reduce((min, id) => id < min ? id : min, keptRunIds[0]);
33616
- const stale = keys.filter((k) => {
33617
- const runId = runIdFromJsonlKey(k, dirPrefix);
33618
- return runId !== null && runId < cutoff;
33672
+ async function askResourceIdentity(providerRegistry, target, region) {
33673
+ try {
33674
+ const { provider } = providerRegistry.getProviderFor({
33675
+ resourceType: target.resourceType,
33676
+ provisionedBy: target.provisionedBy
33619
33677
  });
33620
- if (stale.length === 0) return;
33621
- await deleteAndPurgeEventObjects(this.backend, stale, dirPrefix);
33622
- this.logger.debug(`Pruned ${stale.length} superseded deployment-event stream(s) for ${this.stackName} (${this.region})`);
33623
- }
33624
- warnOnce(message) {
33625
- if (this.warnedOnce) {
33626
- this.logger.debug(message);
33627
- return;
33628
- }
33629
- this.warnedOnce = true;
33630
- this.logger.warn(`${message} — continuing; deployment events are best-effort and never block the run.`);
33631
- }
33632
- };
33633
- var DeploymentEventsReader = class {
33634
- backend;
33635
- constructor(backend) {
33636
- this.backend = backend;
33637
- }
33638
- async listRegions(stackName) {
33639
- const prefix = `${this.backend.prefix}/${stackName}/`;
33640
- const keys = await this.backend.listRawKeys(prefix);
33641
- const regions = /* @__PURE__ */ new Set();
33642
- for (const key of keys) {
33643
- const segments = key.slice(prefix.length).split("/");
33644
- if (segments.length === 3 && segments[1] === "deployments" && segments[0]) regions.add(segments[0]);
33645
- }
33646
- return [...regions].sort();
33647
- }
33648
- async listRuns(stackName, region) {
33649
- const key = deploymentEventsIndexKey(this.backend.prefix, stackName, region);
33650
- try {
33651
- const raw = await this.backend.getRawObject(key);
33652
- if (raw !== null) {
33653
- const parsed = JSON.parse(raw);
33654
- if (Array.isArray(parsed.runs)) return parsed.runs;
33655
- }
33656
- } catch {}
33657
- const dirPrefix = `${this.backend.prefix}/${stackName}/${region}/deployments/`;
33658
- const runIds = (await this.backend.listRawKeys(dirPrefix)).filter((k) => k.endsWith(".jsonl")).map((k) => k.slice(dirPrefix.length, -6)).sort().reverse();
33659
- return Promise.all(runIds.map((runId) => this.summarizeRunFromJsonl(stackName, region, runId)));
33660
- }
33661
- async summarizeRunFromJsonl(stackName, region, runId) {
33662
- const fallback = {
33663
- runId,
33664
- command: "deploy",
33665
- cdkdVersion: "unknown",
33666
- startedAt: "",
33667
- finishedAt: "",
33668
- result: "UNKNOWN",
33669
- eventCount: 0
33670
- };
33671
- let events = null;
33672
- try {
33673
- events = await this.readRunEvents(stackName, region, runId);
33674
- } catch {
33675
- return fallback;
33676
- }
33677
- if (events === null || events.length === 0) return fallback;
33678
- const started = events.find((e) => e.eventType === "RUN_STARTED");
33679
- let finished;
33680
- for (const e of events) if (e.eventType === "RUN_FINISHED") finished = e;
33681
- return {
33682
- runId,
33683
- command: started?.command ?? fallback.command,
33684
- cdkdVersion: started?.cdkdVersion ?? fallback.cdkdVersion,
33685
- startedAt: started?.timestamp ?? fallback.startedAt,
33686
- finishedAt: finished?.timestamp ?? fallback.finishedAt,
33687
- result: finished?.result ?? "UNKNOWN",
33688
- eventCount: events.length
33689
- };
33690
- }
33691
- async readRunEvents(stackName, region, runId) {
33692
- const key = deploymentEventsKey(this.backend.prefix, stackName, region, runId);
33693
- const raw = await this.backend.getRawObject(key);
33694
- if (raw === null) return null;
33695
- const events = [];
33696
- for (const line of raw.split("\n")) {
33697
- const trimmed = line.trim();
33698
- if (!trimmed) continue;
33699
- try {
33700
- events.push(JSON.parse(trimmed));
33701
- } catch {}
33702
- }
33703
- return events;
33678
+ if (typeof provider.resourceIdentity !== "function") return void 0;
33679
+ const identity = await provider.resourceIdentity(target.physicalId, target.resourceType, { expectedRegion: region });
33680
+ if (identity === RESOURCE_NOT_FOUND) return RESOURCE_NOT_FOUND;
33681
+ return typeof identity === "string" && identity !== "" ? identity : void 0;
33682
+ } catch {
33683
+ return;
33704
33684
  }
33705
- async pruneRuns(stackName, region, opts = {}) {
33706
- const dirPrefix = deploymentsDirPrefix(this.backend.prefix, stackName, region);
33707
- const keys = await this.backend.listRawKeys(dirPrefix);
33708
- const runIdsDesc = keys.map((k) => runIdFromJsonlKey(k, dirPrefix)).filter((id) => id !== null).sort().reverse();
33709
- const indexKey = deploymentEventsIndexKey(this.backend.prefix, stackName, region);
33710
- const indexExisted = keys.includes(indexKey);
33711
- if (opts.all === true) {
33712
- const toDelete = runIdsDesc.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
33713
- const earlierVersions = await deleteAndPurgeEventObjects(this.backend, [...toDelete, indexKey], dirPrefix, "whole-dir");
33714
- return {
33715
- deletedRunIds: runIdsDesc,
33716
- remainingRunIds: [],
33717
- indexDeleted: indexExisted,
33718
- ...earlierVersions !== void 0 && { earlierVersions }
33719
- };
33720
- }
33721
- const noGuards = opts.keep === void 0 && opts.olderThanMs === void 0;
33722
- const keep = opts.keep ?? (noGuards ? 20 : void 0);
33723
- const protectedByCount = keep === void 0 ? /* @__PURE__ */ new Set() : new Set(runIdsDesc.slice(0, keep));
33724
- let candidates = runIdsDesc.filter((id) => !protectedByCount.has(id));
33725
- if (opts.olderThanMs !== void 0) {
33726
- const cutoff = (opts.now ?? /* @__PURE__ */ new Date()).getTime() - opts.olderThanMs;
33727
- candidates = candidates.filter((id) => {
33728
- const t = runIdTimestampMs(id);
33729
- return t !== null && t < cutoff;
33730
- });
33731
- }
33732
- if (candidates.length === 0) return {
33733
- deletedRunIds: [],
33734
- remainingRunIds: runIdsDesc,
33735
- indexDeleted: false
33736
- };
33737
- const deletedSet = new Set(candidates);
33738
- const deleteKeys = candidates.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
33739
- const remainingRunIds = runIdsDesc.filter((id) => !deletedSet.has(id));
33740
- if (remainingRunIds.length === 0) {
33741
- await deleteAndPurgeEventObjects(this.backend, [...deleteKeys, indexKey], dirPrefix);
33742
- return {
33743
- deletedRunIds: candidates,
33744
- remainingRunIds,
33745
- indexDeleted: indexExisted
33746
- };
33747
- }
33748
- await this.rewriteIndexAfterPrune(indexKey, stackName, region, deletedSet);
33749
- await deleteAndPurgeEventObjects(this.backend, deleteKeys, dirPrefix);
33685
+ }
33686
+ async function createdResourceStillThere(op, ctx) {
33687
+ if (op.deletionPolicy === "Retain") return "proven";
33688
+ if (!orphanNeedsIdentity(op)) return "proven";
33689
+ const physicalId = op.physicalId;
33690
+ if (!physicalId) return "unproven";
33691
+ const live = await readResourceIdentity(ctx.providerRegistry, {
33692
+ resourceType: op.resourceType,
33693
+ physicalId,
33694
+ provisionedBy: op.provisionedBy
33695
+ }, ctx.region);
33696
+ if (live === RESOURCE_NOT_FOUND) return "gone";
33697
+ const journaled = op.createdResourceIdentity;
33698
+ if (typeof journaled !== "string" || journaled === "" || typeof live !== "string") return "unproven";
33699
+ return live === journaled ? "proven" : "mismatch";
33700
+ }
33701
+ async function askForeignHolder(foreignHolder, op) {
33702
+ try {
33703
+ return await foreignHolder(op.resourceType, op.physicalId);
33704
+ } catch {
33750
33705
  return {
33751
- deletedRunIds: candidates,
33752
- remainingRunIds,
33753
- indexDeleted: false
33754
- };
33755
- }
33756
- async rewriteIndexAfterPrune(indexKey, stackName, region, deletedRunIds) {
33757
- let raw;
33758
- try {
33759
- raw = await this.backend.getRawObject(indexKey);
33760
- } catch {
33761
- return;
33762
- }
33763
- if (raw === null) return;
33764
- let parsed;
33765
- try {
33766
- parsed = JSON.parse(raw);
33767
- } catch {
33768
- return;
33769
- }
33770
- if (!Array.isArray(parsed.runs)) return;
33771
- const remaining = parsed.runs.filter((r) => !deletedRunIds.has(r.runId));
33772
- if (remaining.length === parsed.runs.length) return;
33773
- const file = {
33774
- indexVersion: 1,
33775
- stackName,
33776
- region,
33777
- runs: remaining,
33778
- lastModified: Date.now()
33706
+ kind: "unreadable",
33707
+ what: "the other stacks' state records (the scan failed)"
33779
33708
  };
33780
- await this.backend.putRawObject(indexKey, JSON.stringify(file, null, 2));
33781
33709
  }
33782
- };
33710
+ }
33783
33711
 
33784
33712
  //#endregion
33785
33713
  //#region src/deployment/rollback-executor/replay-scope.ts
@@ -34089,93 +34017,6 @@ function renderNestedStackTypeChangeRefusal(typeChanges, stackName) {
34089
34017
  return `Refusing to deploy ${stackName}: ` + (typeChanges.length === 1 ? `a resource changes its Type ` : `${typeChanges.length} resources change their Type `) + `into or out of ${NESTED_STACK_RESOURCE_TYPE}, which cdkd does not replace in place.\n${rows.join("\n")}\n Deploy this as two changes instead: give the new resource a DIFFERENT logical id (in CDK, rename the construct) so the existing row is deleted through its own type's provider and the new one is created under its own — or remove the resource in one deploy and add its replacement in the next. There is no flag that overrides this refusal.`;
34090
34018
  }
34091
34019
 
34092
- //#endregion
34093
- //#region src/deployment/rollback-executor/orphan-identity.ts
34094
- const UNIQUE_PHYSICAL_ID_TYPES = /* @__PURE__ */ new Set([
34095
- "AWS::EC2::VPC",
34096
- "AWS::EC2::Subnet",
34097
- "AWS::EC2::EIP",
34098
- "AWS::EC2::NatGateway",
34099
- "AWS::EC2::SecurityGroup",
34100
- "AWS::EC2::Instance",
34101
- "AWS::EFS::FileSystem",
34102
- "AWS::EFS::MountTarget",
34103
- "AWS::FSx::FileSystem",
34104
- "AWS::KMS::Key",
34105
- "AWS::CertificateManager::Certificate",
34106
- "AWS::ElasticLoadBalancingV2::LoadBalancer",
34107
- "AWS::ElasticLoadBalancingV2::TargetGroup",
34108
- "AWS::ElasticLoadBalancingV2::Listener",
34109
- "AWS::EMR::Cluster",
34110
- "AWS::EMR::InstanceGroupConfig",
34111
- "AWS::EMR::InstanceFleetConfig",
34112
- "AWS::Cognito::UserPool",
34113
- "AWS::Route53::HostedZone",
34114
- "AWS::ServiceDiscovery::PrivateDnsNamespace",
34115
- "AWS::ServiceDiscovery::PublicDnsNamespace",
34116
- "AWS::ServiceDiscovery::HttpNamespace",
34117
- "AWS::ServiceDiscovery::Service",
34118
- "AWS::AppSync::GraphQLApi",
34119
- "AWS::IAM::AccessKey",
34120
- "AWS::Kinesis::StreamConsumer"
34121
- ]);
34122
- const CONTENT_COMPARED_DELETE_TYPES = /* @__PURE__ */ new Set(["AWS::SQS::QueuePolicy", "AWS::SNS::TopicPolicy"]);
34123
- const CDKD_NAMESPACE_ID_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::Stack"]);
34124
- function orphanDeleteNeedsIdentity(resourceType) {
34125
- return !UNIQUE_PHYSICAL_ID_TYPES.has(resourceType) && !CONTENT_COMPARED_DELETE_TYPES.has(resourceType) && !CDKD_NAMESPACE_ID_TYPES.has(resourceType);
34126
- }
34127
- const RESOURCE_IDENTITY_TIMEOUT_MS = 1e4;
34128
- async function readResourceIdentity(providerRegistry, target, region, timeoutMs = RESOURCE_IDENTITY_TIMEOUT_MS) {
34129
- let timer;
34130
- const timedOut = new Promise((resolve) => {
34131
- timer = setTimeout(() => resolve(void 0), timeoutMs);
34132
- });
34133
- try {
34134
- return await Promise.race([askResourceIdentity(providerRegistry, target, region), timedOut]);
34135
- } finally {
34136
- clearTimeout(timer);
34137
- }
34138
- }
34139
- async function askResourceIdentity(providerRegistry, target, region) {
34140
- try {
34141
- const { provider } = providerRegistry.getProviderFor({
34142
- resourceType: target.resourceType,
34143
- provisionedBy: target.provisionedBy
34144
- });
34145
- if (typeof provider.resourceIdentity !== "function") return void 0;
34146
- const identity = await provider.resourceIdentity(target.physicalId, target.resourceType, { expectedRegion: region });
34147
- if (identity === RESOURCE_NOT_FOUND) return RESOURCE_NOT_FOUND;
34148
- return typeof identity === "string" && identity !== "" ? identity : void 0;
34149
- } catch {
34150
- return;
34151
- }
34152
- }
34153
- async function createdResourceStillThere(op, ctx) {
34154
- if (op.deletionPolicy === "Retain") return "proven";
34155
- if (!orphanDeleteNeedsIdentity(op.resourceType)) return "proven";
34156
- const physicalId = op.physicalId;
34157
- if (!physicalId) return "unproven";
34158
- const live = await readResourceIdentity(ctx.providerRegistry, {
34159
- resourceType: op.resourceType,
34160
- physicalId,
34161
- provisionedBy: op.provisionedBy
34162
- }, ctx.region);
34163
- if (live === RESOURCE_NOT_FOUND) return "gone";
34164
- const journaled = op.createdResourceIdentity;
34165
- if (typeof journaled !== "string" || journaled === "" || typeof live !== "string") return "unproven";
34166
- return live === journaled ? "proven" : "mismatch";
34167
- }
34168
- async function askForeignHolder(foreignHolder, op) {
34169
- try {
34170
- return await foreignHolder(op.resourceType, op.physicalId);
34171
- } catch {
34172
- return {
34173
- kind: "unreadable",
34174
- what: "the other stacks' state records (the scan failed)"
34175
- };
34176
- }
34177
- }
34178
-
34179
34020
  //#endregion
34180
34021
  //#region src/deployment/rollback-executor/plan.ts
34181
34022
  function journaledOldTypes(op) {
@@ -35632,7 +35473,7 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
35632
35473
  }
35633
35474
  function protectionRemovalProven(op, deleteProven) {
35634
35475
  if (op.physicalIdRecoveredFromError !== true) return true;
35635
- return deleteProven && (!orphanDeleteNeedsIdentity(op.resourceType) || removeProtectionTypes().includes(op.resourceType));
35476
+ return deleteProven && (!orphanNeedsIdentity(op) || removeProtectionTypes().includes(op.resourceType));
35636
35477
  }
35637
35478
  async function journaledOrphanKeepReason(op, foreignHolder, ctx) {
35638
35479
  const holding = await askForeignHolder(foreignHolder, op);
@@ -36050,6 +35891,344 @@ async function replayFailedOperations(...args) {
36050
35891
  return await withProducerRegions(() => replayProducerRegionEvidence(args[3]), () => withStackRecords(replayStackRecordsView(args[1]), () => replayFailedOperationsUnbound(...args)));
36051
35892
  }
36052
35893
 
35894
+ //#endregion
35895
+ //#region src/provisioning/nested-stack-context.ts
35896
+ const storage$1 = new AsyncLocalStorage();
35897
+ function withNestedStackContext(ctx, fn) {
35898
+ return storage$1.run(ctx, fn);
35899
+ }
35900
+ function getCurrentNestedStackContext() {
35901
+ return storage$1.getStore();
35902
+ }
35903
+ async function collectNestedChildUnaddressed(fn) {
35904
+ const ctx = storage$1.getStore();
35905
+ if (!ctx) return {
35906
+ value: await fn(),
35907
+ unaddressed: void 0
35908
+ };
35909
+ const slot = {};
35910
+ return {
35911
+ value: await storage$1.run({
35912
+ ...ctx,
35913
+ childUnaddressed: slot
35914
+ }, fn),
35915
+ unaddressed: slot.last
35916
+ };
35917
+ }
35918
+
35919
+ //#endregion
35920
+ //#region src/deployment/nested-child-journal.ts
35921
+ const NESTED_PENDING_PARENT_REASON = "nested-pending-parent";
35922
+ const NESTED_STACK_TYPE$2 = "AWS::CloudFormation::Stack";
35923
+ const MAX_NESTED_WALK_DEPTH = 32;
35924
+ function nestedChildStackName(parentStackName, logicalId) {
35925
+ return `${parentStackName}~${logicalId}`;
35926
+ }
35927
+ function nestedPendingSnapshot(state, refusesExportName) {
35928
+ const outputs = { ...isPlainRecord(state.outputs) ? state.outputs : {} };
35929
+ let exportNames = Array.isArray(state.exportNames) ? [...state.exportNames] : void 0;
35930
+ const refused = new Set(importableOutputKeys(state).filter((name) => refusesExportName(name)));
35931
+ if (refused.size > 0) {
35932
+ for (const name of refused) Reflect.deleteProperty(outputs, name);
35933
+ if (exportNames !== void 0) exportNames = exportNames.filter((name) => !refused.has(name));
35934
+ }
35935
+ return {
35936
+ previousOutputs: {
35937
+ outputs,
35938
+ ...exportNames !== void 0 && { exportNames }
35939
+ },
35940
+ previousCrossStackReads: {
35941
+ ...Array.isArray(state.imports) && { imports: [...state.imports] },
35942
+ ...Array.isArray(state.outputReads) && { outputReads: [...state.outputReads] }
35943
+ }
35944
+ };
35945
+ }
35946
+ function displacedPhysicalIdShown(op, logger, physicalId = journalOpPhysicalId(op)) {
35947
+ if (physicalId === void 0) return void 0;
35948
+ const masker = createOpMasker(logger, /* @__PURE__ */ new Map());
35949
+ for (const properties of [
35950
+ op.properties,
35951
+ op.attemptedProperties,
35952
+ op.previousState?.properties
35953
+ ]) {
35954
+ if (properties === void 0) continue;
35955
+ masker.addNamed({
35956
+ resourceType: op.resourceType,
35957
+ properties,
35958
+ logicalId: op.logicalId,
35959
+ physicalIds: [physicalId]
35960
+ });
35961
+ }
35962
+ return displaySafe(String(masker.mask(physicalId)));
35963
+ }
35964
+ function displacedOpClause(op, marks, logger) {
35965
+ const retainedOld = retainedOldPhysicalId(op);
35966
+ if (retainedOld !== void 0 && marks.some((m) => isMarkFor(m, op))) {
35967
+ const shownOld = displacedPhysicalIdShown(op, logger, retainedOld);
35968
+ return `replaced ${shownOld} ${op.oldResourceRetained === true ? "but kept it (UpdateReplacePolicy: Retain)" : op.oldResourceMaySurvive !== void 0 ? "and may have kept it (its delete was not confirmed)" : "and may have kept it (the journal records no verdict)"}; cdkd import adopted the replacement, so ${shownOld} is left untracked`;
35969
+ }
35970
+ const shownId = displacedPhysicalIdShown(op, logger);
35971
+ return shownId !== void 0 ? `recorded ${shownId}, which cdkd import has since replaced under this id` : "recorded no physical id, and cdkd import has since put another resource under this id";
35972
+ }
35973
+ function recordDisplacedSkips(recordEvent, stackName, ops) {
35974
+ for (const op of ops) recordEvent?.({
35975
+ eventType: "ROLLBACK_RESOURCE_SKIPPED",
35976
+ stackName,
35977
+ operation: op.changeType,
35978
+ logicalId: op.logicalId,
35979
+ resourceType: op.resourceType,
35980
+ ...op.provisionedBy && { provisionedBy: op.provisionedBy },
35981
+ reason: "cdkd import has since put another resource under this logical id, so the op was not reverted; check the resource it recorded by hand"
35982
+ });
35983
+ }
35984
+ function revertedNestedRowIds(ops) {
35985
+ return ops.filter((op) => op.resourceType === NESTED_STACK_TYPE$2 && op.changeType === "UPDATE").map((op) => op.logicalId);
35986
+ }
35987
+ const revertRunStorage = new AsyncLocalStorage();
35988
+ function withNestedRevertRun(runId, fn) {
35989
+ const run = {
35990
+ runId,
35991
+ settled: /* @__PURE__ */ new Map(),
35992
+ warnings: 0
35993
+ };
35994
+ return revertRunStorage.run(run, () => fn(run));
35995
+ }
35996
+ function getNestedRevertRun() {
35997
+ return revertRunStorage.getStore();
35998
+ }
35999
+ function errorText(error) {
36000
+ return displaySafe(describeAwsFailure(error).detail);
36001
+ }
36002
+ function isPlainRecord(value) {
36003
+ return typeof value === "object" && value !== null && !Array.isArray(value);
36004
+ }
36005
+ async function dropNestedChildJournals(args) {
36006
+ const { stateBackend, parentStackName, region, resources, logger } = args;
36007
+ const depth = args.depth ?? 0;
36008
+ if (!isPlainRecord(resources)) return;
36009
+ if (depthExceeded(depth, parentStackName, logger)) return;
36010
+ for (const [logicalId, record] of Object.entries(resources)) {
36011
+ if (!isPlainRecord(record) || record["resourceType"] !== NESTED_STACK_TYPE$2) continue;
36012
+ const child = nestedChildStackName(parentStackName, logicalId);
36013
+ try {
36014
+ const data = await stateBackend.getState(child, region);
36015
+ if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) await dropNestedChildJournals({
36016
+ ...args,
36017
+ parentStackName: child,
36018
+ resources: data.state.resources,
36019
+ depth: depth + 1
36020
+ });
36021
+ } catch (error) {
36022
+ warnUncleared(logger, child, error);
36023
+ }
36024
+ try {
36025
+ if (await withChildLock(args.lockManager, child, region, logger, async () => {
36026
+ if (args.beforeDelete) {
36027
+ if (!await args.beforeDelete(child, await readOwnRecord(stateBackend, child, region))) return false;
36028
+ }
36029
+ let gone;
36030
+ try {
36031
+ gone = await stateBackend.deleteRollbackJournal(child, region);
36032
+ } catch (error) {
36033
+ await args.onDeleteFailed?.(child);
36034
+ throw error;
36035
+ }
36036
+ if (gone === false) {
36037
+ await args.onDeleteFailed?.(child);
36038
+ return false;
36039
+ }
36040
+ return true;
36041
+ })) logger.debug(safeMsg`Deleted the rollback journal of nested stack ${displaySafe(child)}`);
36042
+ } catch (error) {
36043
+ warnUncleared(logger, child, error);
36044
+ }
36045
+ }
36046
+ }
36047
+ async function readOwnRecord(stateBackend, child, region) {
36048
+ try {
36049
+ const data = await stateBackend.getState(child, region);
36050
+ if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) return data.state;
36051
+ } catch {}
36052
+ }
36053
+ async function dropSettledNestedJournals(args) {
36054
+ const { stateBackend, parentStackName, region, runId, logger } = args;
36055
+ const depth = args.depth ?? 0;
36056
+ if (runId === void 0) return;
36057
+ if (depthExceeded(depth, parentStackName, logger)) return;
36058
+ const isSettled = (segment) => segment.runId === runId && segment.reason === "nested-pending-parent";
36059
+ for (const [logicalId, grandchildren] of args.settled) {
36060
+ const child = nestedChildStackName(parentStackName, logicalId);
36061
+ if (grandchildren.size > 0) await dropSettledNestedJournals({
36062
+ ...args,
36063
+ parentStackName: child,
36064
+ settled: grandchildren,
36065
+ depth: depth + 1
36066
+ });
36067
+ try {
36068
+ const removed = await withChildLock(args.lockManager, child, region, logger, () => stateBackend.dropRollbackJournalSegments(child, region, isSettled));
36069
+ if (removed > 0) logger.debug(safeMsg`Dropped ${removed} settled rollback journal segment(s) of ${displaySafe(child)}`);
36070
+ } catch (error) {
36071
+ warnUncleared(logger, child, error);
36072
+ }
36073
+ }
36074
+ }
36075
+ async function withChildLock(lockManager, child, region, logger, fn) {
36076
+ await lockManager.acquireLockWithRetry(child, region, void 0, "rollback");
36077
+ try {
36078
+ return await fn();
36079
+ } finally {
36080
+ await lockManager.releaseLock(child, region).catch((error) => {
36081
+ logger.warn(safeMsg`Failed to release the lock of nested stack ${displayIdent(child)}: ${errorText(error)}`);
36082
+ });
36083
+ }
36084
+ }
36085
+ function depthExceeded(depth, parentStackName, logger) {
36086
+ if (depth < MAX_NESTED_WALK_DEPTH) return false;
36087
+ logger.warn(safeMsg`Stopped clearing nested rollback journals below ${displayIdent(parentStackName)}: ` + safeMsg`the nesting is deeper than ${MAX_NESTED_WALK_DEPTH} levels.`);
36088
+ return true;
36089
+ }
36090
+ function warnUncleared(logger, child, error) {
36091
+ logger.warn(safeMsg`Could not clear the rollback journal of nested stack ${displayIdent(child)}: ${errorText(error)}. ` + "It is inert to every parent revert (they select segments by run) and the next successful deploy of the top-level stack removes it.");
36092
+ }
36093
+ async function revertNestedChildFromJournal(args) {
36094
+ const { ctx, logicalId, childStackName, region, run, logger } = args;
36095
+ const runId = run.runId;
36096
+ const shownChild = displayIdent(childStackName);
36097
+ const refuse = (detail) => {
36098
+ throw markNonRetryable(/* @__PURE__ */ new Error(`Cannot revert nested stack ${shownChild} (row ${displayIdent(logicalId)}): ${detail} The child was NOT (fully) reverted and may still hold the failed deploy's configuration. Inspect it with 'cdkd state show'; re-run the rollback once the cause is fixed (its journal is kept), or re-deploy the parent to converge.`));
36099
+ };
36100
+ if (runId === void 0) refuse("the rollback carries no deploy run id to select its journal segments by.");
36101
+ await ctx.lockManager.acquireLockWithRetry(childStackName, region, void 0, "rollback");
36102
+ try {
36103
+ const stateData = await ctx.stateBackend.getState(childStackName, region);
36104
+ if (!stateData) refuse("its state.json is missing.");
36105
+ if (stateData.divergentBodyRegion !== void 0) refuse("its state record's region field disagrees with the key it is stored under.");
36106
+ const base = stateData.state;
36107
+ const refusalRecovery = {
36108
+ profile: ctx.destroyOptions?.profile,
36109
+ stateBucket: ctx.stateBucket,
36110
+ statePrefix: ctx.destroyOptions?.statePrefix
36111
+ };
36112
+ refuseMalformedState(base, childStackName, region, refusalRecovery);
36113
+ refuseMalformedOrphans(base, childStackName, region, refusalRecovery);
36114
+ refuseMalformedOrphanRecords(base, childStackName, region, refusalRecovery);
36115
+ const segments = ((await ctx.stateBackend.loadRollbackJournal(childStackName, region))?.segments ?? []).filter((segment) => segment.runId === runId);
36116
+ if (segments.length === 0) refuse("its rollback journal holds no segment for this deploy run, so there is no record of what it held before.");
36117
+ const stateResources = { ...base.resources };
36118
+ const mintedOrphans = [];
36119
+ const restoredOutputs = segments.find((s) => s.previousOutputs)?.previousOutputs;
36120
+ const restoredReads = segments.find((s) => s.previousCrossStackReads)?.previousCrossStackReads;
36121
+ let currentEtag = stateData.etag;
36122
+ let persisted = false;
36123
+ let restoring = false;
36124
+ const { skippedOutputs: _dropped, ...carried } = base;
36125
+ const next = () => ({
36126
+ ...carried,
36127
+ version: 12,
36128
+ region,
36129
+ resources: { ...stateResources },
36130
+ ...orphansAfterRollback(base, mintedOrphans),
36131
+ ...restoring && restoredOutputs && { outputs: { ...restoredOutputs.outputs } },
36132
+ ...restoring && restoredReads && {
36133
+ ...restoredReads.imports && { imports: [...restoredReads.imports] },
36134
+ ...restoredReads.outputReads && { outputReads: [...restoredReads.outputReads] }
36135
+ },
36136
+ ...restoring && restoredOutputs?.exportNames && { exportNames: [...restoredOutputs.exportNames] },
36137
+ lastModified: Date.now()
36138
+ });
36139
+ const nextState = () => {
36140
+ const state = next();
36141
+ if (!restoring) return state;
36142
+ if (restoredOutputs && !restoredOutputs.exportNames) delete state.exportNames;
36143
+ if (restoredOutputs) delete state.outputReferenceProvenance;
36144
+ if (restoredReads && !restoredReads.imports) delete state.imports;
36145
+ if (restoredReads && !restoredReads.outputReads) delete state.outputReads;
36146
+ return state;
36147
+ };
36148
+ const save = async () => {
36149
+ persisted = false;
36150
+ try {
36151
+ currentEtag = await ctx.stateBackend.saveState(childStackName, region, nextState(), { ...currentEtag !== void 0 && { expectedEtag: currentEtag } });
36152
+ persisted = true;
36153
+ } catch {
36154
+ try {
36155
+ const fresh = await ctx.stateBackend.getState(childStackName, region);
36156
+ currentEtag = await ctx.stateBackend.saveState(childStackName, region, nextState(), { ...fresh?.etag !== void 0 && { expectedEtag: fresh.etag } });
36157
+ persisted = true;
36158
+ } catch (retryError) {
36159
+ logger.warn(safeMsg`Failed to persist the state of nested stack ${shownChild} after reverting it: ` + safeMsg`${errorText(retryError)}. The resources were reverted in AWS.`);
36160
+ }
36161
+ }
36162
+ };
36163
+ const producerRegions = inheritProducerRegions(producerRegionsFromState({
36164
+ imports: [...base.imports ?? [], ...restoredReads?.imports ?? []],
36165
+ outputReads: [...base.outputReads ?? [], ...restoredReads?.outputReads ?? []]
36166
+ }), args.inheritedProducerRegions);
36167
+ const execCtx = {
36168
+ providerRegistry: ctx.providerRegistry,
36169
+ region,
36170
+ logger,
36171
+ ...ctx.options?.eventRecorder && { recordEvent: (event) => ctx.options.eventRecorder.record(maskEventTextWithBoundBags(event)) },
36172
+ finalSnapshotClients: ctx.options?.finalSnapshotClients,
36173
+ skipFinalSnapshot: ctx.options?.skipFinalSnapshot === true || ctx.destroyOptions?.skipFinalSnapshot === true,
36174
+ ...ctx.destroyOptions?.removeProtection === true && {
36175
+ removeProtection: true,
36176
+ foreignHolder: makeForeignHolderScan(ctx.stateBackend)({
36177
+ stackName: childStackName,
36178
+ region
36179
+ })
36180
+ },
36181
+ importedProducerRegions: producerRegions.regions,
36182
+ producerRegionsIncomplete: !producerRegions.complete,
36183
+ nestedChildRevert: true
36184
+ };
36185
+ const childCtx = {
36186
+ ...ctx,
36187
+ parentStackName: childStackName,
36188
+ parentRegion: region,
36189
+ nestedTemplates: void 0
36190
+ };
36191
+ let failures = 0;
36192
+ let warnings = 0;
36193
+ const inlinePolicyWriters = new RollbackInlinePolicyWriters();
36194
+ const settledBelow = /* @__PURE__ */ new Map();
36195
+ for (let s = segments.length - 1; s >= 0; s--) {
36196
+ const segment = segments[s];
36197
+ const skipPrefix = segment.skipPrefix ?? getCurrentSkipPrefix();
36198
+ const split = splitImportedOps(segment.operations, segment);
36199
+ const result = await withNestedStackContext(childCtx, () => withSkipPrefix(skipPrefix, () => withStackName(childStackName, () => withCreateTokenLedger(ledgerForStack(ctx.stateBackend, childStackName, region), () => withNestedRevertRun(runId, async (inner) => {
36200
+ const replayed = await withPrintingSecrets(journaledOrphanPrintingBag(completedReplayEntries(split.replay), stateResources), () => replayRollback(split.replay, stateResources, childStackName, execCtx, {
36201
+ afterOp: save,
36202
+ onOrphan: (record) => mintedOrphans.push(record),
36203
+ inlinePolicyWriters,
36204
+ failedOperations: segment.failedOperations
36205
+ }));
36206
+ for (const [id, below] of inner.settled) settledBelow.set(id, below);
36207
+ return {
36208
+ ...replayed,
36209
+ warnings: replayed.warnings + inner.warnings
36210
+ };
36211
+ })))));
36212
+ failures += result.failures;
36213
+ warnings += result.warnings + split.displaced.length;
36214
+ recordDisplacedSkips(execCtx.recordEvent, childStackName, split.displaced);
36215
+ for (const op of split.displaced) logger.warn(safeMsg`Nested stack ${childStackName}: ${op.logicalId} ` + safeMsg`${displacedOpClause(op, segment.importedResources ?? [], logger)}; ` + "not reverted, check that resource by hand");
36216
+ }
36217
+ restoring = failures === 0;
36218
+ await save();
36219
+ if (restoring && persisted && restoredOutputs && ctx.exportIndexStore) await ctx.exportIndexStore.updateForStack(childStackName, region, importableOutputs(nextState()));
36220
+ if (warnings > 0) logger.warn(safeMsg`Nested stack ${shownChild}: ${warnings} operation(s) were skipped with a warning during ` + `its revert (see above); they may need attention by hand.`);
36221
+ if (failures > 0) refuse(`${failures} of its operation(s) failed to revert (see the warnings above).`);
36222
+ if (warnings > 0) run.warnings += warnings;
36223
+ else run.settled.set(logicalId, settledBelow);
36224
+ return { warnings };
36225
+ } finally {
36226
+ await ctx.lockManager.releaseLock(childStackName, region).catch((error) => {
36227
+ logger.warn(safeMsg`Failed to release the lock of nested stack ${shownChild}: ${errorText(error)}`);
36228
+ });
36229
+ }
36230
+ }
36231
+
36053
36232
  //#endregion
36054
36233
  //#region src/deployment/rollback-executor/journaled-orphans.ts
36055
36234
  const NONE = {
@@ -36082,6 +36261,7 @@ async function loadJournaledOrphans(stateBackend, stackName, region, rollbackOrp
36082
36261
  for (const segment of segments) if (options.deployRunId !== void 0 && segment.reason === "nested-pending-parent" && segment.runId === options.deployRunId) for (const op of segment.operations) deployLogicalIds.add(op.logicalId);
36083
36262
  const out = [];
36084
36263
  let count = 0;
36264
+ const pendingRequests = segments.flatMap((segment) => segment.failedOperations ?? []).filter((op) => op.pendingCloudControlRequest !== void 0).length;
36085
36265
  for (let s = segments.length - 1; s >= 0; s--) {
36086
36266
  const segment = segments[s];
36087
36267
  if (segment.reason === "nested-pending-parent") continue;
@@ -36099,7 +36279,8 @@ async function loadJournaledOrphans(stateBackend, stackName, region, rollbackOrp
36099
36279
  return {
36100
36280
  segments: out,
36101
36281
  count,
36102
- deployLogicalIds
36282
+ deployLogicalIds,
36283
+ ...pendingRequests > 0 && { pendingRequests }
36103
36284
  };
36104
36285
  }
36105
36286
  function journaledOrphanLines(orphans, logger) {
@@ -36215,10 +36396,24 @@ async function settleJournaledOrphansOnSuccess(args) {
36215
36396
  keepJournal: true
36216
36397
  };
36217
36398
  }
36218
- if (orphans.count === 0) return {
36219
- unaddressed: 0,
36220
- keepJournal: false
36399
+ const pendingKept = (orphans.pendingRequests ?? 0) > 0;
36400
+ const keepPendingOnly = async () => {
36401
+ try {
36402
+ await stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op) => op.pendingCloudControlRequest !== void 0, newerIds, () => false);
36403
+ return true;
36404
+ } catch (err) {
36405
+ logger.warn(safeMsg`Failed to reduce the rollback journal of stack ${stack} to its unsettled Cloud ` + safeMsg`Control requests: ${errorDetail(err)}. The whole journal is kept.`);
36406
+ await markSuperseded(stateBackend, stackName, region, newerIds);
36407
+ return false;
36408
+ }
36221
36409
  };
36410
+ if (orphans.count === 0) {
36411
+ if (pendingKept) await keepPendingOnly();
36412
+ return {
36413
+ unaddressed: 0,
36414
+ keepJournal: pendingKept
36415
+ };
36416
+ }
36222
36417
  const all = orphans.segments.flatMap(({ segment, ops }) => ops.map((op) => ({
36223
36418
  segment,
36224
36419
  op
@@ -36270,15 +36465,18 @@ async function settleJournaledOrphansOnSuccess(args) {
36270
36465
  logger.warn(safeMsg`Failed to remove the settled entries from the rollback journal of stack ${stack}: ` + safeMsg`${errorDetail(err)}. A cdkd rollback or cdkd destroy could act on them again; run a ` + "successful cdkd deploy of the stack first, which settles them again.");
36271
36466
  }
36272
36467
  };
36273
- if (kept.length === 0) return {
36274
- unaddressed: skipped + leftInPlace,
36275
- keepJournal: false,
36276
- ...stripCleared && { stripCleared }
36277
- };
36468
+ if (kept.length === 0) {
36469
+ if (pendingKept && !await keepPendingOnly()) await stripCleared?.();
36470
+ return {
36471
+ unaddressed: skipped + leftInPlace,
36472
+ keepJournal: pendingKept,
36473
+ ...stripCleared && { stripCleared }
36474
+ };
36475
+ }
36278
36476
  const keptIds = new Set(kept.map(({ op }) => op.logicalId));
36279
36477
  const supersededIds = newerIds.filter((id) => !keptIds.has(id));
36280
36478
  const demoted = kept.filter(({ op }) => op.physicalIdRecoveredFromError === false);
36281
- const reduce = () => stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op, segment) => isHandledOrphan(kept, segment, op), supersededIds, (op, segment) => isHandledOrphan(demoted, segment, op));
36479
+ const reduce = () => stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op, segment) => isHandledOrphan(kept, segment, op) || op.pendingCloudControlRequest !== void 0, supersededIds, (op, segment) => isHandledOrphan(demoted, segment, op));
36282
36480
  let reduced = false;
36283
36481
  for (let attempt = 0; attempt < 2 && !reduced; attempt++) try {
36284
36482
  await reduce();
@@ -36479,342 +36677,496 @@ function sameJournaledOrphans(a, b) {
36479
36677
  }
36480
36678
 
36481
36679
  //#endregion
36482
- //#region src/provisioning/nested-stack-context.ts
36483
- const storage$1 = new AsyncLocalStorage();
36484
- function withNestedStackContext(ctx, fn) {
36485
- return storage$1.run(ctx, fn);
36680
+ //#region src/deployment/cc-pending-requests.ts
36681
+ function hasPendingCloudControlRequest(op) {
36682
+ return op.pendingCloudControlRequest !== void 0;
36486
36683
  }
36487
- function getCurrentNestedStackContext() {
36488
- return storage$1.getStore();
36684
+ function pendingRequestCount(journal) {
36685
+ return pendingRequests(journal ?? null).size;
36489
36686
  }
36490
- async function collectNestedChildUnaddressed(fn) {
36491
- const ctx = storage$1.getStore();
36492
- if (!ctx) return {
36493
- value: await fn(),
36494
- unaddressed: void 0
36495
- };
36496
- const slot = {};
36497
- return {
36498
- value: await storage$1.run({
36499
- ...ctx,
36500
- childUnaddressed: slot
36501
- }, fn),
36502
- unaddressed: slot.last
36687
+ async function resolvePendingCloudControlRequests(params) {
36688
+ const { journal, stackName, region } = params;
36689
+ if (pendingRequests(params.loaded).size === 0) return false;
36690
+ const settle = async () => {
36691
+ await params.beforeSettle?.();
36692
+ let current = params.loaded;
36693
+ if (params.underLock) try {
36694
+ current = await journal.loadRollbackJournal(stackName, region);
36695
+ } catch (error) {
36696
+ throw new CdkdError(safeMsg`cdkd ${params.command} of ${displayStackName(stackName)} refused: its rollback ` + "journal recorded an unsettled Cloud Control CREATE when this run started and cannot " + safeMsg`be read now (${displaySafe(describeAwsFailure(error).summary)}). Nothing was ` + "changed; re-run once it can be read.", "CC_PENDING_REQUEST_UNREADABLE");
36697
+ }
36698
+ const pending = pendingRequests(current);
36699
+ if (pending.size > 0) await settlePending(params, pending);
36700
+ return params.underLock !== void 0 || pending.size > 0;
36503
36701
  };
36702
+ return params.underLock ? params.underLock(settle) : settle();
36504
36703
  }
36505
-
36506
- //#endregion
36507
- //#region src/deployment/nested-child-journal.ts
36508
- const NESTED_PENDING_PARENT_REASON = "nested-pending-parent";
36509
- const NESTED_STACK_TYPE$2 = "AWS::CloudFormation::Stack";
36510
- const MAX_NESTED_WALK_DEPTH = 32;
36511
- function nestedChildStackName(parentStackName, logicalId) {
36512
- return `${parentStackName}~${logicalId}`;
36704
+ function pendingRequests(loaded) {
36705
+ const pending = /* @__PURE__ */ new Map();
36706
+ for (const segment of loaded?.segments ?? []) for (const op of segment.failedOperations ?? []) if (hasPendingCloudControlRequest(op)) pending.set(op.pendingCloudControlRequest.requestToken, op);
36707
+ return pending;
36513
36708
  }
36514
- function nestedPendingSnapshot(state, refusesExportName) {
36515
- const outputs = { ...isPlainRecord(state.outputs) ? state.outputs : {} };
36516
- let exportNames = Array.isArray(state.exportNames) ? [...state.exportNames] : void 0;
36517
- const refused = new Set(importableOutputKeys(state).filter((name) => refusesExportName(name)));
36518
- if (refused.size > 0) {
36519
- for (const name of refused) Reflect.deleteProperty(outputs, name);
36520
- if (exportNames !== void 0) exportNames = exportNames.filter((name) => !refused.has(name));
36521
- }
36522
- return {
36523
- previousOutputs: {
36524
- outputs,
36525
- ...exportNames !== void 0 && { exportNames }
36526
- },
36527
- previousCrossStackReads: {
36528
- ...Array.isArray(state.imports) && { imports: [...state.imports] },
36529
- ...Array.isArray(state.outputReads) && { outputReads: [...state.outputReads] }
36709
+ async function settlePending(params, pending) {
36710
+ const { journal, stackName, region, command, logger } = params;
36711
+ const reader = params.reader();
36712
+ const isUnique = params.identifierUnique ?? ccIdentifierIsUnique;
36713
+ const stackShown = displayStackName(stackName);
36714
+ const settlements = /* @__PURE__ */ new Map();
36715
+ const unresolved = [];
36716
+ for (const [token, op] of pending) {
36717
+ const named = `${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)})`;
36718
+ logger.info(safeMsg`A previous run of ${stackShown} stopped waiting for the Cloud Control CREATE of ${named}; ` + "checking how it ended...");
36719
+ const outcome = await reader.resumeAbandonedRequest(token, op.logicalId, op.resourceType);
36720
+ switch (outcome.status) {
36721
+ case "succeeded":
36722
+ case "failed":
36723
+ case "cancelled": {
36724
+ const made = outcome.status === "succeeded" ? outcome.identifier : outcome.remnant;
36725
+ if (made === void 0) {
36726
+ logger.info(safeMsg`The CREATE of ${named} ${outcome.status === "cancelled" ? "was cancelled" : "failed"} ` + "in AWS and made nothing.");
36727
+ settlements.set(token, { kind: "drop" });
36728
+ break;
36729
+ }
36730
+ const madeShown = displacedPhysicalIdShown({
36731
+ ...op,
36732
+ physicalId: made
36733
+ }, logger, made) ?? "a resource";
36734
+ const held = params.stateResources?.[op.logicalId];
36735
+ if (held !== void 0 && held.physicalId === made) {
36736
+ logger.info(safeMsg`The CREATE of ${named} made ${madeShown}, which state already records.`);
36737
+ settlements.set(token, { kind: "drop" });
36738
+ break;
36739
+ }
36740
+ const unique = await isUnique({
36741
+ resourceType: op.resourceType,
36742
+ identifier: made,
36743
+ attemptedProperties: op.attemptedProperties,
36744
+ logicalId: op.logicalId,
36745
+ stackName
36746
+ });
36747
+ const ended = outcome.status === "succeeded" ? "completed" : outcome.status === "cancelled" ? "was cancelled" : "failed";
36748
+ if (outcome.status === "succeeded" && unique && held === void 0 && params.resume?.(op, made)) {
36749
+ logger.info(safeMsg`The CREATE of ${named} completed in AWS after cdkd stopped waiting, and made ` + safeMsg`${madeShown}; this deploy's CREATE of it takes that resource over when it sends ` + "the same properties.");
36750
+ settlements.set(token, { kind: "resume" });
36751
+ break;
36752
+ }
36753
+ if (params.resume !== void 0 && !unique) logger.warn(safeMsg`The CREATE of ${named} ${ended} in AWS after cdkd stopped waiting, and made ` + safeMsg`${madeShown}. cdkd cannot prove its id is unique (it may be a name, which can ` + safeMsg`since belong to another resource), so this deploy does not take it over, and creating ${logicalIdShown(op.logicalId)} ` + "again will ask for the name it holds. Adopt it with cdkd import (--resource " + safeMsg`${logicalIdShown(op.logicalId)}=<its id>), or delete it, then re-run. It is kept in the ` + "rollback journal as a resource the failed deploy created.");
36754
+ else logger.warn(safeMsg`The CREATE of ${named} ${ended} in AWS after cdkd stopped waiting, and made ` + safeMsg`${madeShown}. It is now recorded in the rollback journal as a resource the failed ` + "deploy created: cdkd destroy, cdkd rollback --revert-failed and the next successful deploy delete it as its DeletionPolicy directs when cdkd can prove it is still the resource that create made, and otherwise name it in a warning for you to delete by hand.");
36755
+ settlements.set(token, {
36756
+ kind: "orphan",
36757
+ physicalId: made,
36758
+ unique
36759
+ });
36760
+ break;
36761
+ }
36762
+ case "not-found":
36763
+ logger.warn(safeMsg`Cloud Control no longer has the CREATE request of ${named}: requests expire after ` + "seven days, and a request is not visible from another account or region. cdkd cannot tell whether it created the resource and stops tracking the request. If it exists, adopt it with cdkd import or delete it by hand.");
36764
+ settlements.set(token, { kind: "drop" });
36765
+ break;
36766
+ case "unresolved": {
36767
+ settlements.set(token, { kind: "keep" });
36768
+ const reason = holdsSecretReference(op.attemptedProperties) ? "details withheld: its properties carry a secret" : displaySafe(describeAwsFailure(outcome.error).summary);
36769
+ unresolved.push(safeMsg` - ${named}${reason === "" ? "" : ` (${reason})`}\n` + ` Check it with: ${await reader.buildResumeCommand(token)}`);
36770
+ break;
36771
+ }
36530
36772
  }
36531
- };
36532
- }
36533
- function displacedPhysicalIdShown(op, logger, physicalId = journalOpPhysicalId(op)) {
36534
- if (physicalId === void 0) return void 0;
36535
- const masker = createOpMasker(logger, /* @__PURE__ */ new Map());
36536
- for (const properties of [
36537
- op.properties,
36538
- op.attemptedProperties,
36539
- op.previousState?.properties
36540
- ]) {
36541
- if (properties === void 0) continue;
36542
- masker.addNamed({
36543
- resourceType: op.resourceType,
36544
- properties,
36545
- logicalId: op.logicalId,
36546
- physicalIds: [physicalId]
36547
- });
36548
36773
  }
36549
- return displaySafe(String(masker.mask(physicalId)));
36774
+ if ([...settlements.values()].some((s) => s.kind === "orphan" || s.kind === "drop")) await journal.rewriteRollbackJournalFailedOperations(stackName, region, (op) => {
36775
+ if (!hasPendingCloudControlRequest(op)) return op;
36776
+ const settlement = settlements.get(op.pendingCloudControlRequest.requestToken);
36777
+ if (settlement?.kind === "drop") return withoutPendingRequest(op);
36778
+ if (settlement?.kind !== "orphan") return op;
36779
+ return {
36780
+ ...withoutPendingRequest(op),
36781
+ provisionedBy: "cc-api",
36782
+ physicalId: settlement.physicalId,
36783
+ physicalIdRecoveredFromError: true,
36784
+ ...settlement.unique && { createdIdentifierUnique: true }
36785
+ };
36786
+ });
36787
+ if (unresolved.length > 0) {
36788
+ const kept = [...pending.values()].filter((op) => settlements.get(op.pendingCloudControlRequest.requestToken)?.kind === "keep");
36789
+ const drop = dropFailedCommands(stackName, region, kept.map((op) => op.logicalId));
36790
+ const withheld = drop?.commands.some((c) => c.includes("<")) === true;
36791
+ throw new CdkdError(safeMsg`cdkd ${command} of ${stackShown} refused: a previous run stopped waiting for a Cloud ` + `Control CREATE, and cdkd still cannot tell whether it made its resource. Proceeding could leave that resource untracked. Nothing was changed.
36792
+ ${unresolved.join("\n")}\nRe-run once the request has finished and can be read. If you have reconciled it by hand (cdkd import, or deleted the resource), drop its journal entry with:` + (drop === void 0 ? "" : drop.commands.map((c) => `\n ${c}`).join("")) + (withheld ? "\nA value that is not a plain identifier is shown as a <hole>; read it from the stack's state record and rollback-journal.json." : ""), "CC_PENDING_REQUEST_UNRESOLVED");
36793
+ }
36794
+ }
36795
+ function holdsSecretReference(properties) {
36796
+ if (properties === void 0) return false;
36797
+ return carriesSecretMask(properties) || JSON.stringify(properties).includes("{{resolve:");
36798
+ }
36799
+ const ccIdentifierIsUnique = async ({ resourceType, identifier, attemptedProperties, logicalId, stackName }) => {
36800
+ if (attemptedProperties === void 0 || holdsSecretReference(attemptedProperties)) return false;
36801
+ const [fields, readOnly] = await Promise.all([getPrimaryIdentifierFields(resourceType), getTopLevelReadOnlyProperties(resourceType)]);
36802
+ if (fields === void 0 || readOnly === void 0) return false;
36803
+ const parts = identifier.split("|");
36804
+ if (parts.length !== fields.length) return false;
36805
+ const sent = /* @__PURE__ */ new Set();
36806
+ const collect = (value) => {
36807
+ if (typeof value === "string" || typeof value === "number") for (const piece of nameSegments(String(value))) sent.add(piece);
36808
+ else if (Array.isArray(value)) value.forEach(collect);
36809
+ else if (value !== null && typeof value === "object") Object.values(value).forEach(collect);
36810
+ };
36811
+ collect(attemptedProperties);
36812
+ return parts.some((part, i) => {
36813
+ if (part === "" || !readOnly.has(fields[i])) return false;
36814
+ return !nameSegments(part).some((segment) => sent.has(segment) || looksLikeCdkdGeneratedName(segment, logicalId, stackName));
36815
+ });
36816
+ };
36817
+ function nameSegments(value) {
36818
+ const text = value.toLowerCase();
36819
+ const arn = /^arn:[^:]*:[^:]*:[^:]*:[^:]*:(.*)$/.exec(text);
36820
+ const body = arn ? arn[1] : text;
36821
+ return [
36822
+ text,
36823
+ body,
36824
+ ...body.split(/[:/]/)
36825
+ ].filter((piece) => piece !== "");
36550
36826
  }
36551
- function displacedOpClause(op, marks, logger) {
36552
- const retainedOld = retainedOldPhysicalId(op);
36553
- if (retainedOld !== void 0 && marks.some((m) => isMarkFor(m, op))) {
36554
- const shownOld = displacedPhysicalIdShown(op, logger, retainedOld);
36555
- return `replaced ${shownOld} ${op.oldResourceRetained === true ? "but kept it (UpdateReplacePolicy: Retain)" : op.oldResourceMaySurvive !== void 0 ? "and may have kept it (its delete was not confirmed)" : "and may have kept it (the journal records no verdict)"}; cdkd import adopted the replacement, so ${shownOld} is left untracked`;
36556
- }
36557
- const shownId = displacedPhysicalIdShown(op, logger);
36558
- return shownId !== void 0 ? `recorded ${shownId}, which cdkd import has since replaced under this id` : "recorded no physical id, and cdkd import has since put another resource under this id";
36827
+ function withoutPendingRequest(op) {
36828
+ const { pendingCloudControlRequest: _settled, ...rest } = op;
36829
+ return rest;
36559
36830
  }
36560
- function recordDisplacedSkips(recordEvent, stackName, ops) {
36561
- for (const op of ops) recordEvent?.({
36562
- eventType: "ROLLBACK_RESOURCE_SKIPPED",
36563
- stackName,
36564
- operation: op.changeType,
36565
- logicalId: op.logicalId,
36566
- resourceType: op.resourceType,
36567
- ...op.provisionedBy && { provisionedBy: op.provisionedBy },
36568
- reason: "cdkd import has since put another resource under this logical id, so the op was not reverted; check the resource it recorded by hand"
36569
- });
36831
+
36832
+ //#endregion
36833
+ //#region src/state/deployment-events-store.ts
36834
+ const DEPLOYMENT_EVENTS_MAX_INDEX_RUNS = 20;
36835
+ const FLUSH_INTERVAL_MS = 2e3;
36836
+ const FLUSH_EVENT_THRESHOLD = 50;
36837
+ function newDeploymentRunId(now = /* @__PURE__ */ new Date()) {
36838
+ return `${now.toISOString().replace(/[-:.]/g, "")}-${randomUUID().slice(0, 8)}`;
36570
36839
  }
36571
- function revertedNestedRowIds(ops) {
36572
- return ops.filter((op) => op.resourceType === NESTED_STACK_TYPE$2 && op.changeType === "UPDATE").map((op) => op.logicalId);
36840
+ function deploymentEventsKey(prefix, stackName, region, runId) {
36841
+ return `${prefix}/${stackName}/${region}/deployments/${runId}.jsonl`;
36573
36842
  }
36574
- const revertRunStorage = new AsyncLocalStorage();
36575
- function withNestedRevertRun(runId, fn) {
36576
- const run = {
36577
- runId,
36578
- settled: /* @__PURE__ */ new Map(),
36579
- warnings: 0
36580
- };
36581
- return revertRunStorage.run(run, () => fn(run));
36843
+ function deploymentEventsIndexKey(prefix, stackName, region) {
36844
+ return `${prefix}/${stackName}/${region}/deployments/index.json`;
36582
36845
  }
36583
- function getNestedRevertRun() {
36584
- return revertRunStorage.getStore();
36846
+ function deploymentsDirPrefix(prefix, stackName, region) {
36847
+ return `${prefix}/${stackName}/${region}/deployments/`;
36585
36848
  }
36586
- function errorText(error) {
36587
- return displaySafe(describeAwsFailure(error).detail);
36849
+ const DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION = "deployment-event streams and their index, whose recorded error messages can quote values the secret mask does not catch";
36850
+ async function deleteAndPurgeEventObjects(backend, keys, dirPrefix, scope = "deleted-keys") {
36851
+ if (keys.length === 0) return void 0;
36852
+ let swept;
36853
+ try {
36854
+ await backend.deleteRawObjects(keys);
36855
+ } finally {
36856
+ if (scope === "whole-dir") swept = await backend.purgeNoncurrentVersionsUnderPrefix(dirPrefix, { objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION });
36857
+ else await backend.purgeNoncurrentVersions(keys, {
36858
+ ...keys.length > 1 && { listPrefix: dirPrefix },
36859
+ objectDescription: DEPLOYMENT_EVENTS_OBJECT_DESCRIPTION
36860
+ });
36861
+ }
36862
+ return swept;
36588
36863
  }
36589
- function isPlainRecord(value) {
36590
- return typeof value === "object" && value !== null && !Array.isArray(value);
36864
+ function runIdTimestampMs(runId) {
36865
+ const m = /^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\d{3})Z/.exec(runId);
36866
+ if (!m) return null;
36867
+ const iso = `${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}.${m[7]}Z`;
36868
+ const ms = Date.parse(iso);
36869
+ return Number.isNaN(ms) ? null : ms;
36591
36870
  }
36592
- async function dropNestedChildJournals(args) {
36593
- const { stateBackend, parentStackName, region, resources, logger } = args;
36594
- const depth = args.depth ?? 0;
36595
- if (!isPlainRecord(resources)) return;
36596
- if (depthExceeded(depth, parentStackName, logger)) return;
36597
- for (const [logicalId, record] of Object.entries(resources)) {
36598
- if (!isPlainRecord(record) || record["resourceType"] !== NESTED_STACK_TYPE$2) continue;
36599
- const child = nestedChildStackName(parentStackName, logicalId);
36871
+ function runIdFromJsonlKey(key, dirPrefix) {
36872
+ if (!key.startsWith(dirPrefix) || !key.endsWith(".jsonl")) return null;
36873
+ return key.slice(dirPrefix.length, -6);
36874
+ }
36875
+ var DeploymentEventsStore = class {
36876
+ logger = getLogger().child("DeploymentEvents");
36877
+ backend;
36878
+ stackName;
36879
+ region;
36880
+ command;
36881
+ runId;
36882
+ cdkdVersion;
36883
+ startedAt;
36884
+ events = [];
36885
+ persistedCount = 0;
36886
+ flushTimer;
36887
+ writeChain = Promise.resolve();
36888
+ warnedOnce = false;
36889
+ finalized = false;
36890
+ constructor(backend, options) {
36891
+ this.backend = backend;
36892
+ this.stackName = options.stackName;
36893
+ this.region = options.region;
36894
+ this.command = options.command;
36895
+ this.runId = options.runId ?? newDeploymentRunId();
36896
+ this.cdkdVersion = options.cdkdVersion ?? getCdkdVersion();
36897
+ this.startedAt = (/* @__PURE__ */ new Date()).toISOString();
36898
+ }
36899
+ record(event) {
36600
36900
  try {
36601
- const data = await stateBackend.getState(child, region);
36602
- if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) await dropNestedChildJournals({
36603
- ...args,
36604
- parentStackName: child,
36605
- resources: data.state.resources,
36606
- depth: depth + 1
36901
+ if (this.finalized) return;
36902
+ this.events.push({
36903
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
36904
+ ...event
36607
36905
  });
36608
- } catch (error) {
36609
- warnUncleared(logger, child, error);
36906
+ if (this.events.length - this.persistedCount >= FLUSH_EVENT_THRESHOLD) this.scheduleFlush(0);
36907
+ else this.scheduleFlush(FLUSH_INTERVAL_MS);
36908
+ } catch {}
36909
+ }
36910
+ async finalize(result) {
36911
+ if (this.finalized) return;
36912
+ this.finalized = true;
36913
+ if (this.flushTimer) {
36914
+ clearTimeout(this.flushTimer);
36915
+ this.flushTimer = void 0;
36610
36916
  }
36611
- try {
36612
- if (await withChildLock(args.lockManager, child, region, logger, async () => {
36613
- if (args.beforeDelete) {
36614
- if (!await args.beforeDelete(child, await readOwnRecord(stateBackend, child, region))) return false;
36615
- }
36616
- let gone;
36617
- try {
36618
- gone = await stateBackend.deleteRollbackJournal(child, region);
36619
- } catch (error) {
36620
- await args.onDeleteFailed?.(child);
36621
- throw error;
36622
- }
36623
- if (gone === false) {
36624
- await args.onDeleteFailed?.(child);
36625
- return false;
36626
- }
36627
- return true;
36628
- })) logger.debug(safeMsg`Deleted the rollback journal of nested stack ${displaySafe(child)}`);
36629
- } catch (error) {
36630
- warnUncleared(logger, child, error);
36917
+ if (this.events.length === 0) return;
36918
+ await this.enqueueWrite(async () => {
36919
+ const indexRead = this.readIndexRuns();
36920
+ indexRead.catch(() => {});
36921
+ await this.doFlush();
36922
+ await this.writeIndexAndPrune(result, await indexRead);
36923
+ });
36924
+ }
36925
+ async writeIndexAndPrune(result, existingRuns) {
36926
+ const { key, file, runs } = this.buildIndexUpdate(result, existingRuns);
36927
+ const keptRunIds = runs.map((r) => r.runId);
36928
+ const willPrune = keptRunIds.length >= 20;
36929
+ const dirPrefix = deploymentsDirPrefix(this.backend.prefix, this.stackName, this.region);
36930
+ const staleKeysRead = willPrune ? this.backend.listRawKeys(dirPrefix) : void 0;
36931
+ staleKeysRead?.catch(() => {});
36932
+ await this.backend.putRawObject(key, JSON.stringify(file, null, 2));
36933
+ if (!staleKeysRead) return;
36934
+ await this.pruneSupersededRunFiles(keptRunIds, dirPrefix, await staleKeysRead);
36935
+ }
36936
+ async drain() {
36937
+ await this.writeChain;
36938
+ }
36939
+ scheduleFlush(delayMs) {
36940
+ if (this.flushTimer) {
36941
+ if (delayMs > 0) return;
36942
+ clearTimeout(this.flushTimer);
36631
36943
  }
36944
+ this.flushTimer = setTimeout(() => {
36945
+ this.flushTimer = void 0;
36946
+ this.enqueueWrite(() => this.doFlush());
36947
+ }, delayMs);
36948
+ this.flushTimer.unref?.();
36632
36949
  }
36633
- }
36634
- async function readOwnRecord(stateBackend, child, region) {
36635
- try {
36636
- const data = await stateBackend.getState(child, region);
36637
- if (data && isPlainRecord(data.state) && isPlainRecord(data.state.resources) && (data.state.stackName === void 0 || data.state.stackName === child)) return data.state;
36638
- } catch {}
36639
- }
36640
- async function dropSettledNestedJournals(args) {
36641
- const { stateBackend, parentStackName, region, runId, logger } = args;
36642
- const depth = args.depth ?? 0;
36643
- if (runId === void 0) return;
36644
- if (depthExceeded(depth, parentStackName, logger)) return;
36645
- const isSettled = (segment) => segment.runId === runId && segment.reason === "nested-pending-parent";
36646
- for (const [logicalId, grandchildren] of args.settled) {
36647
- const child = nestedChildStackName(parentStackName, logicalId);
36648
- if (grandchildren.size > 0) await dropSettledNestedJournals({
36649
- ...args,
36650
- parentStackName: child,
36651
- settled: grandchildren,
36652
- depth: depth + 1
36950
+ enqueueWrite(op) {
36951
+ const next = this.writeChain.then(op).catch((err) => {
36952
+ this.warnOnce(`Failed to persist deployment events for run ${this.runId}: ${describeAwsFailure(err).detail}`);
36653
36953
  });
36954
+ this.writeChain = next;
36955
+ return next;
36956
+ }
36957
+ async doFlush() {
36958
+ if (this.events.length === 0 || this.events.length === this.persistedCount) return;
36959
+ const snapshotCount = this.events.length;
36960
+ const body = this.events.slice(0, snapshotCount).map((e) => JSON.stringify(e)).join("\n");
36961
+ await this.backend.putRawObject(deploymentEventsKey(this.backend.prefix, this.stackName, this.region, this.runId), body + "\n", "application/x-ndjson");
36962
+ this.persistedCount = snapshotCount;
36963
+ }
36964
+ async readIndexRuns() {
36965
+ const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
36654
36966
  try {
36655
- const removed = await withChildLock(args.lockManager, child, region, logger, () => stateBackend.dropRollbackJournalSegments(child, region, isSettled));
36656
- if (removed > 0) logger.debug(safeMsg`Dropped ${removed} settled rollback journal segment(s) of ${displaySafe(child)}`);
36657
- } catch (error) {
36658
- warnUncleared(logger, child, error);
36967
+ const raw = await this.backend.getRawObject(key);
36968
+ if (raw !== null) {
36969
+ const parsed = JSON.parse(raw);
36970
+ if (Array.isArray(parsed.runs)) return parsed.runs;
36971
+ }
36972
+ } catch (err) {
36973
+ this.logger.debug(`Deployment-events index unreadable, rewriting: ${describeAwsFailure(err).detail}`);
36659
36974
  }
36975
+ return [];
36660
36976
  }
36661
- }
36662
- async function withChildLock(lockManager, child, region, logger, fn) {
36663
- await lockManager.acquireLockWithRetry(child, region, void 0, "rollback");
36664
- try {
36665
- return await fn();
36666
- } finally {
36667
- await lockManager.releaseLock(child, region).catch((error) => {
36668
- logger.warn(safeMsg`Failed to release the lock of nested stack ${displayIdent(child)}: ${errorText(error)}`);
36977
+ buildIndexUpdate(result, existingRuns) {
36978
+ const key = deploymentEventsIndexKey(this.backend.prefix, this.stackName, this.region);
36979
+ const runs = [{
36980
+ runId: this.runId,
36981
+ command: this.command,
36982
+ cdkdVersion: this.cdkdVersion,
36983
+ startedAt: this.startedAt,
36984
+ finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
36985
+ result,
36986
+ eventCount: this.persistedCount
36987
+ }, ...existingRuns.filter((r) => r.runId !== this.runId)].slice(0, 20);
36988
+ return {
36989
+ key,
36990
+ file: {
36991
+ indexVersion: 1,
36992
+ stackName: this.stackName,
36993
+ region: this.region,
36994
+ runs,
36995
+ lastModified: Date.now()
36996
+ },
36997
+ runs
36998
+ };
36999
+ }
37000
+ async pruneSupersededRunFiles(keptRunIds, dirPrefix, keys) {
37001
+ if (keptRunIds.length < 20) return;
37002
+ const cutoff = keptRunIds.reduce((min, id) => id < min ? id : min, keptRunIds[0]);
37003
+ const stale = keys.filter((k) => {
37004
+ const runId = runIdFromJsonlKey(k, dirPrefix);
37005
+ return runId !== null && runId < cutoff;
36669
37006
  });
37007
+ if (stale.length === 0) return;
37008
+ await deleteAndPurgeEventObjects(this.backend, stale, dirPrefix);
37009
+ this.logger.debug(`Pruned ${stale.length} superseded deployment-event stream(s) for ${this.stackName} (${this.region})`);
36670
37010
  }
36671
- }
36672
- function depthExceeded(depth, parentStackName, logger) {
36673
- if (depth < MAX_NESTED_WALK_DEPTH) return false;
36674
- logger.warn(safeMsg`Stopped clearing nested rollback journals below ${displayIdent(parentStackName)}: ` + safeMsg`the nesting is deeper than ${MAX_NESTED_WALK_DEPTH} levels.`);
36675
- return true;
36676
- }
36677
- function warnUncleared(logger, child, error) {
36678
- logger.warn(safeMsg`Could not clear the rollback journal of nested stack ${displayIdent(child)}: ${errorText(error)}. ` + "It is inert to every parent revert (they select segments by run) and the next successful deploy of the top-level stack removes it.");
36679
- }
36680
- async function revertNestedChildFromJournal(args) {
36681
- const { ctx, logicalId, childStackName, region, run, logger } = args;
36682
- const runId = run.runId;
36683
- const shownChild = displayIdent(childStackName);
36684
- const refuse = (detail) => {
36685
- throw markNonRetryable(/* @__PURE__ */ new Error(`Cannot revert nested stack ${shownChild} (row ${displayIdent(logicalId)}): ${detail} The child was NOT (fully) reverted and may still hold the failed deploy's configuration. Inspect it with 'cdkd state show'; re-run the rollback once the cause is fixed (its journal is kept), or re-deploy the parent to converge.`));
36686
- };
36687
- if (runId === void 0) refuse("the rollback carries no deploy run id to select its journal segments by.");
36688
- await ctx.lockManager.acquireLockWithRetry(childStackName, region, void 0, "rollback");
36689
- try {
36690
- const stateData = await ctx.stateBackend.getState(childStackName, region);
36691
- if (!stateData) refuse("its state.json is missing.");
36692
- if (stateData.divergentBodyRegion !== void 0) refuse("its state record's region field disagrees with the key it is stored under.");
36693
- const base = stateData.state;
36694
- const refusalRecovery = {
36695
- profile: ctx.destroyOptions?.profile,
36696
- stateBucket: ctx.stateBucket,
36697
- statePrefix: ctx.destroyOptions?.statePrefix
37011
+ warnOnce(message) {
37012
+ if (this.warnedOnce) {
37013
+ this.logger.debug(message);
37014
+ return;
37015
+ }
37016
+ this.warnedOnce = true;
37017
+ this.logger.warn(`${message} — continuing; deployment events are best-effort and never block the run.`);
37018
+ }
37019
+ };
37020
+ var DeploymentEventsReader = class {
37021
+ backend;
37022
+ constructor(backend) {
37023
+ this.backend = backend;
37024
+ }
37025
+ async listRegions(stackName) {
37026
+ const prefix = `${this.backend.prefix}/${stackName}/`;
37027
+ const keys = await this.backend.listRawKeys(prefix);
37028
+ const regions = /* @__PURE__ */ new Set();
37029
+ for (const key of keys) {
37030
+ const segments = key.slice(prefix.length).split("/");
37031
+ if (segments.length === 3 && segments[1] === "deployments" && segments[0]) regions.add(segments[0]);
37032
+ }
37033
+ return [...regions].sort();
37034
+ }
37035
+ async listRuns(stackName, region) {
37036
+ const key = deploymentEventsIndexKey(this.backend.prefix, stackName, region);
37037
+ try {
37038
+ const raw = await this.backend.getRawObject(key);
37039
+ if (raw !== null) {
37040
+ const parsed = JSON.parse(raw);
37041
+ if (Array.isArray(parsed.runs)) return parsed.runs;
37042
+ }
37043
+ } catch {}
37044
+ const dirPrefix = `${this.backend.prefix}/${stackName}/${region}/deployments/`;
37045
+ const runIds = (await this.backend.listRawKeys(dirPrefix)).filter((k) => k.endsWith(".jsonl")).map((k) => k.slice(dirPrefix.length, -6)).sort().reverse();
37046
+ return Promise.all(runIds.map((runId) => this.summarizeRunFromJsonl(stackName, region, runId)));
37047
+ }
37048
+ async summarizeRunFromJsonl(stackName, region, runId) {
37049
+ const fallback = {
37050
+ runId,
37051
+ command: "deploy",
37052
+ cdkdVersion: "unknown",
37053
+ startedAt: "",
37054
+ finishedAt: "",
37055
+ result: "UNKNOWN",
37056
+ eventCount: 0
36698
37057
  };
36699
- refuseMalformedState(base, childStackName, region, refusalRecovery);
36700
- refuseMalformedOrphans(base, childStackName, region, refusalRecovery);
36701
- refuseMalformedOrphanRecords(base, childStackName, region, refusalRecovery);
36702
- const segments = ((await ctx.stateBackend.loadRollbackJournal(childStackName, region))?.segments ?? []).filter((segment) => segment.runId === runId);
36703
- if (segments.length === 0) refuse("its rollback journal holds no segment for this deploy run, so there is no record of what it held before.");
36704
- const stateResources = { ...base.resources };
36705
- const mintedOrphans = [];
36706
- const restoredOutputs = segments.find((s) => s.previousOutputs)?.previousOutputs;
36707
- const restoredReads = segments.find((s) => s.previousCrossStackReads)?.previousCrossStackReads;
36708
- let currentEtag = stateData.etag;
36709
- let persisted = false;
36710
- let restoring = false;
36711
- const { skippedOutputs: _dropped, ...carried } = base;
36712
- const next = () => ({
36713
- ...carried,
36714
- version: 12,
36715
- region,
36716
- resources: { ...stateResources },
36717
- ...orphansAfterRollback(base, mintedOrphans),
36718
- ...restoring && restoredOutputs && { outputs: { ...restoredOutputs.outputs } },
36719
- ...restoring && restoredReads && {
36720
- ...restoredReads.imports && { imports: [...restoredReads.imports] },
36721
- ...restoredReads.outputReads && { outputReads: [...restoredReads.outputReads] }
36722
- },
36723
- ...restoring && restoredOutputs?.exportNames && { exportNames: [...restoredOutputs.exportNames] },
36724
- lastModified: Date.now()
36725
- });
36726
- const nextState = () => {
36727
- const state = next();
36728
- if (!restoring) return state;
36729
- if (restoredOutputs && !restoredOutputs.exportNames) delete state.exportNames;
36730
- if (restoredOutputs) delete state.outputReferenceProvenance;
36731
- if (restoredReads && !restoredReads.imports) delete state.imports;
36732
- if (restoredReads && !restoredReads.outputReads) delete state.outputReads;
36733
- return state;
37058
+ let events = null;
37059
+ try {
37060
+ events = await this.readRunEvents(stackName, region, runId);
37061
+ } catch {
37062
+ return fallback;
37063
+ }
37064
+ if (events === null || events.length === 0) return fallback;
37065
+ const started = events.find((e) => e.eventType === "RUN_STARTED");
37066
+ let finished;
37067
+ for (const e of events) if (e.eventType === "RUN_FINISHED") finished = e;
37068
+ return {
37069
+ runId,
37070
+ command: started?.command ?? fallback.command,
37071
+ cdkdVersion: started?.cdkdVersion ?? fallback.cdkdVersion,
37072
+ startedAt: started?.timestamp ?? fallback.startedAt,
37073
+ finishedAt: finished?.timestamp ?? fallback.finishedAt,
37074
+ result: finished?.result ?? "UNKNOWN",
37075
+ eventCount: events.length
36734
37076
  };
36735
- const save = async () => {
36736
- persisted = false;
37077
+ }
37078
+ async readRunEvents(stackName, region, runId) {
37079
+ const key = deploymentEventsKey(this.backend.prefix, stackName, region, runId);
37080
+ const raw = await this.backend.getRawObject(key);
37081
+ if (raw === null) return null;
37082
+ const events = [];
37083
+ for (const line of raw.split("\n")) {
37084
+ const trimmed = line.trim();
37085
+ if (!trimmed) continue;
36737
37086
  try {
36738
- currentEtag = await ctx.stateBackend.saveState(childStackName, region, nextState(), { ...currentEtag !== void 0 && { expectedEtag: currentEtag } });
36739
- persisted = true;
36740
- } catch {
36741
- try {
36742
- const fresh = await ctx.stateBackend.getState(childStackName, region);
36743
- currentEtag = await ctx.stateBackend.saveState(childStackName, region, nextState(), { ...fresh?.etag !== void 0 && { expectedEtag: fresh.etag } });
36744
- persisted = true;
36745
- } catch (retryError) {
36746
- logger.warn(safeMsg`Failed to persist the state of nested stack ${shownChild} after reverting it: ` + safeMsg`${errorText(retryError)}. The resources were reverted in AWS.`);
36747
- }
36748
- }
36749
- };
36750
- const producerRegions = inheritProducerRegions(producerRegionsFromState({
36751
- imports: [...base.imports ?? [], ...restoredReads?.imports ?? []],
36752
- outputReads: [...base.outputReads ?? [], ...restoredReads?.outputReads ?? []]
36753
- }), args.inheritedProducerRegions);
36754
- const execCtx = {
36755
- providerRegistry: ctx.providerRegistry,
36756
- region,
36757
- logger,
36758
- ...ctx.options?.eventRecorder && { recordEvent: (event) => ctx.options.eventRecorder.record(maskEventTextWithBoundBags(event)) },
36759
- finalSnapshotClients: ctx.options?.finalSnapshotClients,
36760
- skipFinalSnapshot: ctx.options?.skipFinalSnapshot === true || ctx.destroyOptions?.skipFinalSnapshot === true,
36761
- ...ctx.destroyOptions?.removeProtection === true && {
36762
- removeProtection: true,
36763
- foreignHolder: makeForeignHolderScan(ctx.stateBackend)({
36764
- stackName: childStackName,
36765
- region
36766
- })
36767
- },
36768
- importedProducerRegions: producerRegions.regions,
36769
- producerRegionsIncomplete: !producerRegions.complete,
36770
- nestedChildRevert: true
37087
+ events.push(JSON.parse(trimmed));
37088
+ } catch {}
37089
+ }
37090
+ return events;
37091
+ }
37092
+ async pruneRuns(stackName, region, opts = {}) {
37093
+ const dirPrefix = deploymentsDirPrefix(this.backend.prefix, stackName, region);
37094
+ const keys = await this.backend.listRawKeys(dirPrefix);
37095
+ const runIdsDesc = keys.map((k) => runIdFromJsonlKey(k, dirPrefix)).filter((id) => id !== null).sort().reverse();
37096
+ const indexKey = deploymentEventsIndexKey(this.backend.prefix, stackName, region);
37097
+ const indexExisted = keys.includes(indexKey);
37098
+ if (opts.all === true) {
37099
+ const toDelete = runIdsDesc.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
37100
+ const earlierVersions = await deleteAndPurgeEventObjects(this.backend, [...toDelete, indexKey], dirPrefix, "whole-dir");
37101
+ return {
37102
+ deletedRunIds: runIdsDesc,
37103
+ remainingRunIds: [],
37104
+ indexDeleted: indexExisted,
37105
+ ...earlierVersions !== void 0 && { earlierVersions }
37106
+ };
37107
+ }
37108
+ const noGuards = opts.keep === void 0 && opts.olderThanMs === void 0;
37109
+ const keep = opts.keep ?? (noGuards ? 20 : void 0);
37110
+ const protectedByCount = keep === void 0 ? /* @__PURE__ */ new Set() : new Set(runIdsDesc.slice(0, keep));
37111
+ let candidates = runIdsDesc.filter((id) => !protectedByCount.has(id));
37112
+ if (opts.olderThanMs !== void 0) {
37113
+ const cutoff = (opts.now ?? /* @__PURE__ */ new Date()).getTime() - opts.olderThanMs;
37114
+ candidates = candidates.filter((id) => {
37115
+ const t = runIdTimestampMs(id);
37116
+ return t !== null && t < cutoff;
37117
+ });
37118
+ }
37119
+ if (candidates.length === 0) return {
37120
+ deletedRunIds: [],
37121
+ remainingRunIds: runIdsDesc,
37122
+ indexDeleted: false
36771
37123
  };
36772
- const childCtx = {
36773
- ...ctx,
36774
- parentStackName: childStackName,
36775
- parentRegion: region,
36776
- nestedTemplates: void 0
37124
+ const deletedSet = new Set(candidates);
37125
+ const deleteKeys = candidates.map((id) => deploymentEventsKey(this.backend.prefix, stackName, region, id));
37126
+ const remainingRunIds = runIdsDesc.filter((id) => !deletedSet.has(id));
37127
+ if (remainingRunIds.length === 0) {
37128
+ await deleteAndPurgeEventObjects(this.backend, [...deleteKeys, indexKey], dirPrefix);
37129
+ return {
37130
+ deletedRunIds: candidates,
37131
+ remainingRunIds,
37132
+ indexDeleted: indexExisted
37133
+ };
37134
+ }
37135
+ await this.rewriteIndexAfterPrune(indexKey, stackName, region, deletedSet);
37136
+ await deleteAndPurgeEventObjects(this.backend, deleteKeys, dirPrefix);
37137
+ return {
37138
+ deletedRunIds: candidates,
37139
+ remainingRunIds,
37140
+ indexDeleted: false
36777
37141
  };
36778
- let failures = 0;
36779
- let warnings = 0;
36780
- const inlinePolicyWriters = new RollbackInlinePolicyWriters();
36781
- const settledBelow = /* @__PURE__ */ new Map();
36782
- for (let s = segments.length - 1; s >= 0; s--) {
36783
- const segment = segments[s];
36784
- const skipPrefix = segment.skipPrefix ?? getCurrentSkipPrefix();
36785
- const split = splitImportedOps(segment.operations, segment);
36786
- const result = await withNestedStackContext(childCtx, () => withSkipPrefix(skipPrefix, () => withStackName(childStackName, () => withCreateTokenLedger(ledgerForStack(ctx.stateBackend, childStackName, region), () => withNestedRevertRun(runId, async (inner) => {
36787
- const replayed = await withPrintingSecrets(journaledOrphanPrintingBag(completedReplayEntries(split.replay), stateResources), () => replayRollback(split.replay, stateResources, childStackName, execCtx, {
36788
- afterOp: save,
36789
- onOrphan: (record) => mintedOrphans.push(record),
36790
- inlinePolicyWriters,
36791
- failedOperations: segment.failedOperations
36792
- }));
36793
- for (const [id, below] of inner.settled) settledBelow.set(id, below);
36794
- return {
36795
- ...replayed,
36796
- warnings: replayed.warnings + inner.warnings
36797
- };
36798
- })))));
36799
- failures += result.failures;
36800
- warnings += result.warnings + split.displaced.length;
36801
- recordDisplacedSkips(execCtx.recordEvent, childStackName, split.displaced);
36802
- for (const op of split.displaced) logger.warn(safeMsg`Nested stack ${childStackName}: ${op.logicalId} ` + safeMsg`${displacedOpClause(op, segment.importedResources ?? [], logger)}; ` + "not reverted, check that resource by hand");
37142
+ }
37143
+ async rewriteIndexAfterPrune(indexKey, stackName, region, deletedRunIds) {
37144
+ let raw;
37145
+ try {
37146
+ raw = await this.backend.getRawObject(indexKey);
37147
+ } catch {
37148
+ return;
36803
37149
  }
36804
- restoring = failures === 0;
36805
- await save();
36806
- if (restoring && persisted && restoredOutputs && ctx.exportIndexStore) await ctx.exportIndexStore.updateForStack(childStackName, region, importableOutputs(nextState()));
36807
- if (warnings > 0) logger.warn(safeMsg`Nested stack ${shownChild}: ${warnings} operation(s) were skipped with a warning during ` + `its revert (see above); they may need attention by hand.`);
36808
- if (failures > 0) refuse(`${failures} of its operation(s) failed to revert (see the warnings above).`);
36809
- if (warnings > 0) run.warnings += warnings;
36810
- else run.settled.set(logicalId, settledBelow);
36811
- return { warnings };
36812
- } finally {
36813
- await ctx.lockManager.releaseLock(childStackName, region).catch((error) => {
36814
- logger.warn(safeMsg`Failed to release the lock of nested stack ${shownChild}: ${errorText(error)}`);
36815
- });
37150
+ if (raw === null) return;
37151
+ let parsed;
37152
+ try {
37153
+ parsed = JSON.parse(raw);
37154
+ } catch {
37155
+ return;
37156
+ }
37157
+ if (!Array.isArray(parsed.runs)) return;
37158
+ const remaining = parsed.runs.filter((r) => !deletedRunIds.has(r.runId));
37159
+ if (remaining.length === parsed.runs.length) return;
37160
+ const file = {
37161
+ indexVersion: 1,
37162
+ stackName,
37163
+ region,
37164
+ runs: remaining,
37165
+ lastModified: Date.now()
37166
+ };
37167
+ await this.backend.putRawObject(indexKey, JSON.stringify(file, null, 2));
36816
37168
  }
36817
- }
37169
+ };
36818
37170
 
36819
37171
  //#endregion
36820
37172
  //#region src/deployment/orphan-adoption.ts
@@ -37120,6 +37472,7 @@ async function settleJournalAfterSuccess(stackName, completedOperations, previou
37120
37472
  const deployRunId = this.options.eventRecorder?.runId;
37121
37473
  const stripOnFailure = /* @__PURE__ */ new Map();
37122
37474
  const [ownLeft] = await Promise.all([(async () => {
37475
+ await orphanUntakenResumes.call(this, stackName, finalResources);
37123
37476
  if (this.absentJournalVersionPurge !== void 0 && this.stateBackend.rollbackJournalReadAbsent(stackName, this.stackRegion)) {
37124
37477
  await this.absentJournalVersionPurge;
37125
37478
  return 0;
@@ -37291,6 +37644,27 @@ async function writeRollbackJournalSegment(stackName, completedOperations, faile
37291
37644
  return false;
37292
37645
  }
37293
37646
  }
37647
+ async function orphanUntakenResumes(stackName, finalResources) {
37648
+ if (this.resumedCreates.size === 0) return;
37649
+ const untaken = new Map([...this.resumedCreates.values()].map((r) => [r.requestToken, r]));
37650
+ this.resumedCreates = /* @__PURE__ */ new Map();
37651
+ try {
37652
+ await this.stateBackend.rewriteRollbackJournalFailedOperations(stackName, this.stackRegion, (op) => {
37653
+ const resumed = op.pendingCloudControlRequest === void 0 ? void 0 : untaken.get(op.pendingCloudControlRequest.requestToken);
37654
+ if (resumed === void 0) return op;
37655
+ if (resumed.gone || finalResources[op.logicalId]?.physicalId === resumed.identifier) return withoutPendingRequest(op);
37656
+ return {
37657
+ ...withoutPendingRequest(op),
37658
+ provisionedBy: "cc-api",
37659
+ physicalId: resumed.identifier,
37660
+ physicalIdRecoveredFromError: true,
37661
+ createdIdentifierUnique: true
37662
+ };
37663
+ });
37664
+ } catch (error) {
37665
+ this.logger.warn(safeMsg`Could not settle the resumed Cloud Control requests in the rollback journal of ` + safeMsg`${displayStackName(stackName)} (${displaySafe(describeAwsFailure(error).summary)}); ` + "the next run settles them.");
37666
+ }
37667
+ }
37294
37668
 
37295
37669
  //#endregion
37296
37670
  //#region src/analyzer/parameter-dependence.ts
@@ -38717,30 +39091,45 @@ async function provisionCreate(logicalId, change, stateResources, stackName, tem
38717
39091
  });
38718
39092
  const createProvider = createDecision.provider;
38719
39093
  const createProps = createDecision.provisionedBy === "cc-api" ? this.preparePropertiesForCcApi(resourceType, resolvedProps, logicalId) : resolvedProps;
38720
- await refuseUnlicensedGeneratedName.call(this, {
38721
- logicalId,
38722
- resourceType,
38723
- stackName,
38724
- createdVia: createDecision.provisionedBy,
38725
- resolvedProps
38726
- });
38727
- await refuseTakenCreateName.call(this, {
39094
+ const resumed = await resumeAbandonedCreate.call(this, {
38728
39095
  logicalId,
38729
39096
  resourceType,
38730
39097
  stackName,
39098
+ resolvedProps,
39099
+ createProps,
38731
39100
  createProvider,
38732
39101
  createdVia: createDecision.provisionedBy,
38733
- createProps,
38734
- secrets: createSecrets,
38735
- stateResources
39102
+ maskSecrets: createSecretMasker(createSecrets)
38736
39103
  });
38737
- this.generatedNameGuard?.noteSent(logicalId);
38738
39104
  let result;
38739
- try {
38740
- result = await this.withRetry(() => withCurrentResourceSecrets(createSecrets, () => createProvider.create(logicalId, resourceType, createProps, { maskSecrets: createSecretMasker(createSecrets) })), logicalId, void 0, void 0, createProvider);
38741
- } catch (error) {
38742
- this.generatedNameGuard?.noteFailed(logicalId, error);
38743
- throw error;
39105
+ if (resumed !== void 0) {
39106
+ this.generatedNameGuard?.noteSent(logicalId);
39107
+ result = resumed;
39108
+ } else {
39109
+ await refuseUnlicensedGeneratedName.call(this, {
39110
+ logicalId,
39111
+ resourceType,
39112
+ stackName,
39113
+ createdVia: createDecision.provisionedBy,
39114
+ resolvedProps
39115
+ });
39116
+ await refuseTakenCreateName.call(this, {
39117
+ logicalId,
39118
+ resourceType,
39119
+ stackName,
39120
+ createProvider,
39121
+ createdVia: createDecision.provisionedBy,
39122
+ createProps,
39123
+ secrets: createSecrets,
39124
+ stateResources
39125
+ });
39126
+ this.generatedNameGuard?.noteSent(logicalId);
39127
+ try {
39128
+ result = await this.withRetry(() => withCurrentResourceSecrets(createSecrets, () => createProvider.create(logicalId, resourceType, createProps, { maskSecrets: createSecretMasker(createSecrets) })), logicalId, void 0, void 0, createProvider);
39129
+ } catch (error) {
39130
+ this.generatedNameGuard?.noteFailed(logicalId, error);
39131
+ throw error;
39132
+ }
38744
39133
  }
38745
39134
  this.generatedNameGuard?.noteReturned(logicalId);
38746
39135
  this.registerNoEchoAttributes(logicalId, result, createSecrets, resolvedProps);
@@ -38870,6 +39259,45 @@ async function refuseTakenCreateName(input) {
38870
39259
  return refuse(`${subject} is created with ${named}, and an existing resource (${shown(holderId)}) already holds that name. Since ${adoptsText}, creating it would take that resource over and record it as this stack's, for a later \`cdkd destroy\` to delete. Nothing was created. Choose a name no other resource holds; ` + ownRemedy + holeNote + (adopt === void 0 ? "" : `
38871
39260
  CONFIRM IT IS YOURS FIRST: another stack or app may own a resource of that name, and adopting it hands that resource to this stack's \`cdkd destroy\`.\nAdopt with: ${adopt.command}`));
38872
39261
  }
39262
+ async function resumeAbandonedCreate(args) {
39263
+ const { logicalId, resourceType } = args;
39264
+ const resumed = this.resumedCreates.get(logicalId);
39265
+ if (resumed === void 0 || resumed.taken || resumed.resourceType !== resourceType) return;
39266
+ const reader = args.createProvider;
39267
+ if (args.createdVia !== "cc-api" || typeof reader.resumeCreatedResource !== "function") return;
39268
+ const probe = {
39269
+ logicalId,
39270
+ changeType: "CREATE",
39271
+ resourceType,
39272
+ attemptedProperties: args.resolvedProps
39273
+ };
39274
+ const [redacted] = this.redactOperationsForJournal([probe]);
39275
+ const sentNow = redacted?.attemptedProperties;
39276
+ const asJson = (value) => value === void 0 ? void 0 : JSON.parse(JSON.stringify(value));
39277
+ if (!isDeepStrictEqual(asJson(sentNow), asJson(resumed.attemptedProperties))) {
39278
+ this.logger.warn(safeMsg`${logicalId}: the template changed since the CREATE cdkd stopped waiting for, so ` + "this deploy creates the resource again; the one that CREATE made is kept in the rollback journal as a resource the failed deploy created.");
39279
+ return;
39280
+ }
39281
+ let result;
39282
+ try {
39283
+ result = await this.withRetry(() => reader.resumeCreatedResource(logicalId, resourceType, resumed.identifier, args.createProps, { maskSecrets: args.maskSecrets }), logicalId, void 0, void 0, args.createProvider);
39284
+ } catch (error) {
39285
+ if (error.resumedResourceGone !== true) throw error;
39286
+ resumed.gone = true;
39287
+ this.logger.warn(safeMsg`${logicalId}: the resource the earlier CREATE made no longer exists; creating it as usual.`);
39288
+ return;
39289
+ }
39290
+ resumed.taken = true;
39291
+ const shown = displacedPhysicalIdShown({
39292
+ logicalId,
39293
+ changeType: "CREATE",
39294
+ resourceType,
39295
+ physicalId: resumed.identifier,
39296
+ attemptedProperties: resumed.attemptedProperties
39297
+ }, this.logger, resumed.identifier) ?? "the resource";
39298
+ this.logger.info(safeMsg`${logicalId}: took over ${shown}, the resource the earlier CREATE made, instead of ` + "creating another.");
39299
+ return result;
39300
+ }
38873
39301
 
38874
39302
  //#endregion
38875
39303
  //#region src/provisioning/data-delete-intent.ts
@@ -45325,11 +45753,20 @@ async function executeDeployment(template, currentState, changes, dag, execution
45325
45753
  record: replaced,
45326
45754
  createdId: replacementCreatedId
45327
45755
  } : void 0;
45756
+ const abandoned = change.changeType === "CREATE" && statePhysicalId === void 0 && createdId === void 0 ? abandonedRequestOf(provisionError) : void 0;
45757
+ const pendingRequest = abandoned?.operation === "CREATE" && /^[-A-Za-z0-9+/=]{1,128}$/.test(abandoned.requestToken) ? {
45758
+ requestToken: abandoned.requestToken,
45759
+ abandonedAt: Date.now()
45760
+ } : void 0;
45328
45761
  const failedOp = {
45329
45762
  logicalId,
45330
45763
  changeType: change.changeType,
45331
45764
  resourceType: change.resourceType,
45332
- provisionedBy: createdId !== void 0 ? "sdk" : newResources[logicalId]?.provisionedBy ?? previousState?.provisionedBy,
45765
+ provisionedBy: createdId !== void 0 ? "sdk" : pendingRequest !== void 0 ? "cc-api" : newResources[logicalId]?.provisionedBy ?? previousState?.provisionedBy,
45766
+ ...pendingRequest !== void 0 && {
45767
+ pendingCloudControlRequest: pendingRequest,
45768
+ deletionPolicy: journaledOrphanPolicy(this.extractTemplateAttributes(template, logicalId).deletionPolicy)
45769
+ },
45333
45770
  ...previousState && { previousState },
45334
45771
  physicalId: createdId ?? statePhysicalId,
45335
45772
  ...createdId !== void 0 && {
@@ -45359,7 +45796,7 @@ async function executeDeployment(template, currentState, changes, dag, execution
45359
45796
  failedOperations.push(replacementOrphanOp);
45360
45797
  }
45361
45798
  const orphanOp = createdId !== void 0 ? failedOp : replacementOrphanOp;
45362
- if (orphanOp?.physicalId !== void 0 && orphanOp.deletionPolicy !== "Retain" && orphanDeleteNeedsIdentity(orphanOp.resourceType)) {
45799
+ if (orphanOp?.physicalId !== void 0 && orphanOp.deletionPolicy !== "Retain" && orphanNeedsIdentity(orphanOp)) {
45363
45800
  const markedIdentity = createdResourceIdentityBeforeFailure(provisionError, logicalId, change.resourceType);
45364
45801
  if (markedIdentity !== void 0) orphanOp.createdResourceIdentity = markedIdentity;
45365
45802
  else if (this.interruptCause !== "user") {
@@ -47038,8 +47475,42 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
47038
47475
  if (exportIndexStore && importableOutputKeys(currentState).length === 0) exportsPrefetch = afterGate(() => exportIndexStore.prefetch());
47039
47476
  }
47040
47477
  this.absentJournalVersionPurge = void 0;
47478
+ let journalAtStart = null;
47479
+ let journalReadError;
47480
+ try {
47481
+ journalAtStart = await this.stateBackend.loadRollbackJournal(stackName, this.stackRegion);
47482
+ } catch (error) {
47483
+ journalReadError = error ?? /* @__PURE__ */ new Error("unreadable rollback journal");
47484
+ }
47485
+ if (!this.options.dryRun && await resolvePendingCloudControlRequests({
47486
+ journal: this.stateBackend,
47487
+ loaded: journalAtStart,
47488
+ reader: () => this.providerRegistry.getCloudControlProvider(),
47489
+ stackName,
47490
+ region: this.stackRegion,
47491
+ command: "deploy",
47492
+ logger: this.logger,
47493
+ stateResources: currentState.resources,
47494
+ resume: (op, identifier) => {
47495
+ const attempted = op.attemptedProperties;
47496
+ if (template.Resources?.[op.logicalId]?.Type !== op.resourceType || attempted === void 0 || carriesSecretMask(attempted) || op.pendingCloudControlRequest === void 0 || Object.values(currentState.resources).some((r) => r.physicalId === identifier && r.resourceType === op.resourceType)) return false;
47497
+ this.resumedCreates.set(op.logicalId, {
47498
+ requestToken: op.pendingCloudControlRequest.requestToken,
47499
+ identifier,
47500
+ resourceType: op.resourceType,
47501
+ attemptedProperties: attempted
47502
+ });
47503
+ return true;
47504
+ },
47505
+ ...gate !== void 0 && { beforeSettle: () => gate }
47506
+ })) try {
47507
+ journalAtStart = await this.stateBackend.loadRollbackJournal(stackName, this.stackRegion);
47508
+ } catch (error) {
47509
+ journalReadError = error ?? /* @__PURE__ */ new Error("unreadable rollback journal");
47510
+ }
47041
47511
  try {
47042
- const loaded = await this.stateBackend.loadRollbackJournal(stackName, this.stackRegion);
47512
+ if (journalReadError !== void 0) throw journalReadError;
47513
+ const loaded = journalAtStart;
47043
47514
  if (loaded === null && !this.options.parentStackInfo && !this.options.dryRun) this.absentJournalVersionPurge = afterGate(() => this.stateBackend.purgeRollbackJournalVersions(stackName, this.stackRegion));
47044
47515
  const journal = loaded && {
47045
47516
  ...loaded,
@@ -47674,6 +48145,7 @@ var DeployEngine = class {
47674
48145
  constructPathTemplate;
47675
48146
  outputsSourceUsable = true;
47676
48147
  attemptedResolvedProps = /* @__PURE__ */ new Map();
48148
+ resumedCreates = /* @__PURE__ */ new Map();
47677
48149
  generatedNameGuard;
47678
48150
  liveTaskLabels = /* @__PURE__ */ new Map();
47679
48151
  retainedOldOnReplacement = /* @__PURE__ */ new Set();
@@ -47746,6 +48218,7 @@ var DeployEngine = class {
47746
48218
  this.fingerprintChildTemplates = void 0;
47747
48219
  this.perResourceInputFingerprints = /* @__PURE__ */ new Map();
47748
48220
  this.attemptedResolvedProps = /* @__PURE__ */ new Map();
48221
+ this.resumedCreates = /* @__PURE__ */ new Map();
47749
48222
  this.generatedNameGuard = void 0;
47750
48223
  this.liveTaskLabels = /* @__PURE__ */ new Map();
47751
48224
  this.outputSecrets = /* @__PURE__ */ new Map();
@@ -48027,5 +48500,5 @@ DeployEngine.prototype.replacementNameOrigin = replacementNameOrigin;
48027
48500
  DeployEngine.prototype.orphanedNameCollisionAdvice = orphanedNameCollisionAdvice;
48028
48501
 
48029
48502
  //#endregion
48030
- export { S3_AUTO_DELETE_OBJECTS_TAG as $, withheldAccountClause as $a, getDockerImageBySourceHash as $c, isReadableResourceEntry as $i, findDestructiveChanges as $n, literalSplitDelimitersOf as $o, applyRoleArnIfSet as $r, splitImportedOps as $s, recordUnderIdIsNotOwn as $t, diffSecurity as A, refuseMalformedResourceEntries as Aa, buildDenyExternalAccessPolicy as Ac, isNamelessDynamicReferenceError as Ai, hasOwnKey as Al, DEFAULT_RESOURCE_TIMEOUT_MS as An, withRetry as Ao, CloudControlProvider as Ar, provenPublicValue as As, withNestedStackContext as At, readProtection as B, refuseMalformedResourcesForDeploy as Ba, isDockerClientEnvKey as Bc, declaresNoEcho as Bi, injectedAwsRegionValue as Bl, storedSecretNameNeedles as Bn, maskWholeValue as Bo, markWaitAbandoned as Br, TEMPLATE_SOURCED_RULES as Bs, awaitInFlightSibling as Bt, withApiLimit as C, refuseMalformedOrphanRecordsForDestroy as Ca, ensureAssetStorage as Cc, coerceParameterTypedValue as Ci, PARTITION_TABLE as Cl, exportNameSecretExposure as Cn, replayWarn as Co, readsNoEchoDeleteValues as Cr, recordNestedStackParameterExpressions as Cs, nestedChildStackName as Ct, findServiceTokenRefusals as D, refuseMalformedOutputs as Da, readBootstrapMarkerBody as Dc, isImpossibleEmptyStoredAttribute as Di, StageLoadError as Dl, collectPublishedOutputNames as Dn, prefetchCreateOnlyPropertyPaths as Do, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Dr, recordPhysicalNameCopy as Ds, withNestedRevertRun as Dt, deferredServiceTokenWarning as E, refuseMalformedOrphansForOrphan as Ea, parseBootstrapMarker as Ec, getAccountInfo as Ei, AssemblyReader as El, collectDeclaredOutputNames as En, requireConfigString as Eo, withPrintingSecrets as Er, recordAttributeIdCopy as Es, revertedNestedRowIds as Et, recordedProtectionEvidence as F, refuseMalformedResourceEntriesForOrphan as Fa, describeDockerFailure as Fc, refStateLookupFromResource as Fi, describeFileReadFailure as Fl, orphanRecordsPrintingBag as Fn, TemplateParser as Fo, deleteIndeterminateGuards as Fr, recordProvenPublicExpression as Fs, loadJournaledOrphans as Ft, deleteBudgetKey as G, repairMalformedOrphansForReadOnly as Ga, redactedDockerCause as Gc, UNREADABLE_RESOURCES_MAP_ROW as Gi, ccRoutedFinalSnapshotError as Gn, passedNoEchoParametersOf as Go, reDisableInstanceApiTermination as Gr, S3StateBackend as Gs, replacedDeleteFailureVerdict as Gt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as H, refuseMalformedResourcesForExport as Ha, partitionSensitiveEnv as Hc, STATE_REGION_DIVERGED as Hi, resolveBucketRegion as Hl, ATOMIC_FINAL_SNAPSHOT_TYPES as Hn, noEchoCoordinatesOf as Ho, ec2InstanceProtectionSite as Hr, isSingleDynamicReferenceToken as Hs, getStackRecords as Ht, recordedProtectionNote as I, refuseMalformedResourcePropertiesForDestroy as Ia, dockerSpawnEnvWithSensitive as Ic, parseWebACLArn as Ii, displayAssemblyPath as Il, secretNamePrintingBag as In, canonicalCoordinates as Io, deleteLeftInPlace as Ir, wholeStringLeavesOf as Is, makeForeignHolderScan as It, DELETE_INDEX_WAIT_PROCEED_NOTE as J, repairMalformedResourcePropertiesForReadOnly as Ja, warnFinchArgvExposure as Jc, displayLogicalId as Ji, isFinalSnapshotError as Jn, valueAtCoordinate as Jo, INTRINSIC_KEYS as Jr, CrossPrefixScanCache as Js, isJournaledOrphan as Jt, resolveDynamoDbDeleteBudgetClock as K, repairMalformedOutputsForReadOnly as Ka, runDockerForeground as Kc, accountArgs as Ki, createPreDeleteFinalSnapshot as Kn, readbackPathFor as Ko, reEnableInstanceApiTermination as Kr, rebuildClientForBucketRegion as Ks, recordAfterRollbackUpdate as Kt, PROTECTION_PROPERTY_BY_TYPE as L, refuseMalformedResourcePropertiesForDrift as La, finchSecretArgvRefusal as Lc, withSharedDrainBudget as Li, renderAssemblyPathEscape as Ll, secretNamePrintingBags as Ln, isMarkedCoordinate as Lo, deleteSkipReason as Lr, STATE_SOURCED_BASELINE_RULES as Ls, sameJournaledOrphans as Lt, noEchoComparisonForTemplate as M, refuseMalformedResourceEntriesForDestroy as Ma, resolveDockerContextDirectory as Mc, AWS_NO_VALUE as Mi, nullPrototypeRecord as Ml, completedReplayEntries as Mn, lambdaFunctionNameForMask as Mo, unchangedBehindSecretReference as Mr, recordMaskOnlyValuesIn as Ms, dropFailedHint as Mt, noEchoExactEchoLeavesOf as N, refuseMalformedResourceEntriesForImport as Na, describeDockerCapturedOutput as Nc, cfnRefValueFromPhysicalId as Ni, ownValue as Nl, journaledOrphanPrintingBag as Nn, sameLambdaFunctionAddress as No, RollbackInlinePolicyWriters as Nr, recordNoEchoAttributeValues as Ns, isHandledOrphan as Nt, serviceTokenBlockingReason as O, refuseMalformedOutputsForDestroy as Oa, validateAssetBucketName as Oc, carriesDynamicReference as Oi, processStackMessages as Ol, isExportAliasCollision as On, templateResourceTypes as Oo, applyCustomResourceResponseExpiration as Or, splitGetAttStringForm as Os, collectNestedChildUnaddressed as Ot, noEchoParameterNamesOf as P, refuseMalformedResourceEntriesForImportSave as Pa, describeDockerExecFailure as Pc, isStalePlaceholderArnAttribute as Pi, absoluteAssemblyPathEscape as Pl, maskEventTextWithBoundBags as Pn, DagBuilder as Po, UNSPECIFIED_SKIP_REASON as Pr, recordNoEchoParameterFreshValue as Ps, journaledOrphanLines as Pt, ECR_AUTO_DELETE_IMAGES_TAG as Q, unreadableResourceEntries as Qa, AssetManifestLoader as Qc, isReadableOrphanRecord as Qi, constructPathOf as Qn, hasMaskableValues as Qo, refuseUnreadableCdkCrossAccountRefs as Qr, isNotImplemented as Qs, recheckFailedPlan as Qt, isProtectionValueActive as R, refuseMalformedResourcePropertiesForExport as Ra, formatDockerLoginError as Rc, parameterInputsFor as Ri, resolveAssemblyPath as Rl, secretNamedRecordNeedles as Rn, maskAtCoordinates as Ro, withIndeterminateGuard as Rr, STATE_SOURCED_CROSS_GENERATION_RULES as Rs, replayFailedOperations as Rt, lookupEachName as S, refuseMalformedOrphanRecords as Sa, assertAssetBucketRegion as Sc, regionLessSecretName as Si, expectedOwnerParam as Sl, exportNameNoEchoParameters as Sn, readConfigString as So, TemplateNoEchoReresolver as Sr, inheritNestedStackParameterAssociations as Ss, getNestedRevertRun as St, recordRetainedForReadoption as T, refuseMalformedOrphansForDestroy as Ta, isCrossRegionRedirect as Tc, parameterTypeMayLoseSecretIdentity as Ti, derivePartitionAndUrlSuffix as Tl, noEchoParameterValueSeed as Tn, requireConfigObject as To, getCurrentResourceSecrets as Tr, physicalNameCopiesOf as Ts, revertNestedChildFromJournal as Tt, beginDeleteWait as U, refuseMalformedState as Ua, redactDockerArgvValues as Uc, STATE_RESOURCES_MALFORMED as Ui, PRE_DELETE_SNAPSHOT_TYPES as Un, noEchoLeavesOf as Uo, isTerminationProtectionPropagationError as Ur, LockManager as Us, withStackRecords as Ut, DynamoDBGlobalTableProvider as V, refuseMalformedResourcesForDestroy as Va, isMalformedEnvKey as Vc, JSON_LISTING_HOLE_VALUE as Vi, clearBucketRegionCache as Vl, extractDeploymentEventError as Vn, maskedLeafCoordinatesOf as Vo, disableInstanceApiTermination as Vr, WHOLE_DYNAMIC_REFERENCE_PATTERN as Vs, destroyStackRecordsView as Vt, compensateRemovedDeletionProtection as W, repairMalformedOrphanRecordsForReadOnly as Wa, redactedCause as Wc, UNREADABLE_ORPHANS_CONTAINER_ROW as Wi, buildFinalSnapshotIdentifier as Wn, noEchoOutputsComparison as Wo, observeThenDisableInstanceApiTermination as Wr, isLockInfoExpired as Ws, removeProtectionTypeList as Wt, deleteTableWithIndexBusyRetry as X, unpreviewableOrphanRecords as Xa, stripControlChars as Xc, hasReadableOutputs as Xi, unsupportedFinalSnapshotError as Xn, carryLogOnlyValues as Xo, poisonRenderedSpellingsCollidingIn as Xr, crossPrefixDeniedWarning as Xs, planFailedOps as Xt, INDEX_SETTLE_POLL_INTERVAL_MS as Y, repairMalformedResourcesForReadOnly as Ya, escapeRegExp$3 as Yc, hasReadableOrphans as Yi, refusesFinalSnapshot as Yn, liveMatchesUnresolvedTokenFrame as Yo, IntrinsicFunctionResolver as Yr, applyCrossPrefixScan as Ys, isReplacementOrphan as Yt, waitForIndexesSettled as Z, unreadableOrphanRecords as Za, stripForDisplay as Zc, hasReadableResources as Zi, maskingRetryLogger as Zn, createUnionSecretMasker as Zo, producerLookupOver as Zr, isAccessDenied$1 as Zs, planRollback as Zt, keptWholeReasonText as _, malformedScrubResourceEntriesRefusalMessage as _a, createAssetRedirectResolver as _c, s3BucketRegionalDomainName as _i, MIGRATE_TMP_PREFIX as _l, exportAliasCollisionScrubWarning as _n, coerceCfnBoolean as _o, CC_BROKEN_REASON as _r, DYNAMIC_REFERENCE_TOKEN_SCAN as _s, planOrphanAdoption as _t, inheritedProvenanceForChildDiff as a, malformedLocalResourcesWarning as aa, hasUnverifiableParameterRefusal as ac, AWS_CREDENTIAL_ENV_KEYS as ai, resolveApp as al, getCurrentProducerRegions as an, hasNoCloudControlHandlers as ao, acquireIdempotencyToken as ar, unionOfSecretBags as as, createReadOnlyAttributeHealerFactory as at, chunks as b, refuseDivergentRecordRegionForDestroy as ba, AssetModeResolver as bc, classifyReplaySecretRegion as bi, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as bl, secretSafeKeyDisplay as bn, configIntegerRefusal as bo, isCustomResource as br, pathCrossesDottedKey as bs, displacedPhysicalIdShown as bt, isAbsoluteAssetPath as c, malformedOrphanRowsKeptWarning as ca, isReadableBag as cc, envCredentialsAreAssumedRole as ci, resolveSkipPrefix as cl, isRedactedRecordedValue as cn, MULTI_REGION_RECREATE_BLOCKED_TYPES as co, DBPROXY_TAGS_WHAT as cr, maskSecretsInError as cs, gray as ct, templateIdentity as d, malformedOutputsRefusalMessage as da, shouldRetainResource as dc, outputReferenceProvenanceOf as di, resolveUseCdkBootstrapAssets as dl, updatePartialMessage as dn, renderStatefulReason as do, readTagList as dr, recordReferenceProvenanceEntry as ds, yellow as dt, malformedDriftResourcePropertiesWarning as ea, acceptedCreateOnlyDropsOf as ec, assertFlagRoleArn as ei, Synthesizer as el, replacementNeverSwapped as en, findActionableSilentDrops as eo, formatDestructiveChange as er, logOnlyValueCount as es, hasCdkAutoDeleteTag as et, conditionFingerprint as f, malformedOutputsWarning as fa, AssetPublisher as fc, recordedOutputReferenceRegions as fi, stateBucketExistenceConfirmed as fl, updatePartialReason as fn, WARM_THROUGHPUT_MEMBERS as fo, refuseMalformedDesiredTags as fr, snapshotPassProvenance as fs, computeParameterTaint as ft, isSecretBearingReferenceString as g, malformedResourcesWarning as ga, buildAssetRedirectMap as gc, s3BucketDualStackDomainName as gi, CFN_TEMPLATE_URL_LIMIT as gl, displayTextOrWithheld as gn, toFiniteNumber as go, stringifyIfAssigned as gr, withoutPhysicalNameCopies as gs, makeSiblingClaimReader as gt, readRecordedConditionVerdicts as h, malformedResourcePropertiesWarning as ha, WorkGraph as hc, s3BucketDomainName as hi, CFN_TEMPLATE_BODY_LIMIT as hl, WITHHELD_NAME_DISPLAY as hn, toCfnInteger as ho, definedAttributes as hr, withPhysicalNameCopies as hs, resourcesNamingDeclaredParameter as ht, crossStackOutputProvenanceSource as i, malformedLocalResourceEntriesWarning as ia, hasReasonlessBaselineRefusal as ic, sendableAssumeRoleCommand as ii, loadCdkJson as il, findNestedStackTypeChanges as in, NO_CC_HANDLERS_REASON as io, withCreateTokenLedger as ir, shareLogOnlyValues as is, formatResourceLine as it, noEchoAttributeNamesOf as j, refuseMalformedResourceEntriesForDeploy as ja, buildDockerImage as jc, keepsSecretReferenceToken as ji, hasPlainPrototype$1 as jl, DEFAULT_RESOURCE_WARN_AFTER_MS as jn, canonicalLambdaFunctionName as jo, slowCcOperationTimeoutMs as jr, recordMaskOnlyValue as js, deleteJournaledOrphans as jt, withResourceDeadline as k, refuseMalformedResourceAttributesForOrphan as ka, validateContainerRepoName as kc, carriesFetchableDynamicReference as ki, defineOwnKey as kl, bindingSkippedOutputs as kn, describeTypeWithThrottleRetry as ko, customResourceResponseExpirationWarning as kr, carriesSecretMask as ks, getCurrentNestedStackContext as kt, listNestedTemplateRows as l, malformedOrphansRefusalMessage as la, orphansAfterRollback as lc, isSettledInstanceState as li, resolveStateBucketWithDefault as ll, redactedDeleteAddressFields as ln, isStatefulRecreateTargetForReplace as lo, DBPROXY_TAG_OPTIONS as lr, maskSecretsInText as ls, green as lt, parentSuppliedValues as m, malformedResourceEntriesWarning as ma, stringifyValue as mc, s3BucketArn as mi, ssmResolvedValueType as ml, DeploymentEventsStore as mn, isWarmThroughputDecrease as mo, tagPlanWarning as mr, scrubResourceRecord as ms, reachableDivergentParameters as mt, IMPLICIT_DELETE_DEPENDENCIES as n, malformedExportSourceWarning as na, exportNamesCarriedFrom as nc, explicitRoleArnOrThrow as ni, getDefaultStateBucketName as nl, seedsDeleteFirstGuard as nn, unwrittenCreateOnlyReplacement as no, ledgerForStack as nr, recordLogOnlyParameterValue as ns, getPriorAttempts as nt, childTemplateLoader as o, malformedOrphanRecordsRefusalMessage as oa, importableOutputKeys as oc, applyCallerIdentityCredentials as oi, resolveAutoAssetStorage as ol, inheritProducerRegions as on, findReplacedReadersOfRecreateTargets as oo, isRefusedByName as or, createSecretMasker as os, bold as ot, conditionInputsFrom as p, malformedRenderedContainersWarning as pa, isSensitiveAttributeName as pc, recordedReferenceRegions as pi, warnDeprecatedNoPrefixCliFlag as pl, DeploymentEventsReader as pn, coerceWarmThroughput as po, tagMapAsList as pr, redactSecretsForState as ps, namesAnyDeclaredParameter as pt, resolveDynamoDbDeleteBudgetMs as q, repairMalformedResourceEntriesForReadOnly as qa, runDockerStreaming as qc, deployRefusesOrphanRowsReason as qi, effectiveDeletionPolicy as qn, readsNoEchoSource as qo, DiffCalculator as qr, CrossPrefixReadError as qs, demoteSupersededOrphans as qt, computeImplicitDeleteEdges as r, malformedLocalOutputsWarning as ra, hasReadableExportSet as rc, isIamRoleArn as ri, getLegacyStateBucketName as rl, orphanDeleteNeedsIdentity as rn, withoutSilentDropProperties as ro, reserveStackCreateToken as rr, recordLogOnlyValue as rs, markRefusedBeforeApplying as rt, findNestedTemplateTreeDefect as s, malformedOrphanRecordsWarning as sa, importableOutputs as sc, callerEnvCredentials as si, resolveCaptureObservedState as sl, REDACTED_DELETE_ADDRESS_SKIP_REASON as sn, shownType as so, markDeleteStarted as sr, errorCauseChain as ss, cyan as st, DeployEngine as t, malformedExportNamesWarning as ta, describeRegionValueKind as tc, assertSendableRoleArn as ti, synthesisStatusMessage as tl, resolveReplacementOldType as tn, findSilentDropProperties as to, earliestDefined as tr, printingCorpusOf as ts, isTruthyCfnBoolean as tt, renderNestedTemplateTreeDefect as u, malformedOrphansWarning as ua, orphansCarriedFrom as uc, keepHeldTokenProvenance as ui, resolveStateBucketWithDefaultAndSource as ul, redactedDeleteAddressSkip as un, isStatefulRecreateTargetSync as uo, planTagDiff as ur, markSameGenerationBag as us, red as ut, mergeNoChangeOutputs as v, malformedStateRefusalMessage as va, loadPublishableAssetManifest as vc, s3BucketWebsiteUrl as vi, findLargeInlineResources as vl, secretBearing as vn, coerceCfnInteger as vo, ProviderRegistry as vr, dynamicReferenceTokens as vs, NESTED_PENDING_PARENT_REASON as vt, keptForReadoption as w, refuseMalformedOrphans as wa, getBootstrapMarkerKey as wc, isUnboundTemplateParameter as wi, canonicalizeRegion as wl, isWholeDynamicReferenceValue as wn, requireConfigArray as wo, isCustomResourceType as wr, recoverMaskedOutput as ws, recordDisplacedSkips as wt, isAccessDeniedError as x, refuseMalformedNestedChildOutputs as xa, BOOTSTRAP_MARKER_PREFIX as xc, producerRegionsFromState as xi, decodeListingKey as xl, carriedExportAliasExposure as xn, configStringRefusal as xo, wouldReturnToSdkProvider as xr, identityKeyFor as xs, dropSettledNestedJournals as xt, makeCanonicalizePropertiesFn as y, previewableOrphanRecords as ya, rewriteTemplateAssetReferences as yc, classifyRecordedSecretRegion as yi, uploadCfnTemplate as yl, secretBearingStateKeyWarning as yn, configBooleanRefusal as yo, ccBrokenReason as yr, isUncertifiedBaselineMaskPosition as ys, displacedOpClause as yt, perType as z, refuseMalformedResourcePropertiesForOrphan as za, getDockerCmd as zc, passedParameterClassesOf as zi, injectAwsRegion as zl, stateSecretNameNeedles as zn, maskReadbackAtCoordinates as zo, isWaitAbandonedError as zr, STATE_SOURCED_READBACK_RULES as zs, replayRollback as zt };
48031
- //# sourceMappingURL=deploy-engine-DOBzE5TD.js.map
48503
+ export { S3_AUTO_DELETE_OBJECTS_TAG as $, unpreviewableOrphanRecords as $a, stripControlChars as $c, hasReadableOutputs as $i, unsupportedFinalSnapshotError as $n, carryLogOnlyValues as $o, poisonRenderedSpellingsCollidingIn as $r, crossPrefixDeniedWarning as $s, isJournaledOrphan as $t, diffSecurity as A, refuseMalformedOutputs as Aa, readBootstrapMarkerBody as Ac, isImpossibleEmptyStoredAttribute as Ai, StageLoadError as Al, collectPublishedOutputNames as An, prefetchCreateOnlyPropertyPaths as Ao, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Ar, recordPhysicalNameCopy as As, NESTED_PENDING_PARENT_REASON as At, readProtection as B, refuseMalformedResourcePropertiesForDrift as Ba, finchSecretArgvRefusal as Bc, withSharedDrainBudget as Bi, renderAssemblyPathEscape as Bl, secretNamePrintingBags as Bn, isMarkedCoordinate as Bo, deleteSkipReason as Br, STATE_SOURCED_BASELINE_RULES as Bs, collectNestedChildUnaddressed as Bt, withApiLimit as C, refuseDivergentRecordRegionForDestroy as Ca, AssetModeResolver as Cc, classifyReplaySecretRegion as Ci, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Cl, secretSafeKeyDisplay as Cn, configIntegerRefusal as Co, isCustomResource as Cr, pathCrossesDottedKey as Cs, dropFailedCommands as Ct, findServiceTokenRefusals as D, refuseMalformedOrphans as Da, getBootstrapMarkerKey as Dc, isUnboundTemplateParameter as Di, canonicalizeRegion as Dl, isWholeDynamicReferenceValue as Dn, requireConfigArray as Do, isCustomResourceType as Dr, recoverMaskedOutput as Ds, loadJournaledOrphans as Dt, deferredServiceTokenWarning as E, refuseMalformedOrphanRecordsForDestroy as Ea, ensureAssetStorage as Ec, coerceParameterTypedValue as Ei, PARTITION_TABLE as El, exportNameSecretExposure as En, replayWarn as Eo, readsNoEchoDeleteValues as Er, recordNestedStackParameterExpressions as Es, journaledOrphanLines as Et, recordedProtectionEvidence as F, refuseMalformedResourceEntriesForDestroy as Fa, resolveDockerContextDirectory as Fc, AWS_NO_VALUE as Fi, nullPrototypeRecord as Fl, completedReplayEntries as Fn, lambdaFunctionNameForMask as Fo, unchangedBehindSecretReference as Fr, recordMaskOnlyValuesIn as Fs, nestedChildStackName as Ft, deleteBudgetKey as G, refuseMalformedResourcesForExport as Ga, partitionSensitiveEnv as Gc, STATE_REGION_DIVERGED as Gi, resolveBucketRegion as Gl, ATOMIC_FINAL_SNAPSHOT_TYPES as Gn, noEchoCoordinatesOf as Go, ec2InstanceProtectionSite as Gr, isSingleDynamicReferenceToken as Gs, awaitInFlightSibling as Gt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as H, refuseMalformedResourcePropertiesForOrphan as Ha, getDockerCmd as Hc, passedParameterClassesOf as Hi, injectAwsRegion as Hl, stateSecretNameNeedles as Hn, maskReadbackAtCoordinates as Ho, isWaitAbandonedError as Hr, STATE_SOURCED_READBACK_RULES as Hs, withNestedStackContext as Ht, recordedProtectionNote as I, refuseMalformedResourceEntriesForImport as Ia, describeDockerCapturedOutput as Ic, cfnRefValueFromPhysicalId as Ii, ownValue as Il, journaledOrphanPrintingBag as In, sameLambdaFunctionAddress as Io, RollbackInlinePolicyWriters as Ir, recordNoEchoAttributeValues as Is, recordDisplacedSkips as It, DELETE_INDEX_WAIT_PROCEED_NOTE as J, repairMalformedOrphansForReadOnly as Ja, redactedDockerCause as Jc, UNREADABLE_RESOURCES_MAP_ROW as Ji, ccRoutedFinalSnapshotError as Jn, passedNoEchoParametersOf as Jo, reDisableInstanceApiTermination as Jr, S3StateBackend as Js, withStackRecords as Jt, resolveDynamoDbDeleteBudgetClock as K, refuseMalformedState as Ka, redactDockerArgvValues as Kc, STATE_RESOURCES_MALFORMED as Ki, PRE_DELETE_SNAPSHOT_TYPES as Kn, noEchoLeavesOf as Ko, isTerminationProtectionPropagationError as Kr, LockManager as Ks, destroyStackRecordsView as Kt, PROTECTION_PROPERTY_BY_TYPE as L, refuseMalformedResourceEntriesForImportSave as La, describeDockerExecFailure as Lc, isStalePlaceholderArnAttribute as Li, absoluteAssemblyPathEscape as Ll, maskEventTextWithBoundBags as Ln, DagBuilder as Lo, UNSPECIFIED_SKIP_REASON as Lr, recordNoEchoParameterFreshValue as Ls, revertNestedChildFromJournal as Lt, noEchoComparisonForTemplate as M, refuseMalformedResourceAttributesForOrphan as Ma, validateContainerRepoName as Mc, carriesFetchableDynamicReference as Mi, defineOwnKey as Ml, bindingSkippedOutputs as Mn, describeTypeWithThrottleRetry as Mo, customResourceResponseExpirationWarning as Mr, carriesSecretMask as Ms, displacedPhysicalIdShown as Mt, noEchoExactEchoLeavesOf as N, refuseMalformedResourceEntries as Na, buildDenyExternalAccessPolicy as Nc, isNamelessDynamicReferenceError as Ni, hasOwnKey as Nl, DEFAULT_RESOURCE_TIMEOUT_MS as Nn, withRetry as No, CloudControlProvider as Nr, provenPublicValue as Ns, dropSettledNestedJournals as Nt, serviceTokenBlockingReason as O, refuseMalformedOrphansForDestroy as Oa, isCrossRegionRedirect as Oc, parameterTypeMayLoseSecretIdentity as Oi, derivePartitionAndUrlSuffix as Ol, noEchoParameterValueSeed as On, requireConfigObject as Oo, getCurrentResourceSecrets as Or, physicalNameCopiesOf as Os, makeForeignHolderScan as Ot, noEchoParameterNamesOf as P, refuseMalformedResourceEntriesForDeploy as Pa, buildDockerImage as Pc, keepsSecretReferenceToken as Pi, hasPlainPrototype$1 as Pl, DEFAULT_RESOURCE_WARN_AFTER_MS as Pn, canonicalLambdaFunctionName as Po, slowCcOperationTimeoutMs as Pr, recordMaskOnlyValue as Ps, getNestedRevertRun as Pt, ECR_AUTO_DELETE_IMAGES_TAG as Q, repairMalformedResourcesForReadOnly as Qa, escapeRegExp$3 as Qc, hasReadableOrphans as Qi, refusesFinalSnapshot as Qn, liveMatchesUnresolvedTokenFrame as Qo, IntrinsicFunctionResolver as Qr, applyCrossPrefixScan as Qs, demoteSupersededOrphans as Qt, isProtectionValueActive as R, refuseMalformedResourceEntriesForOrphan as Ra, describeDockerFailure as Rc, refStateLookupFromResource as Ri, describeFileReadFailure as Rl, orphanRecordsPrintingBag as Rn, TemplateParser as Ro, deleteIndeterminateGuards as Rr, recordProvenPublicExpression as Rs, revertedNestedRowIds as Rt, lookupEachName as S, previewableOrphanRecords as Sa, rewriteTemplateAssetReferences as Sc, classifyRecordedSecretRegion as Si, uploadCfnTemplate as Sl, secretBearingStateKeyWarning as Sn, configBooleanRefusal as So, ccBrokenReason as Sr, isUncertifiedBaselineMaskPosition as Ss, deleteJournaledOrphans as St, recordRetainedForReadoption as T, refuseMalformedOrphanRecords as Ta, assertAssetBucketRegion as Tc, regionLessSecretName as Ti, expectedOwnerParam as Tl, exportNameNoEchoParameters as Tn, readConfigString as To, TemplateNoEchoReresolver as Tr, inheritNestedStackParameterAssociations as Ts, isHandledOrphan as Tt, beginDeleteWait as U, refuseMalformedResourcesForDeploy as Ua, isDockerClientEnvKey as Uc, declaresNoEcho as Ui, injectedAwsRegionValue as Ul, storedSecretNameNeedles as Un, maskWholeValue as Uo, markWaitAbandoned as Ur, TEMPLATE_SOURCED_RULES as Us, replayFailedOperations as Ut, DynamoDBGlobalTableProvider as V, refuseMalformedResourcePropertiesForExport as Va, formatDockerLoginError as Vc, parameterInputsFor as Vi, resolveAssemblyPath as Vl, secretNamedRecordNeedles as Vn, maskAtCoordinates as Vo, withIndeterminateGuard as Vr, STATE_SOURCED_CROSS_GENERATION_RULES as Vs, getCurrentNestedStackContext as Vt, compensateRemovedDeletionProtection as W, refuseMalformedResourcesForDestroy as Wa, isMalformedEnvKey as Wc, JSON_LISTING_HOLE_VALUE as Wi, clearBucketRegionCache as Wl, extractDeploymentEventError as Wn, maskedLeafCoordinatesOf as Wo, disableInstanceApiTermination as Wr, WHOLE_DYNAMIC_REFERENCE_PATTERN as Ws, replayRollback as Wt, deleteTableWithIndexBusyRetry as X, repairMalformedResourceEntriesForReadOnly as Xa, runDockerStreaming as Xc, deployRefusesOrphanRowsReason as Xi, effectiveDeletionPolicy as Xn, readsNoEchoSource as Xo, DiffCalculator as Xr, CrossPrefixReadError as Xs, replacedDeleteFailureVerdict as Xt, INDEX_SETTLE_POLL_INTERVAL_MS as Y, repairMalformedOutputsForReadOnly as Ya, runDockerForeground as Yc, accountArgs as Yi, createPreDeleteFinalSnapshot as Yn, readbackPathFor as Yo, reEnableInstanceApiTermination as Yr, rebuildClientForBucketRegion as Ys, removeProtectionTypeList as Yt, waitForIndexesSettled as Z, repairMalformedResourcePropertiesForReadOnly as Za, warnFinchArgvExposure as Zc, displayLogicalId as Zi, isFinalSnapshotError as Zn, valueAtCoordinate as Zo, INTRINSIC_KEYS as Zr, CrossPrefixScanCache as Zs, recordAfterRollbackUpdate as Zt, keptWholeReasonText as _, malformedResourceEntriesWarning as _a, stringifyValue as _c, s3BucketArn as _i, ssmResolvedValueType as _l, orphanNeedsIdentity as _n, isWarmThroughputDecrease as _o, tagPlanWarning as _r, scrubResourceRecord as _s, planOrphanAdoption as _t, inheritedProvenanceForChildDiff as a, malformedExportSourceWarning as aa, exportNamesCarriedFrom as ac, explicitRoleArnOrThrow as ai, getDefaultStateBucketName as al, replacementNeverSwapped as an, unwrittenCreateOnlyReplacement as ao, ledgerForStack as ar, recordLogOnlyParameterValue as as, createReadOnlyAttributeHealerFactory as at, chunks as b, malformedScrubResourceEntriesRefusalMessage as ba, createAssetRedirectResolver as bc, s3BucketRegionalDomainName as bi, MIGRATE_TMP_PREFIX as bl, exportAliasCollisionScrubWarning as bn, coerceCfnBoolean as bo, CC_BROKEN_REASON as br, DYNAMIC_REFERENCE_TOKEN_SCAN as bs, pendingRequestCount as bt, isAbsoluteAssetPath as c, malformedLocalResourcesWarning as ca, hasUnverifiableParameterRefusal as cc, AWS_CREDENTIAL_ENV_KEYS as ci, resolveApp as cl, findNestedStackTypeChanges as cn, hasNoCloudControlHandlers as co, acquireIdempotencyToken as cr, unionOfSecretBags as cs, gray as ct, templateIdentity as d, malformedOrphanRowsKeptWarning as da, isReadableBag as dc, envCredentialsAreAssumedRole as di, resolveSkipPrefix as dl, REDACTED_DELETE_ADDRESS_SKIP_REASON as dn, MULTI_REGION_RECREATE_BLOCKED_TYPES as do, DBPROXY_TAGS_WHAT as dr, maskSecretsInError as ds, yellow as dt, hasReadableResources as ea, isAccessDenied$1 as ec, producerLookupOver as ei, stripForDisplay as el, isReplacementOrphan as en, unreadableOrphanRecords as eo, maskingRetryLogger as er, createUnionSecretMasker as es, hasCdkAutoDeleteTag as et, conditionFingerprint as f, malformedOrphansRefusalMessage as fa, orphansAfterRollback as fc, isSettledInstanceState as fi, resolveStateBucketWithDefault as fl, isRedactedRecordedValue as fn, isStatefulRecreateTargetForReplace as fo, DBPROXY_TAG_OPTIONS as fr, maskSecretsInText as fs, computeParameterTaint as ft, isSecretBearingReferenceString as g, malformedRenderedContainersWarning as ga, isSensitiveAttributeName as gc, recordedReferenceRegions as gi, warnDeprecatedNoPrefixCliFlag as gl, updatePartialReason as gn, coerceWarmThroughput as go, tagMapAsList as gr, redactSecretsForState as gs, makeSiblingClaimReader as gt, readRecordedConditionVerdicts as h, malformedOutputsWarning as ha, AssetPublisher as hc, recordedOutputReferenceRegions as hi, stateBucketExistenceConfirmed as hl, updatePartialMessage as hn, WARM_THROUGHPUT_MEMBERS as ho, refuseMalformedDesiredTags as hr, snapshotPassProvenance as hs, resourcesNamingDeclaredParameter as ht, crossStackOutputProvenanceSource as i, malformedExportNamesWarning as ia, describeRegionValueKind as ic, assertSendableRoleArn as ii, synthesisStatusMessage as il, recordUnderIdIsNotOwn as in, findSilentDropProperties as io, earliestDefined as ir, printingCorpusOf as is, formatResourceLine as it, noEchoAttributeNamesOf as j, refuseMalformedOutputsForDestroy as ja, validateAssetBucketName as jc, carriesDynamicReference as ji, processStackMessages as jl, isExportAliasCollision as jn, templateResourceTypes as jo, applyCustomResourceResponseExpiration as jr, splitGetAttStringForm as js, displacedOpClause as jt, withResourceDeadline as k, refuseMalformedOrphansForOrphan as ka, parseBootstrapMarker as kc, getAccountInfo as ki, AssemblyReader as kl, collectDeclaredOutputNames as kn, requireConfigString as ko, withPrintingSecrets as kr, recordAttributeIdCopy as ks, sameJournaledOrphans as kt, listNestedTemplateRows as l, malformedOrphanRecordsRefusalMessage as la, importableOutputKeys as lc, applyCallerIdentityCredentials as li, resolveAutoAssetStorage as ll, getCurrentProducerRegions as ln, findReplacedReadersOfRecreateTargets as lo, isRefusedByName as lr, createSecretMasker as ls, green as lt, parentSuppliedValues as m, malformedOutputsRefusalMessage as ma, shouldRetainResource as mc, outputReferenceProvenanceOf as mi, resolveUseCdkBootstrapAssets as ml, redactedDeleteAddressSkip as mn, renderStatefulReason as mo, readTagList as mr, recordReferenceProvenanceEntry as ms, reachableDivergentParameters as mt, IMPLICIT_DELETE_DEPENDENCIES as n, isReadableResourceEntry as na, splitImportedOps as nc, applyRoleArnIfSet as ni, getDockerImageBySourceHash as nl, planRollback as nn, withheldAccountClause as no, findDestructiveChanges as nr, literalSplitDelimitersOf as ns, getPriorAttempts as nt, childTemplateLoader as o, malformedLocalOutputsWarning as oa, hasReadableExportSet as oc, isIamRoleArn as oi, getLegacyStateBucketName as ol, resolveReplacementOldType as on, withoutSilentDropProperties as oo, reserveStackCreateToken as or, recordLogOnlyValue as os, bold as ot, conditionInputsFrom as p, malformedOrphansWarning as pa, orphansCarriedFrom as pc, keepHeldTokenProvenance as pi, resolveStateBucketWithDefaultAndSource as pl, redactedDeleteAddressFields as pn, isStatefulRecreateTargetSync as po, planTagDiff as pr, markSameGenerationBag as ps, namesAnyDeclaredParameter as pt, resolveDynamoDbDeleteBudgetMs as q, repairMalformedOrphanRecordsForReadOnly as qa, redactedCause as qc, UNREADABLE_ORPHANS_CONTAINER_ROW as qi, buildFinalSnapshotIdentifier as qn, noEchoOutputsComparison as qo, observeThenDisableInstanceApiTermination as qr, isLockInfoExpired as qs, getStackRecords as qt, computeImplicitDeleteEdges as r, malformedDriftResourcePropertiesWarning as ra, acceptedCreateOnlyDropsOf as rc, assertFlagRoleArn as ri, Synthesizer as rl, recheckFailedPlan as rn, findActionableSilentDrops as ro, formatDestructiveChange as rr, logOnlyValueCount as rs, markRefusedBeforeApplying as rt, findNestedTemplateTreeDefect as s, malformedLocalResourceEntriesWarning as sa, hasReasonlessBaselineRefusal as sc, sendableAssumeRoleCommand as si, loadCdkJson as sl, seedsDeleteFirstGuard as sn, NO_CC_HANDLERS_REASON as so, withCreateTokenLedger as sr, shareLogOnlyValues as ss, cyan as st, DeployEngine as t, isReadableOrphanRecord as ta, isNotImplemented as tc, refuseUnreadableCdkCrossAccountRefs as ti, AssetManifestLoader as tl, planFailedOps as tn, unreadableResourceEntries as to, constructPathOf as tr, hasMaskableValues as ts, isTruthyCfnBoolean as tt, renderNestedTemplateTreeDefect as u, malformedOrphanRecordsWarning as ua, importableOutputs as uc, callerEnvCredentials as ui, resolveCaptureObservedState as ul, inheritProducerRegions as un, shownType as uo, markDeleteStarted as ur, errorCauseChain as us, red as ut, mergeNoChangeOutputs as v, malformedResourcePropertiesWarning as va, WorkGraph as vc, s3BucketDomainName as vi, CFN_TEMPLATE_BODY_LIMIT as vl, WITHHELD_NAME_DISPLAY as vn, toCfnInteger as vo, definedAttributes as vr, withPhysicalNameCopies as vs, DeploymentEventsReader as vt, keptForReadoption as w, refuseMalformedNestedChildOutputs as wa, BOOTSTRAP_MARKER_PREFIX as wc, producerRegionsFromState as wi, decodeListingKey as wl, carriedExportAliasExposure as wn, configStringRefusal as wo, wouldReturnToSdkProvider as wr, identityKeyFor as ws, dropFailedHint as wt, isAccessDeniedError as x, malformedStateRefusalMessage as xa, loadPublishableAssetManifest as xc, s3BucketWebsiteUrl as xi, findLargeInlineResources as xl, secretBearing as xn, coerceCfnInteger as xo, ProviderRegistry as xr, dynamicReferenceTokens as xs, resolvePendingCloudControlRequests as xt, makeCanonicalizePropertiesFn as y, malformedResourcesWarning as ya, buildAssetRedirectMap as yc, s3BucketDualStackDomainName as yi, CFN_TEMPLATE_URL_LIMIT as yl, displayTextOrWithheld as yn, toFiniteNumber as yo, stringifyIfAssigned as yr, withoutPhysicalNameCopies as ys, DeploymentEventsStore as yt, perType as z, refuseMalformedResourcePropertiesForDestroy as za, dockerSpawnEnvWithSensitive as zc, parseWebACLArn as zi, displayAssemblyPath as zl, secretNamePrintingBag as zn, canonicalCoordinates as zo, deleteLeftInPlace as zr, wholeStringLeavesOf as zs, withNestedRevertRun as zt };
48504
+ //# sourceMappingURL=deploy-engine-DEvS2r2M.js.map