@@ -46,25 +46,109 @@ export function createServerClient<
46
46
} ;
47
47
}
48
48
49
- const deleteAllChunks = async ( key : string ) => {
50
- await deleteChunks (
51
- key ,
52
- async ( chunkName ) => {
53
- if ( typeof cookies . get === 'function' ) {
54
- return await cookies . get ( chunkName ) ;
49
+ let storage : any ;
50
+
51
+ if ( 'get' in cookies ) {
52
+ const deleteAllChunks = async ( key : string ) => {
53
+ await deleteChunks (
54
+ key ,
55
+ async ( chunkName ) => {
56
+ if ( typeof cookies . get === 'function' ) {
57
+ return await cookies . get ( chunkName ) ;
58
+ }
59
+ } ,
60
+ async ( chunkName ) => {
61
+ if ( typeof cookies . remove === 'function' ) {
62
+ return await cookies . remove ( chunkName , {
63
+ ...DEFAULT_COOKIE_OPTIONS ,
64
+ ...cookieOptions ,
65
+ maxAge : 0
66
+ } ) ;
67
+ }
55
68
}
69
+ ) ;
70
+ } ;
71
+
72
+ storage = {
73
+ // to signal to the libraries that these cookies are coming from a server environment and their value should not be trusted
74
+ isServer : true ,
75
+ getItem : async ( key : string ) => {
76
+ const chunkedCookie = await combineChunks ( key , async ( chunkName : string ) => {
77
+ if ( typeof cookies . get === 'function' ) {
78
+ return await cookies . get ( chunkName ) ;
79
+ }
80
+ } ) ;
81
+ return chunkedCookie ;
56
82
} ,
57
- async ( chunkName ) => {
58
- if ( typeof cookies . remove === 'function' ) {
59
- return await cookies . remove ( chunkName , {
60
- ...DEFAULT_COOKIE_OPTIONS ,
61
- ...cookieOptions ,
62
- maxAge : 0
63
- } ) ;
83
+ setItem : async ( key : string , value : string ) => {
84
+ if ( typeof cookies . set === 'function' ) {
85
+ // first delete all chunks so that there would be no overlap
86
+ await deleteAllChunks ( key ) ;
87
+
88
+ const chunks = createChunks ( key , value ) ;
89
+
90
+ for ( let i = 0 ; i < chunks . length ; i += 1 ) {
91
+ const chunk = chunks [ i ] ;
92
+
93
+ await cookies . set ( chunk . name , chunk . value , {
94
+ ...DEFAULT_COOKIE_OPTIONS ,
95
+ ...cookieOptions ,
96
+ maxAge : DEFAULT_COOKIE_OPTIONS . maxAge
97
+ } ) ;
98
+ }
99
+ }
100
+ } ,
101
+ removeItem : async ( key : string ) => {
102
+ if ( typeof cookies . remove === 'function' && typeof cookies . get !== 'function' ) {
103
+ console . log (
104
+ 'Removing chunked cookie without a `get` method is not supported.\n\n\tWhen you call the `createServerClient` function from the `@supabase/ssr` package, make sure you declare both a `get` and `remove` method on the `cookies` object.\n\nhttps://supabase.com/docs/guides/auth/server-side/creating-a-client'
105
+ ) ;
106
+ return ;
107
+ }
108
+
109
+ await deleteAllChunks ( key ) ;
110
+ }
111
+ } ;
112
+ }
113
+
114
+ const setItems : { [ key : string ] : string } = { } ;
115
+ const removedItems : { [ key : string ] : boolean } = { } ;
116
+ if ( 'getAll' in cookies ) {
117
+ storage = {
118
+ // to signal to the libraries that these cookies are coming from a server environment and their value should not be trusted
119
+ isServer : true ,
120
+ getItem : async ( key : string ) => {
121
+ if ( typeof setItems [ key ] === 'string' ) {
122
+ return setItems [ key ] ;
123
+ }
124
+
125
+ if ( removedItems [ key ] ) {
126
+ return null ;
64
127
}
128
+
129
+ const allCookies = await cookies . getAll ( ) ;
130
+ const chunkedCookie = await combineChunks ( key , async ( chunkName : string ) => {
131
+ const cookie = allCookies ?. find ( ( { name } ) => name === chunkName ) || null ;
132
+
133
+ if ( ! cookie ) {
134
+ return null ;
135
+ }
136
+
137
+ return cookie . value ;
138
+ } ) ;
139
+
140
+ return chunkedCookie ;
141
+ } ,
142
+ setItem : async ( key : string , value : string ) => {
143
+ setItems [ key ] = value ;
144
+ delete removedItems [ key ] ;
145
+ } ,
146
+ removeItem : async ( key : string ) => {
147
+ delete setItems [ key ] ;
148
+ removedItems [ key ] = true ;
65
149
}
66
- ) ;
67
- } ;
150
+ } ;
151
+ }
68
152
69
153
const cookieClientOptions = {
70
154
global : {
@@ -77,46 +161,7 @@ export function createServerClient<
77
161
autoRefreshToken : isBrowser ( ) ,
78
162
detectSessionInUrl : isBrowser ( ) ,
79
163
persistSession : true ,
80
- storage : {
81
- // to signal to the libraries that these cookies are coming from a server environment and their value should not be trusted
82
- isServer : true ,
83
- getItem : async ( key : string ) => {
84
- const chunkedCookie = await combineChunks ( key , async ( chunkName : string ) => {
85
- if ( typeof cookies . get === 'function' ) {
86
- return await cookies . get ( chunkName ) ;
87
- }
88
- } ) ;
89
- return chunkedCookie ;
90
- } ,
91
- setItem : async ( key : string , value : string ) => {
92
- if ( typeof cookies . set === 'function' ) {
93
- // first delete all chunks so that there would be no overlap
94
- await deleteAllChunks ( key ) ;
95
-
96
- const chunks = createChunks ( key , value ) ;
97
-
98
- for ( let i = 0 ; i < chunks . length ; i += 1 ) {
99
- const chunk = chunks [ i ] ;
100
-
101
- await cookies . set ( chunk . name , chunk . value , {
102
- ...DEFAULT_COOKIE_OPTIONS ,
103
- ...cookieOptions ,
104
- maxAge : DEFAULT_COOKIE_OPTIONS . maxAge
105
- } ) ;
106
- }
107
- }
108
- } ,
109
- removeItem : async ( key : string ) => {
110
- if ( typeof cookies . remove === 'function' && typeof cookies . get !== 'function' ) {
111
- console . log (
112
- 'Removing chunked cookie without a `get` method is not supported.\n\n\tWhen you call the `createServerClient` function from the `@supabase/ssr` package, make sure you declare both a `get` and `remove` method on the `cookies` object.\n\nhttps://supabase.com/docs/guides/auth/server-side/creating-a-client'
113
- ) ;
114
- return ;
115
- }
116
-
117
- await deleteAllChunks ( key ) ;
118
- }
119
- }
164
+ storage
120
165
}
121
166
} ;
122
167
@@ -126,5 +171,82 @@ export function createServerClient<
126
171
userDefinedClientOptions
127
172
) as SupabaseClientOptions < SchemaName > ;
128
173
129
- return createClient < Database , SchemaName , Schema > ( supabaseUrl , supabaseKey , clientOptions ) ;
174
+ const client = createClient < Database , SchemaName , Schema > (
175
+ supabaseUrl ,
176
+ supabaseKey ,
177
+ clientOptions
178
+ ) ;
179
+
180
+ if ( 'getAll' in cookies ) {
181
+ client . auth . onAuthStateChange ( async ( event ) => {
182
+ if ( event === 'TOKEN_REFRESHED' || event === 'USER_UPDATED' || event === 'SIGNED_OUT' ) {
183
+ if ( typeof cookies . setAll !== 'function' ) {
184
+ console . log ( 'You are holding it wrong!!!!!' ) ;
185
+ }
186
+
187
+ const allCookies = await cookies . getAll ( ) ;
188
+ const cookieNames = allCookies ?. map ( ( { name } ) => name ) || [ ] ;
189
+
190
+ const removeCookies = cookieNames . filter ( ( name ) => {
191
+ if ( removedItems [ name ] ) {
192
+ return true ;
193
+ }
194
+
195
+ const chunkLike = name . match ( / ^ ( .* ) [ . ] ( 0 | [ 1 - 9 ] [ 0 - 9 ] * ) $ / ) ;
196
+ if ( chunkLike && removedItems [ chunkLike [ 1 ] ] ) {
197
+ return true ;
198
+ }
199
+
200
+ return false ;
201
+ } ) ;
202
+
203
+ const setCookies = Object . keys ( setItems ) . flatMap ( ( itemName ) => {
204
+ const removeExistingCookiesForItem = new Set (
205
+ cookieNames . filter ( ( name ) => {
206
+ if ( name === itemName ) {
207
+ return true ;
208
+ }
209
+
210
+ const chunkLike = name . match ( / ^ ( .* ) [ . ] ( 0 | [ 1 - 9 ] [ 0 - 9 ] * ) $ / ) ;
211
+ if ( chunkLike && chunkLike [ 1 ] === itemName ) {
212
+ return true ;
213
+ }
214
+
215
+ return false ;
216
+ } )
217
+ ) ;
218
+
219
+ const chunks = createChunks ( itemName , setItems [ itemName ] ) ;
220
+
221
+ chunks . forEach ( ( chunk ) => {
222
+ removeExistingCookiesForItem . delete ( chunk . name ) ;
223
+ } ) ;
224
+
225
+ removeCookies . push ( ...removeExistingCookiesForItem ) ;
226
+
227
+ return chunks ;
228
+ } ) ;
229
+
230
+ const removeCookieOptions = {
231
+ ...DEFAULT_COOKIE_OPTIONS ,
232
+ ...cookieOptions ,
233
+ maxAge : 0
234
+ } ;
235
+ const setCookieOptions = {
236
+ ...DEFAULT_COOKIE_OPTIONS ,
237
+ ...cookieOptions ,
238
+ maxAge : DEFAULT_COOKIE_OPTIONS . maxAge
239
+ } ;
240
+
241
+ await cookies . setAll (
242
+ [ ] . concat (
243
+ removeCookies . map ( ( name ) => ( { name, value : '' , options : removeCookieOptions } ) ) ,
244
+ setCookies . map ( ( { name, value } ) => ( { name, value, options : setCookieOptions } ) )
245
+ )
246
+ ) ;
247
+ }
248
+ } ) ;
249
+ }
250
+
251
+ return client ;
130
252
}
0 commit comments