@elysiajs/cors
Version:
Plugin for Elysia that for Cross Origin Requests (CORs)
128 lines (127 loc) • 4.46 kB
JavaScript
// src/index.ts
import { Elysia } from "elysia";
var isBun = typeof new Headers()?.toJSON === "function";
var processHeaders = (headers) => {
if (isBun) return Object.keys(headers.toJSON()).join(", ");
let keys = "";
headers.forEach((_, key) => {
keys += key + ", ";
});
if (keys) keys = keys.slice(0, -1);
return keys;
};
var processOrigin = (origin, request, from) => {
if (Array.isArray(origin))
return origin.some((o) => processOrigin(o, request, from));
switch (typeof origin) {
case "string":
if (origin.indexOf("://") === -1) return from.includes(origin);
return origin === from;
case "function":
return origin(request) === true;
case "object":
if (origin instanceof RegExp) return origin.test(from);
}
return false;
};
var cors = (config) => {
let {
aot = true,
origin = true,
methods = true,
allowedHeaders = true,
exposeHeaders = true,
credentials = true,
maxAge = 5,
preflight = true
} = config ?? {};
if (Array.isArray(allowedHeaders))
allowedHeaders = allowedHeaders.join(", ");
if (Array.isArray(exposeHeaders)) exposeHeaders = exposeHeaders.join(", ");
const origins = typeof origin === "boolean" ? void 0 : Array.isArray(origin) ? origin : [origin];
const app = new Elysia({
name: "@elysiajs/cors",
seed: config,
aot
});
const anyOrigin = origins?.some((o) => o === "*");
const handleOrigin = (set, request) => {
if (origin === true) {
set.headers.vary = "*";
set.headers["access-control-allow-origin"] = request.headers.get("Origin") || "*";
return;
}
if (anyOrigin) {
set.headers.vary = "*";
set.headers["access-control-allow-origin"] = "*";
return;
}
if (!origins?.length) return;
const headers = [];
if (origins.length) {
const from = request.headers.get("Origin") ?? "";
for (let i = 0; i < origins.length; i++) {
const value = processOrigin(origins[i], request, from);
if (value === true) {
set.headers.vary = origin ? "Origin" : "*";
set.headers["access-control-allow-origin"] = from || "*";
return;
}
if (value) headers.push(value);
}
}
set.headers.vary = "Origin";
if (headers.length)
set.headers["access-control-allow-origin"] = headers.join(", ");
};
const handleMethod = (set, method) => {
if (!method) return;
if (methods === true)
return set.headers["access-control-allow-methods"] = method ?? "*";
if (methods === false || !methods?.length) return;
if (methods === "*")
return set.headers["access-control-allow-methods"] = "*";
if (!Array.isArray(methods))
return set.headers["access-control-allow-methods"] = methods;
set.headers["access-control-allow-methods"] = methods.join(", ");
};
const defaultHeaders = {};
if (typeof exposeHeaders === "string")
defaultHeaders["access-control-expose-headers"] = exposeHeaders;
if (typeof allowedHeaders === "string")
defaultHeaders["access-control-allow-headers"] = allowedHeaders;
if (credentials === true)
defaultHeaders["access-control-allow-credentials"] = "true";
app.headers(defaultHeaders);
function handleOption({ set, request, headers }) {
handleOrigin(set, request);
handleMethod(set, request.headers.get("access-control-request-method"));
if (allowedHeaders === true || exposeHeaders === true) {
if (allowedHeaders === true)
set.headers["access-control-allow-headers"] = headers["access-control-request-headers"];
if (exposeHeaders === true)
set.headers["access-control-expose-headers"] = Object.keys(headers).join(",");
}
if (maxAge) set.headers["access-control-max-age"] = maxAge.toString();
return new Response(null, {
status: 204
});
}
if (preflight) app.options("/", handleOption).options("/*", handleOption);
return app.onRequest(function processCors({ set, request }) {
handleOrigin(set, request);
handleMethod(set, request.method);
if (allowedHeaders === true || exposeHeaders === true) {
const headers = processHeaders(request.headers);
if (allowedHeaders === true)
set.headers["access-control-allow-headers"] = headers;
if (exposeHeaders === true)
set.headers["access-control-expose-headers"] = headers;
}
});
};
var index_default = cors;
export {
cors,
index_default as default
};