diff --git a/src/setCookie.spec.ts b/src/setCookie.spec.ts new file mode 100644 index 00000000..513c65e5 --- /dev/null +++ b/src/setCookie.spec.ts @@ -0,0 +1,40 @@ +import 'isomorphic-fetch' +import { describe, expect, it } from 'vitest' +import { status } from './status' +import {setCookies} from "./setCookies"; + +describe('setCookies("name", "value"): Response', () => { + it('creates a response with the set-cookie header', async () => { + const response = status(200) + setCookies(response, {name: "name", value: "value"}) + expect(response.headers.get("set-cookie")).toBe("name=value") + }) + it('creates a response with multiple set-cookie headers', async () => { + const response = status(200) + setCookies(response, {name: "name", value: "value"}, {name: "name2", value: "value2"}) + expect(response.headers.get("set-cookie")).toBe("name=value, name2=value2") + }) + it('creates a response with the set-cookie header using options', async () => { + const response = status(200) + setCookies(response, {name: "name", value: "value", + httpOnly: true, + secure: true, + }) + expect(response.headers.get("set-cookie")).toBe("name=value; HttpOnly; Secure") + }) + it('creates a response with the set-cookie header using all options', async () => { + const response = status(200) + const now = new Date(); + setCookies(response, {name: "name", value: "value", + httpOnly: true, + secure: true, + expires: now, + maxAge: 1000, + path: "/", + domain: "itty.dev", + partitioned: true, + sameSite: "Strict" + }) + expect(response.headers.get("set-cookie")).toBe(`name=value; Domain=itty.dev; Path=/; HttpOnly; Secure; Expires=${now.toUTCString()}; Max-Age=1000; Partitioned; SameSite=Strict`) + }) +}) diff --git a/src/setCookies.ts b/src/setCookies.ts new file mode 100644 index 00000000..b1330e84 --- /dev/null +++ b/src/setCookies.ts @@ -0,0 +1,27 @@ +type CookieOptions = { + name: string; + value: string; + domain?: string; + path?: string; + expires?: Date; + httpOnly?: boolean; + maxAge?: number; + partitioned?: boolean; + secure?: boolean; + sameSite?: "Strict" | "Lax" | "None"; +} + +export const setCookies = (response: Response, ...cookies: CookieOptions[]): Response => { + for (let options of cookies) { + response.headers.append("Set-Cookie", `${options.name}=${options.value}\ +${options?.domain ? `; Domain=${options.domain}`: ""}\ +${options?.path ? `; Path=${options?.path}`: ""}\ +${options?.httpOnly ? `; HttpOnly`: ""}\ +${options?.secure ? `; Secure`: ""}\ +${options?.expires? `; Expires=${options.expires.toUTCString()}`: ""}\ +${options?.maxAge? `; Max-Age=${options.maxAge}`: ""}\ +${options?.partitioned? `; Partitioned`: ""}\ +${options?.sameSite? `; SameSite=${options.sameSite}`: ""}`) + } + return response; +}