Skip to content

Commit

Permalink
Edge Cookies: Add .getWithOptions method
Browse files Browse the repository at this point in the history
  • Loading branch information
Kikobeats committed May 18, 2022
1 parent 359d03f commit f9ead86
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 25 deletions.
24 changes: 21 additions & 3 deletions packages/next/server/web/spec-extension/cookies.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import cookie from 'next/dist/compiled/cookie'
import { CookieSerializeOptions } from '../types'

type GetWithOptionsOutput = [
value: string | undefined,
options: { [key: string]: string } | undefined
]

const normalizeCookieOptions = (options: CookieSerializeOptions) => {
options = Object.assign({}, options)

Expand Down Expand Up @@ -59,10 +64,23 @@ export class NextCookies extends Cookies {
super(response.headers.get('cookie'))
this.response = response
}
get = (...args: Parameters<Cookies['get']>) => {
const [value] = this.getWithOptions(...args)
return value
}
getWithOptions = (
...args: Parameters<Cookies['get']>
): GetWithOptionsOutput => {
const raw = super.get(...args)
if (typeof raw !== 'string') return [raw, undefined]
const { [args[0]]: value, ...opts } = cookie.parse(raw)
return [value, opts]
}
set = (...args: Parameters<Cookies['set']>) => {
const isAlreadyAdded = super.has(args[0])
const store = super.set(...args)
const currentCookie = store.get(args[0])

super.set(...args)
const currentCookie = super.get(args[0])

if (typeof currentCookie !== 'string') {
throw new Error(
Expand All @@ -89,7 +107,7 @@ export class NextCookies extends Cookies {
this.response.headers.append('set-cookie', currentCookie)
}

return store
return this
}
delete = (key: any, options: CookieSerializeOptions = {}) => {
const isDeleted = super.delete(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ export const middleware: NextMiddleware = async function (request) {
const response = NextResponse.rewrite(`/rewrites/${bucket}`)
response.cookies.set('bucket', bucket, { maxAge: 10 })
return response
} else {
// check that `bucket` is type "string", not "any"
bucket.toUpperCase()
}

return NextResponse.rewrite(`/rewrites/${bucket}`)
Expand Down
55 changes: 36 additions & 19 deletions test/unit/web-runtime/next-cookies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,27 @@ it('reflect .set into `set-cookie`', async () => {

const response = new NextResponse()

response.cookies.set('foo', 'bar')
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'foo=bar; Path=/'
)
expect(response.cookies.get('foo')).toBe('foo=bar; Path=/')
expect(response.cookies.get('foo')).toBe(undefined)
expect(response.cookies.getWithOptions('foo')).toEqual([undefined, undefined])

response.cookies.set('foo', 'barz')
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'foo=barz; Path=/'
)
expect(response.cookies.get('foo')).toBe('foo=barz; Path=/')
response.cookies
.set('foo', 'bar', { path: '/test' })
.set('fooz', 'barz', { path: '/test2' })

response.cookies.set('fooz', 'barz')
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'foo=barz; Path=/, fooz=barz; Path=/'
)
expect(response.cookies.get('foo')).toBe('bar')
expect(response.cookies.get('fooz')).toBe('barz')

expect(response.cookies.getWithOptions('foo')).toEqual([
'bar',
{ Path: '/test' },
])
expect(response.cookies.getWithOptions('fooz')).toEqual([
'barz',
{ Path: '/test2' },
])

response.cookies.set('foo', 'bar')
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'foo=bar; Path=/, fooz=barz; Path=/'
'foo=bar; Path=/test, fooz=barz; Path=/test2'
)
})

Expand All @@ -68,13 +69,20 @@ it('reflect .delete into `set-cookie`', async () => {
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'foo=bar; Path=/'
)
expect(response.cookies.get('foo')).toBe('foo=bar; Path=/')

expect(response.cookies.get('foo')).toBe('bar')
expect(response.cookies.getWithOptions('foo')).toEqual(['bar', { Path: '/' }])

response.cookies.set('fooz', 'barz')
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'foo=bar; Path=/, fooz=barz; Path=/'
)
expect(response.cookies.get('fooz')).toBe('fooz=barz; Path=/')

expect(response.cookies.get('fooz')).toBe('barz')
expect(response.cookies.getWithOptions('fooz')).toEqual([
'barz',
{ Path: '/' },
])

const firstDelete = response.cookies.delete('foo')
expect(firstDelete).toBe(true)
Expand All @@ -83,13 +91,20 @@ it('reflect .delete into `set-cookie`', async () => {
)

expect(response.cookies.get('foo')).toBe(undefined)
expect(response.cookies.getWithOptions('foo')).toEqual([undefined, undefined])

const secondDelete = response.cookies.delete('fooz')
expect(secondDelete).toBe(true)

expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'fooz=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT, foo=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT'
)

expect(response.cookies.get('fooz')).toBe(undefined)
expect(response.cookies.getWithOptions('fooz')).toEqual([
undefined,
undefined,
])
expect(response.cookies.size).toBe(0)
})

Expand All @@ -109,7 +124,9 @@ it('reflect .clear into `set-cookie`', async () => {
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
'foo=bar; Path=/'
)
expect(response.cookies.get('foo')).toBe('foo=bar; Path=/')

expect(response.cookies.get('foo')).toBe('bar')
expect(response.cookies.getWithOptions('foo')).toEqual(['bar', { Path: '/' }])

response.cookies.set('fooz', 'barz')
expect(Object.fromEntries(response.headers.entries())['set-cookie']).toBe(
Expand Down

0 comments on commit f9ead86

Please sign in to comment.