mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 07:05:11 +00:00
fix(nuxt): clone cookie to detect changes within object (#25007)
This commit is contained in:
parent
2bda817eaf
commit
7087a06c6d
@ -6,6 +6,7 @@ import { deleteCookie, getCookie, getRequestHeader, setCookie } from 'h3'
|
|||||||
import type { H3Event } from 'h3'
|
import type { H3Event } from 'h3'
|
||||||
import destr from 'destr'
|
import destr from 'destr'
|
||||||
import { isEqual } from 'ohash'
|
import { isEqual } from 'ohash'
|
||||||
|
import { klona } from 'klona'
|
||||||
import { useNuxtApp } from '../nuxt'
|
import { useNuxtApp } from '../nuxt'
|
||||||
import { useRequestEvent } from './ssr'
|
import { useRequestEvent } from './ssr'
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ export function useCookie<T = string | null | undefined> (name: string, _opts?:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hasExpired = delay !== undefined && delay <= 0
|
const hasExpired = delay !== undefined && delay <= 0
|
||||||
const cookieValue = hasExpired ? undefined : (cookies[name] as any) ?? opts.default?.()
|
const cookieValue = klona(hasExpired ? undefined : (cookies[name] as any) ?? opts.default?.())
|
||||||
|
|
||||||
// use a custom ref to expire the cookie on client side otherwise use basic ref
|
// use a custom ref to expire the cookie on client side otherwise use basic ref
|
||||||
const cookie = import.meta.client && delay && !hasExpired
|
const cookie = import.meta.client && delay && !hasExpired
|
||||||
|
@ -489,7 +489,19 @@ describe('nuxt composables', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const cookies = res.headers.get('set-cookie')
|
const cookies = res.headers.get('set-cookie')
|
||||||
expect(cookies).toMatchInlineSnapshot('"set-in-plugin=true; Path=/, set=set; Path=/, browser-set=set; Path=/, browser-set-to-null=; Max-Age=0; Path=/, browser-set-to-null-with-default=; Max-Age=0; Path=/"')
|
expect(cookies).toMatchInlineSnapshot('"set-in-plugin=true; Path=/, set=set; Path=/, browser-set=set; Path=/, browser-set-to-null=; Max-Age=0; Path=/, browser-set-to-null-with-default=; Max-Age=0; Path=/, browser-object-default=%7B%22foo%22%3A%22bar%22%7D; Path=/"')
|
||||||
|
})
|
||||||
|
it('updates cookies when they are changed', async () => {
|
||||||
|
const { page } = await renderPage('/cookies')
|
||||||
|
async function extractCookie () {
|
||||||
|
const cookie = await page.evaluate(() => document.cookie)
|
||||||
|
const raw = cookie.match(/browser-object-default=([^;]*)/)![1] ?? 'null'
|
||||||
|
return JSON.parse(decodeURIComponent(raw))
|
||||||
|
}
|
||||||
|
expect(await extractCookie()).toEqual({ foo: 'bar' })
|
||||||
|
await page.getByRole('button').click()
|
||||||
|
expect(await extractCookie()).toEqual({ foo: 'baz' })
|
||||||
|
await page.close()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1462,7 +1474,7 @@ describe('server components/islands', () => {
|
|||||||
const islandRequest = page.waitForResponse(response => response.url().includes('/__nuxt_island/') && response.status() === 200)
|
const islandRequest = page.waitForResponse(response => response.url().includes('/__nuxt_island/') && response.status() === 200)
|
||||||
await page.locator('#increase-pure-component').click()
|
await page.locator('#increase-pure-component').click()
|
||||||
await islandRequest
|
await islandRequest
|
||||||
|
|
||||||
await page.locator('#slot-in-server').getByText('Slot with in .server component').waitFor()
|
await page.locator('#slot-in-server').getByText('Slot with in .server component').waitFor()
|
||||||
await page.locator('#test-slot').getByText('Slot with name test').waitFor()
|
await page.locator('#test-slot').getByText('Slot with name test').waitFor()
|
||||||
|
|
||||||
|
8
test/fixtures/basic/pages/cookies.vue
vendored
8
test/fixtures/basic/pages/cookies.vue
vendored
@ -10,10 +10,18 @@ useCookie('browser-accessed-with-default-value', () => 'default')
|
|||||||
useCookie('browser-set').value = 'set'
|
useCookie('browser-set').value = 'set'
|
||||||
useCookie('browser-set-to-null').value = null
|
useCookie('browser-set-to-null').value = null
|
||||||
useCookie('browser-set-to-null-with-default', () => 'default').value = null
|
useCookie('browser-set-to-null-with-default', () => 'default').value = null
|
||||||
|
|
||||||
|
const objectCookie = useCookie('browser-object-default', {
|
||||||
|
default: () => ({ foo: 'bar' })
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div>cookies testing page</div>
|
<div>cookies testing page</div>
|
||||||
|
<pre>{{ objectCookie }}</pre>
|
||||||
|
<button @click="objectCookie.foo = 'baz'">
|
||||||
|
Change cookie
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user