@go-to-k/cdkd 0.280.47 → 0.281.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.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-fs0W4o1b.js";
2
+ import { $ as requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-Bebl98bx.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, 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";
4
- import { t as ASGProvider } from "./asg-provider-CemPPnK2.js";
4
+ import { t as ASGProvider } from "./asg-provider-BSx4Vrth.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";
@@ -591,6 +591,22 @@ const useCdkBootstrapAssetsOption = new Option("--use-cdk-bootstrap-assets", "Pu
591
591
  */
592
592
  const strictGetattOption = new Option("--strict-getatt", "Fail the deploy on ANY Fn::GetAtt that falls back to the physical ID because cdkd cannot construct the attribute (default: warn and use the physical ID, hard-failing only when the fallback is knowably wrong — an *Arn attribute with a non-ARN value or a *Url attribute with a non-http(s) value). Also fails the deploy when a stack Output cannot be resolved (default: warn and store no value).").default(false);
593
593
  /**
594
+ * Issue #1697 — `--no-cfn-fallback` (deploy + diff). By default, a
595
+ * cross-stack reference (`Fn::ImportValue` / `Fn::GetStackOutput`) that is
596
+ * not found in cdkd state falls back to CloudFormation (`ListExports` /
597
+ * `DescribeStacks` outputs) so a cdkd-deployed consumer can reference a
598
+ * producer stack still managed by CloudFormation (`cdk deploy` / raw CFn).
599
+ * The fallback fires only after a cdkd-state miss (cdkd-first precedence),
600
+ * resolves as a WEAK reference (not recorded into `state.imports` /
601
+ * `state.outputReads`; no destroy-time protection on either side), and
602
+ * degrades gracefully when the caller lacks the CloudFormation read
603
+ * permissions (warning + the original not-found error). This flag disables
604
+ * the fallback entirely for users who want cdkd-state-only resolution —
605
+ * e.g. to keep IAM minimal or to keep an export-name typo failing fast
606
+ * instead of accidentally matching an unrelated CloudFormation export.
607
+ */
608
+ const noCfnFallbackOption = new Option("--no-cfn-fallback", "Do not fall back to CloudFormation (ListExports / stack outputs) when an Fn::ImportValue / Fn::GetStackOutput reference is not found in cdkd state (default: fall back, so producers still managed by CloudFormation can be referenced)");
609
+ /**
594
610
  * CDK annotation-message behavior flags (issue #1230, CDK CLI parity).
595
611
  * Shared by `cdkd synth` and `cdkd deploy` — the two commands that fail on
596
612
  * `Annotations.addError` (issue #1228). `--strict` additionally fails when
@@ -622,6 +638,7 @@ const deployOptions = [
622
638
  replaceOption,
623
639
  useCdkBootstrapAssetsOption,
624
640
  strictGetattOption,
641
+ noCfnFallbackOption,
625
642
  ...resourceTimeoutOptions
626
643
  ];
627
644
  /**
@@ -51815,6 +51832,7 @@ async function deployCommand(stacks, options) {
51815
51832
  ...options.skipFinalSnapshot && { skipFinalSnapshot: true },
51816
51833
  finalSnapshotClients: stackAwsClients,
51817
51834
  ...options.strictGetatt && { strictGetAtt: true },
51835
+ ...options.cfnFallback === false && { cfnFallback: false },
51818
51836
  captureObservedState: resolveCaptureObservedState(options.captureObservedState),
51819
51837
  ...options.resourceWarnAfter?.globalMs !== void 0 && { resourceWarnAfterMs: options.resourceWarnAfter.globalMs },
51820
51838
  ...options.resourceTimeout?.globalMs !== void 0 && { resourceTimeoutMs: options.resourceTimeout.globalMs },
@@ -52876,8 +52894,8 @@ async function loadStateOrEmpty(stackName, region, stateBackend) {
52876
52894
  * Pure with respect to AWS state mutation — only reads state (the resolver
52877
52895
  * may read producer state for `Fn::ImportValue` / `Fn::GetStackOutput`).
52878
52896
  */
52879
- async function computeStackDiff(currentState, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties) {
52880
- const intrinsicResolver = new IntrinsicFunctionResolver(region);
52897
+ async function computeStackDiff(currentState, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties, cfnFallback) {
52898
+ const intrinsicResolver = new IntrinsicFunctionResolver(region, { cfnFallback: cfnFallback ?? true });
52881
52899
  let mergedParameters = parameters;
52882
52900
  let parametersBound = false;
52883
52901
  try {
@@ -52939,10 +52957,10 @@ async function computeStackDiff(currentState, template, region, stackName, state
52939
52957
  * unresolvable case), while resolvable parameters (the freshly-deployed tree)
52940
52958
  * get exact scalar values.
52941
52959
  */
52942
- async function resolveChildStackParameters(parentStackRow, parentTemplate, parentState, region, parentStackName, stateBackend, parentParameters) {
52960
+ async function resolveChildStackParameters(parentStackRow, parentTemplate, parentState, region, parentStackName, stateBackend, parentParameters, cfnFallback) {
52943
52961
  const rawParams = parentStackRow.Properties?.["Parameters"];
52944
52962
  if (!rawParams || typeof rawParams !== "object" || Array.isArray(rawParams)) return {};
52945
- const resolver = new IntrinsicFunctionResolver(region);
52963
+ const resolver = new IntrinsicFunctionResolver(region, { cfnFallback: cfnFallback ?? true });
52946
52964
  const resolved = {};
52947
52965
  for (const [name, value] of Object.entries(rawParams)) try {
52948
52966
  resolved[name] = await resolver.resolve(value, {
@@ -52977,13 +52995,13 @@ async function resolveChildStackParameters(parentStackRow, parentTemplate, paren
52977
52995
  * fail at deploy time.
52978
52996
  */
52979
52997
  async function buildDiffTree(args) {
52980
- const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parameters, canonicalizeProperties, assetRedirect } = args;
52998
+ const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parameters, canonicalizeProperties, assetRedirect, cfnFallback } = args;
52981
52999
  const state = await loadStateOrEmpty(stackName, region, stateBackend);
52982
53000
  const node = {
52983
53001
  stackName,
52984
53002
  displayName,
52985
53003
  region,
52986
- changes: await computeStackDiff(state, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties),
53004
+ changes: await computeStackDiff(state, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties, cfnFallback),
52987
53005
  ccApiRoutes: collectCcApiRoutes(template, state),
52988
53006
  children: []
52989
53007
  };
@@ -52998,7 +53016,7 @@ async function buildDiffTree(args) {
52998
53016
  const childTemplate = readNestedTemplate(childTemplatePath);
52999
53017
  if (assetRedirect) rewriteTemplateAssetReferences(childTemplate, assetRedirect);
53000
53018
  const grandchildTemplates = indexNestedChildTemplates(childTemplate, childTemplatePath);
53001
- const childParameters = await resolveChildStackParameters(resource, template, state, region, stackName, stateBackend, parameters);
53019
+ const childParameters = await resolveChildStackParameters(resource, template, state, region, stackName, stateBackend, parameters, cfnFallback);
53002
53020
  node.children.push(await buildDiffTree({
53003
53021
  stackName: childStackName,
53004
53022
  displayName: childStackName,
@@ -53010,7 +53028,8 @@ async function buildDiffTree(args) {
53010
53028
  diffCalculator,
53011
53029
  parameters: childParameters,
53012
53030
  ...canonicalizeProperties && { canonicalizeProperties },
53013
- ...assetRedirect && { assetRedirect }
53031
+ ...assetRedirect && { assetRedirect },
53032
+ ...cfnFallback !== void 0 && { cfnFallback }
53014
53033
  }));
53015
53034
  }
53016
53035
  for (const [logicalId, resource] of Object.entries(state.resources)) {
@@ -53397,7 +53416,8 @@ async function diffCommand(stacks, options) {
53397
53416
  stateBackend,
53398
53417
  diffCalculator,
53399
53418
  canonicalizeProperties,
53400
- ...assetRedirect && { assetRedirect }
53419
+ ...assetRedirect && { assetRedirect },
53420
+ ...options.cfnFallback === false && { cfnFallback: false }
53401
53421
  }));
53402
53422
  }
53403
53423
  if (options.json) process.stdout.write(`${JSON.stringify(trees.map(diffTreeToJson), null, 2)}\n`);
@@ -53417,7 +53437,7 @@ async function diffCommand(stacks, options) {
53417
53437
  * Create diff command
53418
53438
  */
53419
53439
  function createDiffCommand() {
53420
- const cmd = new Command("diff").description("Show difference between current state and desired state").argument("[stacks...]", "Stack name(s) to diff. Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*').").option("--all", "Diff all stacks", false).option("--recursive", "Recurse into each AWS::CloudFormation::Stack row and diff every nested-stack child against its own deployed state (DFS order). Default is non-recursive, matching cdk diff.", false).option("--fail", "Exit with code 1 when any change is detected (matches cdk diff --fail). With --recursive, considers the whole nested-stack tree.", false).option("--json", "Output the diff as JSON (nested tree shape when combined with --recursive)", false).addOption(useCdkBootstrapAssetsOption).action(withErrorHandling(diffCommand));
53440
+ const cmd = new Command("diff").description("Show difference between current state and desired state").argument("[stacks...]", "Stack name(s) to diff. Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*').").option("--all", "Diff all stacks", false).option("--recursive", "Recurse into each AWS::CloudFormation::Stack row and diff every nested-stack child against its own deployed state (DFS order). Default is non-recursive, matching cdk diff.", false).option("--fail", "Exit with code 1 when any change is detected (matches cdk diff --fail). With --recursive, considers the whole nested-stack tree.", false).option("--json", "Output the diff as JSON (nested tree shape when combined with --recursive)", false).addOption(useCdkBootstrapAssetsOption).addOption(noCfnFallbackOption).action(withErrorHandling(diffCommand));
53421
53441
  [
53422
53442
  ...commonOptions,
53423
53443
  ...appOptions,
@@ -56509,8 +56529,8 @@ async function exportCommand(stackArg, options) {
56509
56529
  const crossRefs = scanCrossStackReferences(allSynthStacks, resolvedStackName);
56510
56530
  if (crossRefs.length > 0) {
56511
56531
  const lines = crossRefs.map((r) => ` ${r.consumerStackName} → ${resolvedStackName}.${r.outputName} at ${r.location}`);
56512
- if (options.strictCrossStack) throw new Error(`Refusing to export: ${crossRefs.length} cross-stack reference(s) to ${resolvedStackName} found in sibling stacks. After migration, those references will break (cdkd's Fn::GetStackOutput reads cdkd state; the migrated stack's outputs live in CFn). Migrate consumers first, or remove the references, or drop --strict-cross-stack to proceed with a warning:\n` + lines.join("\n"));
56513
- logger.warn(`${crossRefs.length} cross-stack reference(s) to '${resolvedStackName}' from sibling stacks. These will break the next time those stacks deploy via cdkd (cdkd's Fn::GetStackOutput resolver reads cdkd state; the migrated stack's outputs are now in CFn). Plan multi-stack migrations from the leaves up.`);
56532
+ if (options.strictCrossStack) throw new Error(`Refusing to export: ${crossRefs.length} cross-stack reference(s) to ${resolvedStackName} found in sibling stacks. After migration, those references depend on the CloudFormation fallback (the migrated stack's outputs live in CFn; cdkd resolves them via DescribeStacks after the cdkd-state miss), and consumers deployed with --no-cfn-fallback break. Migrate consumers first, or remove the references, or drop --strict-cross-stack to proceed with a warning:\n` + lines.join("\n"));
56533
+ logger.warn(`${crossRefs.length} cross-stack reference(s) to '${resolvedStackName}' from sibling stacks. After the migration those consumers resolve this stack's outputs via the CloudFormation fallback (weak reference; the outputs now live in CFn) they break only when deployed with --no-cfn-fallback. Migrate consumers from the leaves up if you rely on cdkd-state-only resolution.`);
56514
56534
  for (const line of lines) logger.warn(line);
56515
56535
  }
56516
56536
  }
@@ -56594,8 +56614,8 @@ async function exportCommand(stackArg, options) {
56594
56614
  const crossRefs = scanCrossStackReferences(allSynthStacks, resolvedStackName);
56595
56615
  if (crossRefs.length > 0) {
56596
56616
  const lines = crossRefs.map((r) => ` ${r.consumerStackName} → ${resolvedStackName}.${r.outputName} at ${r.location}`);
56597
- if (options.strictCrossStack) throw new Error(`Refusing to export: ${crossRefs.length} cross-stack reference(s) to ${resolvedStackName} found in sibling stacks. After migration, those references will break (cdkd's Fn::GetStackOutput reads cdkd state; the migrated stack's outputs live in CFn). Migrate consumers first, or remove the references, or drop --strict-cross-stack to proceed with a warning:\n` + lines.join("\n"));
56598
- logger.warn(`${crossRefs.length} cross-stack reference(s) to '${resolvedStackName}' from sibling stacks. These will break the next time those stacks deploy via cdkd (cdkd's Fn::GetStackOutput resolver reads cdkd state; the migrated stack's outputs are now in CFn). Plan multi-stack migrations from the leaves up.`);
56617
+ if (options.strictCrossStack) throw new Error(`Refusing to export: ${crossRefs.length} cross-stack reference(s) to ${resolvedStackName} found in sibling stacks. After migration, those references depend on the CloudFormation fallback (the migrated stack's outputs live in CFn; cdkd resolves them via DescribeStacks after the cdkd-state miss), and consumers deployed with --no-cfn-fallback break. Migrate consumers first, or remove the references, or drop --strict-cross-stack to proceed with a warning:\n` + lines.join("\n"));
56618
+ logger.warn(`${crossRefs.length} cross-stack reference(s) to '${resolvedStackName}' from sibling stacks. After the migration those consumers resolve this stack's outputs via the CloudFormation fallback (weak reference; the outputs now live in CFn) they break only when deployed with --no-cfn-fallback. Migrate consumers from the leaves up if you rely on cdkd-state-only resolution.`);
56599
56619
  for (const line of lines) logger.warn(line);
56600
56620
  }
56601
56621
  }
@@ -58503,7 +58523,7 @@ async function confirmPrompt$3(prompt) {
58503
58523
  }
58504
58524
  }
58505
58525
  function createExportCommand() {
58506
- const cmd = new Command("export").description("Hand a cdkd-managed stack over to CloudFormation via CFn IMPORT (changeset). AWS resources are unchanged; cdkd state for the stack is deleted on success. Mirror of `cdkd import` (AWS → cdkd) in the reverse direction (cdkd → CFn). Accepts JSON and YAML templates (YAML via a CFn-aware codec that preserves !Ref / !GetAtt / !Sub shorthand). Aborts if any resource is not CFn-importable.").argument("[stack]", "Stack name to export (auto-detected for single-stack apps)").option("--cfn-stack-name <name>", "Name of the destination CloudFormation stack for the root stack. Defaults to the cdkd stack name (or the cdkd2cfnStackName mapping when the name contains '~'). For per-nested-child overrides, use --cfn-child-stack-name.").option("--cfn-child-stack-name <pair...>", "Per-nested-child CFn stack-name override. Repeatable. Format: '<cdkdName>=<cfnName>' (e.g. --cfn-child-stack-name 'MyApp~Database=my-app-db'). The cdkd stack name for a nested child is '<parent>~<childLogicalId>' (v6 state-key form). Without an override the CFn name is derived by replacing '~' with '-'. Only consulted when the exported stack tree contains nested children; ignored for flat stacks.").option("--template <path>", "Path to a pre-rendered CloudFormation template (JSON or YAML — format auto-detected). Skips synth.").option("--stack-region <region>", "Region of the cdkd state record to operate on. Required when the same stack name has state in multiple regions.").option("--dry-run", "Print the import plan without creating a changeset.", false).option("--accept-transient-context", "Allow CLI -c key=value overrides at export time even though they are not persisted to cdk.json / cdk.context.json (default: refuse). When set, the user is responsible for passing the same -c flags to every future cdk deploy.", false).option("--include-non-importable", "Run a 2-phase migration when the stack contains non-importable resources (Custom::*). Phase 1 imports the importable resources; phase 2 CFn-CREATEs the non-importable ones, which re-invokes each Custom Resource's onCreate handler. Make sure onCreate is idempotent before enabling.", false).option("--parameter <key=value...>", "CFn template Parameter override, repeatable. Required when the synthesized template has Parameters without Default values; otherwise overrides the template's default value. Format: --parameter Key=Value.").option("--strict-cross-stack", "Refuse to export when sibling cdkd stacks in the same CDK app reference the exporting stack via Fn::GetStackOutput. Without the flag, cdkd warns but proceeds — the user is expected to migrate the consumer stacks in a follow-up.", false).option("--no-recreate-import-unsupported", "Block instead of auto-handling resource types AWS does NOT support in IMPORT changesets (currently only AWS::ApiGatewayV2::Stage, emitted by CDK HttpApi). Default behavior: cdkd skips these from phase 1, deletes the AWS-side resource between phases, and lets CFn re-CREATE in phase 2 (brief unavailability window). With this flag, the export aborts with a clear error instead.").action(withErrorHandling(exportCommand));
58526
+ const cmd = new Command("export").description("Hand a cdkd-managed stack over to CloudFormation via CFn IMPORT (changeset). AWS resources are unchanged; cdkd state for the stack is deleted on success. Mirror of `cdkd import` (AWS → cdkd) in the reverse direction (cdkd → CFn). Accepts JSON and YAML templates (YAML via a CFn-aware codec that preserves !Ref / !GetAtt / !Sub shorthand). Aborts if any resource is not CFn-importable.").argument("[stack]", "Stack name to export (auto-detected for single-stack apps)").option("--cfn-stack-name <name>", "Name of the destination CloudFormation stack for the root stack. Defaults to the cdkd stack name (or the cdkd2cfnStackName mapping when the name contains '~'). For per-nested-child overrides, use --cfn-child-stack-name.").option("--cfn-child-stack-name <pair...>", "Per-nested-child CFn stack-name override. Repeatable. Format: '<cdkdName>=<cfnName>' (e.g. --cfn-child-stack-name 'MyApp~Database=my-app-db'). The cdkd stack name for a nested child is '<parent>~<childLogicalId>' (v6 state-key form). Without an override the CFn name is derived by replacing '~' with '-'. Only consulted when the exported stack tree contains nested children; ignored for flat stacks.").option("--template <path>", "Path to a pre-rendered CloudFormation template (JSON or YAML — format auto-detected). Skips synth.").option("--stack-region <region>", "Region of the cdkd state record to operate on. Required when the same stack name has state in multiple regions.").option("--dry-run", "Print the import plan without creating a changeset.", false).option("--accept-transient-context", "Allow CLI -c key=value overrides at export time even though they are not persisted to cdk.json / cdk.context.json (default: refuse). When set, the user is responsible for passing the same -c flags to every future cdk deploy.", false).option("--include-non-importable", "Run a 2-phase migration when the stack contains non-importable resources (Custom::*). Phase 1 imports the importable resources; phase 2 CFn-CREATEs the non-importable ones, which re-invokes each Custom Resource's onCreate handler. Make sure onCreate is idempotent before enabling.", false).option("--parameter <key=value...>", "CFn template Parameter override, repeatable. Required when the synthesized template has Parameters without Default values; otherwise overrides the template's default value. Format: --parameter Key=Value.").option("--strict-cross-stack", "Refuse to export when sibling cdkd stacks in the same CDK app reference the exporting stack via Fn::GetStackOutput. Without the flag, cdkd warns and proceeds — the consumers keep resolving via the CloudFormation fallback (weak reference) unless they deploy with --no-cfn-fallback.", false).option("--no-recreate-import-unsupported", "Block instead of auto-handling resource types AWS does NOT support in IMPORT changesets (currently only AWS::ApiGatewayV2::Stage, emitted by CDK HttpApi). Default behavior: cdkd skips these from phase 1, deletes the AWS-side resource between phases, and lets CFn re-CREATE in phase 2 (brief unavailability window). With this flag, the export aborts with a clear error instead.").action(withErrorHandling(exportCommand));
58507
58527
  [
58508
58528
  ...commonOptions,
58509
58529
  ...appOptions,
@@ -72329,7 +72349,7 @@ function createMigrateCommand() {
72329
72349
  */
72330
72350
  function buildProgram() {
72331
72351
  const program = new Command();
72332
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.47");
72352
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.0");
72333
72353
  program.hook("preAction", (_thisCommand, actionCommand) => {
72334
72354
  const { profile } = actionCommand.optsWithGlobals();
72335
72355
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;