@elysiajs/cors
Version:
Plugin for Elysia that for Cross Origin Requests (CORs)
168 lines (166 loc) • 5.91 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
cors: () => cors,
default: () => index_default
});
module.exports = __toCommonJS(index_exports);
var import_elysia = require("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 import_elysia.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;
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";
};
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);
if (preflight && request.method === "OPTIONS") {
return handleOption({
set,
request,
headers: isBun ? request.headers.toJSON() : (
// for non-Bun environments
Object.fromEntries(request.headers.entries())
)
});
}
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;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
cors
});