117 lines
4.2 KiB
Plaintext
117 lines
4.2 KiB
Plaintext
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
|
|
const require_utils_encode = require("../../utils/encode.js");
|
|
let node_crypto = require("node:crypto");
|
|
node_crypto = require_runtime.__toESM(node_crypto, 1);
|
|
//#region src/adapter/lambda-edge/handler.ts
|
|
globalThis.crypto ??= node_crypto.default;
|
|
/**
|
|
* Accepts events from 'Lambda@Edge' event
|
|
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html
|
|
*/
|
|
const convertHeaders = (headers) => {
|
|
const cfHeaders = {};
|
|
headers.forEach((value, key) => {
|
|
cfHeaders[key.toLowerCase()] = [...cfHeaders[key.toLowerCase()] || [], {
|
|
key: key.toLowerCase(),
|
|
value
|
|
}];
|
|
});
|
|
return cfHeaders;
|
|
};
|
|
/**
|
|
* @deprecated `hono/lambda-edge` will be removed in v5. Install `@hono/lambda-edge` and import from there instead.
|
|
*/
|
|
const handle = (app) => {
|
|
return async (event, ...args) => {
|
|
const [context, callback] = args;
|
|
let callbackError = null;
|
|
let callbackResult;
|
|
const cf = getCloudFrontRecord(event);
|
|
const res = await app.fetch(createRequest(cf), {
|
|
event,
|
|
context,
|
|
callback: (err, result) => {
|
|
if (!callbackError && !callbackResult) {
|
|
callbackError = err;
|
|
callbackResult = result;
|
|
}
|
|
callback?.(err, result);
|
|
},
|
|
config: cf.config,
|
|
request: cf.request,
|
|
response: cf.response
|
|
});
|
|
if (callbackError) throw callbackError;
|
|
return callbackResult ?? createResult(res);
|
|
};
|
|
};
|
|
const createResult = async (res) => {
|
|
const contentEncoding = res.headers.get("content-encoding");
|
|
const isBase64Encoded = isContentTypeBinary(res.headers.get("content-type") || "") || !!contentEncoding && !/^identity$/i.test(contentEncoding);
|
|
const body = isBase64Encoded ? require_utils_encode.encodeBase64(await res.arrayBuffer()) : await res.text();
|
|
return {
|
|
status: res.status.toString(),
|
|
headers: convertHeaders(res.headers),
|
|
body,
|
|
...isBase64Encoded && { bodyEncoding: "base64" }
|
|
};
|
|
};
|
|
/**
|
|
* Reads the CloudFront record out of a Lambda@Edge event.
|
|
*
|
|
* The event is supplied by the runtime, so a malformed one means the function
|
|
* was invoked with something other than a Lambda@Edge event. Fail with a
|
|
* message naming the adapter and the missing field, rather than letting an
|
|
* unattributable property access error escape.
|
|
*/
|
|
const getCloudFrontRecord = (event) => {
|
|
const cf = event?.Records?.[0]?.cf;
|
|
if (!cf?.request) throw new TypeError("Unable to map the CloudFront event to a Request: expected `Records[0].cf.request` in the Lambda@Edge event.");
|
|
return cf;
|
|
};
|
|
const createRequest = (cf) => {
|
|
const request = cf.request;
|
|
const queryString = request.querystring;
|
|
const urlPath = `https://${request.headers?.host?.[0]?.value || cf.config?.distributionDomainName}${request.uri}`;
|
|
const url = queryString ? `${urlPath}?${queryString}` : urlPath;
|
|
const headers = new Headers();
|
|
Object.entries(request.headers ?? {}).forEach(([k, v]) => {
|
|
v.forEach((header) => headers.append(k, header.value));
|
|
});
|
|
const requestBody = request.body;
|
|
const method = request.method;
|
|
const rawBody = createBody(method, requestBody);
|
|
let body = rawBody;
|
|
if (rawBody !== void 0) {
|
|
const bytes = typeof rawBody === "string" ? new TextEncoder().encode(rawBody) : rawBody;
|
|
body = bytes;
|
|
headers.set("content-length", bytes.length.toString());
|
|
}
|
|
return new Request(url, {
|
|
headers,
|
|
method,
|
|
body
|
|
});
|
|
};
|
|
/**
|
|
* @deprecated `hono/lambda-edge` will be removed in v5. Install `@hono/lambda-edge` and import from there instead.
|
|
*/
|
|
const createBody = (method, requestBody) => {
|
|
if (!requestBody || !requestBody.data) return;
|
|
if (method === "GET" || method === "HEAD") return;
|
|
if (requestBody.encoding === "base64") return require_utils_encode.decodeBase64(requestBody.data);
|
|
return requestBody.data;
|
|
};
|
|
/**
|
|
* @deprecated `hono/lambda-edge` will be removed in v5. Install `@hono/lambda-edge` and import from there instead.
|
|
*/
|
|
const isContentTypeBinary = (contentType) => {
|
|
if (/^application\/vnd\.(?:apple\.installer|mozilla\.xul)\+xml\s*(?:;|$)/i.test(contentType)) return true;
|
|
return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/i.test(contentType);
|
|
};
|
|
//#endregion
|
|
exports.createBody = createBody;
|
|
exports.handle = handle;
|
|
exports.isContentTypeBinary = isContentTypeBinary;
|