@go-to-k/cdkd 0.278.49 → 0.278.51
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/README.md +34 -13
- package/dist/{asg-provider-t9dJL0zs.js → asg-provider-B2jsUFUl.js} +2 -2
- package/dist/{asg-provider-t9dJL0zs.js.map → asg-provider-B2jsUFUl.js.map} +1 -1
- package/dist/cli.js +196 -56
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-BgLg1tet.js → deploy-engine-C1otn94r.js} +27 -9
- package/dist/deploy-engine-C1otn94r.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BgLg1tet.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as DiffCalculator, $t as resolveBucketRegion, A as red, At as getDockerImageBySourceHash, B as isTerminationProtectionPropagationError, Bt as resolveStateBucketWithDefaultAndSource, C as isStatefulRecreateTargetSync, Ct as validateContainerRepoName, D as cyan, Dt as runDockerForeground, E as bold, En as withErrorHandling, Et as getDockerCmd, F as ProviderRegistry, Ft as resolveApp, G as normalizeAwsTagsToCfn, Gt as CFN_TEMPLATE_URL_LIMIT, H as cfnRefValueFromPhysicalId, Ht as stateBucketExistenceConfirmed, I as findActionableSilentDrops, It as resolveAutoAssetStorage, J as readConfigString, Jt as uploadCfnTemplate, K as resolveExplicitPhysicalId, Kt as MIGRATE_TMP_PREFIX, L as CloudControlProvider, Lt as resolveCaptureObservedState, M as IAMRoleProvider, Mt as synthesisStatusMessage, N as collectInlinePolicyNamesManagedBySiblings, Nt as getDefaultStateBucketName, O as gray, Ot as runDockerStreaming, P as clearOnUpdateRemoval, Pt as getLegacyStateBucketName, Q as applyRoleArnIfSet, R as slowCcOperationTimeoutMs, Rt as resolveSkipPrefix, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as validateAssetBucketName, T as formatResourceLine, Tn as normalizeAwsError, Tt as formatDockerLoginError, U as refStateLookupFromResource, Ut as warnDeprecatedNoPrefixCliFlag, V as IntrinsicFunctionResolver, Vt as resolveUseCdkBootstrapAssets, W as WAFv2WebACLProvider, Wt as CFN_TEMPLATE_BODY_LIMIT, X as requireConfigArray, Xt as AssemblyReader, Y as replayWarn, Yt as expectedOwnerParam, Z as requireConfigString, Zt as processStackMessages, _ as createPreDeleteFinalSnapshot, _n as ResourceTimeoutError, _t as AssetModeResolver, a as DeploymentEventsStore, an as CdkdError, at as TemplateParser, b as unsupportedFinalSnapshotError, bn as StackTerminationProtectionError, bt as getBootstrapMarkerKey, c as replayFailedOperations, cn as DeployCancelledError, ct as rebuildClientForBucketRegion, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalStartServiceError, dt as stringifyValue, en as AwsClients, et as describeTypeWithThrottleRetry, f as computeImplicitDeleteEdges, ft as WorkGraph, g as ccRoutedFinalSnapshotError, gn as ProvisioningError, gt as rewriteTemplateAssetReferences, h as buildFinalSnapshotIdentifier, hn as PartialFailureError, ht as loadPublishableAssetManifest, i as DeploymentEventsReader, it as DagBuilder, j as yellow, jt as Synthesizer, k as green, kt as AssetManifestLoader, l as replayRollback, ln as LocalInvokeBuildError$1, lt as shouldRetainResource, m as PRE_DELETE_SNAPSHOT_TYPES, mn as NestedStackChildDirectDestroyError, mt as createAssetRedirectResolver, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resetAwsClients, nt as isRetryableTransientError, o as planFailedOps, ot as LockManager, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as MissingCdkCliError, pt as buildAssetRedirectMap, q as assertRegionMatch, qt as findLargeInlineResources, r as DeployEngine, rn as setAwsClients, rt as isThrottlingError, s as planRollback, st as S3StateBackend, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as getAwsClients, tt as withRetry, u as withResourceDeadline, un as LocalMigrateError, ut as AssetPublisher, v as isFinalSnapshotError, vn as ResourceUpdateNotSupportedError, vt as BOOTSTRAP_MARKER_PREFIX, w as renderStatefulReason, wt as buildDockerImage, x as extractDeploymentEventError, xt as parseBootstrapMarker, y as refusesFinalSnapshot, yn as StackHasActiveImportsError, yt as ensureAssetStorage, z as disableInstanceApiTermination, zt as resolveStateBucketWithDefault } from "./deploy-engine-
|
|
2
|
+
import { $ as DiffCalculator, $t as resolveBucketRegion, A as red, At as getDockerImageBySourceHash, B as isTerminationProtectionPropagationError, Bt as resolveStateBucketWithDefaultAndSource, C as isStatefulRecreateTargetSync, Ct as validateContainerRepoName, D as cyan, Dt as runDockerForeground, E as bold, En as withErrorHandling, Et as getDockerCmd, F as ProviderRegistry, Ft as resolveApp, G as normalizeAwsTagsToCfn, Gt as CFN_TEMPLATE_URL_LIMIT, H as cfnRefValueFromPhysicalId, Ht as stateBucketExistenceConfirmed, I as findActionableSilentDrops, It as resolveAutoAssetStorage, J as readConfigString, Jt as uploadCfnTemplate, K as resolveExplicitPhysicalId, Kt as MIGRATE_TMP_PREFIX, L as CloudControlProvider, Lt as resolveCaptureObservedState, M as IAMRoleProvider, Mt as synthesisStatusMessage, N as collectInlinePolicyNamesManagedBySiblings, Nt as getDefaultStateBucketName, O as gray, Ot as runDockerStreaming, P as clearOnUpdateRemoval, Pt as getLegacyStateBucketName, Q as applyRoleArnIfSet, R as slowCcOperationTimeoutMs, Rt as resolveSkipPrefix, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as validateAssetBucketName, T as formatResourceLine, Tn as normalizeAwsError, Tt as formatDockerLoginError, U as refStateLookupFromResource, Ut as warnDeprecatedNoPrefixCliFlag, V as IntrinsicFunctionResolver, Vt as resolveUseCdkBootstrapAssets, W as WAFv2WebACLProvider, Wt as CFN_TEMPLATE_BODY_LIMIT, X as requireConfigArray, Xt as AssemblyReader, Y as replayWarn, Yt as expectedOwnerParam, Z as requireConfigString, Zt as processStackMessages, _ as createPreDeleteFinalSnapshot, _n as ResourceTimeoutError, _t as AssetModeResolver, a as DeploymentEventsStore, an as CdkdError, at as TemplateParser, b as unsupportedFinalSnapshotError, bn as StackTerminationProtectionError, bt as getBootstrapMarkerKey, c as replayFailedOperations, cn as DeployCancelledError, ct as rebuildClientForBucketRegion, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalStartServiceError, dt as stringifyValue, en as AwsClients, et as describeTypeWithThrottleRetry, f as computeImplicitDeleteEdges, ft as WorkGraph, g as ccRoutedFinalSnapshotError, gn as ProvisioningError, gt as rewriteTemplateAssetReferences, h as buildFinalSnapshotIdentifier, hn as PartialFailureError, ht as loadPublishableAssetManifest, i as DeploymentEventsReader, it as DagBuilder, j as yellow, jt as Synthesizer, k as green, kt as AssetManifestLoader, l as replayRollback, ln as LocalInvokeBuildError$1, lt as shouldRetainResource, m as PRE_DELETE_SNAPSHOT_TYPES, mn as NestedStackChildDirectDestroyError, mt as createAssetRedirectResolver, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resetAwsClients, nt as isRetryableTransientError, o as planFailedOps, ot as LockManager, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as MissingCdkCliError, pt as buildAssetRedirectMap, q as assertRegionMatch, qt as findLargeInlineResources, r as DeployEngine, rn as setAwsClients, rt as isThrottlingError, s as planRollback, st as S3StateBackend, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as getAwsClients, tt as withRetry, u as withResourceDeadline, un as LocalMigrateError, ut as AssetPublisher, v as isFinalSnapshotError, vn as ResourceUpdateNotSupportedError, vt as BOOTSTRAP_MARKER_PREFIX, w as renderStatefulReason, wt as buildDockerImage, x as extractDeploymentEventError, xt as parseBootstrapMarker, y as refusesFinalSnapshot, yn as StackHasActiveImportsError, yt as ensureAssetStorage, z as disableInstanceApiTermination, zt as resolveStateBucketWithDefault } from "./deploy-engine-C1otn94r.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-B2jsUFUl.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";
|
|
@@ -4824,6 +4824,53 @@ function isPlainObject$1(value) {
|
|
|
4824
4824
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4825
4825
|
}
|
|
4826
4826
|
/**
|
|
4827
|
+
* Is this `Destination` block written in the CFn FLATTENED form
|
|
4828
|
+
* (`{ BucketArn, Format, ... }`) rather than the SDK NESTED one
|
|
4829
|
+
* (`{ S3BucketDestination: { ... } }`)?
|
|
4830
|
+
*
|
|
4831
|
+
* ONE predicate, called from both `resolveS3BucketDestination` (which picks the
|
|
4832
|
+
* bag) and `s3BucketDestinationPath` (which names it). They were written out
|
|
4833
|
+
* twice and a reviewer rightly pointed out that two copies of a branch
|
|
4834
|
+
* condition must be edited together or a refusal starts naming the wrong key.
|
|
4835
|
+
*
|
|
4836
|
+
* `Bucket` is probed alongside `BucketArn` because the readers accept it
|
|
4837
|
+
* (`s3Dest['BucketArn'] ?? s3Dest['Bucket']`); omitting it made a
|
|
4838
|
+
* `{ Bucket }`-only block take the nested branch, find nothing, and drop — the
|
|
4839
|
+
* same silent drop one shape over.
|
|
4840
|
+
*/
|
|
4841
|
+
function isFlattenedDestination(dest) {
|
|
4842
|
+
return Boolean(dest["BucketArn"] || dest["Bucket"] || dest["BucketAccountId"] || dest["Format"]);
|
|
4843
|
+
}
|
|
4844
|
+
/**
|
|
4845
|
+
* The CFn path of the destination bag `resolveS3BucketDestination` will pick —
|
|
4846
|
+
* issue #1493 item 3, which is a MESSAGE concern, not a value one.
|
|
4847
|
+
*
|
|
4848
|
+
* Kept separate from the resolver rather than returned alongside the bag:
|
|
4849
|
+
* `gen-nested-key-coverage`'s write-evidence walk follows a plain
|
|
4850
|
+
* `const x = this.helper(...)` binding to the members written beneath it, and
|
|
4851
|
+
* a DESTRUCTURED `const { bag, path } = ...` is a shape it cannot follow — so
|
|
4852
|
+
* pairing the two silently withdrew the write evidence for
|
|
4853
|
+
* `Destination.BucketArn` / `.BucketAccountId` and turned an opted-in target
|
|
4854
|
+
* red with no behavior change at all. Measured against the pre-change provider
|
|
4855
|
+
* via the critic's `--providers-dir=` seam.
|
|
4856
|
+
*/
|
|
4857
|
+
function s3BucketDestinationPath(dest, destinationPath) {
|
|
4858
|
+
return isPlainObject$1(dest) && isFlattenedDestination(dest) ? destinationPath : `${destinationPath}.S3BucketDestination`;
|
|
4859
|
+
}
|
|
4860
|
+
/**
|
|
4861
|
+
* Name a malformed value in a refusal message, the way `config-shape.ts`'s
|
|
4862
|
+
* private `describe` does for the string-reading guards. Kept local rather than
|
|
4863
|
+
* exported from there because `resolveS3BucketDestination` is S3-specific
|
|
4864
|
+
* branch selection, not a shared shape guard — the two only share the wording.
|
|
4865
|
+
*/
|
|
4866
|
+
function describeValue(value) {
|
|
4867
|
+
if (value === null) return "null";
|
|
4868
|
+
if (Array.isArray(value)) return "an array";
|
|
4869
|
+
if (typeof value === "string") return `a string ${JSON.stringify(value)}`;
|
|
4870
|
+
if (isPlainObject$1(value)) return `an object with keys [${Object.keys(value).join(", ")}]`;
|
|
4871
|
+
return `a ${typeof value} (${String(value)})`;
|
|
4872
|
+
}
|
|
4873
|
+
/**
|
|
4827
4874
|
* Coerce a CFn numeric to a finite number. CloudFormation is stringly typed —
|
|
4828
4875
|
* a hand-written or imported template (the audience the legacy lifecycle
|
|
4829
4876
|
* branches exist for) can carry `"365"` where the schema says number.
|
|
@@ -5345,12 +5392,61 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5345
5392
|
this.logger.debug(`Applied ${configs.length} metrics configuration(s) to bucket ${bucketName}`);
|
|
5346
5393
|
}
|
|
5347
5394
|
/**
|
|
5395
|
+
* Pick the `S3BucketDestination` bag out of an analytics / inventory
|
|
5396
|
+
* `Destination` block, refusing a shape that would otherwise be dropped.
|
|
5397
|
+
*
|
|
5398
|
+
* Two shapes are legitimate and both must keep working: the CFn FLATTENED
|
|
5399
|
+
* form (`Destination: { BucketArn, Format, ... }`, what the schema declares)
|
|
5400
|
+
* and the SDK NESTED form (`Destination: { S3BucketDestination: { ... } }`,
|
|
5401
|
+
* accepted because state records and hand-written templates carry it).
|
|
5402
|
+
*
|
|
5403
|
+
* Issue #1493 item 2: the branch was picked by probing member presence
|
|
5404
|
+
* (`dest?.['BucketAccountId'] || dest?.['BucketArn'] || dest?.['Format']`),
|
|
5405
|
+
* so a `Destination` that is a STRING / array / unresolved intrinsic indexed
|
|
5406
|
+
* every probe to `undefined`, fell through to an equally-`undefined`
|
|
5407
|
+
* `S3BucketDestination`, and the caller's `s3Dest ? … : undefined` omitted
|
|
5408
|
+
* the whole block from the Put — a configuration silently deployed without
|
|
5409
|
+
* the destination it declared. Unlike the sibling defaulting class this is a
|
|
5410
|
+
* DROP, not a substituted default, so `readConfigString` does not cover it:
|
|
5411
|
+
* it needs its own decision, and per issue #1513's precedent that decision is
|
|
5412
|
+
* REFUSE on the template-borne create path, WARN on the replay-reachable
|
|
5413
|
+
* update path (`onUnusable`), where the desired bag can be a historical cdkd
|
|
5414
|
+
* state record with no template-side remedy.
|
|
5415
|
+
*
|
|
5416
|
+
* Also returns the CFn path of the bag it picked (issue #1493 item 3): the
|
|
5417
|
+
* callers used to hardcode `…Destination.S3BucketDestination` in the
|
|
5418
|
+
* `containerPath` they pass to `readConfigString`, so a refusal on the
|
|
5419
|
+
* FLATTENED branch — where the bag IS `dest` itself — named a key the user's
|
|
5420
|
+
* template does not contain.
|
|
5421
|
+
*
|
|
5422
|
+
* @returns the picked bag, or `undefined` when the block was ABSENT or was
|
|
5423
|
+
* refused on a warn-only path. The caller distinguishes the two by testing
|
|
5424
|
+
* its own `Destination` value — see the `continue` at each call site.
|
|
5425
|
+
*/
|
|
5426
|
+
resolveS3BucketDestination(dest, destinationPath, onUnusable) {
|
|
5427
|
+
const nestedPath = `${destinationPath}.S3BucketDestination`;
|
|
5428
|
+
const drop = (message) => {
|
|
5429
|
+
if (onUnusable) {
|
|
5430
|
+
onUnusable(`${message}. Leaving this configuration unchanged; the same value is REFUSED on a template-path create`);
|
|
5431
|
+
return;
|
|
5432
|
+
}
|
|
5433
|
+
throw new Error(message);
|
|
5434
|
+
};
|
|
5435
|
+
if (dest === void 0 || dest === null) return;
|
|
5436
|
+
if (!isPlainObject$1(dest)) return drop(`${destinationPath} must be an object (got ${describeValue(dest)}) — check for an unresolved intrinsic or a mis-nested template value; the destination would otherwise be dropped from the request with no error`);
|
|
5437
|
+
const bag = isFlattenedDestination(dest) ? dest : dest["S3BucketDestination"];
|
|
5438
|
+
if (bag === void 0 || bag === null) return drop(`${destinationPath} carries neither a bucket (BucketArn / Bucket) nor a nested S3BucketDestination object (got ${describeValue(dest)}) — the destination would otherwise be dropped from the request with no error`);
|
|
5439
|
+
if (!isPlainObject$1(bag)) return drop(`${nestedPath} must be an object (got ${describeValue(bag)}) — check for an unresolved intrinsic or a mis-nested template value; the destination would otherwise be dropped from the request with no error`);
|
|
5440
|
+
if (!bag["BucketArn"] && !bag["Bucket"]) return drop(`${bag === dest ? destinationPath : nestedPath} has no destination bucket (BucketArn / Bucket) (got ${describeValue(bag)}) — the request would be rejected by S3, or silently carry no destination`);
|
|
5441
|
+
return bag;
|
|
5442
|
+
}
|
|
5443
|
+
/**
|
|
5348
5444
|
* Apply analytics configurations
|
|
5349
5445
|
*
|
|
5350
5446
|
* CFn property: AnalyticsConfigurations[] (array of configurations)
|
|
5351
5447
|
* SDK: PutBucketAnalyticsConfiguration (one per configuration, keyed by Id)
|
|
5352
5448
|
*/
|
|
5353
|
-
async applyAnalyticsConfigurations(bucketName, configs) {
|
|
5449
|
+
async applyAnalyticsConfigurations(bucketName, configs, onUnusable) {
|
|
5354
5450
|
for (const config of configs) {
|
|
5355
5451
|
const id = config["Id"];
|
|
5356
5452
|
const storageClassAnalysis = config["StorageClassAnalysis"];
|
|
@@ -5368,16 +5464,19 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5368
5464
|
else if (prefix) analyticsConfig.Filter = { Prefix: prefix };
|
|
5369
5465
|
else if (tagFilters && tagFilters.length > 0) analyticsConfig.Filter = { Tag: tagFilters[0] };
|
|
5370
5466
|
}
|
|
5371
|
-
if (storageClassAnalysis?.["DataExport"]) {
|
|
5467
|
+
if (storageClassAnalysis?.["DataExport"] != null) {
|
|
5372
5468
|
const dataExport = storageClassAnalysis["DataExport"];
|
|
5373
|
-
const
|
|
5374
|
-
const
|
|
5469
|
+
const analyticsDestPath = "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport.Destination";
|
|
5470
|
+
const rawDest = dataExport["Destination"];
|
|
5471
|
+
const s3Dest = this.resolveS3BucketDestination(rawDest, analyticsDestPath, onUnusable);
|
|
5472
|
+
if (s3Dest === void 0 && rawDest != null) continue;
|
|
5473
|
+
const destPath = s3BucketDestinationPath(rawDest, analyticsDestPath);
|
|
5375
5474
|
analyticsConfig.StorageClassAnalysis = { DataExport: {
|
|
5376
5475
|
OutputSchemaVersion: readConfigString(dataExport, "OutputSchemaVersion", "V_1", "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport"),
|
|
5377
5476
|
Destination: s3Dest ? { S3BucketDestination: {
|
|
5378
5477
|
Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
|
|
5379
5478
|
BucketAccountId: s3Dest["BucketAccountId"],
|
|
5380
|
-
Format: readConfigString(s3Dest, "Format", "CSV",
|
|
5479
|
+
Format: readConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }),
|
|
5381
5480
|
Prefix: s3Dest["Prefix"]
|
|
5382
5481
|
} } : void 0
|
|
5383
5482
|
} };
|
|
@@ -5432,11 +5531,14 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5432
5531
|
* CFn property: InventoryConfigurations[]
|
|
5433
5532
|
* SDK: PutBucketInventoryConfiguration (one per configuration, keyed by Id)
|
|
5434
5533
|
*/
|
|
5435
|
-
async applyInventoryConfigurations(bucketName, configs) {
|
|
5534
|
+
async applyInventoryConfigurations(bucketName, configs, onUnusable) {
|
|
5436
5535
|
for (const config of configs) {
|
|
5437
5536
|
const id = config["Id"];
|
|
5438
|
-
const
|
|
5439
|
-
const
|
|
5537
|
+
const inventoryDestPath = "AWS::S3::Bucket InventoryConfigurations[].Destination";
|
|
5538
|
+
const rawDest = config["Destination"];
|
|
5539
|
+
const s3Dest = this.resolveS3BucketDestination(rawDest, inventoryDestPath, onUnusable);
|
|
5540
|
+
if (s3Dest === void 0 && rawDest != null) continue;
|
|
5541
|
+
const destPath = s3BucketDestinationPath(rawDest, inventoryDestPath);
|
|
5440
5542
|
const inventoryConfig = {
|
|
5441
5543
|
Id: id,
|
|
5442
5544
|
IsEnabled: config["Enabled"] ?? true,
|
|
@@ -5445,7 +5547,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5445
5547
|
Destination: { S3BucketDestination: s3Dest ? {
|
|
5446
5548
|
Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
|
|
5447
5549
|
AccountId: s3Dest["BucketAccountId"],
|
|
5448
|
-
Format: readConfigString(s3Dest, "Format", "CSV",
|
|
5550
|
+
Format: readConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }),
|
|
5449
5551
|
Prefix: s3Dest["Prefix"]
|
|
5450
5552
|
} : void 0 },
|
|
5451
5553
|
OptionalFields: config["OptionalFields"],
|
|
@@ -5789,7 +5891,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5789
5891
|
}));
|
|
5790
5892
|
this.logger.debug(`Deleted metrics configuration ${id} on bucket ${bucketName}`);
|
|
5791
5893
|
});
|
|
5792
|
-
await this.diffArrayConfigById(bucketName, previousProperties["AnalyticsConfigurations"], properties["AnalyticsConfigurations"], async (_id, cfg) => this.applyAnalyticsConfigurations(bucketName, [cfg]), async (id) => {
|
|
5894
|
+
await this.diffArrayConfigById(bucketName, previousProperties["AnalyticsConfigurations"], properties["AnalyticsConfigurations"], async (_id, cfg) => this.applyAnalyticsConfigurations(bucketName, [cfg], (m) => this.logger.warn(m)), async (id) => {
|
|
5793
5895
|
await this.s3Client.send(new DeleteBucketAnalyticsConfigurationCommand({
|
|
5794
5896
|
Bucket: bucketName,
|
|
5795
5897
|
Id: id
|
|
@@ -5803,7 +5905,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5803
5905
|
}));
|
|
5804
5906
|
this.logger.debug(`Deleted intelligent tiering configuration ${id} on bucket ${bucketName}`);
|
|
5805
5907
|
});
|
|
5806
|
-
await this.diffArrayConfigById(bucketName, previousProperties["InventoryConfigurations"], properties["InventoryConfigurations"], async (_id, cfg) => this.applyInventoryConfigurations(bucketName, [cfg]), async (id) => {
|
|
5908
|
+
await this.diffArrayConfigById(bucketName, previousProperties["InventoryConfigurations"], properties["InventoryConfigurations"], async (_id, cfg) => this.applyInventoryConfigurations(bucketName, [cfg], (m) => this.logger.warn(m)), async (id) => {
|
|
5807
5909
|
await this.s3Client.send(new DeleteBucketInventoryConfigurationCommand({
|
|
5808
5910
|
Bucket: bucketName,
|
|
5809
5911
|
Id: id
|
|
@@ -5823,7 +5925,8 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5823
5925
|
* Apply ALL sub-configs unconditionally on initial create. Used by
|
|
5824
5926
|
* `create()` so the bucket starts out matching the template.
|
|
5825
5927
|
*/
|
|
5826
|
-
async applyAllSubConfigsForCreate(bucketName, properties) {
|
|
5928
|
+
async applyAllSubConfigsForCreate(bucketName, properties, context) {
|
|
5929
|
+
const replayOnUnusable = replayWarn(this.logger, context).onUnusable;
|
|
5827
5930
|
const notifConfig = properties["NotificationConfiguration"];
|
|
5828
5931
|
if (notifConfig) await this.applyNotificationConfiguration(bucketName, notifConfig);
|
|
5829
5932
|
const corsConfig = properties["CorsConfiguration"];
|
|
@@ -5839,11 +5942,11 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5839
5942
|
const metricsConfigs = properties["MetricsConfigurations"];
|
|
5840
5943
|
if (metricsConfigs && Array.isArray(metricsConfigs) && metricsConfigs.length > 0) await this.applyMetricsConfigurations(bucketName, metricsConfigs);
|
|
5841
5944
|
const analyticsConfigs = properties["AnalyticsConfigurations"];
|
|
5842
|
-
if (analyticsConfigs && Array.isArray(analyticsConfigs) && analyticsConfigs.length > 0) await this.applyAnalyticsConfigurations(bucketName, analyticsConfigs);
|
|
5945
|
+
if (analyticsConfigs && Array.isArray(analyticsConfigs) && analyticsConfigs.length > 0) await this.applyAnalyticsConfigurations(bucketName, analyticsConfigs, replayOnUnusable);
|
|
5843
5946
|
const itConfigs = properties["IntelligentTieringConfigurations"];
|
|
5844
5947
|
if (itConfigs && Array.isArray(itConfigs) && itConfigs.length > 0) await this.applyIntelligentTieringConfigurations(bucketName, itConfigs);
|
|
5845
5948
|
const inventoryConfigs = properties["InventoryConfigurations"];
|
|
5846
|
-
if (inventoryConfigs && Array.isArray(inventoryConfigs) && inventoryConfigs.length > 0) await this.applyInventoryConfigurations(bucketName, inventoryConfigs);
|
|
5949
|
+
if (inventoryConfigs && Array.isArray(inventoryConfigs) && inventoryConfigs.length > 0) await this.applyInventoryConfigurations(bucketName, inventoryConfigs, replayOnUnusable);
|
|
5847
5950
|
const replConfig = properties["ReplicationConfiguration"];
|
|
5848
5951
|
if (replConfig) await this.applyReplicationConfiguration(bucketName, replConfig);
|
|
5849
5952
|
const objectLockConfig = properties["ObjectLockConfiguration"];
|
|
@@ -5852,7 +5955,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5852
5955
|
/**
|
|
5853
5956
|
* Create an S3 bucket
|
|
5854
5957
|
*/
|
|
5855
|
-
async create(logicalId, resourceType, properties) {
|
|
5958
|
+
async create(logicalId, resourceType, properties, context) {
|
|
5856
5959
|
this.logger.debug(`Creating S3 bucket ${logicalId}`);
|
|
5857
5960
|
const bucketName = properties["BucketName"] || generateResourceName(logicalId, {
|
|
5858
5961
|
maxLength: 63,
|
|
@@ -5875,7 +5978,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
5875
5978
|
}
|
|
5876
5979
|
try {
|
|
5877
5980
|
await this.applyConfiguration(bucketName, properties);
|
|
5878
|
-
await this.applyAllSubConfigsForCreate(bucketName, properties);
|
|
5981
|
+
await this.applyAllSubConfigsForCreate(bucketName, properties, context);
|
|
5879
5982
|
} catch (innerError) {
|
|
5880
5983
|
if (createdNewBucket) try {
|
|
5881
5984
|
await this.s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }));
|
|
@@ -7823,7 +7926,7 @@ var SNSTopicProvider = class {
|
|
|
7823
7926
|
}
|
|
7824
7927
|
}
|
|
7825
7928
|
if (JSON.stringify(properties["DeliveryStatusLogging"]) !== JSON.stringify(previousProperties["DeliveryStatusLogging"])) {
|
|
7826
|
-
const desiredAttributes = buildDeliveryStatusAttributeMap(properties["DeliveryStatusLogging"], logicalId, "
|
|
7929
|
+
const desiredAttributes = buildDeliveryStatusAttributeMap(properties["DeliveryStatusLogging"], logicalId, "warn");
|
|
7827
7930
|
const previousAttributes = buildDeliveryStatusAttributeMap(previousProperties["DeliveryStatusLogging"], logicalId, "skip");
|
|
7828
7931
|
for (const [attributeName, attributeValue] of desiredAttributes) {
|
|
7829
7932
|
if (previousAttributes.get(attributeName) === attributeValue) continue;
|
|
@@ -8205,11 +8308,24 @@ const SNS_DELIVERY_STATUS_ATTRIBUTE_SUFFIXES = [
|
|
|
8205
8308
|
* rate on create and update alike).
|
|
8206
8309
|
*
|
|
8207
8310
|
* `onMalformed` picks the failure mode for a malformed container / entry
|
|
8208
|
-
* / unknown protocol
|
|
8209
|
-
*
|
|
8210
|
-
*
|
|
8211
|
-
* the
|
|
8212
|
-
*
|
|
8311
|
+
* / unknown protocol, and encodes the create-vs-update distinction
|
|
8312
|
+
* (issue #1538):
|
|
8313
|
+
*
|
|
8314
|
+
* - `'throw'` — the CREATE desired side, which is always template-borne:
|
|
8315
|
+
* a template error must fail fast, naming the offending value.
|
|
8316
|
+
* - `'warn'` — the UPDATE desired side, which is NOT always template-borne:
|
|
8317
|
+
* the rollback executor's revert arm and `cdkd drift --revert` both call
|
|
8318
|
+
* `update()` with a state-derived bag as the DESIRED properties, so a
|
|
8319
|
+
* state record carrying an unsupported protocol / malformed shape (a
|
|
8320
|
+
* hand-written imported template, or a record an older binary wrote)
|
|
8321
|
+
* must warn-and-skip rather than fail the update permanently — there is
|
|
8322
|
+
* no template-side remedy. Skip semantics are well-defined: an entry
|
|
8323
|
+
* whose protocol cannot be canonicalized maps to no attribute names, a
|
|
8324
|
+
* non-array container yields an empty map, and a non-object entry is
|
|
8325
|
+
* skipped. Each warning names the logicalId and the offending value.
|
|
8326
|
+
* - `'skip'` — the PREVIOUS side (cdkd state): same tolerance, silently —
|
|
8327
|
+
* warning on every update about a value the user cannot act on from the
|
|
8328
|
+
* template would be pure noise (guard-the-desired-side-only rule).
|
|
8213
8329
|
*
|
|
8214
8330
|
* Two entries whose `Protocol` values canonicalize to the SAME prefix
|
|
8215
8331
|
* (`http/s` + `https`, say) collapse onto one set of attribute names. The
|
|
@@ -8223,38 +8339,46 @@ const SNS_DELIVERY_STATUS_ATTRIBUTE_SUFFIXES = [
|
|
|
8223
8339
|
* produced `HTTPS*` names AWS rejected outright, so no such template ever
|
|
8224
8340
|
* deployed.
|
|
8225
8341
|
*
|
|
8226
|
-
* The collision WARNS rather than throws
|
|
8227
|
-
* side is also fed by the rollback executor's
|
|
8228
|
-
* STATE record, where the user has no
|
|
8229
|
-
*
|
|
8230
|
-
* non-object entry)
|
|
8231
|
-
*
|
|
8232
|
-
*
|
|
8233
|
-
*
|
|
8234
|
-
*
|
|
8342
|
+
* The collision WARNS rather than throws for the same reason `'warn'` mode
|
|
8343
|
+
* exists: the update desired side is also fed by the rollback executor's
|
|
8344
|
+
* `update()` replay of a cdkd STATE record, where the user has no
|
|
8345
|
+
* template-side remedy. The three malformed-value sites below (unsupported
|
|
8346
|
+
* protocol, non-array container, non-object entry) used to throw on that
|
|
8347
|
+
* side too, which made such a state record permanently unreplayable —
|
|
8348
|
+
* fixed by issue #1538, which moved `update()`'s desired side to `'warn'`
|
|
8349
|
+
* while `create()` keeps `'throw'` (a template create must still fail
|
|
8350
|
+
* fast; #1529 / #1536 deliberately left that contract unchanged).
|
|
8235
8351
|
*/
|
|
8236
8352
|
function buildDeliveryStatusAttributeMap(logging, logicalId, onMalformed) {
|
|
8237
8353
|
const map = /* @__PURE__ */ new Map();
|
|
8238
8354
|
if (logging == null) return map;
|
|
8355
|
+
const warn = (message) => {
|
|
8356
|
+
getLogger().child("SNSTopicProvider").warn(message);
|
|
8357
|
+
};
|
|
8239
8358
|
const seenProtocols = /* @__PURE__ */ new Set();
|
|
8240
8359
|
if (!Array.isArray(logging)) {
|
|
8241
|
-
if (onMalformed === "
|
|
8242
|
-
|
|
8360
|
+
if (onMalformed === "throw") throw new Error(`SNS topic ${logicalId}: DeliveryStatusLogging must be an array of {Protocol, ...} objects, got ${JSON.stringify(logging)}`);
|
|
8361
|
+
if (onMalformed === "warn") warn(`SNS topic ${logicalId}: DeliveryStatusLogging must be an array of {Protocol, ...} objects, got ${JSON.stringify(logging)} — treating it as empty for this update, so previously set delivery-status attributes are reset. The desired properties can come from a cdkd state record (rollback replay / drift --revert), so this does not fail the update; fix the template (or the state record on a replay) to clear this warning.`);
|
|
8362
|
+
return map;
|
|
8243
8363
|
}
|
|
8244
8364
|
for (const entry of logging) {
|
|
8245
8365
|
if (entry == null || typeof entry !== "object" || Array.isArray(entry)) {
|
|
8246
|
-
if (onMalformed === "
|
|
8247
|
-
|
|
8366
|
+
if (onMalformed === "throw") throw new Error(`SNS topic ${logicalId}: DeliveryStatusLogging entries must be {Protocol, ...} objects, got ${JSON.stringify(entry)}`);
|
|
8367
|
+
if (onMalformed === "warn") warn(`SNS topic ${logicalId}: skipping DeliveryStatusLogging entry ${JSON.stringify(entry)} — entries must be {Protocol, ...} objects. Attributes previously set for the skipped entry's protocol are reset, as if the entry had been removed.`);
|
|
8368
|
+
continue;
|
|
8248
8369
|
}
|
|
8249
8370
|
const config = entry;
|
|
8250
8371
|
let protocol;
|
|
8251
8372
|
if (onMalformed === "throw") protocol = normalizeDeliveryStatusProtocolOrThrow(config["Protocol"], logicalId);
|
|
8252
8373
|
else {
|
|
8253
8374
|
const normalized = normalizeDeliveryStatusProtocol(config["Protocol"]);
|
|
8254
|
-
if (normalized === void 0)
|
|
8375
|
+
if (normalized === void 0) {
|
|
8376
|
+
if (onMalformed === "warn") warn(`SNS topic ${logicalId}: skipping DeliveryStatusLogging entry with unsupported protocol ${JSON.stringify(config["Protocol"])}. Expected one of ${SNS_DELIVERY_STATUS_PROTOCOL_SPELLINGS.join(", ")} (case-insensitive). Attributes previously set for the skipped entry's protocol are reset, as if the entry had been removed.`);
|
|
8377
|
+
continue;
|
|
8378
|
+
}
|
|
8255
8379
|
protocol = normalized;
|
|
8256
8380
|
}
|
|
8257
|
-
if (onMalformed
|
|
8381
|
+
if (onMalformed !== "skip" && seenProtocols.has(protocol)) warn(`SNS topic ${logicalId}: DeliveryStatusLogging declares more than one entry for the "${protocol}" attribute prefix (${JSON.stringify(config["Protocol"])} canonicalizes to it). AWS has one attribute set per prefix, so these are merged per field — a later entry overwrites only the sub-fields it declares, and a field it omits keeps the earlier entry's value. Declare a single entry per protocol.`);
|
|
8258
8382
|
seenProtocols.add(protocol);
|
|
8259
8383
|
for (const suffix of SNS_DELIVERY_STATUS_ATTRIBUTE_SUFFIXES) {
|
|
8260
8384
|
const value = config[suffix];
|
|
@@ -8330,10 +8454,13 @@ function normalizeDeliveryStatusProtocol(input) {
|
|
|
8330
8454
|
}
|
|
8331
8455
|
}
|
|
8332
8456
|
/**
|
|
8333
|
-
* Variant used by `create()`
|
|
8334
|
-
*
|
|
8335
|
-
*
|
|
8336
|
-
* `InvalidParameter`
|
|
8457
|
+
* Variant used by `create()` (the `'throw'` mode of
|
|
8458
|
+
* `buildDeliveryStatusAttributeMap`) to fail fast when a template carries
|
|
8459
|
+
* an unknown protocol. Throws a clear error naming the offending value so
|
|
8460
|
+
* the user sees what to fix instead of AWS's generic `InvalidParameter`
|
|
8461
|
+
* rejection. `update()`'s desired side warns-and-skips instead (issue
|
|
8462
|
+
* #1538) because its bag can be a cdkd state record on a rollback replay
|
|
8463
|
+
* or `drift --revert`.
|
|
8337
8464
|
*/
|
|
8338
8465
|
function normalizeDeliveryStatusProtocolOrThrow(input, logicalId) {
|
|
8339
8466
|
const normalized = normalizeDeliveryStatusProtocol(input);
|
|
@@ -9910,11 +10037,11 @@ var LambdaUrlProvider = class {
|
|
|
9910
10037
|
/**
|
|
9911
10038
|
* Create a Lambda Function URL
|
|
9912
10039
|
*/
|
|
9913
|
-
async create(logicalId, resourceType, properties) {
|
|
10040
|
+
async create(logicalId, resourceType, properties, context) {
|
|
9914
10041
|
this.logger.debug(`Creating Lambda URL ${logicalId}`);
|
|
9915
10042
|
const targetFunctionArn = properties["TargetFunctionArn"];
|
|
9916
10043
|
if (!targetFunctionArn) throw new ProvisioningError(`TargetFunctionArn is required for Lambda URL ${logicalId}`, resourceType, logicalId);
|
|
9917
|
-
const authType = requireConfigString(properties["AuthType"], "NONE", "AWS::Lambda::Url AuthType");
|
|
10044
|
+
const authType = requireConfigString(properties["AuthType"], "NONE", "AWS::Lambda::Url AuthType", replayWarn(this.logger, context));
|
|
9918
10045
|
try {
|
|
9919
10046
|
const cors = properties["Cors"];
|
|
9920
10047
|
const createParams = {
|
|
@@ -11519,7 +11646,7 @@ var DynamoDBTableProvider = class {
|
|
|
11519
11646
|
/**
|
|
11520
11647
|
* Create a DynamoDB table
|
|
11521
11648
|
*/
|
|
11522
|
-
async create(logicalId, resourceType, properties) {
|
|
11649
|
+
async create(logicalId, resourceType, properties, context) {
|
|
11523
11650
|
this.logger.debug(`Creating DynamoDB table ${logicalId}`);
|
|
11524
11651
|
const tableName = properties["TableName"] || generateResourceName(logicalId, { maxLength: 255 });
|
|
11525
11652
|
const keySchema = properties["KeySchema"];
|
|
@@ -11528,7 +11655,7 @@ var DynamoDBTableProvider = class {
|
|
|
11528
11655
|
if (!attributeDefinitions) throw new ProvisioningError(`AttributeDefinitions is required for DynamoDB table ${logicalId}`, resourceType, logicalId);
|
|
11529
11656
|
let tableCreated = false;
|
|
11530
11657
|
try {
|
|
11531
|
-
const billingMode = properties["BillingMode"]
|
|
11658
|
+
const billingMode = requireConfigString(properties["BillingMode"], "PROVISIONED", "AWS::DynamoDB::Table BillingMode", replayWarn(this.logger, context));
|
|
11532
11659
|
const createParams = {
|
|
11533
11660
|
TableName: tableName,
|
|
11534
11661
|
KeySchema: keySchema,
|
|
@@ -11602,9 +11729,15 @@ var DynamoDBTableProvider = class {
|
|
|
11602
11729
|
if (table?.TableArn) await this.applyTagDiff(table.TableArn, previousProperties["Tags"], properties["Tags"]);
|
|
11603
11730
|
const normalizeTableClass = (v) => typeof v === "string" && v.length > 0 ? v : "STANDARD";
|
|
11604
11731
|
const tableClassChanged = normalizeTableClass(properties["TableClass"]) !== normalizeTableClass(previousProperties["TableClass"]);
|
|
11605
|
-
const
|
|
11732
|
+
const prevBillingMode = previousProperties["BillingMode"];
|
|
11733
|
+
let billingModeUnusable = false;
|
|
11734
|
+
const requestedBillingMode = properties["BillingMode"] === void 0 ? void 0 : requireConfigString(properties["BillingMode"], "PROVISIONED", "AWS::DynamoDB::Table BillingMode", { onUnusable: (message) => {
|
|
11735
|
+
billingModeUnusable = true;
|
|
11736
|
+
this.logger.warn(`${message} The table's current billing mode${prevBillingMode ? ` (${prevBillingMode})` : ""} is kept for this update rather than flipped to the default.`);
|
|
11737
|
+
} });
|
|
11738
|
+
const billingMode = billingModeUnusable ? prevBillingMode : requestedBillingMode;
|
|
11739
|
+
const billingOrThroughputChanged = JSON.stringify(billingMode) !== JSON.stringify(prevBillingMode) || JSON.stringify(properties["ProvisionedThroughput"]) !== JSON.stringify(previousProperties["ProvisionedThroughput"]);
|
|
11606
11740
|
if (billingOrThroughputChanged || tableClassChanged) {
|
|
11607
|
-
const billingMode = properties["BillingMode"];
|
|
11608
11741
|
const updateInput = { TableName: physicalId };
|
|
11609
11742
|
if (billingOrThroughputChanged && billingMode) updateInput.BillingMode = billingMode;
|
|
11610
11743
|
if (tableClassChanged) updateInput.TableClass = normalizeTableClass(properties["TableClass"]);
|
|
@@ -12557,7 +12690,7 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
12557
12690
|
if (streamSpecInput != null) {
|
|
12558
12691
|
let streamViewType;
|
|
12559
12692
|
try {
|
|
12560
|
-
streamViewType = readConfigString(streamSpecInput, "StreamViewType", "NEW_AND_OLD_IMAGES", "AWS::DynamoDB::GlobalTable StreamSpecification");
|
|
12693
|
+
streamViewType = readConfigString(streamSpecInput, "StreamViewType", "NEW_AND_OLD_IMAGES", "AWS::DynamoDB::GlobalTable StreamSpecification", replayWarn(this.logger, context));
|
|
12561
12694
|
} catch (error) {
|
|
12562
12695
|
throw new ProvisioningError(error instanceof Error ? error.message : String(error), resourceType, logicalId, void 0, error instanceof Error ? error : void 0);
|
|
12563
12696
|
}
|
|
@@ -12574,7 +12707,7 @@ var DynamoDBGlobalTableProvider = class {
|
|
|
12574
12707
|
}
|
|
12575
12708
|
let sdkIndexes;
|
|
12576
12709
|
try {
|
|
12577
|
-
sdkIndexes = toSdkGlobalSecondaryIndexes(properties, currentRegion, billingMode, "min", diagnostics);
|
|
12710
|
+
sdkIndexes = toSdkGlobalSecondaryIndexes(properties, currentRegion, billingMode, "min", diagnostics, replayWarn(this.logger, context).onUnusable);
|
|
12578
12711
|
} catch (error) {
|
|
12579
12712
|
throw new ProvisioningError(error instanceof Error ? error.message : String(error), resourceType, logicalId, void 0, error instanceof Error ? error : void 0);
|
|
12580
12713
|
}
|
|
@@ -14554,9 +14687,16 @@ function pickAutoScalingCapacity(autoScaling, source) {
|
|
|
14554
14687
|
* written before this fix (and hand-authored templates) can carry them, and
|
|
14555
14688
|
* silently re-deriving over an explicit value would be a regression.
|
|
14556
14689
|
*/
|
|
14557
|
-
function toSdkGlobalSecondaryIndexes(properties, region, billingMode, source = "min", diagnostics) {
|
|
14690
|
+
function toSdkGlobalSecondaryIndexes(properties, region, billingMode, source = "min", diagnostics, onUnusableIndexes) {
|
|
14558
14691
|
const rawIndexes = properties["GlobalSecondaryIndexes"];
|
|
14559
|
-
if (rawIndexes !== void 0 && !Array.isArray(rawIndexes))
|
|
14692
|
+
if (rawIndexes !== void 0 && !Array.isArray(rawIndexes)) {
|
|
14693
|
+
const shapeDetail = `AWS::DynamoDB::GlobalTable GlobalSecondaryIndexes must be an array, got ${typeof rawIndexes} (${JSON.stringify(rawIndexes)?.slice(0, 200)}).`;
|
|
14694
|
+
if (onUnusableIndexes) {
|
|
14695
|
+
onUnusableIndexes(`${shapeDetail} Omitting the malformed block, so this create carries NO indexes; the same value is REFUSED on a template-path create`);
|
|
14696
|
+
return [];
|
|
14697
|
+
}
|
|
14698
|
+
throw new Error(`${shapeDetail} An unresolved intrinsic here would otherwise deploy a table with no indexes.`);
|
|
14699
|
+
}
|
|
14560
14700
|
const cfnIndexes = rawIndexes ?? [];
|
|
14561
14701
|
if (cfnIndexes.length === 0) return [];
|
|
14562
14702
|
const replicas = properties["Replicas"] ?? [];
|
|
@@ -44575,9 +44715,9 @@ var S3DirectoryBucketProvider = class {
|
|
|
44575
44715
|
/**
|
|
44576
44716
|
* Create an S3 Express Directory Bucket
|
|
44577
44717
|
*/
|
|
44578
|
-
async create(logicalId, resourceType, properties) {
|
|
44718
|
+
async create(logicalId, resourceType, properties, context) {
|
|
44579
44719
|
this.logger.debug(`Creating S3 Express Directory Bucket ${logicalId}`);
|
|
44580
|
-
const dataRedundancy = requireConfigString(properties["DataRedundancy"], "SingleAvailabilityZone", "AWS::S3Express::DirectoryBucket DataRedundancy");
|
|
44720
|
+
const dataRedundancy = requireConfigString(properties["DataRedundancy"], "SingleAvailabilityZone", "AWS::S3Express::DirectoryBucket DataRedundancy", replayWarn(this.logger, context));
|
|
44581
44721
|
const azName = properties["LocationName"]?.replace(/--x-s3$/, "") || "us-east-1a";
|
|
44582
44722
|
const azId = await this.getAzId(azName);
|
|
44583
44723
|
let bucketName = properties["BucketName"];
|
|
@@ -67565,7 +67705,7 @@ function createMigrateCommand() {
|
|
|
67565
67705
|
*/
|
|
67566
67706
|
function buildProgram() {
|
|
67567
67707
|
const program = new Command();
|
|
67568
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.
|
|
67708
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.51");
|
|
67569
67709
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
67570
67710
|
const { profile } = actionCommand.optsWithGlobals();
|
|
67571
67711
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|