cdk-local 0.106.0 → 0.107.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.
@@ -7847,7 +7847,7 @@ function buildRequestContext(routeKey, eventType, connectionId, connectedAt, sta
7847
7847
  * deployed behavior by checking the response in the caller.
7848
7848
  */
7849
7849
  function buildConnectEvent(opts) {
7850
- const headers = normalizeHeaders(opts.snapshot.headers);
7850
+ const headers = normalizeHeaders$1(opts.snapshot.headers);
7851
7851
  const multiValueHeaders = lowercaseMultiValueHeaders(opts.snapshot.headers);
7852
7852
  return {
7853
7853
  ...headers !== void 0 && { headers },
@@ -7921,7 +7921,7 @@ function formatRequestTime$1(epochMs) {
7921
7921
  /**
7922
7922
  * Lowercase header keys, comma-join duplicates per AWS spec.
7923
7923
  */
7924
- function normalizeHeaders(headers) {
7924
+ function normalizeHeaders$1(headers) {
7925
7925
  const out = {};
7926
7926
  let any = false;
7927
7927
  for (const [name, values] of Object.entries(headers)) {
@@ -8052,7 +8052,7 @@ function safeDecodeURIComponent(s) {
8052
8052
  * forward the buffer through to `WebSocket.send` so binary frames work
8053
8053
  * end to end.
8054
8054
  */
8055
- function readRequestBody(req) {
8055
+ function readRequestBody$1(req) {
8056
8056
  return new Promise((resolve, reject) => {
8057
8057
  const chunks = [];
8058
8058
  req.on("data", (chunk) => {
@@ -8105,7 +8105,7 @@ async function handleConnectionsRequest(opts) {
8105
8105
  if (method === "POST") {
8106
8106
  let body;
8107
8107
  try {
8108
- body = await readRequestBody(req);
8108
+ body = await readRequestBody$1(req);
8109
8109
  } catch (err) {
8110
8110
  writeJson(res, 500, { message: `Failed to read request body: ${err instanceof Error ? err.message : String(err)}` });
8111
8111
  return;
@@ -27142,7 +27142,7 @@ const LISTENER_TYPE = "AWS::ElasticLoadBalancingV2::Listener";
27142
27142
  const LISTENER_RULE_TYPE = "AWS::ElasticLoadBalancingV2::ListenerRule";
27143
27143
  const TARGET_GROUP_TYPE = "AWS::ElasticLoadBalancingV2::TargetGroup";
27144
27144
  const SERVICE_TYPE = "AWS::ECS::Service";
27145
- const LAMBDA_FUNCTION_TYPE = "AWS::Lambda::Function";
27145
+ const LAMBDA_FUNCTION_TYPE$1 = "AWS::Lambda::Function";
27146
27146
  /**
27147
27147
  * Resolve an ALB into its front-door listeners + routing tables. Pure — reads
27148
27148
  * only the supplied stack template. Returns an empty `listeners` array (with
@@ -27305,8 +27305,8 @@ function resolveLambdaForwardTarget(tgProps, tgRef, resources, stackName, label,
27305
27305
  return;
27306
27306
  }
27307
27307
  const lambda = resources[lambdaLogicalId];
27308
- if (!lambda || lambda.Type !== LAMBDA_FUNCTION_TYPE) {
27309
- warnings.push(`${label} forwards to Lambda target group '${tgRef}', whose target resolves to '${lambdaLogicalId}', but no ${LAMBDA_FUNCTION_TYPE} with that logical id exists in ${stackName}. Skipping that target group.`);
27308
+ if (!lambda || lambda.Type !== LAMBDA_FUNCTION_TYPE$1) {
27309
+ warnings.push(`${label} forwards to Lambda target group '${tgRef}', whose target resolves to '${lambdaLogicalId}', but no ${LAMBDA_FUNCTION_TYPE$1} with that logical id exists in ${stackName}. Skipping that target group.`);
27310
27310
  return;
27311
27311
  }
27312
27312
  return {
@@ -28169,6 +28169,8 @@ function decodePart(s) {
28169
28169
  const CLOUDFRONT_DISTRIBUTION_TYPE = "AWS::CloudFront::Distribution";
28170
28170
  const CLOUDFRONT_FUNCTION_TYPE = "AWS::CloudFront::Function";
28171
28171
  const S3_BUCKET_TYPE = "AWS::S3::Bucket";
28172
+ const LAMBDA_URL_TYPE = "AWS::Lambda::Url";
28173
+ const LAMBDA_FUNCTION_TYPE = "AWS::Lambda::Function";
28172
28174
  /**
28173
28175
  * Resolve a distribution logical id within a stack into its routing model.
28174
28176
  * `originOverrides` maps an origin id to a local directory (the `--origin`
@@ -28283,6 +28285,11 @@ function resolveOrigins(dc, template, stack, overrides) {
28283
28285
  }
28284
28286
  const bucketLogicalId = pickBucketLogicalIdFromOrigin(origin, template);
28285
28287
  if (!(origin["S3OriginConfig"] !== void 0 || bucketLogicalId !== void 0)) {
28288
+ const lambdaUrl = resolveLambdaUrlOrigin(origin, template, originId);
28289
+ if (lambdaUrl) {
28290
+ out.set(originId, lambdaUrl);
28291
+ continue;
28292
+ }
28286
28293
  out.set(originId, {
28287
28294
  kind: "custom",
28288
28295
  originId,
@@ -28373,6 +28380,58 @@ function getAttLogicalId(value) {
28373
28380
  const getAtt = value["Fn::GetAtt"];
28374
28381
  if (Array.isArray(getAtt) && getAtt.length === 2 && typeof getAtt[0] === "string") return getAtt[0];
28375
28382
  }
28383
+ /**
28384
+ * Resolve a Lambda Function URL custom origin (`origins.FunctionUrlOrigin`) to
28385
+ * its backing `AWS::Lambda::Function` logical id, or `undefined` when the
28386
+ * origin is not a Function URL (a generic custom HTTP origin). CDK synthesizes
28387
+ * a FunctionUrlOrigin's `DomainName` from the Function URL by stripping the
28388
+ * scheme + trailing slash:
28389
+ * `Fn::Select[2, Fn::Split['/', Fn::GetAtt[<UrlLogicalId>, 'FunctionUrl']]]`.
28390
+ * The `AWS::Lambda::Url` resource's `TargetFunctionArn` then points at the
28391
+ * function (a `Ref` or `Fn::GetAtt[<fn>, 'Arn']`).
28392
+ */
28393
+ function resolveLambdaUrlOrigin(origin, template, originId) {
28394
+ const urlLogicalId = pickFunctionUrlLogicalIdFromOrigin(origin["DomainName"]);
28395
+ if (!urlLogicalId) return void 0;
28396
+ const urlResource = (template.Resources ?? {})[urlLogicalId];
28397
+ if (!urlResource || urlResource.Type !== LAMBDA_URL_TYPE) return void 0;
28398
+ const functionLogicalId = pickTargetFunctionLogicalId((urlResource.Properties ?? {})["TargetFunctionArn"]);
28399
+ if (!functionLogicalId) return void 0;
28400
+ const fnResource = (template.Resources ?? {})[functionLogicalId];
28401
+ if (!fnResource || fnResource.Type !== LAMBDA_FUNCTION_TYPE) return void 0;
28402
+ return {
28403
+ kind: "lambda-url",
28404
+ originId,
28405
+ functionLogicalId,
28406
+ functionUrlLogicalId: urlLogicalId
28407
+ };
28408
+ }
28409
+ /**
28410
+ * Unwrap a FunctionUrlOrigin `DomainName` to its `AWS::Lambda::Url` logical id.
28411
+ * Matches the exact synthesized shape
28412
+ * `{Fn::Select: [2, {Fn::Split: ['/', {Fn::GetAtt: [<UrlLogicalId>, 'FunctionUrl']}]}]}`.
28413
+ */
28414
+ function pickFunctionUrlLogicalIdFromOrigin(value) {
28415
+ const select = asIntrinsic(value, "Fn::Select");
28416
+ if (!Array.isArray(select) || select.length !== 2 || select[0] !== 2) return void 0;
28417
+ const split = asIntrinsic(select[1], "Fn::Split");
28418
+ if (!Array.isArray(split) || split.length !== 2 || split[0] !== "/") return void 0;
28419
+ const getAtt = asIntrinsic(split[1], "Fn::GetAtt");
28420
+ if (Array.isArray(getAtt) && getAtt.length === 2 && typeof getAtt[0] === "string" && getAtt[1] === "FunctionUrl") return getAtt[0];
28421
+ }
28422
+ /**
28423
+ * Unwrap an `AWS::Lambda::Url` `TargetFunctionArn` to the function logical id.
28424
+ * CDK emits either a `Ref` (the function's name reference) or a
28425
+ * `Fn::GetAtt[<fn>, 'Arn']`.
28426
+ */
28427
+ function pickTargetFunctionLogicalId(value) {
28428
+ return refLogicalId(value) ?? getAttLogicalId(value);
28429
+ }
28430
+ /** Read an intrinsic's payload (e.g. the `Fn::Select` array) from a wrapper object. */
28431
+ function asIntrinsic(value, key) {
28432
+ if (!value || typeof value !== "object") return void 0;
28433
+ return value[key];
28434
+ }
28376
28435
  function refLogicalId(value) {
28377
28436
  if (!value || typeof value !== "object") return void 0;
28378
28437
  const ref = value["Ref"];
@@ -28405,6 +28464,59 @@ function isCloudFrontDistribution(resource) {
28405
28464
  return resource.Type === CLOUDFRONT_DISTRIBUTION_TYPE;
28406
28465
  }
28407
28466
 
28467
+ //#endregion
28468
+ //#region src/local/cloudfront-lambda-origin.ts
28469
+ /**
28470
+ * Build the Function URL v2 event from the request, invoke the Lambda, and
28471
+ * translate its response. `invoke` is the warm RIE container's invoke function
28472
+ * (from `createFrontDoorLambdaRunner`).
28473
+ */
28474
+ async function serveLambdaUrlOrigin(args) {
28475
+ const { request } = args;
28476
+ const event = buildHttpApiV2Event({
28477
+ method: request.method,
28478
+ rawUrl: request.querystring ? `${request.uri}?${request.querystring}` : request.uri,
28479
+ headers: normalizeHeaders(request.headers),
28480
+ body: request.body,
28481
+ ...request.sourceIp !== void 0 && { sourceIp: request.sourceIp }
28482
+ }, {
28483
+ route: {
28484
+ method: "ANY",
28485
+ pathPattern: "$default",
28486
+ lambdaLogicalId: args.functionLogicalId,
28487
+ source: "function-url",
28488
+ apiVersion: "v2",
28489
+ stage: "$default",
28490
+ apiLogicalId: args.functionUrlLogicalId,
28491
+ invokeMode: "BUFFERED",
28492
+ declaredAt: args.functionUrlLogicalId
28493
+ },
28494
+ pathParameters: {},
28495
+ matchedPath: request.uri
28496
+ });
28497
+ const translated = translateLambdaResponse(await args.invoke(event), "v2");
28498
+ return {
28499
+ statusCode: translated.statusCode,
28500
+ headers: translated.headers,
28501
+ cookies: translated.cookies,
28502
+ body: translated.body
28503
+ };
28504
+ }
28505
+ /**
28506
+ * Convert Node's incoming-header map (`string | string[] | undefined`) into the
28507
+ * `Record<string, string[]>` shape {@link HttpRequestSnapshot} expects. A
28508
+ * comma-joined string header (Node's default for most duplicates) is passed
28509
+ * through as a single element; an array header is preserved.
28510
+ */
28511
+ function normalizeHeaders(headers) {
28512
+ const out = {};
28513
+ for (const [name, value] of Object.entries(headers)) {
28514
+ if (value === void 0) continue;
28515
+ out[name] = Array.isArray(value) ? value : [value];
28516
+ }
28517
+ return out;
28518
+ }
28519
+
28408
28520
  //#endregion
28409
28521
  //#region src/local/cloudfront-static-origin.ts
28410
28522
  /**
@@ -28535,9 +28647,10 @@ function contentTypeForKey(key) {
28535
28647
  /** Start the local CloudFront server and resolve once it is listening. */
28536
28648
  async function startCloudFrontServer(options) {
28537
28649
  const logger = getLogger().child("cloudfront");
28650
+ const lambdaInvokers = options.lambdaInvokers ?? /* @__PURE__ */ new Map();
28538
28651
  const state = { distribution: options.distribution };
28539
28652
  const handler = (req, res) => {
28540
- handleRequest$1(req, res, state, logger).catch((err) => {
28653
+ handleRequest$1(req, res, state, lambdaInvokers, logger).catch((err) => {
28541
28654
  logger.warn(`Request handling failed: ${err instanceof Error ? err.message : String(err)}`);
28542
28655
  if (!res.headersSent) {
28543
28656
  res.statusCode = 500;
@@ -28567,7 +28680,7 @@ async function startCloudFrontServer(options) {
28567
28680
  };
28568
28681
  }
28569
28682
  /** The per-request pipeline: behavior match -> viewer-request -> origin -> viewer-response. */
28570
- async function handleRequest$1(req, res, state, logger) {
28683
+ async function handleRequest$1(req, res, state, lambdaInvokers, logger) {
28571
28684
  const distribution = state.distribution;
28572
28685
  const rawUrl = req.url ?? "/";
28573
28686
  const queryIdx = rawUrl.indexOf("?");
@@ -28602,7 +28715,17 @@ async function handleRequest$1(req, res, state, logger) {
28602
28715
  };
28603
28716
  }
28604
28717
  const origin = distribution.origins.get(behavior.targetOriginId);
28605
- const originResult = serveFromOrigin(origin, behavior, effectiveUri, distribution, logger);
28718
+ const originResult = await serveFromOrigin(origin, behavior, {
28719
+ uri: effectiveUri,
28720
+ querystring,
28721
+ method: req.method ?? "GET",
28722
+ headers: req.headers,
28723
+ readBody: () => readRequestBody(req),
28724
+ sourceIp: req.socket.remoteAddress ?? "127.0.0.1",
28725
+ distribution,
28726
+ lambdaInvokers,
28727
+ logger
28728
+ });
28606
28729
  if (!originResult) return writePlain(res, 502, originUnavailableMessage(origin, behavior));
28607
28730
  let finalStatus = originResult.statusCode;
28608
28731
  let finalHeaders = originResult.headers;
@@ -28615,10 +28738,29 @@ async function handleRequest$1(req, res, state, logger) {
28615
28738
  finalStatus = mutated.statusCode;
28616
28739
  finalHeaders = cfHeadersToPlain(mutated.headers, originResult.headers);
28617
28740
  }
28741
+ const setCookies = [...originResult.setCookies ?? []];
28742
+ for (const name of Object.keys(finalHeaders)) if (name.toLowerCase() === "set-cookie") {
28743
+ setCookies.push(finalHeaders[name]);
28744
+ delete finalHeaders[name];
28745
+ }
28618
28746
  res.statusCode = finalStatus;
28619
28747
  setHeadersSafely(res, finalHeaders, logger);
28748
+ if (setCookies.length > 0) try {
28749
+ res.setHeader("set-cookie", setCookies);
28750
+ } catch (err) {
28751
+ logger.warn(`Skipping invalid Set-Cookie header(s): ${err instanceof Error ? err.message : String(err)}`);
28752
+ }
28620
28753
  res.end(originResult.body);
28621
28754
  }
28755
+ /** Read the full request body into a Buffer. */
28756
+ function readRequestBody(req) {
28757
+ return new Promise((resolveBody, rejectBody) => {
28758
+ const chunks = [];
28759
+ req.on("data", (chunk) => chunks.push(chunk));
28760
+ req.on("end", () => resolveBody(Buffer.concat(chunks)));
28761
+ req.on("error", rejectBody);
28762
+ });
28763
+ }
28622
28764
  /**
28623
28765
  * Set response headers, skipping any whose name / value Node rejects (invalid
28624
28766
  * HTTP token, CR/LF injection) rather than throwing an opaque 500. A CloudFront
@@ -28633,12 +28775,37 @@ function setHeadersSafely(res, headers, logger) {
28633
28775
  logger.warn(`Skipping invalid response header '${name}': ${err instanceof Error ? err.message : String(err)}`);
28634
28776
  }
28635
28777
  }
28636
- function serveFromOrigin(origin, behavior, uri, distribution, logger) {
28637
- if (behavior.hasLambdaEdge) logger.warn(`Behavior ${behavior.pathPattern ?? "(default)"} carries a Lambda@Edge association; cdk-local does not run Lambda@Edge — serving the S3 origin only.`);
28638
- if (!origin || origin.kind !== "s3") return void 0;
28778
+ async function serveFromOrigin(origin, behavior, args) {
28779
+ const { distribution, logger } = args;
28780
+ if (behavior.hasLambdaEdge) logger.warn(`Behavior ${behavior.pathPattern ?? "(default)"} carries a Lambda@Edge association; cdk-local does not run Lambda@Edge — serving the origin only.`);
28781
+ if (!origin) return void 0;
28782
+ if (origin.kind === "lambda-url") {
28783
+ const invoke = args.lambdaInvokers.get(origin.functionLogicalId);
28784
+ if (!invoke) return void 0;
28785
+ const result = await serveLambdaUrlOrigin({
28786
+ invoke,
28787
+ functionUrlLogicalId: origin.functionUrlLogicalId,
28788
+ functionLogicalId: origin.functionLogicalId,
28789
+ request: {
28790
+ method: args.method,
28791
+ uri: args.uri,
28792
+ querystring: args.querystring,
28793
+ headers: args.headers,
28794
+ body: await args.readBody(),
28795
+ sourceIp: args.sourceIp
28796
+ }
28797
+ });
28798
+ return {
28799
+ statusCode: result.statusCode,
28800
+ headers: result.headers,
28801
+ body: result.body,
28802
+ ...result.cookies.length > 0 && { setCookies: result.cookies }
28803
+ };
28804
+ }
28805
+ if (origin.kind !== "s3") return void 0;
28639
28806
  const result = serveFromStaticOrigin({
28640
28807
  localDirs: origin.localDirs,
28641
- uri,
28808
+ uri: args.uri,
28642
28809
  ...distribution.defaultRootObject !== void 0 && { defaultRootObject: distribution.defaultRootObject },
28643
28810
  customErrorResponses: distribution.customErrorResponses
28644
28811
  });
@@ -28650,7 +28817,8 @@ function serveFromOrigin(origin, behavior, uri, distribution, logger) {
28650
28817
  }
28651
28818
  function originUnavailableMessage(origin, behavior) {
28652
28819
  if (!origin) return `Behavior ${behavior.pathPattern ?? "(default)"} targets unknown origin '${behavior.targetOriginId}'.\n`;
28653
- if (origin.kind === "custom") return `Origin '${origin.originId}' is a custom (non-S3) origin (${origin.domainName}). cdkl start-cloudfront serves S3 origins only.
28820
+ if (origin.kind === "lambda-url") return `Origin '${origin.originId}' is a Lambda Function URL origin whose backing function '${origin.functionLogicalId}' was not booted (it was added after start-up). Restart start-cloudfront.\n`;
28821
+ if (origin.kind === "custom") return `Origin '${origin.originId}' is a custom (non-S3) origin (${origin.domainName}). cdkl start-cloudfront serves S3 origins and Lambda Function URL origins only.
28654
28822
  `;
28655
28823
  return `Origin '${origin.originId}' is an S3 origin with no resolvable local source. Point it at a directory with --origin ${origin.originId}=<dir>.\n`;
28656
28824
  }
@@ -28774,10 +28942,46 @@ function notFound(target, stack, resources) {
28774
28942
  const available = dists.length > 0 ? ` Available distributions in ${stack.stackName}: ${dists.join(", ")}.` : ` ${stack.stackName} declares no ${CLOUDFRONT_DISTRIBUTION_TYPE} resources.`;
28775
28943
  return new LocalStartCloudFrontError(`Target '${target}' did not match a CloudFront distribution in ${stack.stackName}.${available}`);
28776
28944
  }
28945
+ /**
28946
+ * Boot one warm RIE container per unique Lambda Function URL origin in the
28947
+ * distribution (issue #376), returning the runners + an invoker map keyed by
28948
+ * backing-function logical id for {@link startCloudFrontServer}. Returns empty
28949
+ * collections when the distribution has no Function URL origin — start-cloudfront
28950
+ * then stays pure-local (no Docker). Booted once at start-up; NOT re-run on a
28951
+ * `--watch` reload (the warm containers keep their boot-time image).
28952
+ */
28953
+ async function bootLambdaUrlOrigins(distribution, stacks, opts) {
28954
+ const logger = getLogger();
28955
+ const invokers = /* @__PURE__ */ new Map();
28956
+ const runners = [];
28957
+ const functionLogicalIds = /* @__PURE__ */ new Set();
28958
+ for (const origin of distribution.origins.values()) if (origin.kind === "lambda-url") functionLogicalIds.add(origin.functionLogicalId);
28959
+ for (const functionLogicalId of functionLogicalIds) {
28960
+ let runner;
28961
+ try {
28962
+ runner = createFrontDoorLambdaRunner(resolveLambdaTarget(functionLogicalId, stacks), {
28963
+ containerHost: opts.containerHost,
28964
+ skipPull: opts.skipPull,
28965
+ ...opts.region !== void 0 && { region: opts.region }
28966
+ });
28967
+ logger.info(`Booting Lambda Function URL origin container for ${functionLogicalId} (the backing Lambda runs locally via RIE)...`);
28968
+ await runner.start();
28969
+ } catch (err) {
28970
+ await Promise.all(runners.map((r) => r.stop().catch(() => void 0)));
28971
+ throw new LocalStartCloudFrontError(`Failed to boot the Lambda Function URL origin's backing function '${functionLogicalId}': ${err instanceof Error ? err.message : String(err)}`, err instanceof Error ? err : void 0);
28972
+ }
28973
+ runners.push(runner);
28974
+ invokers.set(functionLogicalId, (event) => runner.invoke(event));
28975
+ }
28976
+ return {
28977
+ invokers,
28978
+ runners
28979
+ };
28980
+ }
28777
28981
  /** Emit boot-time WARNs for parts of the distribution cdk-local does not serve. */
28778
28982
  function warnUnsupported(distribution) {
28779
28983
  const logger = getLogger();
28780
- for (const origin of distribution.origins.values()) if (origin.kind === "custom") logger.warn(`Origin '${origin.originId}' is a custom (non-S3) origin (${origin.domainName}); cdkl start-cloudfront serves S3 origins only. Requests routed to it return 502.`);
28984
+ for (const origin of distribution.origins.values()) if (origin.kind === "custom") logger.warn(`Origin '${origin.originId}' is a custom (non-S3, non-Lambda-Function-URL) origin (${origin.domainName}); ${getEmbedConfig().cliName} start-cloudfront serves S3 origins and Lambda Function URL origins only. Requests routed to it return 502.`);
28781
28985
  else if (origin.kind === "s3-unresolved") logger.warn(`Origin '${origin.originId}' is an S3 origin with no resolvable local source (no BucketDeployment found, or its source could not be located in the cloud assembly). Point it at a directory with --origin ${origin.originId}=<dir>. Requests routed to it return 502.`);
28782
28986
  if (distribution.behaviors.some((b) => b.hasLambdaEdge)) logger.warn("One or more cache behaviors carry a Lambda@Edge association; cdk-local does not run Lambda@Edge functions — only CloudFront Functions + the S3 origin are served.");
28783
28987
  }
@@ -28815,26 +29019,35 @@ async function localStartCloudFrontCommand(target, options) {
28815
29019
  });
28816
29020
  target = chosen;
28817
29021
  const { stack, logicalId } = resolveCloudFrontTarget(chosen, stacks);
28818
- return resolveCloudFrontDistribution({
28819
- stack,
28820
- logicalId,
28821
- originOverrides
28822
- });
29022
+ return {
29023
+ distribution: resolveCloudFrontDistribution({
29024
+ stack,
29025
+ logicalId,
29026
+ originOverrides
29027
+ }),
29028
+ stacks
29029
+ };
28823
29030
  };
28824
29031
  const initial = await synthAndResolve();
28825
- warnUnsupported(initial);
29032
+ warnUnsupported(initial.distribution);
29033
+ const { invokers: lambdaInvokers, runners: lambdaRunners } = await bootLambdaUrlOrigins(initial.distribution, initial.stacks, {
29034
+ containerHost: options.host,
29035
+ skipPull: options.pull === false,
29036
+ ...options.region !== void 0 && { region: options.region }
29037
+ });
28826
29038
  let tls;
28827
29039
  if (tlsRequested) tls = await resolveFrontDoorTlsMaterials({
28828
29040
  certPath: options.tlsCert,
28829
29041
  keyPath: options.tlsKey
28830
29042
  });
28831
29043
  const server = await startCloudFrontServer({
28832
- distribution: initial,
29044
+ distribution: initial.distribution,
28833
29045
  host: options.host,
28834
29046
  port: basePort,
28835
- ...tls && { tls }
29047
+ ...tls && { tls },
29048
+ ...lambdaInvokers.size > 0 && { lambdaInvokers }
28836
29049
  });
28837
- process.stdout.write(`CloudFront distribution serving on ${server.url} (${initial.logicalId})\n`);
29050
+ process.stdout.write(`CloudFront distribution serving on ${server.url} (${initial.distribution.logicalId})\n`);
28838
29051
  process.stdout.write("^C to stop.\n");
28839
29052
  let watcher;
28840
29053
  let reloadChain = Promise.resolve();
@@ -28854,8 +29067,8 @@ async function localStartCloudFrontCommand(target, options) {
28854
29067
  reloadChain = reloadChain.then(async () => {
28855
29068
  try {
28856
29069
  const reloaded = await synthAndResolve();
28857
- warnUnsupported(reloaded);
28858
- server.update(reloaded);
29070
+ warnUnsupported(reloaded.distribution);
29071
+ server.update(reloaded.distribution);
28859
29072
  logger.info("Reload complete.");
28860
29073
  } catch (err) {
28861
29074
  logger.warn(`Reload failed; keeping the previous version serving: ${err instanceof Error ? err.message : String(err)}`);
@@ -28876,6 +29089,9 @@ async function localStartCloudFrontCommand(target, options) {
28876
29089
  try {
28877
29090
  await server.close();
28878
29091
  } catch {}
29092
+ await Promise.all(lambdaRunners.map((r) => r.stop().catch((err) => {
29093
+ logger.debug(`Lambda origin runner stop failed: ${err instanceof Error ? err.message : String(err)}`);
29094
+ })));
28879
29095
  process.exit(exitCode);
28880
29096
  };
28881
29097
  process.on("SIGINT", () => void shutdown("SIGINT", 130));
@@ -28884,7 +29100,7 @@ async function localStartCloudFrontCommand(target, options) {
28884
29100
  }
28885
29101
  function createLocalStartCloudFrontCommand(opts = {}) {
28886
29102
  setEmbedConfig(opts.embedConfig);
28887
- const cmd = new Command("start-cloudfront").description("Run a long-running local server that serves a CloudFront distribution: its S3 origin content (resolved from the BucketDeployment source in the cloud assembly) plus its viewer-request / viewer-response CloudFront Functions, reproducing the distribution routing locally so a rewrite / routing change is verifiable in seconds. Serves S3 origins only; custom origins and Lambda@Edge are not run (warn-and-skip). Tip: omit the target in a terminal to pick interactively.").argument("[target]", "CloudFront distribution to serve. Accepts the CDK Construct path ('MyStack/MyDist'), an ancestor prefix, or the stack-qualified logical id ('MyStack:MyDist'). When omitted in a TTY, an interactive picker opens.").action(withErrorHandling(async (target, options) => {
29103
+ const cmd = new Command("start-cloudfront").description("Run a long-running local server that serves a CloudFront distribution: its S3 origin content (resolved from the BucketDeployment source in the cloud assembly) and its Lambda Function URL origins (the backing Lambda is run locally via RIE), plus its viewer-request / viewer-response CloudFront Functions, reproducing the distribution routing locally so a rewrite / routing change is verifiable in seconds. Serves S3 and Lambda Function URL origins; other custom origins and Lambda@Edge are not run (warn-and-skip). Tip: omit the target in a terminal to pick interactively.").argument("[target]", "CloudFront distribution to serve. Accepts the CDK Construct path ('MyStack/MyDist'), an ancestor prefix, or the stack-qualified logical id ('MyStack:MyDist'). When omitted in a TTY, an interactive picker opens.").action(withErrorHandling(async (target, options) => {
28888
29104
  await localStartCloudFrontCommand(target, options);
28889
29105
  }));
28890
29106
  addStartCloudFrontSpecificOptions(cmd);
@@ -28905,7 +29121,7 @@ function createLocalStartCloudFrontCommand(opts = {}) {
28905
29121
  * `cmd`.
28906
29122
  */
28907
29123
  function addStartCloudFrontSpecificOptions(cmd) {
28908
- return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--origin <originId=dir>", "Point a distribution origin at a local directory (repeatable). Use when cdk-local cannot resolve the origin's BucketDeployment source automatically (content uploaded out of band, or a non-CDK bucket).").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--tls", "Terminate real TLS (HTTPS). Uses --tls-cert / --tls-key when supplied, else an auto-generated self-signed cert.").default(false)).addOption(new Option("--tls-cert <path>", "PEM server certificate for --tls (implies --tls).")).addOption(new Option("--tls-key <path>", "PEM server private key for --tls (implies --tls).")).addOption(new Option("--watch", "Hot-reload: re-synth + re-resolve the distribution when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, node_modules, .git are always excluded). The server keeps the previous version serving when synth fails mid-reload.").default(false));
29124
+ return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--origin <originId=dir>", "Point a distribution origin at a local directory (repeatable). Use when cdk-local cannot resolve the origin's BucketDeployment source automatically (content uploaded out of band, or a non-CDK bucket).").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--tls", "Terminate real TLS (HTTPS). Uses --tls-cert / --tls-key when supplied, else an auto-generated self-signed cert.").default(false)).addOption(new Option("--tls-cert <path>", "PEM server certificate for --tls (implies --tls).")).addOption(new Option("--tls-key <path>", "PEM server private key for --tls (implies --tls).")).addOption(new Option("--no-pull", "Skip 'docker pull' for a Lambda Function URL origin's base image (use the locally cached image).")).addOption(new Option("--watch", "Hot-reload: re-synth + re-resolve the distribution when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, node_modules, .git are always excluded). The server keeps the previous version serving when synth fails mid-reload.").default(false));
28909
29125
  }
28910
29126
 
28911
29127
  //#endregion
@@ -30337,6 +30553,15 @@ const STUDIO_SCRIPT = `
30337
30553
  const st = serveState.get(id) || { status: 'stopped', endpoints: [] };
30338
30554
  const running = st.status === 'running';
30339
30555
  const starting = st.status === 'starting';
30556
+ // A serve that exited with a failure reason is FAILED, distinct from a
30557
+ // clean user stop. A boot failure arrives as status 'error'; a crash AFTER
30558
+ // the serve was running arrives as status 'stopped' WITH a message (a clean
30559
+ // user stop is 'stopped' with NO message). A failed serve keeps its
30560
+ // "Started with" context + surfaces the reason + offers a Reconfigure
30561
+ // button instead of silently dropping to a blank composer (which reads as
30562
+ // "my inputs vanished" when the serve actually crashed).
30563
+ const failed = st.status === 'error' || (st.status === 'stopped' && !!st.message);
30564
+ const effErr = errMsg || (failed ? st.message : undefined);
30340
30565
  // A NON-running render (serve stopped / starting) tears down any open
30341
30566
  // WebSocket-console socket: its endpoint is gone, and leaving it open would
30342
30567
  // show "● connected" against a dead serve if the same target is restarted.
@@ -30355,20 +30580,32 @@ const STUDIO_SCRIPT = `
30355
30580
  head.appendChild(el('div', 'target-name', (isTaskRun ? 'Run ' : 'Serve ') + id));
30356
30581
  const btn = running || starting
30357
30582
  ? el('button', null, 'Stop')
30358
- : el('button', null, starting ? 'Starting…' : startLabel);
30583
+ : el('button', null, failed ? 'Reconfigure' : startLabel);
30359
30584
  // Per-run options are only set before a start; collected on the Start click.
30360
30585
  let collectOpts = function () { return undefined; };
30361
30586
  let collectRaw = function () { return undefined; };
30362
30587
  let collectImageOverride = function () { return undefined; };
30363
- btn.onclick = () => { if (running || starting) stopServe(id); else startServe(id, collectOpts(), collectRaw(), collectImageOverride()); };
30588
+ btn.onclick = () => {
30589
+ if (running || starting) {
30590
+ stopServe(id);
30591
+ } else if (failed) {
30592
+ // Clear the failed state so the composer comes back (the user adjusts
30593
+ // options + restarts) — NOT a blind default restart that would drop
30594
+ // the env-vars / other options the crashed serve was started with.
30595
+ serveState.set(id, { status: 'stopped', endpoints: [] });
30596
+ renderServeWorkspace(id);
30597
+ } else {
30598
+ startServe(id, collectOpts(), collectRaw(), collectImageOverride());
30599
+ }
30600
+ };
30364
30601
  head.appendChild(btn);
30365
- if (errMsg) {
30366
- const m = el('div', 'err', errMsg);
30602
+ if (effErr) {
30603
+ const m = el('div', 'err', effErr);
30367
30604
  head.appendChild(m);
30368
30605
  }
30369
30606
  ws.appendChild(head);
30370
30607
 
30371
- if (!running && !starting) {
30608
+ if (!running && !starting && !failed) {
30372
30609
  // A pinned ECS service (deployed-registry image) does not pick up local
30373
30610
  // source edits — offer an image-override Dockerfile picker so it can be
30374
30611
  // rebuilt locally (issue #301). Local-asset services hot-reload under
@@ -30384,11 +30621,12 @@ const STUDIO_SCRIPT = `
30384
30621
  collectRaw = opt.collectRaw;
30385
30622
  }
30386
30623
 
30387
- if (running || starting) {
30624
+ if (running || starting || failed) {
30388
30625
  // Issue #356: the per-run option inputs are gone once the composer is
30389
30626
  // replaced by this running view, so surface what the serve was Started
30390
30627
  // with as a read-only summary (so e.g. a chosen --max-tasks stays
30391
- // visible instead of silently vanishing after Start).
30628
+ // visible instead of silently vanishing after Start). A FAILED serve
30629
+ // keeps this too, so a crash does not read as "my inputs disappeared".
30392
30630
  const lines = formatAppliedOptions(serveApplied.get(id));
30393
30631
  const startedSec = el('div', 'section started-with');
30394
30632
  startedSec.appendChild(el('h3', null, 'Started with'));
@@ -31263,9 +31501,14 @@ const STUDIO_SCRIPT = `
31263
31501
 
31264
31502
  function onServeEvent(ev) {
31265
31503
  // A 'stopped' / 'error' transition clears the running state; otherwise
31266
- // record the latest status + endpoints for the row + workspace.
31504
+ // record the latest status + endpoints for the row + workspace. Keep the
31505
+ // failure reason (ev.message) so the workspace can surface a crash instead
31506
+ // of silently reverting to a blank composer: a boot failure arrives as
31507
+ // 'error' with a message, a crash AFTER the serve was running arrives as
31508
+ // 'stopped' WITH a message, and a clean user stop is 'stopped' with NO
31509
+ // message (renderServeWorkspace uses message presence to tell them apart).
31267
31510
  if (ev.status === 'stopped' || ev.status === 'error') {
31268
- serveState.set(ev.target, { status: ev.status, endpoints: [] });
31511
+ serveState.set(ev.target, { status: ev.status, endpoints: [], message: ev.message });
31269
31512
  } else {
31270
31513
  serveState.set(ev.target, { status: ev.status, endpoints: ev.endpoints || [], hostUrl: ev.hostUrl });
31271
31514
  }
@@ -32954,6 +33197,21 @@ function coerceStopRequest(body) {
32954
33197
  if (typeof targetId !== "string" || targetId.trim() === "") throw new Error("Request body must include a non-empty \"targetId\" string.");
32955
33198
  return { targetId };
32956
33199
  }
33200
+ /**
33201
+ * Route a validated `POST /api/run` request to the right runner: the
33202
+ * single-shot dispatcher for the invoke kinds (`lambda` / `agentcore`), or the
33203
+ * serve manager for every serve kind (`api` / `alb` / `ecs` / `ecs-task` /
33204
+ * `cloudfront`). An `ecs` target that is NOT a servable service (a raw curl
33205
+ * could POST a task-def id with `kind: 'ecs'`) is rejected at the boundary with
33206
+ * a clear message rather than spawning a doomed `start-service`. Extracted from
33207
+ * the `onRun` closure so the kind→runner routing is unit-testable without
33208
+ * booting the studio server.
33209
+ */
33210
+ function routeStudioRun(req, deps) {
33211
+ if (req.kind === "lambda" || req.kind === "agentcore") return deps.dispatcher.run(req);
33212
+ if (req.kind === "ecs" && !deps.servableEcs.has(req.targetId)) return Promise.reject(/* @__PURE__ */ new Error(`'${req.targetId}' is not a servable ECS service (an ECS task definition runs via run-task, not start-service).`));
33213
+ return deps.serveManager.start(req);
33214
+ }
32957
33215
  const SERVE_REQUEST_METHODS = new Set([
32958
33216
  "GET",
32959
33217
  "POST",
@@ -33286,12 +33544,11 @@ async function localStudioCommand(options) {
33286
33544
  appLabel,
33287
33545
  cliName: getEmbedConfig().cliName,
33288
33546
  store,
33289
- onRun: (body) => {
33290
- const req = coerceRunRequest(body);
33291
- if (req.kind === "lambda" || req.kind === "agentcore") return dispatcher.run(req);
33292
- if (req.kind === "ecs" && !servableEcs.has(req.targetId)) return Promise.reject(/* @__PURE__ */ new Error(`'${req.targetId}' is not a servable ECS service (an ECS task definition runs via run-task, not start-service).`));
33293
- return serveManager.start(req);
33294
- },
33547
+ onRun: (body) => routeStudioRun(coerceRunRequest(body), {
33548
+ dispatcher,
33549
+ serveManager,
33550
+ servableEcs
33551
+ }),
33295
33552
  onStop: async (body) => {
33296
33553
  const req = coerceStopRequest(body);
33297
33554
  await serveManager.stop(req);
@@ -33433,5 +33690,5 @@ function addStudioSpecificOptions(cmd) {
33433
33690
  }
33434
33691
 
33435
33692
  //#endregion
33436
- export { addImageOverrideOptions as $, resolveRuntimeCodeMountPath as $n, createAuthorizerCache as $t, startCloudFrontServer as A, matchPreflight as An, AGENTCORE_A2A_PROTOCOL as Ar, MCP_CONTAINER_PORT as At, createLocalStartAlbCommand as B, VtlEvaluationError as Bn, substituteImagePlaceholders as Br, downloadAndExtractS3Bundle as Bt, formatTargetListing as C, invokeRequestAuthorizer as Cn, discoverWebSocketApisOrThrow as Cr, attachContainerLogStreamer as Ct, parseOriginOverrides as D, buildCorsConfigByApiId as Dn, discoverRoutes as Dr, A2A_CONTAINER_PORT as Dt, createLocalStartCloudFrontCommand as E, applyCorsResponseHeaders as En, webSocketApiMatchesIdentifier as Er, invokeAgentCoreWs as Et, compileCloudFrontFunction as F, buildRestV1Event as Fn, AgentCoreResolutionError as Fr, AGENTCORE_SIGV4_SERVICE as Ft, addStartServiceSpecificOptions as G, buildMgmtEndpointEnvUrl as Gn, toCmdArgv as Gt, resolveAlbTarget as H, probeHostGatewaySupport as Hn, LocalInvokeBuildError as Hr, buildAgentCoreCodeImage as Ht, runViewerRequest as I, evaluateResponseParameters as In, pickAgentCoreCandidateStack as Ir, signAgentCoreInvocation as It, addRunTaskSpecificOptions as J, buildConnectEvent as Jn, createLocalInvokeCommand as Jt, createLocalStartServiceCommand as K, handleConnectionsRequest as Kn, classifySourceChange as Kt, runViewerResponse as L, pickResponseTemplate as Ln, resolveAgentCoreTarget as Lr, AGENTCORE_SESSION_ID_HEADER as Lt, CLOUDFRONT_DISTRIBUTION_TYPE as M, translateLambdaResponse as Mn, AGENTCORE_HTTP_PROTOCOL as Mr, MCP_PROTOCOL_VERSION as Mt, isCloudFrontDistribution as N, applyAuthorizerOverlay as Nn, AGENTCORE_MCP_PROTOCOL as Nr, mcpInvokeOnce as Nt, resolveCloudFrontTarget as O, buildCorsConfigFromCloudFrontChain as On, pickRefLogicalId as Or, A2A_PATH as Ot, resolveCloudFrontDistribution as P, buildHttpApiV2Event as Pn, AGENTCORE_RUNTIME_TYPE as Pr, parseSseForJsonRpc as Pt, addEcsAssumeRoleOptions as Q, buildContainerImage as Qn, resolveApiTargetSubset as Qt, addAlbSpecificOptions as R, selectIntegrationResponse as Rn, derivePseudoParametersFromRegion as Rr, invokeAgentCore as Rt, createLocalListCommand as S, evaluateCachedLambdaPolicy as Sn, discoverWebSocketApis as Sr, getContainerNetworkIp as St, addStartCloudFrontSpecificOptions as T, attachAuthorizers as Tn, parseSelectionExpressionPath as Tr, createLocalInvokeAgentCoreCommand as Tt, isApplicationLoadBalancer as U, bufferToBody as Un, buildStsClientConfig as Ur, computeCodeImageTag as Ut, parseLbPortOverrides as V, HOST_GATEWAY_MIN_VERSION as Vn, tryResolveImageFnJoin as Vr, SUPPORTED_CODE_RUNTIMES as Vt, resolveAlbFrontDoor as W, ConnectionRegistry as Wn, resolveProfileCredentials as Wr, renderCodeDockerfile as Wt, MAX_TASKS_SUBNET_RANGE_CAP as X, buildMessageEvent as Xn, createLocalStartApiCommand as Xt, createLocalRunTaskCommand as Y, buildDisconnectEvent as Yn, addStartApiSpecificOptions as Yt, addCommonEcsServiceOptions as Z, architectureToPlatform as Zn, createWatchPredicates as Zt, toStudioTargetGroups as _, verifyCognitoJwt as _n, resolveWatchConfig as _r, buildCloudMapIndex as _t, createLocalStudioCommand as a, availableApiIdentifiers as an, substituteEnvVarsFromState as ar, resolveSharedSidecarCredentials as at, StudioEventBus as b, buildMethodArn as bn, listTargets as br, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as bt, startStudioProxy as c, groupRoutesByServer as cn, createLocalStateProvider as cr, buildImageOverrideTag as ct, createStudioDispatcher as d, resolveSelectionExpression as dn, resolveCfnFallbackRegion as dr, parseImageOverrideFlags as dt, createFileWatcher as en, resolveRuntimeFileExtension as er, buildEcsImageResolutionContext$1 as et, filterStudioCustomResources as f, resolveServiceIntegrationParameters as fn, resolveCfnRegion as fr, resolveImageOverrides as ft, startStudioServer as g, createJwksCache as gn, resolveSsmParameters as gr, listPinnedTargets as gt, filterStudioTargetGroups as h, buildJwksUrlFromIssuer as hn, collectSsmParameterRefs as hr, isLocalCdkAssetImage as ht, coerceStopRequest as i, resolveEnvVars$1 as in, substituteAgainstStateAsync as ir, resolveEcsAssumeRoleOption as it, serveFromStaticOrigin as j, matchRoute as jn, AGENTCORE_AGUI_PROTOCOL as jr, MCP_PATH as jt, matchBehavior as k, isFunctionUrlOacFronted as kn, resolveLambdaArnIntrinsic as kr, a2aInvokeOnce as kt, relayServeRequest as l, readMtlsMaterialsFromDisk as ln, isCfnFlagPresent as lr, enforceImageOverrideOrphans as lt, annotatePinnedEcsTargets as m, buildCognitoJwksUrl as mn, CfnLocalStateProvider as mr, describePinnedImageUri as mt, coerceRunRequest as n, buildStageMap as nn, EcsTaskResolutionError as nr, parseMaxTasks as nt, resolveServeBaseUrl as o, filterRoutesByApiIdentifier as on, substituteEnvVarsFromStateAsync as or, runEcsServiceEmulator as ot, isCustomResourceLambdaTarget as p, defaultCredentialsLoader as pn, resolveCfnStackName as pr, runImageOverrideBuilds as pt, serviceStrategy as q, parseConnectionsPath as qn, addInvokeSpecificOptions as qt, coerceServeRequest as r, materializeLayerFromArn as rn, substituteAgainstState as rr, parseRestartPolicy as rt, createStudioServeManager as s, filterRoutesByApiIdentifiers as sn, LocalStateSourceError as sr, ImageOverrideError as st, addStudioSpecificOptions as t, attachStageContext as tn, resolveRuntimeImage as tr, ecsClusterOption as tt, reinvoke as u, startApiServer as un, rejectExplicitCfnStackWithMultipleStacks as ur, mergeForService as ut, renderStudioHtml as v, verifyJwtAuthorizer as vn, resolveSingleTarget as vr, CloudMapRegistry as vt, LocalStartCloudFrontError as w, invokeTokenAuthorizer as wn, filterWebSocketApisByIdentifiers as wr, addInvokeAgentCoreSpecificOptions as wt, addListSpecificOptions as x, computeRequestIdentityHash as xn, availableWebSocketApiIdentifiers as xr, setShadowReadyTimeoutMs as xt, createStudioStore as y, verifyJwtViaDiscovery as yn, countTargets as yr, DEFAULT_SHADOW_READY_TIMEOUT_MS as yt, albStrategy as z, tryParseStatus as zn, formatStateRemedy as zr, waitForAgentCorePing as zt };
33437
- //# sourceMappingURL=local-studio-COb3K0Br.js.map
33693
+ export { MAX_TASKS_SUBNET_RANGE_CAP as $, buildMessageEvent as $n, createLocalStartApiCommand as $t, startCloudFrontServer as A, buildCorsConfigByApiId as An, discoverRoutes as Ar, A2A_CONTAINER_PORT as At, runViewerResponse as B, pickResponseTemplate as Bn, resolveAgentCoreTarget as Br, AGENTCORE_SESSION_ID_HEADER as Bt, formatTargetListing as C, buildMethodArn as Cn, listTargets as Cr, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as Ct, parseOriginOverrides as D, invokeTokenAuthorizer as Dn, filterWebSocketApisByIdentifiers as Dr, addInvokeAgentCoreSpecificOptions as Dt, createLocalStartCloudFrontCommand as E, invokeRequestAuthorizer as En, discoverWebSocketApisOrThrow as Er, attachContainerLogStreamer as Et, pickFunctionUrlLogicalIdFromOrigin as F, translateLambdaResponse as Fn, AGENTCORE_HTTP_PROTOCOL as Fr, MCP_PROTOCOL_VERSION as Ft, resolveAlbTarget as G, probeHostGatewaySupport as Gn, LocalInvokeBuildError as Gr, buildAgentCoreCodeImage as Gt, albStrategy as H, tryParseStatus as Hn, formatStateRemedy as Hr, waitForAgentCorePing as Ht, pickTargetFunctionLogicalId as I, applyAuthorizerOverlay as In, AGENTCORE_MCP_PROTOCOL as Ir, mcpInvokeOnce as It, addStartServiceSpecificOptions as J, buildMgmtEndpointEnvUrl as Jn, toCmdArgv as Jt, isApplicationLoadBalancer as K, bufferToBody as Kn, buildStsClientConfig as Kr, computeCodeImageTag as Kt, resolveCloudFrontDistribution as L, buildHttpApiV2Event as Ln, AGENTCORE_RUNTIME_TYPE as Lr, parseSseForJsonRpc as Lt, serveLambdaUrlOrigin as M, isFunctionUrlOacFronted as Mn, resolveLambdaArnIntrinsic as Mr, a2aInvokeOnce as Mt, CLOUDFRONT_DISTRIBUTION_TYPE as N, matchPreflight as Nn, AGENTCORE_A2A_PROTOCOL as Nr, MCP_CONTAINER_PORT as Nt, resolveCloudFrontTarget as O, attachAuthorizers as On, parseSelectionExpressionPath as Or, createLocalInvokeAgentCoreCommand as Ot, isCloudFrontDistribution as P, matchRoute as Pn, AGENTCORE_AGUI_PROTOCOL as Pr, MCP_PATH as Pt, createLocalRunTaskCommand as Q, buildDisconnectEvent as Qn, addStartApiSpecificOptions as Qt, compileCloudFrontFunction as R, buildRestV1Event as Rn, AgentCoreResolutionError as Rr, AGENTCORE_SIGV4_SERVICE as Rt, createLocalListCommand as S, verifyJwtViaDiscovery as Sn, countTargets as Sr, DEFAULT_SHADOW_READY_TIMEOUT_MS as St, addStartCloudFrontSpecificOptions as T, evaluateCachedLambdaPolicy as Tn, discoverWebSocketApis as Tr, getContainerNetworkIp as Tt, createLocalStartAlbCommand as U, VtlEvaluationError as Un, substituteImagePlaceholders as Ur, downloadAndExtractS3Bundle as Ut, addAlbSpecificOptions as V, selectIntegrationResponse as Vn, derivePseudoParametersFromRegion as Vr, invokeAgentCore as Vt, parseLbPortOverrides as W, HOST_GATEWAY_MIN_VERSION as Wn, tryResolveImageFnJoin as Wr, SUPPORTED_CODE_RUNTIMES as Wt, serviceStrategy as X, parseConnectionsPath as Xn, addInvokeSpecificOptions as Xt, createLocalStartServiceCommand as Y, handleConnectionsRequest as Yn, classifySourceChange as Yt, addRunTaskSpecificOptions as Z, buildConnectEvent as Zn, createLocalInvokeCommand as Zt, toStudioTargetGroups as _, buildCognitoJwksUrl as _n, CfnLocalStateProvider as _r, describePinnedImageUri as _t, createLocalStudioCommand as a, buildStageMap as an, EcsTaskResolutionError as ar, parseMaxTasks as at, StudioEventBus as b, verifyCognitoJwt as bn, resolveWatchConfig as br, buildCloudMapIndex as bt, startStudioProxy as c, availableApiIdentifiers as cn, substituteEnvVarsFromState as cr, resolveSharedSidecarCredentials as ct, createStudioDispatcher as d, groupRoutesByServer as dn, createLocalStateProvider as dr, buildImageOverrideTag as dt, createWatchPredicates as en, architectureToPlatform as er, addCommonEcsServiceOptions as et, filterStudioCustomResources as f, readMtlsMaterialsFromDisk as fn, isCfnFlagPresent as fr, enforceImageOverrideOrphans as ft, startStudioServer as g, defaultCredentialsLoader as gn, resolveCfnStackName as gr, runImageOverrideBuilds as gt, filterStudioTargetGroups as h, resolveServiceIntegrationParameters as hn, resolveCfnRegion as hr, resolveImageOverrides as ht, coerceStopRequest as i, attachStageContext as in, resolveRuntimeImage as ir, ecsClusterOption as it, serveFromStaticOrigin as j, buildCorsConfigFromCloudFrontChain as jn, pickRefLogicalId as jr, A2A_PATH as jt, matchBehavior as k, applyCorsResponseHeaders as kn, webSocketApiMatchesIdentifier as kr, invokeAgentCoreWs as kt, relayServeRequest as l, filterRoutesByApiIdentifier as ln, substituteEnvVarsFromStateAsync as lr, runEcsServiceEmulator as lt, annotatePinnedEcsTargets as m, resolveSelectionExpression as mn, resolveCfnFallbackRegion as mr, parseImageOverrideFlags as mt, coerceRunRequest as n, createAuthorizerCache as nn, resolveRuntimeCodeMountPath as nr, addImageOverrideOptions as nt, resolveServeBaseUrl as o, materializeLayerFromArn as on, substituteAgainstState as or, parseRestartPolicy as ot, isCustomResourceLambdaTarget as p, startApiServer as pn, rejectExplicitCfnStackWithMultipleStacks as pr, mergeForService as pt, resolveAlbFrontDoor as q, ConnectionRegistry as qn, resolveProfileCredentials as qr, renderCodeDockerfile as qt, coerceServeRequest as r, createFileWatcher as rn, resolveRuntimeFileExtension as rr, buildEcsImageResolutionContext$1 as rt, createStudioServeManager as s, resolveEnvVars$1 as sn, substituteAgainstStateAsync as sr, resolveEcsAssumeRoleOption as st, addStudioSpecificOptions as t, resolveApiTargetSubset as tn, buildContainerImage as tr, addEcsAssumeRoleOptions as tt, reinvoke as u, filterRoutesByApiIdentifiers as un, LocalStateSourceError as ur, ImageOverrideError as ut, renderStudioHtml as v, buildJwksUrlFromIssuer as vn, collectSsmParameterRefs as vr, isLocalCdkAssetImage as vt, LocalStartCloudFrontError as w, computeRequestIdentityHash as wn, availableWebSocketApiIdentifiers as wr, setShadowReadyTimeoutMs as wt, addListSpecificOptions as x, verifyJwtAuthorizer as xn, resolveSingleTarget as xr, CloudMapRegistry as xt, createStudioStore as y, createJwksCache as yn, resolveSsmParameters as yr, listPinnedTargets as yt, runViewerRequest as z, evaluateResponseParameters as zn, pickAgentCoreCandidateStack as zr, signAgentCoreInvocation as zt };
33694
+ //# sourceMappingURL=local-studio-DG6aiOzK.js.map