@go-to-k/cdkd 0.280.40 → 0.280.42

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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as requireConfigObject, $t as AssemblyReader, A as green, At as runDockerForeground, B as disableInstanceApiTermination, Bt as resolveCaptureObservedState, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackTerminationProtectionError, Ct as getBootstrapMarkerKey, D as bold, Dt as buildDockerImage, E as formatResourceLine, Et as validateContainerRepoName, F as clearOnUpdateRemoval, Ft as synthesisStatusMessage, G as WAFv2WebACLProvider, Gt as stateBucketExistenceConfirmed, H as IntrinsicFunctionResolver, Ht as resolveStateBucketWithDefault, I as ProviderRegistry, It as getDefaultStateBucketName, J as assertRegionMatch, Jt as CFN_TEMPLATE_URL_LIMIT, K as normalizeAwsTagsToCfn, Kt as warnDeprecatedNoPrefixCliFlag, L as findActionableSilentDrops, Lt as getLegacyStateBucketName, M as yellow, Mt as AssetManifestLoader, N as IAMRoleProvider, Nt as getDockerImageBySourceHash, O as cyan, On as normalizeAwsError, Ot as formatDockerLoginError, P as collectInlinePolicyNamesManagedBySiblings, Pt as Synthesizer, Q as requireConfigArray, Qt as expectedOwnerParam, R as CloudControlProvider, Rt as resolveApp, S as extractDeploymentEventError, Sn as StackHasActiveImportsError, St as ensureAssetStorage, T as renderStatefulReason, Tt as validateAssetBucketName, U as cfnRefValueFromPhysicalId, Ut as resolveStateBucketWithDefaultAndSource, V as isTerminationProtectionPropagationError, Vt as resolveSkipPrefix, W as refStateLookupFromResource, Wt as resolveUseCdkBootstrapAssets, X as readConfigString, Xt as findLargeInlineResources, Y as configStringRefusal, Yt as MIGRATE_TMP_PREFIX, Z as replayWarn, Zt as uploadCfnTemplate, _ as createPreDeleteFinalSnapshot, _n as NestedStackChildDirectDestroyError, _t as createAssetRedirectResolver, a as DeploymentEventsStore, an as resetAwsClients, at as isRetryableTransientError, b as unsupportedFinalSnapshotError, bn as ResourceTimeoutError, bt as AssetModeResolver, c as replayFailedOperations, cn as CdkdError, ct as TemplateParser, d as IMPLICIT_DELETE_DEPENDENCIES, dn as DeployCancelledError, dt as rebuildClientForBucketRegion, en as processStackMessages, et as requireConfigString, f as computeImplicitDeleteEdges, fn as LocalInvokeBuildError$1, ft as shouldRetainResource, g as ccRoutedFinalSnapshotError, gn as MissingCdkCliError, gt as buildAssetRedirectMap, h as buildFinalSnapshotIdentifier, ht as WorkGraph, i as DeploymentEventsReader, in as getAwsClients, it as withRetry, j as red, jt as runDockerStreaming, k as gray, kn as withErrorHandling, kt as getDockerCmd, l as replayRollback, lt as LockManager, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalStartServiceError, mt as stringifyValue, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resolveBucketRegion, nt as DiffCalculator, o as planFailedOps, on as setAwsClients, ot as isThrottlingError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalMigrateError, pt as AssetPublisher, q as resolveExplicitPhysicalId, qt as CFN_TEMPLATE_BODY_LIMIT, r as DeployEngine, rn as AwsClients, rt as describeTypeWithThrottleRetry, s as planRollback, st as DagBuilder, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as applyRoleArnIfSet, u as withResourceDeadline, ut as S3StateBackend, v as isFinalSnapshotError, vn as PartialFailureError, vt as loadPublishableAssetManifest, w as isStatefulRecreateTargetSync, wt as parseBootstrapMarker, x as makeCanonicalizePropertiesFn, xn as ResourceUpdateNotSupportedError, xt as BOOTSTRAP_MARKER_PREFIX, y as refusesFinalSnapshot, yn as ProvisioningError, yt as rewriteTemplateAssetReferences, z as slowCcOperationTimeoutMs, zt as resolveAutoAssetStorage } from "./deploy-engine-CU47_nau.js";
2
+ import { $ as requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-CuwZzHlM.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
4
- import { t as ASGProvider } from "./asg-provider-BOGjxxxb.js";
4
+ import { t as ASGProvider } from "./asg-provider-a9iV8VG_.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -67,7 +67,7 @@ import AdmZip from "adm-zip";
67
67
  import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$14, TagResourceCommand as TagResourceCommand$21, UntagResourceCommand as UntagResourceCommand$21, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
68
68
  import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, S3VectorsClient, TagResourceCommand as TagResourceCommand$22, UntagResourceCommand as UntagResourceCommand$22 } from "@aws-sdk/client-s3vectors";
