@@ -15,7 +15,9 @@ import { SPAN_STATUS_ERROR, SPAN_STATUS_OK } from '../tracing';
15
15
export interface SupabaseClientConstructor {
16
16
prototype : {
17
17
from : ( table : string ) => PostgrestQueryBuilder ;
18
+ schema : ( schema : string ) => { rpc : ( ...args : unknown [ ] ) => Promise < unknown > } ;
18
19
} ;
20
+ rpc : ( fn : string , params : Record < string , unknown > ) => Promise < unknown > ;
19
21
}
20
22
21
23
const AUTH_OPERATIONS_TO_INSTRUMENT = [
@@ -192,6 +194,76 @@ export function translateFiltersIntoMethods(key: string, query: string): string
192
194
return `${ method } (${ key } , ${ value . join ( '.' ) } )` ;
193
195
}
194
196
197
+ function instrumentRpcReturnedFromSchemaCall ( SupabaseClient : unknown ) : void {
198
+ ( SupabaseClient as unknown as SupabaseClientConstructor ) . prototype . schema = new Proxy (
199
+ ( SupabaseClient as unknown as SupabaseClientConstructor ) . prototype . schema ,
200
+ {
201
+ apply ( target , thisArg , argumentsList ) {
202
+ const rv = Reflect . apply ( target , thisArg , argumentsList ) ;
203
+
204
+ return instrumentRpc ( rv ) ;
205
+ } ,
206
+ } ,
207
+ ) ;
208
+ }
209
+
210
+ function instrumentRpc ( SupabaseClient : unknown ) : unknown {
211
+ ( SupabaseClient as unknown as SupabaseClientConstructor ) . rpc = new Proxy (
212
+ ( SupabaseClient as unknown as SupabaseClientConstructor ) . rpc ,
213
+ {
214
+ apply ( target , thisArg , argumentsList ) {
215
+ const isProducerSpan = argumentsList [ 0 ] === 'enqueue' ;
216
+ const isConsumerSpan = argumentsList [ 0 ] === 'dequeue' ;
217
+
218
+ const maybeQueueParams = argumentsList [ 1 ] ;
219
+
220
+ // If the second argument is not an object, it's not a queue operation
221
+ if ( ! isPlainObject ( maybeQueueParams ) ) {
222
+ return Reflect . apply ( target , thisArg , argumentsList ) ;
223
+ }
224
+
225
+ const msg = maybeQueueParams ?. msg as { title : string } ;
226
+
227
+ const messageId = msg ?. title ;
228
+ const queueName = maybeQueueParams ?. queue_name as string ;
229
+
230
+ const op = isProducerSpan ? 'queue.publish' : isConsumerSpan ? 'queue.process' : '' ;
231
+
232
+ // If the operation is not a queue operation, return the original function
233
+ if ( ! op ) {
234
+ return Reflect . apply ( target , thisArg , argumentsList ) ;
235
+ }
236
+
237
+ return startSpan (
238
+ {
239
+ name : 'supabase.db.rpc' ,
240
+ attributes : {
241
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.db.supabase' ,
242
+ [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : op ,
243
+ } ,
244
+ } ,
245
+ async span => {
246
+ return ( Reflect . apply ( target , thisArg , argumentsList ) as Promise < unknown > ) . then ( ( res : unknown ) => {
247
+ if ( messageId ) {
248
+ span . setAttribute ( 'messaging.message.id' , messageId ) ;
249
+ }
250
+
251
+ if ( queueName ) {
252
+ span . setAttribute ( 'messaging.destination.name' , queueName ) ;
253
+ }
254
+
255
+ span . end ( ) ;
256
+ return res ;
257
+ } ) ;
258
+ } ,
259
+ ) ;
260
+ } ,
261
+ } ,
262
+ ) ;
263
+
264
+ return SupabaseClient ;
265
+ }
266
+
195
267
function instrumentAuthOperation ( operation : AuthOperationFn , isAdmin = false ) : AuthOperationFn {
196
268
return new Proxy ( operation , {
197
269
apply ( target , thisArg , argumentsList ) {
@@ -261,13 +333,13 @@ function instrumentSupabaseAuthClient(supabaseClientInstance: SupabaseClientInst
261
333
} ) ;
262
334
}
263
335
264
- function instrumentSupabaseClientConstructor ( SupabaseClient : unknown ) : void {
265
- if ( instrumented . has ( SupabaseClient ) ) {
336
+ function instrumentSupabaseClientConstructor ( SupabaseClientConstructor : unknown ) : void {
337
+ if ( instrumented . has ( SupabaseClientConstructor ) ) {
266
338
return ;
267
339
}
268
340
269
- ( SupabaseClient as unknown as SupabaseClientConstructor ) . prototype . from = new Proxy (
270
- ( SupabaseClient as unknown as SupabaseClientConstructor ) . prototype . from ,
341
+ ( SupabaseClientConstructor as unknown as SupabaseClientConstructor ) . prototype . from = new Proxy (
342
+ ( SupabaseClientConstructor as unknown as SupabaseClientConstructor ) . prototype . from ,
271
343
{
272
344
apply ( target , thisArg , argumentsList ) {
273
345
const rv = Reflect . apply ( target , thisArg , argumentsList ) ;
@@ -482,6 +554,8 @@ const instrumentSupabase = (supabaseClientInstance: unknown): void => {
482
554
supabaseClientInstance . constructor === Function ? supabaseClientInstance : supabaseClientInstance . constructor ;
483
555
484
556
instrumentSupabaseClientConstructor ( SupabaseClientConstructor ) ;
557
+ instrumentRpcReturnedFromSchemaCall ( SupabaseClientConstructor ) ;
558
+ instrumentRpc ( supabaseClientInstance as SupabaseClientInstance ) ;
485
559
instrumentSupabaseAuthClient ( supabaseClientInstance as SupabaseClientInstance ) ;
486
560
} ;
487
561
0 commit comments