@go-to-k/cdkd 0.230.19 → 0.230.20

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/README.md CHANGED
@@ -23,6 +23,27 @@ Drop-in CDK CLI for existing CDK apps — faster deploys via AWS SDK instead of
23
23
 
24
24
  Numbers below are deploy-phase only (CDK app synthesis is identical between cdkd and AWS CDK — both run the same user code through `aws-cdk-lib`'s synthesizer — so synth time is excluded from the speedup calculation).
25
25
 
26
+ ### vs CloudFormation Express mode — faster than CloudFormation's own fast-deploy option
27
+
28
+ CloudFormation's [Express mode](https://aws.amazon.com/about-aws/whats-new/2026/06/aws-cloudformation-cdk/) is a fast-deploy option that skips resource stabilization waits, similar in spirit to cdkd's `--no-wait`. Even so, cdkd is faster than Express on nearly every stack, and with `--no-wait` it pulls dramatically ahead on stacks dominated by async resources.
29
+
30
+ | Stack | Normal (CFn) | Express | cdkd | cdkd `--no-wait` |
31
+ | --- | ---: | ---: | ---: | ---: |
32
+ | VPC + Lambda + SQS + CloudFront | 562 | 366 | 197 | **40** |
33
+ | DynamoDB | 34 | 34 | 19 | 15 |
34
+ | DynamoDB + KMS | 71 | 55 | 27 | 27 |
35
+ | EC2 | 44 | 31 | 27 | 26 |
36
+ | Lambda | 55 | 34 | 23 | 22 |
37
+ | S3 | 39 | 22 | 23 | 24 |
38
+ | SQS | 83 | 22 | **9** | 9 |
39
+ | SQS + CloudWatch | 87 | 44 | 30 | 31 |
40
+
41
+ Best of 3 runs, deploy-phase only, seconds, `us-west-2`. The `VPC + Lambda + SQS + CloudFront` stack is 1 VPC (2 AZs, NAT Gateway, public + private subnets) + VPC Lambda + Lambda Function URL + CloudFront Distribution + SQS + EventSourceMapping + Consumer Lambda.
42
+
43
+ - **~1.5–2x faster than Express on most stacks** — e.g. SQS finishes in 9s vs Express's 22s (~2.4x).
44
+ - **Async-heavy stacks are where the gap explodes.** On the VPC + CloudFront stack, `cdkd --no-wait` finishes in 40s vs Express's 366s (~9x) — cdkd returns as soon as each create call returns, leaving CloudFront propagation and NAT Gateway stabilization to complete in the background.
45
+ - **S3 is the one case where Express edges cdkd's default** (22s vs 23s). On a near-instant single-resource stack there is little left to parallelize, and `--no-wait` makes no difference there.
46
+
26
47
  ### SDK Provider path — **5.5x faster** (17.0s vs 94.4s)
27
48
 
28
49
  Stack: S3 Bucket, DynamoDB Table, SQS Queue, SNS Topic, SSM Parameter (5 independent resources, fully parallelized by cdkd's DAG scheduler).
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { A as withErrorHandling, B as generateResourceName, C as StackHasActiveImportsError, F as getLiveRenderer, H as withSkipPrefix, I as PATTERN_B_NAME_OPTIONS, L as PATTERN_B_NAME_PROPERTIES, M as getLogger, P as runStackBuffered, R as PATTERN_B_RESOURCE_TYPES, S as ResourceUpdateNotSupportedError, U as withStackName, V as generateResourceNameWithFallback, _ 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 } from "./import-helpers-DayvBD4T.js";
3
3
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-pjPwZz1r.js";
4
- import { $ as warnDeprecatedNoPrefixCliFlag, A as LockManager, B as runDockerForeground, C as findActionableSilentDrops, D as DiffCalculator, E as applyRoleArnIfSet, F as stringifyValue, G as synthesisStatusMessage, H as AssetManifestLoader, I as WorkGraph, J as resolveApp, K as getDefaultStateBucketName, L as buildDockerImage, M as rebuildClientForBucketRegion, N as shouldRetainResource, O as DagBuilder, P as AssetPublisher, Q as resolveStateBucketWithDefaultAndSource, R as formatDockerLoginError, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as getDockerImageBySourceHash, V as runDockerStreaming, W as Synthesizer, X as resolveSkipPrefix, Y as resolveCaptureObservedState, Z as resolveStateBucketWithDefault, _ as green, a as withRetry, at as AssemblyReader, b as IAMRoleProvider, c as computeImplicitDeleteEdges, d as isStatefulRecreateTargetSync, et as CFN_TEMPLATE_BODY_LIMIT, f as renderStatefulReason, g as gray, h as cyan, i as withResourceDeadline, it as uploadCfnTemplate, j as S3StateBackend, k as TemplateParser, l as extractDeploymentEventError, m as bold, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as MIGRATE_TMP_PREFIX, o as isRetryableTransientError, p as formatResourceLine, q as getLegacyStateBucketName, r as DeployEngine, rt as findLargeInlineResources, s as IMPLICIT_DELETE_DEPENDENCIES, st as resolveBucketRegion, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as CFN_TEMPLATE_URL_LIMIT, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, v as red, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, y as yellow, z as getDockerCmd } from "./deploy-engine-Bdy5xKSQ.js";
4
+ import { $ as warnDeprecatedNoPrefixCliFlag, A as LockManager, B as runDockerForeground, C as findActionableSilentDrops, D as DiffCalculator, E as applyRoleArnIfSet, F as stringifyValue, G as synthesisStatusMessage, H as AssetManifestLoader, I as WorkGraph, J as resolveApp, K as getDefaultStateBucketName, L as buildDockerImage, M as rebuildClientForBucketRegion, N as shouldRetainResource, O as DagBuilder, P as AssetPublisher, Q as resolveStateBucketWithDefaultAndSource, R as formatDockerLoginError, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as getDockerImageBySourceHash, V as runDockerStreaming, W as Synthesizer, X as resolveSkipPrefix, Y as resolveCaptureObservedState, Z as resolveStateBucketWithDefault, _ as green, a as withRetry, at as AssemblyReader, b as IAMRoleProvider, c as computeImplicitDeleteEdges, d as isStatefulRecreateTargetSync, et as CFN_TEMPLATE_BODY_LIMIT, f as renderStatefulReason, g as gray, h as cyan, i as withResourceDeadline, it as uploadCfnTemplate, j as S3StateBackend, k as TemplateParser, l as extractDeploymentEventError, m as bold, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as MIGRATE_TMP_PREFIX, o as isRetryableTransientError, p as formatResourceLine, q as getLegacyStateBucketName, r as DeployEngine, rt as findLargeInlineResources, s as IMPLICIT_DELETE_DEPENDENCIES, st as resolveBucketRegion, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as CFN_TEMPLATE_URL_LIMIT, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, v as red, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, y as yellow, z as getDockerCmd } from "./deploy-engine-B0o5NN21.js";
5
5
  import { t as ASGProvider } from "./asg-provider-Dgj3loIG.js";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  import { createHash, randomBytes, randomUUID } from "node:crypto";
@@ -1445,7 +1445,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1445
1445
  const FLUSH_EVENT_THRESHOLD = 50;
1446
1446
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1447
1447
  function getCdkdVersion() {
1448
- return "0.230.19";
1448
+ return "0.230.20";
1449
1449
  }
1450
1450
  /**
1451
1451
  * Generate a time-sortable unique run id, e.g.
@@ -55380,7 +55380,7 @@ function reorderArgs(argv) {
55380
55380
  async function main() {
55381
55381
  installPipeCloseHandler();
55382
55382
  const program = new Command();
55383
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.19");
55383
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.20");
55384
55384
  program.addCommand(createBootstrapCommand());
55385
55385
  program.addCommand(createSynthCommand());
55386
55386
  program.addCommand(createListCommand());
@@ -12535,6 +12535,7 @@ const RETRYABLE_ERROR_MESSAGE_PATTERNS = [
12535
12535
  "Invalid value for the parameter Policy",
12536
12536
  "required permissions for: ENHANCED_MONITORING",
12537
12537
  "Caught ServiceAccessDeniedException",
12538
+ "permissions required to assume the role",
12538
12539
  "conflicting conditional operation",
12539
12540
  "scheduled for deletion",
12540
12541
  "Cannot access stream",
@@ -12742,32 +12743,9 @@ const DEFAULT_RESOURCE_WARN_AFTER_MS = 300 * 1e3;
12742
12743
  * explicitly because the Custom Resource provider's polling cap is 1h.
12743
12744
  */
12744
12745
  const DEFAULT_RESOURCE_TIMEOUT_MS = 1800 * 1e3;
12745
- /**
12746
- * Deploy engine orchestrates the entire deployment process
12747
- *
12748
- * Responsibilities:
12749
- * 1. Acquire stack lock
12750
- * 2. Load current state
12751
- * 3. Calculate diff
12752
- * 4. Validate resource types
12753
- * 5. Execute deployment in DAG order
12754
- * 6. Save new state
12755
- * 7. Release lock
12756
- *
12757
- * Rollback mechanism:
12758
- * - Tracks completed operations during deployment
12759
- * - On failure, rolls back in reverse order (best-effort)
12760
- * - Supports --no-rollback flag to skip rollback (saves partial state and fails)
12761
- * - CREATE → delete the newly created resource
12762
- * - UPDATE → restore previous properties
12763
- * - DELETE → cannot rollback (log warning)
12764
- */
12765
- /**
12766
- * Error thrown when deployment is interrupted by SIGINT
12767
- */
12768
12746
  var InterruptedError = class extends Error {
12769
- constructor() {
12770
- super("Deployment interrupted by user (Ctrl+C)");
12747
+ constructor(reason = "user") {
12748
+ super(reason === "user" ? "Deployment interrupted by user (Ctrl+C)" : "Deployment aborted after another resource failed");
12771
12749
  this.name = "InterruptedError";
12772
12750
  }
12773
12751
  };
@@ -12836,6 +12814,13 @@ var DeployEngine = class {
12836
12814
  resolver;
12837
12815
  interrupted = false;
12838
12816
  /**
12817
+ * Why `interrupted` was set — first cause wins. `'user'` = SIGINT;
12818
+ * `'sibling-failure'` = a resource failed and the remaining work is being
12819
+ * cancelled. Drives the {@link InterruptedError} message so cancelled
12820
+ * siblings don't misreport a Ctrl+C nobody pressed.
12821
+ */
12822
+ interruptCause = null;
12823
+ /**
12839
12824
  * In-flight `provider.readCurrentState` promises kicked off after a
12840
12825
  * successful CREATE / UPDATE. The deploy critical path does NOT
12841
12826
  * `await` these; instead they're drained at the end of `doDeploy`
@@ -13126,11 +13111,13 @@ var DeployEngine = class {
13126
13111
  const renderer = getLiveRenderer();
13127
13112
  renderer.start();
13128
13113
  this.interrupted = false;
13114
+ this.interruptCause = null;
13129
13115
  const sigintHandler = () => {
13130
13116
  renderer.printAbove(() => {
13131
13117
  process.stderr.write("\nInterrupted — saving partial state after current operations complete...\n");
13132
13118
  });
13133
13119
  this.interrupted = true;
13120
+ this.interruptCause ??= "user";
13134
13121
  };
13135
13122
  process.on("SIGINT", sigintHandler);
13136
13123
  try {
@@ -13350,6 +13337,7 @@ var DeployEngine = class {
13350
13337
  await this.provisionResource(logicalId, change, newResources, stackName, template, parameterValues, conditions, actualCounts, progress);
13351
13338
  } catch (provisionError) {
13352
13339
  this.interrupted = true;
13340
+ this.interruptCause ??= "sibling-failure";
13353
13341
  throw provisionError;
13354
13342
  }
13355
13343
  completedOperations.push({
@@ -13366,7 +13354,7 @@ var DeployEngine = class {
13366
13354
  } finally {
13367
13355
  await saveChain;
13368
13356
  }
13369
- if (this.interrupted && this.hasPending(createUpdateExecutor)) throw new InterruptedError();
13357
+ if (this.interrupted && this.hasPending(createUpdateExecutor)) throw new InterruptedError(this.interruptCause ?? "user");
13370
13358
  }
13371
13359
  if (deleteChanges.size > 0) {
13372
13360
  this.logger.info(`${red("Deleting")} ${red(deleteChanges.size)} resource(s)`);
@@ -13387,6 +13375,7 @@ var DeployEngine = class {
13387
13375
  await this.provisionResource(logicalId, change, newResources, stackName, template, parameterValues, conditions, actualCounts, progress);
13388
13376
  } catch (provisionError) {
13389
13377
  this.interrupted = true;
13378
+ this.interruptCause ??= "sibling-failure";
13390
13379
  throw provisionError;
13391
13380
  }
13392
13381
  completedOperations.push({
@@ -13401,7 +13390,7 @@ var DeployEngine = class {
13401
13390
  } finally {
13402
13391
  await saveChain;
13403
13392
  }
13404
- if (this.interrupted && this.hasPending(deleteExecutor)) throw new InterruptedError();
13393
+ if (this.interrupted && this.hasPending(deleteExecutor)) throw new InterruptedError(this.interruptCause ?? "user");
13405
13394
  }
13406
13395
  } catch (error) {
13407
13396
  try {
@@ -14145,7 +14134,7 @@ var DeployEngine = class {
14145
14134
  ...initialDelayMs !== void 0 && { initialDelayMs },
14146
14135
  logger: this.logger,
14147
14136
  isInterrupted: () => this.interrupted,
14148
- onInterrupted: () => new InterruptedError()
14137
+ onInterrupted: () => new InterruptedError(this.interruptCause ?? "user")
14149
14138
  });
14150
14139
  }
14151
14140
  /**
@@ -14188,4 +14177,4 @@ var DeployEngine = class {
14188
14177
 
14189
14178
  //#endregion
14190
14179
  export { warnDeprecatedNoPrefixCliFlag as $, LockManager as A, runDockerForeground as B, findActionableSilentDrops as C, DiffCalculator as D, applyRoleArnIfSet as E, stringifyValue as F, synthesisStatusMessage as G, AssetManifestLoader as H, WorkGraph as I, resolveApp as J, getDefaultStateBucketName as K, buildDockerImage as L, rebuildClientForBucketRegion as M, shouldRetainResource as N, DagBuilder as O, AssetPublisher as P, resolveStateBucketWithDefaultAndSource as Q, formatDockerLoginError as R, ProviderRegistry as S, IntrinsicFunctionResolver as T, getDockerImageBySourceHash as U, runDockerStreaming as V, Synthesizer as W, resolveSkipPrefix as X, resolveCaptureObservedState as Y, resolveStateBucketWithDefault as Z, green as _, withRetry as a, AssemblyReader as at, IAMRoleProvider as b, computeImplicitDeleteEdges as c, isStatefulRecreateTargetSync as d, CFN_TEMPLATE_BODY_LIMIT as et, renderStatefulReason as f, gray as g, cyan as h, withResourceDeadline as i, uploadCfnTemplate as it, S3StateBackend as j, TemplateParser as k, extractDeploymentEventError as l, bold as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, MIGRATE_TMP_PREFIX as nt, isRetryableTransientError as o, clearBucketRegionCache as ot, formatResourceLine as p, getLegacyStateBucketName as q, DeployEngine as r, findLargeInlineResources as rt, IMPLICIT_DELETE_DEPENDENCIES as s, resolveBucketRegion as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, CFN_TEMPLATE_URL_LIMIT as tt, MULTI_REGION_RECREATE_BLOCKED_TYPES as u, red as v, CloudControlProvider as w, collectInlinePolicyNamesManagedBySiblings as x, yellow as y, getDockerCmd as z };
14191
- //# sourceMappingURL=deploy-engine-Bdy5xKSQ.js.map
14180
+ //# sourceMappingURL=deploy-engine-B0o5NN21.js.map