@go-to-k/cdkd 0.163.0 → 0.164.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
@@ -37,6 +37,8 @@ import { AddTagsToResourceCommand as AddTagsToResourceCommand$1, CreateDBCluster
37
37
  import { Command, Option } from "commander";
38
38
  import { writeFileSync as writeFileSync$1 } from "fs";
39
39
  import { join as join$1 } from "path";
40
+ import * as readline$1 from "node:readline/promises";
41
+ import readline from "node:readline/promises";
40
42
  import * as zlib from "node:zlib";
41
43
  import { ApplicationAutoScalingClient, DeleteScalingPolicyCommand, DeregisterScalableTargetCommand, DescribeScalableTargetsCommand, DescribeScalingPoliciesCommand, PutScalingPolicyCommand, RegisterScalableTargetCommand } from "@aws-sdk/client-application-auto-scaling";
42
44
  import { ApiGatewayV2Client, CreateApiCommand, CreateAuthorizerCommand as CreateAuthorizerCommand$1, CreateIntegrationCommand, CreateRouteCommand as CreateRouteCommand$1, CreateStageCommand as CreateStageCommand$1, DeleteApiCommand, DeleteAuthorizerCommand as DeleteAuthorizerCommand$1, DeleteIntegrationCommand, DeleteRouteCommand as DeleteRouteCommand$1, DeleteStageCommand as DeleteStageCommand$1, GetApiCommand, GetApisCommand, GetAuthorizerCommand as GetAuthorizerCommand$1, GetIntegrationCommand, GetRouteCommand, GetStageCommand as GetStageCommand$1, NotFoundException as NotFoundException$3, UpdateApiCommand, UpdateAuthorizerCommand as UpdateAuthorizerCommand$1, UpdateIntegrationCommand, UpdateRouteCommand, UpdateStageCommand as UpdateStageCommand$1 } from "@aws-sdk/client-apigatewayv2";
@@ -59,7 +61,6 @@ import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteP
59
61
  import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$18, ListVectorBucketsCommand, S3VectorsClient } from "@aws-sdk/client-s3vectors";
60
62
  import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand as ListTablesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$19, NotFoundException as NotFoundException$5, S3TablesClient } from "@aws-sdk/client-s3tables";
61
63
  import { AttachLoadBalancerTargetGroupsCommand, AttachLoadBalancersCommand, AttachTrafficSourcesCommand, AutoScalingClient, CreateAutoScalingGroupCommand, CreateOrUpdateTagsCommand, DeleteAutoScalingGroupCommand, DeleteLifecycleHookCommand, DeleteNotificationConfigurationCommand, DeleteTagsCommand as DeleteTagsCommand$1, DescribeAutoScalingGroupsCommand, DescribeLifecycleHooksCommand, DescribeNotificationConfigurationsCommand, DescribeTrafficSourcesCommand, DetachLoadBalancerTargetGroupsCommand, DetachLoadBalancersCommand, DetachTrafficSourcesCommand, DisableMetricsCollectionCommand, EnableMetricsCollectionCommand, PutLifecycleHookCommand, PutNotificationConfigurationCommand, UpdateAutoScalingGroupCommand } from "@aws-sdk/client-auto-scaling";
62
- import * as readline from "node:readline/promises";
63
64
  import { Document, Pair, Scalar, YAMLMap, YAMLSeq, parse as parse$1, stringify } from "yaml";
64
65
  import { mkdir, mkdtemp } from "node:fs/promises";
65
66
  import { Readable } from "node:stream";
@@ -1255,6 +1256,62 @@ async function probeAndRevalidateStateful(input) {
1255
1256
  };
1256
1257
  }
1257
1258
 
