@go-to-k/cdkd 0.284.54 → 0.284.55

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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $n as clearBucketRegionCache, Dr as isCdkdError, Er as formatError, Ht as DiffCalculator, Jt as LockManager, Kt as DagBuilder, Or as normalizeAwsError, Tr as SynthesisError, W as IAMRoleProvider, Xt as S3StateBackend, Zn as AssemblyReader, ar as AssetError, er as resolveBucketRegion, hr as LockError, ir as setAwsClients, kn as Synthesizer, lr as DependencyError, nn as AssetPublisher, nr as getAwsClients, nt as CloudControlProvider, or as CdkdError, q as ProviderRegistry, qt as TemplateParser, r as DeployEngine, rr as resetAwsClients, sr as ConfigError, tr as AwsClients, wr as StateError, yr as ProvisioningError } from "./deploy-engine-B9SrF2-R.js";
1
+ import { An as Synthesizer, Dr as formatError, Er as SynthesisError, Jt as TemplateParser, Or as isCdkdError, Qn as AssemblyReader, Tr as StateError, Ut as DiffCalculator, W as IAMRoleProvider, Yt as LockManager, Zt as S3StateBackend, ar as setAwsClients, br as ProvisioningError, cr as ConfigError, er as clearBucketRegionCache, gr as LockError, ir as resetAwsClients, kr as normalizeAwsError, nr as AwsClients, or as AssetError, q as ProviderRegistry, qt as DagBuilder, r as DeployEngine, rn as AssetPublisher, rr as getAwsClients, rt as CloudControlProvider, sr as CdkdError, tr as resolveBucketRegion, ur as DependencyError } from "./deploy-engine-B1tSPv8F.js";
2
2
  import { n as getLogger, r as setLogger, t as ConsoleLogger } from "./logger-zRrlbaQt.js";
3
3
 
4
4
  export { AssemblyReader, AssetError, AssetPublisher, AwsClients, CdkdError, CloudControlProvider, ConfigError, ConsoleLogger, DagBuilder, DependencyError, DeployEngine, DiffCalculator, IAMRoleProvider, LockError, LockManager, ProviderRegistry, ProvisioningError, S3StateBackend, StateError, SynthesisError, Synthesizer, TemplateParser, clearBucketRegionCache, formatError, getAwsClients, getLogger, isCdkdError, normalizeAwsError, resetAwsClients, resolveBucketRegion, setAwsClients, setLogger };
