Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions lib/set-cookie.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
export interface Cookie {
/** Cookie name */
name: string;
/** Cookie value */
value: string;
/** Cookie path */
path?: string;
/** Absolute expiration date for the cookie */
expires?: Date;
/**
* Relative max age of the cookie in seconds from when the client receives it.
* Note: when using with express's res.cookie() method, multiply maxAge by 1000 to convert to milliseconds.
*/
maxAge?: number;
/**
* Domain for the cookie,
* may begin with "." to indicate the named domain or any subdomain of it
*/
domain?: string;
/** Indicates that this cookie should only be sent over HTTPS */
secure?: boolean;
/** Indicates that this cookie should not be accessible to client-side JavaScript */
httpOnly?: boolean;
/** Indicates a cookie ought not to be sent along with cross-site requests */
sameSite?: string;
/** Indicates the cookie should be stored using partitioned storage */
partitioned?: boolean;
}

export interface CookieMap {
[name: string]: Cookie;
}

export interface Options {
/**
* Calls decodeURIComponent on each value.
* @default true
*/
decodeValues?: boolean;
/**
* Return an object instead of an array.
* @default false
*/
map?: boolean;
/**
* Suppress the warning that is logged when called on a request instead of a response.
* @default false
*/
silent?: boolean;
/**
* Controls whether combined cookie strings are split.
* - `true`: always split
* - `false`: never split
* - `"auto"`: split strings but not arrays
* @default "auto"
*/
split?: boolean | "auto";
}

/** Object with a `headers` property (e.g. Node.js IncomingMessage or fetch Response) */
type ResponseLike = {
headers:
| { getSetCookie(): string[] }
| { "set-cookie"?: string | readonly string[] }
| Record<string, string | string[] | undefined>;
};

type SetCookieInput = string | readonly string[] | ResponseLike;

/**
* Parses set-cookie headers into objects.
*/
export function parseSetCookie(
input: SetCookieInput,
options: Options & { map: true }
): CookieMap;
export function parseSetCookie(
input: SetCookieInput,
options?: Options & { map?: false }
): Cookie[];
export function parseSetCookie(
input: SetCookieInput,
options?: Options
): Cookie[] | CookieMap;

/**
* Parses a single set-cookie header value string.
* @deprecated Use `parseSetCookie` instead.
*/
export function parseString(
setCookieValue: string,
options?: Options
): Cookie | null;

/**
* Splits a combined set-cookie header string into individual set-cookie header strings.
* @deprecated Use `parseSetCookie` with the `split` option instead.
*/
export function splitCookiesString(
input: string | readonly string[] | undefined
): string[];

/**
* @deprecated Renamed to `parseSetCookie`. Kept for backward compatibility.
*/
export {
parseSetCookie as parse,
};

/**
* Default export — the `parseSetCookie` function with additional properties for backward compatibility.
*/
declare const _default: typeof parseSetCookie & {
parseSetCookie: typeof parseSetCookie;
parse: typeof parseSetCookie;
parseString: typeof parseString;
splitCookiesString: typeof splitCookiesString;
};
export default _default;
97 changes: 97 additions & 0 deletions lib/set-cookie.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { expectType, expectError } from "tsd";
import setCookieParser, {
parseSetCookie,
parse,
parseString,
splitCookiesString,
Cookie,
CookieMap,
Options,
} from "./set-cookie.js";

// --- parseSetCookie: return type overloads ---

// Default returns Cookie[]
expectType<Cookie[]>(parseSetCookie("foo=bar"));

// map: true returns CookieMap
expectType<CookieMap>(parseSetCookie("foo=bar", { map: true }));

// map: false returns Cookie[]
expectType<Cookie[]>(parseSetCookie("foo=bar", { map: false }));

// --- parseSetCookie: input types ---

// String input
parseSetCookie("foo=bar");

// Array input
parseSetCookie(["foo=bar", "baz=qux"]);

// Readonly array input
parseSetCookie(["foo=bar"] as readonly string[]);

// Object with headers.getSetCookie (fetch Response-like)
parseSetCookie({ headers: { getSetCookie: () => ["foo=bar"] } });

// Object with headers["set-cookie"] (Node.js IncomingMessage-like)
parseSetCookie({ headers: { "set-cookie": ["foo=bar"] } });

// --- Options ---

// split option accepts boolean or "auto"
parseSetCookie("foo=bar", { split: true });
parseSetCookie("foo=bar", { split: false });
parseSetCookie("foo=bar", { split: "auto" });

// decodeValues option
parseSetCookie("foo=bar", { decodeValues: false });

// silent option
parseSetCookie("foo=bar", { silent: true });

// --- Cookie properties ---

const cookies = parseSetCookie("foo=bar");
const cookie = cookies[0];

expectType<string>(cookie.name);
expectType<string>(cookie.value);
expectType<string | undefined>(cookie.path);
expectType<Date | undefined>(cookie.expires);
expectType<number | undefined>(cookie.maxAge);
expectType<string | undefined>(cookie.domain);
expectType<boolean | undefined>(cookie.secure);
expectType<boolean | undefined>(cookie.httpOnly);
expectType<string | undefined>(cookie.sameSite);
expectType<boolean | undefined>(cookie.partitioned);

// --- parseString ---

const single = parseString("foo=bar");
expectType<Cookie | null>(single);

// --- splitCookiesString ---

const parts = splitCookiesString("foo=bar, baz=qux");
expectType<string[]>(parts);

// Accepts undefined
splitCookiesString(undefined);

// Accepts array (passthrough)
splitCookiesString(["foo=bar"]);

// --- parse (deprecated alias) ---

expectType<Cookie[]>(parse("foo=bar"));
expectType<CookieMap>(parse("foo=bar", { map: true }));

// --- Default export ---

expectType<Cookie[]>(setCookieParser("foo=bar"));
expectType<CookieMap>(setCookieParser("foo=bar", { map: true }));
setCookieParser.parseSetCookie("foo=bar");
setCookieParser.parse("foo=bar");
setCookieParser.parseString("foo=bar");
setCookieParser.splitCookiesString("foo=bar");
Loading
Loading