Files
vat-api.eu/node_modules/srvx/dist/adapters/aws-lambda.mjs
2026-02-13 22:02:30 +01:00

293 lines
9.1 KiB
JavaScript

import { r as wrapFetch, t as errorPlugin } from "../_chunks/_plugins.mjs";
function awsRequest(event, context) {
const req = new Request(awsEventURL(event), {
method: awsEventMethod(event),
headers: awsEventHeaders(event),
body: awsEventBody(event)
});
req.runtime = {
name: "aws-lambda",
awsLambda: {
event,
context
}
};
req.ip = awsEventIP(event);
return req;
}
function awsEventMethod(event) {
return event.httpMethod || event.requestContext?.http?.method || "GET";
}
function awsEventIP(event) {
return event.requestContext?.http?.sourceIp || event.requestContext?.identity?.sourceIp;
}
function awsEventURL(event) {
const hostname = event.headers.host || event.headers.Host || event.requestContext?.domainName || ".";
const path = event.path || event.rawPath;
const query = awsEventQuery(event);
const protocol = (event.headers["X-Forwarded-Proto"] || event.headers["x-forwarded-proto"]) === "http" ? "http" : "https";
return new URL(`${path}${query ? `?${query}` : ""}`, `${protocol}://${hostname}`);
}
function awsEventQuery(event) {
if (typeof event.rawQueryString === "string") return event.rawQueryString;
return stringifyQuery({
...event.queryStringParameters,
...event.multiValueQueryStringParameters
});
}
function awsEventHeaders(event) {
const headers = new Headers();
for (const [key, value] of Object.entries(event.headers)) if (value) headers.set(key, value);
if ("cookies" in event && event.cookies) for (const cookie of event.cookies) headers.append("cookie", cookie);
return headers;
}
function awsEventBody(event) {
if (!event.body) return;
if (event.isBase64Encoded) return Buffer.from(event.body || "", "base64");
return event.body;
}
function awsResponseHeaders(response, event) {
const headers = Object.create(null);
for (const [key, value] of response.headers) if (value) headers[key] = Array.isArray(value) ? value.join(",") : String(value);
const cookies = response.headers.getSetCookie();
if (cookies.length === 0) return { headers };
return event?.version === "2.0" || !!event?.requestContext?.http ? {
headers,
cookies
} : {
headers,
cookies,
multiValueHeaders: { "set-cookie": cookies }
};
}
async function awsResponseBody(response) {
if (!response.body) return { body: "" };
const buffer = await toBuffer(response.body);
return isTextType(response.headers.get("content-type") || "") ? { body: buffer.toString("utf8") } : {
body: buffer.toString("base64"),
isBase64Encoded: true
};
}
async function awsStreamResponse(response, responseStream, event) {
const metadata = {
statusCode: response.status,
...awsResponseHeaders(response, event)
};
if (!metadata.headers["transfer-encoding"]) metadata.headers["transfer-encoding"] = "chunked";
const writer = globalThis.awslambda.HttpResponseStream.from(responseStream, metadata);
if (!response.body) {
writer.end();
return;
}
try {
await streamToNodeStream(response.body, writer);
} finally {
writer.end();
}
}
async function streamToNodeStream(body, writer) {
const reader = body.getReader();
try {
let result = await reader.read();
while (!result.done) {
if (!writer.write(result.value)) await new Promise((resolve) => writer.once("drain", resolve));
result = await reader.read();
}
} finally {
reader.releaseLock();
}
}
function isTextType(contentType = "") {
return /^text\/|\/(javascript|json|xml)|utf-?8/i.test(contentType);
}
function toBuffer(data) {
return new Promise((resolve, reject) => {
const chunks = [];
data.pipeTo(new WritableStream({
write(chunk) {
chunks.push(chunk);
},
close() {
resolve(Buffer.concat(chunks));
},
abort(reason) {
reject(reason);
}
})).catch(reject);
});
}
function stringifyQuery(obj) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(obj)) {
if (value == null) continue;
if (Array.isArray(value)) for (const v of value) params.append(key, String(v));
else params.append(key, String(value));
}
return params.toString();
}
async function requestToAwsEvent(request) {
const url = new URL(request.url);
const headers = {};
const cookies = [];
for (const [key, value] of request.headers) {
if (key.toLowerCase() === "cookie") cookies.push(value);
headers[key] = value;
}
let body;
let isBase64Encoded = false;
if (request.body) {
const buffer = await toBuffer(request.body);
if (isTextType(request.headers.get("content-type") || "")) body = buffer.toString("utf8");
else {
body = buffer.toString("base64");
isBase64Encoded = true;
}
}
const now = Date.now();
return {
httpMethod: request.method,
path: url.pathname,
resource: url.pathname,
queryStringParameters: Object.fromEntries(url.searchParams),
multiValueQueryStringParameters: parseMultiValueQuery(url.searchParams),
pathParameters: void 0,
stageVariables: void 0,
multiValueHeaders: Object.fromEntries([...request.headers].map(([k, v]) => [k, [v]])),
version: "2.0",
rawPath: url.pathname,
rawQueryString: url.search.slice(1),
cookies: cookies.length > 0 ? cookies : void 0,
routeKey: `${request.method} ${url.pathname}`,
headers,
body: body ?? null,
isBase64Encoded,
requestContext: {
accountId: "000000000000",
apiId: "local",
resourceId: "local",
stage: "$default",
requestId: crypto.randomUUID(),
identity: {
sourceIp: "127.0.0.1",
userAgent: request.headers.get("user-agent") || "",
accessKey: null,
accountId: null,
apiKey: null,
apiKeyId: null,
caller: null,
clientCert: null,
cognitoAuthenticationProvider: null,
cognitoAuthenticationType: null,
cognitoIdentityId: null,
cognitoIdentityPoolId: null,
principalOrgId: null,
user: null,
userArn: null
},
resourcePath: url.pathname,
httpMethod: request.method,
path: url.pathname,
protocol: "HTTP/1.1",
requestTimeEpoch: now,
authorizer: void 0,
domainName: url.hostname,
http: {
method: request.method,
path: url.pathname,
protocol: "HTTP/1.1",
sourceIp: "127.0.0.1",
userAgent: request.headers.get("user-agent") || ""
},
routeKey: `${request.method} ${url.pathname}`,
time: new Date(now).toISOString(),
timeEpoch: now,
domainPrefix: url.hostname.split(".")[0]
}
};
}
function parseMultiValueQuery(params) {
const result = {};
for (const [key, value] of params) {
if (!result[key]) result[key] = [];
result[key].push(value);
}
return result;
}
function awsResultToResponse(result) {
if (typeof result === "string") return new Response(result, { status: 200 });
const headers = new Headers();
if (result.headers) {
for (const [key, value] of Object.entries(result.headers)) if (value !== void 0) headers.set(key, String(value));
}
if ("multiValueHeaders" in result && result.multiValueHeaders) {
for (const [key, values] of Object.entries(result.multiValueHeaders)) if (values) for (const value of values) headers.append(key, String(value));
}
if ("cookies" in result && result.cookies) for (const cookie of result.cookies) headers.append("set-cookie", cookie);
let body;
if (typeof result.body === "string") if (result.isBase64Encoded) body = Buffer.from(result.body, "base64");
else body = result.body;
const statusCode = typeof result.statusCode === "number" ? result.statusCode : 200;
return new Response(body, {
status: statusCode,
headers
});
}
function createMockContext() {
const id = crypto.randomUUID();
return {
callbackWaitsForEmptyEventLoop: true,
functionName: "local",
functionVersion: "$LATEST",
invokedFunctionArn: `arn:aws:lambda:us-east-1:000000000000:function:local`,
memoryLimitInMB: "128",
awsRequestId: id,
logGroupName: "/aws/lambda/local",
logStreamName: `${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}/[$LATEST]${id}`,
getRemainingTimeInMillis: () => 3e4,
done: () => {},
fail: () => {},
succeed: () => {}
};
}
function toLambdaHandler(options) {
const server = new AWSLambdaServer(options);
return (event, context) => server.fetch(event, context);
}
async function handleLambdaEvent(fetchHandler, event, context) {
const response = await fetchHandler(awsRequest(event, context));
return {
statusCode: response.status,
...awsResponseHeaders(response, event),
...await awsResponseBody(response)
};
}
async function handleLambdaEventWithStream(fetchHandler, event, responseStream, context) {
await awsStreamResponse(await fetchHandler(awsRequest(event, context)), responseStream, event);
}
async function invokeLambdaHandler(handler, request) {
return awsResultToResponse(await handler(await requestToAwsEvent(request), createMockContext()));
}
var AWSLambdaServer = class {
runtime = "aws-lambda";
options;
fetch;
constructor(options) {
this.options = {
...options,
middleware: [...options.middleware || []]
};
for (const plugin of options.plugins || []) plugin(this);
errorPlugin(this);
const fetchHandler = wrapFetch(this);
this.fetch = (event, context) => handleLambdaEvent(fetchHandler, event, context);
}
serve() {}
ready() {
return Promise.resolve().then(() => this);
}
close() {
return Promise.resolve();
}
};
export { handleLambdaEvent, handleLambdaEventWithStream, invokeLambdaHandler, toLambdaHandler };