import * as http from 'http';
import { CookieSerializeOptions } from 'cookie';

type PasswordsMap = Record<string, string>;
type Password = PasswordsMap | string;
/**
 * {@link https://wicg.github.io/cookie-store/#dictdef-cookielistitem CookieListItem}
 * as specified by W3C.
 */
interface CookieListItem extends Pick<CookieSerializeOptions, "domain" | "path" | "sameSite" | "secure"> {
    /** A string with the name of a cookie. */
    name: string;
    /** A string containing the value of the cookie. */
    value: string;
    /** A number of milliseconds or Date interface containing the expires of the cookie. */
    expires?: CookieSerializeOptions["expires"] | number;
}
/**
 * Superset of {@link CookieListItem} extending it with
 * the `httpOnly`, `maxAge` and `priority` properties.
 */
type ResponseCookie = CookieListItem & Pick<CookieSerializeOptions, "httpOnly" | "maxAge" | "priority">;
/**
 * The high-level type definition of the .get() and .set() methods
 * of { cookies() } from "next/headers"
 */
interface CookieStore {
    get: (name: string) => {
        name: string;
        value: string;
    } | undefined;
    set: {
        (name: string, value: string, cookie?: Partial<ResponseCookie>): void;
        (options: ResponseCookie): void;
    };
}
/**
 * Set-Cookie Attributes do not include `encode`. We omit this from our `cookieOptions` type.
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
 * @see https://developer.chrome.com/docs/devtools/application/cookies/
 */
type CookieOptions = Omit<CookieSerializeOptions, "encode">;
interface SessionOptions {
    /**
     * The cookie name that will be used inside the browser. Make sure it's unique
     * given your application.
     *
     * @example 'vercel-session'
     */
    cookieName: string;
    /**
     * The password(s) that will be used to encrypt the cookie. Can either be a string
     * or an object.
     *
     * When you provide multiple passwords then all of them will be used to decrypt
     * the cookie. But only the most recent (`= highest key`, `2` in the example)
     * password will be used to encrypt the cookie. This allows password rotation.
     *
     * @example { 1: 'password-1', 2: 'password-2' }
     */
    password: Password;
    /**
     * The time (in seconds) that the session will be valid for. Also sets the
     * `max-age` attribute of the cookie automatically (`= ttl - 60s`, so that the
     * cookie always expire before the session).
     *
     * `ttl = 0` means no expiration.
     *
     * @default 1209600
     */
    ttl?: number;
    /**
     * The options that will be passed to the cookie library.
     *
     * If you want to use "session cookies" (cookies that are deleted when the browser
     * is closed) then you need to pass `cookieOptions: { maxAge: undefined }`
     *
     * @see https://github.com/jshttp/cookie#options-1
     */
    cookieOptions?: CookieOptions;
}
type IronSession<T> = T & {
    /**
     * Encrypts the session data and sets the cookie.
     */
    readonly save: () => Promise<void>;
    /**
     * Destroys the session data and removes the cookie.
     */
    readonly destroy: () => void;
    /**
     * Update the session configuration. You still need to call save() to send the new cookie.
     */
    readonly updateConfig: (newSessionOptions: SessionOptions) => void;
};

declare const sealData: (data: unknown, { password, ttl, }: {
    password: string | {
        [x: string]: string;
    };
    ttl?: number;
}) => Promise<string>;
declare const unsealData: <T>(seal: string, { password, ttl, }: {
    password: string | {
        [x: string]: string;
    };
    ttl?: number;
}) => Promise<T>;
declare const getIronSession: {
    <T extends object>(cookies: CookieStore, sessionOptions: SessionOptions): Promise<IronSession<T>>;
    <T extends object>(req: http.IncomingMessage | Request, res: Response | http.ServerResponse<http.IncomingMessage>, sessionOptions: SessionOptions): Promise<IronSession<T>>;
};

export { type IronSession, type SessionOptions, getIronSession, sealData, unsealData };
