@go-to-k/cdkd 0.20.0 → 0.21.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
@@ -1218,9 +1218,9 @@ async function bucketHasAnyState(client, bucketName) {
1218
1218
  }
1219
1219
  }
1220
1220
  async function bucketExists(client, bucketName) {
1221
- const { HeadBucketCommand: HeadBucketCommand5 } = await import("@aws-sdk/client-s3");
1221
+ const { HeadBucketCommand: HeadBucketCommand6 } = await import("@aws-sdk/client-s3");
1222
1222
  try {
1223
- await client.send(new HeadBucketCommand5({ Bucket: bucketName }));
1223
+ await client.send(new HeadBucketCommand6({ Bucket: bucketName }));
1224
1224
  return true;
1225
1225
  } catch (error) {
1226
1226
  const err = error;
@@ -8864,6 +8864,27 @@ var IAMPolicyProvider = class {
8864
8864
  );
8865
8865
  }
8866
8866
  }
8867
+ /**
8868
+ * Adopt an existing IAM inline policy into cdkd state.
8869
+ *
8870
+ * **Explicit override only.** `AWS::IAM::Policy` in CloudFormation is an
8871
+ * inline policy attached to roles / groups / users — not a standalone
8872
+ * resource. Inline policies are not taggable and have no global identity,
8873
+ * so tag-based auto-lookup via `aws:cdk:path` is not feasible. Users
8874
+ * adopting inline policies must pass `--resource <logicalId>=<policyName>`
8875
+ * (the physical id is the policy name itself).
8876
+ *
8877
+ * For standalone managed policies (`AWS::IAM::ManagedPolicy`), the
8878
+ * Cloud Control API fallback handles import via the same explicit
8879
+ * override mode.
8880
+ */
8881
+ // eslint-disable-next-line @typescript-eslint/require-await -- explicit-override-only intentionally has no AWS calls
8882
+ async import(input) {
8883
+ if (input.knownPhysicalId) {
8884
+ return { physicalId: input.knownPhysicalId, attributes: {} };
8885
+ }
8886
+ return null;
8887
+ }
8867
8888
  };
8868
8889
 
8869
8890
  // src/provisioning/providers/iam-instance-profile-provider.ts
@@ -8871,6 +8892,7 @@ import {
8871
8892
  CreateInstanceProfileCommand,
8872
8893
  DeleteInstanceProfileCommand,
8873
8894
  GetInstanceProfileCommand,
8895
+ ListInstanceProfilesCommand,
8874
8896
  AddRoleToInstanceProfileCommand,
8875
8897
  RemoveRoleFromInstanceProfileCommand as RemoveRoleFromInstanceProfileCommand2,
8876
8898
  NoSuchEntityException as NoSuchEntityException3
@@ -9072,6 +9094,48 @@ var IAMInstanceProfileProvider = class {
9072
9094
  );
9073
9095
  }
9074
9096
  }
9097
+ /**
9098
+ * Adopt an existing IAM instance profile into cdkd state.
9099
+ *
9100
+ * Lookup order:
9101
+ * 1. `--resource` override or `Properties.InstanceProfileName` → verify
9102
+ * via `GetInstanceProfile`.
9103
+ * 2. `ListInstanceProfiles` paginator + match `aws:cdk:path` against the
9104
+ * `InstanceProfile.Tags` array returned inline (no separate
9105
+ * `ListInstanceProfileTags` call needed).
9106
+ *
9107
+ * IAM is global; this walks every instance profile in the account once.
9108
+ */
9109
+ async import(input) {
9110
+ const explicit = resolveExplicitPhysicalId(input, "InstanceProfileName");
9111
+ if (explicit) {
9112
+ try {
9113
+ await this.iamClient.send(new GetInstanceProfileCommand({ InstanceProfileName: explicit }));
9114
+ return { physicalId: explicit, attributes: {} };
9115
+ } catch (err) {
9116
+ if (err instanceof NoSuchEntityException3)
9117
+ return null;
9118
+ throw err;
9119
+ }
9120
+ }
9121
+ if (!input.cdkPath)
9122
+ return null;
9123
+ let marker;
9124
+ do {
9125
+ const list = await this.iamClient.send(
9126
+ new ListInstanceProfilesCommand({ ...marker && { Marker: marker } })
9127
+ );
9128
+ for (const profile of list.InstanceProfiles ?? []) {
9129
+ if (!profile.InstanceProfileName)
9130
+ continue;
9131
+ if (matchesCdkPath(profile.Tags, input.cdkPath)) {
9132
+ return { physicalId: profile.InstanceProfileName, attributes: {} };
9133
+ }
9134
+ }
9135
+ marker = list.IsTruncated ? list.Marker : void 0;
9136
+ } while (marker);
9137
+ return null;
9138
+ }
9075
9139
  };
