@go-to-k/cdkd 0.280.17 → 0.280.19
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-DQLjoTQ3.js → asg-provider-B62D31jG.js} +2 -2
- package/dist/{asg-provider-DQLjoTQ3.js.map → asg-provider-B62D31jG.js.map} +1 -1
- package/dist/cli.js +495 -97
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-tCcs8UGn.js → deploy-engine-r4N9-tZD.js} +17 -19
- package/dist/{deploy-engine-tCcs8UGn.js.map → deploy-engine-r4N9-tZD.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 requireConfigString, $t as processStackMessages, A as red, At as runDockerStreaming, B as isTerminationProtectionPropagationError, Bt as resolveSkipPrefix, C as isStatefulRecreateTargetSync, Ct as parseBootstrapMarker, D as cyan, Dn as normalizeAwsError, Dt as formatDockerLoginError, E as bold, Et as buildDockerImage, F as ProviderRegistry, Ft as getDefaultStateBucketName, G as normalizeAwsTagsToCfn, Gt as warnDeprecatedNoPrefixCliFlag, H as cfnRefValueFromPhysicalId, Ht as resolveStateBucketWithDefaultAndSource, I as findActionableSilentDrops, It as getLegacyStateBucketName, J as configStringRefusal, Jt as MIGRATE_TMP_PREFIX, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_BODY_LIMIT, L as CloudControlProvider, Lt as resolveApp, M as IAMRoleProvider, Mt as getDockerImageBySourceHash, N as collectInlinePolicyNamesManagedBySiblings, Nt as Synthesizer, O as gray, On as withErrorHandling, Ot as getDockerCmd, P as clearOnUpdateRemoval, Pt as synthesisStatusMessage, Q as requireConfigObject, Qt as AssemblyReader, R as slowCcOperationTimeoutMs, Rt as resolveAutoAssetStorage, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, Sn as StackTerminationProtectionError, St as getBootstrapMarkerKey, T as formatResourceLine, Tt as validateContainerRepoName, U as refStateLookupFromResource, Ut as resolveUseCdkBootstrapAssets, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefault, W as WAFv2WebACLProvider, Wt as stateBucketExistenceConfirmed, X as replayWarn, Xt as uploadCfnTemplate, Y as readConfigString, Yt as findLargeInlineResources, Z as requireConfigArray, Zt as expectedOwnerParam, _ as createPreDeleteFinalSnapshot, _n as PartialFailureError, _t as loadPublishableAssetManifest, a as DeploymentEventsStore, an as setAwsClients, at as isThrottlingError, b as unsupportedFinalSnapshotError, bn as ResourceUpdateNotSupportedError, bt as BOOTSTRAP_MARKER_PREFIX, c as replayFailedOperations, ct as LockManager, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalInvokeBuildError$1, dt as shouldRetainResource, et as applyRoleArnIfSet, f as computeImplicitDeleteEdges, fn as LocalMigrateError, ft as AssetPublisher, g as ccRoutedFinalSnapshotError, gn as NestedStackChildDirectDestroyError, gt as createAssetRedirectResolver, h as buildFinalSnapshotIdentifier, hn as MissingCdkCliError, ht as buildAssetRedirectMap, i as DeploymentEventsReader, in as resetAwsClients, it as isRetryableTransientError, j as yellow, jt as AssetManifestLoader, k as green, kt as runDockerForeground, l as replayRollback, lt as S3StateBackend, m as PRE_DELETE_SNAPSHOT_TYPES, mt as WorkGraph, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AwsClients, nt as describeTypeWithThrottleRetry, o as planFailedOps, ot as DagBuilder, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalStartServiceError, pt as stringifyValue, q as assertRegionMatch, qt as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, rn as getAwsClients, rt as withRetry, s as planRollback, sn as CdkdError, st as TemplateParser, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveBucketRegion, tt as DiffCalculator, u as withResourceDeadline, un as DeployCancelledError, ut as rebuildClientForBucketRegion, v as isFinalSnapshotError, vn as ProvisioningError, vt as rewriteTemplateAssetReferences, w as renderStatefulReason, wt as validateAssetBucketName, x as extractDeploymentEventError, xn as StackHasActiveImportsError, xt as ensureAssetStorage, y as refusesFinalSnapshot, yn as ResourceTimeoutError, yt as AssetModeResolver, z as disableInstanceApiTermination, zt as resolveCaptureObservedState } from "./deploy-engine-
|
|
2
|
+
import { $ as requireConfigString, $t as processStackMessages, A as red, At as runDockerStreaming, B as isTerminationProtectionPropagationError, Bt as resolveSkipPrefix, C as isStatefulRecreateTargetSync, Ct as parseBootstrapMarker, D as cyan, Dn as normalizeAwsError, Dt as formatDockerLoginError, E as bold, Et as buildDockerImage, F as ProviderRegistry, Ft as getDefaultStateBucketName, G as normalizeAwsTagsToCfn, Gt as warnDeprecatedNoPrefixCliFlag, H as cfnRefValueFromPhysicalId, Ht as resolveStateBucketWithDefaultAndSource, I as findActionableSilentDrops, It as getLegacyStateBucketName, J as configStringRefusal, Jt as MIGRATE_TMP_PREFIX, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_BODY_LIMIT, L as CloudControlProvider, Lt as resolveApp, M as IAMRoleProvider, Mt as getDockerImageBySourceHash, N as collectInlinePolicyNamesManagedBySiblings, Nt as Synthesizer, O as gray, On as withErrorHandling, Ot as getDockerCmd, P as clearOnUpdateRemoval, Pt as synthesisStatusMessage, Q as requireConfigObject, Qt as AssemblyReader, R as slowCcOperationTimeoutMs, Rt as resolveAutoAssetStorage, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, Sn as StackTerminationProtectionError, St as getBootstrapMarkerKey, T as formatResourceLine, Tt as validateContainerRepoName, U as refStateLookupFromResource, Ut as resolveUseCdkBootstrapAssets, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefault, W as WAFv2WebACLProvider, Wt as stateBucketExistenceConfirmed, X as replayWarn, Xt as uploadCfnTemplate, Y as readConfigString, Yt as findLargeInlineResources, Z as requireConfigArray, Zt as expectedOwnerParam, _ as createPreDeleteFinalSnapshot, _n as PartialFailureError, _t as loadPublishableAssetManifest, a as DeploymentEventsStore, an as setAwsClients, at as isThrottlingError, b as unsupportedFinalSnapshotError, bn as ResourceUpdateNotSupportedError, bt as BOOTSTRAP_MARKER_PREFIX, c as replayFailedOperations, ct as LockManager, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalInvokeBuildError$1, dt as shouldRetainResource, et as applyRoleArnIfSet, f as computeImplicitDeleteEdges, fn as LocalMigrateError, ft as AssetPublisher, g as ccRoutedFinalSnapshotError, gn as NestedStackChildDirectDestroyError, gt as createAssetRedirectResolver, h as buildFinalSnapshotIdentifier, hn as MissingCdkCliError, ht as buildAssetRedirectMap, i as DeploymentEventsReader, in as resetAwsClients, it as isRetryableTransientError, j as yellow, jt as AssetManifestLoader, k as green, kt as runDockerForeground, l as replayRollback, lt as S3StateBackend, m as PRE_DELETE_SNAPSHOT_TYPES, mt as WorkGraph, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AwsClients, nt as describeTypeWithThrottleRetry, o as planFailedOps, ot as DagBuilder, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalStartServiceError, pt as stringifyValue, q as assertRegionMatch, qt as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, rn as getAwsClients, rt as withRetry, s as planRollback, sn as CdkdError, st as TemplateParser, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveBucketRegion, tt as DiffCalculator, u as withResourceDeadline, un as DeployCancelledError, ut as rebuildClientForBucketRegion, v as isFinalSnapshotError, vn as ProvisioningError, vt as rewriteTemplateAssetReferences, w as renderStatefulReason, wt as validateAssetBucketName, x as extractDeploymentEventError, xn as StackHasActiveImportsError, xt as ensureAssetStorage, y as refusesFinalSnapshot, yn as ResourceTimeoutError, yt as AssetModeResolver, z as disableInstanceApiTermination, zt as resolveCaptureObservedState } from "./deploy-engine-r4N9-tZD.js";
|
|
3
3
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BYMEE-BS.js";
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-B62D31jG.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";
|
|
@@ -27873,6 +27873,78 @@ const TARGET_GROUP_ATTRIBUTE_DEFAULTS = {
|
|
|
27873
27873
|
"proxy_protocol_v2.enabled": "false"
|
|
27874
27874
|
};
|
|
27875
27875
|
/**
|
|
27876
|
+
* Documented AWS defaults for the BOOLEAN / ENUM-valued LoadBalancer and
|
|
27877
|
+
* Listener attributes, used to reset a removed `LoadBalancerAttributes` /
|
|
27878
|
+
* `ListenerAttributes` entry.
|
|
27879
|
+
*
|
|
27880
|
+
* Unlike ModifyTargetGroupAttributes — which rejects an empty `Value` for
|
|
27881
|
+
* EVERY key — these two APIs accept `Value: ''` for the numeric and
|
|
27882
|
+
* free-form string attributes and REJECT it only where the value is
|
|
27883
|
+
* validated against a fixed set. Live A/B 2026-08-11 (issue #1609 item 1),
|
|
27884
|
+
* via the `alb` integ's removal phase:
|
|
27885
|
+
*
|
|
27886
|
+
* idle_timeout.timeout_seconds -> `Value: ''` ACCEPTED (numeric)
|
|
27887
|
+
* deletion_protection.enabled -> "The value of 'deletion_protection.enabled'
|
|
27888
|
+
* must be 'true' or 'false', but was ''"
|
|
27889
|
+
* routing.http.response.server.enabled (Listener)
|
|
27890
|
+
* -> same rejection, same shape
|
|
27891
|
+
*
|
|
27892
|
+
* A rejection fails the whole Modify* call, so ONE removed boolean took the
|
|
27893
|
+
* entire deploy down (and then the rollback with it). Hence: send the
|
|
27894
|
+
* documented default for the validated keys, and keep the empty string for
|
|
27895
|
+
* everything else — which is both these APIs' own "clear the override"
|
|
27896
|
+
* signal and the behaviour every non-boolean key already relied on.
|
|
27897
|
+
*
|
|
27898
|
+
* That fallback is the deliberate DIVERGENCE from
|
|
27899
|
+
* TARGET_GROUP_ATTRIBUTE_DEFAULTS, whose unknown-key arm warns and retains:
|
|
27900
|
+
* there the empty string is never valid, here it is valid for the majority
|
|
27901
|
+
* of keys, so falling back to it preserves working behaviour instead of
|
|
27902
|
+
* silently retaining a value the template asked to drop.
|
|
27903
|
+
*
|
|
27904
|
+
* A key is listed ONLY when ONE unconditional default is established for it —
|
|
27905
|
+
* documented in the SDK model, or (for
|
|
27906
|
+
* `routing.http.response.server.enabled`, which the model leaves unstated)
|
|
27907
|
+
* proven by the `alb` integ's live removal readback. Two exclusion classes
|
|
27908
|
+
* matter, and both are the difference between failing loudly and writing a
|
|
27909
|
+
* wrong value silently:
|
|
27910
|
+
*
|
|
27911
|
+
* - **Default depends on the LOAD BALANCER** — `load_balancing.cross_zone.enabled`
|
|
27912
|
+
* is always-on and unconfigurable for an ALB but defaults to false on an
|
|
27913
|
+
* NLB / GWLB, and `ipv6.deny_all_igw_traffic` is "false for internet-facing
|
|
27914
|
+
* load balancers and true for internal load balancers". cdkd knows neither
|
|
27915
|
+
* the type nor the scheme at diff time, so a hardcoded entry would send the
|
|
27916
|
+
* WRONG value for half of all load balancers — and since it is a valid
|
|
27917
|
+
* boolean, AWS accepts it. For `ipv6.deny_all_igw_traffic` that means
|
|
27918
|
+
* silently un-blocking internet-gateway access on an INTERNAL load balancer.
|
|
27919
|
+
* - **No documented default at all** — `dns_record.client_routing_policy`
|
|
27920
|
+
* enumerates its possible values but states no default.
|
|
27921
|
+
*
|
|
27922
|
+
* Both classes keep the empty-string behaviour they have always had, so a
|
|
27923
|
+
* removal there fails loudly (for a validated key) instead of guessing.
|
|
27924
|
+
*
|
|
27925
|
+
* Source: the `@aws-sdk/client-elastic-load-balancing-v2` model docs for
|
|
27926
|
+
* `ModifyLoadBalancerAttributes` / `ModifyListenerAttributes`, checked per key;
|
|
27927
|
+
* `routing.http.response.server.enabled`'s default is additionally LIVE-proven
|
|
27928
|
+
* by the `alb` integ's removal readback rather than taken from the docs.
|
|
27929
|
+
*/
|
|
27930
|
+
const LOAD_BALANCER_ATTRIBUTE_DEFAULTS = {
|
|
27931
|
+
"deletion_protection.enabled": "false",
|
|
27932
|
+
"access_logs.s3.enabled": "false",
|
|
27933
|
+
"connection_logs.s3.enabled": "false",
|
|
27934
|
+
"health_check_logs.s3.enabled": "false",
|
|
27935
|
+
"routing.http.desync_mitigation_mode": "defensive",
|
|
27936
|
+
"routing.http.drop_invalid_header_fields.enabled": "false",
|
|
27937
|
+
"routing.http.preserve_host_header.enabled": "false",
|
|
27938
|
+
"routing.http.x_amzn_tls_version_and_cipher_suite.enabled": "false",
|
|
27939
|
+
"routing.http.xff_client_port.enabled": "false",
|
|
27940
|
+
"routing.http.xff_header_processing.mode": "append",
|
|
27941
|
+
"routing.http2.enabled": "true",
|
|
27942
|
+
"waf.fail_open.enabled": "false",
|
|
27943
|
+
"zonal_shift.config.enabled": "false"
|
|
27944
|
+
};
|
|
27945
|
+
/** @see LOAD_BALANCER_ATTRIBUTE_DEFAULTS — same rule, Listener key table. */
|
|
27946
|
+
const LISTENER_ATTRIBUTE_DEFAULTS = { "routing.http.response.server.enabled": "true" };
|
|
27947
|
+
/**
|
|
27876
27948
|
* AWS ELBv2 Provider
|
|
27877
27949
|
*
|
|
27878
27950
|
* Implements resource provisioning for ELBv2 resources:
|
|
@@ -28085,7 +28157,7 @@ var ELBv2Provider = class {
|
|
|
28085
28157
|
return out;
|
|
28086
28158
|
};
|
|
28087
28159
|
if (JSON.stringify(stripHandled(properties)) !== JSON.stringify(stripHandled(previousProperties))) throw new ResourceUpdateNotSupportedError("AWS::ElasticLoadBalancingV2::LoadBalancer", logicalId, "ELBv2 LoadBalancer Name / Type / Scheme are immutable on AWS — none of the ELBv2 Modify* / Set* APIs accept these fields; they are fixed at creation. cdkd handles LoadBalancerAttributes / Subnets / SubnetMappings / SecurityGroups / IpAddressType / Tags in-place; for Name / Type / Scheme re-deploy with cdkd deploy --replace, or destroy + redeploy the stack.");
|
|
28088
|
-
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["LoadBalancerAttributes"]), this.normalizeAttributes(previousProperties["LoadBalancerAttributes"]));
|
|
28160
|
+
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["LoadBalancerAttributes"]), this.normalizeAttributes(previousProperties["LoadBalancerAttributes"]), this.attributeRemovalResolver(LOAD_BALANCER_ATTRIBUTE_DEFAULTS));
|
|
28089
28161
|
if (submittedAttrs.length > 0) {
|
|
28090
28162
|
await this.getClient().send(new ModifyLoadBalancerAttributesCommand({
|
|
28091
28163
|
LoadBalancerArn: physicalId,
|
|
@@ -28309,10 +28381,13 @@ var ELBv2Provider = class {
|
|
|
28309
28381
|
UnhealthyThresholdCount: properties["UnhealthyThresholdCount"] !== void 0 ? Number(properties["UnhealthyThresholdCount"]) : void 0,
|
|
28310
28382
|
...matcher && { Matcher: matcher }
|
|
28311
28383
|
}));
|
|
28312
|
-
const tgAttrDiff = this.diffAttributes(this.normalizeAttributes(properties["TargetGroupAttributes"]), this.normalizeAttributes(previousProperties["TargetGroupAttributes"]), (key) => {
|
|
28313
|
-
const fallback = TARGET_GROUP_ATTRIBUTE_DEFAULTS[key];
|
|
28314
|
-
if (fallback === void 0)
|
|
28315
|
-
|
|
28384
|
+
const tgAttrDiff = this.diffAttributes(this.normalizeAttributes(properties["TargetGroupAttributes"]), this.normalizeAttributes(previousProperties["TargetGroupAttributes"]), (key, currentValue) => {
|
|
28385
|
+
const fallback = Object.hasOwn(TARGET_GROUP_ATTRIBUTE_DEFAULTS, key) ? TARGET_GROUP_ATTRIBUTE_DEFAULTS[key] : void 0;
|
|
28386
|
+
if (fallback === void 0) {
|
|
28387
|
+
this.logger.warn(`TargetGroup attribute ${key} was removed from the template but has no documented default cdkd can reset it to — the live value is retained. Set the attribute explicitly to change it.`);
|
|
28388
|
+
return;
|
|
28389
|
+
}
|
|
28390
|
+
return currentValue === fallback ? void 0 : fallback;
|
|
28316
28391
|
});
|
|
28317
28392
|
if (tgAttrDiff.length > 0) {
|
|
28318
28393
|
await this.getClient().send(new ModifyTargetGroupAttributesCommand({
|
|
@@ -28444,7 +28519,7 @@ var ELBv2Provider = class {
|
|
|
28444
28519
|
...alpnPolicy && alpnPolicy.length > 0 && { AlpnPolicy: alpnPolicy },
|
|
28445
28520
|
...mutualAuth !== void 0 && { MutualAuthentication: mutualAuth }
|
|
28446
28521
|
}));
|
|
28447
|
-
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["ListenerAttributes"]), this.normalizeAttributes(previousProperties["ListenerAttributes"]));
|
|
28522
|
+
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["ListenerAttributes"]), this.normalizeAttributes(previousProperties["ListenerAttributes"]), this.attributeRemovalResolver(LISTENER_ATTRIBUTE_DEFAULTS));
|
|
28448
28523
|
if (submittedAttrs.length > 0) {
|
|
28449
28524
|
await withRetry(() => this.getClient().send(new ModifyListenerAttributesCommand({
|
|
28450
28525
|
ListenerArn: physicalId,
|
|
@@ -28522,14 +28597,28 @@ var ELBv2Provider = class {
|
|
|
28522
28597
|
/**
|
|
28523
28598
|
* Key-diff two normalized `{Key, Value}` attribute lists into the payload
|
|
28524
28599
|
* for a Modify*Attributes call: changed values from `newAttrs` win, and
|
|
28525
|
-
* keys present only in `oldAttrs` are pushed back through `removalValue
|
|
28526
|
-
*
|
|
28527
|
-
*
|
|
28528
|
-
*
|
|
28529
|
-
*
|
|
28530
|
-
*
|
|
28531
|
-
|
|
28532
|
-
|
|
28600
|
+
* keys present only in `oldAttrs` are pushed back through `removalValue`.
|
|
28601
|
+
* A resolver returning `undefined` SKIPS the entry (the resolver owns any
|
|
28602
|
+
* warn). An empty return means nothing changed and the call should be
|
|
28603
|
+
* skipped. Shared by the LoadBalancer / TargetGroup / Listener update
|
|
28604
|
+
* paths — and all three pass their OWN resolver, because the three APIs
|
|
28605
|
+
* disagree about what resets an attribute:
|
|
28606
|
+
*
|
|
28607
|
+
* - LoadBalancer / Listener: the empty string clears a numeric or
|
|
28608
|
+
* free-form-string override, but a BOOLEAN / ENUM key rejects it and
|
|
28609
|
+
* fails the whole call, so those take a documented default
|
|
28610
|
+
* (`LOAD_BALANCER_ATTRIBUTE_DEFAULTS` / `LISTENER_ATTRIBUTE_DEFAULTS`).
|
|
28611
|
+
* - TargetGroup: the empty string is rejected for EVERY key, so the
|
|
28612
|
+
* documented default is the only reset and an unknown key warns and
|
|
28613
|
+
* retains (`TARGET_GROUP_ATTRIBUTE_DEFAULTS`).
|
|
28614
|
+
*
|
|
28615
|
+
* All three behaviours were live-verified 2026-08-11. `removalValue` is
|
|
28616
|
+
* REQUIRED rather than defaulted: there is no reset value that is correct
|
|
28617
|
+
* for all three APIs, so a caller that forgets to pass one should fail to
|
|
28618
|
+
* compile instead of silently inheriting the empty string that two of the
|
|
28619
|
+
* three reject.
|
|
28620
|
+
*/
|
|
28621
|
+
diffAttributes(newAttrs, oldAttrs, removalValue) {
|
|
28533
28622
|
const newAttrMap = new Map(newAttrs.map((a) => [a.Key, a.Value]));
|
|
28534
28623
|
const oldAttrMap = new Map(oldAttrs.map((a) => [a.Key, a.Value]));
|
|
28535
28624
|
const submitted = [];
|
|
@@ -28537,8 +28626,8 @@ var ELBv2Provider = class {
|
|
|
28537
28626
|
Key: k,
|
|
28538
28627
|
Value: v
|
|
28539
28628
|
});
|
|
28540
|
-
for (const [k] of oldAttrMap) if (!newAttrMap.has(k)) {
|
|
28541
|
-
const value = removalValue(k);
|
|
28629
|
+
for (const [k, currentValue] of oldAttrMap) if (!newAttrMap.has(k)) {
|
|
28630
|
+
const value = removalValue(k, currentValue);
|
|
28542
28631
|
if (value !== void 0) submitted.push({
|
|
28543
28632
|
Key: k,
|
|
28544
28633
|
Value: value
|
|
@@ -28547,6 +28636,40 @@ var ELBv2Provider = class {
|
|
|
28547
28636
|
return submitted;
|
|
28548
28637
|
}
|
|
28549
28638
|
/**
|
|
28639
|
+
* Build the `removalValue` resolver for the LoadBalancer / Listener attribute
|
|
28640
|
+
* arms: reset a removed key to its documented default, or to `''` (which
|
|
28641
|
+
* those two APIs accept as "clear the override") when no default is known.
|
|
28642
|
+
*
|
|
28643
|
+
* **A key already AT its default is SKIPPED, and that is a safety property,
|
|
28644
|
+
* not an optimization.** The previous side is not always a template: `cdkd
|
|
28645
|
+
* drift --revert` calls `update(..., newProperties, outcome.awsProperties)`
|
|
28646
|
+
* (`src/cli/commands/drift.ts`), so `oldAttrs` can be the FULL
|
|
28647
|
+
* `readCurrentState` snapshot — every attribute AWS reports, including the
|
|
28648
|
+
* ~18 the user never templated. Against a state record with no
|
|
28649
|
+
* `observedProperties` the desired side is the template's one or two keys,
|
|
28650
|
+
* so every untemplated key looks REMOVED and would be "reset".
|
|
28651
|
+
*
|
|
28652
|
+
* Writing a documented default there would silently disable deletion
|
|
28653
|
+
* protection, access / connection logs, HTTP/2, WAF fail-open and zonal
|
|
28654
|
+
* shift on a live load balancer. Before the defaults table existed this was
|
|
28655
|
+
* accidentally safe — `''` fails validation, so the whole revert aborted and
|
|
28656
|
+
* changed nothing — so introducing the table without this guard would have
|
|
28657
|
+
* converted a loud refusal into a silent destructive write.
|
|
28658
|
+
*
|
|
28659
|
+
* The skip is exact rather than heuristic: a key the user never templated is
|
|
28660
|
+
* BY DEFINITION sitting at its default, so it is skipped; a key the template
|
|
28661
|
+
* really did set is set to a NON-default value (otherwise templating it
|
|
28662
|
+
* would be a no-op), so its reset still fires. A template that set a key to
|
|
28663
|
+
* exactly its default and then dropped it is skipped too — correctly, since
|
|
28664
|
+
* there is nothing to change.
|
|
28665
|
+
*/
|
|
28666
|
+
attributeRemovalResolver(defaults) {
|
|
28667
|
+
return (key, currentValue) => {
|
|
28668
|
+
const fallback = Object.hasOwn(defaults, key) ? defaults[key] : "";
|
|
28669
|
+
return currentValue === fallback ? void 0 : fallback;
|
|
28670
|
+
};
|
|
28671
|
+
}
|
|
28672
|
+
/**
|
|
28550
28673
|
* Normalize a CFn `Targets` value (an array of `{ Id, Port?,
|
|
28551
28674
|
* AvailabilityZone? }` objects) into the SDK's `TargetDescription[]` shape.
|
|
28552
28675
|
* Entries missing an `Id` are dropped (Id is the only required member);
|
|
@@ -34664,6 +34787,7 @@ const MUTABLE_GRAPHQL_API_CONFIG_PROPERTIES = [
|
|
|
34664
34787
|
*/
|
|
34665
34788
|
var AppSyncProvider = class {
|
|
34666
34789
|
client;
|
|
34790
|
+
s3Client;
|
|
34667
34791
|
providerRegion = process.env["AWS_REGION"];
|
|
34668
34792
|
logger = getLogger().child("AppSyncProvider");
|
|
34669
34793
|
/**
|
|
@@ -34714,7 +34838,12 @@ var AppSyncProvider = class {
|
|
|
34714
34838
|
"ServiceRoleArn",
|
|
34715
34839
|
"DynamoDBConfig",
|
|
34716
34840
|
"LambdaConfig",
|
|
34717
|
-
"HttpConfig"
|
|
34841
|
+
"HttpConfig",
|
|
34842
|
+
"ElasticsearchConfig",
|
|
34843
|
+
"EventBridgeConfig",
|
|
34844
|
+
"MetricsConfig",
|
|
34845
|
+
"OpenSearchServiceConfig",
|
|
34846
|
+
"RelationalDatabaseConfig"
|
|
34718
34847
|
])],
|
|
34719
34848
|
["AWS::AppSync::Resolver", /* @__PURE__ */ new Set([
|
|
34720
34849
|
"ApiId",
|
|
@@ -34726,7 +34855,14 @@ var AppSyncProvider = class {
|
|
|
34726
34855
|
"Kind",
|
|
34727
34856
|
"PipelineConfig",
|
|
34728
34857
|
"Runtime",
|
|
34729
|
-
"Code"
|
|
34858
|
+
"Code",
|
|
34859
|
+
"CachingConfig",
|
|
34860
|
+
"CodeS3Location",
|
|
34861
|
+
"MaxBatchSize",
|
|
34862
|
+
"MetricsConfig",
|
|
34863
|
+
"RequestMappingTemplateS3Location",
|
|
34864
|
+
"ResponseMappingTemplateS3Location",
|
|
34865
|
+
"SyncConfig"
|
|
34730
34866
|
])],
|
|
34731
34867
|
["AWS::AppSync::ApiKey", /* @__PURE__ */ new Set([
|
|
34732
34868
|
"ApiId",
|
|
@@ -34734,11 +34870,23 @@ var AppSyncProvider = class {
|
|
|
34734
34870
|
"Expires"
|
|
34735
34871
|
])]
|
|
34736
34872
|
]);
|
|
34737
|
-
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::AppSync::DataSource", /* @__PURE__ */ new Map([["ElasticsearchConfig", "Legacy Elasticsearch alias; use OpenSearchServiceConfig (AppSync deprecated the Elasticsearch DataSource type in favor of OpenSearch)"]])]]);
|
|
34738
34873
|
getClient() {
|
|
34739
34874
|
if (!this.client) this.client = new AppSyncClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
34740
34875
|
return this.client;
|
|
34741
34876
|
}
|
|
34877
|
+
/**
|
|
34878
|
+
* Lazy S3 client for the `*S3Location` properties (Resolver
|
|
34879
|
+
* `CodeS3Location` / `RequestMappingTemplateS3Location` /
|
|
34880
|
+
* `ResponseMappingTemplateS3Location`, GraphQLSchema
|
|
34881
|
+
* `DefinitionS3Location`) — CloudFormation reads the S3 object and inlines
|
|
34882
|
+
* its body, and cdkd mirrors that. Same construction as
|
|
34883
|
+
* `StepFunctionsProvider.getS3Client` (the sibling `DefinitionS3Location`
|
|
34884
|
+
* implementation).
|
|
34885
|
+
*/
|
|
34886
|
+
getS3Client() {
|
|
34887
|
+
if (!this.s3Client) this.s3Client = new S3Client(this.providerRegion ? { region: this.providerRegion } : {});
|
|
34888
|
+
return this.s3Client;
|
|
34889
|
+
}
|
|
34742
34890
|
async create(logicalId, resourceType, properties, context) {
|
|
34743
34891
|
switch (resourceType) {
|
|
34744
34892
|
case "AWS::AppSync::GraphQLApi": return this.createGraphQLApi(logicalId, resourceType, properties, context);
|
|
@@ -34757,11 +34905,16 @@ var AppSyncProvider = class {
|
|
|
34757
34905
|
* `XrayEnabled` / `LogConfig`) + `TagResource` / `UntagResource`
|
|
34758
34906
|
* for `Tags` diff. `Name` is immutable on AWS.
|
|
34759
34907
|
* - `DataSource` → `UpdateDataSourceCommand` (`Description` /
|
|
34760
|
-
* `ServiceRoleArn` /
|
|
34908
|
+
* `ServiceRoleArn` / the per-type configs — `DynamoDBConfig` /
|
|
34909
|
+
* `LambdaConfig` / `HttpConfig` / `ElasticsearchConfig` /
|
|
34910
|
+
* `OpenSearchServiceConfig` / `EventBridgeConfig` /
|
|
34911
|
+
* `RelationalDatabaseConfig` — / `MetricsConfig`).
|
|
34761
34912
|
* `ApiId` / `Name` / `Type` are immutable identity fields.
|
|
34762
34913
|
* - `Resolver` → `UpdateResolverCommand` (`DataSourceName` /
|
|
34763
34914
|
* `RequestMappingTemplate` / `ResponseMappingTemplate` / `Kind` /
|
|
34764
|
-
* `PipelineConfig` / `Runtime` / `Code`
|
|
34915
|
+
* `PipelineConfig` / `Runtime` / `Code` / `CachingConfig` /
|
|
34916
|
+
* `SyncConfig` / `MaxBatchSize` / `MetricsConfig` + the three
|
|
34917
|
+
* `*S3Location` fetch-and-inline pairs). `ApiId` / `TypeName` /
|
|
34765
34918
|
* `FieldName` are immutable identity fields.
|
|
34766
34919
|
* - `ApiKey` → `UpdateApiKeyCommand` (`Description` / `Expires`).
|
|
34767
34920
|
* `ApiId` is immutable; the AWS-generated key id is immutable.
|
|
@@ -34853,7 +35006,23 @@ var AppSyncProvider = class {
|
|
|
34853
35006
|
async updateGraphQLSchema(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
34854
35007
|
const newDef = properties["Definition"];
|
|
34855
35008
|
const oldDef = previousProperties["Definition"];
|
|
34856
|
-
|
|
35009
|
+
const newLoc = properties["DefinitionS3Location"];
|
|
35010
|
+
const oldLoc = previousProperties["DefinitionS3Location"];
|
|
35011
|
+
let definition;
|
|
35012
|
+
if (newDef !== void 0) {
|
|
35013
|
+
if (newLoc !== void 0) this.logger.warn(`${resourceType} ${logicalId}: both Definition and DefinitionS3Location are set — using the inline Definition and ignoring DefinitionS3Location (CFn treats them as alternatives)`);
|
|
35014
|
+
if (newDef === oldDef) return {
|
|
35015
|
+
physicalId,
|
|
35016
|
+
wasReplaced: false
|
|
35017
|
+
};
|
|
35018
|
+
definition = newDef;
|
|
35019
|
+
} else if (newLoc !== void 0) {
|
|
35020
|
+
if (this.deepEqual(newLoc, oldLoc)) return {
|
|
35021
|
+
physicalId,
|
|
35022
|
+
wasReplaced: false
|
|
35023
|
+
};
|
|
35024
|
+
definition = await this.fetchS3LocationBody(newLoc, resourceType, logicalId, "DefinitionS3Location");
|
|
35025
|
+
} else return {
|
|
34857
35026
|
physicalId,
|
|
34858
35027
|
wasReplaced: false
|
|
34859
35028
|
};
|
|
@@ -34861,7 +35030,7 @@ var AppSyncProvider = class {
|
|
|
34861
35030
|
try {
|
|
34862
35031
|
await this.getClient().send(new StartSchemaCreationCommand({
|
|
34863
35032
|
apiId,
|
|
34864
|
-
definition: Buffer.from(
|
|
35033
|
+
definition: Buffer.from(definition, "utf-8")
|
|
34865
35034
|
}));
|
|
34866
35035
|
} catch (error) {
|
|
34867
35036
|
throw this.wrapUpdateError(error, resourceType, logicalId, physicalId, "GraphqlSchema");
|
|
@@ -34884,17 +35053,18 @@ var AppSyncProvider = class {
|
|
|
34884
35053
|
const [apiId, name] = physicalId.split("|");
|
|
34885
35054
|
if (!apiId || !name) throw new ProvisioningError(`Invalid DataSource physical ID format: ${physicalId}`, resourceType, logicalId, physicalId);
|
|
34886
35055
|
const type = properties["Type"] ?? previousProperties["Type"];
|
|
34887
|
-
|
|
34888
|
-
|
|
34889
|
-
|
|
34890
|
-
|
|
34891
|
-
|
|
34892
|
-
|
|
34893
|
-
|
|
34894
|
-
|
|
34895
|
-
|
|
34896
|
-
|
|
34897
|
-
|
|
35056
|
+
if (![
|
|
35057
|
+
"Description",
|
|
35058
|
+
"ServiceRoleArn",
|
|
35059
|
+
"DynamoDBConfig",
|
|
35060
|
+
"LambdaConfig",
|
|
35061
|
+
"HttpConfig",
|
|
35062
|
+
"ElasticsearchConfig",
|
|
35063
|
+
"OpenSearchServiceConfig",
|
|
35064
|
+
"EventBridgeConfig",
|
|
35065
|
+
"RelationalDatabaseConfig",
|
|
35066
|
+
"MetricsConfig"
|
|
35067
|
+
].some((key) => (key in properties || key in previousProperties) && !this.deepEqual(properties[key], previousProperties[key]))) return {
|
|
34898
35068
|
physicalId,
|
|
34899
35069
|
wasReplaced: false
|
|
34900
35070
|
};
|
|
@@ -34903,15 +35073,7 @@ var AppSyncProvider = class {
|
|
|
34903
35073
|
name,
|
|
34904
35074
|
type
|
|
34905
35075
|
};
|
|
34906
|
-
|
|
34907
|
-
if (newRole !== void 0) input.serviceRoleArn = newRole;
|
|
34908
|
-
if (newDDB !== void 0) input.dynamodbConfig = {
|
|
34909
|
-
tableName: newDDB["TableName"],
|
|
34910
|
-
awsRegion: newDDB["AwsRegion"],
|
|
34911
|
-
useCallerCredentials: newDDB["UseCallerCredentials"]
|
|
34912
|
-
};
|
|
34913
|
-
if (newLambda !== void 0) input.lambdaConfig = { lambdaFunctionArn: newLambda["LambdaFunctionArn"] };
|
|
34914
|
-
if (newHttp !== void 0) input.httpConfig = { endpoint: newHttp["Endpoint"] };
|
|
35076
|
+
this.applyDataSourceConfig(input, resourceType, logicalId, properties);
|
|
34915
35077
|
try {
|
|
34916
35078
|
await this.getClient().send(new UpdateDataSourceCommand(input));
|
|
34917
35079
|
} catch (error) {
|
|
@@ -34942,8 +35104,15 @@ var AppSyncProvider = class {
|
|
|
34942
35104
|
"Kind",
|
|
34943
35105
|
"PipelineConfig",
|
|
34944
35106
|
"Runtime",
|
|
34945
|
-
"Code"
|
|
34946
|
-
|
|
35107
|
+
"Code",
|
|
35108
|
+
"CachingConfig",
|
|
35109
|
+
"SyncConfig",
|
|
35110
|
+
"MaxBatchSize",
|
|
35111
|
+
"MetricsConfig",
|
|
35112
|
+
"CodeS3Location",
|
|
35113
|
+
"RequestMappingTemplateS3Location",
|
|
35114
|
+
"ResponseMappingTemplateS3Location"
|
|
35115
|
+
].some((key) => (key in properties || key in previousProperties) && !this.deepEqual(properties[key], previousProperties[key]))) return {
|
|
34947
35116
|
physicalId,
|
|
34948
35117
|
wasReplaced: false
|
|
34949
35118
|
};
|
|
@@ -34952,20 +35121,7 @@ var AppSyncProvider = class {
|
|
|
34952
35121
|
typeName,
|
|
34953
35122
|
fieldName
|
|
34954
35123
|
};
|
|
34955
|
-
|
|
34956
|
-
if (effectiveKind === "UNIT" && properties["DataSourceName"] !== void 0) input.dataSourceName = properties["DataSourceName"];
|
|
34957
|
-
if (properties["RequestMappingTemplate"] !== void 0) input.requestMappingTemplate = properties["RequestMappingTemplate"];
|
|
34958
|
-
if (properties["ResponseMappingTemplate"] !== void 0) input.responseMappingTemplate = properties["ResponseMappingTemplate"];
|
|
34959
|
-
if (properties["Kind"] !== void 0) input.kind = properties["Kind"];
|
|
34960
|
-
if (effectiveKind === "PIPELINE" && properties["PipelineConfig"] !== void 0) input.pipelineConfig = { functions: properties["PipelineConfig"]["Functions"] };
|
|
34961
|
-
if (properties["Runtime"] !== void 0) {
|
|
34962
|
-
const runtime = properties["Runtime"];
|
|
34963
|
-
input.runtime = {
|
|
34964
|
-
name: runtime["Name"],
|
|
34965
|
-
runtimeVersion: runtime["RuntimeVersion"]
|
|
34966
|
-
};
|
|
34967
|
-
}
|
|
34968
|
-
if (properties["Code"] !== void 0) input.code = properties["Code"];
|
|
35124
|
+
await this.applyResolverConfig(input, resourceType, logicalId, properties, previousProperties, true);
|
|
34969
35125
|
try {
|
|
34970
35126
|
await this.getClient().send(new UpdateResolverCommand(input));
|
|
34971
35127
|
} catch (error) {
|
|
@@ -35086,6 +35242,11 @@ var AppSyncProvider = class {
|
|
|
35086
35242
|
*/
|
|
35087
35243
|
getDriftUnknownPaths(resourceType) {
|
|
35088
35244
|
if (resourceType === "AWS::AppSync::GraphQLSchema") return ["DefinitionS3Location"];
|
|
35245
|
+
if (resourceType === "AWS::AppSync::Resolver") return [
|
|
35246
|
+
"CodeS3Location",
|
|
35247
|
+
"RequestMappingTemplateS3Location",
|
|
35248
|
+
"ResponseMappingTemplateS3Location"
|
|
35249
|
+
];
|
|
35089
35250
|
return [];
|
|
35090
35251
|
}
|
|
35091
35252
|
/**
|
|
@@ -35098,15 +35259,15 @@ var AppSyncProvider = class {
|
|
|
35098
35259
|
* possibly-malformed value"). An ABSENT container keeps returning
|
|
35099
35260
|
* `undefined`, which is a legitimate "not configured".
|
|
35100
35261
|
*/
|
|
35101
|
-
asObject(value, path, options) {
|
|
35262
|
+
asObject(value, path, options, resourceType = "AWS::AppSync::GraphQLApi") {
|
|
35102
35263
|
if (value == null) return void 0;
|
|
35103
35264
|
if (typeof value === "object" && !Array.isArray(value)) return value;
|
|
35104
|
-
const message =
|
|
35265
|
+
const message = `${resourceType} ${path} must be an object, got ${Array.isArray(value) ? "array" : typeof value} — cdkd refuses to drop it silently`;
|
|
35105
35266
|
if (options?.onUnusable) {
|
|
35106
35267
|
options.onUnusable(message);
|
|
35107
35268
|
return;
|
|
35108
35269
|
}
|
|
35109
|
-
throw new ProvisioningError(message,
|
|
35270
|
+
throw new ProvisioningError(message, resourceType, options?.logicalId ?? "");
|
|
35110
35271
|
}
|
|
35111
35272
|
/**
|
|
35112
35273
|
* NOTE: `awsRegion` / `defaultAction` are passed through VERBATIM, including
|
|
@@ -35284,6 +35445,211 @@ var AppSyncProvider = class {
|
|
|
35284
35445
|
throw this.wrapUpdateError(error, resourceType, logicalId, apiId, isUpdate ? "GraphqlApi (env vars)" : "GraphqlApi (env vars, post-create)");
|
|
35285
35446
|
}
|
|
35286
35447
|
}
|
|
35448
|
+
/** CFn `CachingConfig` (`Ttl` / `CachingKeys`) -> SDK `cachingConfig`. */
|
|
35449
|
+
toSdkCachingConfig(value, logicalId) {
|
|
35450
|
+
const cfn = this.asObject(value, "CachingConfig", { logicalId }, "AWS::AppSync::Resolver");
|
|
35451
|
+
if (!cfn) return void 0;
|
|
35452
|
+
const out = { ttl: cfn["Ttl"] };
|
|
35453
|
+
if (cfn["CachingKeys"] !== void 0) out.cachingKeys = requireConfigArray(cfn["CachingKeys"], "AWS::AppSync::Resolver CachingConfig.CachingKeys");
|
|
35454
|
+
return out;
|
|
35455
|
+
}
|
|
35456
|
+
/**
|
|
35457
|
+
* CFn `SyncConfig` (`ConflictDetection` / `ConflictHandler` /
|
|
35458
|
+
* `LambdaConflictHandlerConfig.LambdaConflictHandlerArn`) -> SDK
|
|
35459
|
+
* `syncConfig`.
|
|
35460
|
+
*/
|
|
35461
|
+
toSdkSyncConfig(value, logicalId) {
|
|
35462
|
+
const cfn = this.asObject(value, "SyncConfig", { logicalId }, "AWS::AppSync::Resolver");
|
|
35463
|
+
if (!cfn) return void 0;
|
|
35464
|
+
const out = {};
|
|
35465
|
+
if (cfn["ConflictDetection"] !== void 0) out.conflictDetection = cfn["ConflictDetection"];
|
|
35466
|
+
if (cfn["ConflictHandler"] !== void 0) out.conflictHandler = cfn["ConflictHandler"];
|
|
35467
|
+
const lambdaHandler = this.asObject(cfn["LambdaConflictHandlerConfig"], "SyncConfig.LambdaConflictHandlerConfig", { logicalId }, "AWS::AppSync::Resolver");
|
|
35468
|
+
if (lambdaHandler) out.lambdaConflictHandlerConfig = { lambdaConflictHandlerArn: lambdaHandler["LambdaConflictHandlerArn"] };
|
|
35469
|
+
return out;
|
|
35470
|
+
}
|
|
35471
|
+
/**
|
|
35472
|
+
* Parse the `s3://bucket/key` URL the AppSync `*S3Location` string
|
|
35473
|
+
* properties carry.
|
|
35474
|
+
*
|
|
35475
|
+
* CDK's asset bindings (`appsync.Code.fromAsset`, `aws-s3-assets` Asset
|
|
35476
|
+
* `s3ObjectUrl`) emit exactly this form, and the CloudFormation examples
|
|
35477
|
+
* for these properties use it too. Anything else (an `https://` object
|
|
35478
|
+
* URL, a bare bucket, a non-string) is refused with a clear error naming
|
|
35479
|
+
* the property — never silently dropped.
|
|
35480
|
+
*/
|
|
35481
|
+
parseS3LocationUrl(location, resourceType, logicalId, propertyPath) {
|
|
35482
|
+
if (typeof location !== "string") throw new ProvisioningError(`${resourceType} ${propertyPath} must be a string s3://bucket/key URL, got ${Array.isArray(location) ? "array" : typeof location} — check for an unresolved intrinsic`, resourceType, logicalId);
|
|
35483
|
+
const match = /^s3:\/\/([^/]+)\/(.+)$/.exec(location);
|
|
35484
|
+
if (!match || !match[1] || !match[2]) throw new ProvisioningError(`${resourceType} ${propertyPath} must be an s3://bucket/key URL (got '${location}')`, resourceType, logicalId);
|
|
35485
|
+
return {
|
|
35486
|
+
bucket: match[1],
|
|
35487
|
+
key: match[2]
|
|
35488
|
+
};
|
|
35489
|
+
}
|
|
35490
|
+
/**
|
|
35491
|
+
* Fetch an `*S3Location` object body as a UTF-8 string.
|
|
35492
|
+
*
|
|
35493
|
+
* CloudFormation's behavior for these properties is to download the S3
|
|
35494
|
+
* object and pass its CONTENT as the corresponding inline member
|
|
35495
|
+
* (`code` / `requestMappingTemplate` / `responseMappingTemplate` /
|
|
35496
|
+
* `definition`); the URL itself never reaches AppSync. Mirrors
|
|
35497
|
+
* `StepFunctionsProvider.fetchDefinitionFromS3`, including the
|
|
35498
|
+
* empty-body refusal (AWS would reject '' with a generic validation
|
|
35499
|
+
* error naming nothing).
|
|
35500
|
+
*/
|
|
35501
|
+
async fetchS3LocationBody(location, resourceType, logicalId, propertyPath) {
|
|
35502
|
+
const { bucket, key } = this.parseS3LocationUrl(location, resourceType, logicalId, propertyPath);
|
|
35503
|
+
this.logger.debug(`Fetching ${propertyPath} for ${logicalId} from s3://${bucket}/${key}`);
|
|
35504
|
+
let body;
|
|
35505
|
+
try {
|
|
35506
|
+
const resp = await this.getS3Client().send(new GetObjectCommand({
|
|
35507
|
+
Bucket: bucket,
|
|
35508
|
+
Key: key
|
|
35509
|
+
}));
|
|
35510
|
+
if (!resp.Body) throw new Error(`object returned no body`);
|
|
35511
|
+
body = await resp.Body.transformToString();
|
|
35512
|
+
} catch (error) {
|
|
35513
|
+
if (error instanceof ProvisioningError) throw error;
|
|
35514
|
+
throw new ProvisioningError(`Failed to fetch ${propertyPath} s3://${bucket}/${key} for ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, error instanceof Error ? error : void 0);
|
|
35515
|
+
}
|
|
35516
|
+
if (body.length === 0) throw new ProvisioningError(`${propertyPath} object s3://${bucket}/${key} returned an empty body`, resourceType, logicalId);
|
|
35517
|
+
return body;
|
|
35518
|
+
}
|
|
35519
|
+
/**
|
|
35520
|
+
* Resolve an inline-or-S3 property pair to the inline SDK value.
|
|
35521
|
+
*
|
|
35522
|
+
* Precedence: the INLINE property wins when both are present, matching
|
|
35523
|
+
* the repo's established S3Location precedent (StepFunctions
|
|
35524
|
+
* `DefinitionString` over `DefinitionS3Location`, AppSync GraphQLSchema
|
|
35525
|
+
* `Definition` over `DefinitionS3Location`) — CFn treats the pair as
|
|
35526
|
+
* alternatives and CDK's bindings only ever emit one, so both-present is
|
|
35527
|
+
* a hand-authored template; it is honored inline-first with a loud
|
|
35528
|
+
* warning rather than refused.
|
|
35529
|
+
*/
|
|
35530
|
+
async resolveInlineOrS3Template(inline, s3Location, inlineKey, s3Key, resourceType, logicalId) {
|
|
35531
|
+
if (inline !== void 0) {
|
|
35532
|
+
if (s3Location !== void 0) this.logger.warn(`${resourceType} ${logicalId}: both ${inlineKey} and ${s3Key} are set — using the inline ${inlineKey} and ignoring ${s3Key} (CFn treats them as alternatives)`);
|
|
35533
|
+
return inline;
|
|
35534
|
+
}
|
|
35535
|
+
if (s3Location !== void 0) return this.fetchS3LocationBody(s3Location, resourceType, logicalId, s3Key);
|
|
35536
|
+
}
|
|
35537
|
+
/**
|
|
35538
|
+
* Fill the mutable members shared by `CreateResolver` and `UpdateResolver`
|
|
35539
|
+
* from the CFn property bag — the single mapper both paths use so they
|
|
35540
|
+
* cannot diverge (the `applyGraphQLApiConfig` pattern).
|
|
35541
|
+
*
|
|
35542
|
+
* REMOVAL semantics: unlike `UpdateGraphqlApi` (where an omitted member is
|
|
35543
|
+
* "no change" and removal needs reset sentinels), `UpdateResolver` is a
|
|
35544
|
+
* FULL-REPLACE write — the desired bag is mapped in its entirety and an
|
|
35545
|
+
* omitted member is cleared server-side, so "absent in template => omitted
|
|
35546
|
+
* from the update input => cleared by AppSync" and no sentinel is needed.
|
|
35547
|
+
* That semantic is pinned live by the integ fixture's REMOVAL phase
|
|
35548
|
+
* (tests/integration/appsync/verify.sh drops the resolver's MetricsConfig
|
|
35549
|
+
* and asserts AWS reset it while a sibling DataSource keeps its own).
|
|
35550
|
+
* MetricsConfig is the one member A/B'd against real AWS; the other
|
|
35551
|
+
* members rest on the same UpdateResolver full-replace API contract, not
|
|
35552
|
+
* on a per-member live probe (the #1160 doctrine's per-member A/B was
|
|
35553
|
+
* deliberately not paid here — recorded in the PR body).
|
|
35554
|
+
*
|
|
35555
|
+
* Resolver shape is `Kind`-discriminated:
|
|
35556
|
+
* - Kind=UNIT -> DataSourceName applies, PipelineConfig is N/A.
|
|
35557
|
+
* - Kind=PIPELINE -> PipelineConfig applies, DataSourceName is N/A
|
|
35558
|
+
* (AWS rejects the call if it's set).
|
|
35559
|
+
* The gate applies ONLY on update (`forUpdate`), where the effective Kind
|
|
35560
|
+
* falls back to the state-recorded previous value and finally AWS's
|
|
35561
|
+
* default 'UNIT' — an update must not re-send the other kind's member on a
|
|
35562
|
+
* live resolver. On CREATE both members forward UNCONDITIONALLY when
|
|
35563
|
+
* present: gating there would silently drop a crossed shape (the very
|
|
35564
|
+
* silent-drop class this batch closes) where CFn parity is AWS's own loud
|
|
35565
|
+
* rejection — the same forward-don't-gate doctrine as
|
|
35566
|
+
* `applyDataSourceConfig`'s per-type sub-configs.
|
|
35567
|
+
*/
|
|
35568
|
+
async applyResolverConfig(input, resourceType, logicalId, properties, previousProperties, forUpdate = false) {
|
|
35569
|
+
const effectiveKind = properties["Kind"] ?? previousProperties?.["Kind"] ?? "UNIT";
|
|
35570
|
+
if ((!forUpdate || effectiveKind === "UNIT") && properties["DataSourceName"] !== void 0) input.dataSourceName = properties["DataSourceName"];
|
|
35571
|
+
if (properties["Kind"] !== void 0) input.kind = properties["Kind"];
|
|
35572
|
+
if ((!forUpdate || effectiveKind === "PIPELINE") && properties["PipelineConfig"] !== void 0) input.pipelineConfig = { functions: properties["PipelineConfig"]["Functions"] };
|
|
35573
|
+
if (properties["Runtime"] !== void 0) {
|
|
35574
|
+
const runtime = properties["Runtime"];
|
|
35575
|
+
input.runtime = {
|
|
35576
|
+
name: runtime["Name"],
|
|
35577
|
+
runtimeVersion: runtime["RuntimeVersion"]
|
|
35578
|
+
};
|
|
35579
|
+
}
|
|
35580
|
+
const requestTemplate = await this.resolveInlineOrS3Template(properties["RequestMappingTemplate"], properties["RequestMappingTemplateS3Location"], "RequestMappingTemplate", "RequestMappingTemplateS3Location", resourceType, logicalId);
|
|
35581
|
+
if (requestTemplate !== void 0) input.requestMappingTemplate = requestTemplate;
|
|
35582
|
+
const responseTemplate = await this.resolveInlineOrS3Template(properties["ResponseMappingTemplate"], properties["ResponseMappingTemplateS3Location"], "ResponseMappingTemplate", "ResponseMappingTemplateS3Location", resourceType, logicalId);
|
|
35583
|
+
if (responseTemplate !== void 0) input.responseMappingTemplate = responseTemplate;
|
|
35584
|
+
const code = await this.resolveInlineOrS3Template(properties["Code"], properties["CodeS3Location"], "Code", "CodeS3Location", resourceType, logicalId);
|
|
35585
|
+
if (code !== void 0) input.code = code;
|
|
35586
|
+
const caching = this.toSdkCachingConfig(properties["CachingConfig"], logicalId);
|
|
35587
|
+
if (caching) input.cachingConfig = caching;
|
|
35588
|
+
const sync = this.toSdkSyncConfig(properties["SyncConfig"], logicalId);
|
|
35589
|
+
if (sync) input.syncConfig = sync;
|
|
35590
|
+
if (properties["MaxBatchSize"] !== void 0) input.maxBatchSize = properties["MaxBatchSize"];
|
|
35591
|
+
if (properties["MetricsConfig"] !== void 0) input.metricsConfig = properties["MetricsConfig"];
|
|
35592
|
+
}
|
|
35593
|
+
/**
|
|
35594
|
+
* Fill the mutable members shared by `CreateDataSource` and
|
|
35595
|
+
* `UpdateDataSource` from the CFn property bag — single mapper for both
|
|
35596
|
+
* paths (the `applyGraphQLApiConfig` pattern).
|
|
35597
|
+
*
|
|
35598
|
+
* REMOVAL semantics: `UpdateDataSource` is a FULL-REPLACE write like
|
|
35599
|
+
* `UpdateResolver` — an omitted member is cleared server-side, so removal
|
|
35600
|
+
* needs no reset sentinel (see `applyResolverConfig`'s note; pinned live
|
|
35601
|
+
* by the integ fixture's REMOVAL phase).
|
|
35602
|
+
*
|
|
35603
|
+
* The per-type sub-configs (`DynamoDBConfig` / `LambdaConfig` /
|
|
35604
|
+
* `HttpConfig` / `ElasticsearchConfig` / `OpenSearchServiceConfig` /
|
|
35605
|
+
* `EventBridgeConfig` / `RelationalDatabaseConfig`) are mutually exclusive
|
|
35606
|
+
* on the `Type` discriminator. The write side deliberately FORWARDS
|
|
35607
|
+
* whichever block the template carries rather than gating on `Type`:
|
|
35608
|
+
* gating would silently drop a mismatched block (the very silent-drop
|
|
35609
|
+
* class this batch closes), while AWS rejects a crossed shape with a loud
|
|
35610
|
+
* validation error. The read side (`readDataSource`) gates on the
|
|
35611
|
+
* response's own discriminator instead.
|
|
35612
|
+
*/
|
|
35613
|
+
applyDataSourceConfig(input, resourceType, logicalId, properties) {
|
|
35614
|
+
if (properties["Description"] !== void 0) input.description = properties["Description"];
|
|
35615
|
+
if (properties["ServiceRoleArn"] !== void 0) input.serviceRoleArn = properties["ServiceRoleArn"];
|
|
35616
|
+
const dynamo = this.asObject(properties["DynamoDBConfig"], "DynamoDBConfig", { logicalId }, resourceType);
|
|
35617
|
+
if (dynamo) input.dynamodbConfig = {
|
|
35618
|
+
tableName: dynamo["TableName"],
|
|
35619
|
+
awsRegion: dynamo["AwsRegion"],
|
|
35620
|
+
...dynamo["UseCallerCredentials"] !== void 0 ? { useCallerCredentials: dynamo["UseCallerCredentials"] } : {}
|
|
35621
|
+
};
|
|
35622
|
+
const lambda = this.asObject(properties["LambdaConfig"], "LambdaConfig", { logicalId }, resourceType);
|
|
35623
|
+
if (lambda) input.lambdaConfig = { lambdaFunctionArn: lambda["LambdaFunctionArn"] };
|
|
35624
|
+
const http = this.asObject(properties["HttpConfig"], "HttpConfig", { logicalId }, resourceType);
|
|
35625
|
+
if (http) input.httpConfig = { endpoint: http["Endpoint"] };
|
|
35626
|
+
const es = this.asObject(properties["ElasticsearchConfig"], "ElasticsearchConfig", { logicalId }, resourceType);
|
|
35627
|
+
if (es) input.elasticsearchConfig = {
|
|
35628
|
+
endpoint: es["Endpoint"],
|
|
35629
|
+
awsRegion: es["AwsRegion"]
|
|
35630
|
+
};
|
|
35631
|
+
const openSearch = this.asObject(properties["OpenSearchServiceConfig"], "OpenSearchServiceConfig", { logicalId }, resourceType);
|
|
35632
|
+
if (openSearch) input.openSearchServiceConfig = {
|
|
35633
|
+
endpoint: openSearch["Endpoint"],
|
|
35634
|
+
awsRegion: openSearch["AwsRegion"]
|
|
35635
|
+
};
|
|
35636
|
+
const eventBridge = this.asObject(properties["EventBridgeConfig"], "EventBridgeConfig", { logicalId }, resourceType);
|
|
35637
|
+
if (eventBridge) input.eventBridgeConfig = { eventBusArn: eventBridge["EventBusArn"] };
|
|
35638
|
+
const relational = this.asObject(properties["RelationalDatabaseConfig"], "RelationalDatabaseConfig", { logicalId }, resourceType);
|
|
35639
|
+
if (relational) {
|
|
35640
|
+
const rdsConfig = { relationalDatabaseSourceType: relational["RelationalDatabaseSourceType"] };
|
|
35641
|
+
const rdsEndpoint = this.asObject(relational["RdsHttpEndpointConfig"], "RelationalDatabaseConfig.RdsHttpEndpointConfig", { logicalId }, resourceType);
|
|
35642
|
+
if (rdsEndpoint) rdsConfig.rdsHttpEndpointConfig = {
|
|
35643
|
+
awsRegion: rdsEndpoint["AwsRegion"],
|
|
35644
|
+
dbClusterIdentifier: rdsEndpoint["DbClusterIdentifier"],
|
|
35645
|
+
...rdsEndpoint["DatabaseName"] !== void 0 ? { databaseName: rdsEndpoint["DatabaseName"] } : {},
|
|
35646
|
+
...rdsEndpoint["Schema"] !== void 0 ? { schema: rdsEndpoint["Schema"] } : {},
|
|
35647
|
+
...rdsEndpoint["AwsSecretStoreArn"] !== void 0 ? { awsSecretStoreArn: rdsEndpoint["AwsSecretStoreArn"] } : {}
|
|
35648
|
+
};
|
|
35649
|
+
input.relationalDatabaseConfig = rdsConfig;
|
|
35650
|
+
}
|
|
35651
|
+
if (properties["MetricsConfig"] !== void 0) input.metricsConfig = properties["MetricsConfig"];
|
|
35652
|
+
}
|
|
35287
35653
|
async createGraphQLApi(logicalId, resourceType, properties, context) {
|
|
35288
35654
|
this.logger.debug(`Creating GraphQL API ${logicalId}`);
|
|
35289
35655
|
const name = properties["Name"];
|
|
@@ -35368,11 +35734,19 @@ var AppSyncProvider = class {
|
|
|
35368
35734
|
const definition = properties["Definition"];
|
|
35369
35735
|
const definitionS3Location = properties["DefinitionS3Location"];
|
|
35370
35736
|
try {
|
|
35371
|
-
if (definition)
|
|
35372
|
-
|
|
35373
|
-
|
|
35374
|
-
|
|
35375
|
-
|
|
35737
|
+
if (definition) {
|
|
35738
|
+
if (definitionS3Location !== void 0) this.logger.warn(`${resourceType} ${logicalId}: both Definition and DefinitionS3Location are set — using the inline Definition and ignoring DefinitionS3Location (CFn treats them as alternatives)`);
|
|
35739
|
+
await this.getClient().send(new StartSchemaCreationCommand({
|
|
35740
|
+
apiId,
|
|
35741
|
+
definition: new TextEncoder().encode(definition)
|
|
35742
|
+
}));
|
|
35743
|
+
} else if (definitionS3Location !== void 0) {
|
|
35744
|
+
const body = await this.fetchS3LocationBody(definitionS3Location, resourceType, logicalId, "DefinitionS3Location");
|
|
35745
|
+
await this.getClient().send(new StartSchemaCreationCommand({
|
|
35746
|
+
apiId,
|
|
35747
|
+
definition: new TextEncoder().encode(body)
|
|
35748
|
+
}));
|
|
35749
|
+
}
|
|
35376
35750
|
this.logger.debug(`Successfully started schema creation for ${logicalId}`);
|
|
35377
35751
|
return {
|
|
35378
35752
|
physicalId: apiId,
|
|
@@ -35395,18 +35769,7 @@ var AppSyncProvider = class {
|
|
|
35395
35769
|
name,
|
|
35396
35770
|
type
|
|
35397
35771
|
};
|
|
35398
|
-
|
|
35399
|
-
if (properties["ServiceRoleArn"]) input.serviceRoleArn = properties["ServiceRoleArn"];
|
|
35400
|
-
if (properties["DynamoDBConfig"]) {
|
|
35401
|
-
const config = properties["DynamoDBConfig"];
|
|
35402
|
-
input.dynamodbConfig = {
|
|
35403
|
-
tableName: config["TableName"],
|
|
35404
|
-
awsRegion: config["AwsRegion"],
|
|
35405
|
-
useCallerCredentials: config["UseCallerCredentials"]
|
|
35406
|
-
};
|
|
35407
|
-
}
|
|
35408
|
-
if (properties["LambdaConfig"]) input.lambdaConfig = { lambdaFunctionArn: properties["LambdaConfig"]["LambdaFunctionArn"] };
|
|
35409
|
-
if (properties["HttpConfig"]) input.httpConfig = { endpoint: properties["HttpConfig"]["Endpoint"] };
|
|
35772
|
+
this.applyDataSourceConfig(input, resourceType, logicalId, properties);
|
|
35410
35773
|
await this.getClient().send(new CreateDataSourceCommand(input));
|
|
35411
35774
|
const physicalId = `${apiId}|${name}`;
|
|
35412
35775
|
this.logger.debug(`Successfully created DataSource ${logicalId}: ${physicalId}`);
|
|
@@ -35457,19 +35820,7 @@ var AppSyncProvider = class {
|
|
|
35457
35820
|
typeName,
|
|
35458
35821
|
fieldName
|
|
35459
35822
|
};
|
|
35460
|
-
|
|
35461
|
-
if (properties["RequestMappingTemplate"]) input.requestMappingTemplate = properties["RequestMappingTemplate"];
|
|
35462
|
-
if (properties["ResponseMappingTemplate"]) input.responseMappingTemplate = properties["ResponseMappingTemplate"];
|
|
35463
|
-
if (properties["Kind"]) input.kind = properties["Kind"];
|
|
35464
|
-
if (properties["PipelineConfig"]) input.pipelineConfig = { functions: properties["PipelineConfig"]["Functions"] };
|
|
35465
|
-
if (properties["Runtime"]) {
|
|
35466
|
-
const runtime = properties["Runtime"];
|
|
35467
|
-
input.runtime = {
|
|
35468
|
-
name: runtime["Name"],
|
|
35469
|
-
runtimeVersion: runtime["RuntimeVersion"]
|
|
35470
|
-
};
|
|
35471
|
-
}
|
|
35472
|
-
if (properties["Code"]) input.code = properties["Code"];
|
|
35823
|
+
await this.applyResolverConfig(input, resourceType, logicalId, properties);
|
|
35473
35824
|
await this.getClient().send(new CreateResolverCommand(input));
|
|
35474
35825
|
const physicalId = `${apiId}|${typeName}|${fieldName}`;
|
|
35475
35826
|
this.logger.debug(`Successfully created Resolver ${logicalId}: ${physicalId}`);
|
|
@@ -35568,10 +35919,13 @@ var AppSyncProvider = class {
|
|
|
35568
35919
|
* CDK's `aws:*` auto-tags are filtered out and the result key is
|
|
35569
35920
|
* omitted when no user tags remain.
|
|
35570
35921
|
* - `DataSource` → `GetDataSource` (Name, Type, Description,
|
|
35571
|
-
* ServiceRoleArn, DynamoDBConfig, LambdaConfig,
|
|
35922
|
+
* ServiceRoleArn, the per-type configs — DynamoDBConfig, LambdaConfig,
|
|
35923
|
+
* HttpConfig, ElasticsearchConfig, OpenSearchServiceConfig,
|
|
35924
|
+
* EventBridgeConfig, RelationalDatabaseConfig — and MetricsConfig). The
|
|
35572
35925
|
* `ApiId` cdkd holds is recovered from the `apiId|name` physicalId.
|
|
35573
35926
|
* - `Resolver` → `GetResolver` (TypeName, FieldName, DataSourceName,
|
|
35574
|
-
* request/response templates, Kind, PipelineConfig, Runtime, Code
|
|
35927
|
+
* request/response templates, Kind, PipelineConfig, Runtime, Code,
|
|
35928
|
+
* CachingConfig, SyncConfig, MaxBatchSize, MetricsConfig).
|
|
35575
35929
|
* - `ApiKey` → `ListApiKeys` filtered by id (no `GetApiKey` SDK call;
|
|
35576
35930
|
* AppSync only exposes list-based access). Surfaces Description and
|
|
35577
35931
|
* Expires.
|
|
@@ -35749,6 +36103,35 @@ var AppSyncProvider = class {
|
|
|
35749
36103
|
}
|
|
35750
36104
|
if (ds.lambdaConfig?.lambdaFunctionArn !== void 0) result["LambdaConfig"] = { LambdaFunctionArn: ds.lambdaConfig.lambdaFunctionArn };
|
|
35751
36105
|
if (ds.httpConfig?.endpoint !== void 0) result["HttpConfig"] = { Endpoint: ds.httpConfig.endpoint };
|
|
36106
|
+
if (ds.elasticsearchConfig) {
|
|
36107
|
+
const es = {};
|
|
36108
|
+
if (ds.elasticsearchConfig.endpoint !== void 0) es["Endpoint"] = ds.elasticsearchConfig.endpoint;
|
|
36109
|
+
if (ds.elasticsearchConfig.awsRegion !== void 0) es["AwsRegion"] = ds.elasticsearchConfig.awsRegion;
|
|
36110
|
+
if (Object.keys(es).length > 0) result["ElasticsearchConfig"] = es;
|
|
36111
|
+
}
|
|
36112
|
+
if (ds.openSearchServiceConfig) {
|
|
36113
|
+
const os = {};
|
|
36114
|
+
if (ds.openSearchServiceConfig.endpoint !== void 0) os["Endpoint"] = ds.openSearchServiceConfig.endpoint;
|
|
36115
|
+
if (ds.openSearchServiceConfig.awsRegion !== void 0) os["AwsRegion"] = ds.openSearchServiceConfig.awsRegion;
|
|
36116
|
+
if (Object.keys(os).length > 0) result["OpenSearchServiceConfig"] = os;
|
|
36117
|
+
}
|
|
36118
|
+
if (ds.eventBridgeConfig?.eventBusArn !== void 0) result["EventBridgeConfig"] = { EventBusArn: ds.eventBridgeConfig.eventBusArn };
|
|
36119
|
+
if (ds.relationalDatabaseConfig) {
|
|
36120
|
+
const rds = {};
|
|
36121
|
+
if (ds.relationalDatabaseConfig.relationalDatabaseSourceType !== void 0) rds["RelationalDatabaseSourceType"] = ds.relationalDatabaseConfig.relationalDatabaseSourceType;
|
|
36122
|
+
const endpoint = ds.relationalDatabaseConfig.rdsHttpEndpointConfig;
|
|
36123
|
+
if (endpoint) {
|
|
36124
|
+
const ep = {};
|
|
36125
|
+
if (endpoint.awsRegion !== void 0) ep["AwsRegion"] = endpoint.awsRegion;
|
|
36126
|
+
if (endpoint.dbClusterIdentifier !== void 0) ep["DbClusterIdentifier"] = endpoint.dbClusterIdentifier;
|
|
36127
|
+
if (endpoint.databaseName !== void 0) ep["DatabaseName"] = endpoint.databaseName;
|
|
36128
|
+
if (endpoint.schema !== void 0) ep["Schema"] = endpoint.schema;
|
|
36129
|
+
if (endpoint.awsSecretStoreArn !== void 0) ep["AwsSecretStoreArn"] = endpoint.awsSecretStoreArn;
|
|
36130
|
+
if (Object.keys(ep).length > 0) rds["RdsHttpEndpointConfig"] = ep;
|
|
36131
|
+
}
|
|
36132
|
+
if (Object.keys(rds).length > 0) result["RelationalDatabaseConfig"] = rds;
|
|
36133
|
+
}
|
|
36134
|
+
if (ds.metricsConfig !== void 0) result["MetricsConfig"] = ds.metricsConfig;
|
|
35752
36135
|
return result;
|
|
35753
36136
|
}
|
|
35754
36137
|
async readResolver(physicalId) {
|
|
@@ -35783,6 +36166,21 @@ var AppSyncProvider = class {
|
|
|
35783
36166
|
result["RequestMappingTemplate"] = resolver.requestMappingTemplate ?? "";
|
|
35784
36167
|
result["ResponseMappingTemplate"] = resolver.responseMappingTemplate ?? "";
|
|
35785
36168
|
}
|
|
36169
|
+
if (resolver.cachingConfig) {
|
|
36170
|
+
const caching = {};
|
|
36171
|
+
if (resolver.cachingConfig.ttl !== void 0) caching["Ttl"] = resolver.cachingConfig.ttl;
|
|
36172
|
+
if (resolver.cachingConfig.cachingKeys !== void 0) caching["CachingKeys"] = [...resolver.cachingConfig.cachingKeys];
|
|
36173
|
+
if (Object.keys(caching).length > 0) result["CachingConfig"] = caching;
|
|
36174
|
+
}
|
|
36175
|
+
if (resolver.syncConfig) {
|
|
36176
|
+
const sync = {};
|
|
36177
|
+
if (resolver.syncConfig.conflictDetection !== void 0) sync["ConflictDetection"] = resolver.syncConfig.conflictDetection;
|
|
36178
|
+
if (resolver.syncConfig.conflictHandler !== void 0) sync["ConflictHandler"] = resolver.syncConfig.conflictHandler;
|
|
36179
|
+
if (resolver.syncConfig.lambdaConflictHandlerConfig?.lambdaConflictHandlerArn !== void 0) sync["LambdaConflictHandlerConfig"] = { LambdaConflictHandlerArn: resolver.syncConfig.lambdaConflictHandlerConfig.lambdaConflictHandlerArn };
|
|
36180
|
+
if (Object.keys(sync).length > 0) result["SyncConfig"] = sync;
|
|
36181
|
+
}
|
|
36182
|
+
if (resolver.maxBatchSize !== void 0) result["MaxBatchSize"] = resolver.maxBatchSize;
|
|
36183
|
+
if (resolver.metricsConfig !== void 0) result["MetricsConfig"] = resolver.metricsConfig;
|
|
35786
36184
|
return result;
|
|
35787
36185
|
}
|
|
35788
36186
|
async readApiKey(physicalId) {
|
|
@@ -69522,7 +69920,7 @@ function createMigrateCommand() {
|
|
|
69522
69920
|
*/
|
|
69523
69921
|
function buildProgram() {
|
|
69524
69922
|
const program = new Command();
|
|
69525
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.
|
|
69923
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.19");
|
|
69526
69924
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
69527
69925
|
const { profile } = actionCommand.optsWithGlobals();
|
|
69528
69926
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|