@go-to-k/cdkd 0.280.47 → 0.281.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/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-CGL3Vw1P.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-DYdmsCfd.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
  /**
@@ -10710,6 +10727,7 @@ var LambdaUrlProvider = class {
10710
10727
  this.logger.debug(`Creating Lambda URL ${logicalId}`);
10711
10728
  const targetFunctionArn = properties["TargetFunctionArn"];
10712
10729
  if (!targetFunctionArn) throw new ProvisioningError(`TargetFunctionArn is required for Lambda URL ${logicalId}`, resourceType, logicalId);
10730
+ if (context?.replayingState === true && properties["AuthType"] === void 0) this.logger.warn(`Lambda URL ${logicalId} is being restored from a cdkd state record that carries no AuthType, so cdkd cannot vouch for the auth type the URL had. Creating it with the default (NONE), which makes the function URL PUBLIC. Verify the URL's auth type after the rollback completes and set 'authType' explicitly in your CDK code if it should be AWS_IAM.`);
10713
10731
  const authType = requireConfigString(properties["AuthType"], "NONE", "AWS::Lambda::Url AuthType", replayWarn(this.logger, context));
10714
10732
  try {
10715
10733
  const cors = properties["Cors"];
@@ -10759,6 +10777,12 @@ var LambdaUrlProvider = class {
10759
10777
  } });
10760
10778
  const previousAuthType = previousProperties["AuthType"];
10761
10779
  const authType = authTypeUnusable ? typeof previousAuthType === "string" && previousAuthType.trim() !== "" ? previousAuthType : void 0 : requestedAuthType;
10780
+ let effectiveProperties;
10781
+ if (authTypeUnusable) {
10782
+ effectiveProperties = { ...properties };
10783
+ if (authType === void 0) delete effectiveProperties["AuthType"];
10784
+ else effectiveProperties["AuthType"] = authType;
10785
+ }
10762
10786
  const updateParams = {
10763
10787
  FunctionName: physicalId,
10764
10788
  ...authType !== void 0 && { AuthType: authType }
@@ -10779,7 +10803,8 @@ var LambdaUrlProvider = class {
10779
10803
  attributes: {
10780
10804
  FunctionUrl: response.FunctionUrl,
10781
10805
  FunctionArn: response.FunctionArn
10782
- }
10806
+ },
10807
+ ...effectiveProperties && { effectiveProperties }
10783
10808
  };
10784
10809
  } catch (error) {
10785
10810
  const cause = error instanceof Error ? error : void 0;
@@ -13604,12 +13629,18 @@ var DynamoDBGlobalTableProvider = class {
13604
13629
  };
13605
13630
  const diagnostics = [];
13606
13631
  if (billingMode === "PROVISIONED") createParams.ProvisionedThroughput = derivePerCallProvisionedThroughput(properties, currentRegion, "min", diagnostics);
13632
+ let effectiveProperties;
13607
13633
  const streamSpecInput = properties["StreamSpecification"];
13608
13634
  const needsStream = replicas.some((r) => r["Region"] !== currentRegion) || replicas.length > 1;
13609
13635
  if (streamSpecInput != null) {
13610
13636
  let streamViewType;
13637
+ let streamSpecSubstituted = false;
13611
13638
  try {
13612
- streamViewType = readConfigString(streamSpecInput, "StreamViewType", "NEW_AND_OLD_IMAGES", "AWS::DynamoDB::GlobalTable StreamSpecification", replayWarn(this.logger, context));
13639
+ const replayDowngrade = replayWarn(this.logger, context).onUnusable;
13640
+ streamViewType = readConfigString(streamSpecInput, "StreamViewType", "NEW_AND_OLD_IMAGES", "AWS::DynamoDB::GlobalTable StreamSpecification", replayDowngrade ? { onUnusable: (message) => {
13641
+ streamSpecSubstituted = true;
13642
+ replayDowngrade(message);
13643
+ } } : {});
13613
13644
  } catch (error) {
13614
13645
  throw new ProvisioningError(error instanceof Error ? error.message : String(error), resourceType, logicalId, void 0, error instanceof Error ? error : void 0);
13615
13646
  }
@@ -13617,6 +13648,10 @@ var DynamoDBGlobalTableProvider = class {
13617
13648
  StreamEnabled: true,
13618
13649
  StreamViewType: streamViewType
13619
13650
  };
13651
+ if (streamSpecSubstituted) effectiveProperties = {
13652
+ ...properties,
13653
+ StreamSpecification: { StreamViewType: streamViewType }
13654
+ };
13620
13655
  } else if (needsStream) {
13621
13656
  this.logger.info(`Auto-enabling streams (NEW_AND_OLD_IMAGES) on ${logicalId} — required for cross-region replication`);
13622
13657
  createParams.StreamSpecification = {
@@ -13703,7 +13738,8 @@ var DynamoDBGlobalTableProvider = class {
13703
13738
  TableId: tableInfo.tableId,
13704
13739
  StreamArn: tableInfo.streamArn,
13705
13740
  TableName: tableName
13706
- }
13741
+ },
13742
+ ...effectiveProperties && { effectiveProperties }
13707
13743
  };
13708
13744
  } catch (wiringError) {
13709
13745
  this.logger.warn(`Wiring failed after CreateTable for ${tableName}; attempting best-effort cleanup`);
@@ -13827,6 +13863,7 @@ var DynamoDBGlobalTableProvider = class {
13827
13863
  const removedButStillReferenced = oldAttrs.filter((o) => !newAttrs.some((n) => n.AttributeName === o.AttributeName)).filter((a) => a.AttributeName !== void 0 && desiredKeyAttrNames.has(a.AttributeName));
13828
13864
  if (removedButStillReferenced.length > 0) throw new ProvisioningError(`AttributeDefinitions removals are immutable on AWS::DynamoDB::GlobalTable while a key schema still references them (offenders: ${removedButStillReferenced.map((a) => a.AttributeName).join(", ")}); replacement required`, resourceType, logicalId, physicalId);
13829
13865
  const currentRegion = await this.dynamoDBClient.config.region() ?? "";
13866
+ let effectiveProperties;
13830
13867
  try {
13831
13868
  await this.waitForTableActiveAfterUpdate(physicalId, logicalId);
13832
13869
  const describeResp = await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }));
@@ -13897,7 +13934,7 @@ var DynamoDBGlobalTableProvider = class {
13897
13934
  let streamSpecUnusable = false;
13898
13935
  const streamViewType = readConfigString(properties["StreamSpecification"], "StreamViewType", "NEW_AND_OLD_IMAGES", "AWS::DynamoDB::GlobalTable StreamSpecification", { onUnusable: (message) => {
13899
13936
  streamSpecUnusable = true;
13900
- this.logger.warn(`${message} The table's existing stream configuration is left untouched for this update rather than re-pointed at the default.`);
13937
+ this.logger.warn(`AWS::DynamoDB::GlobalTable ${logicalId}: ${message} The table's existing stream configuration is left untouched for this update rather than re-pointed at the default.`);
13901
13938
  } });
13902
13939
  if (!streamSpecUnusable) {
13903
13940
  flatUpdate.StreamSpecification = {
@@ -13905,6 +13942,12 @@ var DynamoDBGlobalTableProvider = class {
13905
13942
  StreamViewType: streamViewType
13906
13943
  };
13907
13944
  flatChanged = true;
13945
+ } else {
13946
+ const previousStreamSpec = previousProperties["StreamSpecification"];
13947
+ const previousStreamSpecUsable = previousStreamSpec !== void 0 && previousStreamSpec !== null && configStringRefusal(previousStreamSpec, "StreamViewType", "NEW_AND_OLD_IMAGES", "AWS::DynamoDB::GlobalTable StreamSpecification") === void 0;
13948
+ effectiveProperties = { ...properties };
13949
+ if (previousStreamSpecUsable) effectiveProperties["StreamSpecification"] = { ...previousStreamSpec };
13950
+ else delete effectiveProperties["StreamSpecification"];
13908
13951
  }
13909
13952
  }
13910
13953
  const awsOnDemand = describeResp.Table?.OnDemandThroughput;
@@ -14185,7 +14228,8 @@ var DynamoDBGlobalTableProvider = class {
14185
14228
  TableId: finalDescribe.Table?.TableId,
14186
14229
  StreamArn: finalDescribe.Table?.LatestStreamArn,
14187
14230
  TableName: physicalId
14188
- }
14231
+ },
14232
+ ...effectiveProperties && { effectiveProperties }
14189
14233
  };
14190
14234
  } catch (error) {
14191
14235
  if (error instanceof ProvisioningError) throw error;
@@ -51815,6 +51859,7 @@ async function deployCommand(stacks, options) {
51815
51859
  ...options.skipFinalSnapshot && { skipFinalSnapshot: true },
51816
51860
  finalSnapshotClients: stackAwsClients,
51817
51861
  ...options.strictGetatt && { strictGetAtt: true },
51862
+ ...options.cfnFallback === false && { cfnFallback: false },
51818
51863
  captureObservedState: resolveCaptureObservedState(options.captureObservedState),
51819
51864
  ...options.resourceWarnAfter?.globalMs !== void 0 && { resourceWarnAfterMs: options.resourceWarnAfter.globalMs },
51820
51865
  ...options.resourceTimeout?.globalMs !== void 0 && { resourceTimeoutMs: options.resourceTimeout.globalMs },
@@ -52876,8 +52921,8 @@ async function loadStateOrEmpty(stackName, region, stateBackend) {
52876
52921
  * Pure with respect to AWS state mutation — only reads state (the resolver
52877
52922
  * may read producer state for `Fn::ImportValue` / `Fn::GetStackOutput`).
52878
52923
  */
