@go-to-k/cdkd 0.281.3 → 0.281.4

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 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-DFZo1Twc.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-Di4-1RJP.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-CBIIk31p.js";
4
+ import { t as ASGProvider } from "./asg-provider-B1QR4dCd.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";
@@ -11597,6 +11597,123 @@ var LambdaLayerVersionProvider = class {
11597
11597
  }
11598
11598
  };
11599
11599
 
11600
+ //#endregion
11601
+ //#region src/provisioning/composite-id.ts
11602
+ /**
11603
+ * Refuse a composite physicalId whose segments would make it ambiguous
11604
+ * (issue [#1672](https://github.com/go-to-k/cdkd/issues/1672)).
11605
+ *
11606
+ * ## Why a composite id exists at all
11607
+ *
11608
+ * `ResourceProvider` passes a SINGLE `physicalId: string` as a resource's
11609
+ * identity, while CloudFormation keeps the physical id and its containing
11610
+ * scope as separate values. So every provider whose type needs more than one
11611
+ * value to address the resource PACKS them into one string joined by
11612
+ * {@link COMPOSITE_ID_SEPARATOR} — `<databaseName>|<tableName>` for
11613
+ * `AWS::Glue::Table`, `<apiId>|<typeName>|<fieldName>` for
11614
+ * `AWS::AppSync::Resolver`, and so on.
11615
+ *
11616
+ * ## Why it has to be guarded
11617
+ *
11618
+ * The separator is NOT escaped, so a segment that itself contains a `|`
11619
+ * produces an id with the wrong arity. Every decode site splits the stored id
11620
+ * back apart and the extra segment shifts everything — for a Glue table named
11621
+ * `a|b` in database `mydb` the recorded id `mydb|a|b` decodes to database
11622
+ * `mydb`, table `a`. Both halves are non-empty, so every existing
11623
+ * "is this id well-formed?" guard passes and the deploy SUCCEEDS. What breaks
11624
+ * is everything afterwards: `cdkd destroy` deletes the WRONG resource if one
11625
+ * exists under the decoded pair (or warn-and-skips, reporting success while
11626
+ * the real resource stays alive and billing), and `cdkd drift` reads back
11627
+ * `undefined` forever.
11628
+ *
11629
+ * AWS itself accepts such a name — verified live us-east-1 2026-08-12,
11630
+ * `glue:CreateTable` with `TableInput.Name: 'a|b'` succeeds — and
11631
+ * CloudFormation manages the resource fine. The limitation is cdkd's own, so
11632
+ * the honest answer is to REFUSE at deploy time with a message that says so,
11633
+ * rather than to record an id that silently names something else. Escaping the
11634
+ * separator, or dropping the packing where the decode sites already receive
11635
+ * the properties bag, are the two real fixes and both remain open on #1672;
11636
+ * this guard is what closes the data-loss path in the meantime.
11637
+ *
11638
+ * ## Two entry points, mirroring `config-shape.ts`
11639
+ *
11640
+ * {@link packCompositeId} is the ACTION (throw, or warn-and-pack under the
11641
+ * replay downgrade) and {@link compositeIdSeparatorRefusal} is the bare
11642
+ * PREDICATE, for a caller whose response is neither — the `import()` paths
11643
+ * warn and return `null` (`skipped-not-found`), which is the idiom those
11644
+ * methods already use for every other unusable id. Both share one message
11645
+ * builder so the two can never drift.
11646
+ *
11647
+ * ## Where to place the call
11648
+ *
11649
+ * Prefer computing the id BEFORE the create call rather than after it. The
11650
+ * refusal is a pre-flight check, and a throw placed after the AWS mutation has
11651
+ * already committed would leave an orphan resource behind with no state
11652
+ * record. Only where a segment is derived from the create RESPONSE (an
11653
+ * AWS-generated id) does the call have to sit after it — and those segments
11654
+ * are structurally incapable of carrying a `|` anyway. A post-call site must
11655
+ * also sit OUTSIDE the `try` whose `catch` re-wraps as
11656
+ * `ProvisioningError('Failed to create …')`, or a refusal would be
11657
+ * mis-reported as an AWS creation failure.
11658
+ *
11659
+ * ## What this does NOT cover
11660
+ *
11661
+ * The claim is "every composite packer this change reaches", not "every `|`
11662
+ * join in the tree". Two deliberate exclusions, recorded so the scope is not
11663
+ * read as wider than it is:
11664
+ *
11665
+ * - **`route53-provider.ts`'s three packers** (`AWS::Route53::RecordSet` and
11666
+ * its siblings) are NOT guarded — the file was owned by a parallel lane when
11667
+ * this shipped. The exposure there is bounded rather than absent:
11668
+ * `parseRecordSetCompositeId` requires EXACTLY three parts, so a four-part
11669
+ * id is REJECTED rather than mis-decoded into a different record. That is
11670
+ * the loud failure mode, not the silent-wrong-resource one this helper
11671
+ * exists for — but the deploy still records an id nothing can decode, so the
11672
+ * type belongs here whenever that lane lands. Tracked in issue
11673
+ * [#1711](https://github.com/go-to-k/cdkd/issues/1711).
11674
+ * - **`intrinsic-function-resolver.ts`'s `|` joins** (the WAFv2 and
11675
+ * `AWS::Events::Rule` arms) are out of scope by KIND, not by ownership: they
11676
+ * build a `Ref` VALUE for the template resolver, never a physicalId cdkd
11677
+ * records and later splits. Nothing decodes them, so an ambiguous join has
11678
+ * no decode site to go wrong at.
11679
+ */
11680
+ /** The character every composite physicalId in this codebase joins segments with. */
11681
+ const COMPOSITE_ID_SEPARATOR = "|";
11682
+ /** The issue tracking the real fix (escaping, or not packing at all). */
11683
+ const COMPOSITE_ID_ISSUE_URL = "https://github.com/go-to-k/cdkd/issues/1672";
11684
+ /** Render `<a>|<b>|<c>` from the segment names. */
11685
+ function idShape(segments) {
11686
+ return segments.map((segment) => `<${segment.name}>`).join("|");
11687
+ }
11688
+ /**
11689
+ * The refusal sentence for a composite id whose segments carry the separator,
11690
+ * or `undefined` when the id is unambiguous.
11691
+ *
11692
+ * Every offending segment is named, not just the first: a template that
11693
+ * mis-names one value frequently mis-names its sibling too, and reporting them
11694
+ * one deploy at a time is the shape of remedy nobody finishes.
11695
+ */
11696
+ function compositeIdSeparatorRefusal(resourceType, logicalId, segments) {
11697
+ const offending = segments.filter((segment) => String(segment.value).includes("|"));
11698
+ if (offending.length === 0) return void 0;
11699
+ return `${resourceType} ${logicalId}: ${offending.map((segment) => `${segment.name} '${String(segment.value)}'`).join(" and ")} contains '${"|"}', which cdkd uses as the separator in this type's physical id (${idShape(segments)}). Recording it would produce an id that decodes back to a DIFFERENT resource, so a later cdkd destroy / drift / update would target the wrong one — or silently skip it while the real resource stays alive. AWS accepts the name and CloudFormation manages such a resource fine; this is a cdkd limitation tracked in ${COMPOSITE_ID_ISSUE_URL}. Rename the resource so no segment contains '${"|"}', or manage it outside cdkd.`;
11700
+ }
11701
+ /**
11702
+ * Join the segments into a composite physicalId, REFUSING one that would be
11703
+ * ambiguous.
11704
+ *
11705
+ * @throws ProvisioningError when a segment contains {@link COMPOSITE_ID_SEPARATOR},
11706
+ * unless `options.onRefusal` is supplied — under which the message is handed
11707
+ * to the callback and the ambiguous id is returned, keeping the pre-guard
11708
+ * behavior.
11709
+ */
11710
+ function packCompositeId(resourceType, logicalId, segments, options) {
11711
+ const refusal = compositeIdSeparatorRefusal(resourceType, logicalId, segments);
11712
+ if (refusal !== void 0) if (options?.onRefusal) options.onRefusal(`${refusal} Continuing with the ambiguous id because the value comes from a cdkd state record, which no template edit can repair; the same value is REFUSED on a template-path create.`);
11713
+ else throw new ProvisioningError(refusal, resourceType, logicalId);
11714
+ return segments.map((segment) => String(segment.value)).join("|");
11715
+ }
11716
+
11600
11717
  //#endregion
