@go-to-k/cdkd 0.18.0 → 0.19.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
@@ -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];
@@ -14178,7 +14229,8 @@ var LogsLogGroupProvider = class {
14178
14229
  import {
14179
14230
  PutMetricAlarmCommand,
14180
14231
  DeleteAlarmsCommand,
14181
- DescribeAlarmsCommand
14232
+ DescribeAlarmsCommand,
14233
+ ListTagsForResourceCommand as ListTagsForResourceCommand3
14182
14234
  } from "@aws-sdk/client-cloudwatch";
14183
14235
  init_aws_clients();
14184
14236
  var CloudWatchAlarmProvider = class {
@@ -14396,6 +14448,62 @@ var CloudWatchAlarmProvider = class {
14396
14448
  }
14397
14449
  return params;
14398
14450
  }
14451
+ /**
14452
+ * Adopt an existing CloudWatch alarm into cdkd state.
14453
+ *
14454
+ * Lookup order:
14455
+ * 1. `--resource` override or `Properties.AlarmName` → verify via `DescribeAlarms`.
14456
+ * 2. `DescribeAlarms` paginated, then `ListTagsForResource(AlarmArn)` per
14457
+ * alarm to match `aws:cdk:path`.
14458
+ */
14459
+ async import(input) {
14460
+ const explicit = resolveExplicitPhysicalId(input, "AlarmName");
14461
+ if (explicit) {
14462
+ try {
14463
+ const resp = await this.cloudWatchClient.send(
14464
+ new DescribeAlarmsCommand({ AlarmNames: [explicit] })
14465
+ );
14466
+ return resp.MetricAlarms?.[0] || resp.CompositeAlarms?.[0] ? { physicalId: explicit, attributes: {} } : null;
14467
+ } catch (err) {
14468
+ if (this.isNotFound(err))
14469
+ return null;
14470
+ throw err;
14471
+ }
14472
+ }
14473
+ if (!input.cdkPath)
14474
+ return null;
14475
+ let nextToken;
14476
+ do {
14477
+ const list = await this.cloudWatchClient.send(
14478
+ new DescribeAlarmsCommand({ ...nextToken && { NextToken: nextToken } })
14479
+ );
14480
+ const all = [...list.MetricAlarms ?? [], ...list.CompositeAlarms ?? []];
14481
+ for (const a of all) {
14482
+ if (!a.AlarmArn || !a.AlarmName)
14483
+ continue;
14484
+ try {
14485
+ const tagsResp = await this.cloudWatchClient.send(
14486
+ new ListTagsForResourceCommand3({ ResourceARN: a.AlarmArn })
14487
+ );
14488
+ if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
14489
+ return { physicalId: a.AlarmName, attributes: {} };
14490
+ }
14491
+ } catch (err) {
14492
+ if (this.isNotFound(err))
14493
+ continue;
14494
+ throw err;
14495
+ }
14496
+ }
14497
+ nextToken = list.NextToken;
14498
+ } while (nextToken);
14499
+ return null;
14500
+ }
14501
+ isNotFound(err) {
14502
+ if (!(err instanceof Error))
14503
+ return false;
14504
+ const name = err.name ?? "";
14505
+ return name === "ResourceNotFoundException" || name === "ResourceNotFound";
14506
+ }
14399
14507
  };
14400
14508
 
14401
14509
  // src/provisioning/providers/secretsmanager-secret-provider.ts