@@ -1,7 +1,7 @@
1
- import { $ as endCommandInterruptScope, $t as importableOutputKeys, A as renderStatefulReason, An as synthesisStatusMessage, Ar as isMarkedNonRetryable, At as maskSecretsInError, B as exportAliasCollisionScrubWarning, Bn as stateBucketExistenceConfirmed, Bt as s3BucketWebsiteUrl, C as isFinalSnapshotError, Cn as getDockerCmd, Cr as StackTerminationProtectionError, Ct as STATE_SOURCED_CROSS_GENERATION_RULES, D as extractDeploymentEventError, Dn as AssetManifestLoader, Dt as dynamicReferenceTokens, E as makeCanonicalizePropertiesFn, En as runDockerStreaming, Et as createSecretMasker, F as green, Fn as resolveCaptureObservedState, Ft as producerRegionsFromState, G as collectInlinePolicyNamesManagedBySiblings, Gn as findLargeInlineResources, Gt as withRetry, H as secretBearingStateKeyWarning, Hn as CFN_TEMPLATE_BODY_LIMIT, Ht as DiffCalculator, I as red, In as resolveSkipPrefix, It as s3BucketArn, J as findActionableSilentDrops, Jn as PARTITION_TABLE, Jt as LockManager, K as clearOnUpdateRemoval, Kn as uploadCfnTemplate, Kt as DagBuilder, L as yellow, Ln as resolveStateBucketWithDefault, Lt as s3BucketDomainName, M as bold, Mn as getLegacyStateBucketName, Mr as isThrottlingError, Mt as redactSecretsForState, N as cyan, Nn as resolveApp, Nr as markNonRetryable, Nt as scrubResourceRecord, O as MULTI_REGION_RECREATE_BLOCKED_TYPES, On as getDockerImageBySourceHash, Or as normalizeAwsError, Ot as errorCauseChain, P as gray, Pn as resolveAutoAssetStorage, Pt as classifyReplaySecretRegion, Q as beginCommandInterruptScope, Qn as processStackMessages, Qt as exportNamesCarriedFrom, R as collectDeclaredOutputNames, Rn as resolveStateBucketWithDefaultAndSource, Rt as s3BucketDualStackDomainName, S as createPreDeleteFinalSnapshot, Sn as formatDockerLoginError, Sr as StackHasActiveImportsError, St as requireConfigString, T as unsupportedFinalSnapshotError, Tn as runDockerForeground, Tt as TEMPLATE_SOURCED_RULES, U as stateKeySecretExposure, Un as CFN_TEMPLATE_URL_LIMIT, Ut as INTRINSIC_KEYS, V as isExportAliasCollision, Vn as warnDeprecatedNoPrefixCliFlag, Vt as applyRoleArnIfSet, W as IAMRoleProvider, Wn as MIGRATE_TMP_PREFIX, Wt as describeTypeWithThrottleRetry, X as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xn as derivePartitionAndUrlSuffix, Xt as S3StateBackend, Y as findSilentDropProperties, Yn as canonicalizeRegion, Yt as displaySafe, Z as DEFAULT_STATE_PREFIX, Zn as AssemblyReader, Zt as rebuildClientForBucketRegion, _ as computeImplicitDeleteEdges, _n as validateAssetBucketName, _r as NestedStackChildDirectDestroyError, _t as configStringRefusal, a as DeploymentEventsStore, an as buildAssetRedirectMap, at as isTerminationProtectionPropagationError, b as buildFinalSnapshotIdentifier, bn as buildDockerImage, br as ResourceTimeoutError, bt as requireConfigArray, c as replayFailedOperations, cn as rewriteTemplateAssetReferences, cr as CrossAccountSecretRefusalError, ct as cfnRefValueFromPhysicalId, d as updatePartialReason, dn as AssetModeResolver, dr as DynamicReferenceRegionAmbiguousError, dt as WAFv2WebACLProvider, en as importableOutputs, er as resolveBucketRegion, et as isInterruptedWaitError, f as UNSPECIFIED_SKIP_REASON, fn as BOOTSTRAP_MARKER_PREFIX, fr as LocalInvokeBuildError$1, ft as normalizeAwsTagsToCfn, g as IMPLICIT_DELETE_DEPENDENCIES, gn as readBootstrapMarkerBody, gr as MissingCdkCliError, gt as configBooleanRefusal, h as maskingRetryLogger, hn as parseBootstrapMarker, ht as coerceCfnBoolean, i as DeploymentEventsReader, in as WorkGraph, ir as setAwsClients, it as disableInstanceApiTermination, j as formatResourceLine, jn as getDefaultStateBucketName, jr as isRetryableTransientError, jt as maskSecretsInText, k as isStatefulRecreateTargetSync, kn as Synthesizer, kr as withErrorHandling, kt as isSingleDynamicReferenceToken, l as replayRollback, ln as escapeRegExp, lt as getAccountInfo, m as withResourceDeadline, mn as getBootstrapMarkerKey, mr as LocalStartServiceError, mt as assertRegionMatch, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AssetPublisher, nr as getAwsClients, nt as CloudControlProvider, o as planFailedOps, on as createAssetRedirectResolver, or as CdkdError, ot as IntrinsicFunctionResolver, p as deleteSkipReason, pn as ensureAssetStorage, pr as LocalMigrateError, pt as resolveExplicitPhysicalId, q as ProviderRegistry, qn as expectedOwnerParam, qt as TemplateParser, r as DeployEngine, rn as stringifyValue, rr as resetAwsClients, rt as slowCcOperationTimeoutMs, s as planRollback, sn as loadPublishableAssetManifest, st as carriesDynamicReference, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as shouldRetainResource, tr as AwsClients, tt as startInterruptWatch, u as updatePartialMessage, un as stripControlChars, ur as DeployCancelledError, ut as refStateLookupFromResource, v as ATOMIC_FINAL_SNAPSHOT_TYPES, vn as validateContainerRepoName, vr as PartialFailureError, vt as readConfigString, w as refusesFinalSnapshot, wn as partitionSensitiveEnv, wt as STATE_SOURCED_READBACK_RULES, x as ccRoutedFinalSnapshotError, xn as dockerSpawnEnvWithSensitive, xr as ResourceUpdateNotSupportedError, xt as requireConfigObject, y as PRE_DELETE_SNAPSHOT_TYPES, yn as buildDenyExternalAccessPolicy, yr as ProvisioningError, yt as replayWarn, z as collectPublishedOutputNames, zn as resolveUseCdkBootstrapAssets, zt as s3BucketRegionalDomainName } from "./deploy-engine-B9SrF2-R.js";
1
+ import { $ as endCommandInterruptScope, $n as processStackMessages, $t as exportNamesCarriedFrom, A as renderStatefulReason, An as Synthesizer, Ar as withErrorHandling, At as isSingleDynamicReferenceToken, B as exportAliasCollisionScrubWarning, Bn as resolveUseCdkBootstrapAssets, Bt as s3BucketRegionalDomainName, C as isFinalSnapshotError, Cn as formatDockerLoginError, Cr as StackHasActiveImportsError, Ct as requireConfigString, D as extractDeploymentEventError, Dn as runDockerStreaming, Dt as createSecretMasker, E as makeCanonicalizePropertiesFn, En as runDockerForeground, Et as TEMPLATE_SOURCED_RULES, F as green, Fn as resolveAutoAssetStorage, Ft as classifyReplaySecretRegion, G as collectInlinePolicyNamesManagedBySiblings, Gn as MIGRATE_TMP_PREFIX, Gt as describeTypeWithThrottleRetry, H as secretBearingStateKeyWarning, Hn as warnDeprecatedNoPrefixCliFlag, Ht as applyRoleArnIfSet, I as red, In as resolveCaptureObservedState, It as producerRegionsFromState, J as findActionableSilentDrops, Jn as expectedOwnerParam, Jt as TemplateParser, K as clearOnUpdateRemoval, Kn as findLargeInlineResources, Kt as withRetry, L as yellow, Ln as resolveSkipPrefix, Lt as s3BucketArn, M as bold, Mn as getDefaultStateBucketName, Mr as isRetryableTransientError, Mt as maskSecretsInText, N as cyan, Nn as getLegacyStateBucketName, Nr as isThrottlingError, Nt as redactSecretsForState, O as MULTI_REGION_RECREATE_BLOCKED_TYPES, On as AssetManifestLoader, Ot as dynamicReferenceTokens, P as gray, Pn as resolveApp, Pr as markNonRetryable, Pt as scrubResourceRecord, Q as beginCommandInterruptScope, Qn as AssemblyReader, Qt as rebuildClientForBucketRegion, R as collectDeclaredOutputNames, Rn as resolveStateBucketWithDefault, Rt as s3BucketDomainName, S as createPreDeleteFinalSnapshot, Sn as dockerSpawnEnvWithSensitive, Sr as ResourceUpdateNotSupportedError, St as requireConfigObject, T as unsupportedFinalSnapshotError, Tn as partitionSensitiveEnv, Tt as STATE_SOURCED_READBACK_RULES, U as stateKeySecretExposure, Un as CFN_TEMPLATE_BODY_LIMIT, Ut as DiffCalculator, V as isExportAliasCollision, Vn as stateBucketExistenceConfirmed, Vt as s3BucketWebsiteUrl, W as IAMRoleProvider, Wn as CFN_TEMPLATE_URL_LIMIT, Wt as INTRINSIC_KEYS, X as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xn as canonicalizeRegion, Xt as displaySafe, Y as findSilentDropProperties, Yn as PARTITION_TABLE, Yt as LockManager, Z as DEFAULT_STATE_PREFIX, Zn as derivePartitionAndUrlSuffix, Zt as S3StateBackend, _ as computeImplicitDeleteEdges, _n as readBootstrapMarkerBody, _r as MissingCdkCliError, _t as configBooleanRefusal, a as DeploymentEventsStore, an as WorkGraph, ar as setAwsClients, at as disableInstanceApiTermination, b as buildFinalSnapshotIdentifier, bn as buildDenyExternalAccessPolicy, br as ProvisioningError, bt as replayWarn, c as replayFailedOperations, cn as loadPublishableAssetManifest, ct as carriesDynamicReference, d as updatePartialReason, dn as stripControlChars, dr as DeployCancelledError, dt as refStateLookupFromResource, en as importableOutputKeys, et as interruptWatchListenerCount, f as UNSPECIFIED_SKIP_REASON, fn as AssetModeResolver, fr as DynamicReferenceRegionAmbiguousError, ft as WAFv2WebACLProvider, g as IMPLICIT_DELETE_DEPENDENCIES, gn as parseBootstrapMarker, gt as coerceCfnBoolean, h as maskingRetryLogger, hn as getBootstrapMarkerKey, hr as LocalStartServiceError, ht as assertRegionMatch, i as DeploymentEventsReader, in as stringifyValue, ir as resetAwsClients, it as slowCcOperationTimeoutMs, j as formatResourceLine, jn as synthesisStatusMessage, jr as isMarkedNonRetryable, jt as maskSecretsInError, k as isStatefulRecreateTargetSync, kn as getDockerImageBySourceHash, kr as normalizeAwsError, kt as errorCauseChain, l as replayRollback, ln as rewriteTemplateAssetReferences, lr as CrossAccountSecretRefusalError, lt as cfnRefValueFromPhysicalId, m as withResourceDeadline, mn as ensureAssetStorage, mr as LocalMigrateError, mt as resolveExplicitPhysicalId, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as shouldRetainResource, nr as AwsClients, nt as startInterruptWatch, o as planFailedOps, on as buildAssetRedirectMap, ot as isTerminationProtectionPropagationError, p as deleteSkipReason, pn as BOOTSTRAP_MARKER_PREFIX, pr as LocalInvokeBuildError$1, pt as normalizeAwsTagsToCfn, q as ProviderRegistry, qn as uploadCfnTemplate, qt as DagBuilder, r as DeployEngine, rn as AssetPublisher, rr as getAwsClients, rt as CloudControlProvider, s as planRollback, sn as createAssetRedirectResolver, sr as CdkdError, st as IntrinsicFunctionResolver, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as importableOutputs, tr as resolveBucketRegion, tt as isInterruptedWaitError, u as updatePartialMessage, un as escapeRegExp, ut as getAccountInfo, v as ATOMIC_FINAL_SNAPSHOT_TYPES, vn as validateAssetBucketName, vr as NestedStackChildDirectDestroyError, vt as configStringRefusal, w as refusesFinalSnapshot, wn as getDockerCmd, wr as StackTerminationProtectionError, wt as STATE_SOURCED_CROSS_GENERATION_RULES, x as ccRoutedFinalSnapshotError, xn as buildDockerImage, xr as ResourceTimeoutError, xt as requireConfigArray, y as PRE_DELETE_SNAPSHOT_TYPES, yn as validateContainerRepoName, yr as PartialFailureError, yt as readConfigString, z as collectPublishedOutputNames, zn as resolveStateBucketWithDefaultAndSource, zt as s3BucketDualStackDomainName } from "./deploy-engine-B1tSPv8F.js";
2
2
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as getCurrentStackName, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
3
- import { t as getCdkdVersion } from "./version-DLRgymoe.js";
4
- import { t as ASGProvider } from "./asg-provider-BaNTIjU4.js";
3
+ import { t as getCdkdVersion } from "./version-DD5yHFTJ.js";
4
+ import { t as ASGProvider } from "./asg-provider-nddX-RVm.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -2055,6 +2055,15 @@ function createListCommand() {
2055
2055
  */
