Skip to content

Commit

Permalink
feat(cookies): add partitioned attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
rezof committed Mar 5, 2024
1 parent ee55789 commit 7a13394
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/new-jars-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@edge-runtime/cookies': minor
---

Add cookies partitioned attribute
3 changes: 3 additions & 0 deletions packages/cookies/src/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function stringifyCookie(c: ResponseCookie | RequestCookie): string {
'secure' in c && c.secure && 'Secure',
'httpOnly' in c && c.httpOnly && 'HttpOnly',
'sameSite' in c && c.sameSite && `SameSite=${c.sameSite}`,
'partitioned' in c && c.partitioned && 'Partitioned',
'priority' in c && c.priority && `Priority=${c.priority}`,
].filter(Boolean)

Expand Down Expand Up @@ -63,6 +64,7 @@ export function parseSetCookie(setCookie: string): undefined | ResponseCookie {
path,
samesite,
secure,
partitioned,
priority,
} = Object.fromEntries(
attributes.map(([key, value]) => [key.toLowerCase(), value]),
Expand All @@ -78,6 +80,7 @@ export function parseSetCookie(setCookie: string): undefined | ResponseCookie {
...(samesite && { sameSite: parseSameSite(samesite) }),
...(secure && { secure: true }),
...(priority && { priority: parsePriority(priority) }),
...(partitioned && { partitioned: true }),
}

return compact(cookie)
Expand Down
2 changes: 1 addition & 1 deletion packages/cookies/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { CookieSerializeOptions } from 'cookie'
export interface CookieListItem
extends Pick<
CookieSerializeOptions,
'domain' | 'path' | 'secure' | 'sameSite'
'domain' | 'path' | 'secure' | 'sameSite' | 'partitioned'
> {
/** A string with the name of a cookie. */
name: string
Expand Down
29 changes: 24 additions & 5 deletions packages/cookies/test/response-cookies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ test('reflect .set into `set-cookie`', async () => {
.set('fooExpires', 'barExpires', { expires: 0 })
.set('fooExpiresDate', 'barExpiresDate', { expires: new Date(0) })
.set('fooMaxAge', '', { maxAge: 0 })
.set('fooSameSite', 'barSameSite', {
sameSite: 'none',
partitioned: true,
secure: true,
})

expect(cookies.get('foo')?.value).toBe('bar')
expect(cookies.get('fooz')?.value).toBe('barz')
expect(cookies.get('fooHttpOnly')?.value).toBe('barHttpOnly')
expect(cookies.get('fooExpires')?.value).toBe('barExpires')
expect(cookies.get('fooExpiresDate')?.value).toBe('barExpiresDate')
expect(cookies.get('fooMaxAge')?.value).toBe('')
expect(cookies.get('fooSameSite')?.value).toBe('barSameSite')

const opt1 = cookies.get('foo')
expect(opt1).toEqual<typeof opt1>({
Expand Down Expand Up @@ -58,6 +64,14 @@ test('reflect .set into `set-cookie`', async () => {
path: '/',
maxAge: 0,
})
expect(cookies.get('fooSameSite')).toEqual({
name: 'fooSameSite',
value: 'barSameSite',
path: '/',
sameSite: 'none',
secure: true,
partitioned: true,
})

expect(headers.getSetCookie()).toEqual([
'foo=bar; Path=/test',
Expand All @@ -66,6 +80,7 @@ test('reflect .set into `set-cookie`', async () => {
'fooExpires=barExpires; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT',
'fooExpiresDate=barExpiresDate; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT',
'fooMaxAge=; Path=/; Max-Age=0',
'fooSameSite=barSameSite; Path=/; Secure; SameSite=none; Partitioned',
])
})

Expand All @@ -81,19 +96,22 @@ it('reflect .set all options attributes into `set-cookie`', async () => {
httpOnly: true,
maxAge: 0,
priority: 'high',
partitioned: true,
})
const cookiesInHeaders = headers.getSetCookie()
expect(cookiesInHeaders).toEqual([
'first-name=first-value; Path=custom-path; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Domain=custom-domain; Secure; HttpOnly; SameSite=strict; Priority=high',
'first-name=first-value; Path=custom-path; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Domain=custom-domain; Secure; HttpOnly; SameSite=strict; Partitioned; Priority=high',
])
})

describe('`set-cookie` into .get and .getAll', () => {
test.each([
'name=value; Secure; HttpOnly',
'name=value; Secure; HttpOnly;',
'name=value; HttpOnly; Secure',
'name=value; HttpOnly; Secure;',
'name=value; Partitioned; Secure; HttpOnly',
'name=value; Secure; Partitioned; HttpOnly;',
'name=value; Secure; HttpOnly; Partitioned',
'name=value; HttpOnly; Partitioned; Secure;',
'name=value; Partitioned; Secure; HttpOnly',
'name=value; HttpOnly; Partitioned; Secure;',
])('parses %s header correctly', (value) => {
const headers = new Headers()
headers.set('set-cookie', value)
Expand All @@ -106,6 +124,7 @@ describe('`set-cookie` into .get and .getAll', () => {
value: 'value',
httpOnly: true,
secure: true,
partitioned: true,
})

expect(cookies.get('name')).toEqual(all[0])
Expand Down

0 comments on commit 7a13394

Please sign in to comment.