@@ -14729,7 +14837,7 @@ var SecretsManagerSecretProvider = class {
14729
14837
  import {
14730
14838
  DescribeParametersCommand,
14731
14839
  GetParameterCommand as GetParameterCommand3,
14732
- ListTagsForResourceCommand as ListTagsForResourceCommand3,
14840
+ ListTagsForResourceCommand as ListTagsForResourceCommand4,
14733
14841
  PutParameterCommand,
14734
14842
  DeleteParameterCommand,
14735
14843
  AddTagsToResourceCommand,
@@ -14977,7 +15085,7 @@ var SSMParameterProvider = class {
14977
15085
  continue;
14978
15086
  try {
14979
15087
  const tagsResp = await this.ssmClient.send(
14980
- new ListTagsForResourceCommand3({ ResourceType: "Parameter", ResourceId: p.Name })
15088
+ new ListTagsForResourceCommand4({ ResourceType: "Parameter", ResourceId: p.Name })
14981
15089
  );
14982
15090
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
14983
15091
  return { physicalId: p.Name, attributes: {} };
@@ -15292,7 +15400,7 @@ import {
15292
15400
  DescribeEventBusCommand,
15293
15401
  ListEventBusesCommand,
15294
15402
  ListRulesCommand,
15295
- ListTagsForResourceCommand as ListTagsForResourceCommand4,
15403
+ ListTagsForResourceCommand as ListTagsForResourceCommand5,
15296
15404
  RemoveTargetsCommand as RemoveTargetsCommand2,
15297
15405
  DeleteRuleCommand as DeleteRuleCommand2,
15298
15406
  ListTargetsByRuleCommand as ListTargetsByRuleCommand2,
@@ -15564,7 +15672,7 @@ var EventBridgeBusProvider = class {
15564
15672
  continue;
15565
15673
  try {
15566
15674
  const tagsResp = await this.eventBridgeClient.send(
15567
- new ListTagsForResourceCommand4({ ResourceARN: bus.Arn })
15675
+ new ListTagsForResourceCommand5({ ResourceARN: bus.Arn })
15568
15676
  );
15569
15677
  if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
15570
15678
  return { physicalId: bus.Name, attributes: {} };
@@ -18639,6 +18747,8 @@ import {
18639
18747
  DeleteRouteCommand as DeleteRouteCommand2,
18640
18748
  CreateAuthorizerCommand as CreateAuthorizerCommand2,
18641
18749
  DeleteAuthorizerCommand as DeleteAuthorizerCommand2,
18750
+ GetApiCommand,
18751
+ GetApisCommand,
18642
18752
  NotFoundException as NotFoundException4
18643
18753
  } from "@aws-sdk/client-apigatewayv2";
18644
18754
  var ApiGatewayV2Provider = class {
@@ -19172,6 +19282,56 @@ var ApiGatewayV2Provider = class {
19172
19282
  );
19173
19283
  }
19174
19284
  }
19285
+ // ─── Import ───────────────────────────────────────────────────────
19286
+ /**
19287
+ * Adopt an existing API Gateway V2 resource into cdkd state.
19288
+ *
19289
+ * `AWS::ApiGatewayV2::Api` supports full tag-based auto-lookup via
19290
+ * `GetApis` (`Tags` is a `Record<string,string>` map on each item).
19291
+ *
19292
+ * Sub-resources (`Stage`, `Integration`, `Route`, `Authorizer`) are
19293
+ * scoped under a parent `ApiId`, and their physical ids are not
19294
+ * globally unique — auto-lookup would need to walk every Api in the
19295
+ * account and every sub-resource within. Explicit-override only;
19296
+ * users adopt an existing HTTP API by passing
19297
+ * `--resource <logicalId>=<physicalId>` for each sub-resource.
19298
+ */
19299
+ async import(input) {
19300
+ if (input.resourceType !== "AWS::ApiGatewayV2::Api") {
19301
+ if (input.knownPhysicalId) {
19302
+ return { physicalId: input.knownPhysicalId, attributes: {} };
19303
+ }
19304
+ return null;
19305
+ }
19306
+ const explicit = resolveExplicitPhysicalId(input, null);
19307
+ if (explicit) {
19308
+ try {
19309
+ await this.getClient().send(new GetApiCommand({ ApiId: explicit }));
19310
+ return { physicalId: explicit, attributes: {} };
19311
+ } catch (err) {
19312
+ if (err instanceof NotFoundException4)
19313
+ return null;
19314
+ throw err;
19315
+ }
19316
+ }
19317
+ if (!input.cdkPath)
19318
+ return null;
19319
+ let nextToken;
19320
+ do {
19321
+ const list = await this.getClient().send(
19322
+ new GetApisCommand({ ...nextToken && { NextToken: nextToken } })
19323
+ );
19324
+ for (const api of list.Items ?? []) {
19325
+ if (!api.ApiId)
19326
+ continue;
19327
+ if (api.Tags?.[CDK_PATH_TAG] === input.cdkPath) {
19328
+ return { physicalId: api.ApiId, attributes: {} };
19329
+ }
19330
+ }
19331
+ nextToken = list.NextToken;
19332
+ } while (nextToken);
19333
+ return null;
19334
+ }
19175
19335
  // ─── Helpers ──────────────────────────────────────────────────────
19176
19336
  /**
19177
19337
  * Convert CloudFormation Tags (Array<{Key, Value}>) to SDK Tags (Record<string, string>).
@@ -19345,7 +19505,7 @@ import {
19345
19505
  GetDistributionCommand,
19346
19506
  GetDistributionConfigCommand,
19347
19507
  ListDistributionsCommand,
19348
- ListTagsForResourceCommand as ListTagsForResourceCommand5,
19508
+ ListTagsForResourceCommand as ListTagsForResourceCommand6,
19349
19509
  NoSuchDistribution
19350
19510
  } from "@aws-sdk/client-cloudfront";
19351
19511
  init_aws_clients();
@@ -19781,7 +19941,7 @@ var CloudFrontDistributionProvider = class {
19781
19941
  continue;
19782
19942
  try {
19783
19943
  const tagsResp = await this.cloudFrontClient.send(
19784
- new ListTagsForResourceCommand5({ Resource: d.ARN })
19944
+ new ListTagsForResourceCommand6({ Resource: d.ARN })
19785
19945
  );
19786
19946
  if (matchesCdkPath(tagsResp.Tags?.Items, input.cdkPath)) {
19787
19947
  return { physicalId: d.Id, attributes: {} };
@@ -20288,7 +20448,7 @@ import {
20288
20448
  DescribeServicesCommand,
20289
20449
  ListClustersCommand,
20290
20450
  ListServicesCommand,
20291
- ListTagsForResourceCommand as ListTagsForResourceCommand6
20451
+ ListTagsForResourceCommand as ListTagsForResourceCommand7
20292
20452
  } from "@aws-sdk/client-ecs";
20293
20453
  function convertTags(tags) {
20294
20454
  if (!tags || tags.length === 0)
@@ -21066,7 +21226,7 @@ var ECSProvider = class {
21066
21226
  );
21067
21227
  for (const arn of list.clusterArns ?? []) {
21068
21228
  const tagsResp = await this.getClient().send(
21069
- new ListTagsForResourceCommand6({ resourceArn: arn })
21229
+ new ListTagsForResourceCommand7({ resourceArn: arn })
21070
21230
  );
21071
21231
  if (this.tagsMatchCdkPath(tagsResp.tags, input.cdkPath)) {
21072
21232
  const name = arn.substring(arn.lastIndexOf("/") + 1);
@@ -21099,7 +21259,7 @@ var ECSProvider = class {
21099
21259
  );
21100
21260
  for (const svcArn of svcList.serviceArns ?? []) {
21101
21261
  const tagsResp = await this.getClient().send(
21102
- new ListTagsForResourceCommand6({ resourceArn: svcArn })
21262
+ new ListTagsForResourceCommand7({ resourceArn: svcArn })
21103
21263
  );
21104
21264
  if (this.tagsMatchCdkPath(tagsResp.tags, input.cdkPath)) {
21105
21265
  const svcName = svcArn.substring(svcArn.lastIndexOf("/") + 1);
@@ -21673,7 +21833,7 @@ import {
21673
21833
  DeleteDBSubnetGroupCommand,
21674
21834
  DescribeDBSubnetGroupsCommand,
21675
21835
  ModifyDBSubnetGroupCommand,
21676
- ListTagsForResourceCommand as ListTagsForResourceCommand7
21836
+ ListTagsForResourceCommand as ListTagsForResourceCommand8
21677
21837
  } from "@aws-sdk/client-rds";
21678
21838
  var RDSProvider = class {
21679
21839
  rdsClient;
@@ -22314,7 +22474,7 @@ var RDSProvider = class {
22314
22474
  if (!inst.DBInstanceIdentifier || !inst.DBInstanceArn)
22315
22475
  continue;
22316
22476
  const tagsResp = await this.getClient().send(
22317
- new ListTagsForResourceCommand7({ ResourceName: inst.DBInstanceArn })
22477
+ new ListTagsForResourceCommand8({ ResourceName: inst.DBInstanceArn })
22318
22478
  );
22319
22479
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
22320
22480
  return { physicalId: inst.DBInstanceIdentifier, attributes: {} };
@@ -22349,7 +22509,7 @@ var RDSProvider = class {
22349
22509
  if (!c.DBClusterIdentifier || !c.DBClusterArn)
22350
22510
  continue;
22351
22511
  const tagsResp = await this.getClient().send(
22352
- new ListTagsForResourceCommand7({ ResourceName: c.DBClusterArn })
22512
+ new ListTagsForResourceCommand8({ ResourceName: c.DBClusterArn })
22353
22513
  );
22354
22514
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
22355
22515
  return { physicalId: c.DBClusterIdentifier, attributes: {} };
@@ -22384,7 +22544,7 @@ var RDSProvider = class {
22384
22544
  if (!sg.DBSubnetGroupName || !sg.DBSubnetGroupArn)
22385
22545
  continue;
22386
22546
  const tagsResp = await this.getClient().send(
22387
- new ListTagsForResourceCommand7({ ResourceName: sg.DBSubnetGroupArn })
22547
+ new ListTagsForResourceCommand8({ ResourceName: sg.DBSubnetGroupArn })
22388
22548
  );
22389
22549
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
22390
22550
  return { physicalId: sg.DBSubnetGroupName, attributes: {} };
@@ -23290,7 +23450,7 @@ import {
23290
23450
  UpdateUserPoolCommand,
23291
23451
  DescribeUserPoolCommand,
23292
23452
  ListUserPoolsCommand,
23293
- ListTagsForResourceCommand as ListTagsForResourceCommand8,
23453
+ ListTagsForResourceCommand as ListTagsForResourceCommand9,
23294
23454
  ResourceNotFoundException as ResourceNotFoundException12
23295
23455
  } from "@aws-sdk/client-cognito-identity-provider";
23296
23456
  var CognitoUserPoolProvider = class {
@@ -23675,7 +23835,7 @@ var CognitoUserPoolProvider = class {
23675
23835
  if (!arn)
23676
23836
  continue;
23677
23837
  const tagsResp = await this.getClient().send(
23678
- new ListTagsForResourceCommand8({ ResourceArn: arn })
23838
+ new ListTagsForResourceCommand9({ ResourceArn: arn })
23679
23839
  );
23680
23840
  if (tagsResp.Tags?.[CDK_PATH_TAG] === input.cdkPath) {
23681
23841
  return { physicalId: pool.Id, attributes: {} };
@@ -24461,7 +24621,10 @@ import {
24461
24621
  DeleteResolverCommand,
24462
24622
  CreateApiKeyCommand,
24463
24623
  DeleteApiKeyCommand,
24464
- StartSchemaCreationCommand
24624
+ StartSchemaCreationCommand,
24625
+ GetGraphqlApiCommand,
24626
+ ListGraphqlApisCommand,
24627
+ NotFoundException as AppSyncNotFoundException
24465
24628
  } from "@aws-sdk/client-appsync";
24466
24629
  var AppSyncProvider = class {
24467
24630
  client;
@@ -24969,6 +25132,51 @@ var AppSyncProvider = class {
24969
25132
  const name = error.name ?? "";
24970
25133
  return message.includes("not found") || message.includes("does not exist") || name === "NotFoundException";
24971
25134
  }
25135
+ /**
25136
+ * Adopt an existing AppSync resource into cdkd state.
25137
+ *
25138
+ * `AWS::AppSync::GraphQLApi` supports full tag-based auto-lookup via
25139
+ * `ListGraphqlApis` (each item carries a `tags` map). AppSync sub-resources
25140
+ * (`GraphQLSchema`, `DataSource`, `Resolver`, `ApiKey`) are scoped under a
25141
+ * parent `apiId` and cannot be discovered by tag at the account level —
25142
+ * explicit-override only.
25143
+ */
25144
+ async import(input) {
25145
+ if (input.resourceType !== "AWS::AppSync::GraphQLApi") {
25146
+ if (input.knownPhysicalId) {
25147
+ return { physicalId: input.knownPhysicalId, attributes: {} };
25148
+ }
25149
+ return null;
25150
+ }
25151
+ const explicit = resolveExplicitPhysicalId(input, null);
25152
+ if (explicit) {
25153
+ try {
25154
+ await this.getClient().send(new GetGraphqlApiCommand({ apiId: explicit }));
25155
+ return { physicalId: explicit, attributes: {} };
25156
+ } catch (err) {
25157
+ if (err instanceof AppSyncNotFoundException)
25158
+ return null;
25159
+ throw err;
25160
+ }
25161
+ }
25162
+ if (!input.cdkPath)
25163
+ return null;
25164
+ let nextToken;
25165
+ do {
25166
+ const list = await this.getClient().send(
25167
+ new ListGraphqlApisCommand({ ...nextToken && { nextToken } })
25168
+ );
25169
+ for (const api of list.graphqlApis ?? []) {
25170
+ if (!api.apiId)
25171
+ continue;
25172
+ if (api.tags?.[CDK_PATH_TAG] === input.cdkPath) {
25173
+ return { physicalId: api.apiId, attributes: {} };
25174
+ }
25175
+ }
25176
+ nextToken = list.nextToken;
25177
+ } while (nextToken);
25178
+ return null;
25179
+ }
24972
25180
  };
24973
25181
 
24974
25182
  // src/provisioning/providers/glue-provider.ts
@@ -26907,6 +27115,9 @@ import {
26907
27115
  StopLoggingCommand,
26908
27116
  PutEventSelectorsCommand,
26909
27117
  PutInsightSelectorsCommand,
27118
+ GetTrailCommand,
27119
+ ListTrailsCommand,
27120
+ ListTagsCommand as ListTagsCommand2,
26910
27121
  TrailNotFoundException
26911
27122
  } from "@aws-sdk/client-cloudtrail";
26912
27123
  var CloudTrailProvider = class {
@@ -27138,6 +27349,54 @@ var CloudTrailProvider = class {
27138
27349
  getAttribute(_physicalId, _resourceType, attributeName) {
27139
27350
  return Promise.resolve(attributeName);
27140
27351
  }
27352
+ /**
27353
+ * Adopt an existing CloudTrail trail into cdkd state.
27354
+ *
27355
+ * Lookup order:
27356
+ * 1. `--resource` override or `Properties.TrailName` → verify via `GetTrail`.
27357
+ * 2. `ListTrails` + `ListTags` (CloudTrail uses `Tag[]` arrays per ARN),
27358
+ * match `aws:cdk:path` tag.
27359
+ */
27360
+ async import(input) {
27361
+ const explicit = resolveExplicitPhysicalId(input, "TrailName");
27362
+ if (explicit) {
27363
+ try {
27364
+ await this.getClient().send(new GetTrailCommand({ Name: explicit }));
27365
+ return { physicalId: explicit, attributes: {} };
27366
+ } catch (err) {
27367
+ if (err instanceof TrailNotFoundException)
27368
+ return null;
27369
+ throw err;
27370
+ }
27371
+ }
27372
+ if (!input.cdkPath)
27373
+ return null;
27374
+ let nextToken;
27375
+ do {
27376
+ const list = await this.getClient().send(
27377
+ new ListTrailsCommand({ ...nextToken && { NextToken: nextToken } })
27378
+ );
27379
+ for (const trail of list.Trails ?? []) {
27380
+ if (!trail.TrailARN || !trail.Name)
27381
+ continue;
27382
+ try {
27383
+ const tagsResp = await this.getClient().send(
27384
+ new ListTagsCommand2({ ResourceIdList: [trail.TrailARN] })
27385
+ );
27386
+ const list2 = tagsResp.ResourceTagList?.[0];
27387
+ if (matchesCdkPath(list2?.TagsList, input.cdkPath)) {
27388
+ return { physicalId: trail.Name, attributes: {} };
27389
+ }
27390
+ } catch (err) {
27391
+ if (err instanceof TrailNotFoundException)
27392
+ continue;
27393
+ throw err;
27394
+ }
27395
+ }
27396
+ nextToken = list.NextToken;
27397
+ } while (nextToken);
27398
+ return null;
27399
+ }
27141
27400
  };
27142
27401
 
27143
27402
  // src/provisioning/providers/codebuild-provider.ts
@@ -27146,6 +27405,8 @@ import {
27146
27405
  CreateProjectCommand,
27147
27406
  DeleteProjectCommand,
27148
27407
  UpdateProjectCommand,
27408
+ BatchGetProjectsCommand,
27409
+ ListProjectsCommand,
27149
27410
  ResourceNotFoundException as ResourceNotFoundException15
27150
27411
  } from "@aws-sdk/client-codebuild";
27151
27412
  var CodeBuildProvider = class {
@@ -27404,6 +27665,54 @@ var CodeBuildProvider = class {
27404
27665
  getAttribute(_physicalId, _resourceType, attributeName) {
27405
27666
  return Promise.resolve(attributeName);
27406
27667
  }
27668
+ /**
27669
+ * Adopt an existing CodeBuild project into cdkd state.
27670
+ *
27671
+ * Lookup order:
27672
+ * 1. `--resource` override or `Properties.Name` → verify via `BatchGetProjects`.
27673
+ * 2. `ListProjects` + `BatchGetProjects` (CodeBuild uses lowercase
27674
+ * `key`/`value` tags, not the standard `Key`/`Value`), match
27675
+ * `aws:cdk:path` tag.
27676
+ */
27677
+ async import(input) {
27678
+ const explicit = resolveExplicitPhysicalId(input, "Name");
27679
+ if (explicit) {
27680
+ try {
27681
+ const resp = await this.getClient().send(
27682
+ new BatchGetProjectsCommand({ names: [explicit] })
27683
+ );
27684
+ return resp.projects?.[0]?.name ? { physicalId: explicit, attributes: {} } : null;
27685
+ } catch (err) {
27686
+ if (err instanceof ResourceNotFoundException15)
27687
+ return null;
27688
+ throw err;
27689
+ }
27690
+ }
27691
+ if (!input.cdkPath)
27692
+ return null;
27693
+ let nextToken;
27694
+ do {
27695
+ const list = await this.getClient().send(
27696
+ new ListProjectsCommand({ ...nextToken && { nextToken } })
27697
+ );
27698
+ const names = (list.projects ?? []).filter((n) => typeof n === "string");
27699
+ if (names.length > 0) {
27700
+ const batch = await this.getClient().send(new BatchGetProjectsCommand({ names }));
27701
+ for (const proj of batch.projects ?? []) {
27702
+ if (!proj.name)
27703
+ continue;
27704
+ const tags = proj.tags ?? [];
27705
+ for (const t of tags) {
27706
+ if (t.key === CDK_PATH_TAG && t.value === input.cdkPath) {
27707
+ return { physicalId: proj.name, attributes: {} };
27708
+ }
27709
+ }
27710
+ }
27711
+ }
27712
+ nextToken = list.nextToken;
27713
+ } while (nextToken);
27714
+ return null;
27715
+ }
27407
27716
  };
27408
27717
 
27409
27718
  // src/provisioning/providers/s3-vectors-provider.ts
@@ -28195,6 +28504,7 @@ import {
28195
28504
  PutImageScanningConfigurationCommand,
28196
28505
  PutImageTagMutabilityCommand,
28197
28506
  TagResourceCommand as TagResourceCommand7,
28507
+ ListTagsForResourceCommand as ListTagsForResourceCommand10,
28198
28508
  RepositoryNotFoundException
28199
28509
  } from "@aws-sdk/client-ecr";
28200
28510
  var ECRProvider = class {
@@ -28428,6 +28738,56 @@ var ECRProvider = class {
28428
28738
  );
28429
28739
  }
28430
28740
  }
28741
+ /**
28742
+ * Adopt an existing ECR repository into cdkd state.
28743
+ *
28744
+ * Lookup order:
28745
+ * 1. `--resource` override or `Properties.RepositoryName` → verify via
28746
+ * `DescribeRepositories`.
28747
+ * 2. `DescribeRepositories` paginated, then `ListTagsForResource(arn)`
28748
+ * per repository to match `aws:cdk:path` (`Tag[]` array shape).
28749
+ */
28750
+ async import(input) {
28751
+ const explicit = resolveExplicitPhysicalId(input, "RepositoryName");
28752
+ if (explicit) {
28753
+ try {
28754
+ const resp = await this.getClient().send(
28755
+ new DescribeRepositoriesCommand({ repositoryNames: [explicit] })
28756
+ );
28757
+ return resp.repositories?.[0]?.repositoryName ? { physicalId: explicit, attributes: {} } : null;
28758
+ } catch (err) {
28759
+ if (err instanceof RepositoryNotFoundException)
28760
+ return null;
28761
+ throw err;
28762
+ }
28763
+ }
28764
+ if (!input.cdkPath)
28765
+ return null;
28766
+ let nextToken;
28767
+ do {
28768
+ const list = await this.getClient().send(
28769
+ new DescribeRepositoriesCommand({ ...nextToken && { nextToken } })
28770
+ );
28771
+ for (const repo of list.repositories ?? []) {
28772
+ if (!repo.repositoryArn || !repo.repositoryName)
28773
+ continue;
28774
+ try {
28775
+ const tagsResp = await this.getClient().send(
28776
+ new ListTagsForResourceCommand10({ resourceArn: repo.repositoryArn })
28777
+ );
28778
+ if (matchesCdkPath(tagsResp.tags, input.cdkPath)) {
28779
+ return { physicalId: repo.repositoryName, attributes: {} };
28780
+ }
28781
+ } catch (err) {
28782
+ if (err instanceof RepositoryNotFoundException)
28783
+ continue;
28784
+ throw err;
28785
+ }
28786
+ }
28787
+ nextToken = list.nextToken;
28788
+ } while (nextToken);
28789
+ return null;
28790
+ }
28431
28791
  };
28432
28792
 
28433
28793
  // src/provisioning/register-providers.ts
@@ -29998,6 +30358,68 @@ async function deployCommand(stacks, options) {
29998
30358
  }
29999
30359
  const summary = workGraph.summary();
30000
30360
  logger.debug(`Work graph: ${summary["asset-publish"]} asset(s), ${summary["stack"]} stack(s)`);
30361
+ const bufferStackOutput = targetStacks.length > 1;
30362
+ const runStack = async (stackInfo) => {
30363
+ const stackRegion = stackInfo.region || baseRegion;
30364
+ logger.info(
30365
+ `
30366
+ Deploying stack: ${stackInfo.stackName}${stackRegion !== baseRegion ? ` (region: ${stackRegion})` : ""}`
30367
+ );
30368
+ switchRegion(stackRegion);
30369
+ const stackAwsClients = new AwsClients({
30370
+ region: stackRegion,
30371
+ ...options.profile && { profile: options.profile }
30372
+ });
30373
+ setAwsClients(stackAwsClients);
30374
+ const stateS3Client = new AwsClients({
30375
+ region: baseRegion,
30376
+ ...options.profile && { profile: options.profile }
30377
+ });
30378
+ const stackStateBackend = new S3StateBackend(stateS3Client.s3, stateConfig, {
30379
+ region: baseRegion,
30380
+ ...options.profile && { profile: options.profile }
30381
+ });
30382
+ const stackLockManager = new LockManager(stateS3Client.s3, stateConfig);
30383
+ const stackProviderRegistry = new ProviderRegistry();
30384
+ registerAllProviders(stackProviderRegistry);
30385
+ stackProviderRegistry.setCustomResourceResponseBucket(stateBucket, baseRegion);
30386
+ const stackDeployEngine = new DeployEngine(
30387
+ stackStateBackend,
30388
+ stackLockManager,
30389
+ dagBuilder,
30390
+ diffCalculator,
30391
+ stackProviderRegistry,
30392
+ {
30393
+ concurrency: options.concurrency,
30394
+ dryRun: options.dryRun,
30395
+ noRollback: !options.rollback
30396
+ },
30397
+ stackRegion
30398
+ );
30399
+ try {
30400
+ const deployResult = await stackDeployEngine.deploy(
30401
+ stackInfo.stackName,
30402
+ stackInfo.template
30403
+ );
30404
+ logger.info("\nDeployment Summary:");
30405
+ logger.info(` Stack: ${deployResult.stackName}`);
30406
+ logger.info(` Created: ${deployResult.created}`);
30407
+ logger.info(` Updated: ${deployResult.updated}`);
30408
+ logger.info(` Deleted: ${deployResult.deleted}`);
30409
+ logger.info(` Unchanged: ${deployResult.unchanged}`);
30410
+ logger.info(` Duration: ${(deployResult.durationMs / 1e3).toFixed(2)}s`);
30411
+ if (options.dryRun) {
30412
+ logger.info("\n\u2713 Dry run completed - no actual changes made");
30413
+ } else {
30414
+ logger.info("\n\u2713 Deployment completed successfully");
30415
+ }
30416
+ } finally {
30417
+ stackAwsClients.destroy();
30418
+ stateS3Client.destroy();
30419
+ switchRegion(baseRegion);
30420
+ setAwsClients(awsClients);
30421
+ }
30422
+ };
30001
30423
  await workGraph.execute(
30002
30424
  {
30003
30425
  "asset-build": options.imageBuildConcurrency,
@@ -30009,65 +30431,16 @@ async function deployCommand(stacks, options) {
30009
30431
  await assetPublisher.executeNode(node);
30010
30432
  } else {
30011
30433
  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);
30434
+ if (!bufferStackOutput) {
30435
+ await runStack(stackInfo);
30436
+ return;
30437
+ }
30438
+ const outcome = await runStackBuffered(() => runStack(stackInfo));
30439
+ if (outcome.lines.length > 0) {
30440
+ process.stdout.write(outcome.lines.join("\n") + "\n");
30070
30441
  }
30442
+ if (!outcome.ok)
30443
+ throw outcome.error;
30071
30444
  }
30072
30445
  }
30073
30446
  );
@@ -32326,7 +32699,7 @@ function reorderArgs(argv) {
32326
32699
  }
32327
32700
  async function main() {
32328
32701
  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");
32702
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.19.0");
32330
32703
  program.addCommand(createBootstrapCommand());
32331
32704
  program.addCommand(createSynthCommand());
32332
32705
  program.addCommand(createListCommand());