69
69
  import { ListTagsForResourceCommand as ListTagsForResourceCommand$18, S3ControlClient, TagResourceCommand as TagResourceCommand$23, UntagResourceCommand as UntagResourceCommand$23 } from "@aws-sdk/client-s3-control";
70
- import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$19, NotFoundException as NotFoundException$6, S3TablesClient, TagResourceCommand as TagResourceCommand$24, UntagResourceCommand as UntagResourceCommand$24 } from "@aws-sdk/client-s3tables";
70
+ import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetNamespaceCommand as GetNamespaceCommand$1, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$19, NotFoundException as NotFoundException$6, S3TablesClient, TagResourceCommand as TagResourceCommand$24, UntagResourceCommand as UntagResourceCommand$24 } from "@aws-sdk/client-s3tables";
71
71
  import { Document, Pair, Scalar, YAMLMap, YAMLSeq, parse as parse$1, stringify } from "yaml";
72
72
  import { createLocalStartAgentCoreCommand, createLocalStartCloudFrontCommand, createLocalStateProvider, getEmbedConfig, isCfnFlagPresent, listTargets, rejectExplicitCfnStackWithMultipleStacks, resolveCfnFallbackRegion, setEmbedConfig, substituteAgainstState, substituteAgainstStateAsync, substituteEnvVarsFromState, substituteEnvVarsFromStateAsync } from "cdk-local";
73
73
  import { A2A_CONTAINER_PORT, A2A_PATH, AGENTCORE_A2A_PROTOCOL, AGENTCORE_AGUI_PROTOCOL, AGENTCORE_MCP_PROTOCOL, ConnectionRegistry, EcsTaskResolutionError, HOST_GATEWAY_MIN_VERSION, LocalInvokeBuildError, MCP_CONTAINER_PORT, MCP_PATH, a2aInvokeOnce, addAlbSpecificOptions, addCommonEcsServiceOptions, addStartServiceSpecificOptions, albStrategy, architectureToPlatform, attachAuthorizers, attachStageContext, availableApiIdentifiers, bufferToBody, buildAgentCoreCodeImage, buildCognitoJwksUrl, buildConnectEvent, buildContainerImage, buildCorsConfigByApiId, buildCorsConfigFromCloudFrontChain, buildDisconnectEvent, buildJwksUrlFromIssuer, buildMessageEvent, buildMgmtEndpointEnvUrl, buildStageMap, classifySourceChange, createAuthorizerCache, createFileWatcher, createFileWatcher as createFileWatcher$1, createJwksCache, createWatchPredicates, defaultCredentialsLoader, derivePseudoParametersFromRegion, discoverRoutes, discoverWebSocketApis, downloadAndExtractS3Bundle, filterRoutesByApiIdentifier, groupRoutesByServer, handleConnectionsRequest, invokeAgentCore, invokeAgentCoreWs, materializeLayerFromArn, mcpInvokeOnce, parseConnectionsPath, parseSelectionExpressionPath, pickAgentCoreCandidateStack, pickAgentCoreCandidateStack as pickAgentCoreCandidateStack$1, probeHostGatewaySupport, readMtlsMaterialsFromDisk, resolveAgentCoreTarget, resolveEnvVars, resolveHostGatewayExtraHosts, resolveRuntimeCodeMountPath, resolveRuntimeFileExtension, resolveRuntimeImage, resolveSingleTarget, resolveWatchConfig, runEcsServiceEmulator, signAgentCoreInvocation, startApiServer, substituteImagePlaceholders, tryResolveImageFnJoin, verifyJwtViaDiscovery, waitForAgentCorePing } from "cdk-local/internal";
