diff --git a/src/utils/__snapshots__/helpers.spec.ts.snap b/src/utils/__snapshots__/helpers.spec.ts.snap new file mode 100644 index 0000000..78715ac --- /dev/null +++ b/src/utils/__snapshots__/helpers.spec.ts.snap @@ -0,0 +1,24 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`helpers > parseCookieHeader > should parse a Cookie header 1`] = `[]`; + +exports[`helpers > parseCookieHeader > should parse a Cookie header 2`] = ` +[ + { + "name": "a", + "value": "b", + }, + { + "name": "c", + "value": " hello ", + }, + { + "name": "e", + "value": "f", + }, +] +`; + +exports[`helpers > serializeCookieHeader > should serialize a cookie to a Set-Cookie header 1`] = `"a=; Max-Age=123; Path=/; HttpOnly; Secure"`; + +exports[`helpers > serializeCookieHeader > should serialize a cookie to a Set-Cookie header 2`] = `"b=%20weird%20value; Max-Age=345"`; diff --git a/src/utils/helpers.spec.ts b/src/utils/helpers.spec.ts new file mode 100644 index 0000000..6365928 --- /dev/null +++ b/src/utils/helpers.spec.ts @@ -0,0 +1,36 @@ +import { describe, it, expect } from "vitest"; + +import { + serialize, + parse, + // intentionally importing ^ to make sure they're exported, remove in v1.0.0 + parseCookieHeader, + serializeCookieHeader, +} from "./helpers"; + +describe("helpers", () => { + describe("parseCookieHeader", () => { + it("should parse a Cookie header", () => { + expect(parseCookieHeader("")).toMatchSnapshot(); + expect( + parseCookieHeader(`a=b;c=${encodeURIComponent(" hello ")};e=f`), + ).toMatchSnapshot(); + }); + }); + + describe("serializeCookieHeader", () => { + it("should serialize a cookie to a Set-Cookie header", () => { + expect( + serializeCookieHeader("a", "", { + path: "/", + maxAge: 123, + httpOnly: true, + secure: true, + }), + ).toMatchSnapshot(); + expect( + serializeCookieHeader("b", " weird value", { maxAge: 345 }), + ).toMatchSnapshot(); + }); + }); +}); diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index fef3027..cce85c6 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -1,4 +1,50 @@ -export { parse, serialize } from "cookie"; +import type { CookieSerializeOptions } from "cookie"; +import { parse as cookieParse, serialize as cookieSerialize } from "cookie"; + +/** + * @deprecated Since v0.4.0: Please use {@link parseCookieHeader}. `parse` will + * not be available for import starting v1.0.0 of `@supabase/ssr`. + */ +export const parse = cookieParse; + +/** + * @deprecated Since v0.4.0: Please use {@link serializeCookieHeader}. + * `serialize` will not be available for import starting v1.0.0 of + * `@supabase/ssr`. + */ +export const serialize = cookieSerialize; + +/** + * Parses the `Cookie` HTTP header into an array of cookie name-value objects. + * + * @param header The `Cookie` HTTP header. Decodes cookie names and values from + * URI encoding first. + */ +export function parseCookieHeader( + header: string, +): { name: string; value: string }[] { + const parsed = cookieParse(header); + + return Object.keys(parsed ?? {}).map((name) => ({ + name, + value: parsed[name], + })); +} + +/** + * Converts the arguments to a valid `Set-Cookie` header. Non US-ASCII chars + * and other forbidden cookie chars will be URI encoded. + * + * @param name Name of cookie. + * @param value Value of cookie. + */ +export function serializeCookieHeader( + name: string, + value: string, + options: CookieSerializeOptions, +): string { + return cookieSerialize(name, value, options); +} export function isBrowser() { return (