1
- import { DataProvider , fetchUtils } from 'ra-core' ;
1
+ import { DataProvider , fetchUtils , withLifecycleCallbacks } from 'ra-core' ;
2
2
import postgrestRestProvider , {
3
3
IDataProviderConfig ,
4
4
defaultPrimaryKeys ,
@@ -24,10 +24,19 @@ export const supabaseDataProvider = ({
24
24
defaultListOp = 'eq' ,
25
25
primaryKeys = defaultPrimaryKeys ,
26
26
schema = defaultSchema ,
27
+ storagePath,
28
+ filenameFromData = ( { filename } ) => filename ,
27
29
} : {
28
30
instanceUrl : string ;
29
31
apiKey : string ;
30
32
supabaseClient : SupabaseClient ;
33
+ storagePath ?: string | ( ( resource : string ) => string ) ;
34
+ filenameFromData ?: ( _ : {
35
+ data : string ;
36
+ resource : string ;
37
+ field : string ;
38
+ filename : string ;
39
+ } ) => string ;
31
40
} & Partial < Omit < IDataProviderConfig , 'apiUrl' > > ) : DataProvider => {
32
41
const config : IDataProviderConfig = {
33
42
apiUrl : `${ instanceUrl } /rest/v1` ,
@@ -36,7 +45,50 @@ export const supabaseDataProvider = ({
36
45
primaryKeys,
37
46
schema,
38
47
} ;
39
- return postgrestRestProvider ( config ) ;
48
+ return withLifecycleCallbacks ( postgrestRestProvider ( config ) , [
49
+ {
50
+ resource : '*' ,
51
+ beforeSave : async (
52
+ data : any ,
53
+ dataProvider : DataProvider ,
54
+ resource : string
55
+ ) => {
56
+ if ( ! storagePath ) return data ;
57
+ const newFiles = (
58
+ await Promise . all (
59
+ Object . keys ( data )
60
+ . filter ( key => data [ key ] ?. rawFile instanceof File )
61
+ . map ( async ( key : string ) => {
62
+ const file = data [ key ] ;
63
+ const bucket =
64
+ storagePath instanceof Function
65
+ ? storagePath ( resource )
66
+ : storagePath ;
67
+ const filename = filenameFromData ( {
68
+ data,
69
+ resource,
70
+ field : key ,
71
+ filename : file . rawFile . name ,
72
+ } ) ;
73
+
74
+ const { error } = await supabaseClient . storage
75
+ . from ( bucket )
76
+ . upload ( filename , file . rawFile ) ;
77
+ if ( error ) throw error ;
78
+ const {
79
+ data : { publicUrl } ,
80
+ } = supabaseClient . storage
81
+ . from ( bucket )
82
+ . getPublicUrl ( filename ) ;
83
+
84
+ return { [ key ] : publicUrl } ;
85
+ } )
86
+ )
87
+ ) . reduce ( ( acc , val ) => ( { ...acc , ...val } ) , { } ) ;
88
+ return { ...data , ...newFiles } ;
89
+ } ,
90
+ } ,
91
+ ] ) ;
40
92
} ;
41
93
42
94
/**
0 commit comments