@go-to-k/cdkd 0.165.0 → 0.166.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,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { _ as withSkipPrefix, a as runDockerStreaming, c as getLogger, d as getLiveRenderer, f as PATTERN_B_NAME_PROPERTIES, g as generateResourceNameWithFallback, h as generateResourceName, i as runDockerForeground, n as formatDockerLoginError, p as PATTERN_B_RESOURCE_TYPES, r as getDockerCmd, u as runStackBuffered, v as withStackName } from "./docker-cmd-iDMcWcre.js";
3
- import { A as S3StateBackend, B as resolveCaptureObservedState, C as assertRegionMatch, D as DagBuilder, E as DiffCalculator, F as buildDockerImage, G as CFN_TEMPLATE_BODY_LIMIT, H as resolveStateBucketWithDefault, I as Synthesizer, J as findLargeInlineResources, K as CFN_TEMPLATE_URL_LIMIT, L as getDefaultStateBucketName, M as AssetPublisher, N as stringifyValue, O as TemplateParser, P as WorkGraph, Q as resolveBucketRegion, R as getLegacyStateBucketName, S as CloudControlProvider, T as applyRoleArnIfSet, U as resolveStateBucketWithDefaultAndSource, V as resolveSkipPrefix, W as warnDeprecatedNoPrefixCliFlag, X as AssemblyReader, Y as uploadCfnTemplate, _ as matchesCdkPath, a as withRetry, at as LocalStartServiceError, b as ProviderRegistry, bt as normalizeAwsError, c as bold, ct as NestedStackChildDirectDestroyError, d as green, dt as ResourceTimeoutError, et as CdkdError, f as red, ft as ResourceUpdateNotSupportedError, g as CDK_PATH_TAG, h as collectInlinePolicyNamesManagedBySiblings, ht as StackTerminationProtectionError, i as withResourceDeadline, it as LocalMigrateError, j as shouldRetainResource, k as LockManager, l as cyan, lt as PartialFailureError, m as IAMRoleProvider, mt as StackHasActiveImportsError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as IMPLICIT_DELETE_DEPENDENCIES, p as yellow, pt as RouteDiscoveryError, q as MIGRATE_TMP_PREFIX, r as DeployEngine, rt as LocalInvokeBuildError, s as formatResourceLine, st as MissingCdkCliError, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as gray, ut as ProvisioningError, v as normalizeAwsTagsToCfn, w as IntrinsicFunctionResolver, x as findActionableSilentDrops, xt as withErrorHandling, y as resolveExplicitPhysicalId, z as resolveApp } from "./deploy-engine-DEbogepd.js";
3
+ import { A as S3StateBackend, B as resolveCaptureObservedState, C as assertRegionMatch, D as DagBuilder, E as DiffCalculator, F as buildDockerImage, G as CFN_TEMPLATE_BODY_LIMIT, H as resolveStateBucketWithDefault, I as Synthesizer, J as findLargeInlineResources, K as CFN_TEMPLATE_URL_LIMIT, L as getDefaultStateBucketName, M as AssetPublisher, N as stringifyValue, O as TemplateParser, P as WorkGraph, Q as resolveBucketRegion, R as getLegacyStateBucketName, S as CloudControlProvider, T as applyRoleArnIfSet, U as resolveStateBucketWithDefaultAndSource, V as resolveSkipPrefix, W as warnDeprecatedNoPrefixCliFlag, X as AssemblyReader, Y as uploadCfnTemplate, _ as matchesCdkPath, a as withRetry, at as LocalStartServiceError, b as ProviderRegistry, bt as normalizeAwsError, c as bold, ct as NestedStackChildDirectDestroyError, d as green, dt as ResourceTimeoutError, et as CdkdError, f as red, ft as ResourceUpdateNotSupportedError, g as CDK_PATH_TAG, h as collectInlinePolicyNamesManagedBySiblings, ht as StackTerminationProtectionError, i as withResourceDeadline, it as LocalMigrateError, j as shouldRetainResource, k as LockManager, l as cyan, lt as PartialFailureError, m as IAMRoleProvider, mt as StackHasActiveImportsError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as IMPLICIT_DELETE_DEPENDENCIES, p as yellow, pt as RouteDiscoveryError, q as MIGRATE_TMP_PREFIX, r as DeployEngine, rt as LocalInvokeBuildError, s as formatResourceLine, st as MissingCdkCliError, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as gray, ut as ProvisioningError, v as normalizeAwsTagsToCfn, w as IntrinsicFunctionResolver, x as findActionableSilentDrops, xt as withErrorHandling, y as resolveExplicitPhysicalId, z as resolveApp } from "./deploy-engine-BQkk03hJ.js";
4
4
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-B15NAPbL.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, createHmac, createPublicKey, createVerify, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
@@ -449,6 +449,27 @@ function parseRecreateViaCcApiToken(value, previous) {
449
449
  }
