@go-to-k/cdkd 0.219.7 → 0.219.9
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/cli.js +52 -5
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-BWfGeCMs.js → deploy-engine-DVP4vDXG.js} +134 -2
- package/dist/deploy-engine-DVP4vDXG.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BWfGeCMs.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { A as withErrorHandling, B as generateResourceNameWithFallback, C as StackHasActiveImportsError, F as getLiveRenderer, H as withStackName, I as PATTERN_B_NAME_PROPERTIES, L as PATTERN_B_RESOURCE_TYPES, M as getLogger, P as runStackBuffered, S as ResourceUpdateNotSupportedError, V as withSkipPrefix, _ as MissingCdkCliError, a as assertRegionMatch, b as ProvisioningError, f as LocalInvokeBuildError$1, i as resolveExplicitPhysicalId, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as matchesCdkPath, o as disableInstanceApiTermination, p as LocalMigrateError, r as normalizeAwsTagsToCfn, s as isTerminationProtectionPropagationError, t as CDK_PATH_TAG, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError, z as generateResourceName } from "./import-helpers-wLipXr5g.js";
|
|
3
3
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-pjPwZz1r.js";
|
|
4
|
-
import { A as WorkGraph, B as resolveCaptureObservedState, C as DagBuilder, D as shouldRetainResource, E as S3StateBackend, F as runDockerStreaming, G as CFN_TEMPLATE_BODY_LIMIT, H as resolveStateBucketWithDefault, I as Synthesizer, J as findLargeInlineResources, K as CFN_TEMPLATE_URL_LIMIT, L as getDefaultStateBucketName, M as formatDockerLoginError, N as getDockerCmd, O as AssetPublisher, P as runDockerForeground, Q as resolveBucketRegion, R as getLegacyStateBucketName, S as DiffCalculator, T as LockManager, U as resolveStateBucketWithDefaultAndSource, V as resolveSkipPrefix, W as warnDeprecatedNoPrefixCliFlag, X as AssemblyReader, Y as uploadCfnTemplate, _ as ProviderRegistry, a as withRetry, b as IntrinsicFunctionResolver, c as formatResourceLine, d as gray, f as green, g as collectInlinePolicyNamesManagedBySiblings, h as IAMRoleProvider, i as withResourceDeadline, j as buildDockerImage, k as stringifyValue, l as bold, m as yellow, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as isRetryableTransientError, p as red, q as MIGRATE_TMP_PREFIX, r as DeployEngine, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as cyan, v as findActionableSilentDrops, w as TemplateParser, x as applyRoleArnIfSet, y as CloudControlProvider, z as resolveApp } from "./deploy-engine-
|
|
4
|
+
import { A as WorkGraph, B as resolveCaptureObservedState, C as DagBuilder, D as shouldRetainResource, E as S3StateBackend, F as runDockerStreaming, G as CFN_TEMPLATE_BODY_LIMIT, H as resolveStateBucketWithDefault, I as Synthesizer, J as findLargeInlineResources, K as CFN_TEMPLATE_URL_LIMIT, L as getDefaultStateBucketName, M as formatDockerLoginError, N as getDockerCmd, O as AssetPublisher, P as runDockerForeground, Q as resolveBucketRegion, R as getLegacyStateBucketName, S as DiffCalculator, T as LockManager, U as resolveStateBucketWithDefaultAndSource, V as resolveSkipPrefix, W as warnDeprecatedNoPrefixCliFlag, X as AssemblyReader, Y as uploadCfnTemplate, _ as ProviderRegistry, a as withRetry, b as IntrinsicFunctionResolver, c as formatResourceLine, d as gray, f as green, g as collectInlinePolicyNamesManagedBySiblings, h as IAMRoleProvider, i as withResourceDeadline, j as buildDockerImage, k as stringifyValue, l as bold, m as yellow, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as isRetryableTransientError, p as red, q as MIGRATE_TMP_PREFIX, r as DeployEngine, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as cyan, v as findActionableSilentDrops, w as TemplateParser, x as applyRoleArnIfSet, y as CloudControlProvider, z as resolveApp } from "./deploy-engine-DVP4vDXG.js";
|
|
5
5
|
import { t as ASGProvider } from "./asg-provider-B_hrCxRx.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
@@ -33762,8 +33762,20 @@ function countProtectedResources(state) {
|
|
|
33762
33762
|
* - Switches `process.env.AWS_REGION` for the duration of the destroy when
|
|
33763
33763
|
* the stack's recorded region differs from `baseRegion`. Restored in the
|
|
33764
33764
|
* `finally` block.
|
|
33765
|
+
* - Persists state incrementally during the delete loop (issue #804):
|
|
33766
|
+
* each successfully deleted resource is removed from the state object
|
|
33767
|
+
* and the trimmed state is written back to S3, mirroring deploy's
|
|
33768
|
+
* `saveStateAfterResource`. An interrupted destroy therefore leaves a
|
|
33769
|
+
* state file listing only resources that still exist, so a re-run does
|
|
33770
|
+
* not replay deletes against already-deleted resources. Persist
|
|
33771
|
+
* failures are logged and never fail the destroy. Every persisted
|
|
33772
|
+
* destroy snapshot CLEARS `outputs` (and drops `imports` / `outputReads`)
|
|
33773
|
+
* so a partial-destroy state never advertises an export / import whose
|
|
33774
|
+
* backing resource is gone — the in-memory `state` the strong-ref check
|
|
33775
|
+
* above reads is untouched.
|
|
33765
33776
|
* - On full success, deletes the state file. On any failure, the state
|
|
33766
|
-
* file is preserved
|
|
33777
|
+
* file is preserved (trimmed to the remaining resources, outputs/imports
|
|
33778
|
+
* cleared) so the user can retry.
|
|
33767
33779
|
*/
|
|
33768
33780
|
async function runDestroyForStack(stackName, state, ctx) {
|
|
33769
33781
|
const logger = getLogger();
|
|
@@ -33843,6 +33855,27 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
33843
33855
|
throw new StackHasActiveImportsError(stackName, regionForState, consumers);
|
|
33844
33856
|
}
|
|
33845
33857
|
}
|
|
33858
|
+
const remainingResources = { ...state.resources };
|
|
33859
|
+
const buildDestroySnapshot = () => {
|
|
33860
|
+
const { imports: _imports, outputReads: _outputReads, ...rest } = state;
|
|
33861
|
+
return {
|
|
33862
|
+
...rest,
|
|
33863
|
+
resources: { ...remainingResources },
|
|
33864
|
+
outputs: {},
|
|
33865
|
+
lastModified: Date.now()
|
|
33866
|
+
};
|
|
33867
|
+
};
|
|
33868
|
+
let saveChain = Promise.resolve();
|
|
33869
|
+
const persistStateAfterDelete = (logicalId) => {
|
|
33870
|
+
saveChain = saveChain.then(async () => {
|
|
33871
|
+
try {
|
|
33872
|
+
await ctx.stateBackend.saveState(stackName, regionForState, buildDestroySnapshot());
|
|
33873
|
+
logger.debug(`State persisted after deleting ${logicalId}`);
|
|
33874
|
+
} catch (error) {
|
|
33875
|
+
logger.warn(`Failed to persist state after deleting ${logicalId} (continuing): ${error instanceof Error ? error.message : String(error)}`);
|
|
33876
|
+
}
|
|
33877
|
+
});
|
|
33878
|
+
};
|
|
33846
33879
|
const renderer = getLiveRenderer();
|
|
33847
33880
|
renderer.start();
|
|
33848
33881
|
try {
|
|
@@ -33946,12 +33979,16 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
33946
33979
|
renderer.removeTask(logicalId);
|
|
33947
33980
|
logger.info(` ${formatResourceLine("deleted", logicalId, resource.resourceType)}`);
|
|
33948
33981
|
result.deletedCount++;
|
|
33982
|
+
delete remainingResources[logicalId];
|
|
33983
|
+
persistStateAfterDelete(logicalId);
|
|
33949
33984
|
} catch (error) {
|
|
33950
33985
|
renderer.removeTask(logicalId);
|
|
33951
33986
|
const msg = error instanceof Error ? error.message : String(error);
|
|
33952
33987
|
if (msg.includes("does not exist") || msg.includes("not found") || msg.includes("No policy found") || msg.includes("NoSuchEntity") || msg.includes("NotFoundException")) {
|
|
33953
33988
|
logger.debug(` ${logicalId} already deleted, removing from state`);
|
|
33954
33989
|
result.deletedCount++;
|
|
33990
|
+
delete remainingResources[logicalId];
|
|
33991
|
+
persistStateAfterDelete(logicalId);
|
|
33955
33992
|
} else if (error instanceof ResourceTimeoutError) {
|
|
33956
33993
|
const wrapped = new ProvisioningError(error.message, resource.resourceType, logicalId, resource.physicalId, error);
|
|
33957
33994
|
logger.error(` ✗ Failed to delete ${logicalId}:`, wrapped.message);
|
|
@@ -33966,16 +34003,25 @@ async function runDestroyForStack(stackName, state, ctx) {
|
|
|
33966
34003
|
});
|
|
33967
34004
|
await Promise.all(deletePromises);
|
|
33968
34005
|
}
|
|
34006
|
+
await saveChain;
|
|
33969
34007
|
if (result.errorCount === 0) {
|
|
33970
34008
|
await ctx.stateBackend.deleteState(stackName, regionForState);
|
|
33971
34009
|
logger.debug("State deleted");
|
|
33972
34010
|
if (ctx.exportIndexStore) await ctx.exportIndexStore.removeStack(stackName, regionForState);
|
|
33973
|
-
} else
|
|
34011
|
+
} else {
|
|
34012
|
+
try {
|
|
34013
|
+
await ctx.stateBackend.saveState(stackName, regionForState, buildDestroySnapshot());
|
|
34014
|
+
} catch (error) {
|
|
34015
|
+
logger.warn(`Failed to persist remaining state after partial destroy: ${error instanceof Error ? error.message : String(error)}. The state file may still list already-deleted resources; a re-run resolves them idempotently.`);
|
|
34016
|
+
}
|
|
34017
|
+
logger.warn(`${result.errorCount} resource(s) failed to delete. State preserved.`);
|
|
34018
|
+
}
|
|
33974
34019
|
const retainedSuffix = result.retainedCount > 0 ? `, ${result.retainedCount} retained` : "";
|
|
33975
34020
|
if (result.errorCount === 0) logger.info(`\n${green("✓")} ${bold(`Stack ${stackName} destroyed`)} (${green(result.deletedCount)} deleted${retainedSuffix}, ${result.errorCount} errors)`);
|
|
33976
34021
|
else logger.warn(`\n${yellow("⚠")} ${bold(`Stack ${stackName} partially destroyed`)} (${green(result.deletedCount)} deleted${retainedSuffix}, ${red(result.errorCount)} errors). State preserved — re-run 'cdkd destroy' / 'cdkd state destroy' to clean up.`);
|
|
33977
34022
|
} finally {
|
|
33978
34023
|
renderer.stop();
|
|
34024
|
+
await saveChain;
|
|
33979
34025
|
logger.debug("Releasing lock...");
|
|
33980
34026
|
await ctx.lockManager.releaseLock(stackName, regionForState);
|
|
33981
34027
|
if (destroyAwsClients) {
|
|
@@ -36341,12 +36387,13 @@ function renderChangeLines(changes, logFn, ccApiRoutes) {
|
|
|
36341
36387
|
logFn(` [~] ${logicalId} (${change.resourceType})${annotateRouting(logicalId)}`);
|
|
36342
36388
|
if (change.propertyChanges && change.propertyChanges.length > 0) for (const propChange of change.propertyChanges) {
|
|
36343
36389
|
const requiresReplace = propChange.requiresReplacement ? " [requires replacement]" : "";
|
|
36390
|
+
const propagated = propChange.replacementPropagated ? " [replacement propagated]" : "";
|
|
36344
36391
|
const oldFiltered = stripUnchangedValues(propChange.oldValue, propChange.newValue);
|
|
36345
36392
|
const newFiltered = stripUnchangedValues(propChange.newValue, propChange.oldValue);
|
|
36346
36393
|
const indent = " ";
|
|
36347
36394
|
const oldStr = (JSON.stringify(oldFiltered, null, 2) ?? "undefined").replace(/\n/g, `\n${indent}`);
|
|
36348
36395
|
const newStr = (JSON.stringify(newFiltered, null, 2) ?? "undefined").replace(/\n/g, `\n${indent}`);
|
|
36349
|
-
logFn(` - ${propChange.path}:${requiresReplace}`);
|
|
36396
|
+
logFn(` - ${propChange.path}:${requiresReplace}${propagated}`);
|
|
36350
36397
|
logFn(` old: ${oldStr}`);
|
|
36351
36398
|
logFn(` new: ${newStr}`);
|
|
36352
36399
|
}
|
|
@@ -52867,7 +52914,7 @@ function reorderArgs(argv) {
|
|
|
52867
52914
|
async function main() {
|
|
52868
52915
|
installPipeCloseHandler();
|
|
52869
52916
|
const program = new Command();
|
|
52870
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.219.
|
|
52917
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.219.9");
|
|
52871
52918
|
program.addCommand(createBootstrapCommand());
|
|
52872
52919
|
program.addCommand(createSynthCommand());
|
|
52873
52920
|
program.addCommand(createListCommand());
|