@go-to-k/cdkd 0.18.0 → 0.18.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
@@ -537,10 +537,122 @@ var destroyOptions = [
537
537
  )
538
538
  ];
539
539
 
540
+ // src/provisioning/resource-name.ts
541
+ import { AsyncLocalStorage } from "node:async_hooks";
542
+ import { createHash } from "node:crypto";
543
+ var stackNameStore = new AsyncLocalStorage();
544
+ function withStackName(stackName, fn) {
545
+ return stackNameStore.run(stackName, fn);
546
+ }
547
+ function getCurrentStackName() {
548
+ return stackNameStore.getStore();
549
+ }
550
+ function generateResourceName(name, options) {
551
+ const { maxLength, lowercase = false, allowedPattern = /[^a-zA-Z0-9-]/g } = options;
552
+ const currentStackName = stackNameStore.getStore();
553
+ const fullName = currentStackName ? `${currentStackName}-${name}` : name;
554
+ let sanitized = lowercase ? fullName.toLowerCase() : fullName;
555
+ sanitized = sanitized.replace(allowedPattern, "-");
556
+ sanitized = sanitized.replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
557
+ if (sanitized.length <= maxLength) {
558
+ return sanitized;
559
+ }
560
+ const hash = createHash("sha256").update(fullName).digest("hex").substring(0, 8);
561
+ const maxPrefixLength = maxLength - hash.length - 1;
562
+ const prefix = sanitized.substring(0, maxPrefixLength).replace(/-+$/, "");
563
+ return `${prefix}-${hash}`;
564
+ }
565
+ var FALLBACK_NAME_RULES = {
566
+ "AWS::S3::Bucket": { nameProperty: "BucketName", options: { maxLength: 63, lowercase: true } },
567
+ "AWS::SQS::Queue": { nameProperty: "QueueName", options: { maxLength: 80 } },
568
+ "AWS::SNS::Topic": { nameProperty: "TopicName", options: { maxLength: 256 } },
569
+ "AWS::Lambda::Function": { nameProperty: "FunctionName", options: { maxLength: 64 } },
570
+ "AWS::Lambda::LayerVersion": { nameProperty: "LayerName", options: { maxLength: 64 } },
571
+ "AWS::IAM::Role": { nameProperty: "RoleName", options: { maxLength: 64 } },
572
+ "AWS::IAM::Policy": { nameProperty: "PolicyName", options: { maxLength: 64 } },
573
+ "AWS::IAM::User": { nameProperty: "UserName", options: { maxLength: 64 } },
574
+ "AWS::IAM::Group": { nameProperty: "GroupName", options: { maxLength: 128 } },
575
+ "AWS::IAM::InstanceProfile": {
576
+ nameProperty: "InstanceProfileName",
577
+ options: { maxLength: 128 }
578
+ },
579
+ "AWS::DynamoDB::Table": { nameProperty: "TableName", options: { maxLength: 255 } },
580
+ "AWS::ECR::Repository": {
581
+ nameProperty: "RepositoryName",
582
+ options: { maxLength: 256, lowercase: true }
583
+ },
584
+ "AWS::ECS::Cluster": { nameProperty: "ClusterName", options: { maxLength: 255 } },
585
+ "AWS::ECS::Service": { nameProperty: "ServiceName", options: { maxLength: 255 } },
586
+ "AWS::Logs::LogGroup": { nameProperty: "LogGroupName", options: { maxLength: 512 } },
587
+ "AWS::CloudWatch::Alarm": { nameProperty: "AlarmName", options: { maxLength: 256 } },
588
+ "AWS::Events::Rule": { nameProperty: "Name", options: { maxLength: 64 } },
589
+ "AWS::Events::EventBus": { nameProperty: "Name", options: { maxLength: 256 } },
590
+ "AWS::Kinesis::Stream": { nameProperty: "Name", options: { maxLength: 128 } },
591
+ "AWS::StepFunctions::StateMachine": {
592
+ nameProperty: "StateMachineName",
593
+ options: { maxLength: 80 }
594
+ },
595
+ "AWS::SecretsManager::Secret": {
596
+ nameProperty: "Name",
597
+ options: { maxLength: 512, allowedPattern: /[^a-zA-Z0-9-/_]/g }
598
+ },
599
+ "AWS::SSM::Parameter": { nameProperty: "Name", options: { maxLength: 2048 } },
600
+ "AWS::Cognito::UserPool": { nameProperty: "UserPoolName", options: { maxLength: 128 } },
601
+ "AWS::ElastiCache::SubnetGroup": {
602
+ nameProperty: "CacheSubnetGroupName",
603
+ options: { maxLength: 255, lowercase: true }
604
+ },
605
+ "AWS::ElastiCache::CacheCluster": {
606
+ nameProperty: "ClusterName",
607
+ options: { maxLength: 40, lowercase: true }
608
+ },
609
+ "AWS::RDS::DBSubnetGroup": {
610
+ nameProperty: "DBSubnetGroupName",
611
+ options: { maxLength: 255, lowercase: true }
612
+ },
613
+ "AWS::RDS::DBCluster": {
614
+ nameProperty: "DBClusterIdentifier",
615
+ options: { maxLength: 63, lowercase: true }
616
+ },
617
+ "AWS::RDS::DBInstance": {
618
+ nameProperty: "DBInstanceIdentifier",
619
+ options: { maxLength: 63, lowercase: true }
620
+ },
621
+ "AWS::ElasticLoadBalancingV2::LoadBalancer": {
622
+ nameProperty: "Name",
623
+ options: { maxLength: 32 }
624
+ },
625
+ "AWS::ElasticLoadBalancingV2::TargetGroup": {
626
+ nameProperty: "Name",
627
+ options: { maxLength: 32 }
628
+ },
629
+ "AWS::WAFv2::WebACL": { nameProperty: "Name", options: { maxLength: 128 } },
630
+ "AWS::CodeBuild::Project": { nameProperty: "Name", options: { maxLength: 255 } },
631
+ "AWS::S3Express::DirectoryBucket": {
632
+ nameProperty: "BucketName",
633
+ options: { maxLength: 63, lowercase: true }
634
+ }
635
+ };
636
+ function applyDefaultNameForFallback(logicalId, resourceType, properties) {
637
+ const rule = FALLBACK_NAME_RULES[resourceType];
638
+ if (!rule)
639
+ return properties;
640
+ if (properties[rule.nameProperty])
641
+ return properties;
642
+ const generatedName = generateResourceName(logicalId, rule.options);
643
+ return {
644
+ ...properties,
645
+ [rule.nameProperty]: generatedName
646
+ };
647
+ }
648
+
540
649
  // src/utils/live-renderer.ts
