Skip to content

Commit a471c0e

Browse files
committed
Initial file storage support
1 parent 3398447 commit a471c0e

File tree

1 file changed

+54
-2
lines changed

1 file changed

+54
-2
lines changed

packages/ra-supabase-core/src/dataProvider.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DataProvider, fetchUtils } from 'ra-core';
1+
import { DataProvider, fetchUtils, withLifecycleCallbacks } from 'ra-core';
22
import postgrestRestProvider, {
33
IDataProviderConfig,
44
defaultPrimaryKeys,
@@ -24,10 +24,19 @@ export const supabaseDataProvider = ({
2424
defaultListOp = 'eq',
2525
primaryKeys = defaultPrimaryKeys,
2626
schema = defaultSchema,
27+
storagePath,
28+
filenameFromData = ({ filename }) => filename,
2729
}: {
2830
instanceUrl: string;
2931
apiKey: string;
3032
supabaseClient: SupabaseClient;
33+
storagePath?: string | ((resource: string) => string);
34+
filenameFromData?: (_: {
35+
data: string;
36+
resource: string;
37+
field: string;
38+
filename: string;
39+
}) => string;
3140
} & Partial<Omit<IDataProviderConfig, 'apiUrl'>>): DataProvider => {
3241
const config: IDataProviderConfig = {
3342
apiUrl: `${instanceUrl}/rest/v1`,
@@ -36,7 +45,50 @@ export const supabaseDataProvider = ({
3645
primaryKeys,
3746
schema,
3847
};
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+
]);
4092
};
4193

4294
/**

0 commit comments

Comments
 (0)