9076
9140
 
9077
9141
  // src/provisioning/providers/iam-user-group-provider.ts
@@ -9102,6 +9166,8 @@ import {
9102
9166
  DeleteLoginProfileCommand,
9103
9167
  ListAccessKeysCommand,
9104
9168
  DeleteAccessKeyCommand,
9169
+ ListUsersCommand,
9170
+ ListUserTagsCommand,
9105
9171
  NoSuchEntityException as NoSuchEntityException4,
9106
9172
  TagUserCommand,
9107
9173
  PutUserPermissionsBoundaryCommand,
@@ -10080,6 +10146,92 @@ var IAMUserGroupProvider = class {
10080
10146
  );
10081
10147
  }
10082
10148
  }
10149
+ // ─── Import dispatch ──────────────────────────────────────────────
10150
+ /**
10151
+ * Adopt an existing IAM user / group / user-to-group addition into cdkd state.
10152
+ *
10153
+ * - **AWS::IAM::User**: tag-based auto-lookup via `ListUsers` +
10154
+ * `ListUserTags`. Falls back to `--resource` override or
10155
+ * `Properties.UserName`.
10156
+ * - **AWS::IAM::Group**: explicit-override only. IAM groups are not
10157
+ * taggable (no `ListGroupTags` API), so tag-based auto-lookup is not
10158
+ * possible. Caller can still pass `Properties.GroupName` or
10159
+ * `--resource` to verify and adopt by name.
10160
+ * - **AWS::IAM::UserToGroupAddition**: explicit-override only. Has no
10161
+ * AWS-side identity beyond the (group, users) attachment itself.
10162
+ */
10163
+ async import(input) {
10164
+ switch (input.resourceType) {
10165
+ case "AWS::IAM::User":
10166
+ return this.importUser(input);
10167
+ case "AWS::IAM::Group":
10168
+ return this.importGroup(input);
10169
+ case "AWS::IAM::UserToGroupAddition":
10170
+ return this.importUserToGroupAddition(input);
10171
+ default:
10172
+ return null;
10173
+ }
10174
+ }
10175
+ async importUser(input) {
10176
+ const explicit = resolveExplicitPhysicalId(input, "UserName");
10177
+ if (explicit) {
10178
+ try {
10179
+ await this.iamClient.send(new GetUserCommand({ UserName: explicit }));
10180
+ return { physicalId: explicit, attributes: {} };
10181
+ } catch (err) {
10182
+ if (err instanceof NoSuchEntityException4)
10183
+ return null;
10184
+ throw err;
10185
+ }
10186
+ }
10187
+ if (!input.cdkPath)
10188
+ return null;
10189
+ let marker;
10190
+ do {
10191
+ const list = await this.iamClient.send(
10192
+ new ListUsersCommand({ ...marker && { Marker: marker } })
10193
+ );
10194
+ for (const user of list.Users ?? []) {
10195
+ if (!user.UserName)
10196
+ continue;
10197
+ try {
10198
+ const tags = await this.iamClient.send(
10199
+ new ListUserTagsCommand({ UserName: user.UserName })
10200
+ );
10201
+ if (matchesCdkPath(tags.Tags, input.cdkPath)) {
10202
+ return { physicalId: user.UserName, attributes: {} };
10203
+ }
10204
+ } catch (err) {
10205
+ if (err instanceof NoSuchEntityException4)
10206
+ continue;
10207
+ throw err;
10208
+ }
10209
+ }
10210
+ marker = list.IsTruncated ? list.Marker : void 0;
10211
+ } while (marker);
10212
+ return null;
10213
+ }
10214
+ async importGroup(input) {
10215
+ const explicit = resolveExplicitPhysicalId(input, "GroupName");
10216
+ if (explicit) {
10217
+ try {
10218
+ await this.iamClient.send(new GetGroupCommand({ GroupName: explicit }));
10219
+ return { physicalId: explicit, attributes: {} };
10220
+ } catch (err) {
10221
+ if (err instanceof NoSuchEntityException4)
10222
+ return null;
10223
+ throw err;
10224
+ }
10225
+ }
10226
+ return null;
10227
+ }
10228
+ // eslint-disable-next-line @typescript-eslint/require-await -- explicit-override-only intentionally has no AWS calls
10229
+ async importUserToGroupAddition(input) {
10230
+ if (input.knownPhysicalId) {
10231
+ return { physicalId: input.knownPhysicalId, attributes: {} };
10232
+ }
10233
+ return null;
10234
+ }
10083
10235
  };
10084
10236
 