2056
2056
  function forwardSigtermToSigint() {
2057
2057
  beginCommandInterruptScope();
2058
+ try {
2059
+ return installSigtermForwarder();
2060
+ } catch (error) {
2061
+ endCommandInterruptScope();
2062
+ throw error;
2063
+ }
2064
+ }
2065
+ /** The registration half of {@link forwardSigtermToSigint}, after its scope is open. */
2066
+ function installSigtermForwarder() {
2058
2067
  const handler = () => {
2059
2068
  if (process.listenerCount("SIGINT") === 0) process.exit(143);
2060
2069
  process.emit("SIGINT", "SIGINT");
@@ -2065,6 +2074,117 @@ function forwardSigtermToSigint() {
2065
2074
  endCommandInterruptScope();
2066
2075
  };
2067
2076
  }
2077
+ /**
2078
+ * Register a command-scoped SIGINT handler for the destroy commands
2079
+ * (issue #2117).
2080
+ *
2081
+ * `cdkd deploy` has had one of these since issue #1348 (`deploy.ts`'s
2082
+ * `topLevelSigintHandler`). The destroy side had none, so the ONLY channel
2083
+ * carrying "the user interrupted" from `runDestroyForStack` back to the
2084
+ * `--all` loop was `DestroyRunResult.interrupted` — a boolean assigned ONCE,
2085
+ * inside the runner's `try`, after its level loop. Every instant where the
2086
+ * runner's `draining` flag flips AFTER that assignment is an instant where
2087
+ * `cdkd destroy --all` went on to delete the NEXT stack after the user asked
2088
+ * it to stop.
2089
+ *
2090
+ * The runner's outer `finally` re-syncs `result.interrupted ||= draining` to
2091
+ * cover the widest such window (renderer teardown, state flush, lock release),
2092
+ * and that line is marked TACTICAL in its own comment: it narrows the window
2093
+ * rather than removing it. Two gaps survive it, and neither is reachable from
2094
+ * inside the runner at all:
2095
+ *
2096
+ * 1. The runner removes its SIGINT listener in its inner `finally`, BEFORE the
2097
+ * re-sync line and its `return`, so from there on nothing of the runner's is
2098
+ * armed. This watch covers that stretch — by RECORDING once a graceful owner
2099
+ * is gone and the stack is done, and by QUITTING in the mirror-image window
2100
+ * at the START of a stack, where the runner has not armed yet and could not
2101
+ * act on a recorded flag (see `gracefulOwnerArmed` below).
2102
+ * 2. Everything the `--all` loop itself does between two stacks — the
2103
+ * `RUN_FINISHED` event, `eventRecorder.finalize`, `purgeEventsAfterDestroy`
2104
+ * — runs with no runner handler armed at all.
2105
+ *
2106
+ * A handler that lives for the whole command closes both, because it is armed
2107
+ * in every window rather than in the ones the runner happens to span. The two
2108
+ * flags answer different questions and both are kept: `result.interrupted` is
2109
+ * the PER-STACK outcome (it decides that stack's state preservation, its
2110
+ * summary line and its `--purge-events` skip), while this one is the
2111
+ * COMMAND-level "stop" the loop wants.
2112
+ *
2113
+ * Note on the counterpart contract: `deploy-engine.ts` removes its own SIGINT
2114
+ * handler before releasing its lock, which is safe only because `deploy.ts`'s
2115
+ * top-level handler outlives it. The destroy side now has the same property
2116
+ * for the same reason — `destroy-runner.ts`'s `process.removeListener('SIGINT',
2117
+ * sigintHandler)` is no longer the last handler standing, because this one is
2118
+ * disposed only in the command's outermost `finally`.
2119
+ *
2120
+ * @param opts.command the user-facing command name used in the force-quit
2121
+ * notice (`cdkd destroy` / `cdkd state destroy`).
2122
+ */
2123
+ function watchCommandInterrupt(opts) {
2124
+ let interrupted = false;
2125
+ let stacksInFlight = 0;
2126
+ /**
2127
+ * Is some OTHER listener going to handle this signal gracefully?
2128
+ *
2129
+ * Being inside `runStack` is NOT the same question, and assuming it was is a
2130
+ * regression this fix already shipped once: `runDestroyForStack` registers
2131
+ * its own handler about two hundred lines in, AFTER the strong-reference
2132
+ * pre-flight scan (an S3 LIST plus a GET per stack) and the per-stack
2133
+ * confirm prompt. Staying silent across that window swallowed the signal
2134
+ * outright — no notice, no exit, no escalation on a repeat — and because
2135
+ * this watch IS a listener, `interrupt-watch.ts`'s last-listener force-quit
2136
+ * could no longer fire there either. The runner then began with `draining`
2137
+ * false and destroyed the whole stack the user had just asked to stop, which
2138
+ * is issue #2117's own defect one window further in.
2139
+ *
2140
+ * Counting listeners answers the real question, and the two exclusions are
2141
+ * what make the count mean "graceful owner":
2142
+ *
2143
+ * - our own handler, which is not an answer to itself;
2144
+ * - `interrupt-watch.ts`'s shared handler, which is a LATCH rather than a
2145
+ * graceful owner — deferring to it is exactly the swallow above.
2146
+ *
2147
+ * A provider's transient wait listener (CustomResource / ACM / CloudFront /
2148
+ * Route53) does count, and that is correct rather than a false positive:
2149
+ * those exist only DURING a provider wait, which is strictly inside the
2150
+ * runner handler's own lifetime, so one cannot be present while the runner's
2151
+ * is absent.
2152
+ */
2153
+ function gracefulOwnerArmed() {
2154
+ return process.listeners("SIGINT").filter((l) => l !== handler).length - interruptWatchListenerCount() > 0;
2155
+ }
2156
+ const handler = () => {
2157
+ if (stacksInFlight > 0 && gracefulOwnerArmed()) {
2158
+ interrupted = true;
2159
+ return;
2160
+ }
2161
+ if (interrupted) {
2162
+ process.stderr.write("\nForce-quit.\n");
2163
+ process.exit(130);
2164
+ }
2165
+ interrupted = true;
2166
+ if (stacksInFlight > 0) {
2167
+ process.stderr.write(`\nInterrupted before ${opts.command} armed its per-stack teardown — quitting now. Nothing was deleted and no stack lock is held.\n`);
2168
+ process.exit(130);
2169
+ }
2170
+ process.stderr.write(`\nInterrupted — ${opts.command} will stop before starting another stack (press Ctrl-C again to force-quit)...\n`);
2171
+ };
2172
+ process.on("SIGINT", handler);
2173
+ return {
2174
+ interrupted: () => interrupted,
2175
+ async runStack(fn) {
2176
+ stacksInFlight += 1;
2177
+ try {
2178
+ return await fn();
2179
+ } finally {
2180
+ stacksInFlight -= 1;
2181
+ }
2182
+ },
2183
+ dispose: () => {
2184
+ process.removeListener("SIGINT", handler);
2185
+ }
2186
+ };
2187
+ }
2068
2188
 
2069
2189
  //#endregion
2070
2190
  //#region src/deployment/recreate-targets.ts
@@ -68211,7 +68331,14 @@ async function destroyCommand(stackArgs, options) {
68211
68331
  ...options.profile && { profile: options.profile }
68212
68332
  });
