@go-to-k/cdkd 0.281.15 → 0.281.16

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 replayWarn, $t as findLargeInlineResources, A as green, At as buildDockerImage, B as slowCcOperationTimeoutMs, Bt as getLegacyStateBucketName, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as ResourceTimeoutError, Ct as AssetModeResolver, D as bold, Dt as parseBootstrapMarker, E as formatResourceLine, En as StackTerminationProtectionError, Et as getBootstrapMarkerKey, F as clearOnUpdateRemoval, Ft as AssetManifestLoader, G as getAccountInfo, Gt as resolveStateBucketWithDefault, H as isTerminationProtectionPropagationError, Ht as resolveAutoAssetStorage, I as ProviderRegistry, It as getDockerImageBySourceHash, J as normalizeAwsTagsToCfn, Jt as stateBucketExistenceConfirmed, K as refStateLookupFromResource, Kt as resolveStateBucketWithDefaultAndSource, L as findActionableSilentDrops, Lt as Synthesizer, M as yellow, Mn as withErrorHandling, Mt as getDockerCmd, N as IAMRoleProvider, Nt as runDockerForeground, O as cyan, Ot as validateAssetBucketName, P as collectInlinePolicyNamesManagedBySiblings, Pt as runDockerStreaming, Q as readConfigString, Qt as MIGRATE_TMP_PREFIX, R as findSilentDropProperties, Rt as synthesisStatusMessage, S as extractDeploymentEventError, Sn as ProvisioningError, St as rewriteTemplateAssetReferences, T as renderStatefulReason, Tn as StackHasActiveImportsError, Tt as ensureAssetStorage, U as IntrinsicFunctionResolver, Ut as resolveCaptureObservedState, V as disableInstanceApiTermination, Vt as resolveApp, W as cfnRefValueFromPhysicalId, Wt as resolveSkipPrefix, X as assertRegionMatch, Xt as CFN_TEMPLATE_BODY_LIMIT, Y as resolveExplicitPhysicalId, Yt as warnDeprecatedNoPrefixCliFlag, Z as configStringRefusal, Zt as CFN_TEMPLATE_URL_LIMIT, _ as createPreDeleteFinalSnapshot, _n as LocalStartServiceError, _t as stringifyValue, a as DeploymentEventsStore, an as resolveBucketRegion, at as DiffCalculator, b as unsupportedFinalSnapshotError, bn as NestedStackChildDirectDestroyError, bt as createAssetRedirectResolver, c as replayFailedOperations, cn as resetAwsClients, ct as isRetryableTransientError, d as IMPLICIT_DELETE_DEPENDENCIES, dn as CdkdError, dt as TemplateParser, en as uploadCfnTemplate, et as requireConfigArray, f as computeImplicitDeleteEdges, ft as LockManager, g as ccRoutedFinalSnapshotError, gn as LocalMigrateError, gt as AssetPublisher, h as buildFinalSnapshotIdentifier, hn as LocalInvokeBuildError$1, ht as shouldRetainResource, i as DeploymentEventsReader, it as applyRoleArnIfSet, j as red, jn as normalizeAwsError, jt as formatDockerLoginError, k as gray, kt as validateContainerRepoName, l as replayRollback, ln as setAwsClients, lt as isThrottlingError, m as PRE_DELETE_SNAPSHOT_TYPES, mn as DeployCancelledError, mt as rebuildClientForBucketRegion, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AssemblyReader, nt as requireConfigString, o as planFailedOps, on as AwsClients, ot as describeTypeWithThrottleRetry, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pt as S3StateBackend, q as WAFv2WebACLProvider, qt as resolveUseCdkBootstrapAssets, r as DeployEngine, rn as processStackMessages, rt as derivePartitionAndUrlSuffix, s as planRollback, sn as getAwsClients, st as withRetry, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as expectedOwnerParam, tt as requireConfigObject, u as withResourceDeadline, ut as DagBuilder, v as isFinalSnapshotError, vt as WorkGraph, w as isStatefulRecreateTargetSync, wn as ResourceUpdateNotSupportedError, wt as BOOTSTRAP_MARKER_PREFIX, x as makeCanonicalizePropertiesFn, xn as PartialFailureError, xt as loadPublishableAssetManifest, y as refusesFinalSnapshot, yn as MissingCdkCliError, yt as buildAssetRedirectMap, z as CloudControlProvider, zt as getDefaultStateBucketName } from "./deploy-engine-B2MDP-jK.js";
2
+ import { $ as replayWarn, $t as findLargeInlineResources, A as green, At as buildDockerImage, B as slowCcOperationTimeoutMs, Bt as getLegacyStateBucketName, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as ResourceTimeoutError, Ct as AssetModeResolver, D as bold, Dt as parseBootstrapMarker, E as formatResourceLine, En as StackTerminationProtectionError, Et as getBootstrapMarkerKey, F as clearOnUpdateRemoval, Ft as AssetManifestLoader, G as getAccountInfo, Gt as resolveStateBucketWithDefault, H as isTerminationProtectionPropagationError, Ht as resolveAutoAssetStorage, I as ProviderRegistry, It as getDockerImageBySourceHash, J as normalizeAwsTagsToCfn, Jt as stateBucketExistenceConfirmed, K as refStateLookupFromResource, Kt as resolveStateBucketWithDefaultAndSource, L as findActionableSilentDrops, Lt as Synthesizer, M as yellow, Mn as withErrorHandling, Mt as getDockerCmd, N as IAMRoleProvider, Nt as runDockerForeground, O as cyan, Ot as validateAssetBucketName, P as collectInlinePolicyNamesManagedBySiblings, Pt as runDockerStreaming, Q as readConfigString, Qt as MIGRATE_TMP_PREFIX, R as findSilentDropProperties, Rt as synthesisStatusMessage, S as extractDeploymentEventError, Sn as ProvisioningError, St as rewriteTemplateAssetReferences, T as renderStatefulReason, Tn as StackHasActiveImportsError, Tt as ensureAssetStorage, U as IntrinsicFunctionResolver, Ut as resolveCaptureObservedState, V as disableInstanceApiTermination, Vt as resolveApp, W as cfnRefValueFromPhysicalId, Wt as resolveSkipPrefix, X as assertRegionMatch, Xt as CFN_TEMPLATE_BODY_LIMIT, Y as resolveExplicitPhysicalId, Yt as warnDeprecatedNoPrefixCliFlag, Z as configStringRefusal, Zt as CFN_TEMPLATE_URL_LIMIT, _ as createPreDeleteFinalSnapshot, _n as LocalStartServiceError, _t as stringifyValue, a as DeploymentEventsStore, an as resolveBucketRegion, at as DiffCalculator, b as unsupportedFinalSnapshotError, bn as NestedStackChildDirectDestroyError, bt as createAssetRedirectResolver, c as replayFailedOperations, cn as resetAwsClients, ct as isRetryableTransientError, d as IMPLICIT_DELETE_DEPENDENCIES, dn as CdkdError, dt as TemplateParser, en as uploadCfnTemplate, et as requireConfigArray, f as computeImplicitDeleteEdges, ft as LockManager, g as ccRoutedFinalSnapshotError, gn as LocalMigrateError, gt as AssetPublisher, h as buildFinalSnapshotIdentifier, hn as LocalInvokeBuildError$1, ht as shouldRetainResource, i as DeploymentEventsReader, it as applyRoleArnIfSet, j as red, jn as normalizeAwsError, jt as formatDockerLoginError, k as gray, kt as validateContainerRepoName, l as replayRollback, ln as setAwsClients, lt as isThrottlingError, m as PRE_DELETE_SNAPSHOT_TYPES, mn as DeployCancelledError, mt as rebuildClientForBucketRegion, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AssemblyReader, nt as requireConfigString, o as planFailedOps, on as AwsClients, ot as describeTypeWithThrottleRetry, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pt as S3StateBackend, q as WAFv2WebACLProvider, qt as resolveUseCdkBootstrapAssets, r as DeployEngine, rn as processStackMessages, rt as derivePartitionAndUrlSuffix, s as planRollback, sn as getAwsClients, st as withRetry, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as expectedOwnerParam, tt as requireConfigObject, u as withResourceDeadline, ut as DagBuilder, v as isFinalSnapshotError, vt as WorkGraph, w as isStatefulRecreateTargetSync, wn as ResourceUpdateNotSupportedError, wt as BOOTSTRAP_MARKER_PREFIX, x as makeCanonicalizePropertiesFn, xn as PartialFailureError, xt as loadPublishableAssetManifest, y as refusesFinalSnapshot, yn as MissingCdkCliError, yt as buildAssetRedirectMap, z as CloudControlProvider, zt as getDefaultStateBucketName } from "./deploy-engine-CfnMSwyx.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-CgQFJdPo.js";
4
+ import { t as ASGProvider } from "./asg-provider-B1pHGT_X.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";
@@ -12194,6 +12194,43 @@ function packCompositeId(resourceType, logicalId, segments, options) {
12194
12194
  else throw new ProvisioningError(refusal, resourceType, logicalId);
12195
12195
  return segments.map((segment) => String(segment.value)).join("|");
12196
12196
  }