52879
- async function computeStackDiff(currentState, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties) {
52880
- const intrinsicResolver = new IntrinsicFunctionResolver(region);
52924
+ async function computeStackDiff(currentState, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties, cfnFallback) {
52925
+ const intrinsicResolver = new IntrinsicFunctionResolver(region, { cfnFallback: cfnFallback ?? true });
52881
52926
  let mergedParameters = parameters;
52882
52927
  let parametersBound = false;
52883
52928
  try {
@@ -52939,10 +52984,10 @@ async function computeStackDiff(currentState, template, region, stackName, state
52939
52984
  * unresolvable case), while resolvable parameters (the freshly-deployed tree)
52940
52985
  * get exact scalar values.
52941
52986
  */
52942
- async function resolveChildStackParameters(parentStackRow, parentTemplate, parentState, region, parentStackName, stateBackend, parentParameters) {
52987
+ async function resolveChildStackParameters(parentStackRow, parentTemplate, parentState, region, parentStackName, stateBackend, parentParameters, cfnFallback) {
52943
52988
  const rawParams = parentStackRow.Properties?.["Parameters"];
52944
52989
  if (!rawParams || typeof rawParams !== "object" || Array.isArray(rawParams)) return {};
52945
- const resolver = new IntrinsicFunctionResolver(region);
52990
+ const resolver = new IntrinsicFunctionResolver(region, { cfnFallback: cfnFallback ?? true });
52946
52991
  const resolved = {};
52947
52992
  for (const [name, value] of Object.entries(rawParams)) try {
52948
52993
  resolved[name] = await resolver.resolve(value, {
@@ -52977,13 +53022,13 @@ async function resolveChildStackParameters(parentStackRow, parentTemplate, paren
52977
53022
  * fail at deploy time.
52978
53023
  */
52979
53024
  async function buildDiffTree(args) {
52980
- const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parameters, canonicalizeProperties, assetRedirect } = args;
53025
+ const { stackName, displayName, region, template, nestedTemplates, recursive, stateBackend, diffCalculator, parameters, canonicalizeProperties, assetRedirect, cfnFallback } = args;
52981
53026
  const state = await loadStateOrEmpty(stackName, region, stateBackend);
52982
53027
  const node = {
52983
53028
  stackName,
52984
53029
  displayName,
52985
53030
  region,
52986
- changes: await computeStackDiff(state, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties),
53031
+ changes: await computeStackDiff(state, template, region, stackName, stateBackend, diffCalculator, parameters, canonicalizeProperties, cfnFallback),
52987
53032
  ccApiRoutes: collectCcApiRoutes(template, state),
52988
53033
  children: []
52989
53034
  };
@@ -52998,7 +53043,7 @@ async function buildDiffTree(args) {
52998
53043
  const childTemplate = readNestedTemplate(childTemplatePath);
52999
53044
  if (assetRedirect) rewriteTemplateAssetReferences(childTemplate, assetRedirect);
53000
53045
  const grandchildTemplates = indexNestedChildTemplates(childTemplate, childTemplatePath);
53001
- const childParameters = await resolveChildStackParameters(resource, template, state, region, stackName, stateBackend, parameters);
53046
+ const childParameters = await resolveChildStackParameters(resource, template, state, region, stackName, stateBackend, parameters, cfnFallback);
53002
53047
  node.children.push(await buildDiffTree({
53003
53048
  stackName: childStackName,
53004
53049
  displayName: childStackName,
@@ -53010,7 +53055,8 @@ async function buildDiffTree(args) {
53010
53055
  diffCalculator,
53011
53056
  parameters: childParameters,
53012
53057
  ...canonicalizeProperties && { canonicalizeProperties },
53013
- ...assetRedirect && { assetRedirect }
53058
+ ...assetRedirect && { assetRedirect },
53059
+ ...cfnFallback !== void 0 && { cfnFallback }
53014
53060
  }));
53015
53061
  }
53016
53062
  for (const [logicalId, resource] of Object.entries(state.resources)) {
@@ -53397,7 +53443,8 @@ async function diffCommand(stacks, options) {
53397
53443
  stateBackend,
53398
53444
  diffCalculator,
53399
53445
  canonicalizeProperties,
53400
- ...assetRedirect && { assetRedirect }
53446
+ ...assetRedirect && { assetRedirect },
53447
+ ...options.cfnFallback === false && { cfnFallback: false }
53401
53448
  }));
53402
53449
  }
53403
53450
  if (options.json) process.stdout.write(`${JSON.stringify(trees.map(diffTreeToJson), null, 2)}\n`);
@@ -53417,7 +53464,7 @@ async function diffCommand(stacks, options) {
53417
53464
  * Create diff command
53418
53465
  */
53419
53466
  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));
53467
+ 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
53468
  [
53422
53469
  ...commonOptions,
53423
53470
  ...appOptions,
@@ -56509,8 +56556,8 @@ async function exportCommand(stackArg, options) {
56509
56556
  const crossRefs = scanCrossStackReferences(allSynthStacks, resolvedStackName);
56510
56557
  if (crossRefs.length > 0) {
56511
56558
  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.`);
56559
+ 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"));
56560
+ 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
56561
  for (const line of lines) logger.warn(line);
56515
56562
  }
56516
56563
  }
@@ -56594,8 +56641,8 @@ async function exportCommand(stackArg, options) {
56594
56641
  const crossRefs = scanCrossStackReferences(allSynthStacks, resolvedStackName);
56595
56642
  if (crossRefs.length > 0) {
56596
56643
  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.`);
56644
+ 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"));
56645
+ 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
56646
  for (const line of lines) logger.warn(line);
56600
56647
  }
56601
56648
  }
@@ -58503,7 +58550,7 @@ async function confirmPrompt$3(prompt) {
58503
58550
  }
58504
58551
  }
58505
58552
  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));
58553
+ 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
58554
  [
58508
58555
  ...commonOptions,
58509
58556
  ...appOptions,
@@ -72329,7 +72376,7 @@ function createMigrateCommand() {
72329
72376
  */
72330
72377
  function buildProgram() {
72331
72378
  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");
72379
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.1");
72333
72380
  program.hook("preAction", (_thisCommand, actionCommand) => {
72334
72381
  const { profile } = actionCommand.optsWithGlobals();
72335
72382
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;