@go-to-k/cdkd 0.281.23 → 0.281.24
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 +9 -0
- package/dist/{asg-provider-CCSQkGwO.js → asg-provider-CxK7d3pH.js} +2 -2
- package/dist/{asg-provider-CCSQkGwO.js.map → asg-provider-CxK7d3pH.js.map} +1 -1
- package/dist/cli.js +275 -29
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-uxo_FCje.js → deploy-engine-BkXNtI7L.js} +3 -3
- package/dist/{deploy-engine-uxo_FCje.js.map → deploy-engine-BkXNtI7L.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as configStringRefusal, $t as MIGRATE_TMP_PREFIX, A as green, At as validateContainerRepoName, B as slowCcOperationTimeoutMs, Bt as getDefaultStateBucketName, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as PartialFailureError, Ct as rewriteTemplateAssetReferences, D as bold, Dn as StackHasActiveImportsError, Dt as getBootstrapMarkerKey, E as formatResourceLine, En as ResourceUpdateNotSupportedError, Et as ensureAssetStorage, F as clearOnUpdateRemoval, Ft as runDockerStreaming, G as getAccountInfo, Gt as resolveSkipPrefix, H as isTerminationProtectionPropagationError, Ht as resolveApp, I as ProviderRegistry, It as AssetManifestLoader, J as normalizeAwsTagsToCfn, Jt as resolveUseCdkBootstrapAssets, K as refStateLookupFromResource, Kt as resolveStateBucketWithDefault, L as findActionableSilentDrops, Lt as getDockerImageBySourceHash, M as yellow, Mt as formatDockerLoginError, N as IAMRoleProvider, Nn as normalizeAwsError, Nt as getDockerCmd, O as cyan, On as StackTerminationProtectionError, Ot as parseBootstrapMarker, P as collectInlinePolicyNamesManagedBySiblings, Pn as withErrorHandling, Pt as runDockerForeground, Q as configBooleanRefusal, Qt as CFN_TEMPLATE_URL_LIMIT, R as findSilentDropProperties, Rt as Synthesizer, S as extractDeploymentEventError, Sn as NestedStackChildDirectDestroyError, St as loadPublishableAssetManifest, T as renderStatefulReason, Tn as ResourceTimeoutError, Tt as BOOTSTRAP_MARKER_PREFIX, U as IntrinsicFunctionResolver, Ut as resolveAutoAssetStorage, V as disableInstanceApiTermination, Vt as getLegacyStateBucketName, W as cfnRefValueFromPhysicalId, Wt as resolveCaptureObservedState, X as assertRegionMatch, Xt as warnDeprecatedNoPrefixCliFlag, Y as resolveExplicitPhysicalId, Yt as stateBucketExistenceConfirmed, Z as coerceCfnBoolean, Zt as CFN_TEMPLATE_BODY_LIMIT, _ as createPreDeleteFinalSnapshot, _n as LocalInvokeBuildError$1, _t as AssetPublisher, a as DeploymentEventsStore, an as processStackMessages, at as applyRoleArnIfSet, b as unsupportedFinalSnapshotError, bt as buildAssetRedirectMap, c as replayFailedOperations, cn as AwsClients, ct as withRetry, d as IMPLICIT_DELETE_DEPENDENCIES, dn as setAwsClients, dt as DagBuilder, en as findLargeInlineResources, et as readConfigString, f as computeImplicitDeleteEdges, ft as TemplateParser, g as ccRoutedFinalSnapshotError, gn as DeployCancelledError, gt as shouldRetainResource, h as buildFinalSnapshotIdentifier, ht as rebuildClientForBucketRegion, i as DeploymentEventsReader, in as AssemblyReader, it as requireConfigString, j as red, jt as buildDockerImage, k as gray, kt as validateAssetBucketName, l as replayRollback, ln as getAwsClients, lt as isRetryableTransientError, m as PRE_DELETE_SNAPSHOT_TYPES, mt as S3StateBackend, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as expectedOwnerParam, nt as requireConfigArray, o as planFailedOps, ot as DiffCalculator, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as CdkdError, pt as LockManager, q as WAFv2WebACLProvider, qt as resolveStateBucketWithDefaultAndSource, r as DeployEngine, rn as derivePartitionAndUrlSuffix, rt as requireConfigObject, s as planRollback, sn as resolveBucketRegion, st as describeTypeWithThrottleRetry, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as uploadCfnTemplate, tt as replayWarn, u as withResourceDeadline, un as resetAwsClients, ut as isThrottlingError, v as isFinalSnapshotError, vn as LocalMigrateError, vt as stringifyValue, w as isStatefulRecreateTargetSync, wn as ProvisioningError, wt as AssetModeResolver, x as makeCanonicalizePropertiesFn, xn as MissingCdkCliError, xt as createAssetRedirectResolver, y as refusesFinalSnapshot, yn as LocalStartServiceError, yt as WorkGraph, z as CloudControlProvider, zt as synthesisStatusMessage } from "./deploy-engine-
|
|
2
|
+
import { $ as configStringRefusal, $t as MIGRATE_TMP_PREFIX, A as green, At as validateContainerRepoName, B as slowCcOperationTimeoutMs, Bt as getDefaultStateBucketName, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as PartialFailureError, Ct as rewriteTemplateAssetReferences, D as bold, Dn as StackHasActiveImportsError, Dt as getBootstrapMarkerKey, E as formatResourceLine, En as ResourceUpdateNotSupportedError, Et as ensureAssetStorage, F as clearOnUpdateRemoval, Ft as runDockerStreaming, G as getAccountInfo, Gt as resolveSkipPrefix, H as isTerminationProtectionPropagationError, Ht as resolveApp, I as ProviderRegistry, It as AssetManifestLoader, J as normalizeAwsTagsToCfn, Jt as resolveUseCdkBootstrapAssets, K as refStateLookupFromResource, Kt as resolveStateBucketWithDefault, L as findActionableSilentDrops, Lt as getDockerImageBySourceHash, M as yellow, Mt as formatDockerLoginError, N as IAMRoleProvider, Nn as normalizeAwsError, Nt as getDockerCmd, O as cyan, On as StackTerminationProtectionError, Ot as parseBootstrapMarker, P as collectInlinePolicyNamesManagedBySiblings, Pn as withErrorHandling, Pt as runDockerForeground, Q as configBooleanRefusal, Qt as CFN_TEMPLATE_URL_LIMIT, R as findSilentDropProperties, Rt as Synthesizer, S as extractDeploymentEventError, Sn as NestedStackChildDirectDestroyError, St as loadPublishableAssetManifest, T as renderStatefulReason, Tn as ResourceTimeoutError, Tt as BOOTSTRAP_MARKER_PREFIX, U as IntrinsicFunctionResolver, Ut as resolveAutoAssetStorage, V as disableInstanceApiTermination, Vt as getLegacyStateBucketName, W as cfnRefValueFromPhysicalId, Wt as resolveCaptureObservedState, X as assertRegionMatch, Xt as warnDeprecatedNoPrefixCliFlag, Y as resolveExplicitPhysicalId, Yt as stateBucketExistenceConfirmed, Z as coerceCfnBoolean, Zt as CFN_TEMPLATE_BODY_LIMIT, _ as createPreDeleteFinalSnapshot, _n as LocalInvokeBuildError$1, _t as AssetPublisher, a as DeploymentEventsStore, an as processStackMessages, at as applyRoleArnIfSet, b as unsupportedFinalSnapshotError, bt as buildAssetRedirectMap, c as replayFailedOperations, cn as AwsClients, ct as withRetry, d as IMPLICIT_DELETE_DEPENDENCIES, dn as setAwsClients, dt as DagBuilder, en as findLargeInlineResources, et as readConfigString, f as computeImplicitDeleteEdges, ft as TemplateParser, g as ccRoutedFinalSnapshotError, gn as DeployCancelledError, gt as shouldRetainResource, h as buildFinalSnapshotIdentifier, ht as rebuildClientForBucketRegion, i as DeploymentEventsReader, in as AssemblyReader, it as requireConfigString, j as red, jt as buildDockerImage, k as gray, kt as validateAssetBucketName, l as replayRollback, ln as getAwsClients, lt as isRetryableTransientError, m as PRE_DELETE_SNAPSHOT_TYPES, mt as S3StateBackend, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as expectedOwnerParam, nt as requireConfigArray, o as planFailedOps, ot as DiffCalculator, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as CdkdError, pt as LockManager, q as WAFv2WebACLProvider, qt as resolveStateBucketWithDefaultAndSource, r as DeployEngine, rn as derivePartitionAndUrlSuffix, rt as requireConfigObject, s as planRollback, sn as resolveBucketRegion, st as describeTypeWithThrottleRetry, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as uploadCfnTemplate, tt as replayWarn, u as withResourceDeadline, un as resetAwsClients, ut as isThrottlingError, v as isFinalSnapshotError, vn as LocalMigrateError, vt as stringifyValue, w as isStatefulRecreateTargetSync, wn as ProvisioningError, wt as AssetModeResolver, x as makeCanonicalizePropertiesFn, xn as MissingCdkCliError, xt as createAssetRedirectResolver, y as refusesFinalSnapshot, yn as LocalStartServiceError, yt as WorkGraph, z as CloudControlProvider, zt as synthesisStatusMessage } from "./deploy-engine-BkXNtI7L.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-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-CxK7d3pH.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";
|
|
@@ -58338,9 +58338,17 @@ function stackTreeToJson(roots) {
|
|
|
58338
58338
|
* PR B2 — until that lands, the orchestrator hard-errors at submission
|
|
58339
58339
|
* time with a clear pointer.
|
|
58340
58340
|
*
|
|
58341
|
-
* The list is intentionally narrow
|
|
58342
|
-
*
|
|
58343
|
-
*
|
|
58341
|
+
* The list is intentionally narrow, and stays hand-written because each member
|
|
58342
|
+
* is a cdkd / CDK construct rather than something the registry describes.
|
|
58343
|
+
*
|
|
58344
|
+
* It is NOT the only refusal, though — the "defer to the CreateChangeSet
|
|
58345
|
+
* error" note this comment used to end on was revisited in issue
|
|
58346
|
+
* [#1659](https://github.com/go-to-k/cdkd/issues/1659). Types AWS refuses for
|
|
58347
|
+
* IMPORT because their registry schema declares no `read` handler are now
|
|
58348
|
+
* caught by {@link buildImportPlan}'s pre-flight instead, which needs no
|
|
58349
|
+
* hand-maintained list (the signal is derived from the schema cdkd already
|
|
58350
|
+
* fetches for the identifier) and names every offender in one pass — AWS's own
|
|
58351
|
+
* error names only some of them.
|
|
58344
58352
|
*/
|
|
58345
58353
|
const NEVER_IMPORTABLE_TYPES = /* @__PURE__ */ new Set(["AWS::CDK::Metadata"]);
|
|
58346
58354
|
/**
|
|
@@ -58513,6 +58521,16 @@ const COMPOSITE_ID_SPLITTERS = {
|
|
|
58513
58521
|
propertiesOverlay: { ApiId: apiId }
|
|
58514
58522
|
};
|
|
58515
58523
|
},
|
|
58524
|
+
"AWS::S3Tables::Namespace": (physicalId) => {
|
|
58525
|
+
const parts = physicalId.split("|");
|
|
58526
|
+
if (parts.length !== 2) throw new Error(`expected 2 parts ('<tableBucketARN>|<namespaceName>'), got ${parts.length}: '${physicalId}'`);
|
|
58527
|
+
const [tableBucketARN, namespace] = parts;
|
|
58528
|
+
if (!tableBucketARN || !namespace) throw new Error(`empty part in '<tableBucketARN>|<namespaceName>': '${physicalId}'`);
|
|
58529
|
+
return { resourceIdentifier: {
|
|
58530
|
+
TableBucketARN: tableBucketARN,
|
|
58531
|
+
Namespace: namespace
|
|
58532
|
+
} };
|
|
58533
|
+
},
|
|
58516
58534
|
"AWS::Lambda::Permission": (physicalId, properties) => {
|
|
58517
58535
|
const functionName = readStringProperty(properties, "FunctionName", "AWS::Lambda::Permission");
|
|
58518
58536
|
return {
|
|
@@ -58598,6 +58616,144 @@ function readStringProperty(properties, key, resourceType) {
|
|
|
58598
58616
|
return v;
|
|
58599
58617
|
}
|
|
58600
58618
|
/**
|
|
58619
|
+
* Types whose cdkd physicalId is a COMPOSITE (`|`-joined) string while
|
|
58620
|
+
* CloudFormation's `primaryIdentifier` is a SINGLE field — so the physicalId is
|
|
58621
|
+
* NOT the identifier value, and it is not a SPLIT of the composite either
|
|
58622
|
+
* (issue [#1659](https://github.com/go-to-k/cdkd/issues/1659)).
|
|
58623
|
+
*
|
|
58624
|
+
* ## Why this table exists next to `COMPOSITE_ID_SPLITTERS`
|
|
58625
|
+
*
|
|
58626
|
+
* `resolveResourceIdentifier` used to conflate two independent questions: the
|
|
58627
|
+
* ARITY of the CFn identifier, and the FORMAT of cdkd's physical id. The
|
|
58628
|
+
* single-field branch assumed "the physicalId IS the identifier value", which
|
|
58629
|
+
* holds for every type whose id is a scalar and silently produces a wrong value
|
|
58630
|
+
* for a composite-id type whose CFn identifier happens to be single-field —
|
|
58631
|
+
* `{ TableARN: 'arn:aws:s3tables:...|analytics|events' }` for an
|
|
58632
|
+
* `AWS::S3Tables::Table`. `COMPOSITE_ID_SPLITTERS` cannot fix that: it is only
|
|
58633
|
+
* consulted on the multi-field branch, so registering a type there would add an
|
|
58634
|
+
* entry no code path reaches.
|
|
58635
|
+
*
|
|
58636
|
+
* This table is consulted BEFORE the arity branch, so the two concerns are
|
|
58637
|
+
* separated: a registered type never takes the "physicalId is the identifier"
|
|
58638
|
+
* assumption regardless of what the schema's field count says.
|
|
58639
|
+
*
|
|
58640
|
+
* ## Why a RESOLVE and not a split
|
|
58641
|
+
*
|
|
58642
|
+
* The correct identifier for each member is a different value entirely, not a
|
|
58643
|
+
* segment of the composite — an ARN AWS minted, or an `sgr-` rule id. So each
|
|
58644
|
+
* entry reads the value cdkd recorded in state (`attributes`), and refuses when
|
|
58645
|
+
* it is absent rather than guessing.
|
|
58646
|
+
*
|
|
58647
|
+
* ## Live measurement (us-east-1, 2026-08-13)
|
|
58648
|
+
*
|
|
58649
|
+
* Every field below is BOTH the type's single-field `primaryIdentifier` AND
|
|
58650
|
+
* `readOnlyProperties`, which is why each resolution returns an EMPTY
|
|
58651
|
+
* `propertiesOverlay`: writing a read-only property into the synth template's
|
|
58652
|
+
* `Properties` block is rejected by CFn at changeset-create.
|
|
58653
|
+
*
|
|
58654
|
+
* | Type | `primaryIdentifier` | recorded as |
|
|
58655
|
+
* |---|---|---|
|
|
58656
|
+
* | `AWS::AppSync::DataSource` | `DataSourceArn` | `attributes.DataSourceArn` |
|
|
58657
|
+
* | `AWS::AppSync::Resolver` | `ResolverArn` | `attributes.ResolverArn` |
|
|
58658
|
+
* | `AWS::S3Tables::Table` | `TableARN` | `attributes.TableARN` |
|
|
58659
|
+
* | `AWS::EC2::SecurityGroupIngress` | `Id` | NOTHING (issue #1761) |
|
|
58660
|
+
*
|
|
58661
|
+
* All four declare a `read` handler, so CFn genuinely does accept them for
|
|
58662
|
+
* IMPORT — unlike `AWS::Glue::Table`, the type issue #1659's title names, which
|
|
58663
|
+
* CFn rejects outright (see {@link typeIsImportUnsupported}).
|
|
58664
|
+
*/
|
|
58665
|
+
const COMPOSITE_PHYSICAL_ID_IDENTIFIERS = {
|
|
58666
|
+
"AWS::AppSync::DataSource": recordedArnIdentifier({
|
|
58667
|
+
resourceType: "AWS::AppSync::DataSource",
|
|
58668
|
+
field: "DataSourceArn",
|
|
58669
|
+
physicalIdShape: "<apiId>|<name>",
|
|
58670
|
+
arnServiceSegment: "appsync"
|
|
58671
|
+
}),
|
|
58672
|
+
"AWS::AppSync::Resolver": recordedArnIdentifier({
|
|
58673
|
+
resourceType: "AWS::AppSync::Resolver",
|
|
58674
|
+
field: "ResolverArn",
|
|
58675
|
+
physicalIdShape: "<apiId>|<typeName>|<fieldName>",
|
|
58676
|
+
arnServiceSegment: "appsync"
|
|
58677
|
+
}),
|
|
58678
|
+
"AWS::S3Tables::Table": recordedArnIdentifier({
|
|
58679
|
+
resourceType: "AWS::S3Tables::Table",
|
|
58680
|
+
field: "TableARN",
|
|
58681
|
+
physicalIdShape: "<tableBucketARN>|<namespace>|<name>",
|
|
58682
|
+
arnServiceSegment: "s3tables"
|
|
58683
|
+
}),
|
|
58684
|
+
"AWS::EC2::SecurityGroupIngress": {
|
|
58685
|
+
field: "Id",
|
|
58686
|
+
resolve: ({ logicalId }) => {
|
|
58687
|
+
throw new Error(`cdkd's physical id for AWS::EC2::SecurityGroupIngress is the composite '<groupId>|<ipProtocol>|<fromPort>|<toPort>', but CloudFormation IMPORT identifies the rule by the 'sgr-...' security-group rule id AWS assigns, which cdkd does not record in state (tracked in https://github.com/go-to-k/cdkd/issues/1761). Remove '${logicalId}' from the stack before exporting (the rule stays in AWS and can be re-declared in CloudFormation afterwards), or destroy it first and let CloudFormation create it fresh.`);
|
|
58688
|
+
}
|
|
58689
|
+
}
|
|
58690
|
+
};
|
|
58691
|
+
/**
|
|
58692
|
+
* Build the {@link CompositePhysicalIdIdentifier} for a type whose CFn
|
|
58693
|
+
* identifier is an ARN cdkd records in `attributes` under the SAME name as the
|
|
58694
|
+
* `primaryIdentifier` field.
|
|
58695
|
+
*
|
|
58696
|
+
* Two accepted sources, mirroring the splitter family's "both shapes exist in
|
|
58697
|
+
* state in the wild" contract:
|
|
58698
|
+
*
|
|
58699
|
+
* 1. the recorded attribute, which is what a fresh deploy and a cdkd `import`
|
|
58700
|
+
* both write; and
|
|
58701
|
+
* 2. a physicalId that is ALREADY the bare ARN. Two live producers:
|
|
58702
|
+
* `S3TablesProvider.importTable` records it for a Cloud-Control-routed
|
|
58703
|
+
* table (CC's identifier for the type IS the ARN), and an AppSync child
|
|
58704
|
+
* adopted through `cdkd import --migrate-from-cloudformation` records
|
|
58705
|
+
* CloudFormation's `PhysicalResourceId` verbatim, which is likewise the
|
|
58706
|
+
* ARN.
|
|
58707
|
+
*
|
|
58708
|
+
* **Both sources are validated by the SAME predicate.** An earlier cut checked
|
|
58709
|
+
* the ARN's shape only on source 2 — the rare one — while source 1, which
|
|
58710
|
+
* fires on essentially every export, accepted any non-blank string verbatim.
|
|
58711
|
+
* That is the wrong way round: a hand-edited state row, a row written by an
|
|
58712
|
+
* older binary that recorded the composite under the attribute name, or an ARN
|
|
58713
|
+
* for a different service sitting under `attributes.<field>` would each have
|
|
58714
|
+
* been shipped as the IMPORT identifier and silently adopted the WRONG
|
|
58715
|
+
* resource, which is precisely what this table exists to prevent.
|
|
58716
|
+
*
|
|
58717
|
+
* Anything failing both sources is refused. That covers the degraded record
|
|
58718
|
+
* `docs/state-management.md` describes — written by a cdkd older than the fix
|
|
58719
|
+
* that started recording the ARN, or by an import that could not reach STS —
|
|
58720
|
+
* and the remedy is the one that doc already gives.
|
|
58721
|
+
*/
|
|
58722
|
+
function recordedArnIdentifier(options) {
|
|
58723
|
+
const { resourceType, field, physicalIdShape, arnServiceSegment } = options;
|
|
58724
|
+
/**
|
|
58725
|
+
* Is this value usable AS the type's CFn identifier?
|
|
58726
|
+
*
|
|
58727
|
+
* - `arn:` prefix and the type's own SERVICE segment: an ARN naming another
|
|
58728
|
+
* service is a different value entirely. Partition-agnostic by
|
|
58729
|
+
* construction, so `arn:aws-cn:s3tables:...` matches.
|
|
58730
|
+
* - no `|`: cdkd's composite for `AWS::S3Tables::Table` is built FROM the
|
|
58731
|
+
* bucket ARN, so it satisfies both checks above — the separator test is
|
|
58732
|
+
* what distinguishes the composite from the identifier, on BOTH sources.
|
|
58733
|
+
*/
|
|
58734
|
+
const isUsableIdentifier = (value) => {
|
|
58735
|
+
const trimmed = value.trim();
|
|
58736
|
+
return trimmed.startsWith("arn:") && trimmed.includes(`:${arnServiceSegment}:`) && !trimmed.includes("|");
|
|
58737
|
+
};
|
|
58738
|
+
return {
|
|
58739
|
+
field,
|
|
58740
|
+
resolve: ({ logicalId, physicalId, attributes }) => {
|
|
58741
|
+
const recorded = attributes[field];
|
|
58742
|
+
if (typeof recorded === "string" && isUsableIdentifier(recorded)) return recorded.trim();
|
|
58743
|
+
if (isUsableIdentifier(physicalId)) return physicalId.trim();
|
|
58744
|
+
const recordedNote = typeof recorded === "string" && recorded.trim() ? `attributes.${field} is recorded as '${recorded.trim()}', which is not a ${arnServiceSegment} ARN` : `attributes.${field} is missing or empty`;
|
|
58745
|
+
throw new Error(`cdkd's physical id for ${resourceType} is the composite '${physicalIdShape}', but CloudFormation IMPORT identifies the resource by its ${field}, which cdkd state does not record usably for '${logicalId}' (${recordedNote}). Re-deploy the stack once so cdkd records ${field}, then re-run cdkd export.`);
|
|
58746
|
+
}
|
|
58747
|
+
};
|
|
58748
|
+
}
|
|
58749
|
+
/**
|
|
58750
|
+
* Every type registered in {@link COMPOSITE_PHYSICAL_ID_IDENTIFIERS}. Exported
|
|
58751
|
+
* so a test can assert the table's SIZE, not just membership — a new entry
|
|
58752
|
+
* needs a measurement row in the table's doc comment, and a size-blind test
|
|
58753
|
+
* would let one land silently.
|
|
58754
|
+
*/
|
|
58755
|
+
const COMPOSITE_PHYSICAL_ID_IDENTIFIER_TYPES = Object.keys(COMPOSITE_PHYSICAL_ID_IDENTIFIERS);
|
|
58756
|
+
/**
|
|
58601
58757
|
* Resource types AWS does NOT support in IMPORT changesets but DOES
|
|
58602
58758
|
* support normal CREATE for. cdkd handles these via a pre-delete + phase-2
|
|
58603
58759
|
* CREATE dance (see {@link RecreateBeforePhase2Entry}). When the user
|
|
@@ -58751,17 +58907,20 @@ async function exportCommand(stackArg, options) {
|
|
|
58751
58907
|
}
|
|
58752
58908
|
}
|
|
58753
58909
|
}
|
|
58910
|
+
const { phase1Imports, phase2Creates, recreateBeforePhase2, nestedStackRows, blocked } = await buildImportPlan(state, template, awsClients.cloudFormation, resolvedStackName, {
|
|
58911
|
+
recreateImportUnsupported: options.recreateImportUnsupported,
|
|
58912
|
+
skipImportSupportPreflight: options.skipImportSupportPreflight
|
|
58913
|
+
});
|
|
58914
|
+
if (blocked.length > 0) {
|
|
58915
|
+
logger.error("The following resources block migration:");
|
|
58916
|
+
for (const b of blocked) logger.error(` - ${b.logicalId} (${b.resourceType}): ${b.reason}`);
|
|
58917
|
+
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.`);
|
|
58918
|
+
}
|
|
58754
58919
|
const owner = `${process.env["USER"] || "unknown"}@${process.env["HOSTNAME"] || "host"}:${process.pid}`;
|
|
58755
58920
|
if (!options.dryRun) {
|
|
58756
58921
|
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.`);
|
|
58757
58922
|
}
|
|
58758
58923
|
try {
|
|
58759
|
-
const { phase1Imports, phase2Creates, recreateBeforePhase2, nestedStackRows, blocked } = await buildImportPlan(state, template, awsClients.cloudFormation, resolvedStackName, { recreateImportUnsupported: options.recreateImportUnsupported });
|
|
58760
|
-
if (blocked.length > 0) {
|
|
58761
|
-
logger.error("The following resources block migration:");
|
|
58762
|
-
for (const b of blocked) logger.error(` - ${b.logicalId} (${b.resourceType}): ${b.reason}`);
|
|
58763
|
-
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.`);
|
|
58764
|
-
}
|
|
58765
58924
|
if (nestedStackRows.length > 0) {
|
|
58766
58925
|
const nestedStackTree = await buildCdkdStateStackTree(resolvedStackName, targetRegion, stateBackend, state);
|
|
58767
58926
|
reportDriftBaselineGaps(state, logger);
|
|
@@ -58804,7 +58963,8 @@ async function exportCommand(stackArg, options) {
|
|
|
58804
58963
|
dryRun: options.dryRun,
|
|
58805
58964
|
yes: options.yes,
|
|
58806
58965
|
includeNonImportable: options.includeNonImportable,
|
|
58807
|
-
recreateImportUnsupported: options.recreateImportUnsupported
|
|
58966
|
+
recreateImportUnsupported: options.recreateImportUnsupported,
|
|
58967
|
+
skipImportSupportPreflight: options.skipImportSupportPreflight
|
|
58808
58968
|
}
|
|
58809
58969
|
})).outcome === "success") printNextSteps({
|
|
58810
58970
|
cfnStackName: options.cfnStackName ?? cdkd2cfnStackName(resolvedStackName),
|
|
@@ -59343,7 +59503,16 @@ async function buildImportPlan(state, template, cfnClient, parentStackName, opti
|
|
|
59343
59503
|
}
|
|
59344
59504
|
let resolved;
|
|
59345
59505
|
try {
|
|
59346
|
-
|
|
59506
|
+
const schemaInfo = await cachedTypeSchemaInfo(resourceType, cfnClient, identifierCache);
|
|
59507
|
+
if (!options.skipImportSupportPreflight && typeIsImportUnsupported(schemaInfo)) {
|
|
59508
|
+
blocked.push({
|
|
59509
|
+
logicalId,
|
|
59510
|
+
resourceType,
|
|
59511
|
+
reason: `AWS CloudFormation does not support ${resourceType} in IMPORT changesets: its CloudFormation registry schema declares no 'read' handler (and reports the type as NON_PROVISIONABLE), and IMPORT needs that handler to look the resource up by identifier. CreateChangeSet would reject the whole export with "ResourceTypes [${resourceType}] are not supported for Import". Remove the resource from the stack before exporting (it stays in AWS and can be re-declared in CloudFormation afterwards), or destroy it first and let CloudFormation create it fresh. If AWS has since added IMPORT support for this type, please open a cdkd issue.`
|
|
59512
|
+
});
|
|
59513
|
+
continue;
|
|
59514
|
+
}
|
|
59515
|
+
resolved = resolveResourceIdentifier(resourceType, logicalId, stateEntry.physicalId, stateEntry.properties ?? {}, stateEntry.attributes ?? {}, schemaInfo);
|
|
59347
59516
|
} catch (err) {
|
|
59348
59517
|
blocked.push({
|
|
59349
59518
|
logicalId,
|
|
@@ -59373,6 +59542,11 @@ async function buildImportPlan(state, template, cfnClient, parentStackName, opti
|
|
|
59373
59542
|
* `ResourcesToImport[].ResourceIdentifier` for the given resource type
|
|
59374
59543
|
* and cdkd state's physical ID.
|
|
59375
59544
|
*
|
|
59545
|
+
* Types whose cdkd physicalId is COMPOSITE while the CFn identifier is a
|
|
59546
|
+
* single field (`COMPOSITE_PHYSICAL_ID_IDENTIFIERS`): resolved from cdkd
|
|
59547
|
+
* state's recorded attributes, BEFORE the field-count branch below — the
|
|
59548
|
+
* physicalId is neither the identifier nor a source to split (issue #1659).
|
|
59549
|
+
*
|
|
59376
59550
|
* Single-key types: the map has a single entry keyed by the schema's
|
|
59377
59551
|
* primaryIdentifier field name (e.g. `{ BucketName: 'my-bucket' }`).
|
|
59378
59552
|
*
|
|
@@ -59382,16 +59556,27 @@ async function buildImportPlan(state, template, cfnClient, parentStackName, opti
|
|
|
59382
59556
|
* into one entry per field. Composite types without a registered
|
|
59383
59557
|
* splitter surface a clear error pointing at where to add one.
|
|
59384
59558
|
*
|
|
59385
|
-
*
|
|
59386
|
-
*
|
|
59387
|
-
*
|
|
59388
|
-
*
|
|
59389
|
-
|
|
59390
|
-
|
|
59391
|
-
|
|
59392
|
-
|
|
59393
|
-
|
|
59394
|
-
|
|
59559
|
+
* `entry` is the caller's already-resolved registry-schema info — see
|
|
59560
|
+
* {@link cachedTypeSchemaInfo}, which prefers `DescribeType` (the authoritative
|
|
59561
|
+
* AWS-internal registry) and falls back to a hardcoded single-key table when
|
|
59562
|
+
* DescribeType fails (insufficient permissions, throttling, obscure type
|
|
59563
|
+
* without a registry entry). Taking it as a parameter rather than fetching is
|
|
59564
|
+
* what keeps `buildImportPlan` to ONE DescribeType per type across both the
|
|
59565
|
+
* IMPORT pre-flight and this resolution.
|
|
59566
|
+
*/
|
|
59567
|
+
function resolveResourceIdentifier(resourceType, logicalId, physicalId, properties, attributes, entry) {
|
|
59568
|
+
const compositeIdentifier = COMPOSITE_PHYSICAL_ID_IDENTIFIERS[resourceType];
|
|
59569
|
+
if (compositeIdentifier) {
|
|
59570
|
+
if (entry.fields.length !== 1 || entry.fields[0] !== compositeIdentifier.field) throw new Error(`${resourceType} is registered in COMPOSITE_PHYSICAL_ID_IDENTIFIERS as identified by '${compositeIdentifier.field}', but CloudFormation now reports primaryIdentifier [${entry.fields.join(", ")}]. The registry schema changed under cdkd — update the entry in src/cli/commands/export.ts (or move the type to COMPOSITE_ID_SPLITTERS if its identifier is now composite too)`);
|
|
59571
|
+
const value = compositeIdentifier.resolve({
|
|
59572
|
+
logicalId,
|
|
59573
|
+
physicalId,
|
|
59574
|
+
attributes
|
|
59575
|
+
});
|
|
59576
|
+
return {
|
|
59577
|
+
resourceIdentifier: { [compositeIdentifier.field]: value },
|
|
59578
|
+
propertiesOverlay: {}
|
|
59579
|
+
};
|
|
59395
59580
|
}
|
|
59396
59581
|
if (entry.fields.length === 1) return { resourceIdentifier: { [entry.fields[0]]: physicalId } };
|
|
59397
59582
|
const splitter = COMPOSITE_ID_SPLITTERS[resourceType];
|
|
@@ -59406,6 +59591,53 @@ async function resolveResourceIdentifier(resourceType, physicalId, properties, c
|
|
|
59406
59591
|
return result;
|
|
59407
59592
|
}
|
|
59408
59593
|
/**
|
|
59594
|
+
* Cache-consulting wrapper around {@link fetchPrimaryIdentifier}. Shared by
|
|
59595
|
+
* `resolveResourceIdentifier` and `buildImportPlan`'s pre-flight so one
|
|
59596
|
+
* DescribeType per type answers both questions.
|
|
59597
|
+
*/
|
|
59598
|
+
async function cachedTypeSchemaInfo(resourceType, cfnClient, cache) {
|
|
59599
|
+
const cached = cache.get(resourceType);
|
|
59600
|
+
if (cached !== void 0) return cached;
|
|
59601
|
+
const entry = await fetchPrimaryIdentifier(resourceType, cfnClient);
|
|
59602
|
+
cache.set(resourceType, entry);
|
|
59603
|
+
return entry;
|
|
59604
|
+
}
|
|
59605
|
+
/**
|
|
59606
|
+
* True when the registry schema says CloudFormation will refuse the type in an
|
|
59607
|
+
* IMPORT changeset (`ValidationError: ResourceTypes [<T>] are not supported
|
|
59608
|
+
* for Import`) — IMPORT looks the resource up by identifier through the type's
|
|
59609
|
+
* `read` handler, so a type without one cannot be adopted.
|
|
59610
|
+
*
|
|
59611
|
+
* Live-measured (us-east-1, 2026-08-13) against `CreateChangeSet
|
|
59612
|
+
* --change-set-type IMPORT`: `AWS::Glue::Table` / `AWS::Route53::RecordSet` /
|
|
59613
|
+
* `AWS::AppSync::ApiKey` / `AWS::EC2::NetworkAclEntry` /
|
|
59614
|
+
* `AWS::Route53::RecordSetGroup` / `AWS::SQS::QueuePolicy` /
|
|
59615
|
+
* `AWS::SNS::TopicPolicy` all lack a `read` handler, are all
|
|
59616
|
+
* `NON_PROVISIONABLE`, and were all rejected; `AWS::S3::Bucket`
|
|
59617
|
+
* (`FULLY_MUTABLE`, read handler present) passed the type check. Both shapes
|
|
59618
|
+
* of "no read handler" occur and both count: NO `handlers` block at all (the
|
|
59619
|
+
* legacy types) and a `handlers` block whose keys are only create / update /
|
|
59620
|
+
* delete (`AWS::EC2::NetworkAclEntry`).
|
|
59621
|
+
*
|
|
59622
|
+
* **Why the verdict needs TWO agreeing fields.** Reading "the `handlers` key is
|
|
59623
|
+
* missing" as a refusal on its own makes any partial or unusual response block
|
|
59624
|
+
* an export that works today — the one regression this pre-flight could cause,
|
|
59625
|
+
* and strictly worse than the status quo of letting AWS answer. So the refusal
|
|
59626
|
+
* also requires `ProvisioningType: NON_PROVISIONABLE`; a response satisfying
|
|
59627
|
+
* only one of the two resolves to `unknown` and is left to CreateChangeSet.
|
|
59628
|
+
*
|
|
59629
|
+
* The two were perfectly CORRELATED across the 21 types sampled on 2026-08-13
|
|
59630
|
+
* (every no-read-handler type was NON_PROVISIONABLE and vice versa), so on
|
|
59631
|
+
* today's registry the conjunction's real work is requiring a COMPLETE
|
|
59632
|
+
* DescribeType response before refusing. The `read` handler stays the primary
|
|
59633
|
+
* signal because it is the mechanistic reason CFn accepts a type for IMPORT —
|
|
59634
|
+
* refusing on `ProvisioningType` alone would reject a NON_PROVISIONABLE type
|
|
59635
|
+
* that does declare one, should AWS ever publish that combination.
|
|
59636
|
+
*/
|
|
59637
|
+
function typeIsImportUnsupported(entry) {
|
|
59638
|
+
return entry.importSupport === "unsupported";
|
|
59639
|
+
}
|
|
59640
|
+
/**
|
|
59409
59641
|
* Fetch the primary identifier field names for a resource type, with a
|
|
59410
59642
|
* hardcoded single-key fallback when DescribeType is unavailable.
|
|
59411
59643
|
*/
|
|
@@ -59413,15 +59645,26 @@ async function fetchPrimaryIdentifier(resourceType, cfnClient) {
|
|
|
59413
59645
|
try {
|
|
59414
59646
|
const resp = await describeTypeWithThrottleRetry(resourceType, cfnClient);
|
|
59415
59647
|
if (resp.Schema) {
|
|
59416
|
-
const
|
|
59417
|
-
|
|
59648
|
+
const parsed = JSON.parse(resp.Schema);
|
|
59649
|
+
const primary = parsed.primaryIdentifier;
|
|
59650
|
+
if (Array.isArray(primary) && primary.length > 0 && primary.every((p) => typeof p === "string")) {
|
|
59651
|
+
const fields = primary.map((p) => p.replace(/^\/properties\//, ""));
|
|
59652
|
+
const handlers = parsed.handlers;
|
|
59653
|
+
return {
|
|
59654
|
+
fields,
|
|
59655
|
+
importSupport: typeof handlers === "object" && handlers !== null && Object.prototype.hasOwnProperty.call(handlers, "read") ? "importable" : resp.ProvisioningType === "NON_PROVISIONABLE" ? "unsupported" : "unknown"
|
|
59656
|
+
};
|
|
59657
|
+
}
|
|
59418
59658
|
}
|
|
59419
59659
|
} catch (err) {
|
|
59420
59660
|
const msg = err instanceof Error ? err.message : String(err);
|
|
59421
59661
|
getLogger().debug(`DescribeType failed for ${resourceType}: ${msg} — using fallback`);
|
|
59422
59662
|
}
|
|
59423
59663
|
const fallback = PRIMARY_IDENTIFIER_FALLBACK[resourceType];
|
|
59424
|
-
if (fallback) return {
|
|
59664
|
+
if (fallback) return {
|
|
59665
|
+
fields: [fallback],
|
|
59666
|
+
importSupport: "unknown"
|
|
59667
|
+
};
|
|
59425
59668
|
throw new Error(`primary identifier unknown (DescribeType returned no usable schema and no fallback is registered). Add ${resourceType} to PRIMARY_IDENTIFIER_FALLBACK in export.ts, or open an issue.`);
|
|
59426
59669
|
}
|
|
59427
59670
|
/**
|
|
@@ -60347,7 +60590,10 @@ async function runPerStackImportLoop(args) {
|
|
|
60347
60590
|
const perStackPlans = [];
|
|
60348
60591
|
for (const node of leafFirst) {
|
|
60349
60592
|
const meta = nodesByCdkdName.get(node.stackName);
|
|
60350
|
-
const plan = await buildImportPlan(meta.state, meta.template, deps.cfnClient, meta.cdkdStackName, {
|
|
60593
|
+
const plan = await buildImportPlan(meta.state, meta.template, deps.cfnClient, meta.cdkdStackName, {
|
|
60594
|
+
recreateImportUnsupported: options.recreateImportUnsupported,
|
|
60595
|
+
skipImportSupportPreflight: options.skipImportSupportPreflight === true
|
|
60596
|
+
});
|
|
60351
60597
|
if (plan.blocked.length > 0) {
|
|
60352
60598
|
const lines = plan.blocked.map((b) => ` - ${b.logicalId} (${b.resourceType}): ${b.reason}`);
|
|
60353
60599
|
throw new Error(`Stack '${meta.cdkdStackName}' has ${plan.blocked.length} resource(s) that block migration:\n${lines.join("\n")}`);
|
|
@@ -60763,7 +61009,7 @@ async function confirmPrompt$3(prompt) {
|
|
|
60763
61009
|
}
|
|
60764
61010
|
}
|
|
60765
61011
|
function createExportCommand() {
|
|
60766
|
-
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));
|
|
61012
|
+
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("--skip-import-support-preflight", "Skip the pre-flight that refuses resource types whose CloudFormation registry schema says CFn cannot IMPORT them (no read handler AND NON_PROVISIONABLE), and let CreateChangeSet answer instead. The pre-flight is a registry HEURISTIC, not AWS's supported-for-import list, so this is the escape hatch for a type AWS has since made importable. Expect the changeset to be rejected if the heuristic was right.", 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));
|
|
60767
61013
|
[
|
|
60768
61014
|
...commonOptions,
|
|
60769
61015
|
...appOptions,
|
|
@@ -74608,7 +74854,7 @@ function createMigrateCommand() {
|
|
|
74608
74854
|
*/
|
|
74609
74855
|
function buildProgram() {
|
|
74610
74856
|
const program = new Command();
|
|
74611
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.
|
|
74857
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.24");
|
|
74612
74858
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
74613
74859
|
const { profile } = actionCommand.optsWithGlobals();
|
|
74614
74860
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|