/** * Copyright (c) 2026 AzerothJS. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * Cross-Origin Resource Sharing at the edge. * * CORS is two responsibilities and this middleware owns both. A preflight (an OPTIONS with an * Access-Control-Request-Method) is answered HERE with 204 and the negotiated headers, but it * still traverses the inner middleware first, so metering wired inside this layer (a rate * limiter) counts every preflight; only the inner response is discarded - routes do not * implement the browser's bookkeeping. A real cross-origin request runs the app, and the CORS * response headers are added to whatever it returned. * * The origin decision is one predicate: an exact string, an allowlist, a function, or `true` * to reflect any origin. Origin is attacker-controlled (browsers send the literal `null` for * sandboxed frames, data: and file: documents), so a throwing predicate is a denial, never a * rejection. Credentials refuse `origin: true` at wiring time - reflecting every origin with * credentials hands authenticated bodies to any site, which is strictly worse than the `*` * the spec forbids - and no origin form under credentials ever allows the shared `null` * origin: a literal `'null'` entry is refused at wiring time, a predicate match is denied. * `Vary: Origin` is appended - never overwritten - on every path, the no-Origin one included, * so a cache keyed on it stays correct alongside the compression layer's own `Vary`. */ import { type EdgeMiddleware } from './edge.ts'; /** * What {@link CorsOptions.origin} accepts: one exact origin, a list, `true` (reflect any * origin - credentials stay OFF), or a predicate over the caller's `Origin` header value. */ export type CorsOrigin = string | string[] | boolean | ((origin: string) => boolean); /** * Options for {@link cors}. The posture is deny-by-default: only what `origin` admits is * reflected, and `credentials` never combines with a wildcard - the browser would refuse it * and the pairing is exactly how private APIs leak to arbitrary sites. */ export interface CorsOptions { /** Allowed origin(s): an exact string, an allowlist, a predicate, or `true` to reflect any. */ origin: CorsOrigin; /** Methods advertised on preflight (default GET, HEAD, PUT, PATCH, POST, DELETE). */ methods?: string[]; /** Allowed request headers on preflight (default: the CORS safelist - Accept, Accept-Language, Content-Language, Content-Type). */ allowedHeaders?: string[]; /** Response headers a browser may read beyond the safelisted set. */ exposedHeaders?: string[]; /** Send Access-Control-Allow-Credentials (default false). Refuses `origin: true` and the `null` origin. */ credentials?: boolean; /** Preflight cache lifetime in seconds (default 600). */ maxAgeSeconds?: number; } /** * Cross-Origin Resource Sharing. Answers preflights directly and decorates real cross-origin * responses; same-origin requests (no Origin header) pass through unchanged. */ export declare function cors(options: CorsOptions): EdgeMiddleware;