cdk-local 0.147.21 → 0.148.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +3 -18
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -2
- package/dist/{local-studio-BBA_8Xvk.d.ts → local-studio-9bZLFQqv.d.ts} +31 -2
- package/dist/local-studio-9bZLFQqv.d.ts.map +1 -0
- package/dist/{local-studio-J8BtocsI.js → local-studio-DoyRYZf6.js} +354 -156
- package/dist/local-studio-DoyRYZf6.js.map +1 -0
- package/package.json +8 -1
- package/dist/local-studio-BBA_8Xvk.d.ts.map +0 -1
- package/dist/local-studio-J8BtocsI.js.map +0 -1
|
@@ -5,6 +5,13 @@ import * as path$1 from "node:path";
|
|
|
5
5
|
import path, { dirname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
6
6
|
import { Command, Option } from "commander";
|
|
7
7
|
import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
|
|
8
|
+
import { Agent, createServer, request } from "node:http";
|
|
9
|
+
import { Agent as Agent$1, createServer as createServer$1 } from "node:https";
|
|
10
|
+
import { NodeHttpHandler } from "@smithy/node-http-handler";
|
|
11
|
+
import { Agent as Agent$2 } from "agent-base";
|
|
12
|
+
import { HttpProxyAgent } from "http-proxy-agent";
|
|
13
|
+
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
14
|
+
import { getProxyForUrl } from "proxy-from-env";
|
|
8
15
|
import { unzipSync } from "fflate";
|
|
9
16
|
import { MultiSelectPrompt } from "@clack/core";
|
|
10
17
|
import { S_BAR, S_BAR_END, S_BAR_START, S_CHECKBOX_ACTIVE, S_CHECKBOX_INACTIVE, S_CHECKBOX_SELECTED, confirm, isCancel, multiselect, select, text } from "@clack/prompts";
|
|
@@ -15,7 +22,7 @@ import { GetFunctionConfigurationCommand, LambdaClient } from "@aws-sdk/client-l
|
|
|
15
22
|
import { BedrockAgentCoreControlClient, GetAgentRuntimeCommand } from "@aws-sdk/client-bedrock-agentcore-control";
|
|
16
23
|
import { GetParameterCommand, GetParametersCommand, SSMClient } from "@aws-sdk/client-ssm";
|
|
17
24
|
import { execFile, spawn } from "node:child_process";
|
|
18
|
-
import { connect, createServer } from "node:net";
|
|
25
|
+
import { connect, createServer as createServer$2 } from "node:net";
|
|
19
26
|
import { promisify } from "node:util";
|
|
20
27
|
import * as nodeCrypto from "node:crypto";
|
|
21
28
|
import { X509Certificate, createHash, createHmac, createPublicKey, createVerify, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -25,8 +32,6 @@ import { join as join$1 } from "path";
|
|
|
25
32
|
import { WebSocket, WebSocketServer } from "ws";
|
|
26
33
|
import { Readable } from "node:stream";
|
|
27
34
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
28
|
-
import { createServer as createServer$1, request } from "node:http";
|
|
29
|
-
import { createServer as createServer$2 } from "node:https";
|
|
30
35
|
import { mkdir, mkdtemp, readFile as readFile$1, readdir, rm, writeFile } from "node:fs/promises";
|
|
31
36
|
import { pipeline } from "node:stream/promises";
|
|
32
37
|
import * as chokidar from "chokidar";
|
|
@@ -42,6 +47,290 @@ import { CloudFrontClient, paginateListKeyValueStores } from "@aws-sdk/client-cl
|
|
|
42
47
|
import { CloudFrontKeyValueStoreClient, GetKeyCommand, ResourceNotFoundException } from "@aws-sdk/client-cloudfront-keyvaluestore";
|
|
43
48
|
import { EventEmitter } from "node:events";
|
|
44
49
|
|
|
50
|
+
//#region src/utils/url-authority.ts
|
|
51
|
+
/**
|
|
52
|
+
* Compose the authority component of a URL from a host and a port.
|
|
53
|
+
*
|
|
54
|
+
* Every local serve prints an endpoint banner, and several of those banners
|
|
55
|
+
* are MACHINE-PARSED — `cdkl studio` reads them to learn where to point its
|
|
56
|
+
* capture proxy (`local/studio-serve-manager`'s `readyRe` /
|
|
57
|
+
* `parsePublishedHostEndpoint`), then resolves the result with `new URL(...)`
|
|
58
|
+
* before it will forward anything there. So an authority that the WHATWG
|
|
59
|
+
* parser rejects is not a cosmetic log defect: the serve is refused.
|
|
60
|
+
*
|
|
61
|
+
* The one shape that used to be composed wrong is an IPv6 literal. RFC 3986
|
|
62
|
+
* 3.2.2 requires it to be bracketed inside an authority, so a bare
|
|
63
|
+
* `${host}:${port}` turns `--container-host ::` into `http://:::8080`, which
|
|
64
|
+
* is not a URL — while the IPv4 wildcard `0.0.0.0`, the same intention spelled
|
|
65
|
+
* differently, works. Issue go-to-k/cdk-local#599.
|
|
66
|
+
*
|
|
67
|
+
* The detection is mechanical rather than a list of known values: a colon is
|
|
68
|
+
* forbidden in both a registered name and an IPv4 address, so a host carrying
|
|
69
|
+
* one is an IPv6 literal — PROVIDED the rest of it could be one, which is a
|
|
70
|
+
* character-class test (hex digits, `:`, and `.` for the IPv4-mapped form)
|
|
71
|
+
* rather than an enumeration. The qualifier is load-bearing rather than
|
|
72
|
+
* pedantry: `buildRedirectLocation` fills its host from an ALB `#{host}`
|
|
73
|
+
* template or a configured literal, so a CRLF-injection attempt reaches this
|
|
74
|
+
* function AS-IS — `example.test\r\nx-injected: yes`, with the CR/LF still in
|
|
75
|
+
* it, because `front-door-server` sanitises the Location only AFTER building
|
|
76
|
+
* it. Either way it is a colon in something that is not an address and must
|
|
77
|
+
* pass through untouched rather than gain brackets it never had. (CR and LF
|
|
78
|
+
* are outside the character class by construction, so the raw and flattened
|
|
79
|
+
* spellings classify identically — but the raw one is what actually arrives.)
|
|
80
|
+
* Caught by `front-door-server.test.ts`'s raw-socket injection case.
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
83
|
+
* A host that could be an IPv6 literal: hex digits, `:` separators, and `.`
|
|
84
|
+
* for the IPv4-mapped form (`::ffff:127.0.0.1`). Deliberately NOT a full
|
|
85
|
+
* grammar — the job is to separate "an address" from "not an address", and
|
|
86
|
+
* validating an address that has already been bound to is not this function's
|
|
87
|
+
* business.
|
|
88
|
+
*/
|
|
89
|
+
const IPV6_LITERAL_CHARS = /^[0-9A-Fa-f:.]+$/;
|
|
90
|
+
/**
|
|
91
|
+
* Render `host` as it must appear inside a URL authority.
|
|
92
|
+
*
|
|
93
|
+
* - An IPv6 literal is bracketed, in either case (`FE80::1` -> `[FE80::1]`).
|
|
94
|
+
* - An already-bracketed literal comes back bracketed exactly once, so the
|
|
95
|
+
* function is idempotent: `[::1]` never becomes `[[::1]]`. That matters
|
|
96
|
+
* because a caller often feeds back a `URL.hostname`, which is ALREADY
|
|
97
|
+
* bracketed.
|
|
98
|
+
* - A zone id (`fe80::1%en0`) is DROPPED, keeping `[fe80::1]`. No URL parser
|
|
99
|
+
* accepts one — Node's `new URL` throws on both the raw `%en0` and the
|
|
100
|
+
* percent-encoded `%25en0` — and a zone id is a host-local interface
|
|
101
|
+
* selector that carries no meaning for whoever reads the banner. Emitting
|
|
102
|
+
* an authority nothing can parse is the exact failure this helper exists to
|
|
103
|
+
* prevent, so the scope is dropped rather than propagated. The brackets are
|
|
104
|
+
* removed BEFORE that decision, so `[fe80::1%en0]` is stripped too — an
|
|
105
|
+
* early return on "already bracketed" would have waved the one input that
|
|
106
|
+
* is both bracketed and unparseable straight through.
|
|
107
|
+
* - Everything else (IPv4 literal, registered name, the empty string, and a
|
|
108
|
+
* colon-bearing string that is not an address) is returned untouched.
|
|
109
|
+
*/
|
|
110
|
+
function formatHostForAuthority(host) {
|
|
111
|
+
const inner = host.length > 1 && host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
|
|
112
|
+
if (!inner.includes(":")) return host;
|
|
113
|
+
const zoneAt = inner.indexOf("%");
|
|
114
|
+
const literal = zoneAt === -1 ? inner : inner.slice(0, zoneAt);
|
|
115
|
+
if (!IPV6_LITERAL_CHARS.test(literal)) return host;
|
|
116
|
+
return `[${literal}]`;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compose `<host>:<port>` for use inside a URL, bracketing an IPv6 literal.
|
|
120
|
+
*
|
|
121
|
+
* An empty `host` is passed through as-is rather than substituted: the helper
|
|
122
|
+
* composes an authority, it does not invent a host, and a caller that has no
|
|
123
|
+
* host has a bug of its own. The result (`:8080`) does not parse, which is the
|
|
124
|
+
* honest rendering of that state.
|
|
125
|
+
*/
|
|
126
|
+
function formatAuthority(host, port) {
|
|
127
|
+
return `${formatHostForAuthority(host)}:${port}`;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Read the HOST out of an authority (`<host>` or `<host>:<port>`), returning
|
|
131
|
+
* it BARE — an IPv6 literal comes back without its brackets, ready to be
|
|
132
|
+
* handed straight back to {@link formatAuthority}.
|
|
133
|
+
*
|
|
134
|
+
* The inverse of {@link formatAuthority}, and it exists for the same reason:
|
|
135
|
+
* `authority.split(':')[0]` is the obvious thing to write and it is wrong for
|
|
136
|
+
* exactly one input. A conforming client sends `Host: [::1]:8080` (measured —
|
|
137
|
+
* see `tests/unit/local/ipv6-host-header.test.ts`), and splitting that on the
|
|
138
|
+
* first colon yields `'['`, so an ALB `#{host}` substitution built from it
|
|
139
|
+
* produced `http://[:8080/...`. Issue go-to-k/cdk-local#599.
|
|
140
|
+
*
|
|
141
|
+
* # It refuses rather than guesses — on BOTH arms
|
|
142
|
+
*
|
|
143
|
+
* This is an attacker-reachable parser: the request `Host` header feeds an
|
|
144
|
+
* ALB `#{host}` substitution, and whatever comes back is composed into a
|
|
145
|
+
* redirect `Location`. So a malformed authority yields the empty string
|
|
146
|
+
* rather than the fragment that happens to be readable, on either branch.
|
|
147
|
+
*
|
|
148
|
+
* BRACKETED — read to the closing `]`, and only when the value is
|
|
149
|
+
* well-formed: there must BE a closing bracket, and what follows it must be
|
|
150
|
+
* empty or `:<digits>`. Guessing here is the worse of the two directions,
|
|
151
|
+
* because the guess PARSES: `[evil.example` (no closing bracket) would come
|
|
152
|
+
* back as `evil.example`, turning a half-named host into a valid `Location`
|
|
153
|
+
* the client would follow, where the malformed input should have produced
|
|
154
|
+
* nothing. `[a:b]junk` would silently drop its trailing junk, and `[x:y`
|
|
155
|
+
* would return a multi-colon value as a host — the very thing the other arm
|
|
156
|
+
* refuses.
|
|
157
|
+
*
|
|
158
|
+
* UNBRACKETED — the text before its single `:`. Two or more colons yields
|
|
159
|
+
* the empty string: it is not a shape any conforming client sends (Node
|
|
160
|
+
* brackets — measured in `tests/unit/local/ipv6-host-header.test.ts`), it has
|
|
161
|
+
* no unambiguous split, and returning the leading fragment would hand a
|
|
162
|
+
* caller a host that is not the one named. `split(':')[0]` did exactly that —
|
|
163
|
+
* `fe80::1:8080` came back as `'fe80'`.
|
|
164
|
+
*/
|
|
165
|
+
function hostFromAuthority(authority) {
|
|
166
|
+
if (authority.startsWith("[")) {
|
|
167
|
+
const close = authority.indexOf("]");
|
|
168
|
+
if (close === -1) return "";
|
|
169
|
+
const afterBracket = authority.slice(close + 1);
|
|
170
|
+
if (afterBracket !== "" && !/^:\d+$/.test(afterBracket)) return "";
|
|
171
|
+
return authority.slice(1, close);
|
|
172
|
+
}
|
|
173
|
+
const firstColon = authority.indexOf(":");
|
|
174
|
+
if (firstColon === -1) return authority;
|
|
175
|
+
if (authority.includes(":", firstColon + 1)) return "";
|
|
176
|
+
return authority.slice(0, firstColon);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/utils/aws-proxy.ts
|
|
181
|
+
/**
|
|
182
|
+
* Proxy-aware AWS SDK client plumbing (issue #634).
|
|
183
|
+
*
|
|
184
|
+
* The AWS SDK for JavaScript v3 does not read `HTTPS_PROXY` / `HTTP_PROXY` /
|
|
185
|
+
* `NO_PROXY` on its own: a proxy must be supplied through a `requestHandler`
|
|
186
|
+
* by whoever constructs the client. On a machine whose only egress is a
|
|
187
|
+
* corporate forward proxy, every AWS call cdk-local makes would otherwise
|
|
188
|
+
* fail (typically as `CredentialsProviderError: self-signed certificate in
|
|
189
|
+
* certificate chain` — the direct route is intercepted).
|
|
190
|
+
*
|
|
191
|
+
* `buildProxyClientConfig()` is the single seam: it returns an EMPTY config
|
|
192
|
+
* when no proxy environment variable is set (zero behavior change for
|
|
193
|
+
* existing users), and a `{ requestHandler, credentials }` fragment when one
|
|
194
|
+
* is. Every AWS SDK client construction in cdk-local spreads it (directly, or
|
|
195
|
+
* via `buildStsClientConfig` for the STS sites);
|
|
196
|
+
* `tests/unit/utils/aws-proxy-client-audit.test.ts` fences the sweep so a new
|
|
197
|
+
* construction site cannot silently skip it.
|
|
198
|
+
*/
|
|
199
|
+
/**
|
|
200
|
+
* The SDK applies these defaults only when it builds its OWN agents from a
|
|
201
|
+
* plain option bag; an externally supplied Agent instance passes through
|
|
202
|
+
* `NodeHttpHandler.resolveDefaultConfig` untouched. Set them explicitly so
|
|
203
|
+
* the proxied path keeps the same socket profile as the unproxied default.
|
|
204
|
+
*/
|
|
205
|
+
const AGENT_OPTS = {
|
|
206
|
+
keepAlive: true,
|
|
207
|
+
maxSockets: 50
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Whether any standard proxy environment variable is set (either spelling).
|
|
211
|
+
* `NO_PROXY` alone does not count — with no proxy to route to there is
|
|
212
|
+
* nothing to exempt from.
|
|
213
|
+
*
|
|
214
|
+
* Read live (not memoized) so a host CLI that sets the variables
|
|
215
|
+
* programmatically before constructing clients is honored.
|
|
216
|
+
*/
|
|
217
|
+
function isProxyEnvConfigured() {
|
|
218
|
+
const env = process.env;
|
|
219
|
+
return Boolean(env["https_proxy"] || env["HTTPS_PROXY"] || env["http_proxy"] || env["HTTP_PROXY"] || env["all_proxy"] || env["ALL_PROXY"]);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* An `agent-base` Agent that decides PER REQUEST whether to tunnel through
|
|
223
|
+
* the configured proxy or connect directly. `NodeHttpHandler` picks its agent
|
|
224
|
+
* by protocol alone, and `https-proxy-agent` does not consult `NO_PROXY` —
|
|
225
|
+
* so the `NO_PROXY` decision has to live in `connect()`, where the target
|
|
226
|
+
* host is known.
|
|
227
|
+
*
|
|
228
|
+
* `getProxyForUrl` (proxy-from-env) implements the standard semantics:
|
|
229
|
+
* lowercase spellings win, entries split on commas AND whitespace, an entry
|
|
230
|
+
* is an EXACT hostname match unless it starts with `.` or `*` (then a
|
|
231
|
+
* suffix match), a `:port` on an entry must match the target port, and a
|
|
232
|
+
* bare `*` disables proxying entirely.
|
|
233
|
+
*
|
|
234
|
+
* The inner agents are cached per proxy URL (not rebuilt per `connect()`),
|
|
235
|
+
* and `destroy()` forwards to every one of them. Exported for unit tests;
|
|
236
|
+
* construct through {@link buildProxyClientConfig} everywhere else.
|
|
237
|
+
*/
|
|
238
|
+
var EnvRoutingProxyAgent = class extends Agent$2 {
|
|
239
|
+
proxyAgents = /* @__PURE__ */ new Map();
|
|
240
|
+
directHttpAgent = new Agent(AGENT_OPTS);
|
|
241
|
+
directHttpsAgent = new Agent$1(AGENT_OPTS);
|
|
242
|
+
constructor() {
|
|
243
|
+
super(AGENT_OPTS);
|
|
244
|
+
}
|
|
245
|
+
connect(_req, options) {
|
|
246
|
+
const secure = options.secureEndpoint;
|
|
247
|
+
const host = options.host ?? "localhost";
|
|
248
|
+
const port = options.port || (secure ? 443 : 80);
|
|
249
|
+
const proxyUrl = getProxyForUrl(`${secure ? "https" : "http"}://${formatAuthority(host, port)}`);
|
|
250
|
+
if (!proxyUrl) return secure ? this.directHttpsAgent : this.directHttpAgent;
|
|
251
|
+
const key = `${secure ? "https" : "http"}|${proxyUrl}`;
|
|
252
|
+
let agent = this.proxyAgents.get(key);
|
|
253
|
+
if (!agent) {
|
|
254
|
+
agent = secure ? new HttpsProxyAgent(proxyUrl, AGENT_OPTS) : new HttpProxyAgent(proxyUrl, AGENT_OPTS);
|
|
255
|
+
this.proxyAgents.set(key, agent);
|
|
256
|
+
}
|
|
257
|
+
return agent;
|
|
258
|
+
}
|
|
259
|
+
destroy() {
|
|
260
|
+
for (const agent of this.proxyAgents.values()) agent.destroy();
|
|
261
|
+
this.proxyAgents.clear();
|
|
262
|
+
this.directHttpAgent.destroy();
|
|
263
|
+
this.directHttpsAgent.destroy();
|
|
264
|
+
super.destroy();
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* Build a fresh `NodeHttpHandler` that routes through the proxy environment.
|
|
269
|
+
* Fresh per call on purpose: `NodeHttpHandler.destroy()` destroys its agents
|
|
270
|
+
* unconditionally (external instances included), so a handler — and its
|
|
271
|
+
* agents — must never be shared across clients, or one client's `destroy()`
|
|
272
|
+
* strands its siblings.
|
|
273
|
+
*/
|
|
274
|
+
function buildProxyRequestHandler() {
|
|
275
|
+
const agent = new EnvRoutingProxyAgent();
|
|
276
|
+
return new NodeHttpHandler({
|
|
277
|
+
httpAgent: agent,
|
|
278
|
+
httpsAgent: agent
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* AWS SDK client config that honors the standard proxy environment
|
|
283
|
+
* (`HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY`, lowercase spellings included,
|
|
284
|
+
* with `NO_PROXY` exemptions evaluated per request).
|
|
285
|
+
*
|
|
286
|
+
* Returns `{}` when no proxy variable is set, so the unproxied path keeps
|
|
287
|
+
* the SDK's own defaults and the change is a no-op for existing users.
|
|
288
|
+
*
|
|
289
|
+
* When one IS set, the fragment carries:
|
|
290
|
+
*
|
|
291
|
+
* - `requestHandler` — routes the client's own wire calls through the proxy.
|
|
292
|
+
* The SDK's internal STS hops (`role_arn` profiles, web identity) inherit
|
|
293
|
+
* it via `parentClientConfig`.
|
|
294
|
+
* - `credentials` — the SDK's default provider chain with the handler ALSO
|
|
295
|
+
* threaded into `clientConfig`, because the SSO portal / SSOOIDC clients
|
|
296
|
+
* the chain constructs do NOT inherit the service client's handler (they
|
|
297
|
+
* coalesce only `logger` / `region` / `userAgentAppId` from it). The
|
|
298
|
+
* `clientConfig` carries NOTHING but `requestHandler` — a `region` there
|
|
299
|
+
* would override the SSO portal region. The chain gets its OWN handler
|
|
300
|
+
* instance so a service client's `destroy()` cannot strand it. IMDS and
|
|
301
|
+
* ECS container credentials call `node:http` directly and correctly
|
|
302
|
+
* bypass the proxy (link-local traffic).
|
|
303
|
+
*
|
|
304
|
+
* Sites that resolve their own explicit `credentials` spread this fragment
|
|
305
|
+
* FIRST and their credentials after, so the override wins while the
|
|
306
|
+
* `requestHandler` stays.
|
|
307
|
+
*
|
|
308
|
+
* Host-side use case: a host CLI (e.g. cdkd) constructing its own AWS SDK
|
|
309
|
+
* clients alongside cdk-local's spreads the same fragment so both honor the
|
|
310
|
+
* same proxy environment with the same `NO_PROXY` semantics.
|
|
311
|
+
*/
|
|
312
|
+
function buildProxyClientConfig(opts = {}) {
|
|
313
|
+
if (!isProxyEnvConfigured()) return {};
|
|
314
|
+
const profile = opts.profile;
|
|
315
|
+
const chainHandler = buildProxyRequestHandler();
|
|
316
|
+
let chain;
|
|
317
|
+
const credentials = async (identityProperties) => {
|
|
318
|
+
if (!chain) {
|
|
319
|
+
const { defaultProvider } = await import("@aws-sdk/credential-provider-node");
|
|
320
|
+
chain = defaultProvider({
|
|
321
|
+
...profile ? { profile } : {},
|
|
322
|
+
clientConfig: { requestHandler: chainHandler }
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
return chain(identityProperties);
|
|
326
|
+
};
|
|
327
|
+
return {
|
|
328
|
+
requestHandler: buildProxyRequestHandler(),
|
|
329
|
+
credentials
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
//#endregion
|
|
45
334
|
//#region src/utils/profile-resolver.ts
|
|
46
335
|
/**
|
|
47
336
|
* Resolve `--profile <p>` to a concrete credential set AND the profile's
|
|
@@ -65,7 +354,7 @@ import { EventEmitter } from "node:events";
|
|
|
65
354
|
* `resolveContainerFallbackRegion`.
|
|
66
355
|
*/
|
|
67
356
|
async function resolveProfileCredentials(profile) {
|
|
68
|
-
const sts = new STSClient({ profile });
|
|
357
|
+
const sts = new STSClient(buildStsClientConfig({ profile }));
|
|
69
358
|
try {
|
|
70
359
|
const credsProvider = sts.config.credentials;
|
|
71
360
|
const creds = typeof credsProvider === "function" ? await credsProvider() : credsProvider;
|
|
@@ -102,9 +391,14 @@ async function resolveProfileCredentials(profile) {
|
|
|
102
391
|
* Returns a fresh object each call so callers can spread additional
|
|
103
392
|
* fields (custom `requestHandler`, `maxAttempts`, etc.) without
|
|
104
393
|
* mutating a shared default.
|
|
394
|
+
*
|
|
395
|
+
* Also spreads {@link buildProxyClientConfig} (issue #634), so every STS
|
|
396
|
+
* site through this helper honors `HTTPS_PROXY` / `NO_PROXY` for free —
|
|
397
|
+
* a no-op (empty fragment) when no proxy environment variable is set.
|
|
105
398
|
*/
|
|
106
399
|
function buildStsClientConfig(args) {
|
|
107
400
|
return {
|
|
401
|
+
...buildProxyClientConfig({ profile: args.profile }),
|
|
108
402
|
...args.region && { region: args.region },
|
|
109
403
|
...args.profile && { profile: args.profile }
|
|
110
404
|
};
|
|
@@ -2804,22 +3098,40 @@ async function getClient(service, region) {
|
|
|
2804
3098
|
let client;
|
|
2805
3099
|
switch (service) {
|
|
2806
3100
|
case "sqs":
|
|
2807
|
-
client = new (await (import("@aws-sdk/client-sqs"))).SQSClient({
|
|
3101
|
+
client = new (await (import("@aws-sdk/client-sqs"))).SQSClient({
|
|
3102
|
+
...buildProxyClientConfig(),
|
|
3103
|
+
region
|
|
3104
|
+
});
|
|
2808
3105
|
break;
|
|
2809
3106
|
case "sns":
|
|
2810
|
-
client = new (await (import("@aws-sdk/client-sns"))).SNSClient({
|
|
3107
|
+
client = new (await (import("@aws-sdk/client-sns"))).SNSClient({
|
|
3108
|
+
...buildProxyClientConfig(),
|
|
3109
|
+
region
|
|
3110
|
+
});
|
|
2811
3111
|
break;
|
|
2812
3112
|
case "eventbridge":
|
|
2813
|
-
client = new (await (import("@aws-sdk/client-eventbridge"))).EventBridgeClient({
|
|
3113
|
+
client = new (await (import("@aws-sdk/client-eventbridge"))).EventBridgeClient({
|
|
3114
|
+
...buildProxyClientConfig(),
|
|
3115
|
+
region
|
|
3116
|
+
});
|
|
2814
3117
|
break;
|
|
2815
3118
|
case "kinesis":
|
|
2816
|
-
client = new (await (import("@aws-sdk/client-kinesis"))).KinesisClient({
|
|
3119
|
+
client = new (await (import("@aws-sdk/client-kinesis"))).KinesisClient({
|
|
3120
|
+
...buildProxyClientConfig(),
|
|
3121
|
+
region
|
|
3122
|
+
});
|
|
2817
3123
|
break;
|
|
2818
3124
|
case "sfn":
|
|
2819
|
-
client = new (await (import("@aws-sdk/client-sfn"))).SFNClient({
|
|
3125
|
+
client = new (await (import("@aws-sdk/client-sfn"))).SFNClient({
|
|
3126
|
+
...buildProxyClientConfig(),
|
|
3127
|
+
region
|
|
3128
|
+
});
|
|
2820
3129
|
break;
|
|
2821
3130
|
case "ssm":
|
|
2822
|
-
client = new (await (import("@aws-sdk/client-ssm"))).SSMClient({
|
|
3131
|
+
client = new (await (import("@aws-sdk/client-ssm"))).SSMClient({
|
|
3132
|
+
...buildProxyClientConfig(),
|
|
3133
|
+
region
|
|
3134
|
+
});
|
|
2823
3135
|
break;
|
|
2824
3136
|
default: throw new Error(`unknown service '${service}'`);
|
|
2825
3137
|
}
|
|
@@ -5152,6 +5464,7 @@ var CfnLocalStateProvider = class {
|
|
|
5152
5464
|
getClient() {
|
|
5153
5465
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
5154
5466
|
if (!this.client) this.client = new CloudFormationClient({
|
|
5467
|
+
...buildProxyClientConfig({ profile: this.clientOptions.profile }),
|
|
5155
5468
|
region: this.region,
|
|
5156
5469
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
5157
5470
|
});
|
|
@@ -5160,6 +5473,7 @@ var CfnLocalStateProvider = class {
|
|
|
5160
5473
|
getLambdaClient() {
|
|
5161
5474
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
5162
5475
|
if (!this.lambdaClient) this.lambdaClient = new LambdaClient({
|
|
5476
|
+
...buildProxyClientConfig({ profile: this.clientOptions.profile }),
|
|
5163
5477
|
region: this.region,
|
|
5164
5478
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
5165
5479
|
});
|
|
@@ -5168,6 +5482,7 @@ var CfnLocalStateProvider = class {
|
|
|
5168
5482
|
getAgentCoreControlClient() {
|
|
5169
5483
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
5170
5484
|
if (!this.agentCoreControlClient) this.agentCoreControlClient = new BedrockAgentCoreControlClient({
|
|
5485
|
+
...buildProxyClientConfig({ profile: this.clientOptions.profile }),
|
|
5171
5486
|
region: this.region,
|
|
5172
5487
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
5173
5488
|
});
|
|
@@ -5176,6 +5491,7 @@ var CfnLocalStateProvider = class {
|
|
|
5176
5491
|
getSsmClient() {
|
|
5177
5492
|
if (this.disposed) throw new Error("CfnLocalStateProvider used after dispose()");
|
|
5178
5493
|
if (!this.ssmClient) this.ssmClient = new SSMClient({
|
|
5494
|
+
...buildProxyClientConfig({ profile: this.clientOptions.profile }),
|
|
5179
5495
|
region: this.region,
|
|
5180
5496
|
...this.clientOptions.profile !== void 0 && { profile: this.clientOptions.profile }
|
|
5181
5497
|
});
|
|
@@ -5555,7 +5871,7 @@ function formatAwsErrorForWarn(err, operation) {
|
|
|
5555
5871
|
*/
|
|
5556
5872
|
async function resolveProfileRegion(profile) {
|
|
5557
5873
|
if (profile === void 0 || profile === "") return void 0;
|
|
5558
|
-
const sts = new STSClient({ profile });
|
|
5874
|
+
const sts = new STSClient(buildStsClientConfig({ profile }));
|
|
5559
5875
|
try {
|
|
5560
5876
|
const regionProvider = sts.config.region;
|
|
5561
5877
|
const resolved = typeof regionProvider === "function" ? await regionProvider() : regionProvider;
|
|
@@ -7878,6 +8194,7 @@ async function pullEcrImage(imageUri, options) {
|
|
|
7878
8194
|
} else if (crossAccount) logger.info(`Cross-account ECR pull: image account ${parsed.accountId} != caller ${callerAccount}. Using the caller's credentials; pass --ecr-role-arn <arn> if AWS rejects with AccessDenied.`);
|
|
7879
8195
|
if (crossRegion) logger.info(`Cross-region ECR pull: image region ${parsed.region} != caller ${callerRegion ?? "(unset)"}. Authenticating against the image region directly.`);
|
|
7880
8196
|
const ecr = new ECRClient({
|
|
8197
|
+
...buildProxyClientConfig({ profile: options.profile }),
|
|
7881
8198
|
region: parsed.region,
|
|
7882
8199
|
...assumed ? { credentials: assumed } : options.profile ? { profile: options.profile } : {}
|
|
7883
8200
|
});
|
|
@@ -8332,7 +8649,7 @@ async function ensureDockerAvailable() {
|
|
|
8332
8649
|
*/
|
|
8333
8650
|
function pickFreePort() {
|
|
8334
8651
|
return new Promise((resolvePort, rejectPort) => {
|
|
8335
|
-
const server = createServer();
|
|
8652
|
+
const server = createServer$2();
|
|
8336
8653
|
server.unref();
|
|
8337
8654
|
server.on("error", rejectPort);
|
|
8338
8655
|
server.listen(0, "127.0.0.1", () => {
|
|
@@ -8557,136 +8874,6 @@ function extractHashFromImageUri(imageUri) {
|
|
|
8557
8874
|
return /:([a-f0-9]{8,})$/.exec(imageUri)?.[1];
|
|
8558
8875
|
}
|
|
8559
8876
|
|
|
8560
|
-
//#endregion
|
|
8561
|
-
//#region src/utils/url-authority.ts
|
|
8562
|
-
/**
|
|
8563
|
-
* Compose the authority component of a URL from a host and a port.
|
|
8564
|
-
*
|
|
8565
|
-
* Every local serve prints an endpoint banner, and several of those banners
|
|
8566
|
-
* are MACHINE-PARSED — `cdkl studio` reads them to learn where to point its
|
|
8567
|
-
* capture proxy (`local/studio-serve-manager`'s `readyRe` /
|
|
8568
|
-
* `parsePublishedHostEndpoint`), then resolves the result with `new URL(...)`
|
|
8569
|
-
* before it will forward anything there. So an authority that the WHATWG
|
|
8570
|
-
* parser rejects is not a cosmetic log defect: the serve is refused.
|
|
8571
|
-
*
|
|
8572
|
-
* The one shape that used to be composed wrong is an IPv6 literal. RFC 3986
|
|
8573
|
-
* 3.2.2 requires it to be bracketed inside an authority, so a bare
|
|
8574
|
-
* `${host}:${port}` turns `--container-host ::` into `http://:::8080`, which
|
|
8575
|
-
* is not a URL — while the IPv4 wildcard `0.0.0.0`, the same intention spelled
|
|
8576
|
-
* differently, works. Issue go-to-k/cdk-local#599.
|
|
8577
|
-
*
|
|
8578
|
-
* The detection is mechanical rather than a list of known values: a colon is
|
|
8579
|
-
* forbidden in both a registered name and an IPv4 address, so a host carrying
|
|
8580
|
-
* one is an IPv6 literal — PROVIDED the rest of it could be one, which is a
|
|
8581
|
-
* character-class test (hex digits, `:`, and `.` for the IPv4-mapped form)
|
|
8582
|
-
* rather than an enumeration. The qualifier is load-bearing rather than
|
|
8583
|
-
* pedantry: `buildRedirectLocation` fills its host from an ALB `#{host}`
|
|
8584
|
-
* template or a configured literal, so a CRLF-injection attempt reaches this
|
|
8585
|
-
* function AS-IS — `example.test\r\nx-injected: yes`, with the CR/LF still in
|
|
8586
|
-
* it, because `front-door-server` sanitises the Location only AFTER building
|
|
8587
|
-
* it. Either way it is a colon in something that is not an address and must
|
|
8588
|
-
* pass through untouched rather than gain brackets it never had. (CR and LF
|
|
8589
|
-
* are outside the character class by construction, so the raw and flattened
|
|
8590
|
-
* spellings classify identically — but the raw one is what actually arrives.)
|
|
8591
|
-
* Caught by `front-door-server.test.ts`'s raw-socket injection case.
|
|
8592
|
-
*/
|
|
8593
|
-
/**
|
|
8594
|
-
* A host that could be an IPv6 literal: hex digits, `:` separators, and `.`
|
|
8595
|
-
* for the IPv4-mapped form (`::ffff:127.0.0.1`). Deliberately NOT a full
|
|
8596
|
-
* grammar — the job is to separate "an address" from "not an address", and
|
|
8597
|
-
* validating an address that has already been bound to is not this function's
|
|
8598
|
-
* business.
|
|
8599
|
-
*/
|
|
8600
|
-
const IPV6_LITERAL_CHARS = /^[0-9A-Fa-f:.]+$/;
|
|
8601
|
-
/**
|
|
8602
|
-
* Render `host` as it must appear inside a URL authority.
|
|
8603
|
-
*
|
|
8604
|
-
* - An IPv6 literal is bracketed, in either case (`FE80::1` -> `[FE80::1]`).
|
|
8605
|
-
* - An already-bracketed literal comes back bracketed exactly once, so the
|
|
8606
|
-
* function is idempotent: `[::1]` never becomes `[[::1]]`. That matters
|
|
8607
|
-
* because a caller often feeds back a `URL.hostname`, which is ALREADY
|
|
8608
|
-
* bracketed.
|
|
8609
|
-
* - A zone id (`fe80::1%en0`) is DROPPED, keeping `[fe80::1]`. No URL parser
|
|
8610
|
-
* accepts one — Node's `new URL` throws on both the raw `%en0` and the
|
|
8611
|
-
* percent-encoded `%25en0` — and a zone id is a host-local interface
|
|
8612
|
-
* selector that carries no meaning for whoever reads the banner. Emitting
|
|
8613
|
-
* an authority nothing can parse is the exact failure this helper exists to
|
|
8614
|
-
* prevent, so the scope is dropped rather than propagated. The brackets are
|
|
8615
|
-
* removed BEFORE that decision, so `[fe80::1%en0]` is stripped too — an
|
|
8616
|
-
* early return on "already bracketed" would have waved the one input that
|
|
8617
|
-
* is both bracketed and unparseable straight through.
|
|
8618
|
-
* - Everything else (IPv4 literal, registered name, the empty string, and a
|
|
8619
|
-
* colon-bearing string that is not an address) is returned untouched.
|
|
8620
|
-
*/
|
|
8621
|
-
function formatHostForAuthority(host) {
|
|
8622
|
-
const inner = host.length > 1 && host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
|
|
8623
|
-
if (!inner.includes(":")) return host;
|
|
8624
|
-
const zoneAt = inner.indexOf("%");
|
|
8625
|
-
const literal = zoneAt === -1 ? inner : inner.slice(0, zoneAt);
|
|
8626
|
-
if (!IPV6_LITERAL_CHARS.test(literal)) return host;
|
|
8627
|
-
return `[${literal}]`;
|
|
8628
|
-
}
|
|
8629
|
-
/**
|
|
8630
|
-
* Compose `<host>:<port>` for use inside a URL, bracketing an IPv6 literal.
|
|
8631
|
-
*
|
|
8632
|
-
* An empty `host` is passed through as-is rather than substituted: the helper
|
|
8633
|
-
* composes an authority, it does not invent a host, and a caller that has no
|
|
8634
|
-
* host has a bug of its own. The result (`:8080`) does not parse, which is the
|
|
8635
|
-
* honest rendering of that state.
|
|
8636
|
-
*/
|
|
8637
|
-
function formatAuthority(host, port) {
|
|
8638
|
-
return `${formatHostForAuthority(host)}:${port}`;
|
|
8639
|
-
}
|
|
8640
|
-
/**
|
|
8641
|
-
* Read the HOST out of an authority (`<host>` or `<host>:<port>`), returning
|
|
8642
|
-
* it BARE — an IPv6 literal comes back without its brackets, ready to be
|
|
8643
|
-
* handed straight back to {@link formatAuthority}.
|
|
8644
|
-
*
|
|
8645
|
-
* The inverse of {@link formatAuthority}, and it exists for the same reason:
|
|
8646
|
-
* `authority.split(':')[0]` is the obvious thing to write and it is wrong for
|
|
8647
|
-
* exactly one input. A conforming client sends `Host: [::1]:8080` (measured —
|
|
8648
|
-
* see `tests/unit/local/ipv6-host-header.test.ts`), and splitting that on the
|
|
8649
|
-
* first colon yields `'['`, so an ALB `#{host}` substitution built from it
|
|
8650
|
-
* produced `http://[:8080/...`. Issue go-to-k/cdk-local#599.
|
|
8651
|
-
*
|
|
8652
|
-
* # It refuses rather than guesses — on BOTH arms
|
|
8653
|
-
*
|
|
8654
|
-
* This is an attacker-reachable parser: the request `Host` header feeds an
|
|
8655
|
-
* ALB `#{host}` substitution, and whatever comes back is composed into a
|
|
8656
|
-
* redirect `Location`. So a malformed authority yields the empty string
|
|
8657
|
-
* rather than the fragment that happens to be readable, on either branch.
|
|
8658
|
-
*
|
|
8659
|
-
* BRACKETED — read to the closing `]`, and only when the value is
|
|
8660
|
-
* well-formed: there must BE a closing bracket, and what follows it must be
|
|
8661
|
-
* empty or `:<digits>`. Guessing here is the worse of the two directions,
|
|
8662
|
-
* because the guess PARSES: `[evil.example` (no closing bracket) would come
|
|
8663
|
-
* back as `evil.example`, turning a half-named host into a valid `Location`
|
|
8664
|
-
* the client would follow, where the malformed input should have produced
|
|
8665
|
-
* nothing. `[a:b]junk` would silently drop its trailing junk, and `[x:y`
|
|
8666
|
-
* would return a multi-colon value as a host — the very thing the other arm
|
|
8667
|
-
* refuses.
|
|
8668
|
-
*
|
|
8669
|
-
* UNBRACKETED — the text before its single `:`. Two or more colons yields
|
|
8670
|
-
* the empty string: it is not a shape any conforming client sends (Node
|
|
8671
|
-
* brackets — measured in `tests/unit/local/ipv6-host-header.test.ts`), it has
|
|
8672
|
-
* no unambiguous split, and returning the leading fragment would hand a
|
|
8673
|
-
* caller a host that is not the one named. `split(':')[0]` did exactly that —
|
|
8674
|
-
* `fe80::1:8080` came back as `'fe80'`.
|
|
8675
|
-
*/
|
|
8676
|
-
function hostFromAuthority(authority) {
|
|
8677
|
-
if (authority.startsWith("[")) {
|
|
8678
|
-
const close = authority.indexOf("]");
|
|
8679
|
-
if (close === -1) return "";
|
|
8680
|
-
const afterBracket = authority.slice(close + 1);
|
|
8681
|
-
if (afterBracket !== "" && !/^:\d+$/.test(afterBracket)) return "";
|
|
8682
|
-
return authority.slice(1, close);
|
|
8683
|
-
}
|
|
8684
|
-
const firstColon = authority.indexOf(":");
|
|
8685
|
-
if (firstColon === -1) return authority;
|
|
8686
|
-
if (authority.includes(":", firstColon + 1)) return "";
|
|
8687
|
-
return authority.slice(0, firstColon);
|
|
8688
|
-
}
|
|
8689
|
-
|
|
8690
8877
|
//#endregion
|
|
8691
8878
|
//#region src/local/rie-client.ts
|
|
8692
8879
|
/**
|
|
@@ -14371,7 +14558,7 @@ function defaultCredentialsLoader() {
|
|
|
14371
14558
|
if (cached) return cached;
|
|
14372
14559
|
cached = (async () => {
|
|
14373
14560
|
const { STSClient } = await import("@aws-sdk/client-sts");
|
|
14374
|
-
const client = new STSClient({});
|
|
14561
|
+
const client = new STSClient({ ...buildProxyClientConfig() });
|
|
14375
14562
|
const creds = await client.config.credentials();
|
|
14376
14563
|
client.destroy();
|
|
14377
14564
|
return {
|
|
@@ -15140,13 +15327,13 @@ async function startApiServer(opts) {
|
|
|
15140
15327
|
if (!res.headersSent) writeError$1(res, 502);
|
|
15141
15328
|
});
|
|
15142
15329
|
};
|
|
15143
|
-
const server = opts.mtls ? createServer$
|
|
15330
|
+
const server = opts.mtls ? createServer$1({
|
|
15144
15331
|
requestCert: true,
|
|
15145
15332
|
rejectUnauthorized: true,
|
|
15146
15333
|
ca: opts.mtls.caPem,
|
|
15147
15334
|
cert: opts.mtls.certPem,
|
|
15148
15335
|
key: opts.mtls.keyPem
|
|
15149
|
-
}, requestHandler) : createServer
|
|
15336
|
+
}, requestHandler) : createServer(requestHandler);
|
|
15150
15337
|
const scheme = opts.mtls ? "https" : "http";
|
|
15151
15338
|
server.on("connection", (socket) => {
|
|
15152
15339
|
socket.setNoDelay(true);
|
|
@@ -16507,6 +16694,7 @@ async function assumeRoleForLayer(roleArn, region, options) {
|
|
|
16507
16694
|
async function defaultLambdaClientFactory() {
|
|
16508
16695
|
const { LambdaClient } = await import("@aws-sdk/client-lambda");
|
|
16509
16696
|
return (region, credentials) => new LambdaClient({
|
|
16697
|
+
...buildProxyClientConfig(),
|
|
16510
16698
|
region,
|
|
16511
16699
|
...credentials && { credentials: {
|
|
16512
16700
|
accessKeyId: credentials.accessKeyId,
|
|
@@ -16517,7 +16705,10 @@ async function defaultLambdaClientFactory() {
|
|
|
16517
16705
|
}
|
|
16518
16706
|
async function defaultStsClientFactory() {
|
|
16519
16707
|
const { STSClient } = await import("@aws-sdk/client-sts");
|
|
16520
|
-
return (region) => new STSClient({
|
|
16708
|
+
return (region) => new STSClient({
|
|
16709
|
+
...buildProxyClientConfig(),
|
|
16710
|
+
region
|
|
16711
|
+
});
|
|
16521
16712
|
}
|
|
16522
16713
|
async function buildGetLayerVersionCommand(layerArn, versionNumber) {
|
|
16523
16714
|
const { GetLayerVersionCommand } = await import("@aws-sdk/client-lambda");
|
|
@@ -19889,6 +20080,7 @@ function defaultFetchObject$1(options) {
|
|
|
19889
20080
|
return async (location) => {
|
|
19890
20081
|
const { S3Client, GetObjectCommand } = await import("@aws-sdk/client-s3");
|
|
19891
20082
|
const client = new S3Client({
|
|
20083
|
+
...buildProxyClientConfig({ profile: options.profile }),
|
|
19892
20084
|
...options.region && { region: options.region },
|
|
19893
20085
|
...options.profile && !options.credentials && { profile: options.profile },
|
|
19894
20086
|
...options.credentials && { credentials: {
|
|
@@ -22429,10 +22621,12 @@ async function resolveEcsSecrets(entries, options = {}) {
|
|
|
22429
22621
|
if (entries.length === 0) return [];
|
|
22430
22622
|
const logger = getLogger().child("ecs-secrets");
|
|
22431
22623
|
const secretsClient = options.secretsManagerClient ?? new SecretsManagerClient({
|
|
22624
|
+
...buildProxyClientConfig({ profile: options.profile }),
|
|
22432
22625
|
...options.region && { region: options.region },
|
|
22433
22626
|
...options.profile && { profile: options.profile }
|
|
22434
22627
|
});
|
|
22435
22628
|
const ssmClient = options.ssmClient ?? new SSMClient({
|
|
22629
|
+
...buildProxyClientConfig({ profile: options.profile }),
|
|
22436
22630
|
...options.region && { region: options.region },
|
|
22437
22631
|
...options.profile && { profile: options.profile }
|
|
22438
22632
|
});
|
|
@@ -25256,10 +25450,10 @@ async function startFrontDoorServer(opts) {
|
|
|
25256
25450
|
if (!res.headersSent) writeError(res, 502, "Bad Gateway");
|
|
25257
25451
|
});
|
|
25258
25452
|
};
|
|
25259
|
-
const server = opts.tls ? createServer$
|
|
25453
|
+
const server = opts.tls ? createServer$1({
|
|
25260
25454
|
cert: opts.tls.certPem,
|
|
25261
25455
|
key: opts.tls.keyPem
|
|
25262
|
-
}, requestHandler) : createServer
|
|
25456
|
+
}, requestHandler) : createServer(requestHandler);
|
|
25263
25457
|
const scheme = opts.tls ? "https" : "http";
|
|
25264
25458
|
server.on("connection", (socket) => socket.setNoDelay(true));
|
|
25265
25459
|
server.on("upgrade", (req, clientSocket, head) => {
|
|
@@ -31367,10 +31561,10 @@ async function startCloudFrontServer(options) {
|
|
|
31367
31561
|
});
|
|
31368
31562
|
};
|
|
31369
31563
|
const scheme = options.tls ? "https" : "http";
|
|
31370
|
-
const server = options.tls ? createServer$
|
|
31564
|
+
const server = options.tls ? createServer$1({
|
|
31371
31565
|
cert: options.tls.certPem,
|
|
31372
31566
|
key: options.tls.keyPem
|
|
31373
|
-
}, handler) : createServer
|
|
31567
|
+
}, handler) : createServer(handler);
|
|
31374
31568
|
const port = await listen(server, options.host, options.port);
|
|
31375
31569
|
return {
|
|
31376
31570
|
url: `${scheme}://${formatAuthority(options.host, port)}`,
|
|
@@ -31808,6 +32002,7 @@ function defaultFetchObject(bucketName, options) {
|
|
|
31808
32002
|
const { S3Client, GetObjectCommand } = await import("@aws-sdk/client-s3");
|
|
31809
32003
|
return {
|
|
31810
32004
|
client: new S3Client({
|
|
32005
|
+
...buildProxyClientConfig(),
|
|
31811
32006
|
...options.region && { region: options.region },
|
|
31812
32007
|
...options.credentials && { credentials: {
|
|
31813
32008
|
accessKeyId: options.credentials.accessKeyId,
|
|
@@ -31897,6 +32092,7 @@ async function resolveDeployedOriginBucket(options) {
|
|
|
31897
32092
|
async function defaultGetOrigins(options) {
|
|
31898
32093
|
const { CloudFrontClient, GetDistributionConfigCommand } = await import("@aws-sdk/client-cloudfront");
|
|
31899
32094
|
const client = new CloudFrontClient({
|
|
32095
|
+
...buildProxyClientConfig(),
|
|
31900
32096
|
region: "us-east-1",
|
|
31901
32097
|
...options.credentials && { credentials: {
|
|
31902
32098
|
accessKeyId: options.credentials.accessKeyId,
|
|
@@ -31921,6 +32117,7 @@ async function defaultGetOrigins(options) {
|
|
|
31921
32117
|
*/
|
|
31922
32118
|
function createDeployedKvsDataSource(options) {
|
|
31923
32119
|
const client = new CloudFrontKeyValueStoreClient({
|
|
32120
|
+
...buildProxyClientConfig(),
|
|
31924
32121
|
region: options.region ?? "us-east-1",
|
|
31925
32122
|
...options.credentials !== void 0 && { credentials: options.credentials }
|
|
31926
32123
|
});
|
|
@@ -31953,6 +32150,7 @@ function createDeployedKvsDataSource(options) {
|
|
|
31953
32150
|
*/
|
|
31954
32151
|
async function resolveDeployedKvsArnByName(name, options = {}) {
|
|
31955
32152
|
const client = new CloudFrontClient({
|
|
32153
|
+
...buildProxyClientConfig(),
|
|
31956
32154
|
region: options.region ?? "us-east-1",
|
|
31957
32155
|
...options.credentials !== void 0 && { credentials: options.credentials }
|
|
31958
32156
|
});
|
|
@@ -32650,7 +32848,7 @@ function attachAgentCoreWsBridge(httpServer, config) {
|
|
|
32650
32848
|
*/
|
|
32651
32849
|
function startAgentCoreWsBridge(config) {
|
|
32652
32850
|
const host = config.host ?? "127.0.0.1";
|
|
32653
|
-
const httpServer = createServer
|
|
32851
|
+
const httpServer = createServer((_req, res) => {
|
|
32654
32852
|
res.writeHead(426, { "Content-Type": "text/plain" });
|
|
32655
32853
|
res.end("Upgrade required: connect over WebSocket.\n");
|
|
32656
32854
|
});
|
|
@@ -32788,7 +32986,7 @@ function startAgentCoreHttpServer(config) {
|
|
|
32788
32986
|
const routes = config.routes ?? DEFAULT_ROUTES;
|
|
32789
32987
|
const attachWs = config.attachWs ?? true;
|
|
32790
32988
|
const notFoundHint = buildNotFoundHint(routes, attachWs);
|
|
32791
|
-
const httpServer = createServer
|
|
32989
|
+
const httpServer = createServer((req, res) => {
|
|
32792
32990
|
const path = (req.url ?? "/").split("?")[0];
|
|
32793
32991
|
const match = routes.find((r) => r.method === req.method && r.path === path);
|
|
32794
32992
|
if (!match) {
|
|
@@ -37031,7 +37229,7 @@ async function startStudioServer(options) {
|
|
|
37031
37229
|
groups: options.targetGroups,
|
|
37032
37230
|
dockerfiles: options.dockerfiles ?? []
|
|
37033
37231
|
});
|
|
37034
|
-
const server = createServer
|
|
37232
|
+
const server = createServer((req, res) => handleRequest(req, res, options.bus, html, () => targetsJson, options, instanceId));
|
|
37035
37233
|
const boundPort = await listenWithBump(server, host, options.port, maxBump);
|
|
37036
37234
|
return {
|
|
37037
37235
|
url: `http://${formatAuthority(host, boundPort)}`,
|
|
@@ -37963,7 +38161,7 @@ function startStudioProxy(config) {
|
|
|
37963
38161
|
const upstreamUrl = new URL(resolvedUpstream);
|
|
37964
38162
|
const upstreamHost = stripHostBrackets(upstreamUrl.hostname);
|
|
37965
38163
|
const upstreamPort = Number(upstreamUrl.port) || 80;
|
|
37966
|
-
const server = createServer
|
|
38164
|
+
const server = createServer((clientReq, clientRes) => {
|
|
37967
38165
|
const id = idFactory();
|
|
37968
38166
|
const startedAt = clock();
|
|
37969
38167
|
const path = clientReq.url ?? "/";
|
|
@@ -39627,5 +39825,5 @@ function addStudioSpecificOptions(cmd) {
|
|
|
39627
39825
|
}
|
|
39628
39826
|
|
|
39629
39827
|
//#endregion
|
|
39630
|
-
export { applyEdgeResponseResult as $, buildJwksUrlFromIssuer as $n, resolveCfnStackName as $r, buildCloudMapIndex as $t, startAgentCoreHttpServer as A, describeCredentialLoadFailure as Ai, classifySourceChange as An, ConnectionRegistry as Ar, addRunTaskSpecificOptions as At, idFromArn as B, buildStageMap as Bn, resolveRuntimeFileExtension as Br, resolveEcsAssumeRoleOption as Bt, addListSpecificOptions as C, resolveAgentCoreTarget as Ci, waitForAgentCorePing as Cn, tryParseStatus as Cr, parseLbPortOverrides as Ct, createLocalStartAgentCoreCommand as D, tryResolveImageFnJoin as Di, computeCodeImageTag as Dn, probeHostGatewaySupport as Dr, addStartServiceSpecificOptions as Dt, addStartAgentCoreSpecificOptions as E, substituteImagePlaceholders as Ei, buildAgentCoreCodeImage as En, HOST_GATEWAY_MIN_VERSION as Er, resolveAlbFrontDoor as Et, createLocalStartCloudFrontCommand as F, createWatchPredicates as Fn, buildDisconnectEvent as Fr, addImageOverrideOptions as Ft, classifyS3Error as G, filterRoutesByApiIdentifiers as Gn, substituteEnvVarsFromState as Gr, enforceImageOverrideOrphans as Gt, createDeployedKvsDataSource as H, resolveEnvVars$1 as Hn, EcsTaskResolutionError as Hr, runEcsServiceEmulator as Ht, normalizeKvsFileKeys as I, resolveApiTargetSubset as In, buildMessageEvent as Ir, buildEcsImageResolutionContext$1 as It, startCloudFrontServer as J, startApiServer as Jn, createLocalStateProvider as Jr, resolveImageOverrides as Jt, createS3OriginReader as K, groupRoutesByServer as Kn, substituteEnvVarsFromStateAsync as Kr, mergeForService as Kt, parseKvsFileOverrides as L, createAuthorizerCache as Ln, architectureToPlatform as Lr, ecsClusterOption as Lt, startAgentCoreWsBridge as M, resolveProfileCredentials as Mi, createLocalInvokeCommand as Mn, handleConnectionsRequest as Mr, MAX_TASKS_SUBNET_RANGE_CAP as Mt, LocalStartCloudFrontError as N, addStartApiSpecificOptions as Nn, parseConnectionsPath as Nr, addCommonEcsServiceOptions as Nt, buildAgentCoreServeAuthCheck as O, LocalInvokeBuildError as Oi, renderCodeDockerfile as On, resolveHostGatewayExtraHosts as Or, createLocalStartServiceCommand as Ot, addStartCloudFrontSpecificOptions as P, createLocalStartApiCommand as Pn, buildConnectEvent as Pr, addEcsAssumeRoleOptions as Pt, applyEdgeRequestResult as Q, buildCognitoJwksUrl as Qn, resolveCfnRegion as Qr, listPinnedTargets as Qt, parseOriginOverrides as R, createFileWatcher as Rn, buildContainerImage as Rr, parseMaxTasks as Rt, StudioEventBus as S, pickAgentCoreCandidateStack as Si, waitForAgentCoreHttpReady as Sn, selectIntegrationResponse as Sr, createLocalStartAlbCommand as St, formatTargetListing as T, formatStateRemedy as Ti, SUPPORTED_CODE_RUNTIMES as Tn, HOST_DOCKER_INTERNAL_GATEWAY as Tr, isApplicationLoadBalancer as Tt, resolveDeployedKvsArnByName as U, availableApiIdentifiers as Un, substituteAgainstState as Ur, ImageOverrideError as Ut, resolveKvsModulesForDistribution as V, materializeLayerFromArn as Vn, resolveRuntimeImage as Vr, resolveSharedSidecarCredentials as Vt, resolveDeployedOriginBucket as W, filterRoutesByApiIdentifier as Wn, substituteAgainstStateAsync as Wr, buildImageOverrideTag as Wt, serveFromStaticOrigin as X, resolveServiceIntegrationParameters as Xn, rejectExplicitCfnStackWithMultipleStacks as Xr, describePinnedImageUri as Xt, resolveErrorResponseCandidates as Y, resolveSelectionExpression as Yn, isCfnFlagPresent as Yr, runImageOverrideBuilds as Yt, serveLambdaUrlOrigin as Z, defaultCredentialsLoader as Zn, resolveCfnFallbackRegion as Zr, isLocalCdkAssetImage as Zt, filterStudioTargetGroups as _, AGENTCORE_AGUI_PROTOCOL as _i, parseSseForJsonRpc as _n, applyAuthorizerOverlay as _r, createCloudFrontModule as _t, createLocalStudioCommand as a, countTargets as ai, attachContainerLogStreamer as an, computeRequestIdentityHash as ar, describeS3OriginDomain as at, renderStudioHtml as b, AGENTCORE_RUNTIME_TYPE as bi, AGENTCORE_SESSION_ID_HEADER as bn, evaluateResponseParameters as br, addAlbSpecificOptions as bt, startStudioProxy as c, discoverWebSocketApis as ci, bridgeAgentCoreWs as cn, invokeTokenAuthorizer as cr, pickFunctionUrlLogicalIdFromOrigin as ct, createStudioDispatcher as d, parseSelectionExpressionPath as di, A2A_PATH as dn, buildCorsConfigByApiId as dr, pickTargetFunctionLogicalId as dt, CfnLocalStateProvider as ei, CloudMapRegistry as en, createJwksCache as er, buildEdgeRequestEvent as et, filterStudioCustomResources as f, webSocketApiMatchesIdentifier as fi, a2aInvokeOnce as fn, buildCorsConfigFromCloudFrontChain as fr, resolveCloudFrontDistribution as ft, annotatePinnedEcsTargets as g, AGENTCORE_A2A_PROTOCOL as gi, mcpInvokeOnce as gn, translateLambdaResponse as gr, stripCloudFrontImport as gt, annotateEcsTaskPinnedTargets as h, resolveLambdaArnIntrinsic as hi, MCP_PROTOCOL_VERSION as hn, matchRoute as hr, runViewerResponse as ht, coerceStopRequest as i, resolveSingleTarget as ii, getContainerNetworkIp as in, buildMethodArn as ir, CLOUDFRONT_DISTRIBUTION_TYPE as it, attachAgentCoreWsBridge as j, buildStsClientConfig as ji, addInvokeSpecificOptions as jn, buildMgmtEndpointEnvUrl as jr, createLocalRunTaskCommand as jt, selectServeInboundAuth as k, describeAwsFailureForWarn as ki, toCmdArgv as kn, bufferToBody as kr, serviceStrategy as kt, relayServeRequest as l, discoverWebSocketApisOrThrow as li, invokeAgentCoreWs as ln, attachAuthorizers as lr, pickKvsLogicalIdFromArn as lt, annotateAlbPinnedBackingServices as m, pickRefLogicalId as mi, MCP_PATH as mn, matchPreflight as mr, runViewerRequest as mt, coerceRunRequest as n, resolveSsmParameters as ni, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as nn, verifyJwtAuthorizer as nr, edgeHeadersToHttp as nt, resolveServeBaseUrl as o, listTargets as oi, addInvokeAgentCoreSpecificOptions as on, evaluateCachedLambdaPolicy as or, extractKvsAssociations as ot, isCustomResourceLambdaTarget as p, discoverRoutes as pi, MCP_CONTAINER_PORT as pn, isFunctionUrlOacFronted as pr, compileCloudFrontFunction as pt, matchBehavior as q, readMtlsMaterialsFromDisk as qn, LocalStateSourceError as qr, parseImageOverrideFlags as qt, coerceServeRequest as r, resolveWatchConfig as ri, setShadowReadyTimeoutMs as rn, verifyJwtViaDiscovery as rr, httpHeadersToEdge as rt, createStudioServeManager as s, availableWebSocketApiIdentifiers as si, createLocalInvokeAgentCoreCommand as sn, invokeRequestAuthorizer as sr, isCloudFrontDistribution as st, addStudioSpecificOptions as t, collectSsmParameterRefs as ti, DEFAULT_SHADOW_READY_TIMEOUT_MS as tn, verifyCognitoJwt as tr, buildEdgeResponseEvent as tt, reinvoke as u, filterWebSocketApisByIdentifiers as ui, A2A_CONTAINER_PORT as un, applyCorsResponseHeaders as ur, pickLambdaEdgeFunctionLogicalId as ut, startStudioServer as v, AGENTCORE_HTTP_PROTOCOL as vi, AGENTCORE_SIGV4_SERVICE as vn, buildHttpApiV2Event as vr, createLocalFileKvsDataSource as vt, createLocalListCommand as w, derivePseudoParametersFromRegion as wi, downloadAndExtractS3Bundle as wn, VtlEvaluationError as wr, resolveAlbTarget as wt, createStudioStore as x, AgentCoreResolutionError as xi, invokeAgentCore as xn, pickResponseTemplate as xr, albStrategy as xt, toStudioTargetGroups as y, AGENTCORE_MCP_PROTOCOL as yi, signAgentCoreInvocation as yn, buildRestV1Event as yr, createUnboundCloudFrontModule as yt, resolveCloudFrontTarget as z, attachStageContext as zn, resolveRuntimeCodeMountPath as zr, parseRestartPolicy as zt };
|
|
39631
|
-
//# sourceMappingURL=local-studio-
|
|
39828
|
+
export { applyEdgeResponseResult as $, buildJwksUrlFromIssuer as $n, resolveCfnStackName as $r, buildCloudMapIndex as $t, startAgentCoreHttpServer as A, describeCredentialLoadFailure as Ai, classifySourceChange as An, ConnectionRegistry as Ar, addRunTaskSpecificOptions as At, idFromArn as B, buildStageMap as Bn, resolveRuntimeFileExtension as Br, resolveEcsAssumeRoleOption as Bt, addListSpecificOptions as C, resolveAgentCoreTarget as Ci, waitForAgentCorePing as Cn, tryParseStatus as Cr, parseLbPortOverrides as Ct, createLocalStartAgentCoreCommand as D, tryResolveImageFnJoin as Di, computeCodeImageTag as Dn, probeHostGatewaySupport as Dr, addStartServiceSpecificOptions as Dt, addStartAgentCoreSpecificOptions as E, substituteImagePlaceholders as Ei, buildAgentCoreCodeImage as En, HOST_GATEWAY_MIN_VERSION as Er, resolveAlbFrontDoor as Et, createLocalStartCloudFrontCommand as F, createWatchPredicates as Fn, buildDisconnectEvent as Fr, addImageOverrideOptions as Ft, classifyS3Error as G, filterRoutesByApiIdentifiers as Gn, substituteEnvVarsFromState as Gr, enforceImageOverrideOrphans as Gt, createDeployedKvsDataSource as H, resolveEnvVars$1 as Hn, EcsTaskResolutionError as Hr, runEcsServiceEmulator as Ht, normalizeKvsFileKeys as I, resolveApiTargetSubset as In, buildMessageEvent as Ir, buildEcsImageResolutionContext$1 as It, startCloudFrontServer as J, startApiServer as Jn, createLocalStateProvider as Jr, resolveImageOverrides as Jt, createS3OriginReader as K, groupRoutesByServer as Kn, substituteEnvVarsFromStateAsync as Kr, mergeForService as Kt, parseKvsFileOverrides as L, createAuthorizerCache as Ln, architectureToPlatform as Lr, ecsClusterOption as Lt, startAgentCoreWsBridge as M, resolveProfileCredentials as Mi, createLocalInvokeCommand as Mn, handleConnectionsRequest as Mr, MAX_TASKS_SUBNET_RANGE_CAP as Mt, LocalStartCloudFrontError as N, buildProxyClientConfig as Ni, addStartApiSpecificOptions as Nn, parseConnectionsPath as Nr, addCommonEcsServiceOptions as Nt, buildAgentCoreServeAuthCheck as O, LocalInvokeBuildError as Oi, renderCodeDockerfile as On, resolveHostGatewayExtraHosts as Or, createLocalStartServiceCommand as Ot, addStartCloudFrontSpecificOptions as P, isProxyEnvConfigured as Pi, createLocalStartApiCommand as Pn, buildConnectEvent as Pr, addEcsAssumeRoleOptions as Pt, applyEdgeRequestResult as Q, buildCognitoJwksUrl as Qn, resolveCfnRegion as Qr, listPinnedTargets as Qt, parseOriginOverrides as R, createFileWatcher as Rn, buildContainerImage as Rr, parseMaxTasks as Rt, StudioEventBus as S, pickAgentCoreCandidateStack as Si, waitForAgentCoreHttpReady as Sn, selectIntegrationResponse as Sr, createLocalStartAlbCommand as St, formatTargetListing as T, formatStateRemedy as Ti, SUPPORTED_CODE_RUNTIMES as Tn, HOST_DOCKER_INTERNAL_GATEWAY as Tr, isApplicationLoadBalancer as Tt, resolveDeployedKvsArnByName as U, availableApiIdentifiers as Un, substituteAgainstState as Ur, ImageOverrideError as Ut, resolveKvsModulesForDistribution as V, materializeLayerFromArn as Vn, resolveRuntimeImage as Vr, resolveSharedSidecarCredentials as Vt, resolveDeployedOriginBucket as W, filterRoutesByApiIdentifier as Wn, substituteAgainstStateAsync as Wr, buildImageOverrideTag as Wt, serveFromStaticOrigin as X, resolveServiceIntegrationParameters as Xn, rejectExplicitCfnStackWithMultipleStacks as Xr, describePinnedImageUri as Xt, resolveErrorResponseCandidates as Y, resolveSelectionExpression as Yn, isCfnFlagPresent as Yr, runImageOverrideBuilds as Yt, serveLambdaUrlOrigin as Z, defaultCredentialsLoader as Zn, resolveCfnFallbackRegion as Zr, isLocalCdkAssetImage as Zt, filterStudioTargetGroups as _, AGENTCORE_AGUI_PROTOCOL as _i, parseSseForJsonRpc as _n, applyAuthorizerOverlay as _r, createCloudFrontModule as _t, createLocalStudioCommand as a, countTargets as ai, attachContainerLogStreamer as an, computeRequestIdentityHash as ar, describeS3OriginDomain as at, renderStudioHtml as b, AGENTCORE_RUNTIME_TYPE as bi, AGENTCORE_SESSION_ID_HEADER as bn, evaluateResponseParameters as br, addAlbSpecificOptions as bt, startStudioProxy as c, discoverWebSocketApis as ci, bridgeAgentCoreWs as cn, invokeTokenAuthorizer as cr, pickFunctionUrlLogicalIdFromOrigin as ct, createStudioDispatcher as d, parseSelectionExpressionPath as di, A2A_PATH as dn, buildCorsConfigByApiId as dr, pickTargetFunctionLogicalId as dt, CfnLocalStateProvider as ei, CloudMapRegistry as en, createJwksCache as er, buildEdgeRequestEvent as et, filterStudioCustomResources as f, webSocketApiMatchesIdentifier as fi, a2aInvokeOnce as fn, buildCorsConfigFromCloudFrontChain as fr, resolveCloudFrontDistribution as ft, annotatePinnedEcsTargets as g, AGENTCORE_A2A_PROTOCOL as gi, mcpInvokeOnce as gn, translateLambdaResponse as gr, stripCloudFrontImport as gt, annotateEcsTaskPinnedTargets as h, resolveLambdaArnIntrinsic as hi, MCP_PROTOCOL_VERSION as hn, matchRoute as hr, runViewerResponse as ht, coerceStopRequest as i, resolveSingleTarget as ii, getContainerNetworkIp as in, buildMethodArn as ir, CLOUDFRONT_DISTRIBUTION_TYPE as it, attachAgentCoreWsBridge as j, buildStsClientConfig as ji, addInvokeSpecificOptions as jn, buildMgmtEndpointEnvUrl as jr, createLocalRunTaskCommand as jt, selectServeInboundAuth as k, describeAwsFailureForWarn as ki, toCmdArgv as kn, bufferToBody as kr, serviceStrategy as kt, relayServeRequest as l, discoverWebSocketApisOrThrow as li, invokeAgentCoreWs as ln, attachAuthorizers as lr, pickKvsLogicalIdFromArn as lt, annotateAlbPinnedBackingServices as m, pickRefLogicalId as mi, MCP_PATH as mn, matchPreflight as mr, runViewerRequest as mt, coerceRunRequest as n, resolveSsmParameters as ni, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as nn, verifyJwtAuthorizer as nr, edgeHeadersToHttp as nt, resolveServeBaseUrl as o, listTargets as oi, addInvokeAgentCoreSpecificOptions as on, evaluateCachedLambdaPolicy as or, extractKvsAssociations as ot, isCustomResourceLambdaTarget as p, discoverRoutes as pi, MCP_CONTAINER_PORT as pn, isFunctionUrlOacFronted as pr, compileCloudFrontFunction as pt, matchBehavior as q, readMtlsMaterialsFromDisk as qn, LocalStateSourceError as qr, parseImageOverrideFlags as qt, coerceServeRequest as r, resolveWatchConfig as ri, setShadowReadyTimeoutMs as rn, verifyJwtViaDiscovery as rr, httpHeadersToEdge as rt, createStudioServeManager as s, availableWebSocketApiIdentifiers as si, createLocalInvokeAgentCoreCommand as sn, invokeRequestAuthorizer as sr, isCloudFrontDistribution as st, addStudioSpecificOptions as t, collectSsmParameterRefs as ti, DEFAULT_SHADOW_READY_TIMEOUT_MS as tn, verifyCognitoJwt as tr, buildEdgeResponseEvent as tt, reinvoke as u, filterWebSocketApisByIdentifiers as ui, A2A_CONTAINER_PORT as un, applyCorsResponseHeaders as ur, pickLambdaEdgeFunctionLogicalId as ut, startStudioServer as v, AGENTCORE_HTTP_PROTOCOL as vi, AGENTCORE_SIGV4_SERVICE as vn, buildHttpApiV2Event as vr, createLocalFileKvsDataSource as vt, createLocalListCommand as w, derivePseudoParametersFromRegion as wi, downloadAndExtractS3Bundle as wn, VtlEvaluationError as wr, resolveAlbTarget as wt, createStudioStore as x, AgentCoreResolutionError as xi, invokeAgentCore as xn, pickResponseTemplate as xr, albStrategy as xt, toStudioTargetGroups as y, AGENTCORE_MCP_PROTOCOL as yi, signAgentCoreInvocation as yn, buildRestV1Event as yr, createUnboundCloudFrontModule as yt, resolveCloudFrontTarget as z, attachStageContext as zn, resolveRuntimeCodeMountPath as zr, parseRestartPolicy as zt };
|
|
39829
|
+
//# sourceMappingURL=local-studio-DoyRYZf6.js.map
|