12197
+ /** Render the expected id shape, e.g. `<databaseName>|<tableName>`. */
12198
+ function formatShape(segments) {
12199
+ return segments.map((segment) => `<${segment}>`).join("|");
12200
+ }
12201
+ /**
12202
+ * The message EVERY malformed-composite-id decode site emits (issue
12203
+ * [#1657](https://github.com/go-to-k/cdkd/issues/1657)).
12204
+ *
12205
+ * ## Why one builder
12206
+ *
12207
+ * Roughly half the decode sites stated the expected shape and half only echoed
12208
+ * the value back, and the format is documented nowhere else — so on the silent
12209
+ * half the message was the user's only possible route to the answer and it did
12210
+ * not carry it. Routing the sites that already got it right through the same
12211
+ * builder is what stops them drifting back.
12212
+ *
12213
+ * ## This is a WORDING fix, not an acceptance change
12214
+ *
12215
+ * Each caller keeps its own split-and-guard exactly as it was. The arities
12216
+ * genuinely differ (some sites accept AT LEAST N segments, some destructure the
12217
+ * first N and tolerate extras — the #1672 ambiguity, tracked separately), and
12218
+ * folding them into one predicate here would silently change which ids deploy.
12219
+ *
12220
+ * ## The `skipping` variant
12221
+ *
12222
+ * On the DELETE path the established policy is warn-and-continue, so a
12223
+ * malformed record leaves the AWS resource ALIVE while `cdkd destroy` reports
12224
+ * success. That policy is not changed here — but the warning now says what the
12225
+ * skip costs, because an orphan the user is never told about is one they cannot
12226
+ * go and delete.
12227
+ */
12228
+ function compositeIdFormatMessage(format, logicalId, physicalId, options) {
12229
+ const accepted = format.alsoAccepts ? `"${formatShape(format.segments)}" or ${format.alsoAccepts}` : `"${formatShape(format.segments)}"`;
12230
+ const head = `Invalid physicalId format for ${format.label} ${logicalId}: expected ${accepted}, got "${physicalId}"`;
12231
+ if (!options?.skipping) return head;
12232
+ return `${head}. Skipping the delete — the AWS resource is LEFT IN PLACE and cdkd will report this delete as successful, so delete it by hand (or repair the id in state.json and re-run) if it still exists. NOTE this arm is reached from cdkd destroy AND from the deploy engine's replacement / rollback deletes.`;
12233
+ }
12197
12234
 