68213
68333
  setAwsClients(awsClients);
68214
- const unforwardSigterm = forwardSigtermToSigint();
68334
+ const interruptWatch = watchCommandInterrupt({ command: "cdkd destroy" });
68335
+ let unforwardSigterm;
68336
+ try {
68337
+ unforwardSigterm = forwardSigtermToSigint();
68338
+ } catch (error) {
68339
+ interruptWatch.dispose();
68340
+ throw error;
68341
+ }
68215
68342
  try {
68216
68343
  const stateConfig = {
68217
68344
  bucket: stateBucket,
@@ -68271,6 +68398,7 @@ async function destroyCommand(stackArgs, options) {
68271
68398
  let totalErrors = 0;
68272
68399
  let totalSkipped = 0;
68273
68400
  let interrupted = false;
68401
+ const runInterrupted = () => interrupted || interruptWatch.interrupted();
68274
68402
  let stackNames;
68275
68403
  if (options.all) stackNames = candidateStacks.map((s) => s.stackName);
68276
68404
  else if (stackPatterns.length > 0) stackNames = matchStacks(candidateStacks, stackPatterns).map((s) => s.stackName);
@@ -68347,6 +68475,7 @@ async function destroyCommand(stackArgs, options) {
68347
68475
  totalErrors++;
68348
68476
  continue;
68349
68477
  }
68478
+ if (runInterrupted()) break;
68350
68479
  const eventRecorder = startRunRecorder({
68351
68480
  backend: stateBackend,
68352
68481
  stackName,
@@ -68355,7 +68484,7 @@ async function destroyCommand(stackArgs, options) {
68355
68484
  });
68356
68485
  let destroyRunResult = "SUCCEEDED";
68357
68486
  try {
68358
- const result = await withNestedStackContext({
68487
+ const result = await interruptWatch.runStack(() => withNestedStackContext({
68359
68488
  stateBackend,
68360
68489
  lockManager,
68361
68490
  providerRegistry,
@@ -68394,7 +68523,7 @@ async function destroyCommand(stackArgs, options) {
68394
68523
  ...options.resourceWarnAfter?.perTypeMs && { resourceWarnAfterByType: options.resourceWarnAfter.perTypeMs },
68395
68524
  ...options.resourceTimeout?.perTypeMs && { resourceTimeoutByType: options.resourceTimeout.perTypeMs },
68396
68525
  eventRecorder
68397
- }));
68526
+ })));
68398
68527
  totalErrors += result.errorCount;
68399
68528
  totalSkipped += result.skippedCount;
68400
68529
  if (result.interrupted) interrupted = true;
@@ -68421,15 +68550,16 @@ async function destroyCommand(stackArgs, options) {
68421
68550
  await purgeEventsAfterDestroy(new DeploymentEventsReader(stateBackend), stackName, stackTargetRegion, {
68422
68551
  purgeEvents: options.purgeEvents,
68423
68552
  runResult: destroyRunResult,
68424
- interrupted
68553
+ interrupted: runInterrupted()
68425
68554
  }, logger);
68426
- if (interrupted) break;
68555
+ if (runInterrupted()) break;
68427
68556
  }
68428
68557
  if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd destroy' to retry. If the same resource keeps failing, 'cdkd state orphan <stack>' removes the state record without deleting AWS resources.`);
68429
- if (interrupted) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd destroy' to finish.`);
68558
+ if (runInterrupted()) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd destroy' to finish.`);
68430
68559
  if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} cdkd could not address, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). Repair the physicalId in state.json and re-run 'cdkd destroy', or delete the resources by hand and drop the records with 'cdkd state orphan <stack>'.`);
68431
68560
  } finally {
68432
68561
  unforwardSigterm();
68562
+ interruptWatch.dispose();
68433
68563
  awsClients.destroy();
68434
68564
  }
68435
68565
  }
@@ -72997,7 +73127,14 @@ async function stateDestroyCommand(stackArgs, options) {
72997
73127
  registerAllProviders(providerRegistry);
72998
73128
  providerRegistry.setCustomResourceResponseBucket(setup.bucket);
72999
73129
  if (options.allowUnsupportedTypes?.length) providerRegistry.allowUnsupportedTypes(options.allowUnsupportedTypes);
73000
- const unforwardSigterm = forwardSigtermToSigint();
73130
+ const interruptWatch = watchCommandInterrupt({ command: "cdkd state destroy" });
73131
+ let unforwardSigterm;
73132
+ try {
73133
+ unforwardSigterm = forwardSigtermToSigint();
73134
+ } catch (error) {
73135
+ interruptWatch.dispose();
73136
+ throw error;
73137
+ }
73001
73138
  try {
73002
73139
  const stateRefs = await setup.stateBackend.listStacks();
73003
73140
  const knownStackNames = new Set(stateRefs.map((r) => r.stackName));
@@ -73033,6 +73170,7 @@ async function stateDestroyCommand(stackArgs, options) {
73033
73170
  let totalErrors = 0;
73034
73171
  let totalSkipped = 0;
73035
73172
  let interrupted = false;
73173
+ const runInterrupted = () => interrupted || interruptWatch.interrupted();
73036
73174
  for (const stackName of stackNames) {
73037
73175
  const refs = stateRefs.filter((r) => r.stackName === stackName);
73038
73176
  let targets;
@@ -73054,7 +73192,8 @@ async function stateDestroyCommand(stackArgs, options) {
73054
73192
  logger.warn(`No state found for stack ${stackName}${ref.region ? ` in ${ref.region}` : ""}, skipping`);
73055
73193
  continue;
73056
73194
  }
73057
- const result = await withNestedStackContext({
73195
+ if (runInterrupted()) break;
73196
+ const result = await interruptWatch.runStack(() => withNestedStackContext({
73058
73197
  stateBackend: setup.stateBackend,
73059
73198
  lockManager: setup.lockManager,
73060
73199
  providerRegistry,
@@ -73092,19 +73231,20 @@ async function stateDestroyCommand(stackArgs, options) {
73092
73231
  ...options.resourceTimeout?.globalMs !== void 0 && { resourceTimeoutMs: options.resourceTimeout.globalMs },
73093
73232
  ...options.resourceWarnAfter?.perTypeMs && { resourceWarnAfterByType: options.resourceWarnAfter.perTypeMs },
73094
73233
  ...options.resourceTimeout?.perTypeMs && { resourceTimeoutByType: options.resourceTimeout.perTypeMs }
73095
- }));
73234
+ })));
73096
73235
  totalErrors += result.errorCount;
73097
73236
  totalSkipped += result.skippedCount;
73098
73237
  if (result.interrupted) interrupted = true;
73099
- if (interrupted) break;
73238
+ if (runInterrupted()) break;
73100
73239
  }
73101
- if (interrupted) break;
73240
+ if (runInterrupted()) break;
73102
73241
  }
73103
73242
  if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd state destroy' to retry. If the same resource keeps failing, 'cdkd state orphan <stack>' removes the state record without deleting AWS resources.`);
73104
- if (interrupted) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd state destroy' to finish.`);
73243
+ if (runInterrupted()) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd state destroy' to finish.`);
73105
73244
  if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} cdkd could not address, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). Repair the physicalId in state.json and re-run 'cdkd state destroy', or delete the resources by hand and drop the records with 'cdkd state orphan <stack>'.`);
73106
73245
  } finally {
73107
73246
  unforwardSigterm();
73247
+ interruptWatch.dispose();
73108
73248
  setup.dispose();
73109
73249
  }
73110
73250
  }
@@ -87364,4 +87504,4 @@ function buildProgram() {
87364
87504
 
87365
87505
  //#endregion
87366
87506
  export { buildProgram };
87367
- //# sourceMappingURL=program-Bpz-tAA5.js.map
87507
+ //# sourceMappingURL=program-CTreQYc-.js.map