import { Promisable } from "type-fest";
type Origin = boolean | string | RegExp | Array<string | RegExp>;
interface CORSOptions {
  /**
   * Configures the **Access-Control-Allow-Origin** CORS header.
   *
   * Possible values:
   * - true: Enable CORS for any origin (same as "*")
   * - false: Don't setup CORS
   * - string: Set to a specific origin, if set to "*" it will allow any origin
   * - RegExp: Set to a RegExp to match against the origin
   * - Array<string | RegExp>: Set to an array of origins to match against the
   *  string or RegExp
   * - Function: Set to a function that will be called with the request origin
   * and should return a boolean indicating if the origin is allowed or not.
   * @default true
   */
  origin?: Origin | ((origin: string) => Promisable<Origin>);
  /**
   * Configures the **Access-Control-Allow-Methods** CORS header.
   * @default ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"]
   */
  methods?: Array<string>;
  /**
   * Configures the **Access-Control-Allow-Headers** CORS header.
   * @default []
   */
  allowedHeaders?: string[];
  /**
   * Configures the **Access-Control-Expose-Headers** CORS header.
   * @default []
   */
  exposedHeaders?: string[];
  /**
   * Configures the **Access-Control-Allow-Credentials** CORS header.
   * @default false
   */
  credentials?: boolean;
  /**
   * Configures the **Access-Control-Max-Age** CORS header.
   * @default 0
   */
  maxAge?: number;
}
/**
 * Setup CORS for a giving Request and Response objects pair using the specified
 * options.
 *
 * The default options are:
 * - origin: true
 * - methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE"]
 * - allowedHeaders: []
 * - exposedHeaders: []
 * - credentials: false
 * - maxAge: 0
 *
 * @param request The Request object
 * @param response The Response object
 * @param options Optional configuration for CORS
 * @returns The same Response object mutated
 *
 * @example
 * // Create a response, then setup CORS for it
 * export async function loader({ request }: LoaderArgs) {
 *   let data = await getData(request);
 *   let response = json<LoaderData>(data);
 *   return await cors(request, response);
 * }
 * @example
 * // Create response and setup CORS in a single line
 * export async function loader({ request }: LoaderArgs) {
 *   let data = await getData(request);
 *   return await cors(request, json<LoaderData>(data));
 * }
 * @example
 * // Setup for any data request
 * export let handleDataRequest: HandleDataRequestFunction = async (
 *   response,
 *   { request }
 * ) => {
 *   return await cors(request, response);
 * };
 * @example
 * // Pass a configuration object to setup CORS
 * export async function loader({ request }: LoaderArgs) {
 *   let data = await getData(request);
 *   return await cors(request, json<LoaderData>(data), {
 *     origin: "https://example.com"
 *   });
 * }
 * @example
 * // Mutate response and then return it
 * export async function loader({ request }: LoaderArgs) {
 *   let data = await getData(request);
 *   let response = json<LoaderData>(data);
 *   await cors(request, response); // this mutates the Response object
 *   return response;
 * }
 */
export declare function cors(
  request: Request,
  response: Response,
  options?: CORSOptions
): Promise<Response>;
export {};