450
450
  const recreateViaCcApiOption = new Option("--recreate-via-cc-api <logicalId>", "Destroy + recreate the named resource (by CloudFormation logical id) via Cloud Control API in this deploy, so a top-level CFn property cdkd would otherwise silently drop reaches AWS via CC. Repeatable — pass the flag once per resource. Per-resource opt-in (no bulk / no per-stack shortcut) so the destroy-and-recreate cost is acknowledged for each target. Stateful resource types (RDS, DynamoDB, S3, EFS, ...) refuse unless --force-stateful-recreation is ALSO passed (two-flag protection). Cannot be combined with --allow-unsupported-properties on the same resource type and property.").argParser(parseRecreateViaCcApiToken);
451
451
  /**
452
+ * Issue [#651] — `--recreate-via-sdk-provider <LogicalId>` is the reverse
453
+ * direction of `--recreate-via-cc-api`. Once a resource is sticky on
454
+ * `provisionedBy: 'cc-api'` (e.g. after a #615 SDK→CC migration, or
455
+ * because cdkd auto-routed it via the #614 default-on Cloud Control
456
+ * fallback on a fresh deploy), subsequent SDK Provider backfills
457
+ * (issue #609) do NOT auto-migrate it back — sticky semantics avoid
458
+ * SDK↔CC ping-pong on every backfill release. This flag is the
459
+ * user-initiated CC → SDK migration: destroy + recreate the named
460
+ * resource so the new copy is `provisionedBy: 'sdk'`.
461
+ *
462
+ * Symmetric to `--recreate-via-cc-api`: same per-resource explicit
463
+ * opt-in, same destroy-then-create ordering, same stateful guard,
464
+ * same multi-region refusal, same `Continue? (y/N)` interactive prompt.
465
+ */
466
+ function parseRecreateViaSdkProviderToken(value, previous) {
467
+ const token = value.trim();
468
+ if (!LOGICAL_ID_FORMAT.test(token)) throw new Error(`Invalid --recreate-via-sdk-provider value "${value}": expected a CloudFormation logical id (alphanumeric, starts with a letter, max 255 chars). One --recreate-via-sdk-provider flag per resource — repeat the flag for additional targets.`);
469
+ return [...previous ?? [], token];
470
+ }
471
+ const recreateViaSdkProviderOption = new Option("--recreate-via-sdk-provider <logicalId>", "Destroy + recreate the named resource (by CloudFormation logical id) via cdkd's SDK Provider in this deploy, so a resource currently sticky on provisionedBy: cc-api flips back to provisionedBy: sdk. Used after a #609 backfill release adds SDK coverage for a type the user originally needed CC for (e.g. Lambda LoggingConfig). Repeatable — pass the flag once per resource. Per-resource opt-in. Stateful resource types refuse unless --force-stateful-recreation is ALSO passed.").argParser(parseRecreateViaSdkProviderToken);
472
+ /**
452
473
  * Issue [#615] — `--force-stateful-recreation` (boolean) is the second
453
474
  * flag required to allow `--recreate-via-cc-api` to operate on a
454
475
  * stateful resource (RDS / DynamoDB / EFS / S3 with data / etc.). Two
@@ -480,6 +501,7 @@ const deployOptions = [
480
501
  allowUnsupportedTypesOption,
481
502
  allowUnsupportedPropertiesOption,
482
503
  recreateViaCcApiOption,
504
+ recreateViaSdkProviderOption,
483
505
  forceStatefulRecreationOption,
484
506
  ...resourceTimeoutOptions
485
507
  ];
@@ -1089,16 +1111,31 @@ function renderStatefulReason(reason) {
1089
1111
  */
