@go-to-k/cdkd 0.290.4 → 0.290.5
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-NffO_bpL.js → asg-provider-DU7mN-cS.js} +2 -2
- package/dist/{asg-provider-NffO_bpL.js.map → asg-provider-DU7mN-cS.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-DD7JE_Ic.js → deploy-engine-WFO9o9M0.js} +219 -43
- package/dist/deploy-engine-WFO9o9M0.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-20PIJFu9.js → program-D30EPjOn.js} +306 -105
- package/dist/{program-20PIJFu9.js.map → program-D30EPjOn.js.map} +1 -1
- package/dist/{version-BUcQz4SU.js → version-BBIkp8ja.js} +2 -2
- package/dist/{version-BUcQz4SU.js.map → version-BBIkp8ja.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-DD7JE_Ic.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as isVersionOnlyInvocation, t as getCdkdVersion } from "./version-
|
|
2
|
+
import { n as isVersionOnlyInvocation, t as getCdkdVersion } from "./version-BBIkp8ja.js";
|
|
3
3
|
|
|
4
4
|
//#region src/cli/pipe-close-handler.ts
|
|
5
5
|
/**
|
|
@@ -74,7 +74,7 @@ async function main() {
|
|
|
74
74
|
console.log(getCdkdVersion());
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
|
-
const { buildProgram } = await import("./program-
|
|
77
|
+
const { buildProgram } = await import("./program-D30EPjOn.js");
|
|
78
78
|
const program = buildProgram();
|
|
79
79
|
const args = reorderArgs(process.argv);
|
|
80
80
|
await program.parseAsync(args);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { b as displayIdent, d as applyDefaultNameForFallback, f as explicitNamePropertyFor, g as looksLikeCdkdGeneratedName, h as getCurrentStackName, m as generateResourceNameWithFallback, n as getLogger, p as generateResourceName, r as isStdoutReservedForPayload, s as getLiveRenderer, v as withStackName, x as displaySafe, y as UNRENDERABLE } from "./logger-th1myfgh.js";
|
|
2
2
|
import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
|
|
3
|
-
import { t as getCdkdVersion } from "./version-
|
|
3
|
+
import { t as getCdkdVersion } from "./version-BBIkp8ja.js";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import { createHash, randomUUID } from "node:crypto";
|
|
6
6
|
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -9164,9 +9164,60 @@ function safeJournalText(value) {
|
|
|
9164
9164
|
return displaySafe(value, { asciiOnly: true }) || "<unrenderable>";
|
|
9165
9165
|
}
|
|
9166
9166
|
/**
|
|
9167
|
+
* The per-operation shape check (issue #3140). The journal is an unchecked
|
|
9168
|
+
* cast beyond `journalVersion` and `segments` being an array, and the
|
|
9169
|
+
* executor keys EVERY lookup on `op.logicalId` -- `stateResources[..]`,
|
|
9170
|
+
* `orphanLogicalIds.has(..)`, the events it records -- so a non-string id
|
|
9171
|
+
* planted in the bucket either coerces at each lookup (`123` finds the
|
|
9172
|
+
* record named `'123'`) or throws a raw `TypeError` at the first one (an
|
|
9173
|
+
* object whose `toString` is not callable, the issue #2947 shape). Refused
|
|
9174
|
+
* HERE, once, so no downstream reader has to remember; the executor keeps its
|
|
9175
|
+
* own `typeof` guard on the one pasted command as defense-in-depth, because
|
|
9176
|
+
* the deploy engine's in-process rollback reaches it without this parser.
|
|
9177
|
+
*
|
|
9178
|
+
* Only the fields a lookup or a route is keyed on: `logicalId` (non-empty
|
|
9179
|
+
* string), `resourceType` (string), `changeType` (string -- an unknown value
|
|
9180
|
+
* lands on the executor's UPDATE arm by design, pinned by a case there), and
|
|
9181
|
+
* `physicalId` when present (string). `previousState` and the rest stay as
|
|
9182
|
+
* they were; a bad value there fails the op it belongs to, not the parse.
|
|
9183
|
+
*
|
|
9184
|
+
* The refusal names the INDEX and the TYPE, never the value -- there is
|
|
9185
|
+
* nothing to sanitize, so nothing to get wrong.
|
|
9186
|
+
*/
|
|
9187
|
+
function refuseMalformedOperation(shownStack, where, op) {
|
|
9188
|
+
const fail = (field, value, expected) => refuseMalformed(shownStack, `${where}.${field} must be ${expected} (got ${kind(value)}).`);
|
|
9189
|
+
if (typeof op !== "object" || op === null || Array.isArray(op)) refuseMalformed(shownStack, `${where} must be an object (got ${kind(op)}).`);
|
|
9190
|
+
const o = op;
|
|
9191
|
+
if (typeof o["logicalId"] !== "string" || o["logicalId"].length === 0) fail("logicalId", o["logicalId"], "a non-empty string");
|
|
9192
|
+
if (typeof o["resourceType"] !== "string") fail("resourceType", o["resourceType"], "a string");
|
|
9193
|
+
if (typeof o["changeType"] !== "string") fail("changeType", o["changeType"], "a string");
|
|
9194
|
+
if (o["physicalId"] !== void 0 && typeof o["physicalId"] !== "string") fail("physicalId", o["physicalId"], "a string when present");
|
|
9195
|
+
}
|
|
9196
|
+
/** The TYPE of a JSON-derived value, for a refusal that must not echo the value. */
|
|
9197
|
+
function kind(v) {
|
|
9198
|
+
return v === null ? "null" : Array.isArray(v) ? "array" : typeof v;
|
|
9199
|
+
}
|
|
9200
|
+
/**
|
|
9201
|
+
* The one spelling of a malformed-journal refusal. `detail` is built from
|
|
9202
|
+
* indices, field names and `kind()` words only -- never a journal value -- and
|
|
9203
|
+
* every refusal names the way out, as `UnknownRollbackJournalVersionError`
|
|
9204
|
+
* names `Upgrade cdkd`: the journal is a sibling of `state.json`, so removing
|
|
9205
|
+
* that one object discards it (`cdkd destroy` sweeps it as well), and no
|
|
9206
|
+
* other stack is affected because `cdkd rollback` never parses another
|
|
9207
|
+
* stack's journal. The same text reaches the deploy engine's `Failed to write
|
|
9208
|
+
* rollback journal` warning, since appending a segment parses the existing
|
|
9209
|
+
* journal first.
|
|
9210
|
+
*/
|
|
9211
|
+
function refuseMalformed(shownStack, detail) {
|
|
9212
|
+
throw new Error(`Rollback journal for '${shownStack}' is malformed: ${detail} Remove the stack's rollback-journal.json (next to its state.json) to discard it.`);
|
|
9213
|
+
}
|
|
9214
|
+
/**
|
|
9167
9215
|
* Parse + validate a journal body. Throws
|
|
9168
9216
|
* {@link UnknownRollbackJournalVersionError} on a newer version, and a plain
|
|
9169
|
-
* Error on a structurally-invalid body
|
|
9217
|
+
* Error on a structurally-invalid body -- including, since issue #3140, a
|
|
9218
|
+
* segment that is not an object, an `operations` that is not an array, and an
|
|
9219
|
+
* operation whose `logicalId` / `resourceType` / `changeType` / `physicalId`
|
|
9220
|
+
* is not the string the executor keys on (see `refuseMalformedOperation`).
|
|
9170
9221
|
*/
|
|
9171
9222
|
function parseRollbackJournal(bodyString, stackName) {
|
|
9172
9223
|
const shownStack = safeJournalText(stackName);
|
|
@@ -9186,6 +9237,16 @@ function parseRollbackJournal(bodyString, stackName) {
|
|
|
9186
9237
|
}
|
|
9187
9238
|
if (j.journalVersion > 1) throw new UnknownRollbackJournalVersionError(j.journalVersion, stackName);
|
|
9188
9239
|
if (!Array.isArray(j.segments)) throw new Error(`Rollback journal for '${shownStack}' is missing a 'segments' array.`);
|
|
9240
|
+
j.segments.forEach((segment, s) => {
|
|
9241
|
+
if (typeof segment !== "object" || segment === null || Array.isArray(segment)) refuseMalformed(shownStack, `segments[${s}] must be an object (got ${kind(segment)}).`);
|
|
9242
|
+
const seg = segment;
|
|
9243
|
+
if (!Array.isArray(seg["operations"])) refuseMalformed(shownStack, `segments[${s}].operations must be an array (got ${kind(seg["operations"])}).`);
|
|
9244
|
+
seg["operations"].forEach((op, i) => refuseMalformedOperation(shownStack, `segments[${s}].operations[${i}]`, op));
|
|
9245
|
+
if (seg["failedOperations"] !== void 0) {
|
|
9246
|
+
if (!Array.isArray(seg["failedOperations"])) refuseMalformed(shownStack, `segments[${s}].failedOperations must be an array when present (got ${kind(seg["failedOperations"])}).`);
|
|
9247
|
+
seg["failedOperations"].forEach((op, i) => refuseMalformedOperation(shownStack, `segments[${s}].failedOperations[${i}]`, op));
|
|
9248
|
+
}
|
|
9249
|
+
});
|
|
9189
9250
|
return {
|
|
9190
9251
|
journalVersion: j.journalVersion,
|
|
9191
9252
|
stackName: j.stackName ?? stackName,
|
|
@@ -13148,7 +13209,11 @@ const UNKNOWN_PART_PLACEHOLDER = "\0";
|
|
|
13148
13209
|
* longer equals the leaf's text around the middle, so the arm refuses) -- and,
|
|
13149
13210
|
* through the frame arm's rewrite, for the nested-stack parameter recorder's
|
|
13150
13211
|
* `frameSpellingOf`, which carries a framed parameter to the child only when
|
|
13151
|
-
*
|
|
13212
|
+
* the position pass rewrote it -- which, on a value the recorder's gate (ii)
|
|
13213
|
+
* finds the scan silent on, only the frame arm can do (the value scan, the
|
|
13214
|
+
* skeleton arm and the cross-stack arm each rewrite an object-sourced leaf
|
|
13215
|
+
* whose WHOLE value is a recorded plaintext, and (ii) is what refuses that
|
|
13216
|
+
* value). The recorder's own rendering of such a part does not
|
|
13152
13217
|
* decide the case: a part outside the token leaves its one span and service
|
|
13153
13218
|
* prefix the same either way.
|
|
13154
13219
|
*
|
|
@@ -13422,8 +13487,15 @@ function positionByCrossStackSource(bag, source, secrets) {
|
|
|
13422
13487
|
* the source leaf is an `Fn::Join` / `Fn::Sub` there is none, so the leaf fell
|
|
13423
13488
|
* to the value scan — and the value map is keyed by the resolved PLAINTEXT, so
|
|
13424
13489
|
* a colliding pair collapses there exactly as it did before #1904. That is the
|
|
13425
|
-
* DOMINANT CDK shape rather than an edge case:
|
|
13426
|
-
* token renders the secret ARN as a `Ref`, hence an `Fn::Join`.
|
|
13490
|
+
* DOMINANT CDK shape rather than an edge case: a secret reached through an L2
|
|
13491
|
+
* token usually renders the secret ARN as a `Ref`, hence an `Fn::Join`. The
|
|
13492
|
+
* exceptions render a plain `{{resolve:...}}` string, which the literal arm
|
|
13493
|
+
* already positions: a secret imported by a LITERAL ARN
|
|
13494
|
+
* (`Secret.fromSecretCompleteArn` / `fromSecretPartialArn`, whose
|
|
13495
|
+
* `secretValue` and `secretValueFromJson` both inline it),
|
|
13496
|
+
* `SecretValue.secretsManager('<literal arn>')` and
|
|
13497
|
+
* `SecretValue.ssmSecure(...)` (synth-probed on this repo's aws-cdk-lib,
|
|
13498
|
+
* issue #3143; `new Secret(...)` and `fromSecretNameV2` are the join).
|
|
13427
13499
|
*
|
|
13428
13500
|
* Three conditions must ALL hold before an expression is persisted, and each
|
|
13429
13501
|
* removes a different way of being wrong:
|
|
@@ -23430,20 +23502,22 @@ const recordedSecretExpressions = {
|
|
|
23430
23502
|
*/
|
|
23431
23503
|
const cachedEc2InstanceAttributes = Object.create(null);
|
|
23432
23504
|
/**
|
|
23433
|
-
* The
|
|
23434
|
-
* #3096), each holding a value the resolver read LIVE because the
|
|
23435
|
-
* record omitted it — `definedAttributes` drops a member the provider
|
|
23436
|
-
* not read back (issue #3077), so the `Fn::GetAtt` falls out of the
|
|
23437
|
-
* lookup and into `constructAttribute`'s per-type arm. Keyed by physical
|
|
23438
|
-
*
|
|
23439
|
-
*
|
|
23440
|
-
*
|
|
23441
|
-
*
|
|
23442
|
-
*
|
|
23443
|
-
*
|
|
23444
|
-
*
|
|
23445
|
-
*
|
|
23446
|
-
*
|
|
23505
|
+
* The three sibling caches of {@link cachedEc2InstanceAttributes} (issues
|
|
23506
|
+
* #3096 / #3097), each holding a value the resolver read LIVE because the
|
|
23507
|
+
* state record omitted it — `definedAttributes` drops a member the provider
|
|
23508
|
+
* could not read back (issue #3077), so the `Fn::GetAtt` falls out of the
|
|
23509
|
+
* flat lookup and into `constructAttribute`'s per-type arm. Keyed by physical
|
|
23510
|
+
* id: the read is region-pinned (`clientsForRegion(this.explicitRegion)`),
|
|
23511
|
+
* so the key names one resource in that region, and the value — a default
|
|
23512
|
+
* security group id, a distribution hostname, a security group's VPC —
|
|
23513
|
+
* never changes; like the instance cache, a refusal caches nothing. Same
|
|
23514
|
+
* process lifetime, cleared together with it by {@link resetAccountInfoCache}.
|
|
23515
|
+
* The RDS `DBProxy` / `DBProxyEndpoint` `VpcId` arms have no cache because
|
|
23516
|
+
* they have no live read: `AwsClients` exposes no RDS client and this file
|
|
23517
|
+
* imports none, so those two arms refuse outright (see
|
|
23518
|
+
* `refuseUnservedAttribute`'s callers).
|
|
23519
|
+
*
|
|
23520
|
+
* All four are NULL-PROTOTYPE objects (#3096 delta review, measured): the
|
|
23447
23521
|
* key is a state-record physical id, and on a plain `{}` a record holding
|
|
23448
23522
|
* `constructor` / `__proto__` / `hasOwnProperty` read a FUNCTION out of
|
|
23449
23523
|
* `Object.prototype` as the cached value — served with zero AWS calls, ahead
|
|
@@ -23452,6 +23526,7 @@ const cachedEc2InstanceAttributes = Object.create(null);
|
|
|
23452
23526
|
*/
|
|
23453
23527
|
const cachedVpcDefaultSecurityGroups = Object.create(null);
|
|
23454
23528
|
const cachedCloudFrontDomainNames = Object.create(null);
|
|
23529
|
+
const cachedSecurityGroupVpcIds = Object.create(null);
|
|
23455
23530
|
/**
|
|
23456
23531
|
* The region this call answers for: the caller's override, else the ambient one.
|
|
23457
23532
|
*
|
|
@@ -23900,6 +23975,29 @@ async function resolveAccountIdentity() {
|
|
|
23900
23975
|
}
|
|
23901
23976
|
}
|
|
23902
23977
|
/**
|
|
23978
|
+
* Is a STORED `''` for this attribute a value the resource can never have —
|
|
23979
|
+
* so the flat lookup must read it as ABSENT and let the live arm run?
|
|
23980
|
+
*
|
|
23981
|
+
* Exactly one attribute qualifies today (issue #3097 review): an
|
|
23982
|
+
* `AWS::EC2::SecurityGroup`'s `VpcId`. Every security group lives in a VPC
|
|
23983
|
+
* (EC2-Classic retired 2022-08-15), so `''` can only be the pre-#3097
|
|
23984
|
+
* provider's copy of a template that declared no `VpcId` — and that record is
|
|
23985
|
+
* rewritten only by an `update()`, which a no-change deploy never issues, so
|
|
23986
|
+
* without this carve-out the stored `''` shadows the live arm for the life of
|
|
23987
|
+
* the record. The record itself stays `''` until the next update; only the
|
|
23988
|
+
* RESOLUTION changes.
|
|
23989
|
+
*
|
|
23990
|
+
* Deliberately NOT a general "`''` means absent" rule: #3077 records a settled
|
|
23991
|
+
* EC2 instance's missing public address as the KNOWN empty `''`
|
|
23992
|
+
* (CloudFormation's own answer), and that one must keep being served from
|
|
23993
|
+
* state rather than sent back to `DescribeInstances` on every resolution.
|
|
23994
|
+
* A new entry here needs the same argument — that `''` is IMPOSSIBLE for the
|
|
23995
|
+
* attribute, not merely unlikely.
|
|
23996
|
+
*/
|
|
23997
|
+
function isImpossibleEmptyStoredAttribute(resourceType, attributeName, storedValue) {
|
|
23998
|
+
return storedValue === "" && resourceType === "AWS::EC2::SecurityGroup" && attributeName === "VpcId";
|
|
23999
|
+
}
|
|
24000
|
+
/**
|
|
23903
24001
|
* Does a constructed `Fn::GetAtt` answer embed the placeholder account id?
|
|
23904
24002
|
*
|
|
23905
24003
|
* The guard in `constructGuardedAttribute` used to test
|
|
@@ -25133,7 +25231,8 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
25133
25231
|
const resource = Object.hasOwn(context.resources, logicalId) ? context.resources[logicalId] : void 0;
|
|
25134
25232
|
if (!resource) throw markNonRetryable(/* @__PURE__ */ new Error(`Resource ${logicalId} not found for Fn::GetAtt`));
|
|
25135
25233
|
if (!(resource.resourceType === "AWS::EC2::VPC" && attributeName === "Ipv6CidrBlocks") && resource.attributes !== void 0) {
|
|
25136
|
-
const
|
|
25234
|
+
const storedValue = Object.hasOwn(resource.attributes, attributeName) ? resource.attributes[attributeName] : void 0;
|
|
25235
|
+
const flatValue = isImpossibleEmptyStoredAttribute(resource.resourceType, attributeName, storedValue) ? void 0 : storedValue;
|
|
25137
25236
|
if (flatValue !== void 0) {
|
|
25138
25237
|
this.rejectPlaceholderArnAttribute(resource, attributeName, flatValue, logicalId, context);
|
|
25139
25238
|
if (resource.resourceType === "AWS::Route53::HostedZone" && attributeName === "NameServers" && typeof flatValue === "string") {
|
|
@@ -25578,7 +25677,38 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
25578
25677
|
}
|
|
25579
25678
|
if (resourceType === "AWS::EC2::SecurityGroup") switch (attributeName) {
|
|
25580
25679
|
case "GroupId": return physicalId;
|
|
25581
|
-
case "VpcId":
|
|
25680
|
+
case "VpcId": {
|
|
25681
|
+
if (!/^sg-[0-9a-f]+$/.test(physicalId)) throw markNonRetryable(new IntrinsicResolutionRefusalError(`Cannot resolve Fn::GetAtt [${logicalId}, VpcId] for AWS::EC2::SecurityGroup: the state record's physical id "${displaySafe(this.maskThenStripThenMask(physicalId, context)).slice(0, 64)}" is not a security group id (sg-<hex>), so cdkd will not look it up. Repair the record (cdkd import, or re-create the security group) and deploy again.`));
|
|
25682
|
+
const cachedVpcId = cachedSecurityGroupVpcIds[physicalId];
|
|
25683
|
+
if (cachedVpcId !== void 0) return cachedVpcId;
|
|
25684
|
+
let vpcId;
|
|
25685
|
+
try {
|
|
25686
|
+
vpcId = (await this.clientsForRegion(this.explicitRegion).ec2.send(new DescribeSecurityGroupsCommand({ GroupIds: [physicalId] }))).SecurityGroups?.[0]?.VpcId;
|
|
25687
|
+
} catch (err) {
|
|
25688
|
+
this.refuseUnservedAttribute({
|
|
25689
|
+
logicalId,
|
|
25690
|
+
attributeName,
|
|
25691
|
+
resourceType,
|
|
25692
|
+
physicalId,
|
|
25693
|
+
context,
|
|
25694
|
+
observed: this.describeFailureObserved("DescribeSecurityGroups", err, context),
|
|
25695
|
+
remedy: "Fix the read (the ec2:DescribeSecurityGroups permission, or the region) and deploy again."
|
|
25696
|
+
});
|
|
25697
|
+
}
|
|
25698
|
+
if (vpcId) {
|
|
25699
|
+
cachedSecurityGroupVpcIds[physicalId] = vpcId;
|
|
25700
|
+
return vpcId;
|
|
25701
|
+
}
|
|
25702
|
+
this.refuseUnservedAttribute({
|
|
25703
|
+
logicalId,
|
|
25704
|
+
attributeName,
|
|
25705
|
+
resourceType,
|
|
25706
|
+
physicalId,
|
|
25707
|
+
context,
|
|
25708
|
+
observed: "DescribeSecurityGroups reports no VpcId for the group",
|
|
25709
|
+
remedy: "Check the security group in the console, or reference the attribute from a later deploy."
|
|
25710
|
+
});
|
|
25711
|
+
}
|
|
25582
25712
|
default: return this.guardedPhysicalIdFallback(logicalId, attributeName, resourceType, physicalId, context);
|
|
25583
25713
|
}
|
|
25584
25714
|
if (resourceType === "AWS::EC2::Subnet") switch (attributeName) {
|
|
@@ -25716,9 +25846,12 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
25716
25846
|
* belongs, a `vpc-...` in a security-group slot, a distribution id where a
|
|
25717
25847
|
* hostname belongs, a proxy name in a `VpcId` position. Loud only where AWS
|
|
25718
25848
|
* rejects the shape; an Output, an export or a free-text property carried it
|
|
25719
|
-
* silently. The
|
|
25720
|
-
*
|
|
25721
|
-
*
|
|
25849
|
+
* silently. The security group `VpcId` arm (issue #3097) joined with the
|
|
25850
|
+
* opposite pre-fix defect — it answered `undefined`, which `Fn::Join`
|
|
25851
|
+
* renders `'undefined'` — and takes the same refusal. The physical id can
|
|
25852
|
+
* never be the value for these attributes, so the honest answer is a
|
|
25853
|
+
* refusal naming the resource, the attribute, what was observed and the
|
|
25854
|
+
* remedy.
|
|
25722
25855
|
*
|
|
25723
25856
|
* DELIBERATELY NOT `markNonRetryable`, unlike every other refusal in this
|
|
25724
25857
|
* file but the fabricated-account guard: the verdict is TIME-DEPENDENT. A
|
|
@@ -25734,7 +25867,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
|
|
|
25734
25867
|
* interpolated hole happens to carry a pattern — the `logicalId` (the #1838
|
|
25735
25868
|
* hazard: `DependencyViolation` and two other bare words), or the error
|
|
25736
25869
|
* CLASS name `describeFailureObserved` puts in `observed`, which none of
|
|
25737
|
-
* these
|
|
25870
|
+
* these four reads raises — and then re-describes and can heal.
|
|
25738
25871
|
* Measured, not designed: the fabricated-account guard sits in exactly the
|
|
25739
25872
|
* same place. Threading a sanitized SDK error as `cause` so a throttled
|
|
25740
25873
|
* describe classifies as transient was considered and left out — a
|
|
@@ -29016,7 +29149,7 @@ var CloudControlProvider = class {
|
|
|
29016
29149
|
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
29017
29150
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
29018
29151
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
29019
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
29152
|
+
const { ASGProvider } = await import("./asg-provider-DU7mN-cS.js").then((n) => n.n);
|
|
29020
29153
|
const asgProvider = new ASGProvider();
|
|
29021
29154
|
return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
|
|
29022
29155
|
}
|
|
@@ -34214,20 +34347,22 @@ const WARM_THROUGHPUT_MEMBERS = ["ReadUnitsPerSecond", "WriteUnitsPerSecond"];
|
|
|
34214
34347
|
*
|
|
34215
34348
|
* The accepted STRING set is `Number()`'s, which is WIDER than a decimal
|
|
34216
34349
|
* integer: `'0x1e'`, `'0o36'`, `'1e3'`, `'30.5'` and `' 30 '` all coerce.
|
|
34217
|
-
* CloudFormation accepts
|
|
34218
|
-
*
|
|
34219
|
-
*
|
|
34220
|
-
*
|
|
34221
|
-
*
|
|
34222
|
-
* the
|
|
34223
|
-
*
|
|
34224
|
-
*
|
|
34225
|
-
*
|
|
34226
|
-
*
|
|
34227
|
-
*
|
|
34228
|
-
*
|
|
34229
|
-
*
|
|
34230
|
-
*
|
|
34350
|
+
* CloudFormation accepts NONE of those on a DynamoDB capacity and only the
|
|
34351
|
+
* LAST on `AWS::Logs::LogGroup.RetentionInDays` (both measured — the tables
|
|
34352
|
+
* are on {@link toCfnInteger}), so this helper is for the GUARD callers only:
|
|
34353
|
+
* `stateful-types.ts`'s `has-retention`, the DynamoDB already-matches /
|
|
34354
|
+
* decrease / zero-capacity tests, the live-readback compares. A guard is safe
|
|
34355
|
+
* on the wider set — over-acceptance there can only produce MORE refusals or
|
|
34356
|
+
* skip fewer calls. A caller that FORWARDS the number to AWS reads through the
|
|
34357
|
+
* grammar CloudFormation measured for that handler instead:
|
|
34358
|
+
* `logs-loggroup-provider.ts` through {@link toCfnInteger} (issue
|
|
34359
|
+
* [#2698](https://github.com/go-to-k/cdkd/issues/2698)), every DynamoDB
|
|
34360
|
+
* capacity / throughput forwarder (`coerceWarmThroughput` below, the
|
|
34361
|
+
* `GlobalTable` provider's `ProvisionedThroughput` / `OnDemandThroughput`
|
|
34362
|
+
* readers AND the diagnostic / mirror predicates paired with them) through
|
|
34363
|
+
* `config-shape.ts`'s `coerceCfnInteger` (issue
|
|
34364
|
+
* [#3135](https://github.com/go-to-k/cdkd/issues/3135)). A forwarder left on
|
|
34365
|
+
* THIS helper sends `Number('0x9')` for a template CloudFormation refuses.
|
|
34231
34366
|
*
|
|
34232
34367
|
* EXPORTED, and not because warm throughput needs it exported. This exact rule
|
|
34233
34368
|
* was hand-written three times — here, as `dynamodb-table-provider.ts`'s
|
|
@@ -34289,6 +34424,37 @@ function toFiniteNumber(value) {
|
|
|
34289
34424
|
* behaviour varies on padding, so each helper carries its own measurement and
|
|
34290
34425
|
* a caller picks by the property it forwards.
|
|
34291
34426
|
*
|
|
34427
|
+
* The DynamoDB measurement, read beside the Logs one so the two grammars sit
|
|
34428
|
+
* side by side (`AWS::DynamoDB::Table.ProvisionedThroughput.ReadCapacityUnits`
|
|
34429
|
+
* plus one `WriteCapacityUnits` row, us-east-1, 2026-09-14, issue
|
|
34430
|
+
* [#3135](https://github.com/go-to-k/cdkd/issues/3135); same protocol, live
|
|
34431
|
+
* value read back with `dynamodb describe-table`). "properties validation" is
|
|
34432
|
+
* CloudFormation's own template-property check, which fires BEFORE the
|
|
34433
|
+
* handler; "handler" is the DynamoDB resource handler's model validation:
|
|
34434
|
+
*
|
|
34435
|
+
* ```
|
|
34436
|
+
* template spelling CloudFormation live RCU after
|
|
34437
|
+
* 5 (JSON number) accepted 5
|
|
34438
|
+
* "6" accepted 6
|
|
34439
|
+
* "+8" accepted 8
|
|
34440
|
+
* "010" accepted (decimal, not octal) 10
|
|
34441
|
+
* " 7 " (padded) REJECTED (properties validation) unchanged
|
|
34442
|
+
* "7 " (trailing space) REJECTED (properties validation) unchanged
|
|
34443
|
+
* "" (empty string) REJECTED (properties validation) unchanged
|
|
34444
|
+
* "0x9" (RCU or WCU) REJECTED (handler) unchanged
|
|
34445
|
+
* "1e1" REJECTED (Validation failed) unchanged
|
|
34446
|
+
* "6.0" REJECTED (same) unchanged
|
|
34447
|
+
* "6.5" REJECTED (same) unchanged
|
|
34448
|
+
* ```
|
|
34449
|
+
*
|
|
34450
|
+
* The two agree on the digits (`/^[+-]?\d+$/`, hex / exponent / decimal-point
|
|
34451
|
+
* rejected by both) and DISAGREE on padding: the Logs handler trims, DynamoDB
|
|
34452
|
+
* rejects `" 7 "` and `"7 "` before any handler runs. So the DynamoDB
|
|
34453
|
+
* forwarders read through {@link coerceCfnInteger} itself — the no-trim
|
|
34454
|
+
* grammar — and NOT through this helper, whose trim is licensed by the Logs
|
|
34455
|
+
* measurement alone. `""` is not portable as "absent" either: on a REQUIRED
|
|
34456
|
+
* Integer it is rejected outright, where `RetentionInDays` reads it as absent.
|
|
34457
|
+
*
|
|
34292
34458
|
* What this helper does NOT decide: the empty / whitespace-only strings above
|
|
34293
34459
|
* are CloudFormation's spelling of "property absent", which is a statement
|
|
34294
34460
|
* about the PROPERTY, not about the number — they answer `undefined` here, and
|
|
@@ -34322,6 +34488,16 @@ function toCfnInteger(value) {
|
|
|
34322
34488
|
* Pure: takes the raw bag, returns numbers, logs nothing. Each caller owns its
|
|
34323
34489
|
* own message, so the wording stays consistent across that provider's send
|
|
34324
34490
|
* sites without forcing one wording across both providers.
|
|
34491
|
+
*
|
|
34492
|
+
* A member is read through {@link coerceCfnInteger} — CloudFormation's
|
|
34493
|
+
* measured DynamoDB Integer grammar (issue #3135, table on
|
|
34494
|
+
* {@link toCfnInteger}) — because this block is FORWARDED. A spelling
|
|
34495
|
+
* CloudFormation rejects (`" 7 "`, `"0x9"`, `"1e1"`, `"6.5"`) is therefore a
|
|
34496
|
+
* DROPPED member, named in `droppedMembers` exactly like an unresolved
|
|
34497
|
+
* intrinsic: the caller's diagnostic reports it and the live AWS value is left
|
|
34498
|
+
* alone. It is never read as ABSENT (the `=== undefined` test above runs on
|
|
34499
|
+
* the RAW value), and it is never forwarded as `Number()`'s reading, which
|
|
34500
|
+
* sent `7` for a template CloudFormation refuses.
|
|
34325
34501
|
*/
|
|
34326
34502
|
function coerceWarmThroughput(raw) {
|
|
34327
34503
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return { droppedMembers: [] };
|
|
@@ -34330,7 +34506,7 @@ function coerceWarmThroughput(raw) {
|
|
|
34330
34506
|
const droppedMembers = [];
|
|
34331
34507
|
for (const member of WARM_THROUGHPUT_MEMBERS) {
|
|
34332
34508
|
if (bag[member] === void 0) continue;
|
|
34333
|
-
const coerced =
|
|
34509
|
+
const coerced = coerceCfnInteger(bag[member]);
|
|
34334
34510
|
if (coerced === void 0) {
|
|
34335
34511
|
droppedMembers.push(member);
|
|
34336
34512
|
continue;
|
|
@@ -41672,5 +41848,5 @@ var DeployEngine = class DeployEngine {
|
|
|
41672
41848
|
};
|
|
41673
41849
|
|
|
41674
41850
|
//#endregion
|
|
41675
|
-
export { secretSafeKeyDisplay as $,
|
|
41676
|
-
//# sourceMappingURL=deploy-engine-
|
|
41851
|
+
export { secretSafeKeyDisplay as $, isCrossRegionRedirect as $n, CdkdError as $r, applyRoleArnIfSet as $t, planOrphanAdoption as A, forceQuitRecoveryClause as An, resolveStateBucketWithDefaultAndSource as Ar, isSettledInstanceState as At, formatResourceLine as B, shouldRetainResource as Bn, expectedOwnerParam as Br, readConfigString as Bt, createPreDeleteFinalSnapshot as C, isRetryableTransientError as Ci, redactSecretsForState as Cn, getDefaultStateBucketName as Cr, cfnRefValueFromPhysicalId as Ct, makeCanonicalizePropertiesFn as D, markRedactedCause as Di, rebuildClientForBucketRegion as Dn, resolveCaptureObservedState as Dr, isUnboundTemplateParameter as Dt, unsupportedFinalSnapshotError as E, markNonRetryable as Ei, S3StateBackend as En, resolveAutoAssetStorage as Er, isImpossibleEmptyStoredAttribute as Et, WARM_THROUGHPUT_MEMBERS as F, exportNamesCarriedFrom as Fn, CFN_TEMPLATE_URL_LIMIT as Fr, coerceCfnBoolean as Ft, red as G, createAssetRedirectResolver as Gn, processStackMessages as Gr, classifyReplaySecretRegion as Gt, cyan as H, stringifyValue as Hn, canonicalizeRegion as Hr, requireConfigArray as Ht, coerceWarmThroughput as I, importableOutputKeys as In, MIGRATE_TMP_PREFIX as Ir, coerceCfnInteger as It, collectPublishedOutputNames as J, AssetModeResolver as Jn, AwsClients as Jr, s3BucketArn as Jt, yellow as K, loadPublishableAssetManifest as Kn, clearBucketRegionCache as Kr, producerRegionsFromState as Kt, isWarmThroughputDecrease as L, importableOutputs as Ln, findLargeInlineResources as Lr, configBooleanRefusal as Lt, isStatefulRecreateTargetForReplace as M, shellQuote as Mn, stateBucketExistenceConfirmed as Mr, normalizeAwsTagsToCfn as Mt, isStatefulRecreateTargetSync as N, CUSTOM_RESOURCE_RESPONSE_PREFIX as Nn, warnDeprecatedNoPrefixCliFlag as Nr, resolveExplicitPhysicalId as Nt, extractDeploymentEventError as O, retryClassificationText as Oi, buildForceUnlockCommand as On, resolveSkipPrefix as Or, parameterTypeMayLoseSecretIdentity as Ot, renderStatefulReason as P, DEFAULT_STATE_PREFIX as Pn, CFN_TEMPLATE_BODY_LIMIT as Pr, assertRegionMatch as Pt, secretBearingStateKeyWarning as Q, getBootstrapMarkerKey as Qn, AssetError as Qr, s3BucketWebsiteUrl as Qt, toCfnInteger as R, orphansAfterRollback as Rn, uploadCfnTemplate as Rr, configIntegerRefusal as Rt, ccRoutedFinalSnapshotError as S, isMarkedNonRetryable as Si, recoverMaskedOutput as Sn, synthesisStatusMessage as Sr, carriesDynamicReference as St, refusesFinalSnapshot as T, isTransientServerError as Ti, LockManager as Tn, resolveApp as Tr, getAccountInfo as Tt, gray as U, WorkGraph as Un, derivePartitionAndUrlSuffix as Ur, requireConfigObject as Ut, bold as V, AssetPublisher as Vn, PARTITION_TABLE as Vr, replayWarn as Vt, green as W, buildAssetRedirectMap as Wn, AssemblyReader as Wr, requireConfigString as Wt, isExportAliasCollision as X, assertAssetBucketRegion as Xn, resetAwsClients as Xr, s3BucketDualStackDomainName as Xt, exportAliasCollisionScrubWarning as Y, BOOTSTRAP_MARKER_PREFIX as Yn, getAwsClients as Yr, s3BucketDomainName as Yt, secretBearing as Z, ensureAssetStorage as Zn, setAwsClients as Zr, s3BucketRegionalDomainName as Zt, isSecretBearingReferenceString as _, SynthesisError as _i, isSingleDynamicReferenceToken as _n, escapeRegExp$1 as _r, deleteIndeterminateGuards as _t, DeploymentEventsStore as a, IntrinsicResolutionRefusalError as ai, withRetry as an, describeAwsFailure as ar, wouldReturnToSdkProvider as at, PRE_DELETE_SNAPSHOT_TYPES as b, normalizeAwsError as bi, maskSecretsInText as bn, getDockerImageBySourceHash as br, isTerminationProtectionPropagationError as bt, replayFailedOperations as c, LockError as ci, STATE_SOURCED_BASELINE_RULES as cn, describeDockerExecFailure as cr, maskerOrIdentity as ct, updatePartialReason as d, ProvisioningError as di, TEMPLATE_SOURCED_RULES as dn, formatDockerLoginError as dr, interruptWatchListenerCount as dt, ConfigError as ei, DiffCalculator as en, parseBootstrapMarker as er, getCurrentResourceSecrets as et, withResourceDeadline as f, ResourceTimeoutError as fi, carriesSecretMask as fn, getDockerCmd as fr, isInterruptedWaitError as ft, bagHoldsSecretExpression as g, StateError as gi, identityKeyFor as gn, runDockerStreaming as gr, UNSPECIFIED_SKIP_REASON as gt, computeImplicitDeleteEdges as h, StackTerminationProtectionError as hi, errorCauseChain as hn, runDockerForeground as hr, slowCcOperationTimeoutMs as ht, DeploymentEventsReader as i, DynamicReferenceRegionAmbiguousError as ii, describeTypeWithThrottleRetry as in, buildDenyExternalAccessPolicy as ir, ProviderRegistry as it, MULTI_REGION_RECREATE_BLOCKED_TYPES as j, formatLockExpiry as jn, resolveUseCdkBootstrapAssets as jr, WAFv2WebACLProvider as jt, makeSiblingClaimReader as k, __exportAll as ki, buildLockContentionMessage as kn, resolveStateBucketWithDefault as kr, refStateLookupFromResource as kt, replayRollback as l, NestedStackChildDirectDestroyError as li, STATE_SOURCED_CROSS_GENERATION_RULES as ln, describeDockerFailure as lr, beginCommandInterruptScope as lt, IMPLICIT_DELETE_DEPENDENCIES as m, StackHasActiveImportsError as mi, dynamicReferenceTokens as mn, redactDockerArgvValues as mr, CloudControlProvider as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, DependencyError as ni, findActionableSilentDrops as nn, validateAssetBucketName as nr, collectInlinePolicyNamesManagedBySiblings as nt, planFailedOps as o, LocalInvokeBuildError as oi, DagBuilder as on, buildDockerImage as or, createMaskedRetryLogger as ot, maskingRetryLogger as p, ResourceUpdateNotSupportedError as pi, createSecretMasker as pn, partitionSensitiveEnv as pr, startInterruptWatch as pt, collectDeclaredOutputNames as q, rewriteTemplateAssetReferences as qn, resolveBucketRegion as qr, withSharedDrainBudget as qt, DeployEngine as r, DeployCancelledError as ri, findSilentDropProperties as rn, validateContainerRepoName as rr, clearOnUpdateRemoval as rt, planRollback as s, LocalStartServiceError as si, TemplateParser as sn, describeDockerCapturedOutput as sr, maskDeep as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, CrossAccountSecretRefusalError as ti, INTRINSIC_KEYS as tn, readBootstrapMarkerBody as tr, IAMRoleProvider as tt, updatePartialMessage as u, PartialFailureError as ui, STATE_SOURCED_READBACK_RULES as un, dockerSpawnEnvWithSensitive as ur, endCommandInterruptScope as ut, bindingSkippedOutputs as v, formatError as vi, markSameGenerationBag as vn, stripControlChars as vr, deleteSkipReason as vt, isFinalSnapshotError as w, isThrottlingError as wi, scrubResourceRecord as wn, getLegacyStateBucketName as wr, coerceParameterTypedValue as wt, buildFinalSnapshotIdentifier as x, withErrorHandling as xi, recordMaskOnlyValue as xn, Synthesizer as xr, IntrinsicFunctionResolver as xt, ATOMIC_FINAL_SNAPSHOT_TYPES as y, isCdkdError as yi, maskSecretsInError as yn, AssetManifestLoader as yr, disableInstanceApiTermination as yt, toFiniteNumber as z, orphansCarriedFrom as zn, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as zr, configStringRefusal as zt };
|
|
41852
|
+
//# sourceMappingURL=deploy-engine-WFO9o9M0.js.map
|