@@ -69,7 +69,7 @@ export function createTRPCHandle<Router extends AnyRouter, URL extends string>({
6969 } ) => void ;
7070} ) : Handle {
7171 return async ( { event, resolve } ) => {
72- if ( event . url . pathname . startsWith ( url + '/' ) ) {
72+ if ( event . url . pathname . startsWith ( url + '/' ) ) {
7373 const request = event . request as Request & {
7474 headers : Dict < string | string [ ] > ;
7575 } ;
@@ -81,6 +81,34 @@ export function createTRPCHandle<Router extends AnyRouter, URL extends string>({
8181 body : await request . text ( )
8282 } ;
8383
84+ // Using the default `event.setHeaders` and `event.cookies` will not work
85+ // as the event in not resolved by SvelteKit. Instead, we "proxy" the access
86+ // to the headers and cookies, so that we can set them later.
87+ const headersProxy : Record < string , string > = { } ;
88+ const originalCookiesSet = event . cookies . set ;
89+ const originalCookiesDelete = event . cookies . delete ;
90+ const newCookiesNames : string [ ] = [ ] ;
91+ const deleteCookiesNames : string [ ] = [ ] ;
92+ event . setHeaders = ( headers ) => {
93+ for ( const [ key , value ] of Object . entries ( headers ) ) {
94+ headersProxy [ key ] = value ;
95+ }
96+ } ;
97+ event . cookies . set = ( name , value , opts ) => {
98+ newCookiesNames . push ( name ) ;
99+ if ( deleteCookiesNames . includes ( name ) ) {
100+ deleteCookiesNames . splice ( deleteCookiesNames . indexOf ( name ) , 1 ) ;
101+ }
102+ originalCookiesSet ( name , value , opts ) ;
103+ } ;
104+ event . cookies . delete = ( name ) => {
105+ deleteCookiesNames . push ( name ) ;
106+ if ( newCookiesNames . includes ( name ) ) {
107+ newCookiesNames . splice ( newCookiesNames . indexOf ( name ) , 1 ) ;
108+ }
109+ originalCookiesDelete ( name ) ;
110+ } ;
111+
84112 const httpResponse = await resolveHTTPResponse ( {
85113 router,
86114 req,
@@ -97,6 +125,23 @@ export function createTRPCHandle<Router extends AnyRouter, URL extends string>({
97125 body : string ;
98126 } ;
99127
128+ // Set headers and cookies that were set using SvelteKit's `event.setHeaders` and `event.cookies.set`.
129+ for ( const [ key , value ] of Object . entries ( headersProxy ) ) {
130+ headers [ key ] = value ;
131+ }
132+ const cookies = event . cookies . getAll ( ) . filter ( ( cookie ) => {
133+ // Only pick new cookies
134+ if ( ! newCookiesNames . includes ( cookie . name ) ) return false ;
135+ // Don't pick cookies that were deleted
136+ if ( deleteCookiesNames . includes ( cookie . name ) ) return false ;
137+ return true ;
138+ } ) ;
139+ if ( cookies . length > 0 ) {
140+ headers [ 'Set-Cookie' ] = cookies
141+ . map ( ( cookie ) => `${ cookie . name } =${ cookie . value } ` )
142+ . join ( '; ' ) ;
143+ }
144+
100145 return new Response ( body , { status, headers } ) ;
101146 }
102147
0 commit comments