1259
+ //#endregion
1260
+ //#region src/cli/commands/recreate-confirm-prompt.ts
1261
+ /**
1262
+ * Interactive confirmation prompt for `cdkd deploy --recreate-via-cc-api`
1263
+ * (issue [#649]).
1264
+ *
1265
+ * Mirror of {@link ../prefix-migration-check.ts}'s `promptMigrationConfirm`
1266
+ * but for the recreate-via-cc-api destroy+recreate cycle:
1267
+ *
1268
+ * - `opts.yes` (CDK CLI parity `-y` / `--yes`) skips the prompt and
1269
+ * prints the per-target plan as a `WARN` block (the existing v1
1270
+ * surface). CI use case.
1271
+ * - When `opts.yes` is false, the prompt fires after the per-target
1272
+ * plan. Default is `N` because the side effect is destructive
1273
+ * (a per-resource destroy + recreate cycle).
1274
+ * - Non-TTY guard: if `opts.yes` is false AND stdin is not a TTY,
1275
+ * throws with an actionable message rather than hanging or
1276
+ * silently declining. CI runs without `--yes` would otherwise look
1277
+ * like a successful skipped-deploy.
1278
+ *
1279
+ * The per-target plan surfaces a **DATA LOSS** prefix for stateful
1280
+ * targets (those with a non-null `statefulReason` after the live
1281
+ * `s3:ListObjectsV2` probe — see issue [#648]); these reached pre-flight
1282
+ * only because the user opted in with `--force-stateful-recreation`,
1283
+ * so the prompt's **DATA LOSS** wording is the third "stop and think"
1284
+ * moment.
1285
+ */
1286
+ async function promptRecreateConfirm(input) {
1287
+ if (input.targets.length === 0) return true;
1288
+ const logger = getLogger();
1289
+ logger.warn("");
1290
+ logger.warn(`--recreate-via-cc-api will destroy + recreate ${input.targets.length} resource(s) via Cloud Control API on stack ${input.stackName}:`);
1291
+ for (const t of input.targets) {
1292
+ const stateful = t.statefulReason !== null;
1293
+ const dataLossPrefix = stateful ? "**DATA LOSS** " : "";
1294
+ const stateNote = stateful ? ` — stateful (${t.statefulReason}); --force-stateful-recreation acknowledged` : "";
1295
+ logger.warn(` - ${dataLossPrefix}${t.logicalId} (${t.resourceType})${stateNote}`);
1296
+ if (stateful) logger.warn(` DATA: all data in ${t.logicalId} will be lost (no automatic data migration)`);
1297
+ }
1298
+ logger.warn(" The destroy + recreate cycle is per-resource; sibling resources are unaffected. Downstream consumers of any recreated resource's outputs (Fn::GetStackOutput / Fn::ImportValue) will need a re-deploy to see the new physical id.");
1299
+ if (input.yes) return true;
1300
+ if (process.stdin.isTTY !== true) throw new Error("--recreate-via-cc-api confirm prompt cannot run in a non-interactive environment. Pass --yes / -y to confirm the destroy + recreate cycle, or run the deploy from a real terminal.");
1301
+ const rl = readline.createInterface({
1302
+ input: process.stdin,
1303
+ output: process.stdout
1304
+ });
1305
+ try {
1306
+ const trimmed = (await rl.question("\nContinue? (y/N): ")).trim().toLowerCase();
1307
+ if (trimmed === "y" || trimmed === "yes") return true;
1308
+ logger.info("Deploy cancelled — no resources modified.");
1309
+ return false;
1310
+ } finally {
1311
+ rl.close();
1312
+ }
1313
+ }
1314
+
1258
1315
  //#endregion
1259
1316
  //#region src/state/export-index-store.ts