541
650
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
542
651
  var FRAME_INTERVAL_MS = 80;
543
652
  var ESC = "\x1B[";
653
+ function scopedKey(id, stackName) {
654
+ return stackName ? `${stackName}:${id}` : id;
655
+ }
544
656
  var LiveRenderer = class {
545
657
  constructor(stream = process.stdout) {
546
658
  this.stream = stream;
@@ -594,12 +706,14 @@ var LiveRenderer = class {
594
706
  this.active = false;
595
707
  }
596
708
  addTask(id, label) {
597
- this.tasks.set(id, { label, startedAt: Date.now() });
709
+ const stackName = getCurrentStackName();
710
+ this.tasks.set(scopedKey(id, stackName), { label, startedAt: Date.now(), stackName });
598
711
  if (this.active)
599
712
  this.draw();
600
713
  }
601
714
  removeTask(id) {
602
- if (!this.tasks.delete(id))
715
+ const stackName = getCurrentStackName();
716
+ if (!this.tasks.delete(scopedKey(id, stackName)))
603
717
  return;
604
718
  if (this.active)
605
719
  this.draw();
@@ -635,11 +749,16 @@ var LiveRenderer = class {
635
749
  return;
636
750
  const frame = SPINNER_FRAMES[this.spinnerIndex % SPINNER_FRAMES.length];
637
751
  this.spinnerIndex++;
752
+ const distinctStacks = /* @__PURE__ */ new Set();
753
+ for (const task of this.tasks.values())
754
+ distinctStacks.add(task.stackName);
755
+ const showStackPrefix = distinctStacks.size > 1;
638
756
  const cols = this.stream.columns ?? 80;
639
757
  const lines = [];
640
758
  for (const task of this.tasks.values()) {
641
759
  const elapsed = ((Date.now() - task.startedAt) / 1e3).toFixed(1);
642
- const raw = ` ${frame} ${task.label} (${elapsed}s)`;
760
+ const prefix = showStackPrefix && task.stackName ? `[${task.stackName}] ` : "";
761
+ const raw = ` ${frame} ${prefix}${task.label} (${elapsed}s)`;
643
762
  lines.push(this.truncate(raw, cols));
644
763
  }
645
764
  this.stream.write(lines.join("\n") + "\n");
@@ -672,6 +791,24 @@ function getLiveRenderer() {
672
791
  return globalRenderer;
673
792
  }
674
793
 
794
+ // src/utils/stack-context.ts
795
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
796
+ var outputBufferStore = new AsyncLocalStorage2();
797
+ async function runStackBuffered(fn) {
798
+ const buffer = { lines: [] };
799
+ return outputBufferStore.run(buffer, async () => {
800
+ try {
801
+ const result = await fn();
802
+ return { ok: true, result, lines: buffer.lines };
803
+ } catch (error) {
804
+ return { ok: false, error, lines: buffer.lines };
805
+ }
806
+ });
807
+ }
808
+ function getCurrentStackOutputBuffer() {
809
+ return outputBufferStore.getStore();
810
+ }
811
+
675
812
  // src/utils/logger.ts
676
813
  var colors = {
677
814
  reset: "\x1B[0m",
@@ -726,28 +863,48 @@ var ConsoleLogger = class {
726
863
  }
727
864
  return `${message}${formattedArgs}`;
728
865
  }
866
+ /**
867
+ * Route a formatted log line. When a per-stack output buffer is active in
868
+ * the current async context (parallel multi-stack deploy), capture the
869
+ * line into the buffer so it can be flushed as one atomic block when the
870
+ * stack finishes. Otherwise fall through to the live renderer / console
871
+ * as before.
872
+ */
873
+ emit(level, formatted) {
874
+ const buffer = getCurrentStackOutputBuffer();
875
+ if (buffer) {
876
+ buffer.lines.push(formatted);
877
+ return;
878
+ }
879
+ getLiveRenderer().printAbove(() => {
880
+ if (level === "error")
881
+ console.error(formatted);
882
+ else if (level === "warn")
883
+ console.warn(formatted);
884
+ else if (level === "info")
885
+ console.info(formatted);
886
+ else
887
+ console.debug(formatted);
888
+ });
889
+ }
729
890
  debug(message, ...args) {
730
891
  if (this.shouldLog("debug")) {
731
- const formatted = this.formatMessage("debug", message, ...args);
732
- getLiveRenderer().printAbove(() => console.debug(formatted));
892
+ this.emit("debug", this.formatMessage("debug", message, ...args));
733
893
  }
734
894
  }
735
895
  info(message, ...args) {
736
896
  if (this.shouldLog("info")) {
737
- const formatted = this.formatMessage("info", message, ...args);
738
- getLiveRenderer().printAbove(() => console.info(formatted));
897
+ this.emit("info", this.formatMessage("info", message, ...args));
739
898
  }
740
899
  }
741
900
  warn(message, ...args) {
742
901
  if (this.shouldLog("warn")) {
743
- const formatted = this.formatMessage("warn", message, ...args);
744
- getLiveRenderer().printAbove(() => console.warn(formatted));
902
+ this.emit("warn", this.formatMessage("warn", message, ...args));
745
903
  }
746
904
  }
747
905
  error(message, ...args) {
748
906
  if (this.shouldLog("error")) {
749
- const formatted = this.formatMessage("error", message, ...args);
750
- getLiveRenderer().printAbove(() => console.error(formatted));
907
+ this.emit("error", this.formatMessage("error", message, ...args));
751
908
  }
752
909
  }
753
910
  /**
@@ -7765,112 +7922,6 @@ import {
7765
7922
  } from "@aws-sdk/client-iam";
7766
7923
  init_aws_clients();
7767
7924
 
7768
- // src/provisioning/resource-name.ts
7769
- import { AsyncLocalStorage } from "node:async_hooks";
7770
- import { createHash } from "node:crypto";
7771
- var stackNameStore = new AsyncLocalStorage();
7772
- function withStackName(stackName, fn) {
7773
- return stackNameStore.run(stackName, fn);
7774
- }
7775
- function generateResourceName(name, options) {
7776
- const { maxLength, lowercase = false, allowedPattern = /[^a-zA-Z0-9-]/g } = options;
7777
- const currentStackName = stackNameStore.getStore();
7778
- const fullName = currentStackName ? `${currentStackName}-${name}` : name;
7779
- let sanitized = lowercase ? fullName.toLowerCase() : fullName;
7780
- sanitized = sanitized.replace(allowedPattern, "-");
7781
- sanitized = sanitized.replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
7782
- if (sanitized.length <= maxLength) {
7783
- return sanitized;
7784
- }
7785
- const hash = createHash("sha256").update(fullName).digest("hex").substring(0, 8);
7786
- const maxPrefixLength = maxLength - hash.length - 1;
7787
- const prefix = sanitized.substring(0, maxPrefixLength).replace(/-+$/, "");
7788
- return `${prefix}-${hash}`;
7789
- }
7790
- var FALLBACK_NAME_RULES = {
7791
- "AWS::S3::Bucket": { nameProperty: "BucketName", options: { maxLength: 63, lowercase: true } },
7792
- "AWS::SQS::Queue": { nameProperty: "QueueName", options: { maxLength: 80 } },
7793
- "AWS::SNS::Topic": { nameProperty: "TopicName", options: { maxLength: 256 } },
7794
- "AWS::Lambda::Function": { nameProperty: "FunctionName", options: { maxLength: 64 } },
7795
- "AWS::Lambda::LayerVersion": { nameProperty: "LayerName", options: { maxLength: 64 } },
7796
- "AWS::IAM::Role": { nameProperty: "RoleName", options: { maxLength: 64 } },
7797
- "AWS::IAM::Policy": { nameProperty: "PolicyName", options: { maxLength: 64 } },
7798
- "AWS::IAM::User": { nameProperty: "UserName", options: { maxLength: 64 } },
7799
- "AWS::IAM::Group": { nameProperty: "GroupName", options: { maxLength: 128 } },
7800
- "AWS::IAM::InstanceProfile": {
7801
- nameProperty: "InstanceProfileName",
7802
- options: { maxLength: 128 }
7803
- },
7804
- "AWS::DynamoDB::Table": { nameProperty: "TableName", options: { maxLength: 255 } },
7805
- "AWS::ECR::Repository": {
7806
- nameProperty: "RepositoryName",
7807
- options: { maxLength: 256, lowercase: true }
7808
- },
7809
- "AWS::ECS::Cluster": { nameProperty: "ClusterName", options: { maxLength: 255 } },
7810
- "AWS::ECS::Service": { nameProperty: "ServiceName", options: { maxLength: 255 } },
7811
- "AWS::Logs::LogGroup": { nameProperty: "LogGroupName", options: { maxLength: 512 } },
7812
- "AWS::CloudWatch::Alarm": { nameProperty: "AlarmName", options: { maxLength: 256 } },
7813
- "AWS::Events::Rule": { nameProperty: "Name", options: { maxLength: 64 } },
7814
- "AWS::Events::EventBus": { nameProperty: "Name", options: { maxLength: 256 } },
7815
- "AWS::Kinesis::Stream": { nameProperty: "Name", options: { maxLength: 128 } },
7816
- "AWS::StepFunctions::StateMachine": {
7817
- nameProperty: "StateMachineName",
7818
- options: { maxLength: 80 }
7819
- },
7820
- "AWS::SecretsManager::Secret": {
7821
- nameProperty: "Name",
7822
- options: { maxLength: 512, allowedPattern: /[^a-zA-Z0-9-/_]/g }
7823
- },
7824
- "AWS::SSM::Parameter": { nameProperty: "Name", options: { maxLength: 2048 } },
7825
- "AWS::Cognito::UserPool": { nameProperty: "UserPoolName", options: { maxLength: 128 } },
7826
- "AWS::ElastiCache::SubnetGroup": {
7827
- nameProperty: "CacheSubnetGroupName",
7828
- options: { maxLength: 255, lowercase: true }
7829
- },
7830
- "AWS::ElastiCache::CacheCluster": {
7831
- nameProperty: "ClusterName",
7832
- options: { maxLength: 40, lowercase: true }
7833
- },
7834
- "AWS::RDS::DBSubnetGroup": {
7835
- nameProperty: "DBSubnetGroupName",
7836
- options: { maxLength: 255, lowercase: true }
7837
- },
7838
- "AWS::RDS::DBCluster": {
7839
- nameProperty: "DBClusterIdentifier",
7840
- options: { maxLength: 63, lowercase: true }
7841
- },
7842
- "AWS::RDS::DBInstance": {
7843
- nameProperty: "DBInstanceIdentifier",
7844
- options: { maxLength: 63, lowercase: true }
7845
- },
7846
- "AWS::ElasticLoadBalancingV2::LoadBalancer": {
7847
- nameProperty: "Name",
7848
- options: { maxLength: 32 }
7849
- },
7850
- "AWS::ElasticLoadBalancingV2::TargetGroup": {
7851
- nameProperty: "Name",
7852
- options: { maxLength: 32 }
7853
- },
7854
- "AWS::WAFv2::WebACL": { nameProperty: "Name", options: { maxLength: 128 } },
7855
- "AWS::CodeBuild::Project": { nameProperty: "Name", options: { maxLength: 255 } },
7856
- "AWS::S3Express::DirectoryBucket": {
7857
- nameProperty: "BucketName",
7858
- options: { maxLength: 63, lowercase: true }
7859
- }
7860
- };
7861
- function applyDefaultNameForFallback(logicalId, resourceType, properties) {
7862
- const rule = FALLBACK_NAME_RULES[resourceType];
7863
- if (!rule)
7864
- return properties;
7865
- if (properties[rule.nameProperty])
7866
- return properties;
7867
- const generatedName = generateResourceName(logicalId, rule.options);
7868
- return {
7869
- ...properties,
7870
- [rule.nameProperty]: generatedName
7871
- };
7872
- }
7873
-
7874
7925
  // src/provisioning/import-helpers.ts
7875
7926
  function readNameProperty(input, propertyName) {
7876
7927
  const value = input.properties?.[propertyName];
@@ -29998,6 +30049,68 @@ async function deployCommand(stacks, options) {
29998
30049
  }
29999
30050
  const summary = workGraph.summary();
30000
30051
  logger.debug(`Work graph: ${summary["asset-publish"]} asset(s), ${summary["stack"]} stack(s)`);
30052
+ const bufferStackOutput = targetStacks.length > 1;
30053
+ const runStack = async (stackInfo) => {
30054
+ const stackRegion = stackInfo.region || baseRegion;
30055
+ logger.info(
30056
+ `
30057
+ Deploying stack: ${stackInfo.stackName}${stackRegion !== baseRegion ? ` (region: ${stackRegion})` : ""}`
30058
+ );
30059
+ switchRegion(stackRegion);
30060
+ const stackAwsClients = new AwsClients({
30061
+ region: stackRegion,
30062
+ ...options.profile && { profile: options.profile }
30063
+ });
30064
+ setAwsClients(stackAwsClients);
30065
+ const stateS3Client = new AwsClients({
30066
+ region: baseRegion,
30067
+ ...options.profile && { profile: options.profile }
30068
+ });
30069
+ const stackStateBackend = new S3StateBackend(stateS3Client.s3, stateConfig, {
30070
+ region: baseRegion,
30071
+ ...options.profile && { profile: options.profile }
30072
+ });
30073
+ const stackLockManager = new LockManager(stateS3Client.s3, stateConfig);
30074
+ const stackProviderRegistry = new ProviderRegistry();
30075
+ registerAllProviders(stackProviderRegistry);
30076
+ stackProviderRegistry.setCustomResourceResponseBucket(stateBucket, baseRegion);
30077
+ const stackDeployEngine = new DeployEngine(
30078
+ stackStateBackend,
30079
+ stackLockManager,
30080
+ dagBuilder,
30081
+ diffCalculator,
30082
+ stackProviderRegistry,
30083
+ {
30084
+ concurrency: options.concurrency,
30085
+ dryRun: options.dryRun,
30086
+ noRollback: !options.rollback
30087
+ },
30088
+ stackRegion
30089
+ );
30090
+ try {
30091
+ const deployResult = await stackDeployEngine.deploy(
30092
+ stackInfo.stackName,
30093
+ stackInfo.template
30094
+ );
30095
+ logger.info("\nDeployment Summary:");
30096
+ logger.info(` Stack: ${deployResult.stackName}`);
30097
+ logger.info(` Created: ${deployResult.created}`);
30098
+ logger.info(` Updated: ${deployResult.updated}`);
30099
+ logger.info(` Deleted: ${deployResult.deleted}`);
30100
+ logger.info(` Unchanged: ${deployResult.unchanged}`);
30101
+ logger.info(` Duration: ${(deployResult.durationMs / 1e3).toFixed(2)}s`);
30102
+ if (options.dryRun) {
30103
+ logger.info("\n\u2713 Dry run completed - no actual changes made");
30104
+ } else {
30105
+ logger.info("\n\u2713 Deployment completed successfully");
30106
+ }
30107
+ } finally {
30108
+ stackAwsClients.destroy();
30109
+ stateS3Client.destroy();
30110
+ switchRegion(baseRegion);
30111
+ setAwsClients(awsClients);
30112
+ }
30113
+ };
30001
30114
  await workGraph.execute(
30002
30115
  {
30003
30116
  "asset-build": options.imageBuildConcurrency,
@@ -30009,65 +30122,16 @@ async function deployCommand(stacks, options) {
30009
30122
  await assetPublisher.executeNode(node);
30010
30123
  } else {
30011
30124
  const { stack: stackInfo } = node.data;
30012
- const stackRegion = stackInfo.region || baseRegion;
30013
- logger.info(
30014
- `
30015
- Deploying stack: ${stackInfo.stackName}${stackRegion !== baseRegion ? ` (region: ${stackRegion})` : ""}`
30016
- );
30017
- switchRegion(stackRegion);
30018
- const stackAwsClients = new AwsClients({
30019
- region: stackRegion,
30020
- ...options.profile && { profile: options.profile }
30021
- });
30022
- setAwsClients(stackAwsClients);
30023
- const stateS3Client = new AwsClients({
30024
- region: baseRegion,
30025
- ...options.profile && { profile: options.profile }
30026
- });
30027
- const stackStateBackend = new S3StateBackend(stateS3Client.s3, stateConfig, {
30028
- region: baseRegion,
30029
- ...options.profile && { profile: options.profile }
30030
- });
30031
- const stackLockManager = new LockManager(stateS3Client.s3, stateConfig);
30032
- const stackProviderRegistry = new ProviderRegistry();
30033
- registerAllProviders(stackProviderRegistry);
30034
- stackProviderRegistry.setCustomResourceResponseBucket(stateBucket, baseRegion);
30035
- const stackDeployEngine = new DeployEngine(
30036
- stackStateBackend,
30037
- stackLockManager,
30038
- dagBuilder,
30039
- diffCalculator,
30040
- stackProviderRegistry,
30041
- {
30042
- concurrency: options.concurrency,
30043
- dryRun: options.dryRun,
30044
- noRollback: !options.rollback
30045
- },
30046
- stackRegion
30047
- );
30048
- try {
30049
- const deployResult = await stackDeployEngine.deploy(
30050
- stackInfo.stackName,
30051
- stackInfo.template
30052
- );
30053
- logger.info("\nDeployment Summary:");
30054
- logger.info(` Stack: ${deployResult.stackName}`);
30055
- logger.info(` Created: ${deployResult.created}`);
30056
- logger.info(` Updated: ${deployResult.updated}`);
30057
- logger.info(` Deleted: ${deployResult.deleted}`);
30058
- logger.info(` Unchanged: ${deployResult.unchanged}`);
30059
- logger.info(` Duration: ${(deployResult.durationMs / 1e3).toFixed(2)}s`);
30060
- if (options.dryRun) {
30061
- logger.info("\n\u2713 Dry run completed - no actual changes made");
30062
- } else {
30063
- logger.info("\n\u2713 Deployment completed successfully");
30064
- }
30065
- } finally {
30066
- stackAwsClients.destroy();
30067
- stateS3Client.destroy();
30068
- switchRegion(baseRegion);
30069
- setAwsClients(awsClients);
30125
+ if (!bufferStackOutput) {
30126
+ await runStack(stackInfo);
30127
+ return;
30128
+ }
30129
+ const outcome = await runStackBuffered(() => runStack(stackInfo));
30130
+ if (outcome.lines.length > 0) {
30131
+ process.stdout.write(outcome.lines.join("\n") + "\n");
30070
30132
  }
30133
+ if (!outcome.ok)
30134
+ throw outcome.error;
30071
30135
  }
30072
30136
  }
30073
30137
  );
@@ -32326,7 +32390,7 @@ function reorderArgs(argv) {
32326
32390
  }
32327
32391
  async function main() {
32328
32392
  const program = new Command13();
32329
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.18.0");
32393
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.18.1");
32330
32394
  program.addCommand(createBootstrapCommand());
32331
32395
  program.addCommand(createSynthCommand());
32332
32396
  program.addCommand(createListCommand());