1
- import { parse , serialize } from "cookie-es" ;
2
- import { objectHash } from "ohash" ;
3
1
import type { CookieSerializeOptions } from "cookie-es" ;
4
2
import type { H3Event } from "../event" ;
3
+ import {
4
+ parse as parseCookie ,
5
+ serialize as serializeCookie ,
6
+ parseSetCookie ,
7
+ } from "cookie-es" ;
8
+ import { getDistinctCookieKey } from "./internal/cookie" ;
5
9
6
10
/**
7
11
* Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
@@ -12,7 +16,7 @@ import type { H3Event } from "../event";
12
16
* ```
13
17
*/
14
18
export function parseCookies ( event : H3Event ) : Record < string , string > {
15
- return parse ( event . node . req . headers . cookie || "" ) ;
19
+ return parseCookie ( event . node . req . headers . cookie || "" ) ;
16
20
}
17
21
18
22
/**
@@ -42,20 +46,38 @@ export function setCookie(
42
46
event : H3Event ,
43
47
name : string ,
44
48
value : string ,
45
- serializeOptions ? : CookieSerializeOptions ,
49
+ serializeOptions : CookieSerializeOptions = { } ,
46
50
) {
47
- serializeOptions = { path : "/" , ...serializeOptions } ;
48
- const cookieStr = serialize ( name , value , serializeOptions ) ;
49
- let setCookies = event . node . res . getHeader ( "set-cookie" ) ;
50
- if ( ! Array . isArray ( setCookies ) ) {
51
- setCookies = [ setCookies as any ] ;
51
+ // Apply default path
52
+ if ( ! serializeOptions . path ) {
53
+ serializeOptions = { path : "/" , ...serializeOptions } ;
52
54
}
53
55
54
- const _optionsHash = objectHash ( serializeOptions ) ;
55
- setCookies = setCookies . filter ( ( cookieValue : string ) => {
56
- return cookieValue && _optionsHash !== objectHash ( parse ( cookieValue ) ) ;
57
- } ) ;
58
- event . node . res . setHeader ( "set-cookie" , [ ...setCookies , cookieStr ] ) ;
56
+ // Serialize cookie
57
+ const newCookie = serializeCookie ( name , value , serializeOptions ) ;
58
+
59
+ // Check and add only not any other set-cookie headers already set
60
+ // const currentCookies = event.response.headers.getSetCookie();
61
+ const currentCookies = splitCookiesString (
62
+ event . node . res . getHeader ( "set-cookie" ) as string | string [ ] ,
63
+ ) ;
64
+ if ( currentCookies . length === 0 ) {
65
+ event . node . res . setHeader ( "set-cookie" , newCookie ) ;
66
+ return ;
67
+ }
68
+
69
+ // Merge and deduplicate unique set-cookie headers
70
+ const newCookieKey = getDistinctCookieKey ( name , serializeOptions ) ;
71
+ event . node . res . removeHeader ( "set-cookie" ) ;
72
+ for ( const cookie of currentCookies ) {
73
+ const parsed = parseSetCookie ( cookie ) ;
74
+ const key = getDistinctCookieKey ( parsed . name , parsed ) ;
75
+ if ( key === newCookieKey ) {
76
+ continue ;
77
+ }
78
+ event . node . res . appendHeader ( "set-cookie" , cookie ) ;
79
+ }
80
+ event . node . res . appendHeader ( "set-cookie" , newCookie ) ;
59
81
}
60
82
61
83
/**
0 commit comments