10085
10237
  // src/provisioning/providers/s3-bucket-provider.ts
@@ -13523,6 +13675,9 @@ var LambdaEventSourceMappingProvider = class {
13523
13675
  import {
13524
13676
  PublishLayerVersionCommand,
13525
13677
  DeleteLayerVersionCommand,
13678
+ GetLayerVersionByArnCommand,
13679
+ ListLayersCommand,
13680
+ ListTagsCommand as ListTagsCommand2,
13526
13681
  ResourceNotFoundException as ResourceNotFoundException5
13527
13682
  } from "@aws-sdk/client-lambda";
13528
13683
  init_aws_clients();
@@ -13661,6 +13816,67 @@ var LambdaLayerVersionProvider = class {
13661
13816
  );
13662
13817
  }
13663
13818
  }
13819
+ /**
13820
+ * Adopt an existing Lambda layer version into cdkd state.
13821
+ *
13822
+ * Lookup order:
13823
+ * 1. `--resource <id>=<layerVersionArn>` override → verify with
13824
+ * `GetLayerVersionByArn`. (Note: there is no `LayerName` field that
13825
+ * uniquely names a *version*; a layer name resolves to the latest
13826
+ * version, so an explicit ARN is the only unambiguous override.)
13827
+ * 2. `ListLayers` paginator + `ListTags(Resource: layerArn)` (which
13828
+ * returns a `Tags: Record<string,string>` map keyed by tag name).
13829
+ * Match `aws:cdk:path` and adopt `LatestMatchingVersion.LayerVersionArn`.
13830
+ *
13831
+ * **Caveat**: Lambda layer versions are immutable, so auto-lookup adopts
13832
+ * the LATEST version of the named layer that carries the matching CDK
13833
+ * path tag. If the user's CDK app has since published newer versions
13834
+ * outside cdkd's tracking, the adopted physical id may be stale; pass
13835
+ * `--resource <id>=<arn>` to pin a specific version.
13836
+ */
13837
+ async import(input) {
13838
+ if (input.knownPhysicalId) {
13839
+ try {
13840
+ await this.lambdaClient.send(
13841
+ new GetLayerVersionByArnCommand({ Arn: input.knownPhysicalId })
13842
+ );
13843
+ return { physicalId: input.knownPhysicalId, attributes: {} };
13844
+ } catch (err) {
13845
+ if (err instanceof ResourceNotFoundException5)
13846
+ return null;
13847
+ throw err;
13848
+ }
13849
+ }
13850
+ if (!input.cdkPath)
13851
+ return null;
13852
+ let marker;
13853
+ do {
13854
+ const list = await this.lambdaClient.send(
13855
+ new ListLayersCommand({ ...marker && { Marker: marker } })
13856
+ );
13857
+ for (const layer of list.Layers ?? []) {
13858
+ if (!layer.LayerArn || !layer.LatestMatchingVersion?.LayerVersionArn)
13859
+ continue;
13860
+ try {
13861
+ const tagsResp = await this.lambdaClient.send(
13862
+ new ListTagsCommand2({ Resource: layer.LayerArn })
13863
+ );
13864
+ if (tagsResp.Tags?.[CDK_PATH_TAG] === input.cdkPath) {
13865
+ return {
13866
+ physicalId: layer.LatestMatchingVersion.LayerVersionArn,
13867
+ attributes: {}
13868
+ };
13869
+ }
13870
+ } catch (err) {
13871
+ if (err instanceof ResourceNotFoundException5)
13872
+ continue;
13873
+ throw err;
13874
+ }
13875
+ }
13876
+ marker = list.NextMarker;
13877
+ } while (marker);
13878
+ return null;
13879
+ }
13664
13880
  };
13665
13881
 
13666
13882
  // src/provisioning/providers/dynamodb-table-provider.ts
@@ -24768,7 +24984,12 @@ import {
24768
24984
  DeleteNamespaceCommand,
24769
24985
  CreateServiceCommand as CreateServiceCommand2,
24770
24986
  DeleteServiceCommand as DeleteServiceCommand2,
24987
+ GetNamespaceCommand,
24771
24988
  GetOperationCommand,
24989
+ GetServiceCommand,
24990
+ ListNamespacesCommand,
24991
+ ListServicesCommand as ListServicesCommand2,
24992
+ ListTagsForResourceCommand as ListTagsForResourceCommand15,
24772
24993
  NamespaceNotFound,
24773
24994
  ServiceNotFound
24774
24995
  } from "@aws-sdk/client-servicediscovery";
@@ -25089,6 +25310,107 @@ var ServiceDiscoveryProvider = class {
25089
25310
  logicalId
25090
25311
  );