11601
11718
  //#region src/provisioning/providers/lambda-event-invoke-config-provider.ts
11602
11719
  /**
@@ -11640,8 +11757,14 @@ var LambdaEventInvokeConfigProvider = class {
11640
11757
  /**
11641
11758
  * Compose the Cloud-Control-compatible compound physical id.
11642
11759
  */
11643
- buildPhysicalId(functionName, qualifier) {
11644
- return `${functionName}|${qualifier}`;
11760
+ buildPhysicalId(logicalId, functionName, qualifier, options) {
11761
+ return packCompositeId("AWS::Lambda::EventInvokeConfig", logicalId, [{
11762
+ name: "functionName",
11763
+ value: functionName
11764
+ }, {
11765
+ name: "qualifier",
11766
+ value: qualifier
11767
+ }], options);
11645
11768
  }
11646
11769
  /**
11647
11770
  * Split a `<FunctionName>|<Qualifier>` physical id back into its parts.
@@ -11699,9 +11822,9 @@ var LambdaEventInvokeConfigProvider = class {
11699
11822
  coerceNumber: true,
11700
11823
  ...replayWarn(this.logger, context)
11701
11824
  });
11825
+ const physicalId = this.buildPhysicalId(logicalId, functionName, qualifier, context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
11702
11826
  try {
11703
11827
  await this.lambdaClient.send(new PutFunctionEventInvokeConfigCommand(this.buildPutInput(properties)));
11704
- const physicalId = this.buildPhysicalId(functionName, qualifier);
11705
11828
  this.logger.debug(`Successfully created Lambda EventInvokeConfig ${logicalId}: ${physicalId}`);
11706
11829
  return {
11707
11830
  physicalId,
@@ -18860,7 +18983,7 @@ var EC2Provider = class {
18860
18983
  case "AWS::EC2::Subnet": return this.createSubnet(logicalId, resourceType, properties);
18861
18984
  case "AWS::EC2::InternetGateway": return this.createInternetGateway(logicalId, resourceType, properties);
18862
18985
  case "AWS::EC2::EIP": return this.createEip(logicalId, resourceType, properties, context);
18863
- case "AWS::EC2::VPCGatewayAttachment": return this.createVpcGatewayAttachment(logicalId, resourceType, properties);
18986
+ case "AWS::EC2::VPCGatewayAttachment": return this.createVpcGatewayAttachment(logicalId, resourceType, properties, context);
18864
18987
  case "AWS::EC2::NatGateway": return this.createNatGateway(logicalId, resourceType, properties);
18865
18988
  case "AWS::EC2::RouteTable": return this.createRouteTable(logicalId, resourceType, properties);
18866
18989
  case "AWS::EC2::Route": return this.createRoute(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0);
@@ -18869,7 +18992,7 @@ var EC2Provider = class {
18869
18992
  case "AWS::EC2::SecurityGroupIngress": return this.createSecurityGroupIngress(logicalId, resourceType, properties, context?.replayingState === true ? (message) => this.logger.warn(message) : void 0);
18870
18993
  case "AWS::EC2::Instance": return this.createInstance(logicalId, resourceType, properties, context);
18871
18994
  case "AWS::EC2::NetworkAcl": return this.createNetworkAcl(logicalId, resourceType, properties);
18872
- case "AWS::EC2::NetworkAclEntry": return this.createNetworkAclEntry(logicalId, resourceType, properties);
18995
+ case "AWS::EC2::NetworkAclEntry": return this.createNetworkAclEntry(logicalId, resourceType, properties, context);
18873
18996
  case "AWS::EC2::SubnetNetworkAclAssociation": return this.createSubnetNetworkAclAssociation(logicalId, resourceType, properties);
18874
18997
  default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
18875
18998
  }
@@ -19301,8 +19424,24 @@ var EC2Provider = class {
19301
19424
  throw new ProvisioningError(`Failed to delete InternetGateway ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
19302
19425
  }
19303
19426
  }
19304
- eipPhysicalId(publicIp, allocationId) {
19305
- return `${publicIp}|${allocationId}`;
19427
+ /**
19428
+ * Both segments are AWS-generated (a dotted-quad address and an
19429
+ * `eipalloc-...` id), so neither can carry cdkd's `|` separator and the
19430
+ * refusal below is a fence rather than a live guard (issue #1672). It is
19431
+ * applied uniformly with the rest of the composite-packing sites so a future
19432
+ * id-shape change cannot quietly reintroduce the ambiguity; for the same
19433
+ * reason it is safe on BOTH callers — `createEip` (post-`AllocateAddress`)
19434
+ * and `import()` (post-`DescribeAddresses`) — even though a throw on either
19435
+ * would arrive after the AWS call.
19436
+ */
19437
+ eipPhysicalId(logicalId, publicIp, allocationId, options) {
19438
+ return packCompositeId("AWS::EC2::EIP", logicalId, [{
19439
+ name: "publicIp",
19440
+ value: publicIp
19441
+ }, {
19442
+ name: "allocationId",
19443
+ value: allocationId
19444
+ }], options);
19306
19445
  }
19307
19446
  parseEipPhysicalId(physicalId) {
19308
19447
  if (physicalId.includes("|")) {
@@ -19317,14 +19456,16 @@ var EC2Provider = class {
19317
19456
  }
19318
19457
  async createEip(logicalId, resourceType, properties, context) {
19319
19458
  this.logger.debug(`Creating EIP ${logicalId}`);
19459
+ let allocationId;
19460
+ let publicIp;
19320
19461
  try {
19321
19462
  const response = await this.ec2Client.send(new AllocateAddressCommand({
19322
19463
  Domain: requireConfigString(properties["Domain"], "vpc", "AWS::EC2::EIP Domain", replayWarn(this.logger, context)),
19323
19464
  NetworkBorderGroup: properties["NetworkBorderGroup"],
19324
19465
  PublicIpv4Pool: properties["PublicIpv4Pool"]
19325
19466
  }));
19326
- const allocationId = response.AllocationId;
19327
- const publicIp = response.PublicIp;
19467
+ allocationId = response.AllocationId;
19468
+ publicIp = response.PublicIp;
19328
19469
  await this.applyTags(allocationId, properties, logicalId);
19329
19470
  const instanceId = properties["InstanceId"];
19330
19471
  if (instanceId) if (process.env["CDKD_NO_WAIT"] === "true") this.logger.warn(`EIP ${logicalId} (${allocationId}) was NOT associated with ${instanceId}: --no-wait skips the instance running-state wait, and AssociateAddress rejects an instance that is not yet running. Verify and associate once the instance is running: aws ec2 describe-instances --instance-ids ${instanceId} --query 'Reservations[].Instances[].State.Name' && aws ec2 associate-address --allocation-id ${allocationId} --instance-id ${instanceId}`);
@@ -19336,17 +19477,17 @@ var EC2Provider = class {
19336
19477
  this.logger.debug(`Associated EIP ${logicalId} (${allocationId}) to ${instanceId}`);
19337
19478
  }
19338
19479
  this.logger.debug(`Successfully created EIP ${logicalId}: ${allocationId} (${publicIp})`);
19339
- return {
19340
- physicalId: this.eipPhysicalId(publicIp, allocationId),
19341
- attributes: {
19342
- AllocationId: allocationId,
19343
- PublicIp: publicIp
19344
- }
19345
- };
19346
19480
  } catch (error) {
19347
19481
  const cause = error instanceof Error ? error : void 0;
19348
19482
  throw new ProvisioningError(`Failed to create EIP ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
19349
19483
  }
19484
+ return {
19485
+ physicalId: this.eipPhysicalId(logicalId, publicIp, allocationId, context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0),
19486
+ attributes: {
19487
+ AllocationId: allocationId,
19488
+ PublicIp: publicIp
19489
+ }
19490
+ };
19350
19491
  }
19351
19492
  async updateEip(logicalId, physicalId, properties, previousProperties) {
19352
19493
  this.logger.debug(`Updating EIP ${logicalId}: ${physicalId}`);
@@ -19412,17 +19553,23 @@ var EC2Provider = class {
19412
19553
  default: return;
19413
19554
  }
19414
19555
  }
19415
- async createVpcGatewayAttachment(logicalId, resourceType, properties) {
19556
+ async createVpcGatewayAttachment(logicalId, resourceType, properties, context) {
19416
19557
  this.logger.debug(`Creating VPCGatewayAttachment ${logicalId}`);
19417
19558
  const vpcId = properties["VpcId"];
19418
19559
  const internetGatewayId = properties["InternetGatewayId"];
19419
19560
  if (!vpcId || !internetGatewayId) throw new ProvisioningError(`VpcId and InternetGatewayId are required for VPCGatewayAttachment ${logicalId}`, resourceType, logicalId);
19561
+ const physicalId = packCompositeId(resourceType, logicalId, [{
19562
+ name: "internetGatewayId",
19563
+ value: internetGatewayId
19564
+ }, {
19565
+ name: "vpcId",
19566
+ value: vpcId
19567
+ }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
19420
19568
  try {
19421
19569
  await this.ec2Client.send(new AttachInternetGatewayCommand({
19422
19570
  VpcId: vpcId,
19423
19571
  InternetGatewayId: internetGatewayId
19424
19572
  }));
19425
- const physicalId = `${internetGatewayId}|${vpcId}`;
19426
19573
  this.logger.debug(`Successfully created VPCGatewayAttachment ${logicalId}: ${physicalId}`);
19427
19574
  return {
19428
19575
  physicalId,
@@ -19574,6 +19721,13 @@ var EC2Provider = class {
19574
19721
  onMultipleDestinations(`${message} Continuing with ${usedKey} and ignoring the rest.`);
19575
19722
  } else throw new ProvisioningError(message, resourceType, logicalId);
19576
19723
  }
19724
+ const physicalId = packCompositeId(resourceType, logicalId, [{
19725
+ name: "routeTableId",
19726
+ value: routeTableId
19727
+ }, {
19728
+ name: "destination",
19729
+ value: destination
19730
+ }], onMultipleDestinations ? { onRefusal: onMultipleDestinations } : void 0);
19577
19731
  try {
19578
19732
  await this.ec2Client.send(new CreateRouteCommand({
19579
19733
  RouteTableId: routeTableId,
@@ -19590,7 +19744,6 @@ var EC2Provider = class {
19590
19744
  VpcEndpointId: properties["VpcEndpointId"] ?? void 0,
19591
19745
  VpcPeeringConnectionId: properties["VpcPeeringConnectionId"] ?? void 0
19592
19746
  }));
19593
- const physicalId = `${routeTableId}|${destination}`;
19594
19747
  this.logger.debug(`Successfully created Route ${logicalId}: ${physicalId}`);
19595
19748
  return {
19596
19749
  physicalId,
@@ -19901,6 +20054,24 @@ var EC2Provider = class {
19901
20054
  const effectiveProperties = narrowed === properties ? void 0 : narrowed;
19902
20055
  const fromPort = properties["FromPort"];
19903
20056
  const toPort = properties["ToPort"];
20057
+ const physicalId = packCompositeId(resourceType, logicalId, [
20058
+ {
20059
+ name: "groupId",
20060
+ value: groupId
20061
+ },
20062
+ {
20063
+ name: "ipProtocol",
20064
+ value: ipProtocol
20065
+ },
20066
+ {
20067
+ name: "fromPort",
20068
+ value: fromPort ?? "-1"
20069
+ },
20070
+ {
20071
+ name: "toPort",
20072
+ value: toPort ?? "-1"
20073
+ }
20074
+ ], onUnusableProtocol ? { onRefusal: onUnusableProtocol } : void 0);
19904
20075
  try {
19905
20076
  await this.ec2Client.send(new AuthorizeSecurityGroupIngressCommand({
19906
20077
  GroupId: groupId,
@@ -19909,7 +20080,6 @@ var EC2Provider = class {
19909
20080
  IpProtocol: ipProtocol
19910
20081
  }]
19911
20082
  }));
19912
- const physicalId = `${groupId}|${ipProtocol}|${fromPort ?? "-1"}|${toPort ?? "-1"}`;
19913
20083
  this.logger.debug(`Successfully created SecurityGroupIngress ${logicalId}: ${physicalId}`);
19914
20084
  return {
19915
20085
  physicalId,
@@ -19918,7 +20088,6 @@ var EC2Provider = class {
19918
20088
  };
19919
20089
  } catch (error) {
19920
20090
  if (error instanceof Error && error.message.includes("already exists")) {
19921
- const physicalId = `${groupId}|${ipProtocol}|${fromPort ?? "-1"}|${toPort ?? "-1"}`;
19922
20091
  this.logger.debug(`SecurityGroupIngress ${logicalId} already exists, treating as success`);
19923
20092
  return {
19924
20093
  physicalId,
@@ -20586,7 +20755,7 @@ var EC2Provider = class {
20586
20755
  throw new ProvisioningError(`Failed to delete NetworkAcl ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
20587
20756
  }
20588
20757
  }
20589
- async createNetworkAclEntry(logicalId, resourceType, properties) {
20758
+ async createNetworkAclEntry(logicalId, resourceType, properties, context) {
20590
20759
  this.logger.debug(`Creating NetworkAclEntry ${logicalId}`);
20591
20760
  const networkAclId = properties["NetworkAclId"];
20592
20761
  const ruleNumber = properties["RuleNumber"];
@@ -20594,6 +20763,20 @@ var EC2Provider = class {
20594
20763
  const ruleAction = properties["RuleAction"];
20595
20764
  const egress = properties["Egress"] ?? false;
20596
20765
  if (!networkAclId || ruleNumber === void 0 || protocol === void 0 || !ruleAction) throw new ProvisioningError(`NetworkAclId, RuleNumber, Protocol, and RuleAction are required for NetworkAclEntry ${logicalId}`, resourceType, logicalId);
20766
+ const physicalId = packCompositeId(resourceType, logicalId, [
20767
+ {
20768
+ name: "networkAclId",
20769
+ value: networkAclId
20770
+ },
20771
+ {
20772
+ name: "ruleNumber",
20773
+ value: ruleNumber
20774
+ },
20775
+ {
20776
+ name: "egress",
20777
+ value: egress
20778
+ }
20779
+ ], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
20597
20780
  try {
20598
20781
  const cidrBlock = properties["CidrBlock"];
20599
20782
  const ipv6CidrBlock = properties["Ipv6CidrBlock"];
@@ -20616,7 +20799,6 @@ var EC2Provider = class {
20616
20799
  Type: icmpTypeCode["Type"]
20617
20800
  } : void 0
20618
20801
  }));
20619
- const physicalId = `${networkAclId}|${ruleNumber}|${egress}`;
20620
20802
  this.logger.debug(`Successfully created NetworkAclEntry ${logicalId}: ${physicalId}`);
20621
20803
  return {
20622
20804
  physicalId,
@@ -20875,7 +21057,7 @@ var EC2Provider = class {
20875
21057
  * physical-name property instead.
20876
21058
  */
20877
21059
  async import(input) {
20878
- if (input.knownPhysicalId) return this.verifyExplicit(input.resourceType, input.knownPhysicalId);
21060
+ if (input.knownPhysicalId) return this.verifyExplicit(input.logicalId, input.resourceType, input.knownPhysicalId);
20879
21061
  return null;
20880
21062
  }
20881
21063
  /**
@@ -21436,7 +21618,7 @@ var EC2Provider = class {
21436
21618
  }
21437
21619
  }
21438
21620
  }
21439
- async verifyExplicit(resourceType, physicalId) {
21621
+ async verifyExplicit(logicalId, resourceType, physicalId) {
21440
21622
  try {
21441
21623
  switch (resourceType) {
21442
21624
  case "AWS::EC2::VPC": return (await this.ec2Client.send(new DescribeVpcsCommand({ VpcIds: [physicalId] }))).Vpcs?.[0] ? {
@@ -21460,8 +21642,19 @@ var EC2Provider = class {
21460
21642
  const filter = allocationId ? { AllocationIds: [allocationId] } : { PublicIps: publicIp ? [publicIp] : [] };
21461
21643
  const addr = (await this.ec2Client.send(new DescribeAddressesCommand(filter))).Addresses?.[0];
21462
21644
  if (!addr?.AllocationId || !addr.PublicIp) return null;
21645
+ const eipRefusal = compositeIdSeparatorRefusal("AWS::EC2::EIP", logicalId, [{
21646
+ name: "publicIp",
21647
+ value: addr.PublicIp
21648
+ }, {
21649
+ name: "allocationId",
21650
+ value: addr.AllocationId
21651
+ }]);
21652
+ if (eipRefusal !== void 0) {
21653
+ this.logger.warn(`${eipRefusal} Skipping import.`);
21654
+ return null;
21655
+ }
21463
21656
  return {
21464
- physicalId: this.eipPhysicalId(addr.PublicIp, addr.AllocationId),
21657
+ physicalId: this.eipPhysicalId(logicalId, addr.PublicIp, addr.AllocationId),
21465
21658
  attributes: {
21466
21659
  AllocationId: addr.AllocationId,
21467
21660
  PublicIp: addr.PublicIp
@@ -22468,6 +22661,20 @@ var ApiGatewayProvider = class ApiGatewayProvider {
22468
22661
  const requestValidatorId = properties["RequestValidatorId"];
22469
22662
  const authorizationScopes = properties["AuthorizationScopes"];
22470
22663
  if (!restApiId || !resourceId || !httpMethod) throw new ProvisioningError(`RestApiId, ResourceId, and HttpMethod are required for API Gateway Method ${logicalId}`, resourceType, logicalId);
22664
+ const physicalId = packCompositeId(resourceType, logicalId, [
22665
+ {
22666
+ name: "restApiId",
22667
+ value: restApiId
22668
+ },
22669
+ {
22670
+ name: "resourceId",
22671
+ value: resourceId
22672
+ },
22673
+ {
22674
+ name: "httpMethod",
22675
+ value: httpMethod
22676
+ }
22677
+ ], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
22471
22678
  try {
22472
22679
  await this.apiGatewayClient.send(new PutMethodCommand({
22473
22680
  restApiId,
@@ -22545,7 +22752,6 @@ var ApiGatewayProvider = class ApiGatewayProvider {
22545
22752
  }
22546
22753
  throw innerError;
22547
22754
  }
22548
- const physicalId = `${restApiId}|${resourceId}|${httpMethod}`;
22549
22755
  this.logger.debug(`Successfully created API Gateway Method ${logicalId}: ${physicalId}`);
22550
22756
  return {
22551
22757
  physicalId,
@@ -36511,9 +36717,9 @@ var AppSyncProvider = class {
36511
36717
  switch (resourceType) {
36512
36718
  case "AWS::AppSync::GraphQLApi": return this.createGraphQLApi(logicalId, resourceType, properties, context);
36513
36719
  case "AWS::AppSync::GraphQLSchema": return this.createGraphQLSchema(logicalId, resourceType, properties);
36514
- case "AWS::AppSync::DataSource": return this.createDataSource(logicalId, resourceType, properties);
36515
- case "AWS::AppSync::Resolver": return this.createResolver(logicalId, resourceType, properties);
36516
- case "AWS::AppSync::ApiKey": return this.createApiKey(logicalId, resourceType, properties);
36720
+ case "AWS::AppSync::DataSource": return this.createDataSource(logicalId, resourceType, properties, context);
36721
+ case "AWS::AppSync::Resolver": return this.createResolver(logicalId, resourceType, properties, context);
36722
+ case "AWS::AppSync::ApiKey": return this.createApiKey(logicalId, resourceType, properties, context);
36517
36723
  default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
36518
36724
  }
36519
36725
  }
@@ -37427,12 +37633,19 @@ var AppSyncProvider = class {
37427
37633
  throw new ProvisioningError(`Failed to create GraphQL Schema ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
37428
37634
  }
37429
37635
  }
37430
- async createDataSource(logicalId, resourceType, properties) {
37636
+ async createDataSource(logicalId, resourceType, properties, context) {
37431
37637
  this.logger.debug(`Creating DataSource ${logicalId}`);
37432
37638
  const apiId = properties["ApiId"];
37433
37639
  const name = properties["Name"];
37434
37640
  const type = properties["Type"];
37435
37641
  if (!apiId || !name || !type) throw new ProvisioningError(`ApiId, Name, and Type are required for DataSource ${logicalId}`, resourceType, logicalId);
37642
+ const physicalId = packCompositeId(resourceType, logicalId, [{
37643
+ name: "apiId",
37644
+ value: apiId
37645
+ }, {
37646
+ name: "name",
37647
+ value: name
37648
+ }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
37436
37649
  try {
37437
37650
  const input = {
37438
37651
  apiId,
@@ -37441,7 +37654,6 @@ var AppSyncProvider = class {
37441
37654
  };
37442
37655
  this.applyDataSourceConfig(input, resourceType, logicalId, properties);
37443
37656
  await this.getClient().send(new CreateDataSourceCommand(input));
37444
- const physicalId = `${apiId}|${name}`;
37445
37657
  this.logger.debug(`Successfully created DataSource ${logicalId}: ${physicalId}`);
37446
37658
  return {
37447
37659
  physicalId,
@@ -37478,12 +37690,26 @@ var AppSyncProvider = class {
37478
37690
  throw new ProvisioningError(`Failed to delete DataSource ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
37479
37691
  }
37480
37692
  }
37481
- async createResolver(logicalId, resourceType, properties) {
37693
+ async createResolver(logicalId, resourceType, properties, context) {
37482
37694
  this.logger.debug(`Creating Resolver ${logicalId}`);
37483
37695
  const apiId = properties["ApiId"];
37484
37696
  const typeName = properties["TypeName"];
37485
37697
  const fieldName = properties["FieldName"];
37486
37698
  if (!apiId || !typeName || !fieldName) throw new ProvisioningError(`ApiId, TypeName, and FieldName are required for Resolver ${logicalId}`, resourceType, logicalId);
37699
+ const physicalId = packCompositeId(resourceType, logicalId, [
37700
+ {
37701
+ name: "apiId",
37702
+ value: apiId
37703
+ },
37704
+ {
37705
+ name: "typeName",
37706
+ value: typeName
37707
+ },
37708
+ {
37709
+ name: "fieldName",
37710
+ value: fieldName
37711
+ }
37712
+ ], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
37487
37713
  try {
37488
37714
  const input = {
37489
37715
  apiId,
@@ -37492,7 +37718,6 @@ var AppSyncProvider = class {
37492
37718
  };
37493
37719
  await this.applyResolverConfig(input, resourceType, logicalId, properties);
37494
37720
  await this.getClient().send(new CreateResolverCommand(input));
37495
- const physicalId = `${apiId}|${typeName}|${fieldName}`;
37496
37721
  this.logger.debug(`Successfully created Resolver ${logicalId}: ${physicalId}`);
37497
37722
  return {
37498
37723
  physicalId,
@@ -37528,28 +37753,34 @@ var AppSyncProvider = class {
37528
37753
  throw new ProvisioningError(`Failed to delete Resolver ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
37529
37754
  }
37530
37755
  }
37531
- async createApiKey(logicalId, resourceType, properties) {
37756
+ async createApiKey(logicalId, resourceType, properties, context) {
37532
37757
  this.logger.debug(`Creating ApiKey ${logicalId}`);
37533
37758
  const apiId = properties["ApiId"];
37534
37759
  if (!apiId) throw new ProvisioningError(`ApiId is required for ApiKey ${logicalId}`, resourceType, logicalId);
37760
+ let apiKeyId;
37535
37761
  try {
37536
37762
  const input = { apiId };
37537
37763
  if (properties["Description"]) input.description = properties["Description"];
37538
37764
  if (properties["Expires"]) input.expires = properties["Expires"];
37539
- const response = await this.getClient().send(new CreateApiKeyCommand(input));
37540
- const apiKeyId = response.apiKey.id;
37765
+ apiKeyId = (await this.getClient().send(new CreateApiKeyCommand(input))).apiKey.id;
37541
37766
  this.logger.debug(`Successfully created ApiKey ${logicalId}: ${apiKeyId}`);
37542
- return {
37543
- physicalId: `${apiId}|${apiKeyId}`,
37544
- attributes: {
37545
- ApiKey: response.apiKey.id,
37546
- Arn: `arn:aws:appsync:*:*:apis/${apiId}/apikeys/${apiKeyId}`
37547
- }
37548
- };
37549
37767
  } catch (error) {
37550
37768
  const cause = error instanceof Error ? error : void 0;
37551
37769
  throw new ProvisioningError(`Failed to create ApiKey ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
37552
37770
  }
37771
+ return {
37772
+ physicalId: packCompositeId(resourceType, logicalId, [{
37773
+ name: "apiId",
37774
+ value: apiId
37775
+ }, {
37776
+ name: "apiKeyId",
37777
+ value: apiKeyId
37778
+ }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0),
37779
+ attributes: {
37780
+ ApiKey: apiKeyId,
37781
+ Arn: `arn:aws:appsync:*:*:apis/${apiId}/apikeys/${apiKeyId}`
37782
+ }
37783
+ };
37553
37784
  }
37554
37785
  async deleteApiKey(logicalId, physicalId, resourceType, context) {
37555
37786
  this.logger.debug(`Deleting ApiKey ${logicalId}: ${physicalId}`);
@@ -38209,6 +38440,13 @@ var GlueProvider = class {
38209
38440
  replayingState: context?.replayingState === true
38210
38441
  });
38211
38442
  const openTableFormatInput = properties["OpenTableFormatInput"];
38443
+ const physicalId = packCompositeId(resourceType, logicalId, [{
38444
+ name: "databaseName",
38445
+ value: databaseName
38446
+ }, {
38447
+ name: "tableName",
38448
+ value: tableName
38449
+ }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
38212
38450
  try {
38213
38451
  await this.getClient().send(new CreateTableCommand$1({
38214
38452
  CatalogId: catalogId,
@@ -38216,7 +38454,6 @@ var GlueProvider = class {
38216
38454
  TableInput: this.buildTableInput(tableInput, tableName),
38217
38455
  ...openTableFormatInput !== void 0 && { OpenTableFormatInput: openTableFormatInput }
38218
38456
  }));
38219
- const physicalId = `${databaseName}|${tableName}`;
38220
38457
  this.logger.debug(`Successfully created Glue Table ${logicalId}: ${physicalId}`);
38221
38458
  return {
38222
38459
  physicalId,
@@ -49322,11 +49559,11 @@ var S3TablesProvider = class {
49322
49559
  if (!this.client) this.client = new S3TablesClient(this.providerRegion ? { region: this.providerRegion } : {});
49323
49560
  return this.client;
49324
49561
  }
49325
- async create(logicalId, resourceType, properties) {
49562
+ async create(logicalId, resourceType, properties, context) {
49326
49563
  switch (resourceType) {
49327
49564
  case "AWS::S3Tables::TableBucket": return this.createTableBucket(logicalId, resourceType, properties);
49328
- case "AWS::S3Tables::Namespace": return this.createNamespace(logicalId, resourceType, properties);
49329
- case "AWS::S3Tables::Table": return this.createTable(logicalId, resourceType, properties);
49565
+ case "AWS::S3Tables::Namespace": return this.createNamespace(logicalId, resourceType, properties, context);
49566
+ case "AWS::S3Tables::Table": return this.createTable(logicalId, resourceType, properties, context);
49330
49567
  default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
49331
49568
  }
49332
49569
  }
@@ -49442,7 +49679,7 @@ var S3TablesProvider = class {
49442
49679
  namespaceContinuationToken = namespacesResult.continuationToken;
49443
49680
  } while (namespaceContinuationToken);
49444
49681
  }
49445
- async createNamespace(logicalId, resourceType, properties) {
49682
+ async createNamespace(logicalId, resourceType, properties, context) {
49446
49683
  this.logger.debug(`Creating S3 Tables Namespace ${logicalId}`);
49447
49684
  const tableBucketARN = properties["TableBucketARN"];
49448
49685
  if (!tableBucketARN) throw new ProvisioningError(`TableBucketARN is required for S3 Tables Namespace ${logicalId}`, resourceType, logicalId);
@@ -49451,12 +49688,18 @@ var S3TablesProvider = class {
49451
49688
  if (Array.isArray(rawNs) && rawNs.length > 0 && typeof rawNs[0] === "string") namespaceName = rawNs[0];
49452
49689
  else if (typeof rawNs === "string" && rawNs.length > 0) namespaceName = rawNs;
49453
49690
  if (!namespaceName) throw new ProvisioningError(`Namespace is required for S3 Tables Namespace ${logicalId}`, resourceType, logicalId);
49691
+ const physicalId = packCompositeId(resourceType, logicalId, [{
49692
+ name: "tableBucketARN",
49693
+ value: tableBucketARN
49694
+ }, {
49695
+ name: "namespace",
49696
+ value: namespaceName
49697
+ }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
49454
49698
  try {
49455
49699
  await this.getClient().send(new CreateNamespaceCommand({
49456
49700
  tableBucketARN,
49457
49701
  namespace: [namespaceName]
49458
49702
  }));
49459
- const physicalId = `${tableBucketARN}|${namespaceName}`;
49460
49703
  this.logger.debug(`Successfully created S3 Tables Namespace ${logicalId}: ${physicalId}`);
49461
49704
  return {
49462
49705
  physicalId,
@@ -49487,7 +49730,7 @@ var S3TablesProvider = class {
49487
49730
  throw new ProvisioningError(`Failed to delete S3 Tables Namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
49488
49731
  }
49489
49732
  }
49490
- async createTable(logicalId, resourceType, properties) {
49733
+ async createTable(logicalId, resourceType, properties, context) {
49491
49734
  this.logger.debug(`Creating S3 Tables Table ${logicalId}`);
49492
49735
  const tableBucketARN = properties["TableBucketARN"];
49493
49736
  if (!tableBucketARN) throw new ProvisioningError(`TableBucketARN is required for S3 Tables Table ${logicalId}`, resourceType, logicalId);
@@ -49498,6 +49741,20 @@ var S3TablesProvider = class {
49498
49741
  const format = properties["OpenTableFormat"] ?? properties["Format"];
49499
49742
  if (!format) throw new ProvisioningError(`OpenTableFormat is required for S3 Tables Table ${logicalId}`, resourceType, logicalId);
49500
49743
  const tags = this.cfnTagsToSdkMap(properties["Tags"]);
49744
+ const physicalId = packCompositeId(resourceType, logicalId, [
49745
+ {
49746
+ name: "tableBucketARN",
49747
+ value: tableBucketARN
49748
+ },
49749
+ {
49750
+ name: "namespace",
49751
+ value: namespace
49752
+ },
49753
+ {
49754
+ name: "name",
49755
+ value: name
49756
+ }
49757
+ ], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
49501
49758
  try {
49502
49759
  const response = await this.getClient().send(new CreateTableCommand$2({
49503
49760
  tableBucketARN,
@@ -49506,7 +49763,6 @@ var S3TablesProvider = class {
49506
49763
  format,
49507
49764
  ...tags !== void 0 && { tags }
49508
49765
  }));
49509
- const physicalId = `${tableBucketARN}|${namespace}|${name}`;
49510
49766
  if (!response.tableARN) throw new ProvisioningError(`CreateTable did not return a tableARN for ${logicalId} (${physicalId}) — refusing to record an empty TableARN attribute`, resourceType, logicalId, physicalId);
49511
49767
  const tableARN = response.tableARN;
49512
49768
  this.logger.debug(`Successfully created S3 Tables Table ${logicalId}: ${physicalId}`);
@@ -49726,6 +49982,17 @@ var S3TablesProvider = class {
49726
49982
  if (err instanceof NotFoundException$6) return null;
49727
49983
  throw err;
49728
49984
  }
49985
+ const namespaceRefusal = compositeIdSeparatorRefusal("AWS::S3Tables::Namespace", input.logicalId, [{
49986
+ name: "tableBucketARN",
49987
+ value: identity.tableBucketARN
49988
+ }, {
49989
+ name: "namespace",
49990
+ value: identity.namespace
49991
+ }]);
49992
+ if (namespaceRefusal !== void 0) {
49993
+ this.logger.warn(`${namespaceRefusal} Skipping import.`);
49994
+ return null;
49995
+ }
49729
49996
  return {
49730
49997
  physicalId: `${identity.tableBucketARN}|${identity.namespace}`,
49731
49998
  attributes: {}
@@ -49823,6 +50090,24 @@ var S3TablesProvider = class {
49823
50090
  attributes: { TableARN: tableARN }
49824
50091
  };
49825
50092
  }
50093
+ const tableRefusal = compositeIdSeparatorRefusal("AWS::S3Tables::Table", input.logicalId, [
50094
+ {
50095
+ name: "tableBucketARN",
50096
+ value: identity.tableBucketARN
50097
+ },
50098
+ {
50099
+ name: "namespace",
50100
+ value: identity.namespace
50101
+ },
50102
+ {
50103
+ name: "name",
50104
+ value: identity.name
50105
+ }
50106
+ ]);
50107
+ if (tableRefusal !== void 0) {
50108
+ this.logger.warn(`${tableRefusal} Skipping import.`);
50109
+ return null;
50110
+ }
49826
50111
  return {
49827
50112
  physicalId: `${identity.tableBucketARN}|${identity.namespace}|${identity.name}`,
49828
50113
  attributes: { TableARN: tableARN }
@@ -72732,7 +73017,7 @@ function createMigrateCommand() {
72732
73017
  */
72733
73018
  function buildProgram() {
72734
73019
  const program = new Command();
72735
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.3");
73020
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.4");
72736
73021
  program.hook("preAction", (_thisCommand, actionCommand) => {
72737
73022
  const { profile } = actionCommand.optsWithGlobals();
72738
73023
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;