12198
12235
  //#endregion
12199
12236
  //#region src/provisioning/providers/lambda-event-invoke-config-provider.ts
@@ -19200,6 +19237,32 @@ function canonicalizeIpProtocolValue(value) {
19200
19237
 
19201
19238
  //#endregion
19202
19239
  //#region src/provisioning/providers/ec2-provider.ts
19240
+ /** Shapes of the four `AWS::EC2::*` composite physicalIds (issue #1657). */
19241
+ const EC2_VPC_GATEWAY_ATTACHMENT_ID_FORMAT = {
19242
+ label: "VPCGatewayAttachment",
19243
+ segments: ["internetGatewayId", "vpcId"]
19244
+ };
19245
+ const EC2_ROUTE_ID_FORMAT = {
19246
+ label: "Route",
19247
+ segments: ["routeTableId", "destination"]
19248
+ };
19249
+ const EC2_SG_INGRESS_ID_FORMAT = {
19250
+ label: "SecurityGroupIngress",
19251
+ segments: [
19252
+ "groupId",
19253
+ "ipProtocol",
19254
+ "fromPort",
19255
+ "toPort"
19256
+ ]
19257
+ };
19258
+ const EC2_NETWORK_ACL_ENTRY_ID_FORMAT = {
19259
+ label: "NetworkAclEntry",
19260
+ segments: [
19261
+ "networkAclId",
19262
+ "ruleNumber",
19263
+ "egress"
19264
+ ]
19265
+ };
19203
19266
  /**
19204
19267
  * The `AWS::EC2::Route` destination keys, in CloudFormation's own precedence
19205
19268
  * order — which is also the order `createRoute`'s
@@ -20092,7 +20155,7 @@ var EC2Provider = class {
20092
20155
  async deleteVpcGatewayAttachment(logicalId, physicalId, resourceType, context) {
20093
20156
  this.logger.debug(`Deleting VPCGatewayAttachment ${logicalId}: ${physicalId}`);
20094
20157
  const parts = physicalId.split("|");
20095
- if (parts.length !== 2) throw new ProvisioningError(`Invalid physicalId format for VPCGatewayAttachment ${logicalId}: expected "IGW|VpcId", got "${physicalId}"`, resourceType, logicalId, physicalId);
20158
+ if (parts.length !== 2) throw new ProvisioningError(compositeIdFormatMessage(EC2_VPC_GATEWAY_ATTACHMENT_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
20096
20159
  const [internetGatewayId, vpcId] = parts;
20097
20160
  try {
20098
20161
  await this.withDependencyViolationRetry(() => this.ec2Client.send(new DetachInternetGatewayCommand({
@@ -20285,7 +20348,7 @@ var EC2Provider = class {
20285
20348
  async deleteRoute(logicalId, physicalId, resourceType, context) {
20286
20349
  this.logger.debug(`Deleting Route ${logicalId}: ${physicalId}`);
20287
20350
  const parts = physicalId.split("|");
20288
- if (parts.length !== 2) throw new ProvisioningError(`Invalid physicalId format for Route ${logicalId}: expected "RouteTableId|Destination", got "${physicalId}"`, resourceType, logicalId, physicalId);
20351
+ if (parts.length !== 2) throw new ProvisioningError(compositeIdFormatMessage(EC2_ROUTE_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
20289
20352
  const [routeTableId, destination] = parts;
20290
20353
  try {
20291
20354
  const destinationParam = destination?.includes(":") ? { DestinationIpv6CidrBlock: destination } : destination?.startsWith("pl-") ? { DestinationPrefixListId: destination } : { DestinationCidrBlock: destination };
@@ -20629,7 +20692,7 @@ var EC2Provider = class {
20629
20692
  async deleteSecurityGroupIngress(logicalId, physicalId, resourceType, properties, context) {
20630
20693
  this.logger.debug(`Deleting SecurityGroupIngress ${logicalId}: ${physicalId}`);
20631
20694
  const parts = physicalId.split("|");
20632
- if (parts.length !== 4) throw new ProvisioningError(`Invalid physicalId format for SecurityGroupIngress ${logicalId}: expected "GroupId|Protocol|FromPort|ToPort", got "${physicalId}"`, resourceType, logicalId, physicalId);
20695
+ if (parts.length !== 4) throw new ProvisioningError(compositeIdFormatMessage(EC2_SG_INGRESS_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
20633
20696
  const [groupId, ipProtocol, fromPortStr, toPortStr] = parts;
20634
20697
  const ipPermission = properties ? this.buildIpPermission(properties) : {
20635
20698
  IpProtocol: ipProtocol,
@@ -21319,7 +21382,7 @@ var EC2Provider = class {
21319
21382
  this.logger.debug(`Deleting NetworkAclEntry ${logicalId}: ${physicalId}`);
21320
21383
  const parts = physicalId.split("|");
21321
21384
  if (parts.length < 3) {
21322
- this.logger.warn(`Invalid NetworkAclEntry physical ID format: ${physicalId}, skipping`);
21385
+ this.logger.warn(compositeIdFormatMessage(EC2_NETWORK_ACL_ENTRY_ID_FORMAT, logicalId, physicalId, { skipping: true }));
21323
21386
  return;
21324
21387
  }
21325
21388
  const networkAclId = parts[0];
@@ -21629,7 +21692,7 @@ var EC2Provider = class {
21629
21692
  * Skipped (return `undefined`, falls through to the comparator's
21630
21693
  * "unsupported" outcome):
21631
21694
  * - **AWS::EC2::VPCGatewayAttachment**: physical id is
21632
- * `IGW|VpcId`. The two ids are immutable inputs to the SDK call;
21695
+ * `<internetGatewayId>|<vpcId>`. The two ids are immutable inputs to the SDK call;
21633
21696
  * drift detection on this resource has no useful signal beyond
21634
21697
  * existence verification (which the user can do via the parent IGW
21635
21698
  * / VPC drift report).
@@ -22321,6 +22384,15 @@ function isDefaultEgressRule(rule) {
22321
22384
 
22322
22385
  //#endregion
22323
22386
  //#region src/provisioning/providers/apigateway-provider.ts
22387
+ /** Shape of an `AWS::ApiGateway::Method` physicalId (issue #1657). */
22388
+ const APIGW_METHOD_ID_FORMAT = {
22389
+ label: "API Gateway Method",
22390
+ segments: [
22391
+ "restApiId",
22392
+ "resourceId",
22393
+ "httpMethod"
22394
+ ]
22395
+ };
22324
22396
  /**
22325
22397
  * AWS API Gateway Provider
22326
22398
  *
@@ -23306,7 +23378,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
23306
23378
  async updateMethod(logicalId, physicalId, resourceType, properties, previousProperties) {
23307
23379
  this.logger.debug(`Updating API Gateway Method ${logicalId}: ${physicalId}`);
23308
23380
  const parts = physicalId.split("|");
23309
- if (parts.length !== 3) throw new ProvisioningError(`Invalid physicalId format for API Gateway Method ${logicalId}: expected "restApiId|resourceId|httpMethod", got "${physicalId}"`, resourceType, logicalId, physicalId);
23381
+ if (parts.length !== 3) throw new ProvisioningError(compositeIdFormatMessage(APIGW_METHOD_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
23310
23382
  const [restApiId, resourceId, httpMethod] = parts;
23311
23383
  const patchOperations = [];
23312
23384
  for (const { key, path } of [
@@ -23380,7 +23452,7 @@ var ApiGatewayProvider = class ApiGatewayProvider {
23380
23452
  async deleteMethod(logicalId, physicalId, resourceType, context) {
23381
23453
  this.logger.debug(`Deleting API Gateway Method ${logicalId}: ${physicalId}`);
23382
23454
  const parts = physicalId.split("|");
23383
- if (parts.length !== 3) throw new ProvisioningError(`Invalid physicalId format for API Gateway Method ${logicalId}: expected "restApiId|resourceId|httpMethod", got "${physicalId}"`, resourceType, logicalId, physicalId);
23455
+ if (parts.length !== 3) throw new ProvisioningError(compositeIdFormatMessage(APIGW_METHOD_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
23384
23456
  const [restApiId, resourceId, httpMethod] = parts;
23385
23457
  try {
23386
23458
  await this.apiGatewayClient.send(new DeleteMethodCommand({
@@ -37181,6 +37253,23 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
37181
37253
 
37182
37254
  //#endregion
37183
37255
  //#region src/provisioning/providers/appsync-provider.ts
37256
+ /** Shapes of the three `AWS::AppSync::*` child composite physicalIds (issue #1657). */
37257
+ const APPSYNC_DATASOURCE_ID_FORMAT = {
37258
+ label: "AppSync DataSource",
37259
+ segments: ["apiId", "name"]
37260
+ };
37261
+ const APPSYNC_RESOLVER_ID_FORMAT = {
37262
+ label: "AppSync Resolver",
37263
+ segments: [
37264
+ "apiId",
37265
+ "typeName",
37266
+ "fieldName"
37267
+ ]
37268
+ };
37269
+ const APPSYNC_APIKEY_ID_FORMAT = {
37270
+ label: "AppSync ApiKey",
37271
+ segments: ["apiId", "apiKeyId"]
37272
+ };
37184
37273
  const MUTABLE_GRAPHQL_API_CONFIG_PROPERTIES = [
37185
37274
  "UserPoolConfig",
37186
37275
  "OpenIDConnectConfig",
@@ -37651,7 +37740,7 @@ var AppSyncProvider = class {
37651
37740
  if (next !== void 0 && prev !== void 0 && next !== prev) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, `AWS AppSync DataSource.${field} is immutable — destroy + redeploy to change`);
37652
37741
  }
37653
37742
  const [apiId, name] = physicalId.split("|");
37654
- if (!apiId || !name) throw new ProvisioningError(`Invalid DataSource physical ID format: ${physicalId}`, resourceType, logicalId, physicalId);
37743
+ if (!apiId || !name) throw new ProvisioningError(compositeIdFormatMessage(APPSYNC_DATASOURCE_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
37655
37744
  const type = properties["Type"] ?? previousProperties["Type"];
37656
37745
  if (![
37657
37746
  "Description",
@@ -37689,7 +37778,7 @@ var AppSyncProvider = class {
37689
37778
  if (next !== void 0 && prev !== void 0 && next !== prev) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, `AWS AppSync Resolver.${field} is immutable — destroy + redeploy to change`);
37690
37779
  }
37691
37780
  const parts = physicalId.split("|");
37692
- if (parts.length < 3) throw new ProvisioningError(`Invalid Resolver physical ID format: ${physicalId}`, resourceType, logicalId, physicalId);
37781
+ if (parts.length < 3) throw new ProvisioningError(compositeIdFormatMessage(APPSYNC_RESOLVER_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
37693
37782
  const [apiId, typeName, fieldName] = parts;
37694
37783
  if (![
37695
37784
  "DataSourceName",
@@ -37723,7 +37812,7 @@ var AppSyncProvider = class {
37723
37812
  async updateApiKey(logicalId, physicalId, resourceType, properties, previousProperties) {
37724
37813
  if (properties["ApiId"] !== void 0 && previousProperties["ApiId"] !== void 0 && properties["ApiId"] !== previousProperties["ApiId"]) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "AWS AppSync ApiKey.ApiId is immutable — destroy + redeploy to change");
37725
37814
  const [apiId, apiKeyId] = physicalId.split("|");
37726
- if (!apiId || !apiKeyId) throw new ProvisioningError(`Invalid ApiKey physical ID format: ${physicalId}`, resourceType, logicalId, physicalId);
37815
+ if (!apiId || !apiKeyId) throw new ProvisioningError(compositeIdFormatMessage(APPSYNC_APIKEY_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
37727
37816
  const newDesc = properties["Description"];
37728
37817
  const oldDesc = previousProperties["Description"];
37729
37818
  const newExp = properties["Expires"];
@@ -38429,7 +38518,7 @@ var AppSyncProvider = class {
38429
38518
  this.logger.debug(`Deleting DataSource ${logicalId}: ${physicalId}`);
38430
38519
  const [apiId, name] = physicalId.split("|");
38431
38520
  if (!apiId || !name) {
38432
- this.logger.warn(`Invalid DataSource physical ID format: ${physicalId}, skipping`);
38521
+ this.logger.warn(compositeIdFormatMessage(APPSYNC_DATASOURCE_ID_FORMAT, logicalId, physicalId, { skipping: true }));
38433
38522
  return;
38434
38523
  }
38435
38524
  try {
@@ -38492,7 +38581,7 @@ var AppSyncProvider = class {
38492
38581
  this.logger.debug(`Deleting Resolver ${logicalId}: ${physicalId}`);
38493
38582
  const parts = physicalId.split("|");
38494
38583
  if (parts.length < 3) {
38495
- this.logger.warn(`Invalid Resolver physical ID format: ${physicalId}, skipping`);
38584
+ this.logger.warn(compositeIdFormatMessage(APPSYNC_RESOLVER_ID_FORMAT, logicalId, physicalId, { skipping: true }));
38496
38585
  return;
38497
38586
  }
38498
38587
  const [apiId, typeName, fieldName] = parts;
@@ -38548,7 +38637,7 @@ var AppSyncProvider = class {
38548
38637
  this.logger.debug(`Deleting ApiKey ${logicalId}: ${physicalId}`);
38549
38638
  const [apiId, apiKeyId] = physicalId.split("|");
38550
38639
  if (!apiId || !apiKeyId) {
38551
- this.logger.warn(`Invalid ApiKey physical ID format: ${physicalId}, skipping`);
38640
+ this.logger.warn(compositeIdFormatMessage(APPSYNC_APIKEY_ID_FORMAT, logicalId, physicalId, { skipping: true }));
38552
38641
  return;
38553
38642
  }
38554
38643
  try {
@@ -38935,6 +39024,11 @@ var AppSyncProvider = class {
38935
39024
 
38936
39025
  //#endregion
38937
39026
  //#region src/provisioning/providers/glue-provider.ts
39027
+ /** Shape of an `AWS::Glue::Table` physicalId, for every decode site (issue #1657). */
39028
+ const GLUE_TABLE_ID_FORMAT = {
39029
+ label: "Glue Table",
39030
+ segments: ["databaseName", "tableName"]
39031
+ };
38938
39032
  /**
38939
39033
  * Read a template-borne value that is about to be forwarded to a Glue read
38940
39034
  * API as a string.
@@ -39232,7 +39326,7 @@ var GlueProvider = class {
39232
39326
  async updateTable(logicalId, physicalId, resourceType, properties, previousProperties) {
39233
39327
  this.logger.debug(`Updating Glue Table ${logicalId}: ${physicalId}`);
39234
39328
  const [databaseName, tableName] = physicalId.split("|");
39235
- if (!databaseName || !tableName) throw new ProvisioningError(`Invalid Glue Table physical ID format: ${physicalId}`, resourceType, logicalId, physicalId);
39329
+ if (!databaseName || !tableName) throw new ProvisioningError(compositeIdFormatMessage(GLUE_TABLE_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
39236
39330
  const tableInput = properties["TableInput"];
39237
39331
  if (!tableInput) throw new ProvisioningError(`TableInput is required for Glue Table update ${logicalId}`, resourceType, logicalId, physicalId);
39238
39332
  const catalogId = properties["CatalogId"];
@@ -39269,7 +39363,7 @@ var GlueProvider = class {
39269
39363
  this.logger.debug(`Deleting Glue Table ${logicalId}: ${physicalId}`);
39270
39364
  const [databaseName, tableName] = physicalId.split("|");
39271
39365
  if (!databaseName || !tableName) {
39272
- this.logger.warn(`Invalid Glue Table physical ID format: ${physicalId}, skipping`);
39366
+ this.logger.warn(compositeIdFormatMessage(GLUE_TABLE_ID_FORMAT, logicalId, physicalId, { skipping: true }));
39273
39367
  return;
39274
39368
  }
39275
39369
  const target = deleteCatalogId(properties);
@@ -50232,6 +50326,20 @@ var S3DirectoryBucketProvider = class {
50232
50326
 
50233
50327
  //#endregion
50234
50328
  //#region src/provisioning/providers/s3-tables-provider.ts
50329
+ /** Shapes of the two `AWS::S3Tables::*` composite physicalIds (issue #1657). */
50330
+ const S3_TABLES_NAMESPACE_ID_FORMAT = {
50331
+ label: "S3 Tables Namespace",
50332
+ segments: ["tableBucketARN", "namespace"]
50333
+ };
50334
+ const S3_TABLES_TABLE_ID_FORMAT = {
50335
+ label: "S3 Tables Table",
50336
+ segments: [
50337
+ "tableBucketARN",
50338
+ "namespace",
50339
+ "name"
50340
+ ],
50341
+ alsoAccepts: "a table ARN"
50342
+ };
50235
50343
  /**
50236
50344
  * Parse cdkd's composite namespace physicalId `<tableBucketARN>|<namespace>`.
50237
50345
  *
@@ -50478,7 +50586,7 @@ var S3TablesProvider = class {
50478
50586
  async deleteNamespace(logicalId, physicalId, resourceType, context) {
50479
50587
  this.logger.debug(`Deleting S3 Tables Namespace ${logicalId}: ${physicalId}`);
50480
50588
  const [tableBucketARN, namespaceName] = physicalId.split("|");
50481
- if (!tableBucketARN || !namespaceName) throw new ProvisioningError(`Invalid physical ID format for S3 Tables Namespace ${logicalId}: ${physicalId}`, resourceType, logicalId, physicalId);
50589
+ if (!tableBucketARN || !namespaceName) throw new ProvisioningError(compositeIdFormatMessage(S3_TABLES_NAMESPACE_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
50482
50590
  try {
50483
50591
  await this.getClient().send(new DeleteNamespaceCommand$1({
50484
50592
  tableBucketARN,
@@ -50892,7 +51000,7 @@ var S3TablesProvider = class {
50892
51000
  this.logger.debug(`S3 Tables Table ${physicalId} does not exist, skipping deletion`);
50893
51001
  return;
50894
51002
  }
50895
- 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);
51003
+ if (resolved === "unparseable") throw new ProvisioningError(compositeIdFormatMessage(S3_TABLES_TABLE_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
50896
51004
  const { tableBucketARN, namespace, name } = resolved;
50897
51005
  try {
50898
51006
  await this.getClient().send(new DeleteTableCommand$2({
@@ -51013,7 +51121,7 @@ var S3TablesProvider = class {
51013
51121
  if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
51014
51122
  const resolvedParts = await this.resolveTableParts(physicalId);
51015
51123
  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);
51016
- 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);
51124
+ if (resolvedParts === "unparseable") throw new ProvisioningError(`applyTableTagsDiff: ${compositeIdFormatMessage(S3_TABLES_TABLE_ID_FORMAT, logicalId, physicalId)}. Cannot derive the table ARN for the tag update, and refusing to silently drop it.`, resourceType, logicalId, physicalId);
51017
51125
  const { tableBucketARN, namespace, name } = resolvedParts;
51018
51126
  const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
51019
51127
  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);
@@ -73857,7 +73965,7 @@ function createMigrateCommand() {
73857
73965
  */
73858
73966
  function buildProgram() {
73859
73967
  const program = new Command();
73860
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.15");
73968
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.16");
73861
73969
  program.hook("preAction", (_thisCommand, actionCommand) => {
73862
73970
  const { profile } = actionCommand.optsWithGlobals();
73863
73971
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;