@go-to-k/cdkd 0.290.24 → 0.290.26
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-CHeJf5zw.js → asg-provider-7KM2pV3Q.js} +2 -2
- package/dist/{asg-provider-CHeJf5zw.js.map → asg-provider-7KM2pV3Q.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-BcNBidfy.js → deploy-engine-CbIc5Y73.js} +502 -220
- package/dist/deploy-engine-CbIc5Y73.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-DaoJ7P4H.js → program-BgDlhE-S.js} +459 -96
- package/dist/{program-DaoJ7P4H.js.map → program-BgDlhE-S.js.map} +1 -1
- package/dist/{version-PsB8OjhM.js → version-yD49aCCv.js} +2 -2
- package/dist/{version-PsB8OjhM.js.map → version-yD49aCCv.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BcNBidfy.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as displaySafe, S as displayIdent, b as STACK_REF_MAX_CODE_POINTS, 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 truncateCodePoints, x as UNRENDERABLE, y as withoutGeneratedFallbackName } from "./logger-CkHVgzLx.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-yD49aCCv.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";
|
|
@@ -59,6 +59,191 @@ var __exportAll = (all, no_symbols) => {
|
|
|
59
59
|
return target;
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/utils/aws-failure-text.ts
|
|
64
|
+
/**
|
|
65
|
+
* Appended to a redacted summary so the withheld half is still reachable.
|
|
66
|
+
*
|
|
67
|
+
* EXPORTED for the TESTS, and that is now its only reason. It was exported
|
|
68
|
+
* because `cloud-control-provider.ts`'s `abandonWait` reduced on its own wider
|
|
69
|
+
* predicate and had to compose this sentence by hand; issue
|
|
70
|
+
* [#3297](https://github.com/go-to-k/cdkd/issues/3297) removed that predicate
|
|
71
|
+
* and the hand-copy with it, so no `src/` file spells this literal twice. The
|
|
72
|
+
* remaining importer is `cloud-control-wait-abandoned.test.ts`, which asserts
|
|
73
|
+
* the ABSENCE of the pointer and would silently stop discriminating if it
|
|
74
|
+
* hard-coded the words instead.
|
|
75
|
+
*/
|
|
76
|
+
const VERBOSE_POINTER = "Re-run with --verbose for AWS's own message.";
|
|
77
|
+
/**
|
|
78
|
+
* The summary {@link describeAwsFailure} builds for an `Error` it is reducing.
|
|
79
|
+
*
|
|
80
|
+
* UN-exported by issue [#3297](https://github.com/go-to-k/cdkd/issues/3297).
|
|
81
|
+
* It was exported for one caller — `cloud-control-provider.ts`, whose own
|
|
82
|
+
* authorship predicate was WIDER than this module's, so the helper handed it
|
|
83
|
+
* raw text for a shape it wanted reduced and it had to build this string
|
|
84
|
+
* itself. That predicate is gone and so is the divergence, leaving the export
|
|
85
|
+
* with no callers and a doc citing one that no longer exists. Keep it private:
|
|
86
|
+
* a re-export is the signal that a second predicate has appeared.
|
|
87
|
+
*/
|
|
88
|
+
function redactedAwsFailureSummary(error) {
|
|
89
|
+
return `${error.name || "Error"}. ${VERBOSE_POINTER}`;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Whether AWS wrote this failure's message.
|
|
93
|
+
*
|
|
94
|
+
* Keyed on a real SERVICE signal: `$fault`, which every modeled
|
|
95
|
+
* `@smithy/smithy-client` `ServiceException` carries, or a NUMERIC
|
|
96
|
+
* `$metadata.httpStatusCode`, which only a deserialized RESPONSE has. Nothing
|
|
97
|
+
* under `src/` sets either, so a match cannot be a cdkd-authored error.
|
|
98
|
+
*
|
|
99
|
+
* **`$metadata` PRESENCE is deliberately NOT the signal, and an earlier
|
|
100
|
+
* revision of this function used it** (issue
|
|
101
|
+
* [#3297](https://github.com/go-to-k/cdkd/issues/3297)). `@smithy/core`'s retry
|
|
102
|
+
* middleware stamps `$metadata = {attempts, totalRetryDelay}` onto EVERY error
|
|
103
|
+
* it gives up on — socket errors included — and creates the object when it is
|
|
104
|
+
* absent. Measured against a real `CloudControlClient` pointed at a closed
|
|
105
|
+
* port:
|
|
106
|
+
*
|
|
107
|
+
* name 'Error', code 'ECONNREFUSED', $fault undefined,
|
|
108
|
+
* message 'connect ECONNREFUSED 127.0.0.1:1',
|
|
109
|
+
* $metadata { attempts: 3, totalRetryDelay: 58 }
|
|
110
|
+
*
|
|
111
|
+
* So the old predicate classified a plain transport failure as AWS-authored and
|
|
112
|
+
* reduced it to its `name` — which for a socket error is the bare token
|
|
113
|
+
* `Error`, carrying no diagnosis at all. That deleted `connect ECONNREFUSED
|
|
114
|
+
* <ip>:443`, the exact wording issue
|
|
115
|
+
* [#3236](https://github.com/go-to-k/cdkd/issues/3236) was REPORTED with, from
|
|
116
|
+
* the only durable record of the outage.
|
|
117
|
+
*
|
|
118
|
+
* The `CredentialsProviderError` name is the third arm because credential
|
|
119
|
+
* resolution carries NEITHER signal — identity is resolved by
|
|
120
|
+
* `httpAuthSchemeMiddleware` at step `serialize`, which WRAPS retry's
|
|
121
|
+
* `finalizeRequest`, so an escaping credential error never enters retry's catch
|
|
122
|
+
* (measured, and the mechanism is why: retry CREATES `$metadata` when absent,
|
|
123
|
+
* so an error arriving without one proves it bypassed retry). It is also the
|
|
124
|
+
* shape whose message carries the most: `@aws-sdk/credential-provider-process`
|
|
125
|
+
* wraps EVERY exec failure in it, so the text interpolates the helper's ARGV
|
|
126
|
+
* and its stderr.
|
|
127
|
+
*
|
|
128
|
+
* **Its siblings are deliberately NOT matched, and the reasons differ per class
|
|
129
|
+
* rather than being one rule.** `@smithy/property-provider` exports a family of
|
|
130
|
+
* three — `ProviderError`, and its subclasses `CredentialsProviderError` and
|
|
131
|
+
* `TokenProviderError` — plus `@smithy/credential-provider-imds`'s
|
|
132
|
+
* `InstanceMetadataV1FallbackError`, the only subclass OF
|
|
133
|
+
* `CredentialsProviderError` in the installed tree. (All four set `name`; an
|
|
134
|
+
* earlier revision read "the only subclass that overrides `name`", which is
|
|
135
|
+
* false of the three siblings.) Each was read rather than reasoned about,
|
|
136
|
+
* because the answers go BOTH ways:
|
|
137
|
+
*
|
|
138
|
+
* - `TokenProviderError` must NOT be reduced. Its message IS the remedy —
|
|
139
|
+
* `Token is expired. To refresh this SSO session run 'aws sso login' with
|
|
140
|
+
* the corresponding profile.` — so reducing it to a wire name would delete
|
|
141
|
+
* the fix instruction. A revision matching the whole `*ProviderError` suffix
|
|
142
|
+
* did exactly that. The benefit is not realized on the Cloud Control poll
|
|
143
|
+
* path today, and claiming otherwise was measured false:
|
|
144
|
+
* `@aws-sdk/credential-provider-sso` catches every token failure and
|
|
145
|
+
* rethrows it as a `CredentialsProviderError`, so the shape cannot escape a
|
|
146
|
+
* SigV4 client there. The carve-out is a rule about the FAMILY, kept because
|
|
147
|
+
* the rewrap is upstream behaviour that can change.
|
|
148
|
+
* - `ProviderError` (the base) and `InstanceMetadataV1FallbackError` carry
|
|
149
|
+
* connectivity and CONFIG wording respectively — the IMDS one interpolates
|
|
150
|
+
* three fixed literals naming config keys, with no argv, stderr, profile
|
|
151
|
+
* value or identity in it. Both are more useful raw.
|
|
152
|
+
*
|
|
153
|
+
* So string EQUALITY is right here, and right by enumeration rather than by
|
|
154
|
+
* assumption. Re-check the list when the SDK major moves; do not widen it to a
|
|
155
|
+
* suffix. The specific mechanism to re-check is `ProviderError.from()`, which
|
|
156
|
+
* does `Object.assign(new this(...), error)` — that copies a SOURCE error's own
|
|
157
|
+
* `name` over the class field and would defeat string equality outright. It has
|
|
158
|
+
* ZERO call sites anywhere in `node_modules` today, which is the only reason
|
|
159
|
+
* equality is safe rather than merely correct-looking.
|
|
160
|
+
*
|
|
161
|
+
* `$response` is gone with the `$metadata` disjunct, and the reason is NOT the
|
|
162
|
+
* obvious one -- an earlier revision of this comment said it "is only ever set
|
|
163
|
+
* on a `ServiceException`, which carries `$fault` anyway", and review measured
|
|
164
|
+
* that false. `@smithy/core`'s `deserializerMiddleware` stamps `$response` on
|
|
165
|
+
* ANY error escaping the deserializer, and the very next line reads
|
|
166
|
+
* `if (!("$metadata" in error))`, i.e. the library explicitly handles the
|
|
167
|
+
* `$response`-without-`$metadata` shape (a `JSON.parse` `SyntaxError` out of
|
|
168
|
+
* `parseJsonBody`). What actually preserves the verdict is the SIBLING line in
|
|
169
|
+
* that same catch: `error.$metadata = { httpStatusCode: response.statusCode,
|
|
170
|
+
* ... }`, so the `httpStatusCode` disjunct subsumes `$response` for every
|
|
171
|
+
* response the middleware can read. The residual is a `response` failing
|
|
172
|
+
* `HttpResponse.isInstance`, or a throw inside that block's own
|
|
173
|
+
* `catch (ignored)` -- shapes with no HTTP status at all, which are not service
|
|
174
|
+
* rejections and should not be reduced.
|
|
175
|
+
*
|
|
176
|
+
* A transport-level failure (a socket timeout, a DNS error) reaches a caller
|
|
177
|
+
* with neither signal, and that is the correct answer rather than a gap: those
|
|
178
|
+
* messages are written by the HTTP layer and name a host, never a caller.
|
|
179
|
+
*/
|
|
180
|
+
function isAwsAuthoredFailure(error) {
|
|
181
|
+
const candidate = error;
|
|
182
|
+
return candidate.$fault !== void 0 || typeof candidate.$metadata?.httpStatusCode === "number" || error.name === "CredentialsProviderError";
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Exactly what `String(value)` produces, without the throw.
|
|
186
|
+
*
|
|
187
|
+
* `String(value)` is the only spelling that carries an `Error`'s NAME as well
|
|
188
|
+
* as its message (`"AccessDenied: User ... is not authorized"`), and several
|
|
189
|
+
* call sites depend on that: four build a persisted `outcome: 'partial'`
|
|
190
|
+
* reason where the wire code is the discriminator an operator reads first.
|
|
191
|
+
* {@link describeAwsFailure}'s `detail` is the MESSAGE only, so it is NOT a
|
|
192
|
+
* drop-in for the bare form -- substituting it silently deletes the code.
|
|
193
|
+
* Measured, after a sweep did exactly that at nine sites.
|
|
194
|
+
*
|
|
195
|
+
* So this is the 1:1 replacement: same output for every value `String` can
|
|
196
|
+
* convert, and a stable sentence for the ones it cannot. A null-prototype
|
|
197
|
+
* object throws `TypeError: Cannot convert object to primitive value`, and an
|
|
198
|
+
* object with a hostile or `null` `toString` throws whatever it likes -- inside
|
|
199
|
+
* a catch, that replaces the failure being reported.
|
|
200
|
+
*
|
|
201
|
+
* Use `describeAwsFailure(x).detail` where the site previously read
|
|
202
|
+
* `x instanceof Error ? x.message : String(x)`; use THIS where it read a bare
|
|
203
|
+
* `String(x)`.
|
|
204
|
+
*
|
|
205
|
+
* NOT a substitute for `displaySafe` in `display-safe.ts`, which guards the
|
|
206
|
+
* same coercion and answers differently on purpose -- it falls back to
|
|
207
|
+
* `Object.prototype.toString` and, more importantly, SANITISES the result for a
|
|
208
|
+
* terminal. Anything about to be rendered or logged goes through that one; this
|
|
209
|
+
* one is for the text a catch is about to record.
|
|
210
|
+
*/
|
|
211
|
+
function safeStringify$1(value) {
|
|
212
|
+
try {
|
|
213
|
+
return String(value);
|
|
214
|
+
} catch {
|
|
215
|
+
return "a value that could not be converted to text";
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Describe a caught failure for a thrown message. See {@link AwsFailureText}.
|
|
220
|
+
*/
|
|
221
|
+
function describeAwsFailure(error) {
|
|
222
|
+
if (error instanceof Error) {
|
|
223
|
+
if (!isAwsAuthoredFailure(error)) return {
|
|
224
|
+
summary: error.message,
|
|
225
|
+
detail: error.message,
|
|
226
|
+
redacted: false
|
|
227
|
+
};
|
|
228
|
+
return {
|
|
229
|
+
summary: redactedAwsFailureSummary(error),
|
|
230
|
+
detail: error.message,
|
|
231
|
+
redacted: true
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
let detail;
|
|
235
|
+
try {
|
|
236
|
+
detail = String(error);
|
|
237
|
+
} catch {
|
|
238
|
+
detail = "a value that could not be converted to text";
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
summary: `a non-Error value of type ${typeof error}. ${VERBOSE_POINTER}`,
|
|
242
|
+
detail,
|
|
243
|
+
redacted: true
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
62
247
|
//#endregion
|
|
63
248
|
//#region src/deployment/retryable-errors.ts
|
|
64
249
|
/**
|
|
@@ -722,7 +907,7 @@ function isRetryableTransientError(error, message) {
|
|
|
722
907
|
* classify.
|
|
723
908
|
*/
|
|
724
909
|
function retryClassificationText(error) {
|
|
725
|
-
const top =
|
|
910
|
+
const top = describeAwsFailure(error).detail;
|
|
726
911
|
if (!hasRedactedCause(error)) return top;
|
|
727
912
|
const parts = [];
|
|
728
913
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -7360,7 +7545,7 @@ function repairSpawnRefusal(text, args, maskedArgs) {
|
|
|
7360
7545
|
* error would only say "Command failed with exit code N".
|
|
7361
7546
|
*/
|
|
7362
7547
|
function describeDockerExecFailure(error, args) {
|
|
7363
|
-
const message = thrownMessageText(error) || safeStringify
|
|
7548
|
+
const message = thrownMessageText(error) || safeStringify(error);
|
|
7364
7549
|
const stderrText = capturedStreamText(error, "stderr");
|
|
7365
7550
|
return redactDockerArgvInText(stderrText ? `${message}\n${stderrText}` : message, args);
|
|
7366
7551
|
}
|
|
@@ -7403,7 +7588,7 @@ function thrownMessageText(error) {
|
|
|
7403
7588
|
* two of these call sites are in `cleanupEcsRun`, where an exception aborts
|
|
7404
7589
|
* the remaining volume / network teardown and leaks real Docker resources.
|
|
7405
7590
|
*/
|
|
7406
|
-
function safeStringify
|
|
7591
|
+
function safeStringify(error) {
|
|
7407
7592
|
try {
|
|
7408
7593
|
return String(error);
|
|
7409
7594
|
} catch {
|
|
@@ -7429,7 +7614,7 @@ function safeStringify$1(error) {
|
|
|
7429
7614
|
* wrapper text needs the status as well.
|
|
7430
7615
|
*/
|
|
7431
7616
|
function describeDockerFailure(error, args) {
|
|
7432
|
-
return redactDockerArgvInText(capturedStreamText(error, "stderr") || thrownMessageText(error) || safeStringify
|
|
7617
|
+
return redactDockerArgvInText(capturedStreamText(error, "stderr") || thrownMessageText(error) || safeStringify(error), args);
|
|
7433
7618
|
}
|
|
7434
7619
|
/**
|
|
7435
7620
|
* A `cause` that is safe to CHAIN onto a wrapper error, for a caller that
|
|
@@ -7896,191 +8081,6 @@ var DockerAssetPublisher = class {
|
|
|
7896
8081
|
}
|
|
7897
8082
|
};
|
|
7898
8083
|
|
|
7899
|
-
//#endregion
|
|
7900
|
-
//#region src/utils/aws-failure-text.ts
|
|
7901
|
-
/**
|
|
7902
|
-
* Appended to a redacted summary so the withheld half is still reachable.
|
|
7903
|
-
*
|
|
7904
|
-
* EXPORTED for the TESTS, and that is now its only reason. It was exported
|
|
7905
|
-
* because `cloud-control-provider.ts`'s `abandonWait` reduced on its own wider
|
|
7906
|
-
* predicate and had to compose this sentence by hand; issue
|
|
7907
|
-
* [#3297](https://github.com/go-to-k/cdkd/issues/3297) removed that predicate
|
|
7908
|
-
* and the hand-copy with it, so no `src/` file spells this literal twice. The
|
|
7909
|
-
* remaining importer is `cloud-control-wait-abandoned.test.ts`, which asserts
|
|
7910
|
-
* the ABSENCE of the pointer and would silently stop discriminating if it
|
|
7911
|
-
* hard-coded the words instead.
|
|
7912
|
-
*/
|
|
7913
|
-
const VERBOSE_POINTER = "Re-run with --verbose for AWS's own message.";
|
|
7914
|
-
/**
|
|
7915
|
-
* The summary {@link describeAwsFailure} builds for an `Error` it is reducing.
|
|
7916
|
-
*
|
|
7917
|
-
* UN-exported by issue [#3297](https://github.com/go-to-k/cdkd/issues/3297).
|
|
7918
|
-
* It was exported for one caller — `cloud-control-provider.ts`, whose own
|
|
7919
|
-
* authorship predicate was WIDER than this module's, so the helper handed it
|
|
7920
|
-
* raw text for a shape it wanted reduced and it had to build this string
|
|
7921
|
-
* itself. That predicate is gone and so is the divergence, leaving the export
|
|
7922
|
-
* with no callers and a doc citing one that no longer exists. Keep it private:
|
|
7923
|
-
* a re-export is the signal that a second predicate has appeared.
|
|
7924
|
-
*/
|
|
7925
|
-
function redactedAwsFailureSummary(error) {
|
|
7926
|
-
return `${error.name || "Error"}. ${VERBOSE_POINTER}`;
|
|
7927
|
-
}
|
|
7928
|
-
/**
|
|
7929
|
-
* Whether AWS wrote this failure's message.
|
|
7930
|
-
*
|
|
7931
|
-
* Keyed on a real SERVICE signal: `$fault`, which every modeled
|
|
7932
|
-
* `@smithy/smithy-client` `ServiceException` carries, or a NUMERIC
|
|
7933
|
-
* `$metadata.httpStatusCode`, which only a deserialized RESPONSE has. Nothing
|
|
7934
|
-
* under `src/` sets either, so a match cannot be a cdkd-authored error.
|
|
7935
|
-
*
|
|
7936
|
-
* **`$metadata` PRESENCE is deliberately NOT the signal, and an earlier
|
|
7937
|
-
* revision of this function used it** (issue
|
|
7938
|
-
* [#3297](https://github.com/go-to-k/cdkd/issues/3297)). `@smithy/core`'s retry
|
|
7939
|
-
* middleware stamps `$metadata = {attempts, totalRetryDelay}` onto EVERY error
|
|
7940
|
-
* it gives up on — socket errors included — and creates the object when it is
|
|
7941
|
-
* absent. Measured against a real `CloudControlClient` pointed at a closed
|
|
7942
|
-
* port:
|
|
7943
|
-
*
|
|
7944
|
-
* name 'Error', code 'ECONNREFUSED', $fault undefined,
|
|
7945
|
-
* message 'connect ECONNREFUSED 127.0.0.1:1',
|
|
7946
|
-
* $metadata { attempts: 3, totalRetryDelay: 58 }
|
|
7947
|
-
*
|
|
7948
|
-
* So the old predicate classified a plain transport failure as AWS-authored and
|
|
7949
|
-
* reduced it to its `name` — which for a socket error is the bare token
|
|
7950
|
-
* `Error`, carrying no diagnosis at all. That deleted `connect ECONNREFUSED
|
|
7951
|
-
* <ip>:443`, the exact wording issue
|
|
7952
|
-
* [#3236](https://github.com/go-to-k/cdkd/issues/3236) was REPORTED with, from
|
|
7953
|
-
* the only durable record of the outage.
|
|
7954
|
-
*
|
|
7955
|
-
* The `CredentialsProviderError` name is the third arm because credential
|
|
7956
|
-
* resolution carries NEITHER signal — identity is resolved by
|
|
7957
|
-
* `httpAuthSchemeMiddleware` at step `serialize`, which WRAPS retry's
|
|
7958
|
-
* `finalizeRequest`, so an escaping credential error never enters retry's catch
|
|
7959
|
-
* (measured, and the mechanism is why: retry CREATES `$metadata` when absent,
|
|
7960
|
-
* so an error arriving without one proves it bypassed retry). It is also the
|
|
7961
|
-
* shape whose message carries the most: `@aws-sdk/credential-provider-process`
|
|
7962
|
-
* wraps EVERY exec failure in it, so the text interpolates the helper's ARGV
|
|
7963
|
-
* and its stderr.
|
|
7964
|
-
*
|
|
7965
|
-
* **Its siblings are deliberately NOT matched, and the reasons differ per class
|
|
7966
|
-
* rather than being one rule.** `@smithy/property-provider` exports a family of
|
|
7967
|
-
* three — `ProviderError`, and its subclasses `CredentialsProviderError` and
|
|
7968
|
-
* `TokenProviderError` — plus `@smithy/credential-provider-imds`'s
|
|
7969
|
-
* `InstanceMetadataV1FallbackError`, the only subclass OF
|
|
7970
|
-
* `CredentialsProviderError` in the installed tree. (All four set `name`; an
|
|
7971
|
-
* earlier revision read "the only subclass that overrides `name`", which is
|
|
7972
|
-
* false of the three siblings.) Each was read rather than reasoned about,
|
|
7973
|
-
* because the answers go BOTH ways:
|
|
7974
|
-
*
|
|
7975
|
-
* - `TokenProviderError` must NOT be reduced. Its message IS the remedy —
|
|
7976
|
-
* `Token is expired. To refresh this SSO session run 'aws sso login' with
|
|
7977
|
-
* the corresponding profile.` — so reducing it to a wire name would delete
|
|
7978
|
-
* the fix instruction. A revision matching the whole `*ProviderError` suffix
|
|
7979
|
-
* did exactly that. The benefit is not realized on the Cloud Control poll
|
|
7980
|
-
* path today, and claiming otherwise was measured false:
|
|
7981
|
-
* `@aws-sdk/credential-provider-sso` catches every token failure and
|
|
7982
|
-
* rethrows it as a `CredentialsProviderError`, so the shape cannot escape a
|
|
7983
|
-
* SigV4 client there. The carve-out is a rule about the FAMILY, kept because
|
|
7984
|
-
* the rewrap is upstream behaviour that can change.
|
|
7985
|
-
* - `ProviderError` (the base) and `InstanceMetadataV1FallbackError` carry
|
|
7986
|
-
* connectivity and CONFIG wording respectively — the IMDS one interpolates
|
|
7987
|
-
* three fixed literals naming config keys, with no argv, stderr, profile
|
|
7988
|
-
* value or identity in it. Both are more useful raw.
|
|
7989
|
-
*
|
|
7990
|
-
* So string EQUALITY is right here, and right by enumeration rather than by
|
|
7991
|
-
* assumption. Re-check the list when the SDK major moves; do not widen it to a
|
|
7992
|
-
* suffix. The specific mechanism to re-check is `ProviderError.from()`, which
|
|
7993
|
-
* does `Object.assign(new this(...), error)` — that copies a SOURCE error's own
|
|
7994
|
-
* `name` over the class field and would defeat string equality outright. It has
|
|
7995
|
-
* ZERO call sites anywhere in `node_modules` today, which is the only reason
|
|
7996
|
-
* equality is safe rather than merely correct-looking.
|
|
7997
|
-
*
|
|
7998
|
-
* `$response` is gone with the `$metadata` disjunct, and the reason is NOT the
|
|
7999
|
-
* obvious one -- an earlier revision of this comment said it "is only ever set
|
|
8000
|
-
* on a `ServiceException`, which carries `$fault` anyway", and review measured
|
|
8001
|
-
* that false. `@smithy/core`'s `deserializerMiddleware` stamps `$response` on
|
|
8002
|
-
* ANY error escaping the deserializer, and the very next line reads
|
|
8003
|
-
* `if (!("$metadata" in error))`, i.e. the library explicitly handles the
|
|
8004
|
-
* `$response`-without-`$metadata` shape (a `JSON.parse` `SyntaxError` out of
|
|
8005
|
-
* `parseJsonBody`). What actually preserves the verdict is the SIBLING line in
|
|
8006
|
-
* that same catch: `error.$metadata = { httpStatusCode: response.statusCode,
|
|
8007
|
-
* ... }`, so the `httpStatusCode` disjunct subsumes `$response` for every
|
|
8008
|
-
* response the middleware can read. The residual is a `response` failing
|
|
8009
|
-
* `HttpResponse.isInstance`, or a throw inside that block's own
|
|
8010
|
-
* `catch (ignored)` -- shapes with no HTTP status at all, which are not service
|
|
8011
|
-
* rejections and should not be reduced.
|
|
8012
|
-
*
|
|
8013
|
-
* A transport-level failure (a socket timeout, a DNS error) reaches a caller
|
|
8014
|
-
* with neither signal, and that is the correct answer rather than a gap: those
|
|
8015
|
-
* messages are written by the HTTP layer and name a host, never a caller.
|
|
8016
|
-
*/
|
|
8017
|
-
function isAwsAuthoredFailure(error) {
|
|
8018
|
-
const candidate = error;
|
|
8019
|
-
return candidate.$fault !== void 0 || typeof candidate.$metadata?.httpStatusCode === "number" || error.name === "CredentialsProviderError";
|
|
8020
|
-
}
|
|
8021
|
-
/**
|
|
8022
|
-
* Exactly what `String(value)` produces, without the throw.
|
|
8023
|
-
*
|
|
8024
|
-
* `String(value)` is the only spelling that carries an `Error`'s NAME as well
|
|
8025
|
-
* as its message (`"AccessDenied: User ... is not authorized"`), and several
|
|
8026
|
-
* call sites depend on that: four build a persisted `outcome: 'partial'`
|
|
8027
|
-
* reason where the wire code is the discriminator an operator reads first.
|
|
8028
|
-
* {@link describeAwsFailure}'s `detail` is the MESSAGE only, so it is NOT a
|
|
8029
|
-
* drop-in for the bare form -- substituting it silently deletes the code.
|
|
8030
|
-
* Measured, after a sweep did exactly that at nine sites.
|
|
8031
|
-
*
|
|
8032
|
-
* So this is the 1:1 replacement: same output for every value `String` can
|
|
8033
|
-
* convert, and a stable sentence for the ones it cannot. A null-prototype
|
|
8034
|
-
* object throws `TypeError: Cannot convert object to primitive value`, and an
|
|
8035
|
-
* object with a hostile or `null` `toString` throws whatever it likes -- inside
|
|
8036
|
-
* a catch, that replaces the failure being reported.
|
|
8037
|
-
*
|
|
8038
|
-
* Use `describeAwsFailure(x).detail` where the site previously read
|
|
8039
|
-
* `x instanceof Error ? x.message : String(x)`; use THIS where it read a bare
|
|
8040
|
-
* `String(x)`.
|
|
8041
|
-
*
|
|
8042
|
-
* NOT a substitute for `displaySafe` in `display-safe.ts`, which guards the
|
|
8043
|
-
* same coercion and answers differently on purpose -- it falls back to
|
|
8044
|
-
* `Object.prototype.toString` and, more importantly, SANITISES the result for a
|
|
8045
|
-
* terminal. Anything about to be rendered or logged goes through that one; this
|
|
8046
|
-
* one is for the text a catch is about to record.
|
|
8047
|
-
*/
|
|
8048
|
-
function safeStringify(value) {
|
|
8049
|
-
try {
|
|
8050
|
-
return String(value);
|
|
8051
|
-
} catch {
|
|
8052
|
-
return "a value that could not be converted to text";
|
|
8053
|
-
}
|
|
8054
|
-
}
|
|
8055
|
-
/**
|
|
8056
|
-
* Describe a caught failure for a thrown message. See {@link AwsFailureText}.
|
|
8057
|
-
*/
|
|
8058
|
-
function describeAwsFailure(error) {
|
|
8059
|
-
if (error instanceof Error) {
|
|
8060
|
-
if (!isAwsAuthoredFailure(error)) return {
|
|
8061
|
-
summary: error.message,
|
|
8062
|
-
detail: error.message,
|
|
8063
|
-
redacted: false
|
|
8064
|
-
};
|
|
8065
|
-
return {
|
|
8066
|
-
summary: redactedAwsFailureSummary(error),
|
|
8067
|
-
detail: error.message,
|
|
8068
|
-
redacted: true
|
|
8069
|
-
};
|
|
8070
|
-
}
|
|
8071
|
-
let detail;
|
|
8072
|
-
try {
|
|
8073
|
-
detail = String(error);
|
|
8074
|
-
} catch {
|
|
8075
|
-
detail = "a value that could not be converted to text";
|
|
8076
|
-
}
|
|
8077
|
-
return {
|
|
8078
|
-
summary: `a non-Error value of type ${typeof error}. ${VERBOSE_POINTER}`,
|
|
8079
|
-
detail,
|
|
8080
|
-
redacted: true
|
|
8081
|
-
};
|
|
8082
|
-
}
|
|
8083
|
-
|
|
8084
8084
|
//#endregion
|
|
8085
8085
|
//#region src/utils/deny-external-access-policy.ts
|
|
8086
8086
|
/**
|
|
@@ -9534,6 +9534,44 @@ function isReadableBag(container) {
|
|
|
9534
9534
|
return typeof container === "object" && container !== null && !Array.isArray(container);
|
|
9535
9535
|
}
|
|
9536
9536
|
/**
|
|
9537
|
+
* What KIND of value a record's `region` field holds, as a bounded token safe
|
|
9538
|
+
* to print at default verbosity (issue
|
|
9539
|
+
* [#3328](https://github.com/go-to-k/cdkd/issues/3328)).
|
|
9540
|
+
*
|
|
9541
|
+
* The VALUE is never safe there: a body region is chosen by anyone able to
|
|
9542
|
+
* write that key, and a line reading `body region 'eu-west-1'` hands an
|
|
9543
|
+
* operator a region to aim a destructive re-run at — the misdirection half of
|
|
9544
|
+
* that issue. Its kind is the answer to "what is wrong with this record"
|
|
9545
|
+
* without being the answer to "which region should I use", and the result is
|
|
9546
|
+
* one of TEN fixed strings (`null`, `an array`, and an article plus each of
|
|
9547
|
+
* `typeof`'s eight), so no input can forge a line through it.
|
|
9548
|
+
*
|
|
9549
|
+
* `probeLegacyState` reaches the same JUDGEMENT one field over and does NOT
|
|
9550
|
+
* call this — it renders a bare `typeof` into a sentence a unit case pins
|
|
9551
|
+
* verbatim (`'region' is number, not a string`). Two spellings of a bounded
|
|
9552
|
+
* token, deliberately not collapsed: the two are not interchangeable strings,
|
|
9553
|
+
* and changing that one is a message change with its own fence.
|
|
9554
|
+
*
|
|
9555
|
+
* `null` and arrays are named rather than left as `object`, the way
|
|
9556
|
+
* `parseStateBody` names its own refused roots — `typeof null` is `'object'`,
|
|
9557
|
+
* which would report the two most likely hand-edit shapes as the same thing.
|
|
9558
|
+
* The article is computed because `a object` reads as a defect in the very
|
|
9559
|
+
* diagnostic the reader is being asked to trust.
|
|
9560
|
+
*
|
|
9561
|
+
* HOME: this module rather than beside either caller, for the reason
|
|
9562
|
+
* {@link isReadableBag}'s note gives — `src/state/s3-state-backend.ts`
|
|
9563
|
+
* (`adoptKeyRegion`, which produces the divergence) and
|
|
9564
|
+
* `src/state/malformed-resources-bag.ts` (the destroy refusal that renders it)
|
|
9565
|
+
* both need it, and the second is imported by modules that `vi.mock` the
|
|
9566
|
+
* first wholesale.
|
|
9567
|
+
*/
|
|
9568
|
+
function describeRegionValueKind(value) {
|
|
9569
|
+
if (value === null) return "null";
|
|
9570
|
+
if (Array.isArray(value)) return "an array";
|
|
9571
|
+
const type = typeof value;
|
|
9572
|
+
return `${/^[aeiou]/.test(type) ? "an" : "a"} ${type}`;
|
|
9573
|
+
}
|
|
9574
|
+
/**
|
|
9537
9575
|
* The keys of `state.outputs` an `Fn::ImportValue` may bind to (issue
|
|
9538
9576
|
* [#2193](https://github.com/go-to-k/cdkd/issues/2193)) — THE predicate
|
|
9539
9577
|
* behind "what does this stack export". Four readers used to answer that
|
|
@@ -10287,6 +10325,11 @@ var S3StateBackend = class {
|
|
|
10287
10325
|
*
|
|
10288
10326
|
* Note: S3 returns ETag with surrounding quotes (e.g., `"abc123"`). We
|
|
10289
10327
|
* preserve the quotes — they are required for `IfMatch` conditions.
|
|
10328
|
+
*
|
|
10329
|
+
* On the region-scoped path the returned `state.region` is ALWAYS the
|
|
10330
|
+
* region of the key it was read from, whatever the body said — see
|
|
10331
|
+
* {@link adoptKeyRegion}, which also reports a body that disagreed via
|
|
10332
|
+
* `divergentBodyRegion`.
|
|
10290
10333
|
*/
|
|
10291
10334
|
async getState(stackName, region) {
|
|
10292
10335
|
await this.ensureClientForBucket();
|
|
@@ -10303,11 +10346,13 @@ var S3StateBackend = class {
|
|
|
10303
10346
|
if (!response.Body) throw new StateError(`State file for stack '${shownStackName}' (${shownRegionName}) has no body`);
|
|
10304
10347
|
if (!response.ETag) throw new StateError(`State file for stack '${shownStackName}' (${shownRegionName}) has no ETag`);
|
|
10305
10348
|
const bodyString = await response.Body.transformToString();
|
|
10306
|
-
const
|
|
10349
|
+
const parsed = this.parseStateBody(bodyString, stackName);
|
|
10350
|
+
const { state, divergentBodyRegion } = this.adoptKeyRegion(parsed, region, shownStackName, shownRegionName);
|
|
10307
10351
|
this.logger.debug(`Retrieved state: ${shownStackName} (${shownRegionName}), ETag: ${response.ETag}`);
|
|
10308
10352
|
return {
|
|
10309
10353
|
state,
|
|
10310
|
-
etag: response.ETag
|
|
10354
|
+
etag: response.ETag,
|
|
10355
|
+
...divergentBodyRegion !== void 0 && { divergentBodyRegion }
|
|
10311
10356
|
};
|
|
10312
10357
|
} catch (error) {
|
|
10313
10358
|
if (!isNoSuchKey(error)) {
|
|
@@ -10869,6 +10914,83 @@ var S3StateBackend = class {
|
|
|
10869
10914
|
displayName(stackName) {
|
|
10870
10915
|
return displaySafe(stackName, { asciiOnly: true }) || "<unrenderable>";
|
|
10871
10916
|
}
|
|
10917
|
+
/**
|
|
10918
|
+
* Make the S3 KEY's region the region of the record read from it, and report
|
|
10919
|
+
* a body that named a different one.
|
|
10920
|
+
*
|
|
10921
|
+
* The key is the authority, and that is not a new rule: `saveState`
|
|
10922
|
+
* normalizes the body it writes against the same `region` argument
|
|
10923
|
+
* `getStateKey` builds the key from, and has done since `83e5ddb66` — the
|
|
10924
|
+
* commit that introduced the region-scoped layout (schema v2, PR
|
|
10925
|
+
* [#57](https://github.com/go-to-k/cdkd/pull/57)). Key and body therefore
|
|
10926
|
+
* agree by construction for every record any cdkd version has ever written,
|
|
10927
|
+
* so this makes the READ symmetric with a write rule that already held
|
|
10928
|
+
* rather than inventing a second one — and a divergence means the record was
|
|
10929
|
+
* written by something that is not cdkd.
|
|
10930
|
+
*
|
|
10931
|
+
* It is not cosmetic. `region` is what `destroy-runner.ts` locks, saves and
|
|
10932
|
+
* `deleteState`s against (`state.region ?? ctx.baseRegion`), and what
|
|
10933
|
+
* `DeleteContext.expectedRegion` carries so a provider can tell "the
|
|
10934
|
+
* resource is genuinely gone" from "I looked in the wrong region"
|
|
10935
|
+
* (`src/provisioning/region-check.ts`). A divergent body aimed all of that
|
|
10936
|
+
* at a region the record does not live in, and `cdkd state destroy` reported
|
|
10937
|
+
* `✓ State deleted` having deleted nothing (issue
|
|
10938
|
+
* [#3328](https://github.com/go-to-k/cdkd/issues/3328)). Normalizing HERE
|
|
10939
|
+
* fixes every consumer at once, with no region threaded through any of them.
|
|
10940
|
+
*
|
|
10941
|
+
* REFUSING instead was rejected deliberately: this is the shared read path
|
|
10942
|
+
* for deploy, destroy, rollback AND the recovery commands (`cdkd state
|
|
10943
|
+
* orphan`, `cdkd state destroy`), which is the same reason `parseStateBody`
|
|
10944
|
+
* validates nothing inside a well-formed root. A refusal would strand the
|
|
10945
|
+
* record it was asked to clean up, leaving `aws s3 rm` as the only remedy.
|
|
10946
|
+
*
|
|
10947
|
+
* It REPLACES rather than defaults, which is the half `??` cannot do:
|
|
10948
|
+
* `state.region ?? ctx.baseRegion` falls through only for `null` /
|
|
10949
|
+
* `undefined`, so a `"region": ""` built the key `cdkd/<stack>//state.json`
|
|
10950
|
+
* and a `"region": 123` reached `acquireLock` / `deleteState` as a region.
|
|
10951
|
+
*
|
|
10952
|
+
* **An ABSENT region is normalized too, and silently.** A body carrying no
|
|
10953
|
+
* `region` makes no claim to contradict, and the key it was read from names
|
|
10954
|
+
* one — which is the answer `legacyProbeBelongsTo` already gives one layout
|
|
10955
|
+
* over, where a body naming no region belongs to ANY region (issue
|
|
10956
|
+
* [#2550](https://github.com/go-to-k/cdkd/issues/2550)): "any region" plus
|
|
10957
|
+
* "read under this key" is this key's region. It is also strictly better than
|
|
10958
|
+
* what absence used to reach, which was `ctx.baseRegion` at the destroy —
|
|
10959
|
+
* the CLI's region, which need not be the key's at all.
|
|
10960
|
+
*
|
|
10961
|
+
* **`null` and `''` are NOT folded in with absent here, unlike in
|
|
10962
|
+
* `legacyProbeBelongsTo`**, and the difference is the key: the legacy key
|
|
10963
|
+
* names no region, so a falsy field there has to mean "any". This key names
|
|
10964
|
+
* one, so nothing needs inferring and the only question left is whether the
|
|
10965
|
+
* body AGREES — which `null` and `''` do not. They are also two of the shapes
|
|
10966
|
+
* `export.ts`'s nested-child refusal keys on, and folding them in would drop
|
|
10967
|
+
* that refusal silently.
|
|
10968
|
+
*
|
|
10969
|
+
* The divergent value is REPORTED to the caller rather than only logged
|
|
10970
|
+
* because one caller refuses on it: `walkCdkdStateStackTree` (`export.ts`)
|
|
10971
|
+
* fails a nested child whose recorded region is not its parent's, and
|
|
10972
|
+
* normalizing the state without reporting would have made that refusal
|
|
10973
|
+
* unreachable rather than fixed.
|
|
10974
|
+
*/
|
|
10975
|
+
adoptKeyRegion(state, region, shownStackName, shownRegionName) {
|
|
10976
|
+
const raw = state.region;
|
|
10977
|
+
if (raw === region) return { state };
|
|
10978
|
+
if (raw === void 0) return { state: {
|
|
10979
|
+
...state,
|
|
10980
|
+
region
|
|
10981
|
+
} };
|
|
10982
|
+
const kind = describeRegionValueKind(raw);
|
|
10983
|
+
this.logger.warn(`State record for stack '${shownStackName}' carries a 'region' of its own (${kind}) that is not the region of the S3 key it was read from ('${shownRegionName}'). cdkd stamps the key's region into every record it writes, so this record was not written by cdkd. Continuing against '${shownRegionName}' — the key is authoritative. Re-run with --verbose to see the recorded value, where it has one to show.`);
|
|
10984
|
+
const shownBodyRegion = truncateCodePoints(displaySafe(raw, { asciiOnly: true }), 255);
|
|
10985
|
+
this.logger.debug(`State record for stack '${shownStackName}' carries body region ` + (shownBodyRegion.text === "" ? `${kind}, which renders as nothing — its kind above is the whole of it.` : `'${shownBodyRegion.text}'${shownBodyRegion.truncated ? " [cut]" : ""}.`));
|
|
10986
|
+
return {
|
|
10987
|
+
state: {
|
|
10988
|
+
...state,
|
|
10989
|
+
region
|
|
10990
|
+
},
|
|
10991
|
+
divergentBodyRegion: raw
|
|
10992
|
+
};
|
|
10993
|
+
}
|
|
10872
10994
|
async probeLegacyState(stackName) {
|
|
10873
10995
|
try {
|
|
10874
10996
|
const response = await this.s3Client.send(new GetObjectCommand({
|
|
@@ -10957,6 +11079,15 @@ var S3StateBackend = class {
|
|
|
10957
11079
|
this.logger.debug(`Legacy state for stack '${this.displayName(stackName)}' has region '${displaySafe(state.region, { asciiOnly: true }) || "<unrenderable>"}', not '${displaySafe(region, { asciiOnly: true }) || "<unrenderable>"}' — skipping legacy fallback.`);
|
|
10958
11080
|
return null;
|
|
10959
11081
|
}
|
|
11082
|
+
const legacyRegion = state.region;
|
|
11083
|
+
if (legacyRegion !== void 0 && (typeof legacyRegion !== "string" || legacyRegion === "")) {
|
|
11084
|
+
this.logger.debug(`Legacy state for stack '${this.displayName(stackName)}' names no usable region (${describeRegionValueKind(legacyRegion)}); reading it as region-less.`);
|
|
11085
|
+
const { region: _dropped, ...withoutRegion } = state;
|
|
11086
|
+
return {
|
|
11087
|
+
state: withoutRegion,
|
|
11088
|
+
etag: response.ETag
|
|
11089
|
+
};
|
|
11090
|
+
}
|
|
10960
11091
|
return {
|
|
10961
11092
|
state,
|
|
10962
11093
|
etag: response.ETag
|
|
@@ -17847,7 +17978,7 @@ async function withRetry(operation, logicalId, opts = {}) {
|
|
|
17847
17978
|
return await operation();
|
|
17848
17979
|
} catch (error) {
|
|
17849
17980
|
lastError = error;
|
|
17850
|
-
const message =
|
|
17981
|
+
const message = describeAwsFailure(error).detail;
|
|
17851
17982
|
const classifyText = retryClassificationText(error);
|
|
17852
17983
|
if (isMarkedNonRetryable(error)) throw error;
|
|
17853
17984
|
const retryable = opts.isRetryable ? opts.isRetryable(classifyText, error) : isRetryableTransientError(error, classifyText);
|
|
@@ -20971,18 +21102,26 @@ function malformedStateRefusalMessage(stackName, region) {
|
|
|
20971
21102
|
* **That remedy is a TEMPLATE, not a substituted command, and the asymmetry
|
|
20972
21103
|
* with the `cdkd state show` line above it is the point.** `state orphan`
|
|
20973
21104
|
* DELETES a record; `state show` reads one. The `region` this function is
|
|
20974
|
-
* handed comes from `destroy-runner.ts`'s
|
|
20975
|
-
*
|
|
20976
|
-
*
|
|
20977
|
-
*
|
|
20978
|
-
* `
|
|
20979
|
-
*
|
|
20980
|
-
*
|
|
20981
|
-
*
|
|
20982
|
-
*
|
|
20983
|
-
*
|
|
20984
|
-
*
|
|
20985
|
-
*
|
|
21105
|
+
* handed comes from `destroy-runner.ts`'s `state.region ?? ctx.baseRegion` —
|
|
21106
|
+
* which WAS record-body content `getState` did not check against the key it
|
|
21107
|
+
* loaded from, measured 2026-09-17: a record planted at
|
|
21108
|
+
* `.../us-east-1/state.json` carrying `"region": "eu-west-1"` rendered a
|
|
21109
|
+
* pasteable `cdkd state orphan <stack> --stack-region eu-west-1`, aiming a
|
|
21110
|
+
* destructive command at a DIFFERENT region's record for the same stack. That
|
|
21111
|
+
* is the misdirection class {@link stackClause} records for stack names, one
|
|
21112
|
+
* field over. Substituting into the read-only `state show` line is the
|
|
21113
|
+
* pre-existing behaviour of {@link malformedStateDetail} and is left alone;
|
|
21114
|
+
* what this lane must not add is a destructive one.
|
|
21115
|
+
*
|
|
21116
|
+
* **go-to-k/cdkd#3328 closed the BODY half of that, and the template stays
|
|
21117
|
+
* anyway** — the measurement above is now history, not a live repro.
|
|
21118
|
+
* `S3StateBackend.getState` normalizes a region-scoped record's `region` to
|
|
21119
|
+
* its KEY's and warns on a body that disagreed, so `state.region` reaching
|
|
21120
|
+
* this function is the key's region. But the key is an S3 KEY SEGMENT, which
|
|
21121
|
+
* is bucket-plantable in its own right (`cdkd/<stack>/<anything>/state.json`
|
|
21122
|
+
* lists as a region), and a legacy record still falls through to
|
|
21123
|
+
* `ctx.baseRegion`. So the value is still not this process's own, and a
|
|
21124
|
+
* DELETING command built from it is still the thing not to hand over.
|
|
20986
21125
|
*
|
|
20987
21126
|
* **A template is not enough on its own, because the name the reader would
|
|
20988
21127
|
* type into it comes from the clause ABOVE.** `safeIdentifier` composes
|
|
@@ -21007,9 +21146,16 @@ function malformedStateRefusalMessage(stackName, region) {
|
|
|
21007
21146
|
* "with the stack and region this message NAMES", which is the attacker's
|
|
21008
21147
|
* region (review round 2 of go-to-k/cdkd#3332: templating had removed the
|
|
21009
21148
|
* paste, not the aim). The arm therefore points at the record's S3 KEY, which
|
|
21010
|
-
* `getState` resolved and a record body cannot forge
|
|
21011
|
-
*
|
|
21012
|
-
*
|
|
21149
|
+
* `getState` resolved and a record body cannot forge.
|
|
21150
|
+
*
|
|
21151
|
+
* Since go-to-k/cdkd#3328 the printed region IS that key's — `getState`
|
|
21152
|
+
* normalizes a region-scoped record's `region` to the key's region and warns
|
|
21153
|
+
* on a body that disagreed — so the arm no longer has to warn the reader that
|
|
21154
|
+
* the two may differ, and its text no longer does. It still says WHERE the
|
|
21155
|
+
* region comes from and still sends the reader to `cdkd state list --long` to
|
|
21156
|
+
* confirm the key, because a key segment is itself bucket-plantable and
|
|
21157
|
+
* because a LEGACY record has no key region at all, in which case the value
|
|
21158
|
+
* printed is the CLI's own and `--stack-region` must be omitted.
|
|
21013
21159
|
*
|
|
21014
21160
|
* **The cap this arm measures against is `STACK_REF_MAX_CODE_POINTS`, not the
|
|
21015
21161
|
* 128 every other text in this module uses**, and it is threaded rather than
|
|
@@ -21027,7 +21173,7 @@ function malformedStateRefusalMessage(stackName, region) {
|
|
|
21027
21173
|
function malformedDestroyResourcesRefusalMessage(stackName, region) {
|
|
21028
21174
|
const cap = STACK_REF_MAX_CODE_POINTS;
|
|
21029
21175
|
const exact = safeIdentifier(stackName, cap) === stackName && safeIdentifier(region, cap) === region;
|
|
21030
|
-
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
|
|
21176
|
+
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)}`}`;
|
|
21031
21177
|
}
|
|
21032
21178
|
/**
|
|
21033
21179
|
* For `cdkd destroy` / `cdkd state destroy`: refuse a record whose `resources`
|
|
@@ -21049,6 +21195,89 @@ function refuseMalformedResourcesForDestroy(state, stackName, region) {
|
|
|
21049
21195
|
if (hasReadableResources(state)) return;
|
|
21050
21196
|
throw markNonRetryable(new CdkdError(malformedDestroyResourcesRefusalMessage(stackName, region), STATE_RESOURCES_MALFORMED));
|
|
21051
21197
|
}
|
|
21198
|
+
/** The code a destroy refusal over a body/key region divergence carries. */
|
|
21199
|
+
const STATE_REGION_DIVERGED = "STATE_REGION_DIVERGED";
|
|
21200
|
+
/**
|
|
21201
|
+
* The DESTROY refusal text for a record whose BODY names a different region
|
|
21202
|
+
* than the KEY it was read from, while it still lists resources (issue
|
|
21203
|
+
* [#3328](https://github.com/go-to-k/cdkd/issues/3328), review round 1).
|
|
21204
|
+
*
|
|
21205
|
+
* **This is the one case where adopting the key is not enough, and it is a
|
|
21206
|
+
* consequence of adopting it rather than an argument against.**
|
|
21207
|
+
* `S3StateBackend.getState` replaces the body's `region` with the key's, which
|
|
21208
|
+
* is right for the key math, the lock and the record's own identity — cdkd
|
|
21209
|
+
* stamps the key's region into every body it writes, so a divergence means
|
|
21210
|
+
* another writer. But WHERE THE RESOURCES ARE is a different question, and a
|
|
21211
|
+
* divergent record is the one shape that gives two answers to it. cdkd cannot
|
|
21212
|
+
* tell which half is honest:
|
|
21213
|
+
*
|
|
21214
|
+
* - the BODY lies (a planted field, the misdirection this issue is about) —
|
|
21215
|
+
* the resources are in the key's region and acting there is correct;
|
|
21216
|
+
* - the KEY lies (an `aws s3 cp` between region prefixes, a restore, a
|
|
21217
|
+
* third-party writer) — the resources are in the body's region, and acting
|
|
21218
|
+
* in the key's finds NOTHING.
|
|
21219
|
+
*
|
|
21220
|
+
* The second one is not a wash, it is silent data loss: `destroy-runner.ts`
|
|
21221
|
+
* reads a `*NotFound` from a provider as ALREADY DELETED (`deletedCount++`,
|
|
21222
|
+
* the row dropped from the record), so a whole stack of live resources would
|
|
21223
|
+
* be reported destroyed and `deleteState` would then remove the only record
|
|
21224
|
+
* naming them. `assertRegionMatch` — the guard that exists to stop exactly
|
|
21225
|
+
* that inference — cannot fire, because after normalization
|
|
21226
|
+
* `DeleteContext.expectedRegion` and the client region are the same value by
|
|
21227
|
+
* construction.
|
|
21228
|
+
*
|
|
21229
|
+
* So the refusal is narrow by design and its trigger is the CONJUNCTION:
|
|
21230
|
+
* divergent AND at least one resource. **A resource-less record is
|
|
21231
|
+
* deliberately NOT refused** — there is nothing to orphan, and that is the
|
|
21232
|
+
* issue's own measured repro plus the `cdkd state destroy` recovery path the
|
|
21233
|
+
* read-side decision exists to protect. The read path still refuses NOTHING:
|
|
21234
|
+
* `cdkd state show`, `cdkd state list` and `cdkd state orphan` all keep
|
|
21235
|
+
* working on the very record this refuses to DELETE FROM, which is what keeps
|
|
21236
|
+
* it fixable.
|
|
21237
|
+
*
|
|
21238
|
+
* The remedy is a TEMPLATE, never a substituted command, for the reason
|
|
21239
|
+
* {@link malformedDestroyResourcesRefusalMessage} records — the region reaching
|
|
21240
|
+
* this builder is an S3 key SEGMENT, which anyone able to write the bucket
|
|
21241
|
+
* chooses. (NOT "because cdkd does not know which region belongs in the flag",
|
|
21242
|
+
* which an earlier revision said and which is false for this flag:
|
|
21243
|
+
* `--stack-region` on `state orphan` selects the RECORD, and the key's region
|
|
21244
|
+
* is exactly that.) The body's region is not printed at all — its KIND is, the
|
|
21245
|
+
* bounded token {@link describeRegionValueKind} produces, for the reason
|
|
21246
|
+
* `getState`'s warn gives.
|
|
21247
|
+
*
|
|
21248
|
+
* And the target-naming half is GATED on both identifiers rendering EXACTLY,
|
|
21249
|
+
* the second half of that sibling's rule: a template is not enough on its own,
|
|
21250
|
+
* because the name the reader types into it comes from the clause ABOVE.
|
|
21251
|
+
*/
|
|
21252
|
+
function divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBodyRegion, resourceCount) {
|
|
21253
|
+
const cap = STACK_REF_MAX_CODE_POINTS;
|
|
21254
|
+
const exact = safeIdentifier(stackName, cap) === stackName && safeIdentifier(keyRegion, cap) === keyRegion;
|
|
21255
|
+
const lists = resourceCount === void 0 ? "its resources map cannot be read" : `it still lists ${resourceCount} resource${resourceCount === 1 ? "" : "s"}`;
|
|
21256
|
+
const kind = describeRegionValueKind(divergentBodyRegion);
|
|
21257
|
+
const opening = exact ? `cdkd will not destroy stack ${shellQuote(safeIdentifier(stackName, cap))} (${shellQuote(safeIdentifier(keyRegion, cap))}): the state record read from that region's key carries a 'region' of its own (${kind}) that is not the key's, and ${lists}` : `cdkd will not destroy the state record this command loaded: it carries a 'region' of its own (${kind}) that is not the region of the key it was read from, and ${lists}`;
|
|
21258
|
+
const remedy = exact ? "Re-run with --verbose to see what the record's region field holds, then either destroy against the region the resources are really in, or repair that field to match the key it is stored under and re-run. To drop the record and leave the live resources standing, spelled out rather than pasteable because that command DELETES a record: cdkd state orphan <stack> --stack-region <region>" : `This record's stack name or region does NOT render exactly — what any surrounding output shows 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)}`;
|
|
21259
|
+
return `${opening} ${resourceCount === void 0 ? `— so cdkd can neither count what it would delete nor tell which region it is in` : `— so cdkd cannot tell which region those resources are in`}. cdkd stamps the key's region into every record it writes, so this record was not written by cdkd. Destroying against the key's region would issue every delete there; if the record's own region is the honest half, each delete comes back not-found, which this command reads as ALREADY DELETED — it would report success, remove the record, and leave every resource standing in the other region with nothing naming it. ${remedy}`;
|
|
21260
|
+
}
|
|
21261
|
+
/**
|
|
21262
|
+
* Refuse a destroy over a record whose body region diverged from its key's,
|
|
21263
|
+
* while it still lists resources — see
|
|
21264
|
+
* {@link divergentRecordRegionRefusalMessage} for why the conjunction is the
|
|
21265
|
+
* trigger and why a resource-less record is not refused.
|
|
21266
|
+
*
|
|
21267
|
+
* CALL IT AT THE TOP OF THE DESTROY, **above the `resourceCount` fast path**,
|
|
21268
|
+
* for the placement reason {@link refuseMalformedResourcesForDestroy} gives —
|
|
21269
|
+
* and BELOW that call, because this one reads the bag's SIZE and only that
|
|
21270
|
+
* guard proves the bag can be read at all.
|
|
21271
|
+
*
|
|
21272
|
+
* `divergentBodyRegion` is `S3StateBackend.getState`'s report, `undefined` on
|
|
21273
|
+
* every record that agreed with its key — which is every record cdkd wrote.
|
|
21274
|
+
*/
|
|
21275
|
+
function refuseDivergentRecordRegionForDestroy(state, stackName, keyRegion, divergentBodyRegion) {
|
|
21276
|
+
if (divergentBodyRegion === void 0) return;
|
|
21277
|
+
const resourceCount = isReadableBag(state.resources) ? Object.keys(state.resources).length : void 0;
|
|
21278
|
+
if (resourceCount === 0) return;
|
|
21279
|
+
throw markNonRetryable(new CdkdError(divergentRecordRegionRefusalMessage(stackName, keyRegion, divergentBodyRegion, resourceCount), STATE_REGION_DIVERGED));
|
|
21280
|
+
}
|
|
21052
21281
|
/**
|
|
21053
21282
|
* The DEPLOY refusal text for the `resources` bag (issue
|
|
21054
21283
|
* [#3161](https://github.com/go-to-k/cdkd/issues/3161)).
|
|
@@ -21560,10 +21789,12 @@ function stackClause(stackName, region) {
|
|
|
21560
21789
|
*
|
|
21561
21790
|
* **It diverges from {@link malformedDestroyResourcesRefusalMessage}, which
|
|
21562
21791
|
* keeps `cdkd state orphan` a template on purpose, and the difference is where
|
|
21563
|
-
* the identity comes from.** That builder is reached with a
|
|
21564
|
-
*
|
|
21565
|
-
*
|
|
21566
|
-
*
|
|
21792
|
+
* the identity comes from.** That builder is reached with a REGION cdkd read
|
|
21793
|
+
* off the state bucket (`state.region ?? ctx.baseRegion` in
|
|
21794
|
+
* `destroy-runner.ts`; since go-to-k/cdkd#3328 the first operand is the S3
|
|
21795
|
+
* KEY's region rather than the record body's, which is a key SEGMENT and so
|
|
21796
|
+
* still plantable) -- its stack name is the caller's, so the region alone is
|
|
21797
|
+
* what would aim a destructive command using a value cdkd does not own. This one is reached only with the caller's
|
|
21567
21798
|
* synthesized stack and `pickStackRegion`'s answer, so substituting is safe and
|
|
21568
21799
|
* omitting the region is the wider action. Two opposite precedents in one
|
|
21569
21800
|
* module; neither is the general rule.
|
|
@@ -22639,6 +22870,21 @@ var DiffCalculator = class DiffCalculator {
|
|
|
22639
22870
|
* The three environment variables that carry a static AWS identity into a child
|
|
22640
22871
|
* process or container. Spelled once here so a forwarding site and the fence
|
|
22641
22872
|
* that watches it cannot disagree about the population.
|
|
22873
|
+
*
|
|
22874
|
+
* That claim is only true while the population is IMPORTED, and for one release
|
|
22875
|
+
* it was not: every `forwardAwsEnv` body hardcoded its own array and
|
|
22876
|
+
* `local-surface-env-identity.test.ts` hardcoded the quoted literal, so the
|
|
22877
|
+
* constant guaranteed nothing and a fourth key added here would have reached
|
|
22878
|
+
* neither (issue [#3250](https://github.com/go-to-k/cdkd/issues/3250) item 4).
|
|
22879
|
+
* Every forwarding site now spreads this array and the fence treats the
|
|
22880
|
+
* constant's NAME as one of its site shapes, with a floor per spelling — so a
|
|
22881
|
+
* site quietly going back to a local copy drops out of one shape's count while
|
|
22882
|
+
* the other stays green, which is the failure that floor exists to report.
|
|
22883
|
+
*
|
|
22884
|
+
* Derive the readers with
|
|
22885
|
+
* `grep -rn AWS_CREDENTIAL_ENV_KEYS src tests`, never from a list written here:
|
|
22886
|
+
* a list of call sites in a doc comment is the shape that went stale in the
|
|
22887
|
+
* first place.
|
|
22642
22888
|
*/
|
|
22643
22889
|
const AWS_CREDENTIAL_ENV_KEYS = [
|
|
22644
22890
|
"AWS_ACCESS_KEY_ID",
|
|
@@ -22686,6 +22932,25 @@ function callerEnvCredentials() {
|
|
|
22686
22932
|
return getPreAssumeEnvCredentials();
|
|
22687
22933
|
}
|
|
22688
22934
|
/**
|
|
22935
|
+
* Is the credential triple currently in `process.env` cdkd's OWN `--role-arn`
|
|
22936
|
+
* assumed role rather than the caller's?
|
|
22937
|
+
*
|
|
22938
|
+
* For a site that has to EXPLAIN a `callerEnvCredentials()` miss, not for one
|
|
22939
|
+
* that has to act on it. `undefined` from that function is ambiguous to a USER
|
|
22940
|
+
* in exactly one direction: with a role assumed, `AWS_ACCESS_KEY_ID` is visibly
|
|
22941
|
+
* set — cdkd set it — so an error telling them to set it is advice they have
|
|
22942
|
+
* already followed, and the real reason is that cdkd refuses to act as the role
|
|
22943
|
+
* here (issue [#3250](https://github.com/go-to-k/cdkd/issues/3250) item 5).
|
|
22944
|
+
*
|
|
22945
|
+
* Do not branch BEHAVIOUR on this. The three-way decision belongs to
|
|
22946
|
+
* `callerEnvCredentials` / `applyCallerIdentityCredentials`, which distinguish
|
|
22947
|
+
* "no role assumed" from "a role assumed over a caller who had nothing" — a
|
|
22948
|
+
* distinction this boolean deliberately collapses.
|
|
22949
|
+
*/
|
|
22950
|
+
function envCredentialsAreAssumedRole() {
|
|
22951
|
+
return getAssumedRoleCredentials() !== void 0;
|
|
22952
|
+
}
|
|
22953
|
+
/**
|
|
22689
22954
|
* Correct an environment bag that was populated by copying `process.env`, so it
|
|
22690
22955
|
* carries the CALLER's identity rather than a `--role-arn` assumed role's.
|
|
22691
22956
|
*
|
|
@@ -32160,7 +32425,7 @@ var CloudControlProvider = class {
|
|
|
32160
32425
|
const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
32161
32426
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
32162
32427
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
32163
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
32428
|
+
const { ASGProvider } = await import("./asg-provider-7KM2pV3Q.js").then((n) => n.n);
|
|
32164
32429
|
const asgProvider = new ASGProvider();
|
|
32165
32430
|
return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
|
|
32166
32431
|
}
|
|
@@ -36308,8 +36573,8 @@ var IAMRoleProvider = class {
|
|
|
36308
36573
|
this.logger.warn(`Skipped deleting old role ${physicalId} during replacement: ${deleteResult.reason}. The old role may be orphaned and require manual cleanup.`);
|
|
36309
36574
|
}
|
|
36310
36575
|
} catch (error) {
|
|
36311
|
-
orphanReason = `old role ${physicalId} could not be deleted: ${safeStringify(error)}`;
|
|
36312
|
-
this.logger.warn(`Failed to delete old role ${physicalId} during replacement: ${safeStringify(error)}. The old role may be orphaned and require manual cleanup.`);
|
|
36576
|
+
orphanReason = `old role ${physicalId} could not be deleted: ${safeStringify$1(error)}`;
|
|
36577
|
+
this.logger.warn(`Failed to delete old role ${physicalId} during replacement: ${safeStringify$1(error)}. The old role may be orphaned and require manual cleanup.`);
|
|
36313
36578
|
}
|
|
36314
36579
|
const base = {
|
|
36315
36580
|
physicalId: createResult.physicalId,
|
|
@@ -38526,6 +38791,23 @@ function makeSiblingClaimReader(params) {
|
|
|
38526
38791
|
//#endregion
|
|
38527
38792
|
//#region src/types/deployment-events.ts
|
|
38528
38793
|
/**
|
|
38794
|
+
* Structured deployment-event types (issue #808).
|
|
38795
|
+
*
|
|
38796
|
+
* cdkd's CloudFormation `DescribeStackEvents` equivalent: every deploy /
|
|
38797
|
+
* destroy run appends one JSONL line per lifecycle event to
|
|
38798
|
+
* `s3://{bucket}/{prefix}/{stackName}/{region}/deployments/{runId}.jsonl`,
|
|
38799
|
+
* plus a small `deployments/index.json` listing the last N runs.
|
|
38800
|
+
*
|
|
38801
|
+
* Deliberately a SEPARATE key family from `state.json` — no state schema
|
|
38802
|
+
* bump is involved (state stays at its current version), and event files
|
|
38803
|
+
* survive `cdkd destroy` (state deletion does not touch `deployments/`),
|
|
38804
|
+
* so post-mortem context is available even after the stack is gone.
|
|
38805
|
+
*
|
|
38806
|
+
* SECURITY: events carry error + metadata ONLY. Resource properties are
|
|
38807
|
+
* never recorded here (they may contain secrets); properties already live
|
|
38808
|
+
* in state.json.
|
|
38809
|
+
*/
|
|
38810
|
+
/**
|
|
38529
38811
|
* Walk an error's `.cause` chain (bounded) and extract metadata for a
|
|
38530
38812
|
* deployment event. The outermost error supplies `name` / `message`
|
|
38531
38813
|
* (matching what the user sees in the log); the innermost AWS-SDK-shaped
|
|
@@ -38535,7 +38817,7 @@ function makeSiblingClaimReader(params) {
|
|
|
38535
38817
|
function extractDeploymentEventError(err) {
|
|
38536
38818
|
if (!(err instanceof Error)) return {
|
|
38537
38819
|
name: "UnknownError",
|
|
38538
|
-
message:
|
|
38820
|
+
message: safeStringify$1(err)
|
|
38539
38821
|
};
|
|
38540
38822
|
const result = {
|
|
38541
38823
|
name: err.name || "Error",
|
|
@@ -38707,7 +38989,7 @@ const PRE_DELETE_SNAPSHOT_TIMEOUT_MS = 36e5;
|
|
|
38707
38989
|
/** Post-snapshot settle budget for a Redshift cluster before its delete. */
|
|
38708
38990
|
const REDSHIFT_CLUSTER_SETTLE_TIMEOUT_MS = 12e5;
|
|
38709
38991
|
function errMsg(error) {
|
|
38710
|
-
return
|
|
38992
|
+
return describeAwsFailure(error).detail;
|
|
38711
38993
|
}
|
|
38712
38994
|
function isVolumeNotFound(error) {
|
|
38713
38995
|
return (error instanceof Error ? error.name : "") === "InvalidVolume.NotFound" || errMsg(error).includes("InvalidVolume.NotFound");
|
|
@@ -45154,5 +45436,5 @@ var DeployEngine = class DeployEngine {
|
|
|
45154
45436
|
};
|
|
45155
45437
|
|
|
45156
45438
|
//#endregion
|
|
45157
|
-
export { secretBearing as $,
|
|
45158
|
-
//# sourceMappingURL=deploy-engine-
|
|
45439
|
+
export { secretBearing as $, formatError as $i, recordMaskOnlyValue as $n, getDockerImageBySourceHash as $r, s3BucketArn as $t, extractDeploymentEventError as A, resetAwsClients as Ai, refuseMalformedState as An, assertAssetBucketRegion as Ar, isImpossibleEmptyStoredAttribute as At, toCfnInteger as B, LocalInvokeBuildError as Bi, STATE_SOURCED_BASELINE_RULES as Bn, describeDockerCapturedOutput as Br, coerceCfnBoolean as Bt, buildFinalSnapshotIdentifier as C, derivePartitionAndUrlSuffix as Ci, producerRecordKey as Cn, WorkGraph as Cr, isTerminationProtectionPropagationError as Ct, refusesFinalSnapshot as D, resolveBucketRegion as Di, refuseMalformedOutputsForDestroy as Dn, rewriteTemplateAssetReferences as Dr, cfnRefValueFromPhysicalId as Dt, isFinalSnapshotError as E, clearBucketRegionCache as Ei, refuseMalformedOutputs as En, loadPublishableAssetManifest as Er, carriesFetchableDynamicReference as Et, isStatefulRecreateTargetSync as F, CrossAccountSecretRefusalError as Fi, findSilentDropProperties as Fn, readBootstrapMarkerBody as Fr, isSettledInstanceState as Ft, gray as G, PartialFailureError as Gi, createSecretMasker as Gn, getDockerCmd as Gr, readConfigString as Gt, formatResourceLine as H, LockError as Hi, STATE_SOURCED_READBACK_RULES as Hn, describeDockerFailure as Hr, configBooleanRefusal as Ht, renderStatefulReason as I, DependencyError as Ii, describeTypeWithThrottleRetry as In, validateAssetBucketName as Ir, WAFv2WebACLProvider as It, yellow as J, ResourceUpdateNotSupportedError as Ji, identityKeyFor as Jn, runDockerForeground as Jr, requireConfigObject as Jt, green as K, ProvisioningError as Ki, dynamicReferenceTokens as Kn, partitionSensitiveEnv as Kr, replayWarn as Kt, WARM_THROUGHPUT_MEMBERS as L, DeployCancelledError as Li, withRetry as Ln, validateContainerRepoName as Lr, normalizeAwsTagsToCfn as Lt, planOrphanAdoption as M, AssetError as Mi, repairMalformedResourcePropertiesForReadOnly as Mn, getBootstrapMarkerKey as Mr, isUnboundTemplateParameter as Mt, MULTI_REGION_RECREATE_BLOCKED_TYPES as N, CdkdError as Ni, repairMalformedResourcesForReadOnly as Nn, isCrossRegionRedirect as Nr, parameterTypeMayLoseSecretIdentity as Nt, unsupportedFinalSnapshotError as O, AwsClients as Oi, refuseMalformedResourcePropertiesForOrphan as On, AssetModeResolver as Or, coerceParameterTypedValue as Ot, isStatefulRecreateTargetForReplace as P, ConfigError as Pi, findActionableSilentDrops as Pn, parseBootstrapMarker as Pr, refStateLookupFromResource as Pt, isExportAliasCollision as Q, SynthesisError as Qi, maskSecretsInText as Qn, AssetManifestLoader as Qr, withSharedDrainBudget as Qt, coerceWarmThroughput as R, DynamicReferenceRegionAmbiguousError as Ri, DagBuilder as Rn, buildDenyExternalAccessPolicy as Rr, resolveExplicitPhysicalId as Rt, PRE_DELETE_SNAPSHOT_TYPES as S, canonicalizeRegion as Si, malformedStateRefusalMessage as Sn, stringifyValue as Sr, disableInstanceApiTermination as St, createPreDeleteFinalSnapshot as T, processStackMessages as Ti, refuseMalformedNestedChildOutputs as Tn, createAssetRedirectResolver as Tr, carriesDynamicReference as Tt, bold as U, MalformedProducerRecordRefusalError as Ui, TEMPLATE_SOURCED_RULES as Un, dockerSpawnEnvWithSensitive as Ur, configIntegerRefusal as Ut, toFiniteNumber as V, LocalStartServiceError as Vi, STATE_SOURCED_CROSS_GENERATION_RULES as Vn, describeDockerExecFailure as Vr, coerceCfnInteger as Vt, cyan as W, NestedStackChildDirectDestroyError as Wi, carriesSecretMask as Wn, formatDockerLoginError as Wr, configStringRefusal as Wt, collectPublishedOutputNames as X, StackTerminationProtectionError as Xi, markSameGenerationBag as Xn, escapeRegExp$1 as Xr, classifyReplaySecretRegion as Xt, collectDeclaredOutputNames as Y, StackHasActiveImportsError as Yi, isSingleDynamicReferenceToken as Yn, runDockerStreaming as Yr, requireConfigString as Yt, exportAliasCollisionScrubWarning as Z, StateError as Zi, maskSecretsInError as Zn, stripControlChars as Zr, producerRegionsFromState as Zt, isSecretBearingReferenceString as _, uploadCfnTemplate as _i, malformedOutputsRefusalMessage as _n, isReadableBag as _r, isWaitAbandonedError as _t, DeploymentEventsStore as a, isThrottlingError as aa, resolveAutoAssetStorage as ai, AWS_CREDENTIAL_ENV_KEYS as an, rebuildClientForBucketRegion as ar, clearOnUpdateRemoval as at, bindingSkippedOutputs as b, expectedOwnerParam as bi, malformedResourcePropertiesWarning as bn, shouldRetainResource as br, deleteIndeterminateGuards as bt, replayFailedOperations as c, markRedactedCause as ca, resolveStateBucketWithDefault as ci, envCredentialsAreAssumedRole as cn, forceQuitRecoveryClause as cr, createMaskedRetryLogger as ct, updatePartialReason as d, safeStringify$1 as da, stateBucketExistenceConfirmed as di, STATE_RESOURCES_MALFORMED as dn, CUSTOM_RESOURCE_RESPONSE_PREFIX as dr, beginCommandInterruptScope as dt, isCdkdError as ea, Synthesizer as ei, s3BucketDomainName as en, recoverMaskedOutput as er, secretBearingStateKeyWarning as et, withResourceDeadline as f, __exportAll as fa, warnDeprecatedNoPrefixCliFlag as fi, hasReadableOutputs as fn, DEFAULT_STATE_PREFIX as fr, endCommandInterruptScope as ft, bagHoldsSecretExpression as g, findLargeInlineResources as gi, malformedLocalOutputsWarning as gn, importableOutputs as gr, CloudControlProvider as gt, computeImplicitDeleteEdges as h, MIGRATE_TMP_PREFIX as hi, malformedExportSourceWarning as hn, importableOutputKeys as hr, startInterruptWatch as ht, DeploymentEventsReader as i, isRetryableTransientError as ia, resolveApp as ii, applyRoleArnIfSet as in, S3StateBackend as ir, collectInlinePolicyNamesManagedBySiblings as it, makeSiblingClaimReader as j, setAwsClients as ji, repairMalformedOutputsForReadOnly as jn, ensureAssetStorage as jr, isNamelessDynamicReferenceError as jt, makeCanonicalizePropertiesFn as k, getAwsClients as ki, refuseMalformedResourcesForDestroy as kn, BOOTSTRAP_MARKER_PREFIX as kr, getAccountInfo as kt, replayRollback as l, retryClassificationText as la, resolveStateBucketWithDefaultAndSource as li, DiffCalculator as ln, formatLockExpiry as lr, maskDeep as lt, IMPLICIT_DELETE_DEPENDENCIES as m, CFN_TEMPLATE_URL_LIMIT as mi, malformedExportNamesWarning as mn, hasReadableExportSet as mr, isInterruptedWaitError as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, withErrorHandling as na, getDefaultStateBucketName as ni, s3BucketRegionalDomainName as nn, scrubResourceRecord as nr, getCurrentResourceSecrets as nt, planFailedOps as o, isTransientServerError as oa, resolveCaptureObservedState as oi, applyCallerIdentityCredentials as on, buildForceUnlockCommand as or, ProviderRegistry as ot, maskingRetryLogger as p, CFN_TEMPLATE_BODY_LIMIT as pi, hasReadableResources as pn, exportNamesCarriedFrom as pr, interruptWatchListenerCount as pt, red as q, ResourceTimeoutError as qi, errorCauseChain as qn, redactDockerArgvValues as qr, requireConfigArray as qt, DeployEngine as r, isMarkedNonRetryable as ra, getLegacyStateBucketName as ri, s3BucketWebsiteUrl as rn, LockManager as rr, IAMRoleProvider as rt, planRollback as s, markNonRetryable as sa, resolveSkipPrefix as si, callerEnvCredentials as sn, buildLockContentionMessage as sr, wouldReturnToSdkProvider as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, normalizeAwsError as ta, synthesisStatusMessage as ti, s3BucketDualStackDomainName as tn, redactSecretsForState as tr, secretSafeKeyDisplay as tt, updatePartialMessage as u, describeAwsFailure as ua, resolveUseCdkBootstrapAssets as ui, INTRINSIC_KEYS as un, shellQuote as ur, maskerOrIdentity as ut, keptWholeReasonText as v, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as vi, malformedOutputsWarning as vn, orphansAfterRollback as vr, slowCcOperationTimeoutMs as vt, ccRoutedFinalSnapshotError as w, AssemblyReader as wi, refuseDivergentRecordRegionForDestroy as wn, buildAssetRedirectMap as wr, IntrinsicFunctionResolver as wt, ATOMIC_FINAL_SNAPSHOT_TYPES as x, PARTITION_TABLE as xi, malformedResourcesWarning as xn, AssetPublisher as xr, deleteSkipReason as xt, mergeNoChangeOutputs as y, decodeListingKey as yi, malformedRenderedContainersWarning as yn, orphansCarriedFrom as yr, UNSPECIFIED_SKIP_REASON as yt, isWarmThroughputDecrease as z, IntrinsicResolutionRefusalError as zi, TemplateParser as zn, buildDockerImage as zr, assertRegionMatch as zt };
|
|
45440
|
+
//# sourceMappingURL=deploy-engine-CbIc5Y73.js.map
|