@go-to-k/cdkd 0.18.1 → 0.20.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
@@ -1155,11 +1155,11 @@ async function resolveStateBucketWithDefaultAndSource(cliBucket, region) {
1155
1155
  return syncResult;
1156
1156
  const logger = getLogger();
1157
1157
  logger.debug("No state bucket specified, resolving default from account...");
1158
- const { GetCallerIdentityCommand: GetCallerIdentityCommand9 } = await import("@aws-sdk/client-sts");
1158
+ const { GetCallerIdentityCommand: GetCallerIdentityCommand11 } = await import("@aws-sdk/client-sts");
1159
1159
  const { S3Client: S3Client11 } = await import("@aws-sdk/client-s3");
1160
1160
  const { getAwsClients: getAwsClients2 } = await Promise.resolve().then(() => (init_aws_clients(), aws_clients_exports));
1161
1161
  const awsClients = getAwsClients2();
1162
- const identity = await awsClients.sts.send(new GetCallerIdentityCommand9({}));
1162
+ const identity = await awsClients.sts.send(new GetCallerIdentityCommand11({}));
1163
1163
  const accountId = identity.Account;
1164
1164
  const newName = getDefaultStateBucketName(accountId);
1165
1165
  const legacyName = getLegacyStateBucketName(accountId, region);
@@ -3431,9 +3431,9 @@ var AssetPublisher = class {
3431
3431
  const region = options.region || process.env["AWS_REGION"] || "us-east-1";
3432
3432
  let accountId = options.accountId;
3433
3433
  if (!accountId) {
3434
- const { STSClient: STSClient7, GetCallerIdentityCommand: GetCallerIdentityCommand9 } = await import("@aws-sdk/client-sts");
3435
- const stsClient = new STSClient7({ region });
3436
- const identity = await stsClient.send(new GetCallerIdentityCommand9({}));
3434
+ const { STSClient: STSClient9, GetCallerIdentityCommand: GetCallerIdentityCommand11 } = await import("@aws-sdk/client-sts");
3435
+ const stsClient = new STSClient9({ region });
3436
+ const identity = await stsClient.send(new GetCallerIdentityCommand11({}));
3437
3437
  accountId = identity.Account;
3438
3438
  stsClient.destroy();
3439
3439
  }
@@ -14229,7 +14229,8 @@ var LogsLogGroupProvider = class {
14229
14229
  import {
14230
14230
  PutMetricAlarmCommand,
14231
14231
  DeleteAlarmsCommand,
14232
- DescribeAlarmsCommand
14232
+ DescribeAlarmsCommand,
14233
+ ListTagsForResourceCommand as ListTagsForResourceCommand3
14233
14234
  } from "@aws-sdk/client-cloudwatch";
14234
14235
  init_aws_clients();
14235
14236
  var CloudWatchAlarmProvider = class {
@@ -14447,6 +14448,62 @@ var CloudWatchAlarmProvider = class {
14447
14448
  }
14448
14449
  return params;
14449
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
+ }
14450
14507
  };
14451
14508
 
14452
14509
  // src/provisioning/providers/secretsmanager-secret-provider.ts
@@ -14780,7 +14837,7 @@ var SecretsManagerSecretProvider = class {
14780
14837
  import {
14781
14838
  DescribeParametersCommand,
14782
14839
  GetParameterCommand as GetParameterCommand3,
14783
- ListTagsForResourceCommand as ListTagsForResourceCommand3,
14840
+ ListTagsForResourceCommand as ListTagsForResourceCommand4,
14784
14841
  PutParameterCommand,
14785
14842
  DeleteParameterCommand,
14786
14843
  AddTagsToResourceCommand,
@@ -15028,7 +15085,7 @@ var SSMParameterProvider = class {
15028
15085
  continue;
15029
15086
  try {
15030
15087
  const tagsResp = await this.ssmClient.send(
15031
- new ListTagsForResourceCommand3({ ResourceType: "Parameter", ResourceId: p.Name })
15088
+ new ListTagsForResourceCommand4({ ResourceType: "Parameter", ResourceId: p.Name })
15032
15089
  );
15033
15090
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
15034
15091
  return { physicalId: p.Name, attributes: {} };
@@ -15052,7 +15109,9 @@ import {
15052
15109
  RemoveTargetsCommand,
15053
15110
  DeleteRuleCommand,
15054
15111
  DescribeRuleCommand,
15112
+ ListRulesCommand,
15055
15113
  ListTargetsByRuleCommand,
15114
+ ListTagsForResourceCommand as ListTagsForResourceCommand5,
15056
15115
  TagResourceCommand as TagResourceCommand4,
15057
15116
  UntagResourceCommand as UntagResourceCommand4,
15058
15117
  ResourceNotFoundException as ResourceNotFoundException9
@@ -15320,6 +15379,85 @@ var EventBridgeRuleProvider = class {
15320
15379
  }
15321
15380
  throw new Error(`Unsupported attribute: ${attributeName} for AWS::Events::Rule`);
15322
15381
  }
15382
+ /**
15383
+ * Adopt an existing EventBridge rule into cdkd state.
15384
+ *
15385
+ * Lookup order:
15386
+ * 1. `--resource <id>=<arnOrName>` override → verify with
15387
+ * `DescribeRule` (scoped to the same `EventBusName` declared in
15388
+ * the template, if any). The override is honored as-is so users
15389
+ * can pass either the ARN (cdkd's standard physicalId form for
15390
+ * this provider) or just the rule name.
15391
+ * 2. If the template carries `Properties.Name` use that as the rule
15392
+ * name lookup, then verify with `DescribeRule` and return the
15393
+ * rule's ARN as physicalId.
15394
+ * 3. Walk `ListRules(EventBusName?)` and match `aws:cdk:path` via
15395
+ * `ListTagsForResource(ResourceARN=rule.Arn)`. Returns the rule
15396
+ * ARN as physicalId — same shape that `create` returns.
15397
+ *
15398
+ * EventBridge tags use the standard `Tag[]` array shape
15399
+ * (`Key`/`Value`).
15400
+ */
15401
+ async import(input) {
15402
+ const eventBusName = input.properties["EventBusName"];
15403
+ if (input.knownPhysicalId) {
15404
+ try {
15405
+ const ruleName = this.extractRuleNameFromArn(input.knownPhysicalId);
15406
+ const resp = await this.eventBridgeClient.send(
15407
+ new DescribeRuleCommand({
15408
+ Name: ruleName,
15409
+ ...eventBusName && { EventBusName: eventBusName }
15410
+ })
15411
+ );
15412
+ return { physicalId: resp.Arn ?? input.knownPhysicalId, attributes: {} };
15413
+ } catch (err) {
15414
+ if (err instanceof ResourceNotFoundException9)
15415
+ return null;
15416
+ throw err;
15417
+ }
15418
+ }
15419
+ const templateName = input.properties["Name"];
15420
+ if (templateName) {
15421
+ try {
15422
+ const resp = await this.eventBridgeClient.send(
15423
+ new DescribeRuleCommand({
15424
+ Name: templateName,
15425
+ ...eventBusName && { EventBusName: eventBusName }
15426
+ })
15427
+ );
15428
+ if (resp.Arn)
15429
+ return { physicalId: resp.Arn, attributes: {} };
15430
+ return null;
15431
+ } catch (err) {
15432
+ if (err instanceof ResourceNotFoundException9)
15433
+ return null;
15434
+ throw err;
15435
+ }
15436
+ }
15437
+ if (!input.cdkPath)
15438
+ return null;
15439
+ let nextToken;
15440
+ do {
15441
+ const list = await this.eventBridgeClient.send(
15442
+ new ListRulesCommand({
15443
+ ...eventBusName && { EventBusName: eventBusName },
15444
+ ...nextToken && { NextToken: nextToken }
15445
+ })
15446
+ );
15447
+ for (const rule of list.Rules ?? []) {
15448
+ if (!rule.Arn)
15449
+ continue;
15450
+ const tagsResp = await this.eventBridgeClient.send(
15451
+ new ListTagsForResourceCommand5({ ResourceARN: rule.Arn })
15452
+ );
15453
+ if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
15454
+ return { physicalId: rule.Arn, attributes: {} };
15455
+ }
15456
+ }
15457
+ nextToken = list.NextToken;
15458
+ } while (nextToken);
15459
+ return null;
15460
+ }
15323
15461
  /**
15324
15462
  * Extract rule name from an ARN
15325
15463
  *
@@ -15342,8 +15480,8 @@ import {
15342
15480
  UpdateEventBusCommand,
15343
15481
  DescribeEventBusCommand,
15344
15482
  ListEventBusesCommand,
15345
- ListRulesCommand,
15346
- ListTagsForResourceCommand as ListTagsForResourceCommand4,
15483
+ ListRulesCommand as ListRulesCommand2,
15484
+ ListTagsForResourceCommand as ListTagsForResourceCommand6,
15347
15485
  RemoveTargetsCommand as RemoveTargetsCommand2,
15348
15486
  DeleteRuleCommand as DeleteRuleCommand2,
15349
15487
  ListTargetsByRuleCommand as ListTargetsByRuleCommand2,
@@ -15538,7 +15676,7 @@ var EventBridgeBusProvider = class {
15538
15676
  async cleanupRulesOnBus(busName) {
15539
15677
  try {
15540
15678
  const rulesResponse = await this.eventBridgeClient.send(
15541
- new ListRulesCommand({ EventBusName: busName })
15679
+ new ListRulesCommand2({ EventBusName: busName })
15542
15680
  );
15543
15681
  const rules = rulesResponse.Rules ?? [];
15544
15682
  if (rules.length === 0)
@@ -15615,7 +15753,7 @@ var EventBridgeBusProvider = class {
15615
15753
  continue;
15616
15754
  try {
15617
15755
  const tagsResp = await this.eventBridgeClient.send(
15618
- new ListTagsForResourceCommand4({ ResourceARN: bus.Arn })
15756
+ new ListTagsForResourceCommand6({ ResourceARN: bus.Arn })
15619
15757
  );
15620
15758
  if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
15621
15759
  return { physicalId: bus.Name, attributes: {} };
@@ -18690,6 +18828,8 @@ import {
18690
18828
  DeleteRouteCommand as DeleteRouteCommand2,
18691
18829
  CreateAuthorizerCommand as CreateAuthorizerCommand2,
18692
18830
  DeleteAuthorizerCommand as DeleteAuthorizerCommand2,
18831
+ GetApiCommand,
18832
+ GetApisCommand,
18693
18833
  NotFoundException as NotFoundException4
18694
18834
  } from "@aws-sdk/client-apigatewayv2";
18695
18835
  var ApiGatewayV2Provider = class {
@@ -19223,6 +19363,56 @@ var ApiGatewayV2Provider = class {
19223
19363
  );
19224
19364
  }
19225
19365
  }
19366
+ // ─── Import ───────────────────────────────────────────────────────
19367
+ /**
19368
+ * Adopt an existing API Gateway V2 resource into cdkd state.
19369
+ *
19370
+ * `AWS::ApiGatewayV2::Api` supports full tag-based auto-lookup via
19371
+ * `GetApis` (`Tags` is a `Record<string,string>` map on each item).
19372
+ *
19373
+ * Sub-resources (`Stage`, `Integration`, `Route`, `Authorizer`) are
19374
+ * scoped under a parent `ApiId`, and their physical ids are not
19375
+ * globally unique — auto-lookup would need to walk every Api in the
19376
+ * account and every sub-resource within. Explicit-override only;
19377
+ * users adopt an existing HTTP API by passing
19378
+ * `--resource <logicalId>=<physicalId>` for each sub-resource.
19379
+ */
19380
+ async import(input) {
19381
+ if (input.resourceType !== "AWS::ApiGatewayV2::Api") {
19382
+ if (input.knownPhysicalId) {
19383
+ return { physicalId: input.knownPhysicalId, attributes: {} };
19384
+ }
19385
+ return null;
19386
+ }
19387
+ const explicit = resolveExplicitPhysicalId(input, null);
19388
+ if (explicit) {
19389
+ try {
19390
+ await this.getClient().send(new GetApiCommand({ ApiId: explicit }));
19391
+ return { physicalId: explicit, attributes: {} };
19392
+ } catch (err) {
19393
+ if (err instanceof NotFoundException4)
19394
+ return null;
19395
+ throw err;
19396
+ }
19397
+ }
19398
+ if (!input.cdkPath)
19399
+ return null;
19400
+ let nextToken;
19401
+ do {
19402
+ const list = await this.getClient().send(
19403
+ new GetApisCommand({ ...nextToken && { NextToken: nextToken } })
19404
+ );
19405
+ for (const api of list.Items ?? []) {
19406
+ if (!api.ApiId)
19407
+ continue;
19408
+ if (api.Tags?.[CDK_PATH_TAG] === input.cdkPath) {
19409
+ return { physicalId: api.ApiId, attributes: {} };
19410
+ }
19411
+ }
19412
+ nextToken = list.NextToken;
19413
+ } while (nextToken);
19414
+ return null;
19415
+ }
19226
19416
  // ─── Helpers ──────────────────────────────────────────────────────
19227
19417
  /**
19228
19418
  * Convert CloudFormation Tags (Array<{Key, Value}>) to SDK Tags (Record<string, string>).
@@ -19396,7 +19586,7 @@ import {
19396
19586
  GetDistributionCommand,
19397
19587
  GetDistributionConfigCommand,
19398
19588
  ListDistributionsCommand,
19399
- ListTagsForResourceCommand as ListTagsForResourceCommand5,
19589
+ ListTagsForResourceCommand as ListTagsForResourceCommand7,
19400
19590
  NoSuchDistribution
19401
19591
  } from "@aws-sdk/client-cloudfront";
19402
19592
  init_aws_clients();
@@ -19832,7 +20022,7 @@ var CloudFrontDistributionProvider = class {
19832
20022
  continue;
19833
20023
  try {
19834
20024
  const tagsResp = await this.cloudFrontClient.send(
19835
- new ListTagsForResourceCommand5({ Resource: d.ARN })
20025
+ new ListTagsForResourceCommand7({ Resource: d.ARN })
19836
20026
  );
19837
20027
  if (matchesCdkPath(tagsResp.Tags?.Items, input.cdkPath)) {
19838
20028
  return { physicalId: d.Id, attributes: {} };
@@ -20118,6 +20308,8 @@ import {
20118
20308
  UpdateStateMachineCommand,
20119
20309
  DeleteStateMachineCommand,
20120
20310
  DescribeStateMachineCommand,
20311
+ ListStateMachinesCommand,
20312
+ ListTagsForResourceCommand as ListTagsForResourceCommand8,
20121
20313
  StateMachineDoesNotExist
20122
20314
  } from "@aws-sdk/client-sfn";
20123
20315
  var StepFunctionsProvider = class {
@@ -20300,6 +20492,67 @@ var StepFunctionsProvider = class {
20300
20492
  );
20301
20493
  }
20302
20494
  }
20495
+ /**
20496
+ * Adopt an existing Step Functions state machine into cdkd state.
20497
+ *
20498
+ * Lookup order:
20499
+ * 1. `--resource <id>=<arn>` override → verify with `DescribeStateMachine`.
20500
+ * 2. Walk `ListStateMachines` paginator → `ListTagsForResource(arn)`,
20501
+ * match the lowercase `key`/`value` `aws:cdk:path` tag (SFN uses
20502
+ * lowercase tags, so `matchesCdkPath` from import-helpers does not
20503
+ * apply directly).
20504
+ *
20505
+ * SFN state machines do not expose a template-supplied name field
20506
+ * usable as a stable physicalId — the physicalId is the ARN — so the
20507
+ * fallback to `Properties.<NameField>` in `resolveExplicitPhysicalId`
20508
+ * is skipped here.
20509
+ */
20510
+ async import(input) {
20511
+ if (input.knownPhysicalId) {
20512
+ try {
20513
+ await this.getClient().send(
20514
+ new DescribeStateMachineCommand({ stateMachineArn: input.knownPhysicalId })
20515
+ );
20516
+ return { physicalId: input.knownPhysicalId, attributes: {} };
20517
+ } catch (err) {
20518
+ if (err instanceof StateMachineDoesNotExist)
20519
+ return null;
20520
+ throw err;
20521
+ }
20522
+ }
20523
+ if (!input.cdkPath)
20524
+ return null;
20525
+ let nextToken;
20526
+ do {
20527
+ const list = await this.getClient().send(
20528
+ new ListStateMachinesCommand({ ...nextToken && { nextToken } })
20529
+ );
20530
+ for (const sm of list.stateMachines ?? []) {
20531
+ if (!sm.stateMachineArn)
20532
+ continue;
20533
+ const tagsResp = await this.getClient().send(
20534
+ new ListTagsForResourceCommand8({ resourceArn: sm.stateMachineArn })
20535
+ );
20536
+ if (this.tagsMatchCdkPath(tagsResp.tags, input.cdkPath)) {
20537
+ return { physicalId: sm.stateMachineArn, attributes: {} };
20538
+ }
20539
+ }
20540
+ nextToken = list.nextToken;
20541
+ } while (nextToken);
20542
+ return null;
20543
+ }
20544
+ /**
20545
+ * Match SFN's lowercase `key`/`value` tag shape against the CDK path.
20546
+ */
20547
+ tagsMatchCdkPath(tags, cdkPath) {
20548
+ if (!tags)
20549
+ return false;
20550
+ for (const t of tags) {
20551
+ if (t.key === CDK_PATH_TAG && t.value === cdkPath)
20552
+ return true;
20553
+ }
20554
+ return false;
20555
+ }
20303
20556
  /**
20304
20557
  * Build definition string from CDK properties.
20305
20558
  * Handles both DefinitionString (string) and DefinitionString (object) forms.
@@ -20339,7 +20592,7 @@ import {
20339
20592
  DescribeServicesCommand,
20340
20593
  ListClustersCommand,
20341
20594
  ListServicesCommand,
20342
- ListTagsForResourceCommand as ListTagsForResourceCommand6
20595
+ ListTagsForResourceCommand as ListTagsForResourceCommand9
20343
20596
  } from "@aws-sdk/client-ecs";
20344
20597
  function convertTags(tags) {
20345
20598
  if (!tags || tags.length === 0)
@@ -21117,7 +21370,7 @@ var ECSProvider = class {
21117
21370
  );
21118
21371
  for (const arn of list.clusterArns ?? []) {
21119
21372
  const tagsResp = await this.getClient().send(
21120
- new ListTagsForResourceCommand6({ resourceArn: arn })
21373
+ new ListTagsForResourceCommand9({ resourceArn: arn })
21121
21374
  );
21122
21375
  if (this.tagsMatchCdkPath(tagsResp.tags, input.cdkPath)) {
21123
21376
  const name = arn.substring(arn.lastIndexOf("/") + 1);
@@ -21150,7 +21403,7 @@ var ECSProvider = class {
21150
21403
  );
21151
21404
  for (const svcArn of svcList.serviceArns ?? []) {
21152
21405
  const tagsResp = await this.getClient().send(
21153
- new ListTagsForResourceCommand6({ resourceArn: svcArn })
21406
+ new ListTagsForResourceCommand9({ resourceArn: svcArn })
21154
21407
  );
21155
21408
  if (this.tagsMatchCdkPath(tagsResp.tags, input.cdkPath)) {
21156
21409
  const svcName = svcArn.substring(svcArn.lastIndexOf("/") + 1);
@@ -21202,6 +21455,7 @@ import {
21202
21455
  DeleteTargetGroupCommand,
21203
21456
  ModifyTargetGroupCommand,
21204
21457
  DescribeTargetGroupsCommand,
21458
+ DescribeTagsCommand,
21205
21459
  CreateListenerCommand,
21206
21460
  DeleteListenerCommand,
21207
21461
  ModifyListenerCommand
@@ -21697,6 +21951,107 @@ var ELBv2Provider = class {
21697
21951
  return void 0;
21698
21952
  return certificates;
21699
21953
  }
21954
+ /**
21955
+ * Adopt an existing ELBv2 LoadBalancer or TargetGroup into cdkd state.
21956
+ *
21957
+ * Lookup order:
21958
+ * 1. `--resource <id>=<arn>` override → verify with `DescribeLoadBalancers`
21959
+ * or `DescribeTargetGroups`.
21960
+ * 2. Walk `DescribeLoadBalancers` / `DescribeTargetGroups` paginators →
21961
+ * batch-fetch tags for each ARN with `DescribeTags(ResourceArns)`
21962
+ * and match `aws:cdk:path` (standard `Key`/`Value` Tag[] shape).
21963
+ *
21964
+ * Listener is not auto-importable (no template-supplied stable
21965
+ * identifier and no convenient tag-by-LB-context shortcut); use
21966
+ * `--resource <listenerId>=<arn>` for those.
21967
+ */
21968
+ async import(input) {
21969
+ switch (input.resourceType) {
21970
+ case "AWS::ElasticLoadBalancingV2::LoadBalancer":
21971
+ return this.importLoadBalancer(input);
21972
+ case "AWS::ElasticLoadBalancingV2::TargetGroup":
21973
+ return this.importTargetGroup(input);
21974
+ case "AWS::ElasticLoadBalancingV2::Listener":
21975
+ if (input.knownPhysicalId) {
21976
+ return { physicalId: input.knownPhysicalId, attributes: {} };
21977
+ }
21978
+ return null;
21979
+ default:
21980
+ return null;
21981
+ }
21982
+ }
21983
+ async importLoadBalancer(input) {
21984
+ if (input.knownPhysicalId) {
21985
+ try {
21986
+ const resp = await this.getClient().send(
21987
+ new DescribeLoadBalancersCommand2({ LoadBalancerArns: [input.knownPhysicalId] })
21988
+ );
21989
+ return resp.LoadBalancers?.[0]?.LoadBalancerArn ? { physicalId: resp.LoadBalancers[0].LoadBalancerArn, attributes: {} } : null;
21990
+ } catch (err) {
21991
+ if (this.isNotFoundError(err))
21992
+ return null;
21993
+ throw err;
21994
+ }
21995
+ }
21996
+ if (!input.cdkPath)
21997
+ return null;
21998
+ let marker;
21999
+ do {
22000
+ const list = await this.getClient().send(
22001
+ new DescribeLoadBalancersCommand2({ ...marker && { Marker: marker } })
22002
+ );
22003
+ const arns = (list.LoadBalancers ?? []).map((lb) => lb.LoadBalancerArn).filter((arn) => Boolean(arn));
22004
+ for (let i = 0; i < arns.length; i += 20) {
22005
+ const batch = arns.slice(i, i + 20);
22006
+ const tagsResp = await this.getClient().send(
22007
+ new DescribeTagsCommand({ ResourceArns: batch })
22008
+ );
22009
+ for (const td of tagsResp.TagDescriptions ?? []) {
22010
+ if (td.ResourceArn && matchesCdkPath(td.Tags, input.cdkPath)) {
22011
+ return { physicalId: td.ResourceArn, attributes: {} };
22012
+ }
22013
+ }
22014
+ }
22015
+ marker = list.NextMarker;
22016
+ } while (marker);
22017
+ return null;
22018
+ }
22019
+ async importTargetGroup(input) {
22020
+ if (input.knownPhysicalId) {
22021
+ try {
22022
+ const resp = await this.getClient().send(
22023
+ new DescribeTargetGroupsCommand({ TargetGroupArns: [input.knownPhysicalId] })
22024
+ );
22025
+ return resp.TargetGroups?.[0]?.TargetGroupArn ? { physicalId: resp.TargetGroups[0].TargetGroupArn, attributes: {} } : null;
22026
+ } catch (err) {
22027
+ if (this.isNotFoundError(err))
22028
+ return null;
22029
+ throw err;
22030
+ }
22031
+ }
22032
+ if (!input.cdkPath)
22033
+ return null;
22034
+ let marker;
22035
+ do {
22036
+ const list = await this.getClient().send(
22037
+ new DescribeTargetGroupsCommand({ ...marker && { Marker: marker } })
22038
+ );
22039
+ const arns = (list.TargetGroups ?? []).map((tg) => tg.TargetGroupArn).filter((arn) => Boolean(arn));
22040
+ for (let i = 0; i < arns.length; i += 20) {
22041
+ const batch = arns.slice(i, i + 20);
22042
+ const tagsResp = await this.getClient().send(
22043
+ new DescribeTagsCommand({ ResourceArns: batch })
22044
+ );
22045
+ for (const td of tagsResp.TagDescriptions ?? []) {
22046
+ if (td.ResourceArn && matchesCdkPath(td.Tags, input.cdkPath)) {
22047
+ return { physicalId: td.ResourceArn, attributes: {} };
22048
+ }
22049
+ }
22050
+ }
22051
+ marker = list.NextMarker;
22052
+ } while (marker);
22053
+ return null;
22054
+ }
21700
22055
  /**
21701
22056
  * Check if an error indicates the resource was not found
21702
22057
  */
@@ -21724,7 +22079,7 @@ import {
21724
22079
  DeleteDBSubnetGroupCommand,
21725
22080
  DescribeDBSubnetGroupsCommand,
21726
22081
  ModifyDBSubnetGroupCommand,
21727
- ListTagsForResourceCommand as ListTagsForResourceCommand7
22082
+ ListTagsForResourceCommand as ListTagsForResourceCommand10
21728
22083
  } from "@aws-sdk/client-rds";
21729
22084
  var RDSProvider = class {
21730
22085
  rdsClient;
@@ -22365,7 +22720,7 @@ var RDSProvider = class {
22365
22720
  if (!inst.DBInstanceIdentifier || !inst.DBInstanceArn)
22366
22721
  continue;
22367
22722
  const tagsResp = await this.getClient().send(
22368
- new ListTagsForResourceCommand7({ ResourceName: inst.DBInstanceArn })
22723
+ new ListTagsForResourceCommand10({ ResourceName: inst.DBInstanceArn })
22369
22724
  );
22370
22725
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
22371
22726
  return { physicalId: inst.DBInstanceIdentifier, attributes: {} };
@@ -22400,7 +22755,7 @@ var RDSProvider = class {
22400
22755
  if (!c.DBClusterIdentifier || !c.DBClusterArn)
22401
22756
  continue;
22402
22757
  const tagsResp = await this.getClient().send(
22403
- new ListTagsForResourceCommand7({ ResourceName: c.DBClusterArn })
22758
+ new ListTagsForResourceCommand10({ ResourceName: c.DBClusterArn })
22404
22759
  );
22405
22760
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
22406
22761
  return { physicalId: c.DBClusterIdentifier, attributes: {} };
@@ -22435,7 +22790,7 @@ var RDSProvider = class {
22435
22790
  if (!sg.DBSubnetGroupName || !sg.DBSubnetGroupArn)
22436
22791
  continue;
22437
22792
  const tagsResp = await this.getClient().send(
22438
- new ListTagsForResourceCommand7({ ResourceName: sg.DBSubnetGroupArn })
22793
+ new ListTagsForResourceCommand10({ ResourceName: sg.DBSubnetGroupArn })
22439
22794
  );
22440
22795
  if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
22441
22796
  return { physicalId: sg.DBSubnetGroupName, attributes: {} };
@@ -22461,7 +22816,9 @@ import {
22461
22816
  CreateQueryLoggingConfigCommand,
22462
22817
  DeleteQueryLoggingConfigCommand,
22463
22818
  ListQueryLoggingConfigsCommand,
22464
- ListHostedZonesByNameCommand as ListHostedZonesByNameCommand2
22819
+ ListHostedZonesByNameCommand as ListHostedZonesByNameCommand2,
22820
+ ListHostedZonesCommand,
22821
+ ListTagsForResourceCommand as ListTagsForResourceCommand11
22465
22822
  } from "@aws-sdk/client-route-53";
22466
22823
  var Route53Provider = class {
22467
22824
  route53Client;
@@ -23108,45 +23465,110 @@ var Route53Provider = class {
23108
23465
  physicalId
23109
23466
  );
23110
23467
  }
23111
- };
23112
-
23113
- // src/provisioning/providers/wafv2-provider.ts
23114
- import {
23115
- WAFV2Client,
23116
- CreateWebACLCommand,
23117
- UpdateWebACLCommand,
23118
- DeleteWebACLCommand,
23119
- GetWebACLCommand,
23120
- WAFNonexistentItemException
23121
- } from "@aws-sdk/client-wafv2";
23122
- function parseWebACLArn(arn) {
23123
- const parts = arn.split(":");
23124
- const resourcePart = parts.slice(5).join(":");
23125
- const segments = resourcePart.split("/");
23126
- const scopeRaw = segments[0];
23127
- const name = segments[2];
23128
- const id = segments[3];
23129
- const scope = scopeRaw === "global" ? "CLOUDFRONT" : "REGIONAL";
23130
- return { id, name, scope };
23131
- }
23132
- var WAFv2WebACLProvider = class {
23133
- wafv2Client;
23134
- providerRegion = process.env["AWS_REGION"];
23135
- logger = getLogger().child("WAFv2WebACLProvider");
23136
- handledProperties = /* @__PURE__ */ new Map([
23137
- [
23138
- "AWS::WAFv2::WebACL",
23139
- /* @__PURE__ */ new Set([
23140
- "Name",
23141
- "Scope",
23142
- "Tags",
23143
- "DefaultAction",
23144
- "Description",
23145
- "Rules",
23146
- "VisibilityConfig",
23147
- "CustomResponseBodies",
23148
- "CaptchaConfig",
23149
- "ChallengeConfig",
23468
+ /**
23469
+ * Adopt an existing Route 53 resource into cdkd state.
23470
+ *
23471
+ * Supported types: `AWS::Route53::HostedZone` (full tag-based
23472
+ * lookup); `AWS::Route53::RecordSet` (override-only — RecordSets are
23473
+ * not taggable, and the composite child-of-zone identity makes auto
23474
+ * lookup impractical).
23475
+ */
23476
+ async import(input) {
23477
+ switch (input.resourceType) {
23478
+ case "AWS::Route53::HostedZone":
23479
+ return this.importHostedZone(input);
23480
+ case "AWS::Route53::RecordSet":
23481
+ if (input.knownPhysicalId) {
23482
+ return { physicalId: input.knownPhysicalId, attributes: {} };
23483
+ }
23484
+ return null;
23485
+ default:
23486
+ return null;
23487
+ }
23488
+ }
23489
+ async importHostedZone(input) {
23490
+ if (input.knownPhysicalId) {
23491
+ try {
23492
+ await this.getClient().send(new GetHostedZoneCommand2({ Id: input.knownPhysicalId }));
23493
+ return { physicalId: input.knownPhysicalId, attributes: {} };
23494
+ } catch (err) {
23495
+ if (err instanceof Error && err.name === "NoSuchHostedZone")
23496
+ return null;
23497
+ throw err;
23498
+ }
23499
+ }
23500
+ if (!input.cdkPath)
23501
+ return null;
23502
+ let marker;
23503
+ do {
23504
+ const list = await this.getClient().send(
23505
+ new ListHostedZonesCommand({ ...marker && { Marker: marker } })
23506
+ );
23507
+ for (const zone of list.HostedZones ?? []) {
23508
+ if (!zone.Id)
23509
+ continue;
23510
+ const zoneId = zone.Id.replace("/hostedzone/", "");
23511
+ try {
23512
+ const tagsResp = await this.getClient().send(
23513
+ new ListTagsForResourceCommand11({
23514
+ ResourceType: "hostedzone",
23515
+ ResourceId: zoneId
23516
+ })
23517
+ );
23518
+ if (matchesCdkPath(tagsResp.ResourceTagSet?.Tags, input.cdkPath)) {
23519
+ return { physicalId: zoneId, attributes: {} };
23520
+ }
23521
+ } catch (err) {
23522
+ if (err instanceof Error && err.name === "NoSuchHostedZone")
23523
+ continue;
23524
+ throw err;
23525
+ }
23526
+ }
23527
+ marker = list.IsTruncated ? list.NextMarker : void 0;
23528
+ } while (marker);
23529
+ return null;
23530
+ }
23531
+ };
23532
+
23533
+ // src/provisioning/providers/wafv2-provider.ts
23534
+ import {
23535
+ WAFV2Client,
23536
+ CreateWebACLCommand,
23537
+ UpdateWebACLCommand,
23538
+ DeleteWebACLCommand,
23539
+ GetWebACLCommand,
23540
+ ListWebACLsCommand,
23541
+ ListTagsForResourceCommand as ListTagsForResourceCommand12,
23542
+ WAFNonexistentItemException
23543
+ } from "@aws-sdk/client-wafv2";
23544
+ function parseWebACLArn(arn) {
23545
+ const parts = arn.split(":");
23546
+ const resourcePart = parts.slice(5).join(":");
23547
+ const segments = resourcePart.split("/");
23548
+ const scopeRaw = segments[0];
23549
+ const name = segments[2];
23550
+ const id = segments[3];
23551
+ const scope = scopeRaw === "global" ? "CLOUDFRONT" : "REGIONAL";
23552
+ return { id, name, scope };
23553
+ }
23554
+ var WAFv2WebACLProvider = class {
23555
+ wafv2Client;
23556
+ providerRegion = process.env["AWS_REGION"];
23557
+ logger = getLogger().child("WAFv2WebACLProvider");
23558
+ handledProperties = /* @__PURE__ */ new Map([
23559
+ [
23560
+ "AWS::WAFv2::WebACL",
23561
+ /* @__PURE__ */ new Set([
23562
+ "Name",
23563
+ "Scope",
23564
+ "Tags",
23565
+ "DefaultAction",
23566
+ "Description",
23567
+ "Rules",
23568
+ "VisibilityConfig",
23569
+ "CustomResponseBodies",
23570
+ "CaptchaConfig",
23571
+ "ChallengeConfig",
23150
23572
  "TokenDomains",
23151
23573
  "AssociationConfig"
23152
23574
  ])
@@ -23331,6 +23753,54 @@ var WAFv2WebACLProvider = class {
23331
23753
  );
23332
23754
  }
23333
23755
  }
23756
+ /**
23757
+ * Adopt an existing WAFv2 WebACL into cdkd state.
23758
+ *
23759
+ * Lookup order:
23760
+ * 1. `--resource <id>=<arn>` override → verify with `GetWebACL` (parses
23761
+ * Name/Id/Scope back out of the ARN).
23762
+ * 2. Walk `ListWebACLs(Scope)` → match `aws:cdk:path` via
23763
+ * `ListTagsForResource(ResourceARN)` (returns
23764
+ * `TagInfoForResource.TagList`, standard `Key`/`Value` shape).
23765
+ *
23766
+ * `Scope` is required by `ListWebACLs` — read from
23767
+ * `Properties.Scope` (`REGIONAL` is the default).
23768
+ */
23769
+ async import(input) {
23770
+ if (input.knownPhysicalId) {
23771
+ try {
23772
+ const { id, name, scope: scope2 } = parseWebACLArn(input.knownPhysicalId);
23773
+ await this.getClient().send(new GetWebACLCommand({ Id: id, Name: name, Scope: scope2 }));
23774
+ return { physicalId: input.knownPhysicalId, attributes: {} };
23775
+ } catch (err) {
23776
+ if (err instanceof WAFNonexistentItemException)
23777
+ return null;
23778
+ throw err;
23779
+ }
23780
+ }
23781
+ if (!input.cdkPath)
23782
+ return null;
23783
+ const scope = input.properties["Scope"] || "REGIONAL";
23784
+ let nextMarker;
23785
+ do {
23786
+ const list = await this.getClient().send(
23787
+ new ListWebACLsCommand({ Scope: scope, ...nextMarker && { NextMarker: nextMarker } })
23788
+ );
23789
+ for (const item of list.WebACLs ?? []) {
23790
+ if (!item.ARN)
23791
+ continue;
23792
+ const tagsResp = await this.getClient().send(
23793
+ new ListTagsForResourceCommand12({ ResourceARN: item.ARN })
23794
+ );
23795
+ const tagList = tagsResp.TagInfoForResource?.TagList;
23796
+ if (matchesCdkPath(tagList, input.cdkPath)) {
23797
+ return { physicalId: item.ARN, attributes: {} };
23798
+ }
23799
+ }
23800
+ nextMarker = list.NextMarker;
23801
+ } while (nextMarker);
23802
+ return null;
23803
+ }
23334
23804
  };
23335
23805
 
23336
23806
  // src/provisioning/providers/cognito-provider.ts
@@ -23341,7 +23811,7 @@ import {
23341
23811
  UpdateUserPoolCommand,
23342
23812
  DescribeUserPoolCommand,
23343
23813
  ListUserPoolsCommand,
23344
- ListTagsForResourceCommand as ListTagsForResourceCommand8,
23814
+ ListTagsForResourceCommand as ListTagsForResourceCommand13,
23345
23815
  ResourceNotFoundException as ResourceNotFoundException12
23346
23816
  } from "@aws-sdk/client-cognito-identity-provider";
23347
23817
  var CognitoUserPoolProvider = class {
@@ -23726,7 +24196,7 @@ var CognitoUserPoolProvider = class {
23726
24196
  if (!arn)
23727
24197
  continue;
23728
24198
  const tagsResp = await this.getClient().send(
23729
- new ListTagsForResourceCommand8({ ResourceArn: arn })
24199
+ new ListTagsForResourceCommand13({ ResourceArn: arn })
23730
24200
  );
23731
24201
  if (tagsResp.Tags?.[CDK_PATH_TAG] === input.cdkPath) {
23732
24202
  return { physicalId: pool.Id, attributes: {} };
@@ -23750,13 +24220,18 @@ import {
23750
24220
  CreateCacheClusterCommand,
23751
24221
  DeleteCacheClusterCommand,
23752
24222
  DescribeCacheClustersCommand,
24223
+ DescribeCacheSubnetGroupsCommand,
23753
24224
  CreateCacheSubnetGroupCommand,
23754
24225
  DeleteCacheSubnetGroupCommand,
23755
24226
  ModifyCacheSubnetGroupCommand,
23756
- ModifyCacheClusterCommand
24227
+ ModifyCacheClusterCommand,
24228
+ ListTagsForResourceCommand as ListTagsForResourceCommand14
23757
24229
  } from "@aws-sdk/client-elasticache";
24230
+ import { STSClient as STSClient5, GetCallerIdentityCommand as GetCallerIdentityCommand6 } from "@aws-sdk/client-sts";
23758
24231
  var ElastiCacheProvider = class {
23759
24232
  client;
24233
+ stsClient;
24234
+ cachedAccountId;
23760
24235
  providerRegion = process.env["AWS_REGION"];
23761
24236
  logger = getLogger().child("ElastiCacheProvider");
23762
24237
  handledProperties = /* @__PURE__ */ new Map([
@@ -24158,6 +24633,132 @@ var ElastiCacheProvider = class {
24158
24633
  sleep(ms) {
24159
24634
  return new Promise((resolve4) => setTimeout(resolve4, ms));
24160
24635
  }
24636
+ /**
24637
+ * Adopt an existing ElastiCache resource into cdkd state.
24638
+ *
24639
+ * Supported types:
24640
+ * - `AWS::ElastiCache::CacheCluster` — full tag-based lookup via
24641
+ * `DescribeCacheClusters` + `ListTagsForResource(ResourceName=arn)`.
24642
+ * - `AWS::ElastiCache::SubnetGroup` — full tag-based lookup via
24643
+ * `DescribeCacheSubnetGroups` + `ListTagsForResource(ResourceName=arn)`.
24644
+ *
24645
+ * `ListTagsForResource` requires an ARN. Both `CacheCluster.ARN` and
24646
+ * `CacheSubnetGroup.ARN` are returned by the Describe APIs, so no
24647
+ * extra reconstruction is needed in normal flow; for the explicit
24648
+ * override path we build the ARN from `region` + STS account id +
24649
+ * the resource name.
24650
+ */
24651
+ async import(input) {
24652
+ switch (input.resourceType) {
24653
+ case "AWS::ElastiCache::CacheCluster":
24654
+ return this.importCacheCluster(input);
24655
+ case "AWS::ElastiCache::SubnetGroup":
24656
+ return this.importSubnetGroup(input);
24657
+ default:
24658
+ return null;
24659
+ }
24660
+ }
24661
+ async importCacheCluster(input) {
24662
+ const explicit = resolveExplicitPhysicalId(input, "ClusterName");
24663
+ if (explicit) {
24664
+ try {
24665
+ const resp = await this.getClient().send(
24666
+ new DescribeCacheClustersCommand({ CacheClusterId: explicit })
24667
+ );
24668
+ const c = resp.CacheClusters?.[0];
24669
+ return c?.CacheClusterId ? { physicalId: c.CacheClusterId, attributes: {} } : null;
24670
+ } catch (err) {
24671
+ if (this.isNotFoundError(err, "CacheClusterNotFoundFault"))
24672
+ return null;
24673
+ throw err;
24674
+ }
24675
+ }
24676
+ if (!input.cdkPath)
24677
+ return null;
24678
+ let marker;
24679
+ do {
24680
+ const list = await this.getClient().send(
24681
+ new DescribeCacheClustersCommand({ ...marker && { Marker: marker } })
24682
+ );
24683
+ for (const c of list.CacheClusters ?? []) {
24684
+ if (!c.CacheClusterId)
24685
+ continue;
24686
+ const arn = c.ARN ?? await this.buildClusterArn(c.CacheClusterId);
24687
+ const tagsResp = await this.getClient().send(
24688
+ new ListTagsForResourceCommand14({ ResourceName: arn })
24689
+ );
24690
+ if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
24691
+ return { physicalId: c.CacheClusterId, attributes: {} };
24692
+ }
24693
+ }
24694
+ marker = list.Marker;
24695
+ } while (marker);
24696
+ return null;
24697
+ }
24698
+ async importSubnetGroup(input) {
24699
+ const explicit = resolveExplicitPhysicalId(input, "CacheSubnetGroupName");
24700
+ if (explicit) {
24701
+ try {
24702
+ const resp = await this.getClient().send(
24703
+ new DescribeCacheSubnetGroupsCommand({ CacheSubnetGroupName: explicit })
24704
+ );
24705
+ const g = resp.CacheSubnetGroups?.[0];
24706
+ return g?.CacheSubnetGroupName ? { physicalId: g.CacheSubnetGroupName, attributes: {} } : null;
24707
+ } catch (err) {
24708
+ if (this.isNotFoundError(err, "CacheSubnetGroupNotFoundFault"))
24709
+ return null;
24710
+ throw err;
24711
+ }
24712
+ }
24713
+ if (!input.cdkPath)
24714
+ return null;
24715
+ let marker;
24716
+ do {
24717
+ const list = await this.getClient().send(
24718
+ new DescribeCacheSubnetGroupsCommand({ ...marker && { Marker: marker } })
24719
+ );
24720
+ for (const g of list.CacheSubnetGroups ?? []) {
24721
+ if (!g.CacheSubnetGroupName)
24722
+ continue;
24723
+ const arn = g.ARN ?? await this.buildSubnetGroupArn(g.CacheSubnetGroupName);
24724
+ const tagsResp = await this.getClient().send(
24725
+ new ListTagsForResourceCommand14({ ResourceName: arn })
24726
+ );
24727
+ if (matchesCdkPath(tagsResp.TagList, input.cdkPath)) {
24728
+ return { physicalId: g.CacheSubnetGroupName, attributes: {} };
24729
+ }
24730
+ }
24731
+ marker = list.Marker;
24732
+ } while (marker);
24733
+ return null;
24734
+ }
24735
+ async buildClusterArn(clusterName) {
24736
+ const region = await this.getRegion();
24737
+ const account = await this.getAccountId();
24738
+ return `arn:aws:elasticache:${region}:${account}:cluster:${clusterName}`;
24739
+ }
24740
+ async buildSubnetGroupArn(subnetGroupName) {
24741
+ const region = await this.getRegion();
24742
+ const account = await this.getAccountId();
24743
+ return `arn:aws:elasticache:${region}:${account}:subnetgroup:${subnetGroupName}`;
24744
+ }
24745
+ async getRegion() {
24746
+ const region = await this.getClient().config.region();
24747
+ return region || this.providerRegion || "us-east-1";
24748
+ }
24749
+ async getAccountId() {
24750
+ if (this.cachedAccountId)
24751
+ return this.cachedAccountId;
24752
+ if (!this.stsClient) {
24753
+ this.stsClient = new STSClient5(this.providerRegion ? { region: this.providerRegion } : {});
24754
+ }
24755
+ const identity = await this.stsClient.send(new GetCallerIdentityCommand6({}));
24756
+ if (!identity.Account) {
24757
+ throw new Error("Failed to resolve AWS account id from STS");
24758
+ }
24759
+ this.cachedAccountId = identity.Account;
24760
+ return this.cachedAccountId;
24761
+ }
24161
24762
  };
24162
24763
 
24163
24764
  // src/provisioning/providers/servicediscovery-provider.ts
@@ -24171,7 +24772,7 @@ import {
24171
24772
  NamespaceNotFound,
24172
24773
  ServiceNotFound
24173
24774
  } from "@aws-sdk/client-servicediscovery";
24174
- import { STSClient as STSClient5, GetCallerIdentityCommand as GetCallerIdentityCommand6 } from "@aws-sdk/client-sts";
24775
+ import { STSClient as STSClient6, GetCallerIdentityCommand as GetCallerIdentityCommand7 } from "@aws-sdk/client-sts";
24175
24776
  var ServiceDiscoveryProvider = class {
24176
24777
  client;
24177
24778
  stsClient;
@@ -24203,7 +24804,7 @@ var ServiceDiscoveryProvider = class {
24203
24804
  }
24204
24805
  getStsClient() {
24205
24806
  if (!this.stsClient) {
24206
- this.stsClient = new STSClient5(this.providerRegion ? { region: this.providerRegion } : {});
24807
+ this.stsClient = new STSClient6(this.providerRegion ? { region: this.providerRegion } : {});
24207
24808
  }
24208
24809
  return this.stsClient;
24209
24810
  }
@@ -24494,7 +25095,7 @@ var ServiceDiscoveryProvider = class {
24494
25095
  */
24495
25096
  async buildNamespaceArn(namespaceId) {
24496
25097
  const stsClient = this.getStsClient();
24497
- const identity = await stsClient.send(new GetCallerIdentityCommand6({}));
25098
+ const identity = await stsClient.send(new GetCallerIdentityCommand7({}));
24498
25099
  const accountId = identity.Account || "";
24499
25100
  const region = await this.getClient().config.region();
24500
25101
  return `arn:aws:servicediscovery:${region}:${accountId}:namespace/${namespaceId}`;
@@ -24512,7 +25113,10 @@ import {
24512
25113
  DeleteResolverCommand,
24513
25114
  CreateApiKeyCommand,
24514
25115
  DeleteApiKeyCommand,
24515
- StartSchemaCreationCommand
25116
+ StartSchemaCreationCommand,
25117
+ GetGraphqlApiCommand,
25118
+ ListGraphqlApisCommand,
25119
+ NotFoundException as AppSyncNotFoundException
24516
25120
  } from "@aws-sdk/client-appsync";
24517
25121
  var AppSyncProvider = class {
24518
25122
  client;
@@ -25020,6 +25624,51 @@ var AppSyncProvider = class {
25020
25624
  const name = error.name ?? "";
25021
25625
  return message.includes("not found") || message.includes("does not exist") || name === "NotFoundException";
25022
25626
  }
25627
+ /**
25628
+ * Adopt an existing AppSync resource into cdkd state.
25629
+ *
25630
+ * `AWS::AppSync::GraphQLApi` supports full tag-based auto-lookup via
25631
+ * `ListGraphqlApis` (each item carries a `tags` map). AppSync sub-resources
25632
+ * (`GraphQLSchema`, `DataSource`, `Resolver`, `ApiKey`) are scoped under a
25633
+ * parent `apiId` and cannot be discovered by tag at the account level —
25634
+ * explicit-override only.
25635
+ */
25636
+ async import(input) {
25637
+ if (input.resourceType !== "AWS::AppSync::GraphQLApi") {
25638
+ if (input.knownPhysicalId) {
25639
+ return { physicalId: input.knownPhysicalId, attributes: {} };
25640
+ }
25641
+ return null;
25642
+ }
25643
+ const explicit = resolveExplicitPhysicalId(input, null);
25644
+ if (explicit) {
25645
+ try {
25646
+ await this.getClient().send(new GetGraphqlApiCommand({ apiId: explicit }));
25647
+ return { physicalId: explicit, attributes: {} };
25648
+ } catch (err) {
25649
+ if (err instanceof AppSyncNotFoundException)
25650
+ return null;
25651
+ throw err;
25652
+ }
25653
+ }
25654
+ if (!input.cdkPath)
25655
+ return null;
25656
+ let nextToken;
25657
+ do {
25658
+ const list = await this.getClient().send(
25659
+ new ListGraphqlApisCommand({ ...nextToken && { nextToken } })
25660
+ );
25661
+ for (const api of list.graphqlApis ?? []) {
25662
+ if (!api.apiId)
25663
+ continue;
25664
+ if (api.tags?.[CDK_PATH_TAG] === input.cdkPath) {
25665
+ return { physicalId: api.apiId, attributes: {} };
25666
+ }
25667
+ }
25668
+ nextToken = list.nextToken;
25669
+ } while (nextToken);
25670
+ return null;
25671
+ }
25023
25672
  };
25024
25673
 
25025
25674
  // src/provisioning/providers/glue-provider.ts
@@ -25030,10 +25679,18 @@ import {
25030
25679
  CreateTableCommand as CreateTableCommand2,
25031
25680
  UpdateTableCommand,
25032
25681
  DeleteTableCommand as DeleteTableCommand2,
25682
+ GetDatabaseCommand,
25683
+ GetDatabasesCommand,
25684
+ GetTableCommand,
25685
+ GetTablesCommand,
25686
+ GetTagsCommand,
25033
25687
  EntityNotFoundException
25034
25688
  } from "@aws-sdk/client-glue";
25689
+ import { STSClient as STSClient7, GetCallerIdentityCommand as GetCallerIdentityCommand8 } from "@aws-sdk/client-sts";
25035
25690
  var GlueProvider = class {
25036
25691
  client;
25692
+ stsClient;
25693
+ cachedAccountId;
25037
25694
  providerRegion = process.env["AWS_REGION"];
25038
25695
  logger = getLogger().child("GlueProvider");
25039
25696
  handledProperties = /* @__PURE__ */ new Map([
@@ -25388,21 +26045,182 @@ var GlueProvider = class {
25388
26045
  }
25389
26046
  serde["Parameters"] = converted;
25390
26047
  }
25391
- result.SerdeInfo = serde;
25392
- }
25393
- if (sd["BucketColumns"] !== void 0) {
25394
- result.BucketColumns = sd["BucketColumns"];
26048
+ result.SerdeInfo = serde;
26049
+ }
26050
+ if (sd["BucketColumns"] !== void 0) {
26051
+ result.BucketColumns = sd["BucketColumns"];
26052
+ }
26053
+ if (sd["SortColumns"] !== void 0) {
26054
+ result.SortColumns = sd["SortColumns"];
26055
+ }
26056
+ if (sd["Parameters"] !== void 0) {
26057
+ result.Parameters = sd["Parameters"];
26058
+ }
26059
+ if (sd["StoredAsSubDirectories"] !== void 0) {
26060
+ result.StoredAsSubDirectories = sd["StoredAsSubDirectories"];
26061
+ }
26062
+ return result;
26063
+ }
26064
+ /**
26065
+ * Adopt an existing Glue Database or Table into cdkd state.
26066
+ *
26067
+ * Lookup order (per type):
26068
+ * 1. Explicit override / template name → verify with `GetDatabase`
26069
+ * or `GetTable`.
26070
+ * 2. Walk `GetDatabases` / `GetTables` paginators and match the
26071
+ * `aws:cdk:path` tag via `GetTags(ResourceArn)`. Glue tags are
26072
+ * a `Record<string,string>` map (not a `Tag[]` array), so the
26073
+ * match is `tags?.[CDK_PATH_TAG] === input.cdkPath`.
26074
+ *
26075
+ * Glue list APIs return only names — ARNs are constructed locally
26076
+ * for the per-item GetTags call.
26077
+ */
26078
+ async import(input) {
26079
+ switch (input.resourceType) {
26080
+ case "AWS::Glue::Database":
26081
+ return this.importDatabase(input);
26082
+ case "AWS::Glue::Table":
26083
+ return this.importTable(input);
26084
+ default:
26085
+ return null;
26086
+ }
26087
+ }
26088
+ async importDatabase(input) {
26089
+ const explicitName = input.knownPhysicalId ?? input.properties["DatabaseInput"]?.["Name"];
26090
+ const catalogId = input.properties["CatalogId"];
26091
+ if (explicitName) {
26092
+ try {
26093
+ await this.getClient().send(
26094
+ new GetDatabaseCommand({ Name: explicitName, ...catalogId && { CatalogId: catalogId } })
26095
+ );
26096
+ return { physicalId: explicitName, attributes: {} };
26097
+ } catch (err) {
26098
+ if (err instanceof EntityNotFoundException)
26099
+ return null;
26100
+ throw err;
26101
+ }
26102
+ }
26103
+ if (!input.cdkPath)
26104
+ return null;
26105
+ let nextToken;
26106
+ do {
26107
+ const list = await this.getClient().send(
26108
+ new GetDatabasesCommand({
26109
+ ...nextToken && { NextToken: nextToken },
26110
+ ...catalogId && { CatalogId: catalogId }
26111
+ })
26112
+ );
26113
+ for (const db of list.DatabaseList ?? []) {
26114
+ if (!db.Name)
26115
+ continue;
26116
+ const arn = await this.buildDatabaseArn(db.Name, db.CatalogId);
26117
+ if (await this.tagsMatchCdkPath(arn, input.cdkPath)) {
26118
+ return { physicalId: db.Name, attributes: {} };
26119
+ }
26120
+ }
26121
+ nextToken = list.NextToken;
26122
+ } while (nextToken);
26123
+ return null;
26124
+ }
26125
+ async importTable(input) {
26126
+ const databaseName = input.properties["DatabaseName"];
26127
+ const tableInput = input.properties["TableInput"];
26128
+ const templateTableName = tableInput?.["Name"];
26129
+ const catalogId = input.properties["CatalogId"];
26130
+ if (input.knownPhysicalId) {
26131
+ const [dbName, tName] = input.knownPhysicalId.split("|");
26132
+ if (!dbName || !tName)
26133
+ return null;
26134
+ try {
26135
+ await this.getClient().send(
26136
+ new GetTableCommand({
26137
+ DatabaseName: dbName,
26138
+ Name: tName,
26139
+ ...catalogId && { CatalogId: catalogId }
26140
+ })
26141
+ );
26142
+ return { physicalId: input.knownPhysicalId, attributes: {} };
26143
+ } catch (err) {
26144
+ if (err instanceof EntityNotFoundException)
26145
+ return null;
26146
+ throw err;
26147
+ }
26148
+ }
26149
+ if (databaseName && templateTableName) {
26150
+ try {
26151
+ await this.getClient().send(
26152
+ new GetTableCommand({
26153
+ DatabaseName: databaseName,
26154
+ Name: templateTableName,
26155
+ ...catalogId && { CatalogId: catalogId }
26156
+ })
26157
+ );
26158
+ return { physicalId: `${databaseName}|${templateTableName}`, attributes: {} };
26159
+ } catch (err) {
26160
+ if (err instanceof EntityNotFoundException)
26161
+ return null;
26162
+ throw err;
26163
+ }
25395
26164
  }
25396
- if (sd["SortColumns"] !== void 0) {
25397
- result.SortColumns = sd["SortColumns"];
26165
+ if (!input.cdkPath || !databaseName)
26166
+ return null;
26167
+ let nextToken;
26168
+ do {
26169
+ const list = await this.getClient().send(
26170
+ new GetTablesCommand({
26171
+ DatabaseName: databaseName,
26172
+ ...nextToken && { NextToken: nextToken },
26173
+ ...catalogId && { CatalogId: catalogId }
26174
+ })
26175
+ );
26176
+ for (const t of list.TableList ?? []) {
26177
+ if (!t.Name)
26178
+ continue;
26179
+ const arn = await this.buildTableArn(databaseName, t.Name, catalogId);
26180
+ if (await this.tagsMatchCdkPath(arn, input.cdkPath)) {
26181
+ return { physicalId: `${databaseName}|${t.Name}`, attributes: {} };
26182
+ }
26183
+ }
26184
+ nextToken = list.NextToken;
26185
+ } while (nextToken);
26186
+ return null;
26187
+ }
26188
+ async tagsMatchCdkPath(arn, cdkPath) {
26189
+ try {
26190
+ const resp = await this.getClient().send(new GetTagsCommand({ ResourceArn: arn }));
26191
+ return resp.Tags?.[CDK_PATH_TAG] === cdkPath;
26192
+ } catch (err) {
26193
+ if (err instanceof EntityNotFoundException)
26194
+ return false;
26195
+ throw err;
25398
26196
  }
25399
- if (sd["Parameters"] !== void 0) {
25400
- result.Parameters = sd["Parameters"];
26197
+ }
26198
+ async buildDatabaseArn(databaseName, catalogId) {
26199
+ const region = await this.getRegion();
26200
+ const account = catalogId ?? await this.getAccountId();
26201
+ return `arn:aws:glue:${region}:${account}:database/${databaseName}`;
26202
+ }
26203
+ async buildTableArn(databaseName, tableName, catalogId) {
26204
+ const region = await this.getRegion();
26205
+ const account = catalogId ?? await this.getAccountId();
26206
+ return `arn:aws:glue:${region}:${account}:table/${databaseName}/${tableName}`;
26207
+ }
26208
+ async getRegion() {
26209
+ const region = await this.getClient().config.region();
26210
+ return region || this.providerRegion || "us-east-1";
26211
+ }
26212
+ async getAccountId() {
26213
+ if (this.cachedAccountId)
26214
+ return this.cachedAccountId;
26215
+ if (!this.stsClient) {
26216
+ this.stsClient = new STSClient7(this.providerRegion ? { region: this.providerRegion } : {});
25401
26217
  }
25402
- if (sd["StoredAsSubDirectories"] !== void 0) {
25403
- result.StoredAsSubDirectories = sd["StoredAsSubDirectories"];
26218
+ const identity = await this.stsClient.send(new GetCallerIdentityCommand8({}));
26219
+ if (!identity.Account) {
26220
+ throw new Error("Failed to resolve AWS account id from STS");
25404
26221
  }
25405
- return result;
26222
+ this.cachedAccountId = identity.Account;
26223
+ return this.cachedAccountId;
25406
26224
  }
25407
26225
  };
25408
26226
 
@@ -25885,6 +26703,8 @@ import {
25885
26703
  DecreaseStreamRetentionPeriodCommand,
25886
26704
  StartStreamEncryptionCommand,
25887
26705
  StopStreamEncryptionCommand,
26706
+ ListStreamsCommand,
26707
+ ListTagsForStreamCommand,
25888
26708
  ResourceNotFoundException as ResourceNotFoundException13
25889
26709
  } from "@aws-sdk/client-kinesis";
25890
26710
  var KinesisStreamProvider = class {
@@ -26137,6 +26957,54 @@ var KinesisStreamProvider = class {
26137
26957
  );
26138
26958
  }
26139
26959
  }
26960
+ /**
26961
+ * Adopt an existing Kinesis stream into cdkd state.
26962
+ *
26963
+ * Lookup order:
26964
+ * 1. `--resource <id>=<name>` override or `Properties.Name` → verify
26965
+ * with `DescribeStream`.
26966
+ * 2. Walk `ListStreams` (paged via `ExclusiveStartStreamName`) and
26967
+ * match the `aws:cdk:path` tag via `ListTagsForStream(StreamName)`.
26968
+ *
26969
+ * Kinesis tags use the standard `Tag[]` array shape (`Key`/`Value`),
26970
+ * so `matchesCdkPath` from import-helpers applies directly.
26971
+ */
26972
+ async import(input) {
26973
+ const explicit = resolveExplicitPhysicalId(input, "Name");
26974
+ if (explicit) {
26975
+ try {
26976
+ await this.getClient().send(new DescribeStreamCommand({ StreamName: explicit }));
26977
+ return { physicalId: explicit, attributes: {} };
26978
+ } catch (err) {
26979
+ if (err instanceof ResourceNotFoundException13)
26980
+ return null;
26981
+ throw err;
26982
+ }
26983
+ }
26984
+ if (!input.cdkPath)
26985
+ return null;
26986
+ let exclusiveStartStreamName;
26987
+ while (true) {
26988
+ const list = await this.getClient().send(
26989
+ new ListStreamsCommand({
26990
+ ...exclusiveStartStreamName && { ExclusiveStartStreamName: exclusiveStartStreamName }
26991
+ })
26992
+ );
26993
+ const names = list.StreamNames ?? [];
26994
+ for (const streamName of names) {
26995
+ const tagsResp = await this.getClient().send(
26996
+ new ListTagsForStreamCommand({ StreamName: streamName })
26997
+ );
26998
+ if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
26999
+ return { physicalId: streamName, attributes: {} };
27000
+ }
27001
+ }
27002
+ if (!list.HasMoreStreams || names.length === 0)
27003
+ break;
27004
+ exclusiveStartStreamName = names[names.length - 1];
27005
+ }
27006
+ return null;
27007
+ }
26140
27008
  /**
26141
27009
  * Poll DescribeStream until the stream reaches ACTIVE status
26142
27010
  *
@@ -26179,6 +27047,7 @@ import {
26179
27047
  CreateAccessPointCommand,
26180
27048
  DeleteAccessPointCommand,
26181
27049
  DescribeFileSystemsCommand,
27050
+ DescribeAccessPointsCommand,
26182
27051
  FileSystemNotFound,
26183
27052
  MountTargetNotFound,
26184
27053
  AccessPointNotFound
@@ -26580,6 +27449,100 @@ var EFSProvider = class {
26580
27449
  );
26581
27450
  }
26582
27451
  }
27452
+ /**
27453
+ * Adopt an existing EFS resource into cdkd state.
27454
+ *
27455
+ * Supported types:
27456
+ * - `AWS::EFS::FileSystem` — full tag-based lookup via
27457
+ * `DescribeFileSystems` with `Tags` inline on each item.
27458
+ * - `AWS::EFS::AccessPoint` — full tag-based lookup via
27459
+ * `DescribeAccessPoints` with `Tags` inline on each item.
27460
+ * - `AWS::EFS::MountTarget` — override-only (mount targets are
27461
+ * not taggable; auto lookup is impractical).
27462
+ */
27463
+ async import(input) {
27464
+ switch (input.resourceType) {
27465
+ case "AWS::EFS::FileSystem":
27466
+ return this.importFileSystem(input);
27467
+ case "AWS::EFS::AccessPoint":
27468
+ return this.importAccessPoint(input);
27469
+ case "AWS::EFS::MountTarget":
27470
+ if (input.knownPhysicalId) {
27471
+ return { physicalId: input.knownPhysicalId, attributes: {} };
27472
+ }
27473
+ return null;
27474
+ default:
27475
+ return null;
27476
+ }
27477
+ }
27478
+ async importFileSystem(input) {
27479
+ if (input.knownPhysicalId) {
27480
+ try {
27481
+ const resp = await this.getClient().send(
27482
+ new DescribeFileSystemsCommand({ FileSystemId: input.knownPhysicalId })
27483
+ );
27484
+ const fs = resp.FileSystems?.[0];
27485
+ return fs?.FileSystemId ? { physicalId: fs.FileSystemId, attributes: {} } : null;
27486
+ } catch (err) {
27487
+ if (err instanceof FileSystemNotFound)
27488
+ return null;
27489
+ throw err;
27490
+ }
27491
+ }
27492
+ if (!input.cdkPath)
27493
+ return null;
27494
+ let marker;
27495
+ do {
27496
+ const list = await this.getClient().send(
27497
+ new DescribeFileSystemsCommand({ ...marker && { Marker: marker } })
27498
+ );
27499
+ for (const fs of list.FileSystems ?? []) {
27500
+ if (!fs.FileSystemId)
27501
+ continue;
27502
+ if (matchesCdkPath(fs.Tags, input.cdkPath)) {
27503
+ return { physicalId: fs.FileSystemId, attributes: {} };
27504
+ }
27505
+ }
27506
+ marker = list.NextMarker;
27507
+ } while (marker);
27508
+ return null;
27509
+ }
27510
+ async importAccessPoint(input) {
27511
+ if (input.knownPhysicalId) {
27512
+ try {
27513
+ const resp = await this.getClient().send(
27514
+ new DescribeAccessPointsCommand({ AccessPointId: input.knownPhysicalId })
27515
+ );
27516
+ const ap = resp.AccessPoints?.[0];
27517
+ return ap?.AccessPointId ? { physicalId: ap.AccessPointId, attributes: {} } : null;
27518
+ } catch (err) {
27519
+ if (err instanceof AccessPointNotFound)
27520
+ return null;
27521
+ throw err;
27522
+ }
27523
+ }
27524
+ if (!input.cdkPath)
27525
+ return null;
27526
+ const fileSystemId = input.properties["FileSystemId"];
27527
+ let nextToken;
27528
+ do {
27529
+ const list = await this.getClient().send(
27530
+ new DescribeAccessPointsCommand({
27531
+ ...nextToken && { NextToken: nextToken },
27532
+ ...fileSystemId && { FileSystemId: fileSystemId }
27533
+ })
27534
+ );
27535
+ for (const ap of list.AccessPoints ?? []) {
27536
+ if (!ap.AccessPointId)
27537
+ continue;
27538
+ if (matchesCdkPath(ap.Tags, input.cdkPath)) {
27539
+ return { physicalId: ap.AccessPointId, attributes: {} };
27540
+ }
27541
+ }
27542
+ nextToken = list.NextToken;
27543
+ } while (nextToken);
27544
+ return null;
27545
+ }
26583
27546
  };
26584
27547
 
26585
27548
  // src/provisioning/providers/firehose-provider.ts
@@ -26587,6 +27550,9 @@ import {
26587
27550
  FirehoseClient,
26588
27551
  CreateDeliveryStreamCommand,
26589
27552
  DeleteDeliveryStreamCommand,
27553
+ DescribeDeliveryStreamCommand,
27554
+ ListDeliveryStreamsCommand,
27555
+ ListTagsForDeliveryStreamCommand,
26590
27556
  ResourceNotFoundException as ResourceNotFoundException14
26591
27557
  } from "@aws-sdk/client-firehose";
26592
27558
  var FirehoseProvider = class {
@@ -26923,12 +27889,63 @@ var FirehoseProvider = class {
26923
27889
  }
26924
27890
  return result;
26925
27891
  }
27892
+ /**
27893
+ * Adopt an existing Kinesis Firehose delivery stream into cdkd state.
27894
+ *
27895
+ * Lookup order:
27896
+ * 1. `--resource <id>=<name>` override or `Properties.DeliveryStreamName`
27897
+ * → verify with `DescribeDeliveryStream`.
27898
+ * 2. Walk `ListDeliveryStreams` (paged via `ExclusiveStartDeliveryStreamName`)
27899
+ * and match the `aws:cdk:path` tag via
27900
+ * `ListTagsForDeliveryStream(DeliveryStreamName)`.
27901
+ *
27902
+ * Firehose tags use the standard `Tag[]` array shape (`Key`/`Value`).
27903
+ */
27904
+ async import(input) {
27905
+ const explicit = resolveExplicitPhysicalId(input, "DeliveryStreamName");
27906
+ if (explicit) {
27907
+ try {
27908
+ await this.getClient().send(
27909
+ new DescribeDeliveryStreamCommand({ DeliveryStreamName: explicit })
27910
+ );
27911
+ return { physicalId: explicit, attributes: {} };
27912
+ } catch (err) {
27913
+ if (err instanceof ResourceNotFoundException14)
27914
+ return null;
27915
+ throw err;
27916
+ }
27917
+ }
27918
+ if (!input.cdkPath)
27919
+ return null;
27920
+ let exclusiveStartDeliveryStreamName;
27921
+ while (true) {
27922
+ const list = await this.getClient().send(
27923
+ new ListDeliveryStreamsCommand({
27924
+ ...exclusiveStartDeliveryStreamName && {
27925
+ ExclusiveStartDeliveryStreamName: exclusiveStartDeliveryStreamName
27926
+ }
27927
+ })
27928
+ );
27929
+ const names = list.DeliveryStreamNames ?? [];
27930
+ for (const name of names) {
27931
+ const tagsResp = await this.getClient().send(
27932
+ new ListTagsForDeliveryStreamCommand({ DeliveryStreamName: name })
27933
+ );
27934
+ if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
27935
+ return { physicalId: name, attributes: {} };
27936
+ }
27937
+ }
27938
+ if (!list.HasMoreDeliveryStreams || names.length === 0)
27939
+ break;
27940
+ exclusiveStartDeliveryStreamName = names[names.length - 1];
27941
+ }
27942
+ return null;
27943
+ }
26926
27944
  /**
26927
27945
  * Wait for a delivery stream to become ACTIVE.
26928
27946
  * Firehose CreateDeliveryStream returns immediately while the stream is still CREATING.
26929
27947
  */
26930
27948
  async waitForActive(streamName, logicalId) {
26931
- const { DescribeDeliveryStreamCommand } = await import("@aws-sdk/client-firehose");
26932
27949
  const maxAttempts = 30;
26933
27950
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
26934
27951
  const resp = await this.getClient().send(
@@ -26958,6 +27975,9 @@ import {
26958
27975
  StopLoggingCommand,
26959
27976
  PutEventSelectorsCommand,
26960
27977
  PutInsightSelectorsCommand,
27978
+ GetTrailCommand,
27979
+ ListTrailsCommand,
27980
+ ListTagsCommand as ListTagsCommand2,
26961
27981
  TrailNotFoundException
26962
27982
  } from "@aws-sdk/client-cloudtrail";
26963
27983
  var CloudTrailProvider = class {
@@ -27189,6 +28209,54 @@ var CloudTrailProvider = class {
27189
28209
  getAttribute(_physicalId, _resourceType, attributeName) {
27190
28210
  return Promise.resolve(attributeName);
27191
28211
  }
28212
+ /**
28213
+ * Adopt an existing CloudTrail trail into cdkd state.
28214
+ *
28215
+ * Lookup order:
28216
+ * 1. `--resource` override or `Properties.TrailName` → verify via `GetTrail`.
28217
+ * 2. `ListTrails` + `ListTags` (CloudTrail uses `Tag[]` arrays per ARN),
28218
+ * match `aws:cdk:path` tag.
28219
+ */
28220
+ async import(input) {
28221
+ const explicit = resolveExplicitPhysicalId(input, "TrailName");
28222
+ if (explicit) {
28223
+ try {
28224
+ await this.getClient().send(new GetTrailCommand({ Name: explicit }));
28225
+ return { physicalId: explicit, attributes: {} };
28226
+ } catch (err) {
28227
+ if (err instanceof TrailNotFoundException)
28228
+ return null;
28229
+ throw err;
28230
+ }
28231
+ }
28232
+ if (!input.cdkPath)
28233
+ return null;
28234
+ let nextToken;
28235
+ do {
28236
+ const list = await this.getClient().send(
28237
+ new ListTrailsCommand({ ...nextToken && { NextToken: nextToken } })
28238
+ );
28239
+ for (const trail of list.Trails ?? []) {
28240
+ if (!trail.TrailARN || !trail.Name)
28241
+ continue;
28242
+ try {
28243
+ const tagsResp = await this.getClient().send(
28244
+ new ListTagsCommand2({ ResourceIdList: [trail.TrailARN] })
28245
+ );
28246
+ const list2 = tagsResp.ResourceTagList?.[0];
28247
+ if (matchesCdkPath(list2?.TagsList, input.cdkPath)) {
28248
+ return { physicalId: trail.Name, attributes: {} };
28249
+ }
28250
+ } catch (err) {
28251
+ if (err instanceof TrailNotFoundException)
28252
+ continue;
28253
+ throw err;
28254
+ }
28255
+ }
28256
+ nextToken = list.NextToken;
28257
+ } while (nextToken);
28258
+ return null;
28259
+ }
27192
28260
  };
27193
28261
 
27194
28262
  // src/provisioning/providers/codebuild-provider.ts
@@ -27197,6 +28265,8 @@ import {
27197
28265
  CreateProjectCommand,
27198
28266
  DeleteProjectCommand,
27199
28267
  UpdateProjectCommand,
28268
+ BatchGetProjectsCommand,
28269
+ ListProjectsCommand,
27200
28270
  ResourceNotFoundException as ResourceNotFoundException15
27201
28271
  } from "@aws-sdk/client-codebuild";
27202
28272
  var CodeBuildProvider = class {
@@ -27455,6 +28525,54 @@ var CodeBuildProvider = class {
27455
28525
  getAttribute(_physicalId, _resourceType, attributeName) {
27456
28526
  return Promise.resolve(attributeName);
27457
28527
  }
28528
+ /**
28529
+ * Adopt an existing CodeBuild project into cdkd state.
28530
+ *
28531
+ * Lookup order:
28532
+ * 1. `--resource` override or `Properties.Name` → verify via `BatchGetProjects`.
28533
+ * 2. `ListProjects` + `BatchGetProjects` (CodeBuild uses lowercase
28534
+ * `key`/`value` tags, not the standard `Key`/`Value`), match
28535
+ * `aws:cdk:path` tag.
28536
+ */
28537
+ async import(input) {
28538
+ const explicit = resolveExplicitPhysicalId(input, "Name");
28539
+ if (explicit) {
28540
+ try {
28541
+ const resp = await this.getClient().send(
28542
+ new BatchGetProjectsCommand({ names: [explicit] })
28543
+ );
28544
+ return resp.projects?.[0]?.name ? { physicalId: explicit, attributes: {} } : null;
28545
+ } catch (err) {
28546
+ if (err instanceof ResourceNotFoundException15)
28547
+ return null;
28548
+ throw err;
28549
+ }
28550
+ }
28551
+ if (!input.cdkPath)
28552
+ return null;
28553
+ let nextToken;
28554
+ do {
28555
+ const list = await this.getClient().send(
28556
+ new ListProjectsCommand({ ...nextToken && { nextToken } })
28557
+ );
28558
+ const names = (list.projects ?? []).filter((n) => typeof n === "string");
28559
+ if (names.length > 0) {
28560
+ const batch = await this.getClient().send(new BatchGetProjectsCommand({ names }));
28561
+ for (const proj of batch.projects ?? []) {
28562
+ if (!proj.name)
28563
+ continue;
28564
+ const tags = proj.tags ?? [];
28565
+ for (const t of tags) {
28566
+ if (t.key === CDK_PATH_TAG && t.value === input.cdkPath) {
28567
+ return { physicalId: proj.name, attributes: {} };
28568
+ }
28569
+ }
28570
+ }
28571
+ }
28572
+ nextToken = list.nextToken;
28573
+ } while (nextToken);
28574
+ return null;
28575
+ }
27458
28576
  };
27459
28577
 
27460
28578
  // src/provisioning/providers/s3-vectors-provider.ts
@@ -27635,7 +28753,7 @@ import {
27635
28753
  ListObjectsV2Command as ListObjectsV2Command2,
27636
28754
  DeleteObjectsCommand as DeleteObjectsCommand2
27637
28755
  } from "@aws-sdk/client-s3";
27638
- import { GetCallerIdentityCommand as GetCallerIdentityCommand7 } from "@aws-sdk/client-sts";
28756
+ import { GetCallerIdentityCommand as GetCallerIdentityCommand9 } from "@aws-sdk/client-sts";
27639
28757
  import { EC2Client as EC2Client8, DescribeAvailabilityZonesCommand as DescribeAvailabilityZonesCommand3 } from "@aws-sdk/client-ec2";
27640
28758
  init_aws_clients();
27641
28759
  var S3DirectoryBucketProvider = class {
@@ -27691,7 +28809,7 @@ var S3DirectoryBucketProvider = class {
27691
28809
  * Get the AWS account ID via STS
27692
28810
  */
27693
28811
  async getAccountId() {
27694
- const identity = await this.stsClient.send(new GetCallerIdentityCommand7({}));
28812
+ const identity = await this.stsClient.send(new GetCallerIdentityCommand9({}));
27695
28813
  return identity.Account;
27696
28814
  }
27697
28815
  /**
@@ -28246,6 +29364,7 @@ import {
28246
29364
  PutImageScanningConfigurationCommand,
28247
29365
  PutImageTagMutabilityCommand,
28248
29366
  TagResourceCommand as TagResourceCommand7,
29367
+ ListTagsForResourceCommand as ListTagsForResourceCommand15,
28249
29368
  RepositoryNotFoundException
28250
29369
  } from "@aws-sdk/client-ecr";
28251
29370
  var ECRProvider = class {
@@ -28479,6 +29598,56 @@ var ECRProvider = class {
28479
29598
  );
28480
29599
  }
28481
29600
  }
29601
+ /**
29602
+ * Adopt an existing ECR repository into cdkd state.
29603
+ *
29604
+ * Lookup order:
29605
+ * 1. `--resource` override or `Properties.RepositoryName` → verify via
29606
+ * `DescribeRepositories`.
29607
+ * 2. `DescribeRepositories` paginated, then `ListTagsForResource(arn)`
29608
+ * per repository to match `aws:cdk:path` (`Tag[]` array shape).
29609
+ */
29610
+ async import(input) {
29611
+ const explicit = resolveExplicitPhysicalId(input, "RepositoryName");
29612
+ if (explicit) {
29613
+ try {
29614
+ const resp = await this.getClient().send(
29615
+ new DescribeRepositoriesCommand({ repositoryNames: [explicit] })
29616
+ );
29617
+ return resp.repositories?.[0]?.repositoryName ? { physicalId: explicit, attributes: {} } : null;
29618
+ } catch (err) {
29619
+ if (err instanceof RepositoryNotFoundException)
29620
+ return null;
29621
+ throw err;
29622
+ }
29623
+ }
29624
+ if (!input.cdkPath)
29625
+ return null;
29626
+ let nextToken;
29627
+ do {
29628
+ const list = await this.getClient().send(
29629
+ new DescribeRepositoriesCommand({ ...nextToken && { nextToken } })
29630
+ );
29631
+ for (const repo of list.repositories ?? []) {
29632
+ if (!repo.repositoryArn || !repo.repositoryName)
29633
+ continue;
29634
+ try {
29635
+ const tagsResp = await this.getClient().send(
29636
+ new ListTagsForResourceCommand15({ resourceArn: repo.repositoryArn })
29637
+ );
29638
+ if (matchesCdkPath(tagsResp.tags, input.cdkPath)) {
29639
+ return { physicalId: repo.repositoryName, attributes: {} };
29640
+ }
29641
+ } catch (err) {
29642
+ if (err instanceof RepositoryNotFoundException)
29643
+ continue;
29644
+ throw err;
29645
+ }
29646
+ }
29647
+ nextToken = list.nextToken;
29648
+ } while (nextToken);
29649
+ return null;
29650
+ }
28482
29651
  };
28483
29652
 
28484
29653
  // src/provisioning/register-providers.ts
@@ -29992,11 +31161,11 @@ async function deployCommand(stacks, options) {
29992
31161
  addDependencies(stack.stackName);
29993
31162
  }
29994
31163
  }
29995
- const { STSClient: STSClient7, GetCallerIdentityCommand: GetCallerIdentityCommand9 } = await import("@aws-sdk/client-sts");
29996
- const stsClient = new STSClient7({
31164
+ const { STSClient: STSClient9, GetCallerIdentityCommand: GetCallerIdentityCommand11 } = await import("@aws-sdk/client-sts");
31165
+ const stsClient = new STSClient9({
29997
31166
  region: options.region || process.env["AWS_REGION"] || "us-east-1"
29998
31167
  });
29999
- const callerIdentity = await stsClient.send(new GetCallerIdentityCommand9({}));
31168
+ const callerIdentity = await stsClient.send(new GetCallerIdentityCommand11({}));
30000
31169
  const accountId = callerIdentity.Account;
30001
31170
  stsClient.destroy();
30002
31171
  const assetPublisher = new AssetPublisher();
@@ -31049,7 +32218,7 @@ import {
31049
32218
  PutBucketVersioningCommand as PutBucketVersioningCommand3,
31050
32219
  S3Client as S3Client10
31051
32220
  } from "@aws-sdk/client-s3";
31052
- import { GetCallerIdentityCommand as GetCallerIdentityCommand8 } from "@aws-sdk/client-sts";
32221
+ import { GetCallerIdentityCommand as GetCallerIdentityCommand10 } from "@aws-sdk/client-sts";
31053
32222
  init_aws_clients();
31054
32223
  async function stateMigrateCommand(options) {
31055
32224
  const logger = getLogger();
@@ -31062,7 +32231,7 @@ async function stateMigrateCommand(options) {
31062
32231
  });
31063
32232
  setAwsClients(awsClients);
31064
32233
  try {
31065
- const identity = await awsClients.sts.send(new GetCallerIdentityCommand8({}));
32234
+ const identity = await awsClients.sts.send(new GetCallerIdentityCommand10({}));
31066
32235
  const accountId = identity.Account;
31067
32236
  if (!accountId) {
31068
32237
  throw new Error("STS GetCallerIdentity returned no Account id.");
@@ -32390,7 +33559,7 @@ function reorderArgs(argv) {
32390
33559
  }
32391
33560
  async function main() {
32392
33561
  const program = new Command13();
32393
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.18.1");
33562
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.20.0");
32394
33563
  program.addCommand(createBootstrapCommand());
32395
33564
  program.addCommand(createSynthCommand());
32396
33565
  program.addCommand(createListCommand());