@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/{asg-provider-BOGjxxxb.js → asg-provider-a9iV8VG_.js} +2 -2
- package/dist/{asg-provider-BOGjxxxb.js.map → asg-provider-a9iV8VG_.js.map} +1 -1
- package/dist/cli.js +312 -51
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-CU47_nau.js → deploy-engine-CuwZzHlM.js} +4 -4
- package/dist/{deploy-engine-CU47_nau.js.map → deploy-engine-CuwZzHlM.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as
|
|
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-
|
|
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
|
|
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)
|
|
22731
|
-
|
|
22732
|
-
|
|
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
|
-
|
|
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
|
|
48701
|
-
|
|
48702
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48780
|
-
|
|
48781
|
-
|
|
48782
|
-
|
|
48783
|
-
|
|
48784
|
-
|
|
48785
|
-
|
|
48786
|
-
|
|
48787
|
-
|
|
48788
|
-
|
|
48789
|
-
|
|
48790
|
-
|
|
48791
|
-
|
|
48792
|
-
|
|
48793
|
-
|
|
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:
|
|
48797
|
-
attributes: {}
|
|
49029
|
+
physicalId: tableARN,
|
|
49030
|
+
attributes: { TableARN: tableARN }
|
|
48798
49031
|
};
|
|
48799
49032
|
}
|
|
48800
|
-
return
|
|
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
|
-
|
|
48805
|
-
|
|
48806
|
-
|
|
48807
|
-
|
|
48808
|
-
|
|
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
|
|
48927
|
-
if (
|
|
48928
|
-
|
|
48929
|
-
|
|
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": (
|
|
55635
|
-
|
|
55636
|
-
|
|
55637
|
-
|
|
55638
|
-
|
|
55639
|
-
|
|
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.
|
|
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;
|