Files
SnowLuma/.pnpm-store/v11/files/e5/265af6fadbca1571a78e9083bbdf0ed37e12f2cb202bfa9342d3afd314b4dce3b4df74386bd983a7582128bdbd3d88da6147260b299cb0b5d6368756b6b237
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

110 lines
4.2 KiB
Plaintext

Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#region src/middleware/cors/index.ts
/**
* CORS Middleware for Hono.
*
* @see {@link https://hono.dev/docs/middleware/builtin/cors}
*
* @param {CORSOptions} [options] - The options for the CORS middleware.
* @param {string | string[] | ((origin: string, c: Context) => Promise<string | undefined | null> | string | undefined | null)} [options.origin='*'] - The value of "Access-Control-Allow-Origin" CORS header.
* @param {string[] | ((origin: string, c: Context) => Promise<string[]> | string[])} [options.allowMethods=['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH', 'QUERY']] - The value of "Access-Control-Allow-Methods" CORS header.
* @param {string[]} [options.allowHeaders=[]] - The value of "Access-Control-Allow-Headers" CORS header.
* @param {number} [options.maxAge] - The value of "Access-Control-Max-Age" CORS header.
* @param {boolean} [options.credentials] - The value of "Access-Control-Allow-Credentials" CORS header.
* @param {string[]} [options.exposeHeaders=[]] - The value of "Access-Control-Expose-Headers" CORS header.
* @returns {MiddlewareHandler} The middleware handler function.
*
* @example
* ```ts
* const app = new Hono()
*
* app.use('/api/*', cors())
* app.use(
* '/api2/*',
* cors({
* origin: 'http://example.com',
* allowHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests'],
* allowMethods: ['POST', 'GET', 'OPTIONS'],
* exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
* maxAge: 600,
* credentials: true,
* })
* )
*
* app.all('/api/abc', (c) => {
* return c.json({ success: true })
* })
* app.all('/api2/abc', (c) => {
* return c.json({ success: true })
* })
* ```
*/
const cors = (options) => {
const opts = {
origin: "*",
allowMethods: [
"GET",
"HEAD",
"PUT",
"POST",
"DELETE",
"PATCH",
"QUERY"
],
allowHeaders: [],
exposeHeaders: [],
...options
};
const exposeHeadersStr = opts.exposeHeaders?.length ? opts.exposeHeaders.join(",") : void 0;
const allowHeadersStr = opts.allowHeaders?.length ? opts.allowHeaders.join(",") : void 0;
const findAllowOrigin = ((optsOrigin) => {
if (typeof optsOrigin === "string") {
if (optsOrigin === "*") return () => optsOrigin;
else return (origin) => optsOrigin === origin ? origin : null;
} else if (typeof optsOrigin === "function") return optsOrigin;
else return (origin) => optsOrigin.includes(origin) ? origin : null;
})(opts.origin);
const findAllowMethods = ((optsAllowMethods) => {
if (typeof optsAllowMethods === "function") return async (origin, c) => (await optsAllowMethods(origin, c)).join(",");
else if (Array.isArray(optsAllowMethods)) {
const methodsStr = optsAllowMethods.join(",");
return () => methodsStr;
} else return () => "";
})(opts.allowMethods);
return async function cors(c, next) {
function set(key, value) {
c.res.headers.set(key, value);
}
const allowOrigin = await findAllowOrigin(c.req.header("origin") || "", c);
if (allowOrigin) set("Access-Control-Allow-Origin", allowOrigin);
if (opts.credentials) set("Access-Control-Allow-Credentials", "true");
if (exposeHeadersStr) set("Access-Control-Expose-Headers", exposeHeadersStr);
if (c.req.method === "OPTIONS") {
if (opts.origin !== "*") c.res.headers.append("Vary", "Origin");
if (opts.maxAge != null) set("Access-Control-Max-Age", opts.maxAge.toString());
const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
if (allowMethods) set("Access-Control-Allow-Methods", allowMethods);
let headersStr = allowHeadersStr;
if (!headersStr) {
const requestHeaders = c.req.header("Access-Control-Request-Headers");
if (requestHeaders) headersStr = requestHeaders.split(",").map((h) => h.trim()).join(",");
}
if (headersStr) {
set("Access-Control-Allow-Headers", headersStr);
c.res.headers.append("Vary", "Access-Control-Request-Headers");
}
c.res.headers.delete("Content-Length");
c.res.headers.delete("Content-Type");
return new Response(null, {
headers: c.res.headers,
status: 204,
statusText: "No Content"
});
}
await next();
if (opts.origin !== "*") c.header("Vary", "Origin", { append: true });
};
};
//#endregion
exports.cors = cors;