@@ -22724,13 +22724,33 @@ var ApiGatewayProvider = class ApiGatewayProvider {
22724
22724
  * Users adopting an existing API Gateway should pass
22725
22725
  * `--resource <logicalId>=<physicalId>` for each sub-resource; the
22726
22726
  * physical id format follows what `create()` returns for the same
22727
- * type (e.g. `<restApiId>|<resourceId>` for `AWS::ApiGateway::Resource`).
22727
+ * type. Note this is NOT uniformly a composite: `create()` returns a
22728
+ * BARE `resourceId` for `AWS::ApiGateway::Resource` (the parent
22729
+ * `RestApiId` is read from the recorded properties by every other
22730
+ * method), while `AWS::ApiGateway::Method` genuinely is
22731
+ * `<restApiId>|<resourceId>|<httpMethod>`.
22732
+ *
22733
+ * `import()` otherwise honours the supplied id verbatim, so a composite
22734
+ * passed for a type whose provider stores a SCALAR would be written to
22735
+ * state and then fed to the API as a resource id (issue #1663). That is
22736
+ * not merely a failed call: `deleteResource` treats `NotFoundException`
22737
+ * as an idempotent success, so the bad id would be reported as deleted
22738
+ * while the resource stayed live in AWS — a silent orphan, the same class
22739
+ * as issues #1651 / #1658. So the one type whose stored shape is
22740
+ * unambiguously scalar refuses a composite up front, where the user can
22741
+ * still act on it.
22728
22742
  */
22729
22743
  async import(input) {
22730
- if (input.knownPhysicalId) return {
22731
- physicalId: input.knownPhysicalId,
22732
- attributes: {}
22733
- };
22744
+ if (input.knownPhysicalId) {
22745
+ if (input.resourceType === "AWS::ApiGateway::Resource" && input.knownPhysicalId.includes("|")) {
22746
+ this.logger.warn(`AWS::ApiGateway::Resource ${input.logicalId}: '${input.knownPhysicalId}' looks like a composite, but cdkd stores a BARE resourceId for this type (the parent RestApiId comes from the template). Adopting it would send the whole string to the API as a resource id, and the delete path would then report success on the NotFound. Pass just the resourceId.`);
22747
+ return null;
22748
+ }
22749
+ return {
22750
+ physicalId: input.knownPhysicalId,
22751
+ attributes: {}
22752
+ };
22753
+ }
22734
22754
  return null;
22735
22755
  }
22736
22756
  };
@@ -48418,6 +48438,66 @@ var S3DirectoryBucketProvider = class {
48418
48438
  //#endregion
48419
48439
  //#region src/provisioning/providers/s3-tables-provider.ts
48420
48440
  /**
48441
+ * Parse cdkd's composite namespace physicalId `<tableBucketARN>|<namespace>`.
48442
+ *
48443
+ * Returns `undefined` for any other shape. Exactly two non-empty segments are
48444
+ * required: every other method on the provider splits the stored id on `|` and
48445
+ * indexes segments 0 and 1, so a wrong-arity id recorded verbatim produces a
48446
+ * state row that cannot be updated, deleted or read back (issue #1668).
48447
+ */
48448
+ function parseNamespaceCompositeId(physicalId) {
48449
+ const parts = physicalId.split("|");
48450
+ if (parts.length !== 2) return void 0;
48451
+ const [tableBucketARN, namespace] = parts;
48452
+ if (!tableBucketARN || !namespace) return void 0;
48453
+ return {
48454
+ tableBucketARN,
48455
+ namespace
48456
+ };
48457
+ }
48458
+ /** Parse cdkd's composite table physicalId `<tableBucketARN>|<namespace>|<name>`. */
48459
+ function parseTableCompositeId(physicalId) {
48460
+ const parts = physicalId.split("|");
48461
+ if (parts.length !== 3) return void 0;
48462
+ const [tableBucketARN, namespace, name] = parts;
48463
+ if (!tableBucketARN || !namespace || !name) return void 0;
48464
+ return {
48465
+ tableBucketARN,
48466
+ namespace,
48467
+ name
48468
+ };
48469
+ }
48470
+ /** Read a non-blank string property, tolerating a malformed properties bag. */
48471
+ function readStringProperty$1(properties, key) {
48472
+ const value = properties?.[key];
48473
+ return typeof value === "string" && value.length > 0 ? value : void 0;
48474
+ }
48475
+ /**
48476
+ * Rebuild a table's identity from what `GetTable` returned.
48477
+ *
48478
+ * Deliberately NOT from the template: a CDK-synthesized `TableBucketARN` is an
48479
+ * `Fn::GetAtt` object at import time (full intrinsic resolution runs after
48480
+ * `provider.import()`), so a template-side read is `undefined` on exactly the
48481
+ * `--migrate-from-cloudformation` path this exists to serve.
48482
+ *
48483
+ * The bucket ARN is the table ARN's prefix — S3 Tables ARNs are
48484
+ * `arn:<p>:s3tables:<region>:<acct>:bucket/<bucket>` and
48485
+ * `…:bucket/<bucket>/table/<id>` — so it is recovered by trimming at the last
48486
+ * `/table/` segment. `namespace` comes back as a single-element list.
48487
+ */
48488
+ function tableIdentityFromGetTable(tableARN, namespace, name) {
48489
+ const cut = tableARN.lastIndexOf("/table/");
48490
+ if (cut <= 0) return void 0;
48491
+ const tableBucketARN = tableARN.slice(0, cut);
48492
+ const ns = namespace?.[0];
48493
+ if (!tableBucketARN || !ns || !name) return void 0;
48494
+ return {
48495
+ tableBucketARN,
48496
+ namespace: ns,
48497
+ name
48498
+ };
48499
+ }
48500
+ /**
48421
48501
  * SDK Provider for AWS S3 Tables resources
48422
48502
  *
48423
48503
  * Supports:
@@ -48695,11 +48775,57 @@ var S3TablesProvider = class {
48695
48775
  Namespace: namespaceName
48696
48776
  };
48697
48777
  }
48698
- async readTableCurrentState(physicalId) {
48778
+ /**
48779
+ * Recover a table's `(bucketARN, namespace, name)` from EITHER id shape.
48780
+ *
48781
+ * cdkd's composite carries all three. CloudFormation's physicalId for this
48782
+ * type is the bare `TableARN` (single-field `primaryIdentifier`), and that
48783
+ * form reaches the SDK path in two ways worth tolerating rather than
48784
+ * rejecting:
48785
+ *
48786
+ * - every state row written by `cdkd import` before issue #1668, which
48787
+ * stored the CFn id verbatim; and
48788
+ * - a CC-ROUTED table imported by this version, which deliberately records
48789
+ * the ARN because Cloud Control's Identifier is the ARN — while
48790
+ * `destroy` / `drift` route on `provisionedBy` ALONE (no properties), and
48791
+ * `cdkd import` records `'sdk'`, so those paths land HERE with an ARN.
48792
+ *
48793
+ * Tolerating both is what makes the route-detection at import time
48794
+ * imprecision-proof: whichever shape is stored, every SDK path works.
48795
+ * `GetTable` accepts `tableArn` and returns the parts.
48796
+ */
48797
+ async resolveTableParts(physicalId) {
48798
+ const composite = parseTableCompositeId(physicalId);
48799
+ if (composite) return composite;
48699
48800
  const parts = physicalId.split("|");
48700
- if (parts.length < 3) return void 0;
48701
- const [tableBucketARN, namespace, name] = parts;
48702
- if (!tableBucketARN || !namespace || !name) return void 0;
48801
+ if (parts.length > 3) {
48802
+ const [tableBucketARN, namespace, name] = parts;
48803
+ if (tableBucketARN && namespace && name) return {
48804
+ tableBucketARN,
48805
+ namespace,
48806
+ name
48807
+ };
48808
+ }
48809
+ if (physicalId.includes("|") || !physicalId.startsWith("arn:")) return "unparseable";
48810
+ try {
48811
+ const resp = await this.getClient().send(new GetTableCommand$1({ tableArn: physicalId }));
48812
+ if (!resp.tableARN) return "unparseable";
48813
+ return tableIdentityFromGetTable(resp.tableARN, resp.namespace, resp.name) ?? "unparseable";
48814
+ } catch (err) {
48815
+ if (err instanceof NotFoundException$6) return "not-found";
48816
+ throw err;
48817
+ }
48818
+ }
48819
+ async readTableCurrentState(physicalId) {
48820
+ let resolved;
48821
+ try {
48822
+ resolved = await this.resolveTableParts(physicalId);
48823
+ } catch (err) {
48824
+ this.logger.warn(`S3 Tables Table ${physicalId}: could not resolve its identity for drift (${err instanceof Error ? err.message : String(err)}); reporting drift as unknown.`);
48825
+ return;
48826
+ }
48827
+ if (resolved === "not-found" || resolved === "unparseable") return void 0;
48828
+ const { tableBucketARN, namespace, name } = resolved;
48703
48829
  let resp;
48704
48830
  try {
48705
48831
  resp = await this.getClient().send(new GetTableCommand$1({
@@ -48768,44 +48894,163 @@ var S3TablesProvider = class {
48768
48894
  } while (token);
48769
48895
  return null;
48770
48896
  }
48897
+ /**
48898
+ * Adopt an existing namespace (issue #1668).
48899
+ *
48900
+ * cdkd's physicalId is `<tableBucketARN>|<namespaceName>` and so is
48901
+ * CloudFormation's — the registry declares a two-field
48902
+ * `primaryIdentifier` (`/properties/TableBucketARN` + `/properties/Namespace`,
48903
+ * verified live us-east-1 2026-08-12) and Cloud Control joins a multi-part
48904
+ * identifier with `|`. So the two agree and no foreign form has to be
48905
+ * accepted; what was missing is that a WRONG-ARITY id was recorded verbatim,
48906
+ * after which every other method on this provider — which all split the
48907
+ * stored id on `|` — failed against a state row that looked adopted.
48908
+ *
48909
+ * A wrong-arity override is REFUSED rather than silently replaced with the
48910
+ * template's identity: `knownPhysicalId` is documented as ground truth
48911
+ * (`ResourceImportInput`), so quietly adopting a different resource than the
48912
+ * one the user named would be worse than declining. An unverifiable
48913
+ * namespace returns `null` (`skipped-not-found`), which is loud and leaves
48914
+ * state clean.
48915
+ *
48916
+ * NOTE this now issues an AWS call where it previously made none, so
48917
+ * `s3tables:GetNamespace` is newly required, and a path that could not fail
48918
+ * before can now report `failed` on a non-`NotFound` error (throttle, IAM).
48919
+ */
48771
48920
  async importNamespace(input) {
48772
- if (input.knownPhysicalId) return {
48773
- physicalId: input.knownPhysicalId,
48921
+ if (!input.knownPhysicalId) return null;
48922
+ const identity = parseNamespaceCompositeId(input.knownPhysicalId);
48923
+ if (!identity) {
48924
+ this.logger.warn(`S3 Tables Namespace ${input.logicalId}: physical id '${input.knownPhysicalId}' is not '<tableBucketARN>|<namespace>'. CloudFormation uses the same two-field composite for this type, so this id names no namespace cdkd can verify; skipping import.`);
48925
+ return null;
48926
+ }
48927
+ try {
48928
+ await this.getClient().send(new GetNamespaceCommand$1({
48929
+ tableBucketARN: identity.tableBucketARN,
48930
+ namespace: identity.namespace
48931
+ }));
48932
+ } catch (err) {
48933
+ if (err instanceof NotFoundException$6) return null;
48934
+ throw err;
48935
+ }
48936
+ return {
48937
+ physicalId: `${identity.tableBucketARN}|${identity.namespace}`,
48774
48938
  attributes: {}
48775
48939
  };
48776
- return null;
48777
48940
  }
48941
+ /**
48942
+ * Adopt an existing table (issue #1668).
48943
+ *
48944
+ * Unlike the namespace above, the two id shapes DISAGREE here: cdkd's
48945
+ * physicalId is `<tableBucketARN>|<namespace>|<name>` while the registry
48946
+ * declares a SINGLE-field `primaryIdentifier` of `/properties/TableARN`
48947
+ * (verified live us-east-1 2026-08-12), so CloudFormation's physicalId is
48948
+ * the table ARN. An auto-mode / `--migrate-from-cloudformation` import
48949
+ * merges CFn-derived ids into the overrides, so that ARN was landing in
48950
+ * state verbatim and every later update / delete / read then failed to parse
48951
+ * it — the #1651 class on a second type.
48952
+ *
48953
+ * **The identity is resolved from AWS, not from the template.** An earlier
48954
+ * draft rebuilt the composite out of `Properties.TableBucketARN` /
48955
+ * `Namespace` / `TableName`, and that is INERT for the case this exists to
48956
+ * fix: in a CDK-synthesized template `TableBucketARN` is
48957
+ * `{"Fn::GetAtt": ["TableBucket", "TableBucketARN"]}`, `import.ts`
48958
+ * pre-substitutes only single-key `{Ref}` before calling a provider, and
48959
+ * full intrinsic resolution runs AFTER every `provider.import()`. So the
48960
+ * template read yielded `undefined` on exactly the
48961
+ * `--migrate-from-cloudformation` path that supplies the bare ARN, turning a
48962
+ * corrupt adoption into a non-adoption instead of canonicalizing it.
48963
+ *
48964
+ * `GetTable` accepts `tableArn` directly and returns `name` + `namespace`,
48965
+ * so the ARN resolves its own identity with no template involvement. The
48966
+ * bucket ARN is the table ARN's prefix (`<bucketArn>/table/<id>`); when the
48967
+ * template DOES carry a literal `TableBucketARN` it is cross-checked, and a
48968
+ * disagreement is refused rather than guessed at.
48969
+ */
48778
48970
  async importTable(input) {
48779
- if (input.knownPhysicalId) {
48780
- const parts = input.knownPhysicalId.split("|");
48781
- if (parts.length >= 3) try {
48782
- await this.getClient().send(new GetTableCommand$1({
48783
- tableBucketARN: parts[0],
48784
- namespace: parts[1],
48785
- name: parts[2]
48786
- }));
48787
- return {
48788
- physicalId: input.knownPhysicalId,
48789
- attributes: {}
48790
- };
48791
- } catch (err) {
48792
- if (err instanceof NotFoundException$6) return null;
48793
- throw err;
48794
- }
48971
+ const known = input.knownPhysicalId;
48972
+ if (!known) return null;
48973
+ const composite = parseTableCompositeId(known);
48974
+ const request = composite ? {
48975
+ tableBucketARN: composite.tableBucketARN,
48976
+ namespace: composite.namespace,
48977
+ name: composite.name
48978
+ } : !known.includes("|") && known.startsWith("arn:") ? { tableArn: known } : void 0;
48979
+ if (!request) {
48980
+ this.logger.warn(`S3 Tables Table ${input.logicalId}: physical id '${known}' is neither cdkd's '<tableBucketARN>|<namespace>|<name>' composite nor a table ARN (CloudFormation's physicalId for this type), so it names no table cdkd can verify; skipping import.`);
48981
+ return null;
48982
+ }
48983
+ let response;
48984
+ try {
48985
+ response = await this.getClient().send(new GetTableCommand$1(request));
48986
+ } catch (err) {
48987
+ if (err instanceof NotFoundException$6) return null;
48988
+ throw err;
48989
+ }
48990
+ const tableARN = response.tableARN;
48991
+ if (!tableARN) {
48992
+ this.logger.warn(`S3 Tables Table ${input.logicalId}: GetTable returned no tableARN for '${known}', so the table's identity cannot be confirmed; skipping import.`);
48993
+ return null;
48994
+ }
48995
+ const identity = composite ?? tableIdentityFromGetTable(tableARN, response.namespace, response.name);
48996
+ if (!identity) {
48997
+ this.logger.warn(`S3 Tables Table ${input.logicalId}: GetTable('${known}') did not return a usable namespace / name / bucket-ARN prefix; skipping import.`);
48998
+ return null;
48999
+ }
49000
+ const mismatch = [
49001
+ [
49002
+ "TableBucketARN",
49003
+ readStringProperty$1(input.properties, "TableBucketARN"),
49004
+ identity.tableBucketARN
49005
+ ],
49006
+ [
49007
+ "Namespace",
49008
+ readStringProperty$1(input.properties, "Namespace"),
49009
+ identity.namespace
49010
+ ],
49011
+ [
49012
+ "TableName",
49013
+ readStringProperty$1(input.properties, "TableName") ?? readStringProperty$1(input.properties, "Name"),
49014
+ identity.name
49015
+ ]
49016
+ ].find(([key, declared, resolved]) => {
49017
+ if (!declared) return false;
49018
+ if (key === "TableBucketARN" && !declared.startsWith("arn:")) return false;
49019
+ return (declared.includes("|") ? declared.split("|").pop() ?? declared : declared) !== resolved;
49020
+ });
49021
+ if (mismatch) {
49022
+ const [key, declared, resolved] = mismatch;
49023
+ this.logger.warn(`S3 Tables Table ${input.logicalId}: the supplied physical id '${known}' resolves to ${key} '${resolved}', but the template declares '${declared}'; refusing to adopt a different table than the one the template describes.`);
49024
+ return null;
49025
+ }
49026
+ if (findSilentDropProperties("AWS::S3Tables::Table", input.properties).length > 0) {
49027
+ this.logger.debug(`S3 Tables Table ${input.logicalId}: template carries a Cloud-Control-routing property, recording the bare TableARN (CC's identifier) rather than cdkd's composite.`);
48795
49028
  return {
48796
- physicalId: input.knownPhysicalId,
48797
- attributes: {}
49029
+ physicalId: tableARN,
49030
+ attributes: { TableARN: tableARN }
48798
49031
  };
48799
49032
  }
48800
- return null;
49033
+ return {
49034
+ physicalId: `${identity.tableBucketARN}|${identity.namespace}|${identity.name}`,
49035
+ attributes: { TableARN: tableARN }
49036
+ };
48801
49037
  }
48802
49038
  async deleteTable(logicalId, physicalId, resourceType, context) {
48803
49039
  this.logger.debug(`Deleting S3 Tables Table ${logicalId}: ${physicalId}`);
48804
- const parts = physicalId.split("|");
48805
- if (parts.length < 3) throw new ProvisioningError(`Invalid physical ID format for S3 Tables Table ${logicalId}: ${physicalId}`, resourceType, logicalId, physicalId);
48806
- const tableBucketARN = parts[0];
48807
- const namespace = parts[1];
48808
- const name = parts[2];
49040
+ let resolved;
49041
+ try {
49042
+ resolved = await this.resolveTableParts(physicalId);
49043
+ } catch (error) {
49044
+ const cause = error instanceof Error ? error : void 0;
49045
+ throw new ProvisioningError(`Failed to resolve S3 Tables Table ${logicalId} (${physicalId}): ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
49046
+ }
49047
+ if (resolved === "not-found") {
49048
+ assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
49049
+ this.logger.debug(`S3 Tables Table ${physicalId} does not exist, skipping deletion`);
49050
+ return;
49051
+ }
49052
+ if (resolved === "unparseable") throw new ProvisioningError(`Invalid physical ID format for S3 Tables Table ${logicalId}: ${physicalId} (expected '<tableBucketARN>|<namespace>|<name>' or a table ARN)`, resourceType, logicalId, physicalId);
49053
+ const { tableBucketARN, namespace, name } = resolved;
48809
49054
  try {
48810
49055
  await this.getClient().send(new DeleteTableCommand$2({
48811
49056
  tableBucketARN,
@@ -48923,10 +49168,10 @@ var S3TablesProvider = class {
48923
49168
  const upserts = {};
48924
49169
  for (const [k, v] of Object.entries(next)) if (prev[k] !== v) upserts[k] = v;
48925
49170
  if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
48926
- const parts = physicalId.split("|");
48927
- if (parts.length < 3) throw new ProvisioningError(`applyTableTagsDiff: cannot derive table ARN from physicalId '${physicalId}' (expected '<bucketArn>|<namespace>|<name>') — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
48928
- const [tableBucketARN, namespace, name] = parts;
48929
- if (!tableBucketARN || !namespace || !name) throw new ProvisioningError(`applyTableTagsDiff: cannot derive table ARN from malformed physicalId '${physicalId}' (empty part after split) — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
49171
+ const resolvedParts = await this.resolveTableParts(physicalId);
49172
+ if (resolvedParts === "not-found") throw new ProvisioningError(`applyTableTagsDiff: table '${physicalId}' no longer exists (state is out of sync) — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
49173
+ if (resolvedParts === "unparseable") throw new ProvisioningError(`applyTableTagsDiff: cannot derive table ARN from physicalId '${physicalId}' (expected '<bucketArn>|<namespace>|<name>' or a table ARN) — refusing to silently drop the tag update`, resourceType, logicalId, physicalId);
49174
+ const { tableBucketARN, namespace, name } = resolvedParts;
48930
49175
  const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
48931
49176
  if (!resourceArn) throw new ProvisioningError(`applyTableTagsDiff: GetTable returned no tableARN for ${physicalId} — table is gone or state is out-of-sync. Refusing to silently drop the tag update (run 'cdkd state orphan ${logicalId}' to clean up if the table was deleted out-of-band).`, resourceType, logicalId, physicalId);
48932
49177
  if (removedKeys.length > 0) try {
@@ -55631,13 +55876,29 @@ const COMPOSITE_ID_SPLITTERS = {
55631
55876
  HttpMethod: parts[2]
55632
55877
  } };
55633
55878
  },
55634
- "AWS::ApiGateway::Resource": (id) => {
55635
- const parts = id.split("|");
55636
- if (parts.length !== 2) throw new Error(`expected 2 parts (restApiId|resourceId), got ${parts.length}: '${id}'`);
55637
- return { resourceIdentifier: {
55638
- RestApiId: parts[0],
55639
- ResourceId: parts[1]
55640
- } };
55879
+ "AWS::ApiGateway::Resource": (physicalId, properties) => {
55880
+ if (!physicalId.trim()) throw new Error("empty physical id for AWS::ApiGateway::Resource (expected a resourceId)");
55881
+ const parts = physicalId.split("|");
55882
+ if (parts.length > 2) throw new Error(`expected a bare resourceId or 'restApiId|resourceId', got ${parts.length} parts: '${physicalId}'`);
55883
+ if (parts.length === 2) {
55884
+ const [restApiId, resourceId] = parts;
55885
+ if (!restApiId || !resourceId) throw new Error(`empty part in 'restApiId|resourceId': '${physicalId}'`);
55886
+ return {
55887
+ resourceIdentifier: {
55888
+ RestApiId: restApiId,
55889
+ ResourceId: resourceId
55890
+ },
55891
+ propertiesOverlay: { RestApiId: restApiId }
55892
+ };
55893
+ }
55894
+ const restApiId = readStringProperty(properties, "RestApiId", "AWS::ApiGateway::Resource");
55895
+ return {
55896
+ resourceIdentifier: {
55897
+ RestApiId: restApiId,
55898
+ ResourceId: physicalId
55899
+ },
55900
+ propertiesOverlay: { RestApiId: restApiId }
55901
+ };
55641
55902
  },
55642
55903
  "AWS::EC2::VPCGatewayAttachment": (id) => {
55643
55904
  const parts = id.split("|");
@@ -71670,7 +71931,7 @@ function createMigrateCommand() {
71670
71931
  */
71671
71932
  function buildProgram() {
71672
71933
  const program = new Command();
71673
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.40");
71934
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.42");
71674
71935
  program.hook("preAction", (_thisCommand, actionCommand) => {
71675
71936
  const { profile } = actionCommand.optsWithGlobals();
71676
71937
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;