25091
25312
  }
25313
+ // ─── Import dispatch ──────────────────────────────────────────────
25314
+ /**
25315
+ * Adopt an existing Cloud Map (Service Discovery) resource into cdkd state.
25316
+ *
25317
+ * - **AWS::ServiceDiscovery::PrivateDnsNamespace**: tag-based auto-lookup
25318
+ * via `ListNamespaces` + `ListTagsForResource(ResourceARN)` (Tag[]
25319
+ * array). Falls back to `--resource` override or matching
25320
+ * `Properties.Name` against the namespace name.
25321
+ * - **AWS::ServiceDiscovery::Service**: same shape — `ListServices` +
25322
+ * `ListTagsForResource`. Both use `Tag[]` arrays.
25323
+ */
25324
+ async import(input) {
25325
+ switch (input.resourceType) {
25326
+ case "AWS::ServiceDiscovery::PrivateDnsNamespace":
25327
+ return this.importNamespaceResource(input);
25328
+ case "AWS::ServiceDiscovery::Service":
25329
+ return this.importServiceResource(input);
25330
+ default:
25331
+ return null;
25332
+ }
25333
+ }
25334
+ async importNamespaceResource(input) {
25335
+ if (input.knownPhysicalId) {
25336
+ try {
25337
+ await this.getClient().send(new GetNamespaceCommand({ Id: input.knownPhysicalId }));
25338
+ return { physicalId: input.knownPhysicalId, attributes: {} };
25339
+ } catch (err) {
25340
+ if (err instanceof NamespaceNotFound)
25341
+ return null;
25342
+ throw err;
25343
+ }
25344
+ }
25345
+ const desiredName = typeof input.properties?.["Name"] === "string" ? input.properties["Name"] : void 0;
25346
+ let token;
25347
+ do {
25348
+ const list = await this.getClient().send(
25349
+ new ListNamespacesCommand({ ...token && { NextToken: token } })
25350
+ );
25351
+ for (const ns of list.Namespaces ?? []) {
25352
+ if (!ns.Id || !ns.Arn)
25353
+ continue;
25354
+ if (desiredName && ns.Name === desiredName) {
25355
+ return { physicalId: ns.Id, attributes: {} };
25356
+ }
25357
+ if (input.cdkPath) {
25358
+ try {
25359
+ const tagsResp = await this.getClient().send(
25360
+ new ListTagsForResourceCommand15({ ResourceARN: ns.Arn })
25361
+ );
25362
+ if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
25363
+ return { physicalId: ns.Id, attributes: {} };
25364
+ }
25365
+ } catch (err) {
25366
+ if (err instanceof NamespaceNotFound)
25367
+ continue;
25368
+ throw err;
25369
+ }
25370
+ }
25371
+ }
25372
+ token = list.NextToken;
25373
+ } while (token);
25374
+ return null;
25375
+ }
25376
+ async importServiceResource(input) {
25377
+ if (input.knownPhysicalId) {
25378
+ try {
25379
+ await this.getClient().send(new GetServiceCommand({ Id: input.knownPhysicalId }));
25380
+ return { physicalId: input.knownPhysicalId, attributes: {} };
25381
+ } catch (err) {
25382
+ if (err instanceof ServiceNotFound)
25383
+ return null;
25384
+ throw err;
25385
+ }
25386
+ }
25387
+ if (!input.cdkPath)
25388
+ return null;
25389
+ let token;
25390
+ do {
25391
+ const list = await this.getClient().send(
25392
+ new ListServicesCommand2({ ...token && { NextToken: token } })
25393
+ );
25394
+ for (const svc of list.Services ?? []) {
25395
+ if (!svc.Id || !svc.Arn)
25396
+ continue;
25397
+ try {
25398
+ const tagsResp = await this.getClient().send(
25399
+ new ListTagsForResourceCommand15({ ResourceARN: svc.Arn })
25400
+ );
25401
+ if (matchesCdkPath(tagsResp.Tags, input.cdkPath)) {
25402
+ return { physicalId: svc.Id, attributes: {} };
25403
+ }
25404
+ } catch (err) {
25405
+ if (err instanceof ServiceNotFound)
25406
+ continue;
25407
+ throw err;
25408
+ }
25409
+ }
25410
+ token = list.NextToken;
25411
+ } while (token);
25412
+ return null;
25413
+ }
25092
25414
  /**
25093
25415
  * Build a namespace ARN from namespace ID.
25094
25416
  * Format: arn:aws:servicediscovery:{region}:{account}:namespace/{namespaceId}
@@ -27977,7 +28299,7 @@ import {
27977
28299
  PutInsightSelectorsCommand,
27978
28300
  GetTrailCommand,
27979
28301
  ListTrailsCommand,
27980
- ListTagsCommand as ListTagsCommand2,
28302
+ ListTagsCommand as ListTagsCommand3,
27981
28303
  TrailNotFoundException
27982
28304
  } from "@aws-sdk/client-cloudtrail";
27983
28305
  var CloudTrailProvider = class {
@@ -28241,7 +28563,7 @@ var CloudTrailProvider = class {
28241
28563
  continue;
28242
28564
  try {
28243
28565
  const tagsResp = await this.getClient().send(
28244
- new ListTagsCommand2({ ResourceIdList: [trail.TrailARN] })
28566
+ new ListTagsCommand3({ ResourceIdList: [trail.TrailARN] })
28245
28567
  );
28246
28568
  const list2 = tagsResp.ResourceTagList?.[0];
28247
28569
  if (matchesCdkPath(list2?.TagsList, input.cdkPath)) {
@@ -28580,7 +28902,10 @@ import {
28580
28902
  S3VectorsClient,
28581
28903
  CreateVectorBucketCommand,
28582
28904
  DeleteVectorBucketCommand,
28905
+ GetVectorBucketCommand,
28583
28906
  ListIndexesCommand,
28907
+ ListVectorBucketsCommand,
28908
+ ListTagsForResourceCommand as ListTagsForResourceCommand16,
28584
28909
  DeleteIndexCommand
28585
28910
  } from "@aws-sdk/client-s3vectors";
28586
28911
  var S3VectorsProvider = class {
@@ -28737,6 +29062,54 @@ var S3VectorsProvider = class {
28737
29062
  nextToken = listResult.nextToken;
28738
29063
  } while (nextToken);
28739
29064
  }
29065
+ /**
29066
+ * Adopt an existing S3 Vector Bucket into cdkd state.
29067
+ *
29068
+ * Lookup order:
29069
+ * 1. `--resource <id>=<name>` override or `Properties.VectorBucketName`
29070
+ * → verify via `GetVectorBucket`. The physical id is the bucket name.
29071
+ * 2. `ListVectorBuckets` paginator + `ListTagsForResource(resourceArn)`
29072
+ * (tags map keyed by tag name) and match `aws:cdk:path`.
29073
+ */
29074
+ async import(input) {
29075
+ const explicit = input.knownPhysicalId ?? (typeof input.properties?.["VectorBucketName"] === "string" && input.properties["VectorBucketName"].length > 0 ? input.properties["VectorBucketName"] : void 0);
29076
+ if (explicit) {
29077
+ try {
29078
+ await this.getClient().send(new GetVectorBucketCommand({ vectorBucketName: explicit }));
29079
+ return { physicalId: explicit, attributes: {} };
29080
+ } catch (err) {
29081
+ if (this.isNotFoundError(err))
29082
+ return null;
29083
+ throw err;
29084
+ }
29085
+ }
29086
+ if (!input.cdkPath)
29087
+ return null;
29088
+ let token;
29089
+ do {
29090
+ const list = await this.getClient().send(
29091
+ new ListVectorBucketsCommand({ ...token && { nextToken: token } })
29092
+ );
29093
+ for (const bucket of list.vectorBuckets ?? []) {
29094
+ if (!bucket.vectorBucketName || !bucket.vectorBucketArn)
29095
+ continue;
29096
+ try {
29097
+ const tagsResp = await this.getClient().send(
29098
+ new ListTagsForResourceCommand16({ resourceArn: bucket.vectorBucketArn })
29099
+ );
29100
+ if (tagsResp.tags?.[CDK_PATH_TAG] === input.cdkPath) {
29101
+ return { physicalId: bucket.vectorBucketName, attributes: {} };
29102
+ }
29103
+ } catch (err) {
29104
+ if (this.isNotFoundError(err))
29105
+ continue;
29106
+ throw err;
29107
+ }
29108
+ }
29109
+ token = list.nextToken;
29110
+ } while (token);
29111
+ return null;
29112
+ }
28740
29113
  isNotFoundError(error) {
28741
29114
  if (error instanceof Error) {
28742
29115
  const name = error.name;
@@ -28750,6 +29123,9 @@ var S3VectorsProvider = class {
28750
29123
  import {
28751
29124
  CreateBucketCommand as CreateBucketCommand3,
28752
29125
  DeleteBucketCommand as DeleteBucketCommand2,
29126
+ HeadBucketCommand as HeadBucketCommand4,
29127
+ ListDirectoryBucketsCommand,
29128
+ GetBucketTaggingCommand as GetBucketTaggingCommand2,
28753
29129
  ListObjectsV2Command as ListObjectsV2Command2,
28754
29130
  DeleteObjectsCommand as DeleteObjectsCommand2
28755
29131
  } from "@aws-sdk/client-s3";
@@ -28955,6 +29331,56 @@ var S3DirectoryBucketProvider = class {
28955
29331
  continuationToken = listResponse.IsTruncated ? listResponse.NextContinuationToken : void 0;
28956
29332
  } while (continuationToken);
28957
29333
  }
29334
+ /**
29335
+ * Adopt an existing S3 Express Directory Bucket into cdkd state.
29336
+ *
29337
+ * Lookup order:
29338
+ * 1. `--resource <id>=<name>` override or `Properties.BucketName` →
29339
+ * verify via `HeadBucket`.
29340
+ * 2. `ListDirectoryBuckets` paginator + `GetBucketTagging` (TagSet:
29341
+ * Tag[]) and match `aws:cdk:path`. `GetBucketTagging` may surface
29342
+ * `NoSuchTagSet` / `AccessDenied` per-bucket — those are skipped
29343
+ * rather than fatal.
29344
+ */
29345
+ async import(input) {
29346
+ const explicit = resolveExplicitPhysicalId(input, "BucketName");
29347
+ if (explicit) {
29348
+ try {
29349
+ await this.s3Client.send(new HeadBucketCommand4({ Bucket: explicit }));
29350
+ return { physicalId: explicit, attributes: {} };
29351
+ } catch (err) {
29352
+ const e = err;
29353
+ if (e.name === "NotFound" || e.name === "NoSuchBucket")
29354
+ return null;
29355
+ throw err;
29356
+ }
29357
+ }
29358
+ if (!input.cdkPath)
29359
+ return null;
29360
+ let token;
29361
+ do {
29362
+ const list = await this.s3Client.send(
29363
+ new ListDirectoryBucketsCommand({ ...token && { ContinuationToken: token } })
29364
+ );
29365
+ for (const b of list.Buckets ?? []) {
29366
+ if (!b.Name)
29367
+ continue;
29368
+ try {
29369
+ const tagging = await this.s3Client.send(new GetBucketTaggingCommand2({ Bucket: b.Name }));
29370
+ if (matchesCdkPath(tagging.TagSet, input.cdkPath)) {
29371
+ return { physicalId: b.Name, attributes: {} };
29372
+ }
29373
+ } catch (err) {
29374
+ const e = err;
29375
+ if (e.name === "NoSuchTagSet" || e.name === "AccessDenied")
29376
+ continue;
29377
+ throw err;
29378
+ }
29379
+ }
29380
+ token = list.ContinuationToken;
29381
+ } while (token);
29382
+ return null;
29383
+ }
28958
29384
  };
28959
29385
 
28960
29386
  // src/provisioning/providers/s3-tables-provider.ts
@@ -28966,8 +29392,12 @@ import {
28966
29392
  DeleteNamespaceCommand as DeleteNamespaceCommand2,
28967
29393
  CreateTableCommand as CreateTableCommand3,
28968
29394
  DeleteTableCommand as DeleteTableCommand3,
28969
- ListNamespacesCommand,
29395
+ GetTableBucketCommand,
29396
+ GetTableCommand as GetTableCommand2,
29397
+ ListNamespacesCommand as ListNamespacesCommand2,
28970
29398
  ListTablesCommand as ListTablesCommand2,
29399
+ ListTableBucketsCommand,
29400
+ ListTagsForResourceCommand as ListTagsForResourceCommand17,
28971
29401
  NotFoundException as NotFoundException6
28972
29402
  } from "@aws-sdk/client-s3tables";
28973
29403
  var S3TablesProvider = class {
@@ -29101,7 +29531,7 @@ var S3TablesProvider = class {
29101
29531
  let namespaceContinuationToken;
29102
29532
  do {
29103
29533
  const namespacesResult = await this.getClient().send(
29104
- new ListNamespacesCommand({
29534
+ new ListNamespacesCommand2({
29105
29535
  tableBucketARN,
29106
29536
  continuationToken: namespaceContinuationToken
29107
29537
  })
@@ -29305,6 +29735,165 @@ var S3TablesProvider = class {
29305
29735
  );
29306
29736
  }
29307
29737
  }
29738
+ // ─── Import dispatch ──────────────────────────────────────────────
29739
+ /**
29740
+ * Adopt an existing S3 Tables resource into cdkd state.
29741
+ *
29742
+ * - **AWS::S3Tables::TableBucket**: tag-based auto-lookup via
29743
+ * `ListTableBuckets` + `ListTagsForResource(resourceArn)` (tags map).
29744
+ * Falls back to `--resource <id>=<arn>` or `Properties.TableBucketName`
29745
+ * (resolved by ARN suffix match against `ListTableBuckets`).
29746
+ * - **AWS::S3Tables::Table**: tag-based auto-lookup walks every
29747
+ * table bucket → namespace → table and calls `ListTagsForResource`
29748
+ * on each table ARN; matches `aws:cdk:path`.
29749
+ * - **AWS::S3Tables::Namespace**: explicit-override only. Namespaces
29750
+ * are not taggable in S3 Tables (`ListTagsForResource` accepts only
29751
+ * table-bucket or table ARNs), so auto-lookup is impossible.
29752
+ */
29753
+ async import(input) {
29754
+ switch (input.resourceType) {
29755
+ case "AWS::S3Tables::TableBucket":
29756
+ return this.importTableBucket(input);
29757
+ case "AWS::S3Tables::Namespace":
29758
+ return this.importNamespace(input);
29759
+ case "AWS::S3Tables::Table":
29760
+ return this.importTable(input);
29761
+ default:
29762
+ return null;
29763
+ }
29764
+ }
29765
+ async importTableBucket(input) {
29766
+ if (input.knownPhysicalId) {
29767
+ try {
29768
+ await this.getClient().send(
29769
+ new GetTableBucketCommand({ tableBucketARN: input.knownPhysicalId })
29770
+ );
29771
+ return { physicalId: input.knownPhysicalId, attributes: {} };
29772
+ } catch (err) {
29773
+ if (err instanceof NotFoundException6)
29774
+ return null;
29775
+ throw err;
29776
+ }
29777
+ }
29778
+ const desiredName = typeof input.properties?.["TableBucketName"] === "string" ? input.properties["TableBucketName"] : void 0;
29779
+ let token;
29780
+ do {
29781
+ const list = await this.getClient().send(
29782
+ new ListTableBucketsCommand({ ...token && { continuationToken: token } })
29783
+ );
29784
+ for (const bucket of list.tableBuckets ?? []) {
29785
+ if (!bucket.arn)
29786
+ continue;
29787
+ if (desiredName && bucket.name === desiredName) {
29788
+ return { physicalId: bucket.arn, attributes: {} };
29789
+ }
29790
+ if (input.cdkPath) {
29791
+ try {
29792
+ const tagsResp = await this.getClient().send(
29793
+ new ListTagsForResourceCommand17({ resourceArn: bucket.arn })
29794
+ );
29795
+ if (tagsResp.tags?.[CDK_PATH_TAG] === input.cdkPath) {
29796
+ return { physicalId: bucket.arn, attributes: {} };
29797
+ }
29798
+ } catch (err) {
29799
+ if (err instanceof NotFoundException6)
29800
+ continue;
29801
+ throw err;
29802
+ }
29803
+ }
29804
+ }
29805
+ token = list.continuationToken;
29806
+ } while (token);
29807
+ return null;
29808
+ }
29809
+ // eslint-disable-next-line @typescript-eslint/require-await -- explicit-override-only intentionally has no AWS calls
29810
+ async importNamespace(input) {
29811
+ if (input.knownPhysicalId) {
29812
+ return { physicalId: input.knownPhysicalId, attributes: {} };
29813
+ }
29814
+ return null;
29815
+ }
29816
+ async importTable(input) {
29817
+ if (input.knownPhysicalId) {
29818
+ const parts = input.knownPhysicalId.split("|");
29819
+ if (parts.length >= 3) {
29820
+ try {
29821
+ await this.getClient().send(
29822
+ new GetTableCommand2({
29823
+ tableBucketARN: parts[0],
29824
+ namespace: parts[1],
29825
+ name: parts[2]
29826
+ })
29827
+ );
29828
+ return { physicalId: input.knownPhysicalId, attributes: {} };
29829
+ } catch (err) {
29830
+ if (err instanceof NotFoundException6)
29831
+ return null;
29832
+ throw err;
29833
+ }
29834
+ }
29835
+ return { physicalId: input.knownPhysicalId, attributes: {} };
29836
+ }
29837
+ if (!input.cdkPath)
29838
+ return null;
29839
+ let bucketToken;
29840
+ do {
29841
+ const buckets = await this.getClient().send(
29842
+ new ListTableBucketsCommand({ ...bucketToken && { continuationToken: bucketToken } })
29843
+ );
29844
+ for (const bucket of buckets.tableBuckets ?? []) {
29845
+ if (!bucket.arn)
29846
+ continue;
29847
+ let nsToken;
29848
+ do {
29849
+ const namespaces = await this.getClient().send(
29850
+ new ListNamespacesCommand2({
29851
+ tableBucketARN: bucket.arn,
29852
+ ...nsToken && { continuationToken: nsToken }
29853
+ })
29854
+ );
29855
+ for (const ns of namespaces.namespaces ?? []) {
29856
+ const namespaceName = ns.namespace?.[0];
29857
+ if (!namespaceName)
29858
+ continue;
29859
+ let tableToken;
29860
+ do {
29861
+ const tables = await this.getClient().send(
29862
+ new ListTablesCommand2({
29863
+ tableBucketARN: bucket.arn,
29864
+ namespace: namespaceName,
29865
+ ...tableToken && { continuationToken: tableToken }
29866
+ })
29867
+ );
29868
+ for (const table of tables.tables ?? []) {
29869
+ if (!table.name || !table.tableARN)
29870
+ continue;
29871
+ try {
29872
+ const tagsResp = await this.getClient().send(
29873
+ new ListTagsForResourceCommand17({ resourceArn: table.tableARN })
29874
+ );
29875
+ if (tagsResp.tags?.[CDK_PATH_TAG] === input.cdkPath) {
29876
+ return {
29877
+ physicalId: `${bucket.arn}|${namespaceName}|${table.name}`,
29878
+ attributes: {}
29879
+ };
29880
+ }
29881
+ } catch (err) {
29882
+ if (err instanceof NotFoundException6)
29883
+ continue;
29884
+ throw err;
29885
+ }
29886
+ }
29887
+ tableToken = tables.continuationToken;
29888
+ } while (tableToken);
29889
+ }
29890
+ nsToken = namespaces.continuationToken;
29891
+ } while (nsToken);
29892
+ }
29893
+ bucketToken = buckets.continuationToken;
29894
+ } while (bucketToken);
29895
+ return null;
29896
+ }
29308
29897
  async deleteTable(logicalId, physicalId, resourceType, context) {
29309
29898
  this.logger.debug(`Deleting S3 Tables Table ${logicalId}: ${physicalId}`);
29310
29899
  const parts = physicalId.split("|");
@@ -29364,7 +29953,7 @@ import {
29364
29953
  PutImageScanningConfigurationCommand,
29365
29954
  PutImageTagMutabilityCommand,
29366
29955
  TagResourceCommand as TagResourceCommand7,
29367
- ListTagsForResourceCommand as ListTagsForResourceCommand15,
29956
+ ListTagsForResourceCommand as ListTagsForResourceCommand18,
29368
29957
  RepositoryNotFoundException
29369
29958
  } from "@aws-sdk/client-ecr";
29370
29959
  var ECRProvider = class {
@@ -29633,7 +30222,7 @@ var ECRProvider = class {
29633
30222
  continue;
29634
30223
  try {
29635
30224
  const tagsResp = await this.getClient().send(
29636
- new ListTagsForResourceCommand15({ resourceArn: repo.repositoryArn })
30225
+ new ListTagsForResourceCommand18({ resourceArn: repo.repositoryArn })
29637
30226
  );
29638
30227
  if (matchesCdkPath(tagsResp.tags, input.cdkPath)) {
29639
30228
  return { physicalId: repo.repositoryName, attributes: {} };
@@ -32210,7 +32799,7 @@ import {
32210
32799
  CreateBucketCommand as CreateBucketCommand4,
32211
32800
  DeleteBucketCommand as DeleteBucketCommand3,
32212
32801
  DeleteObjectsCommand as DeleteObjectsCommand3,
32213
- HeadBucketCommand as HeadBucketCommand4,
32802
+ HeadBucketCommand as HeadBucketCommand5,
32214
32803
  ListObjectVersionsCommand as ListObjectVersionsCommand2,
32215
32804
  ListObjectsV2Command as ListObjectsV2Command3,
32216
32805
  PutBucketEncryptionCommand as PutBucketEncryptionCommand3,
@@ -32333,7 +32922,7 @@ async function stateMigrateCommand(options) {
32333
32922
  }
32334
32923
  async function bucketExists2(s3, bucketName) {
32335
32924
  try {
32336
- await s3.send(new HeadBucketCommand4({ Bucket: bucketName }));
32925
+ await s3.send(new HeadBucketCommand5({ Bucket: bucketName }));
32337
32926
  return true;
32338
32927
  } catch (error) {
32339
32928
  const err = error;
@@ -33559,7 +34148,7 @@ function reorderArgs(argv) {
33559
34148
  }
33560
34149
  async function main() {
33561
34150
  const program = new Command13();
33562
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.20.0");
34151
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.21.0");
33563
34152
  program.addCommand(createBootstrapCommand());
33564
34153
  program.addCommand(createSynthCommand());
33565
34154
  program.addCommand(createListCommand());