@elysiajs/cors
Version:
Plugin for Elysia that for Cross Origin Requests (CORs)
136 lines (135 loc) • 4.72 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 = "";
let i = 0;
headers.forEach((_, key) => {
if (i) keys = keys + ", " + key;
else keys = key;
i++;
});
return keys;
};
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 originMap = {};
if (origins) {
for (const origin2 of origins)
if (typeof origin2 === "string") originMap[origin2] = true;
}
const processOrigin = (origin2, request, from) => {
if (Array.isArray(origin2))
return origin2.some((o) => processOrigin(o, request, from));
switch (typeof origin2) {
case "string":
if (from in originMap) return true;
const fromProtocol = from.indexOf("://");
if (fromProtocol !== -1) from = from.slice(fromProtocol + 3);
return origin2 === from;
case "function":
return origin2(request) === true;
case "object":
if (origin2 instanceof RegExp) return origin2.test(from);
}
return false;
};
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;
}
}
}
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
};