1260
1317
  /**
@@ -32451,7 +32508,7 @@ async function runDestroyForStack(stackName, state, ctx) {
32451
32508
  for (const [logicalId, resource] of Object.entries(state.resources)) logger.info(` - ${logicalId} (${resource.resourceType})`);
32452
32509
  const protectedCount = ctx.removeProtection ? countProtectedResources(state) : 0;
32453
32510
  if (!ctx.skipConfirmation) {
32454
- const rl = readline.createInterface({
32511
+ const rl = readline$1.createInterface({
32455
32512
  input: process.stdin,
32456
32513
  output: process.stdout
32457
32514
  });
@@ -33522,7 +33579,7 @@ async function promptMigrationConfirm(renames, opts) {
33522
33579
  logger.warn("These resources will be REPLACED because the new naming convention drops the stack-name prefix.");
33523
33580
  if (opts.yes) return true;
33524
33581
  if (process.stdin.isTTY !== true) throw new Error("--no-prefix-user-supplied-names migration confirm prompt cannot run in a non-interactive environment. Pass --yes / -y to confirm the REPLACEMENT, or run the deploy from a real terminal.");
33525
- const rl = readline.createInterface({
33582
+ const rl = readline$1.createInterface({
33526
33583
  input: process.stdin,
33527
33584
  output: process.stdout
33528
33585
  });
@@ -33736,12 +33793,11 @@ async function deployCommand(stacks, options) {
33736
33793
  if (errorBlock) throw new CdkdError(errorBlock, "RECREATE_VIA_CC_API_INVALID");
33737
33794
  recreateViaCcApiTargets = new Set(validation.targets.map((t) => t.logicalId));
33738
33795
  if (recreateViaCcApiTargets.size > 0) {
33739
- logger.warn(`--recreate-via-cc-api will destroy + recreate ${recreateViaCcApiTargets.size} resource(s) via Cloud Control API on stack ${stackInfo.stackName}:`);
33740
- for (const t of validation.targets) {
33741
- const stateNote = t.statefulReason !== null ? ` ⚠ stateful (${t.statefulReason}) — --force-stateful-recreation acknowledged` : "";
33742
- logger.warn(` - ${t.logicalId} (${t.resourceType})${stateNote}`);
33743
- }
33744
- logger.warn(" The destroy + recreate cycle is per-resource; sibling resources are unaffected. Downstream consumers of any recreated resource's outputs (Fn::GetStackOutput / Fn::ImportValue) will need a re-deploy to see the new physical id.");
33796
+ if (!await promptRecreateConfirm({
33797
+ stackName: stackInfo.stackName,
33798
+ targets: validation.targets,
33799
+ yes: options.yes ?? false
33800
+ })) return;
33745
33801
  }
33746
33802
  }
33747
33803
  const deployEngineOptions = {
@@ -34634,7 +34690,7 @@ async function walkCfnStackTree(stackName, physicalId, cfnClient) {
34634
34690
  };
34635
34691
  }
34636
34692
  async function confirmPrompt$5(prompt) {
34637
- const rl = readline.createInterface({
34693
+ const rl = readline$1.createInterface({
34638
34694
  input: process.stdin,
34639
34695
  output: process.stdout
34640
34696
  });
@@ -35914,7 +35970,7 @@ async function runWithConcurrency(tasks, concurrency) {
35914
35970
  await Promise.all(workers);
35915
35971
  }
35916
35972
  async function confirmPrompt$4(prompt) {
35917
- const rl = readline.createInterface({
35973
+ const rl = readline$1.createInterface({
35918
35974
  input: process.stdin,
35919
35975
  output: process.stdout
35920
35976
  });
@@ -36883,7 +36939,7 @@ function stringifyForAudit(value) {
36883
36939
  return JSON.stringify(value);
36884
36940
  }
36885
36941
  async function confirmPrompt$3(prompt) {
36886
- const rl = readline.createInterface({
36942
+ const rl = readline$1.createInterface({
36887
36943
  input: process.stdin,
36888
36944
  output: process.stdout
36889
36945
  });
@@ -37372,7 +37428,7 @@ async function emptyBucketAllVersions(s3, bucket) {
37372
37428
  } while (keyMarker || versionIdMarker);
37373
37429
  }
37374
37430
  async function confirmPrompt$2(prompt) {
37375
- const rl = readline.createInterface({
37431
+ const rl = readline$1.createInterface({
37376
37432
  input: process.stdin,
37377
37433
  output: process.stdout
37378
37434
  });
@@ -39789,7 +39845,7 @@ function printNextSteps(args) {
39789
39845
  logger.info("");
39790
39846
  }
39791
39847
  async function confirmPrompt$1(prompt) {
39792
- const rl = readline.createInterface({
39848
+ const rl = readline$1.createInterface({
39793
39849
  input: process.stdin,
39794
39850
  output: process.stdout
39795
39851
  });
@@ -40368,7 +40424,7 @@ async function stateOrphanCommand(stackArgs, options) {
40368
40424
  if (!options.yes && !options.force) {
40369
40425
  const targetList = targets.map((t) => formatStackRef(t)).join(", ");
40370
40426
  process.stdout.write(`\nWARNING: This removes cdkd's state record for [${targetList}] only. AWS resources will NOT be deleted.\nUse 'cdkd destroy ${stackName}' if you want to delete the actual resources.\n\n`);
40371
- const rl = readline.createInterface({
40427
+ const rl = readline$1.createInterface({
40372
40428
  input: process.stdin,
40373
40429
  output: process.stdout
40374
40430
  });
@@ -40465,7 +40521,7 @@ async function stateDestroyCommand(stackArgs, options) {
40465
40521
  process.stdout.write(`\nWARNING: This destroys ${stackNames.length} stack(s) and removes their state records:\n`);
40466
40522
  for (const name of stackNames) process.stdout.write(` - ${name}\n`);
40467
40523
  process.stdout.write("\n");
40468
- const rl = readline.createInterface({
40524
+ const rl = readline$1.createInterface({
40469
40525
  input: process.stdin,
40470
40526
  output: process.stdout
40471
40527
  });
@@ -40928,7 +40984,7 @@ async function refreshObservedForStack(stackName, region, stateBackend, lockMana
40928
40984
  }
40929
40985
  }
40930
40986
  async function confirmRefresh(prompt) {
40931
- const rl = readline.createInterface({
40987
+ const rl = readline$1.createInterface({
40932
40988
  input: process.stdin,
40933
40989
  output: process.stdout
40934
40990
  });
@@ -41544,7 +41600,7 @@ function formatOutcome(outcome) {
41544
41600
  }
41545
41601
  }
41546
41602
  async function confirmPrompt(prompt) {
41547
- const rl = readline.createInterface({
41603
+ const rl = readline$1.createInterface({
41548
41604
  input: process.stdin,
41549
41605
  output: process.stdout
41550
41606
  });
@@ -60449,7 +60505,7 @@ function reorderArgs(argv) {
60449
60505
  */
60450
60506
  async function main() {
60451
60507
  const program = new Command();
60452
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.163.0");
60508
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.164.0");
60453
60509
  program.addCommand(createBootstrapCommand());
60454
60510
  program.addCommand(createSynthCommand());
60455
60511
  program.addCommand(createListCommand());