1090
1112
  const EMPTY_ALLOW_SET$1 = /* @__PURE__ */ new Set();
1091
1113
  function validateRecreateTargets(input) {
1114
+ const seenCcApi = new Set(input.recreateViaCcApi);
1115
+ const seenSdk = new Set(input.recreateViaSdkProvider ?? []);
1116
+ const conflictingDirections = [...seenCcApi].filter((id) => seenSdk.has(id));
1092
1117
  const seen = /* @__PURE__ */ new Set();
1093
1118
  const targets = [];
1094
1119
  const unknownLogicalIds = [];
1095
1120
  const missingFromState = [];
1096
1121
  const ambiguousIntent = [];
1122
+ const ambiguousIntentSdk = [];
1097
1123
  const blockedStatefulTargets = [];
1098
1124
  const blockedMultiRegionTargets = [];
1099
- for (const logicalId of input.recreateViaCcApi) {
1125
+ const blockedAlreadySdk = [];
1126
+ const blockedNoSdkProvider = [];
1127
+ const conflictSet = new Set(conflictingDirections);
1128
+ const namedTargets = [...input.recreateViaCcApi.map((id) => ({
1129
+ logicalId: id,
1130
+ direction: "to-cc-api"
1131
+ })), ...(input.recreateViaSdkProvider ?? []).map((id) => ({
1132
+ logicalId: id,
1133
+ direction: "to-sdk"
1134
+ }))];
1135
+ for (const { logicalId, direction } of namedTargets) {
1100
1136
  if (seen.has(logicalId)) continue;
1101
1137
  seen.add(logicalId);
1138
+ if (conflictSet.has(logicalId)) continue;
1102
1139
  const templateResource = input.template.Resources?.[logicalId];
1103
1140
  if (!templateResource) {
1104
1141
  unknownLogicalIds.push(logicalId);
@@ -1114,18 +1151,30 @@ function validateRecreateTargets(input) {
1114
1151
  logicalId,
1115
1152
  resourceType,
1116
1153
  physicalId: recordedResource.physicalId,
1117
- statefulReason: isStatefulRecreateTargetSync(resourceType, recordedResource.properties)
1154
+ statefulReason: isStatefulRecreateTargetSync(resourceType, recordedResource.properties),
1155
+ direction
1118
1156
  };
1119
1157
  targets.push(target);
1120
1158
  if (MULTI_REGION_RECREATE_BLOCKED_TYPES.has(resourceType)) blockedMultiRegionTargets.push(target);
1121
- const actionableDrops = findActionableSilentDrops(resourceType, templateResource.Properties, EMPTY_ALLOW_SET$1);
1122
- for (const { property } of actionableDrops) {
1123
- const allowKey = `${resourceType}:${property}`;
1124
- if (input.allowUnsupportedProperties.has(allowKey)) ambiguousIntent.push({
1159
+ if (direction === "to-cc-api") {
1160
+ const actionableDrops = findActionableSilentDrops(resourceType, templateResource.Properties, EMPTY_ALLOW_SET$1);
1161
+ for (const { property } of actionableDrops) {
1162
+ const allowKey = `${resourceType}:${property}`;
1163
+ if (input.allowUnsupportedProperties.has(allowKey)) ambiguousIntent.push({
1164
+ logicalId,
1165
+ resourceType,
1166
+ property
1167
+ });
1168
+ }
1169
+ } else {
1170
+ const actionableDrops = findActionableSilentDrops(resourceType, templateResource.Properties, input.allowUnsupportedProperties);
1171
+ for (const { property } of actionableDrops) ambiguousIntentSdk.push({
1125
1172
  logicalId,
1126
1173
  resourceType,
1127
1174
  property
1128
1175
  });
1176
+ if (!(recordedResource.provisionedBy === "cc-api")) blockedAlreadySdk.push(target);
1177
+ if (input.hasSdkProvider && !input.hasSdkProvider(resourceType)) blockedNoSdkProvider.push(target);
1129
1178
  }
1130
1179
  if (target.statefulReason !== null && !input.forceStatefulRecreation) blockedStatefulTargets.push(target);
1131
1180
  }
@@ -1134,8 +1183,12 @@ function validateRecreateTargets(input) {
1134
1183
  unknownLogicalIds,
1135
1184
  missingFromState,
1136
1185
  ambiguousIntent,
1186
+ ambiguousIntentSdk,
1137
1187
  blockedStatefulTargets,
1138
- blockedMultiRegionTargets
1188
+ blockedMultiRegionTargets,
1189
+ blockedAlreadySdk,
1190
+ blockedNoSdkProvider,
1191
+ conflictingDirections
1139
1192
  };
1140
1193
  }
1141
1194
  /**
@@ -1147,16 +1200,17 @@ function validateRecreateTargets(input) {
1147
1200
  */
1148
1201
  function renderRecreateTargetsErrors(validation) {
1149
1202
  const lines = [];
1203
+ const FLAG_UMBRELLA = "--recreate-via-cc-api / --recreate-via-sdk-provider";
1150
1204
  if (validation.unknownLogicalIds.length > 0) {
1151
- lines.push(`--recreate-via-cc-api named ${validation.unknownLogicalIds.length} logical id(s) not present in the synth template:`);
1205
+ lines.push(`${FLAG_UMBRELLA} named ${validation.unknownLogicalIds.length} logical id(s) not present in the synth template:`);
1152
1206
  for (const id of validation.unknownLogicalIds) lines.push(` - ${id}`);
1153
1207
  lines.push(" Fix: confirm each id exists in the template (CDK display path is the parent; the logical id is the CFn-emitted name, e.g. cdkd synth | jq '.Resources | keys'). Recreate operates on the synth template's logical ids, not CDK display paths.");
1154
1208
  }
1155
1209
  if (validation.missingFromState.length > 0) {
1156
1210
  if (lines.length > 0) lines.push("");
1157
- lines.push(`--recreate-via-cc-api named ${validation.missingFromState.length} logical id(s) the template declares but cdkd state has no record of:`);
1211
+ lines.push(`${FLAG_UMBRELLA} named ${validation.missingFromState.length} logical id(s) the template declares but cdkd state has no record of:`);
1158
1212
  for (const id of validation.missingFromState) lines.push(` - ${id}`);
1159
- lines.push(" These are fresh CREATEs on the next deploy — recreate has nothing to destroy first. Remove the --recreate-via-cc-api flag for these resources; the new auto-route via Cloud Control (#614) handles fresh deploys.");
1213
+ lines.push(" These are fresh CREATEs on the next deploy — recreate has nothing to destroy first. Remove the flag for these resources; the auto-route via Cloud Control (#614) handles fresh deploys for silent-drop properties, and SDK Provider is the default for everything else.");
1160
1214
  }
1161
1215
  if (validation.ambiguousIntent.length > 0) {
1162
1216
  if (lines.length > 0) lines.push("");
@@ -1166,15 +1220,39 @@ function renderRecreateTargetsErrors(validation) {
1166
1220
  }
1167
1221
  if (validation.blockedStatefulTargets.length > 0) {
1168
1222
  if (lines.length > 0) lines.push("");
1169
- lines.push(`--recreate-via-cc-api would destroy + recreate ${validation.blockedStatefulTargets.length} stateful resource(s). Recreate loses ALL data — no automatic data migration. Re-run with --force-stateful-recreation to acknowledge the data-loss footgun.`);
1223
+ lines.push(`${FLAG_UMBRELLA} would destroy + recreate ${validation.blockedStatefulTargets.length} stateful resource(s). Recreate loses ALL data — no automatic data migration. Re-run with --force-stateful-recreation to acknowledge the data-loss footgun.`);
1170
1224
  for (const blocked of validation.blockedStatefulTargets) lines.push(` - ${blocked.logicalId} (${blocked.resourceType}) — ${renderStatefulReason(blocked.statefulReason)}`);
1171
1225
  }
1172
1226
  if (validation.blockedMultiRegionTargets.length > 0) {
1173
1227
  if (lines.length > 0) lines.push("");
1174
- lines.push(`--recreate-via-cc-api refuses to operate on ${validation.blockedMultiRegionTargets.length} multi-region resource(s) — out of scope for v1 of this flag (the destroy + recreate cycle across replica regions is more involved than the single-region path):`);
1228
+ lines.push(`--recreate-via-cc-api / --recreate-via-sdk-provider refuses to operate on ${validation.blockedMultiRegionTargets.length} multi-region resource(s) — out of scope for v1 of these flags (the destroy + recreate cycle across replica regions is more involved than the single-region path):`);
1175
1229
  for (const blocked of validation.blockedMultiRegionTargets) lines.push(` - ${blocked.logicalId} (${blocked.resourceType})`);
1176
1230
  lines.push(" No --force-stateful-recreation bypass — this category is structurally unsupported in v1. File an issue if you need this path.");
1177
1231
  }
1232
+ if (validation.conflictingDirections.length > 0) {
1233
+ if (lines.length > 0) lines.push("");
1234
+ lines.push(`Conflicting recreate direction — ${validation.conflictingDirections.length} logical id(s) named in BOTH --recreate-via-cc-api AND --recreate-via-sdk-provider:`);
1235
+ for (const id of validation.conflictingDirections) lines.push(` - ${id}`);
1236
+ lines.push(" Fix: pick ONE direction per resource. The two flags drive opposite provisionedBy targets ('cc-api' vs 'sdk').");
1237
+ }
1238
+ if (validation.blockedAlreadySdk.length > 0) {
1239
+ if (lines.length > 0) lines.push("");
1240
+ lines.push(`--recreate-via-sdk-provider named ${validation.blockedAlreadySdk.length} resource(s) that are NOT currently sticky on Cloud Control API (the reverse migration is a no-op):`);
1241
+ for (const blocked of validation.blockedAlreadySdk) lines.push(` - ${blocked.logicalId} (${blocked.resourceType})`);
1242
+ lines.push(" Fix: remove --recreate-via-sdk-provider <id> for these resources. They are already SDK-managed (or pre-v7 legacy state, treated as SDK).");
1243
+ }
1244
+ if (validation.blockedNoSdkProvider.length > 0) {
1245
+ if (lines.length > 0) lines.push("");
1246
+ lines.push(`--recreate-via-sdk-provider named ${validation.blockedNoSdkProvider.length} resource(s) of types cdkd has no SDK provider for (Tier 2 CC-only):`);
1247
+ for (const blocked of validation.blockedNoSdkProvider) lines.push(` - ${blocked.logicalId} (${blocked.resourceType})`);
1248
+ lines.push(" Fix: remove --recreate-via-sdk-provider <id> for these resources. The destroy + recreate would route via Cloud Control anyway — there's no SDK alternative available.");
1249
+ }
1250
+ if (validation.ambiguousIntentSdk.length > 0) {
1251
+ if (lines.length > 0) lines.push("");
1252
+ lines.push(`Inverse ambiguous intent — ${validation.ambiguousIntentSdk.length} --recreate-via-sdk-provider target(s) would IMMEDIATELY be re-routed back to Cloud Control after the recreate because their template uses silent-drop properties NOT in --allow-unsupported-properties:`);
1253
+ for (const overlap of validation.ambiguousIntentSdk) lines.push(` - ${overlap.logicalId} (${overlap.resourceType}) — template uses ${overlap.property}; the default-on CC auto-route would re-route the recreated resource back to CC immediately`);
1254
+ lines.push(" Fix: pass --allow-unsupported-properties <Type>:<Prop> for each silent-drop property so the recreated resource stays on SDK with the property explicitly dropped. Or drop --recreate-via-sdk-provider — the resource already routes via CC and honors the property.");
1255
+ }
1178
1256
  return lines.length > 0 ? lines.join("\n") : null;
1179
1257
  }
1180
1258
  /**
@@ -1225,7 +1303,7 @@ async function probeStatefulRecreateTargetsAsync(targets, s3Client, logger = get
1225
1303
  });
1226
1304
  else promoted.push({ ...target });
1227
1305
  } catch (e) {
1228
- logger.warn(`--recreate-via-cc-api: live S3 probe failed for ${target.logicalId} (bucket ${target.physicalId}); leaving stateful guard at the sync result. If the bucket might be non-empty, re-run with --force-stateful-recreation. Underlying error: ${e instanceof Error ? e.message : String(e)}`);
1306
+ logger.warn(`--recreate-via-cc-api / --recreate-via-sdk-provider: live S3 probe failed for ${target.logicalId} (bucket ${target.physicalId}); leaving stateful guard at the sync result. If the bucket might be non-empty, re-run with --force-stateful-recreation. Underlying error: ${e instanceof Error ? e.message : String(e)}`);
1229
1307
  promoted.push({ ...target });
1230
1308
  }
1231
1309
  }
@@ -1347,13 +1425,18 @@ function renderDownstreamConsumers(producerStack, consumers) {
1347
1425
  async function promptRecreateConfirm(input) {
1348
1426
  if (input.targets.length === 0) return true;
1349
1427
  const logger = getLogger();
1428
+ const toCcCount = input.targets.filter((t) => t.direction === "to-cc-api").length;
1429
+ const toSdkCount = input.targets.filter((t) => t.direction === "to-sdk").length;
1350
1430
  logger.warn("");
1351
- logger.warn(`--recreate-via-cc-api will destroy + recreate ${input.targets.length} resource(s) via Cloud Control API on stack ${input.stackName}:`);
1431
+ if (toCcCount > 0 && toSdkCount > 0) logger.warn(`recreate-via-cc-api / recreate-via-sdk-provider will destroy + recreate ${input.targets.length} resource(s) on stack ${input.stackName} (${toCcCount} → Cloud Control, ${toSdkCount} → SDK Provider):`);
1432
+ else if (toCcCount > 0) logger.warn(`--recreate-via-cc-api will destroy + recreate ${toCcCount} resource(s) via Cloud Control API on stack ${input.stackName}:`);
1433
+ else logger.warn(`--recreate-via-sdk-provider will destroy + recreate ${toSdkCount} resource(s) via SDK Provider on stack ${input.stackName}:`);
1352
1434
  for (const t of input.targets) {
1353
1435
  const stateful = t.statefulReason !== null;
1354
1436
  const dataLossPrefix = stateful ? "**DATA LOSS** " : "";
1437
+ const directionTag = t.direction === "to-cc-api" ? " [SDK → CC]" : " [CC → SDK]";
1355
1438
  const stateNote = stateful ? ` — stateful (${t.statefulReason}); --force-stateful-recreation acknowledged` : "";
1356
- logger.warn(` - ${dataLossPrefix}${t.logicalId} (${t.resourceType})${stateNote}`);
1439
+ logger.warn(` - ${dataLossPrefix}${t.logicalId} (${t.resourceType})${directionTag}${stateNote}`);
1357
1440
  if (stateful) logger.warn(` DATA: all data in ${t.logicalId} will be lost (no automatic data migration)`);
1358
1441
  }
1359
1442
  if (input.downstreamConsumers && input.downstreamConsumers.length > 0) {
@@ -33834,7 +33917,8 @@ async function deployCommand(stacks, options) {
33834
33917
  }
33835
33918
  }
33836
33919
  let recreateViaCcApiTargets;
33837
- if (options.recreateViaCcApi?.length) {
33920
+ let recreateViaSdkProviderTargets;
33921
+ if (options.recreateViaCcApi?.length || options.recreateViaSdkProvider?.length) {
33838
33922
  const stateForRecreateCheck = await stackStateBackend.getState(stackInfo.stackName, stackRegion);
33839
33923
  const validation = await probeAndRevalidateStateful({
33840
33924
  validation: validateRecreateTargets({
@@ -33847,17 +33931,20 @@ async function deployCommand(stacks, options) {
33847
33931
  outputs: {},
33848
33932
  lastModified: Date.now()
33849
33933
  },
33850
- recreateViaCcApi: options.recreateViaCcApi,
33934
+ recreateViaCcApi: options.recreateViaCcApi ?? [],
33935
+ recreateViaSdkProvider: options.recreateViaSdkProvider ?? [],
33851
33936
  allowUnsupportedProperties: new Set(options.allowUnsupportedProperties ?? []),
33852
- forceStatefulRecreation: options.forceStatefulRecreation ?? false
33937
+ forceStatefulRecreation: options.forceStatefulRecreation ?? false,
33938
+ hasSdkProvider: (rt) => stackProviderRegistry.getProviderType(rt) === "sdk"
33853
33939
  }),
33854
33940
  s3Client: stackAwsClients.s3,
33855
33941
  forceStatefulRecreation: options.forceStatefulRecreation ?? false
33856
33942
  });
33857
33943
  const errorBlock = renderRecreateTargetsErrors(validation);
33858
- if (errorBlock) throw new CdkdError(errorBlock, "RECREATE_VIA_CC_API_INVALID");
33859
- recreateViaCcApiTargets = new Set(validation.targets.map((t) => t.logicalId));
33860
- if (recreateViaCcApiTargets.size > 0) {
33944
+ if (errorBlock) throw new CdkdError(errorBlock, "RECREATE_TARGETS_INVALID");
33945
+ recreateViaCcApiTargets = new Set(validation.targets.filter((t) => t.direction === "to-cc-api").map((t) => t.logicalId));
33946
+ recreateViaSdkProviderTargets = new Set(validation.targets.filter((t) => t.direction === "to-sdk").map((t) => t.logicalId));
33947
+ if (recreateViaCcApiTargets.size > 0 || recreateViaSdkProviderTargets.size > 0) {
33861
33948
  const downstreamConsumers = await findDownstreamConsumers({
33862
33949
  producerStack: stackInfo.stackName,
33863
33950
  producerRegion: stackRegion,
@@ -33877,6 +33964,7 @@ async function deployCommand(stacks, options) {
33877
33964
  dryRun: options.dryRun,
33878
33965
  noRollback: !options.rollback,
33879
33966
  ...recreateViaCcApiTargets && recreateViaCcApiTargets.size > 0 && { recreateViaCcApiTargets },
33967
+ ...recreateViaSdkProviderTargets && recreateViaSdkProviderTargets.size > 0 && { recreateViaSdkProviderTargets },
33880
33968
  captureObservedState: resolveCaptureObservedState(options.captureObservedState),
33881
33969
  ...options.resourceWarnAfter?.globalMs !== void 0 && { resourceWarnAfterMs: options.resourceWarnAfter.globalMs },
33882
33970
  ...options.resourceTimeout?.globalMs !== void 0 && { resourceTimeoutMs: options.resourceTimeout.globalMs },
@@ -60619,7 +60707,7 @@ function reorderArgs(argv) {
60619
60707
  */
60620
60708
  async function main() {
60621
60709
  const program = new Command();
60622
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.165.0");
60710
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.166.0");
60623
60711
  program.addCommand(createBootstrapCommand());
60624
60712
  program.addCommand(createSynthCommand());
60625
60713
  program.addCommand(createListCommand());