@go-to-k/cdkd 0.146.1 → 0.147.1

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
@@ -581,11 +581,16 @@ The Custom Resource Lambda must be idempotent AND must POST to
581
581
  `event.ResponseURL` per the cfn-response protocol. Without the flag,
582
582
  the command refuses to proceed and the user is expected to destroy
583
583
  the offending resources (or accept abandoning them) first. Nested
584
- `AWS::CloudFormation::Stack` references block in this release
585
- [#464](https://github.com/go-to-k/cdkd/issues/464) will lift the
586
- restriction. Fresh `cdkd deploy` of nested stacks works via
587
- [#459](https://github.com/go-to-k/cdkd/issues/459); only the
588
- cdkd CFn migration direction is deferred.
584
+ `AWS::CloudFormation::Stack` rows have partial support as of
585
+ [#464](https://github.com/go-to-k/cdkd/issues/464) PR B1: `cdkd export`
586
+ recursively walks the cdkd state tree, validates every parent → child
587
+ link, and surfaces the full leaf-first migration scope to the user;
588
+ the CFn-side `--include-nested-stacks` IMPORT changeset submission
589
+ itself is deferred to PR B2, so the command warns on `--dry-run` /
590
+ hard-errors on real run with a clear pointer + workaround (keep on
591
+ cdkd, or destroy children leaf-first via `cdkd state destroy <child>`
592
+ and re-export the flattened parent). Fresh `cdkd deploy` of nested
593
+ stacks works via [#459](https://github.com/go-to-k/cdkd/issues/459).
589
594
 
590
595
  ```bash
591
596
  cdkd export MyStack # confirmation prompt; CFn stack name = cdkd stack name
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { _ as withSkipPrefix, a as runDockerStreaming, c as getLogger, d as getLiveRenderer, f as PATTERN_B_NAME_PROPERTIES, g as generateResourceNameWithFallback, h as generateResourceName, i as runDockerForeground, n as formatDockerLoginError, p as PATTERN_B_RESOURCE_TYPES, r as getDockerCmd, u as runStackBuffered, v as withStackName } from "./docker-cmd-EtWSTAje.js";
3
- import { A as AssetPublisher, B as resolveStateBucketWithDefault, C as applyRoleArnIfSet, D as LockManager, E as TemplateParser, F as getDefaultStateBucketName, G as MIGRATE_TMP_PREFIX, H as warnDeprecatedNoPrefixCliFlag, I as getLegacyStateBucketName, J as AssemblyReader, K as findLargeInlineResources, L as resolveApp, M as WorkGraph, N as buildDockerImage, O as S3StateBackend, P as Synthesizer, Q as CdkdError, R as resolveCaptureObservedState, S as IntrinsicFunctionResolver, T as DagBuilder, U as CFN_TEMPLATE_BODY_LIMIT, V as resolveStateBucketWithDefaultAndSource, W as CFN_TEMPLATE_URL_LIMIT, X as resolveBucketRegion, _ as normalizeAwsTagsToCfn, _t as normalizeAwsError, a as withRetry, at as MissingCdkCliError, b as CloudControlProvider, c as cyan, ct as ResourceTimeoutError, d as red, dt as StackHasActiveImportsError, f as yellow, ft as StackTerminationProtectionError, g as matchesCdkPath, h as CDK_PATH_TAG, i as withResourceDeadline, j as stringifyValue, k as shouldRetainResource, l as gray, lt as ResourceUpdateNotSupportedError, m as collectInlinePolicyNamesManagedBySiblings, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as LocalMigrateError, o as IMPLICIT_DELETE_DEPENDENCIES, ot as PartialFailureError, p as IAMRoleProvider, q as uploadCfnTemplate, r as DeployEngine, rt as LocalStartServiceError, s as bold, st as ProvisioningError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as LocalInvokeBuildError, u as green, ut as RouteDiscoveryError, v as resolveExplicitPhysicalId, vt as withErrorHandling, w as DiffCalculator, x as assertRegionMatch, y as ProviderRegistry, z as resolveSkipPrefix } from "./deploy-engine-DjnWyAAc.js";
3
+ import { A as AssetPublisher, B as resolveStateBucketWithDefault, C as applyRoleArnIfSet, D as LockManager, E as TemplateParser, F as getDefaultStateBucketName, G as MIGRATE_TMP_PREFIX, H as warnDeprecatedNoPrefixCliFlag, I as getLegacyStateBucketName, J as AssemblyReader, K as findLargeInlineResources, L as resolveApp, M as WorkGraph, N as buildDockerImage, O as S3StateBackend, P as Synthesizer, Q as CdkdError, R as resolveCaptureObservedState, S as IntrinsicFunctionResolver, T as DagBuilder, U as CFN_TEMPLATE_BODY_LIMIT, V as resolveStateBucketWithDefaultAndSource, W as CFN_TEMPLATE_URL_LIMIT, X as resolveBucketRegion, _ as normalizeAwsTagsToCfn, a as withRetry, at as MissingCdkCliError, b as CloudControlProvider, c as cyan, ct as ProvisioningError, d as red, dt as RouteDiscoveryError, f as yellow, ft as StackHasActiveImportsError, g as matchesCdkPath, h as CDK_PATH_TAG, i as withResourceDeadline, j as stringifyValue, k as shouldRetainResource, l as gray, lt as ResourceTimeoutError, m as collectInlinePolicyNamesManagedBySiblings, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as LocalMigrateError, o as IMPLICIT_DELETE_DEPENDENCIES, ot as NestedStackChildDirectDestroyError, p as IAMRoleProvider, pt as StackTerminationProtectionError, q as uploadCfnTemplate, r as DeployEngine, rt as LocalStartServiceError, s as bold, st as PartialFailureError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as LocalInvokeBuildError, u as green, ut as ResourceUpdateNotSupportedError, v as resolveExplicitPhysicalId, vt as normalizeAwsError, w as DiffCalculator, x as assertRegionMatch, y as ProviderRegistry, yt as withErrorHandling, z as resolveSkipPrefix } from "./deploy-engine-CRxNgcqJ.js";
4
4
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-BF03Alpe.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, createHmac, createPublicKey, createVerify, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
@@ -33592,6 +33592,7 @@ async function destroyCommand(stackArgs, options) {
33592
33592
  }
33593
33593
  } else throw new Error("Could not determine which stacks belong to this app. Specify stack names explicitly, use --all, or ensure --app / cdk.json is configured.");
33594
33594
  const stackPatterns = stackArgs.length > 0 ? stackArgs : options.stack ? [options.stack] : [];
33595
+ let totalErrors = 0;
33595
33596
  let stackNames;
33596
33597
  if (options.all) stackNames = candidateStacks.map((s) => s.stackName);
33597
33598
  else if (stackPatterns.length > 0) stackNames = matchStacks(candidateStacks, stackPatterns).map((s) => s.stackName);
@@ -33601,6 +33602,21 @@ async function destroyCommand(stackArgs, options) {
33601
33602
  return;
33602
33603
  } else throw new Error(`Multiple stacks found: ${candidateStacks.map(describeStack).join(", ")}. Specify stack name(s) or use --all`);
33603
33604
  if (stackNames.length === 0) {
33605
+ if (stackPatterns.length > 0) {
33606
+ const allStateNamesSet = new Set(allStateRefs.map((r) => r.stackName));
33607
+ for (const pattern of stackPatterns) {
33608
+ if (pattern.includes("*") || pattern.includes("?") || pattern.includes("/")) continue;
33609
+ if (!allStateNamesSet.has(pattern)) continue;
33610
+ const refRegion = allStateRefs.find((r) => r.stackName === pattern)?.region ?? region;
33611
+ const stateOnlyResult = await stateBackend.getState(pattern, refRegion);
33612
+ if (stateOnlyResult?.state.parentStack) {
33613
+ const err = new NestedStackChildDirectDestroyError(pattern, stateOnlyResult.state.parentStack, stateOnlyResult.state.parentLogicalId);
33614
+ logger.error(` ✗ ${err.message}`);
33615
+ totalErrors++;
33616
+ }
33617
+ }
33618
+ 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.`);
33619
+ }
33604
33620
  logger.info("No matching stacks found in state");
33605
33621
  return;
33606
33622
  }
@@ -33612,7 +33628,6 @@ async function destroyCommand(stackArgs, options) {
33612
33628
  arr.push(ref);
33613
33629
  stateRefsByName.set(ref.stackName, arr);
33614
33630
  }
33615
- let totalErrors = 0;
33616
33631
  for (const stackName of stackNames) {
33617
33632
  logger.info(`\nPreparing to destroy stack: ${stackName}`);
33618
33633
  const refs = stateRefsByName.get(stackName) ?? [];
@@ -33643,6 +33658,12 @@ async function destroyCommand(stackArgs, options) {
33643
33658
  logger.warn(`No state found for stack ${stackName}, skipping`);
33644
33659
  continue;
33645
33660
  }
33661
+ if (stateResult.state.parentStack) {
33662
+ const err = new NestedStackChildDirectDestroyError(stackName, stateResult.state.parentStack, stateResult.state.parentLogicalId);
33663
+ logger.error(` ✗ ${err.message}`);
33664
+ totalErrors++;
33665
+ continue;
33666
+ }
33646
33667
  const result = await withNestedStackContext({
33647
33668
  stateBackend,
33648
33669
  lockManager,
@@ -54035,11 +54056,6 @@ function createLocalCommand() {
54035
54056
  *
54036
54057
  * - `AWS::CDK::Metadata` is a CDK sentinel; not a real AWS resource and
54037
54058
  * CFn refuses to import it.
54038
- * - `AWS::CloudFormation::Stack` is a nested stack reference. Fresh
54039
- * `cdkd deploy` of nested stacks IS supported (issue #459), but
54040
- * moving an existing nested-stack hierarchy from cdkd back into
54041
- * CloudFormation via `cdkd export` is deferred to the
54042
- * [#464](https://github.com/go-to-k/cdkd/issues/464) follow-up.
54043
54059
  * - `AWS::CloudFormation::CustomResource` is the CFn resource type CDK
54044
54060
  * emits for `new cdk.CustomResource(...)` when no `resourceType` is
54045
54061
  * passed. Functionally identical to `Custom::*` — Lambda-backed,
@@ -54049,11 +54065,19 @@ function createLocalCommand() {
54049
54065
  * custom-resource state — invocation history lives in the provider
54050
54066
  * Lambda, not in AWS resource state, so there is nothing to import.
54051
54067
  *
54068
+ * `AWS::CloudFormation::Stack` is **intentionally NOT in this set** — it is
54069
+ * handled by a dedicated branch in {@link buildImportPlan} that routes the
54070
+ * row through the nested-stack tree walker (issue
54071
+ * [#464](https://github.com/go-to-k/cdkd/issues/464) PR B1). The CFn-side
54072
+ * `--include-nested-stacks` IMPORT changeset submission is tracked under
54073
+ * PR B2 — until that lands, the orchestrator hard-errors at submission
54074
+ * time with a clear pointer.
54075
+ *
54052
54076
  * The list is intentionally narrow. Other resource types CFn may not yet
54053
54077
  * support for import are surfaced as errors by the CreateChangeSet call
54054
54078
  * itself; we do not try to maintain a closed allowlist here.
54055
54079
  */
54056
- const NEVER_IMPORTABLE_TYPES = new Set(["AWS::CDK::Metadata", "AWS::CloudFormation::Stack"]);
54080
+ const NEVER_IMPORTABLE_TYPES = new Set(["AWS::CDK::Metadata"]);
54057
54081
  function isNeverImportableType(resourceType) {
54058
54082
  if (NEVER_IMPORTABLE_TYPES.has(resourceType)) return true;
54059
54083
  if (isCustomResourceType(resourceType)) return true;
@@ -54324,12 +54348,24 @@ async function exportCommand(stackArg, options) {
54324
54348
  if (!await lockManager.acquireLock(resolvedStackName, targetRegion, owner, "export")) throw new Error(`Could not acquire lock for stack '${resolvedStackName}' (${targetRegion}) — another cdkd process holds it. Wait for it to finish, or run 'cdkd force-unlock ${resolvedStackName}' if you are certain no other process is active.`);
54325
54349
  }
54326
54350
  try {
54327
- const { phase1Imports, phase2Creates, recreateBeforePhase2, blocked } = await buildImportPlan(state, template, awsClients.cloudFormation, { recreateImportUnsupported: options.recreateImportUnsupported });
54351
+ const { phase1Imports, phase2Creates, recreateBeforePhase2, nestedStackRows, blocked } = await buildImportPlan(state, template, awsClients.cloudFormation, resolvedStackName, { recreateImportUnsupported: options.recreateImportUnsupported });
54328
54352
  if (blocked.length > 0) {
54329
54353
  logger.error("The following resources block migration:");
54330
54354
  for (const b of blocked) logger.error(` - ${b.logicalId} (${b.resourceType}): ${b.reason}`);
54331
54355
  throw new Error(`${blocked.length} resource(s) block migration. Either destroy them first (cdkd destroy / cdkd state destroy cherry-picked), or remove them from the CDK app and re-synthesize.`);
54332
54356
  }
54357
+ if (nestedStackRows.length > 0) {
54358
+ const leafFirst = flattenCdkdStateTreeLeafFirst(await buildCdkdStateStackTree(resolvedStackName, targetRegion, stateBackend, state));
54359
+ logger.info(`Stack '${resolvedStackName}' contains ${nestedStackRows.length} top-level nested stack row(s); cdkd state tree spans ${leafFirst.length} stack(s) total (leaf-first migration order):`);
54360
+ for (const node of leafFirst) logger.info(` - cdkd/${node.stackName}/${node.region}/state.json`);
54361
+ const deferralMessage = `cdkd export does not yet submit nested-stack trees to CloudFormation (${nestedStackRows.length} top-level nested-stack row(s) detected; ${leafFirst.length} cdkd state record(s) in the tree). Recursive --include-nested-stacks IMPORT changeset submission is tracked under issue #464 PR B2. Workarounds until PR B2 ships:\n - Keep the stack on cdkd (recommended — nested-stack deploy / destroy / drift already work via the SDK provider path).\n - OR destroy the nested children first via 'cdkd state destroy <child>' (leaf-first), then re-run 'cdkd export <parent>' against the flattened parent.`;
54362
+ if (options.dryRun) {
54363
+ logger.warn(deferralMessage);
54364
+ logger.info("--dry-run: no CloudFormation changeset will be created.");
54365
+ return;
54366
+ }
54367
+ throw new Error(deferralMessage);
54368
+ }
54333
54369
  if (phase1Imports.length === 0 && phase2Creates.length === 0 && recreateBeforePhase2.length === 0) {
54334
54370
  logger.warn("No resources to migrate — cdkd state is empty.");
54335
54371
  return;
@@ -54496,10 +54532,11 @@ async function assertCfnStackAbsent(cfnClient, stackName) {
54496
54532
  * `AWS::CloudFormation::Stack` (nested stacks) is intentionally NOT in
54497
54533
  * this set: CFn would CREATE a duplicate nested stack rather than adopt
54498
54534
  * the existing one, which would conflict with whatever the cdkd state
54499
- * thought it owned. Fresh `cdkd deploy` of nested stacks is supported
54500
- * via the recursive `NestedStackProvider` (#459), but `cdkd export`
54501
- * adoption back into CloudFormation is deferred to the
54502
- * [#464](https://github.com/go-to-k/cdkd/issues/464) follow-up.
54535
+ * thought it owned. Nested-stack rows are handled by a dedicated branch
54536
+ * in {@link buildImportPlan} (issue
54537
+ * [#464](https://github.com/go-to-k/cdkd/issues/464) PR B1) that routes
54538
+ * the row to the cdkd-state-side tree walker. The CFn-side
54539
+ * `--include-nested-stacks` IMPORT changeset submission lands in PR B2.
54503
54540
  *
54504
54541
  * Exported for unit testing.
54505
54542
  */
@@ -54507,6 +54544,86 @@ function isPhase2CreatableType(resourceType) {
54507
54544
  return isCustomResourceType(resourceType);
54508
54545
  }
54509
54546
  /**
54547
+ * Recursively load the cdkd-state tree rooted at `(rootStackName, region)`.
54548
+ * For every `AWS::CloudFormation::Stack` row in each level's
54549
+ * `state.resources`, derives the child's v6 state key
54550
+ * (`<parent>~<childLogicalId>`) and loads the child state file from S3,
54551
+ * then recurses.
54552
+ *
54553
+ * Throws if any expected child state file is missing — the parent's state
54554
+ * lists a nested-stack row but the child's `cdkd/<parent>~<child>/<region>/state.json`
54555
+ * does not exist. That state-tree inconsistency must be resolved before
54556
+ * any export attempt (typically via `cdkd state orphan <parent>` and a
54557
+ * full re-deploy, or by completing whatever partial operation left the
54558
+ * tree torn).
54559
+ *
54560
+ * Children at each level are loaded sequentially today (not `Promise.all`)
54561
+ * because the failure-mode shape is "fail fast on the first missing
54562
+ * child" rather than "list every missing child" — a single missing-child
54563
+ * pointer is enough for the user to identify the root cause without
54564
+ * fanning out N parallel `getState` calls on a torn tree. PR B2 may
54565
+ * revisit this once the per-child template-fetch / preprocessing /
54566
+ * upload pass dominates the wall-clock cost.
54567
+ *
54568
+ * Exported so the walker can be unit-tested independently of the orchestrator.
54569
+ *
54570
+ * Callers that already loaded the root state record up front (the typical
54571
+ * orchestrator shape — `exportCommand` always reads it via
54572
+ * `stateBackend.getState` before plan-build) can pass it via the optional
54573
+ * `prefetchedRootState` argument to save one S3 round-trip per export run.
54574
+ * Otherwise the walker fetches it itself, matching the standalone-use
54575
+ * signature.
54576
+ */
54577
+ async function buildCdkdStateStackTree(rootStackName, region, stateBackend, prefetchedRootState) {
54578
+ let rootState;
54579
+ if (prefetchedRootState !== void 0) rootState = prefetchedRootState;
54580
+ else {
54581
+ const rootResult = await stateBackend.getState(rootStackName, region);
54582
+ if (!rootResult) throw new Error(`No cdkd state found for stack '${rootStackName}' (${region}). Cannot build nested-stack tree.`);
54583
+ rootState = rootResult.state;
54584
+ }
54585
+ return walkCdkdStateStackTree(rootStackName, region, rootState, stateBackend);
54586
+ }
54587
+ async function walkCdkdStateStackTree(stackName, region, state, stateBackend) {
54588
+ const nestedChildren = /* @__PURE__ */ new Map();
54589
+ for (const [logicalId, resource] of Object.entries(state.resources)) {
54590
+ if (resource.resourceType !== "AWS::CloudFormation::Stack") continue;
54591
+ const childStackName = `${stackName}~${logicalId}`;
54592
+ const childResult = await stateBackend.getState(childStackName, region);
54593
+ if (!childResult) throw new Error(`cdkd state is missing nested-child '${childStackName}' (${region}). Parent stack '${stackName}' lists '${logicalId}' as an ${NESTED_STACK_RESOURCE_TYPE} row but no child state file exists at 'cdkd/${childStackName}/${region}/state.json'. The cdkd state tree is inconsistent — re-deploy the parent stack to refresh, or run 'cdkd state orphan ${stackName}' and re-import.`);
54594
+ if (childResult.state.region !== void 0 && childResult.state.region !== region) throw new Error(`cdkd state region mismatch: nested-child '${childStackName}' has state.region='${childResult.state.region}' but its parent '${stackName}' is being walked against region='${region}'. AWS does not support cross-region nested stacks; the state tree appears corrupt — re-deploy the parent stack to refresh.`);
54595
+ nestedChildren.set(logicalId, await walkCdkdStateStackTree(childStackName, region, childResult.state, stateBackend));
54596
+ }
54597
+ return {
54598
+ stackName,
54599
+ region,
54600
+ state,
54601
+ nestedChildren
54602
+ };
54603
+ }
54604
+ /**
54605
+ * Flatten a {@link CdkdStateStackTree} into a depth-first list of
54606
+ * `(stackName, region)` pairs in **leaf-first** order — same order PR B2's
54607
+ * state-cleanup pass will use to delete each adopted stack's cdkd state
54608
+ * after the CFn-side IMPORT succeeds (so a mid-walk failure leaves the
54609
+ * earlier parent's state intact for retry).
54610
+ *
54611
+ * Exported so callers (orchestrator user-facing summary, unit tests) can
54612
+ * iterate the tree in the same order without re-implementing the walk.
54613
+ */
54614
+ function flattenCdkdStateTreeLeafFirst(tree) {
54615
+ const out = [];
54616
+ walk(tree);
54617
+ return out;
54618
+ function walk(node) {
54619
+ for (const child of node.nestedChildren.values()) walk(child);
54620
+ out.push({
54621
+ stackName: node.stackName,
54622
+ region: node.region
54623
+ });
54624
+ }
54625
+ }
54626
+ /**
54510
54627
  * Build the import plan from cdkd state + the synthesized template.
54511
54628
  *
54512
54629
  * Classifies every template resource into one of:
@@ -54522,14 +54639,22 @@ function isPhase2CreatableType(resourceType) {
54522
54639
  * phases so CFn's phase-2 CREATE doesn't collide. When the user
54523
54640
  * passes `--no-recreate-import-unsupported`, these are moved to
54524
54641
  * `blocked` instead.
54642
+ * - `nestedStackRows`: `AWS::CloudFormation::Stack` rows in the parent
54643
+ * template. Surfaced separately because they are handled by the
54644
+ * nested-stack tree walker, not the per-resource IMPORT path
54645
+ * (issue [#464](https://github.com/go-to-k/cdkd/issues/464) PR B1 + PR B2).
54646
+ * The orchestrator currently hard-errors when any are present —
54647
+ * CFn-side `--include-nested-stacks` IMPORT changeset submission
54648
+ * lands in PR B2.
54525
54649
  * - `blocked`: anything else. A non-empty `blocked` aborts the run.
54526
54650
  */
54527
- async function buildImportPlan(state, template, cfnClient, options = { recreateImportUnsupported: true }) {
54651
+ async function buildImportPlan(state, template, cfnClient, parentStackName, options = { recreateImportUnsupported: true }) {
54528
54652
  const templateResources = template["Resources"];
54529
54653
  if (!templateResources || typeof templateResources !== "object" || Array.isArray(templateResources)) throw new Error("Template has no Resources section.");
54530
54654
  const phase1Imports = [];
54531
54655
  const phase2Creates = [];
54532
54656
  const recreateBeforePhase2 = [];
54657
+ const nestedStackRows = [];
54533
54658
  const blocked = [];
54534
54659
  const identifierCache = /* @__PURE__ */ new Map();
54535
54660
  for (const [logicalId, raw] of Object.entries(templateResources)) {
@@ -54537,6 +54662,22 @@ async function buildImportPlan(state, template, cfnClient, options = { recreateI
54537
54662
  const resourceType = raw.Type ?? "";
54538
54663
  if (!resourceType) continue;
54539
54664
  if (resourceType === "AWS::CDK::Metadata") continue;
54665
+ if (resourceType === "AWS::CloudFormation::Stack") {
54666
+ const parentRow = state.resources[logicalId];
54667
+ if (!parentRow || parentRow.resourceType !== "AWS::CloudFormation::Stack") {
54668
+ blocked.push({
54669
+ logicalId,
54670
+ resourceType,
54671
+ reason: `template has AWS::CloudFormation::Stack row '${logicalId}' but cdkd state has no matching nested-stack entry on parent '${parentStackName}'. Re-deploy or re-import the parent stack to refresh state.`
54672
+ });
54673
+ continue;
54674
+ }
54675
+ nestedStackRows.push({
54676
+ logicalId,
54677
+ childStackName: `${parentStackName}~${logicalId}`
54678
+ });
54679
+ continue;
54680
+ }
54540
54681
  if (isNeverImportableType(resourceType)) {
54541
54682
  if (isPhase2CreatableType(resourceType)) phase2Creates.push({
54542
54683
  logicalId,
@@ -54595,6 +54736,7 @@ async function buildImportPlan(state, template, cfnClient, options = { recreateI
54595
54736
  phase1Imports,
54596
54737
  phase2Creates,
54597
54738
  recreateBeforePhase2,
54739
+ nestedStackRows,
54598
54740
  blocked
54599
54741
  };
54600
54742
  }
@@ -56472,7 +56614,7 @@ function reorderArgs(argv) {
56472
56614
  */
56473
56615
  async function main() {
56474
56616
  const program = new Command();
56475
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.146.1");
56617
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.147.1");
56476
56618
  program.addCommand(createBootstrapCommand());
56477
56619
  program.addCommand(createSynthCommand());
56478
56620
  program.addCommand(createListCommand());