@fluxbase/sdk-react 0.0.1-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/README-ADMIN.md +1076 -0
- package/README.md +178 -0
- package/dist/index.d.mts +606 -0
- package/dist/index.d.ts +606 -0
- package/dist/index.js +992 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +926 -0
- package/dist/index.mjs.map +1 -0
- package/examples/AdminDashboard.tsx +513 -0
- package/examples/README.md +163 -0
- package/package.json +52 -0
- package/src/context.tsx +33 -0
- package/src/index.ts +113 -0
- package/src/use-admin-auth.ts +168 -0
- package/src/use-admin-hooks.ts +309 -0
- package/src/use-api-keys.ts +174 -0
- package/src/use-auth.ts +146 -0
- package/src/use-query.ts +165 -0
- package/src/use-realtime.ts +161 -0
- package/src/use-rpc.ts +109 -0
- package/src/use-storage.ts +257 -0
- package/src/use-users.ts +191 -0
- package/tsconfig.json +24 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsup.config.ts +11 -0
- package/typedoc.json +35 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,926 @@
|
|
|
1
|
+
// src/context.tsx
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var FluxbaseContext = createContext(null);
|
|
5
|
+
function FluxbaseProvider({ client, children }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(FluxbaseContext.Provider, { value: client, children });
|
|
7
|
+
}
|
|
8
|
+
function useFluxbaseClient() {
|
|
9
|
+
const client = useContext(FluxbaseContext);
|
|
10
|
+
if (!client) {
|
|
11
|
+
throw new Error("useFluxbaseClient must be used within a FluxbaseProvider");
|
|
12
|
+
}
|
|
13
|
+
return client;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/use-auth.ts
|
|
17
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
18
|
+
function useUser() {
|
|
19
|
+
const client = useFluxbaseClient();
|
|
20
|
+
return useQuery({
|
|
21
|
+
queryKey: ["fluxbase", "auth", "user"],
|
|
22
|
+
queryFn: async () => {
|
|
23
|
+
const session = client.auth.getSession();
|
|
24
|
+
if (!session) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return await client.auth.getCurrentUser();
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
staleTime: 1e3 * 60 * 5
|
|
34
|
+
// 5 minutes
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function useSession() {
|
|
38
|
+
const client = useFluxbaseClient();
|
|
39
|
+
return useQuery({
|
|
40
|
+
queryKey: ["fluxbase", "auth", "session"],
|
|
41
|
+
queryFn: () => client.auth.getSession(),
|
|
42
|
+
staleTime: 1e3 * 60 * 5
|
|
43
|
+
// 5 minutes
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function useSignIn() {
|
|
47
|
+
const client = useFluxbaseClient();
|
|
48
|
+
const queryClient = useQueryClient();
|
|
49
|
+
return useMutation({
|
|
50
|
+
mutationFn: async (credentials) => {
|
|
51
|
+
return await client.auth.signIn(credentials);
|
|
52
|
+
},
|
|
53
|
+
onSuccess: (session) => {
|
|
54
|
+
queryClient.setQueryData(["fluxbase", "auth", "session"], session);
|
|
55
|
+
if ("user" in session) {
|
|
56
|
+
queryClient.setQueryData(["fluxbase", "auth", "user"], session.user);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
function useSignUp() {
|
|
62
|
+
const client = useFluxbaseClient();
|
|
63
|
+
const queryClient = useQueryClient();
|
|
64
|
+
return useMutation({
|
|
65
|
+
mutationFn: async (credentials) => {
|
|
66
|
+
return await client.auth.signUp(credentials);
|
|
67
|
+
},
|
|
68
|
+
onSuccess: (session) => {
|
|
69
|
+
queryClient.setQueryData(["fluxbase", "auth", "session"], session);
|
|
70
|
+
queryClient.setQueryData(["fluxbase", "auth", "user"], session.user);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function useSignOut() {
|
|
75
|
+
const client = useFluxbaseClient();
|
|
76
|
+
const queryClient = useQueryClient();
|
|
77
|
+
return useMutation({
|
|
78
|
+
mutationFn: async () => {
|
|
79
|
+
await client.auth.signOut();
|
|
80
|
+
},
|
|
81
|
+
onSuccess: () => {
|
|
82
|
+
queryClient.setQueryData(["fluxbase", "auth", "session"], null);
|
|
83
|
+
queryClient.setQueryData(["fluxbase", "auth", "user"], null);
|
|
84
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase"] });
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function useUpdateUser() {
|
|
89
|
+
const client = useFluxbaseClient();
|
|
90
|
+
const queryClient = useQueryClient();
|
|
91
|
+
return useMutation({
|
|
92
|
+
mutationFn: async (data) => {
|
|
93
|
+
return await client.auth.updateUser(data);
|
|
94
|
+
},
|
|
95
|
+
onSuccess: (user) => {
|
|
96
|
+
queryClient.setQueryData(["fluxbase", "auth", "user"], user);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function useAuth() {
|
|
101
|
+
const { data: user, isLoading: isLoadingUser } = useUser();
|
|
102
|
+
const { data: session, isLoading: isLoadingSession } = useSession();
|
|
103
|
+
const signIn = useSignIn();
|
|
104
|
+
const signUp = useSignUp();
|
|
105
|
+
const signOut = useSignOut();
|
|
106
|
+
const updateUser = useUpdateUser();
|
|
107
|
+
return {
|
|
108
|
+
user,
|
|
109
|
+
session,
|
|
110
|
+
isLoading: isLoadingUser || isLoadingSession,
|
|
111
|
+
isAuthenticated: !!session,
|
|
112
|
+
signIn: signIn.mutateAsync,
|
|
113
|
+
signUp: signUp.mutateAsync,
|
|
114
|
+
signOut: signOut.mutateAsync,
|
|
115
|
+
updateUser: updateUser.mutateAsync,
|
|
116
|
+
isSigningIn: signIn.isPending,
|
|
117
|
+
isSigningUp: signUp.isPending,
|
|
118
|
+
isSigningOut: signOut.isPending,
|
|
119
|
+
isUpdating: updateUser.isPending
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/use-query.ts
|
|
124
|
+
import { useQuery as useQuery2, useMutation as useMutation2, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
125
|
+
function useFluxbaseQuery(buildQuery, options) {
|
|
126
|
+
const client = useFluxbaseClient();
|
|
127
|
+
const queryKey = options?.queryKey || ["fluxbase", "query", buildQuery.toString()];
|
|
128
|
+
return useQuery2({
|
|
129
|
+
queryKey,
|
|
130
|
+
queryFn: async () => {
|
|
131
|
+
const query = buildQuery(client);
|
|
132
|
+
const { data, error } = await query.execute();
|
|
133
|
+
if (error) {
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
return Array.isArray(data) ? data : data ? [data] : [];
|
|
137
|
+
},
|
|
138
|
+
...options
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function useTable(table, buildQuery, options) {
|
|
142
|
+
const client = useFluxbaseClient();
|
|
143
|
+
return useFluxbaseQuery(
|
|
144
|
+
(client2) => {
|
|
145
|
+
const query = client2.from(table);
|
|
146
|
+
return buildQuery ? buildQuery(query) : query;
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
...options,
|
|
150
|
+
queryKey: options?.queryKey || ["fluxbase", "table", table, buildQuery?.toString()]
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
function useInsert(table) {
|
|
155
|
+
const client = useFluxbaseClient();
|
|
156
|
+
const queryClient = useQueryClient2();
|
|
157
|
+
return useMutation2({
|
|
158
|
+
mutationFn: async (data) => {
|
|
159
|
+
const query = client.from(table);
|
|
160
|
+
const { data: result, error } = await query.insert(data);
|
|
161
|
+
if (error) {
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
},
|
|
166
|
+
onSuccess: () => {
|
|
167
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "table", table] });
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function useUpdate(table) {
|
|
172
|
+
const client = useFluxbaseClient();
|
|
173
|
+
const queryClient = useQueryClient2();
|
|
174
|
+
return useMutation2({
|
|
175
|
+
mutationFn: async (params) => {
|
|
176
|
+
const query = client.from(table);
|
|
177
|
+
const builtQuery = params.buildQuery(query);
|
|
178
|
+
const { data: result, error } = await builtQuery.update(params.data);
|
|
179
|
+
if (error) {
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
},
|
|
184
|
+
onSuccess: () => {
|
|
185
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "table", table] });
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
function useUpsert(table) {
|
|
190
|
+
const client = useFluxbaseClient();
|
|
191
|
+
const queryClient = useQueryClient2();
|
|
192
|
+
return useMutation2({
|
|
193
|
+
mutationFn: async (data) => {
|
|
194
|
+
const query = client.from(table);
|
|
195
|
+
const { data: result, error } = await query.upsert(data);
|
|
196
|
+
if (error) {
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
},
|
|
201
|
+
onSuccess: () => {
|
|
202
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "table", table] });
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
function useDelete(table) {
|
|
207
|
+
const client = useFluxbaseClient();
|
|
208
|
+
const queryClient = useQueryClient2();
|
|
209
|
+
return useMutation2({
|
|
210
|
+
mutationFn: async (buildQuery) => {
|
|
211
|
+
const query = client.from(table);
|
|
212
|
+
const builtQuery = buildQuery(query);
|
|
213
|
+
const { error } = await builtQuery.delete();
|
|
214
|
+
if (error) {
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
onSuccess: () => {
|
|
219
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "table", table] });
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// src/use-realtime.ts
|
|
225
|
+
import { useEffect, useRef } from "react";
|
|
226
|
+
import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
|
|
227
|
+
function useRealtime(options) {
|
|
228
|
+
const client = useFluxbaseClient();
|
|
229
|
+
const queryClient = useQueryClient3();
|
|
230
|
+
const channelRef = useRef(null);
|
|
231
|
+
const {
|
|
232
|
+
channel: channelName,
|
|
233
|
+
event = "*",
|
|
234
|
+
callback,
|
|
235
|
+
autoInvalidate = true,
|
|
236
|
+
invalidateKey,
|
|
237
|
+
enabled = true
|
|
238
|
+
} = options;
|
|
239
|
+
useEffect(() => {
|
|
240
|
+
if (!enabled) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const channel = client.realtime.channel(channelName);
|
|
244
|
+
channelRef.current = channel;
|
|
245
|
+
const handleChange = (payload) => {
|
|
246
|
+
if (callback) {
|
|
247
|
+
callback(payload);
|
|
248
|
+
}
|
|
249
|
+
if (autoInvalidate) {
|
|
250
|
+
const tableName = channelName.replace(/^table:/, "");
|
|
251
|
+
const key = invalidateKey || ["fluxbase", "table", tableName];
|
|
252
|
+
queryClient.invalidateQueries({ queryKey: key });
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
channel.on(event, handleChange).subscribe();
|
|
256
|
+
return () => {
|
|
257
|
+
channel.unsubscribe();
|
|
258
|
+
channelRef.current = null;
|
|
259
|
+
};
|
|
260
|
+
}, [client, channelName, event, callback, autoInvalidate, invalidateKey, queryClient, enabled]);
|
|
261
|
+
return {
|
|
262
|
+
channel: channelRef.current
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
function useTableSubscription(table, options) {
|
|
266
|
+
return useRealtime({
|
|
267
|
+
...options,
|
|
268
|
+
channel: `table:${table}`
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function useTableInserts(table, callback, options) {
|
|
272
|
+
return useRealtime({
|
|
273
|
+
...options,
|
|
274
|
+
channel: `table:${table}`,
|
|
275
|
+
event: "INSERT",
|
|
276
|
+
callback
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
function useTableUpdates(table, callback, options) {
|
|
280
|
+
return useRealtime({
|
|
281
|
+
...options,
|
|
282
|
+
channel: `table:${table}`,
|
|
283
|
+
event: "UPDATE",
|
|
284
|
+
callback
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
function useTableDeletes(table, callback, options) {
|
|
288
|
+
return useRealtime({
|
|
289
|
+
...options,
|
|
290
|
+
channel: `table:${table}`,
|
|
291
|
+
event: "DELETE",
|
|
292
|
+
callback
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/use-storage.ts
|
|
297
|
+
import { useMutation as useMutation3, useQuery as useQuery3, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
|
|
298
|
+
function useStorageList(bucket, options) {
|
|
299
|
+
const client = useFluxbaseClient();
|
|
300
|
+
const { prefix, limit, offset, ...queryOptions } = options || {};
|
|
301
|
+
return useQuery3({
|
|
302
|
+
queryKey: ["fluxbase", "storage", bucket, "list", { prefix, limit, offset }],
|
|
303
|
+
queryFn: async () => {
|
|
304
|
+
const { data, error } = await client.storage.from(bucket).list({ prefix, limit, offset });
|
|
305
|
+
if (error) {
|
|
306
|
+
throw error;
|
|
307
|
+
}
|
|
308
|
+
return data || [];
|
|
309
|
+
},
|
|
310
|
+
...queryOptions
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
function useStorageUpload(bucket) {
|
|
314
|
+
const client = useFluxbaseClient();
|
|
315
|
+
const queryClient = useQueryClient4();
|
|
316
|
+
return useMutation3({
|
|
317
|
+
mutationFn: async (params) => {
|
|
318
|
+
const { path, file, options } = params;
|
|
319
|
+
const { data, error } = await client.storage.from(bucket).upload(path, file, options);
|
|
320
|
+
if (error) {
|
|
321
|
+
throw error;
|
|
322
|
+
}
|
|
323
|
+
return data;
|
|
324
|
+
},
|
|
325
|
+
onSuccess: () => {
|
|
326
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "storage", bucket, "list"] });
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
function useStorageDownload(bucket, path, enabled = true) {
|
|
331
|
+
const client = useFluxbaseClient();
|
|
332
|
+
return useQuery3({
|
|
333
|
+
queryKey: ["fluxbase", "storage", bucket, "download", path],
|
|
334
|
+
queryFn: async () => {
|
|
335
|
+
if (!path) {
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
const { data, error } = await client.storage.from(bucket).download(path);
|
|
339
|
+
if (error) {
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
342
|
+
return data;
|
|
343
|
+
},
|
|
344
|
+
enabled: enabled && !!path
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function useStorageDelete(bucket) {
|
|
348
|
+
const client = useFluxbaseClient();
|
|
349
|
+
const queryClient = useQueryClient4();
|
|
350
|
+
return useMutation3({
|
|
351
|
+
mutationFn: async (paths) => {
|
|
352
|
+
const { error } = await client.storage.from(bucket).remove(paths);
|
|
353
|
+
if (error) {
|
|
354
|
+
throw error;
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
onSuccess: () => {
|
|
358
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "storage", bucket, "list"] });
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
function useStoragePublicUrl(bucket, path) {
|
|
363
|
+
const client = useFluxbaseClient();
|
|
364
|
+
if (!path) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
const { data } = client.storage.from(bucket).getPublicUrl(path);
|
|
368
|
+
return data.publicUrl;
|
|
369
|
+
}
|
|
370
|
+
function useStorageSignedUrl(bucket, path, expiresIn) {
|
|
371
|
+
const client = useFluxbaseClient();
|
|
372
|
+
return useQuery3({
|
|
373
|
+
queryKey: ["fluxbase", "storage", bucket, "signed-url", path, expiresIn],
|
|
374
|
+
queryFn: async () => {
|
|
375
|
+
if (!path) {
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
const { data, error } = await client.storage.from(bucket).createSignedUrl(path, { expiresIn });
|
|
379
|
+
if (error) {
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
return data?.signedUrl || null;
|
|
383
|
+
},
|
|
384
|
+
enabled: !!path,
|
|
385
|
+
staleTime: expiresIn ? expiresIn * 1e3 - 6e4 : 1e3 * 60 * 50
|
|
386
|
+
// Refresh 1 minute before expiry
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
function useStorageMove(bucket) {
|
|
390
|
+
const client = useFluxbaseClient();
|
|
391
|
+
const queryClient = useQueryClient4();
|
|
392
|
+
return useMutation3({
|
|
393
|
+
mutationFn: async (params) => {
|
|
394
|
+
const { fromPath, toPath } = params;
|
|
395
|
+
const { data, error } = await client.storage.from(bucket).move(fromPath, toPath);
|
|
396
|
+
if (error) {
|
|
397
|
+
throw error;
|
|
398
|
+
}
|
|
399
|
+
return data;
|
|
400
|
+
},
|
|
401
|
+
onSuccess: () => {
|
|
402
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "storage", bucket, "list"] });
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
function useStorageCopy(bucket) {
|
|
407
|
+
const client = useFluxbaseClient();
|
|
408
|
+
const queryClient = useQueryClient4();
|
|
409
|
+
return useMutation3({
|
|
410
|
+
mutationFn: async (params) => {
|
|
411
|
+
const { fromPath, toPath } = params;
|
|
412
|
+
const { data, error } = await client.storage.from(bucket).copy(fromPath, toPath);
|
|
413
|
+
if (error) {
|
|
414
|
+
throw error;
|
|
415
|
+
}
|
|
416
|
+
return data;
|
|
417
|
+
},
|
|
418
|
+
onSuccess: () => {
|
|
419
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "storage", bucket, "list"] });
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
function useStorageBuckets() {
|
|
424
|
+
const client = useFluxbaseClient();
|
|
425
|
+
return useQuery3({
|
|
426
|
+
queryKey: ["fluxbase", "storage", "buckets"],
|
|
427
|
+
queryFn: async () => {
|
|
428
|
+
const { data, error } = await client.storage.listBuckets();
|
|
429
|
+
if (error) {
|
|
430
|
+
throw error;
|
|
431
|
+
}
|
|
432
|
+
return data || [];
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
function useCreateBucket() {
|
|
437
|
+
const client = useFluxbaseClient();
|
|
438
|
+
const queryClient = useQueryClient4();
|
|
439
|
+
return useMutation3({
|
|
440
|
+
mutationFn: async (bucketName) => {
|
|
441
|
+
const { error } = await client.storage.createBucket(bucketName);
|
|
442
|
+
if (error) {
|
|
443
|
+
throw error;
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
onSuccess: () => {
|
|
447
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "storage", "buckets"] });
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
function useDeleteBucket() {
|
|
452
|
+
const client = useFluxbaseClient();
|
|
453
|
+
const queryClient = useQueryClient4();
|
|
454
|
+
return useMutation3({
|
|
455
|
+
mutationFn: async (bucketName) => {
|
|
456
|
+
const { error } = await client.storage.deleteBucket(bucketName);
|
|
457
|
+
if (error) {
|
|
458
|
+
throw error;
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
onSuccess: () => {
|
|
462
|
+
queryClient.invalidateQueries({ queryKey: ["fluxbase", "storage", "buckets"] });
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// src/use-rpc.ts
|
|
468
|
+
import { useQuery as useQuery4, useMutation as useMutation4 } from "@tanstack/react-query";
|
|
469
|
+
function useRPC(functionName, params, options) {
|
|
470
|
+
const client = useFluxbaseClient();
|
|
471
|
+
return useQuery4({
|
|
472
|
+
queryKey: ["rpc", functionName, params],
|
|
473
|
+
queryFn: async () => {
|
|
474
|
+
const { data, error } = await client.rpc(functionName, params);
|
|
475
|
+
if (error) {
|
|
476
|
+
throw new Error(error.message);
|
|
477
|
+
}
|
|
478
|
+
return data;
|
|
479
|
+
},
|
|
480
|
+
...options
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
function useRPCMutation(functionName, options) {
|
|
484
|
+
const client = useFluxbaseClient();
|
|
485
|
+
return useMutation4({
|
|
486
|
+
mutationFn: async (params) => {
|
|
487
|
+
const { data, error } = await client.rpc(functionName, params);
|
|
488
|
+
if (error) {
|
|
489
|
+
throw new Error(error.message);
|
|
490
|
+
}
|
|
491
|
+
return data;
|
|
492
|
+
},
|
|
493
|
+
...options
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
function useRPCBatch(calls, options) {
|
|
497
|
+
const client = useFluxbaseClient();
|
|
498
|
+
return useQuery4({
|
|
499
|
+
queryKey: ["rpc-batch", calls],
|
|
500
|
+
queryFn: async () => {
|
|
501
|
+
const results = await Promise.all(
|
|
502
|
+
calls.map(async ({ name, params }) => {
|
|
503
|
+
const { data, error } = await client.rpc(name, params);
|
|
504
|
+
if (error) {
|
|
505
|
+
throw new Error(`${name}: ${error.message}`);
|
|
506
|
+
}
|
|
507
|
+
return data;
|
|
508
|
+
})
|
|
509
|
+
);
|
|
510
|
+
return results;
|
|
511
|
+
},
|
|
512
|
+
...options
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// src/use-admin-auth.ts
|
|
517
|
+
import { useState, useEffect as useEffect2, useCallback } from "react";
|
|
518
|
+
function useAdminAuth(options = {}) {
|
|
519
|
+
const { autoCheck = true } = options;
|
|
520
|
+
const client = useFluxbaseClient();
|
|
521
|
+
const [user, setUser] = useState(null);
|
|
522
|
+
const [isLoading, setIsLoading] = useState(autoCheck);
|
|
523
|
+
const [error, setError] = useState(null);
|
|
524
|
+
const checkAuth = useCallback(async () => {
|
|
525
|
+
try {
|
|
526
|
+
setIsLoading(true);
|
|
527
|
+
setError(null);
|
|
528
|
+
const { user: user2 } = await client.admin.me();
|
|
529
|
+
setUser(user2);
|
|
530
|
+
} catch (err) {
|
|
531
|
+
setUser(null);
|
|
532
|
+
setError(err);
|
|
533
|
+
} finally {
|
|
534
|
+
setIsLoading(false);
|
|
535
|
+
}
|
|
536
|
+
}, [client]);
|
|
537
|
+
const login = useCallback(
|
|
538
|
+
async (email, password) => {
|
|
539
|
+
try {
|
|
540
|
+
setIsLoading(true);
|
|
541
|
+
setError(null);
|
|
542
|
+
const response = await client.admin.login({ email, password });
|
|
543
|
+
setUser(response.user);
|
|
544
|
+
return response;
|
|
545
|
+
} catch (err) {
|
|
546
|
+
setError(err);
|
|
547
|
+
throw err;
|
|
548
|
+
} finally {
|
|
549
|
+
setIsLoading(false);
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
[client]
|
|
553
|
+
);
|
|
554
|
+
const logout = useCallback(async () => {
|
|
555
|
+
try {
|
|
556
|
+
setIsLoading(true);
|
|
557
|
+
setError(null);
|
|
558
|
+
setUser(null);
|
|
559
|
+
} catch (err) {
|
|
560
|
+
setError(err);
|
|
561
|
+
throw err;
|
|
562
|
+
} finally {
|
|
563
|
+
setIsLoading(false);
|
|
564
|
+
}
|
|
565
|
+
}, []);
|
|
566
|
+
const refresh = useCallback(async () => {
|
|
567
|
+
await checkAuth();
|
|
568
|
+
}, [checkAuth]);
|
|
569
|
+
useEffect2(() => {
|
|
570
|
+
if (autoCheck) {
|
|
571
|
+
checkAuth();
|
|
572
|
+
}
|
|
573
|
+
}, [autoCheck, checkAuth]);
|
|
574
|
+
return {
|
|
575
|
+
user,
|
|
576
|
+
isAuthenticated: user !== null,
|
|
577
|
+
isLoading,
|
|
578
|
+
error,
|
|
579
|
+
login,
|
|
580
|
+
logout,
|
|
581
|
+
refresh
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// src/use-users.ts
|
|
586
|
+
import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
|
|
587
|
+
function useUsers(options = {}) {
|
|
588
|
+
const { autoFetch = true, refetchInterval = 0, ...listOptions } = options;
|
|
589
|
+
const client = useFluxbaseClient();
|
|
590
|
+
const [users, setUsers] = useState2([]);
|
|
591
|
+
const [total, setTotal] = useState2(0);
|
|
592
|
+
const [isLoading, setIsLoading] = useState2(autoFetch);
|
|
593
|
+
const [error, setError] = useState2(null);
|
|
594
|
+
const fetchUsers = useCallback2(async () => {
|
|
595
|
+
try {
|
|
596
|
+
setIsLoading(true);
|
|
597
|
+
setError(null);
|
|
598
|
+
const response = await client.admin.listUsers(listOptions);
|
|
599
|
+
setUsers(response.users);
|
|
600
|
+
setTotal(response.total);
|
|
601
|
+
} catch (err) {
|
|
602
|
+
setError(err);
|
|
603
|
+
} finally {
|
|
604
|
+
setIsLoading(false);
|
|
605
|
+
}
|
|
606
|
+
}, [client, JSON.stringify(listOptions)]);
|
|
607
|
+
const inviteUser = useCallback2(
|
|
608
|
+
async (email, role) => {
|
|
609
|
+
await client.admin.inviteUser({ email, role });
|
|
610
|
+
await fetchUsers();
|
|
611
|
+
},
|
|
612
|
+
[client, fetchUsers]
|
|
613
|
+
);
|
|
614
|
+
const updateUserRole = useCallback2(
|
|
615
|
+
async (userId, role) => {
|
|
616
|
+
await client.admin.updateUserRole(userId, role);
|
|
617
|
+
await fetchUsers();
|
|
618
|
+
},
|
|
619
|
+
[client, fetchUsers]
|
|
620
|
+
);
|
|
621
|
+
const deleteUser = useCallback2(
|
|
622
|
+
async (userId) => {
|
|
623
|
+
await client.admin.deleteUser(userId);
|
|
624
|
+
await fetchUsers();
|
|
625
|
+
},
|
|
626
|
+
[client, fetchUsers]
|
|
627
|
+
);
|
|
628
|
+
const resetPassword = useCallback2(
|
|
629
|
+
async (userId) => {
|
|
630
|
+
return await client.admin.resetUserPassword(userId);
|
|
631
|
+
},
|
|
632
|
+
[client]
|
|
633
|
+
);
|
|
634
|
+
useEffect3(() => {
|
|
635
|
+
if (autoFetch) {
|
|
636
|
+
fetchUsers();
|
|
637
|
+
}
|
|
638
|
+
}, [autoFetch, fetchUsers]);
|
|
639
|
+
useEffect3(() => {
|
|
640
|
+
if (refetchInterval > 0) {
|
|
641
|
+
const interval = setInterval(fetchUsers, refetchInterval);
|
|
642
|
+
return () => clearInterval(interval);
|
|
643
|
+
}
|
|
644
|
+
}, [refetchInterval, fetchUsers]);
|
|
645
|
+
return {
|
|
646
|
+
users,
|
|
647
|
+
total,
|
|
648
|
+
isLoading,
|
|
649
|
+
error,
|
|
650
|
+
refetch: fetchUsers,
|
|
651
|
+
inviteUser,
|
|
652
|
+
updateUserRole,
|
|
653
|
+
deleteUser,
|
|
654
|
+
resetPassword
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// src/use-api-keys.ts
|
|
659
|
+
import { useState as useState3, useEffect as useEffect4, useCallback as useCallback3 } from "react";
|
|
660
|
+
function useAPIKeys(options = {}) {
|
|
661
|
+
const { autoFetch = true } = options;
|
|
662
|
+
const client = useFluxbaseClient();
|
|
663
|
+
const [keys, setKeys] = useState3([]);
|
|
664
|
+
const [isLoading, setIsLoading] = useState3(autoFetch);
|
|
665
|
+
const [error, setError] = useState3(null);
|
|
666
|
+
const fetchKeys = useCallback3(async () => {
|
|
667
|
+
try {
|
|
668
|
+
setIsLoading(true);
|
|
669
|
+
setError(null);
|
|
670
|
+
const response = await client.admin.management.apiKeys.list();
|
|
671
|
+
setKeys(response.api_keys);
|
|
672
|
+
} catch (err) {
|
|
673
|
+
setError(err);
|
|
674
|
+
} finally {
|
|
675
|
+
setIsLoading(false);
|
|
676
|
+
}
|
|
677
|
+
}, [client]);
|
|
678
|
+
const createKey = useCallback3(
|
|
679
|
+
async (request) => {
|
|
680
|
+
const response = await client.admin.management.apiKeys.create(request);
|
|
681
|
+
await fetchKeys();
|
|
682
|
+
return { key: response.key, keyData: response.api_key };
|
|
683
|
+
},
|
|
684
|
+
[client, fetchKeys]
|
|
685
|
+
);
|
|
686
|
+
const updateKey = useCallback3(
|
|
687
|
+
async (keyId, update) => {
|
|
688
|
+
await client.admin.management.apiKeys.update(keyId, update);
|
|
689
|
+
await fetchKeys();
|
|
690
|
+
},
|
|
691
|
+
[client, fetchKeys]
|
|
692
|
+
);
|
|
693
|
+
const revokeKey = useCallback3(
|
|
694
|
+
async (keyId) => {
|
|
695
|
+
await client.admin.management.apiKeys.revoke(keyId);
|
|
696
|
+
await fetchKeys();
|
|
697
|
+
},
|
|
698
|
+
[client, fetchKeys]
|
|
699
|
+
);
|
|
700
|
+
const deleteKey = useCallback3(
|
|
701
|
+
async (keyId) => {
|
|
702
|
+
await client.admin.management.apiKeys.delete(keyId);
|
|
703
|
+
await fetchKeys();
|
|
704
|
+
},
|
|
705
|
+
[client, fetchKeys]
|
|
706
|
+
);
|
|
707
|
+
useEffect4(() => {
|
|
708
|
+
if (autoFetch) {
|
|
709
|
+
fetchKeys();
|
|
710
|
+
}
|
|
711
|
+
}, [autoFetch, fetchKeys]);
|
|
712
|
+
return {
|
|
713
|
+
keys,
|
|
714
|
+
isLoading,
|
|
715
|
+
error,
|
|
716
|
+
refetch: fetchKeys,
|
|
717
|
+
createKey,
|
|
718
|
+
updateKey,
|
|
719
|
+
revokeKey,
|
|
720
|
+
deleteKey
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// src/use-admin-hooks.ts
|
|
725
|
+
import { useState as useState4, useEffect as useEffect5, useCallback as useCallback4 } from "react";
|
|
726
|
+
function useAppSettings(options = {}) {
|
|
727
|
+
const { autoFetch = true } = options;
|
|
728
|
+
const client = useFluxbaseClient();
|
|
729
|
+
const [settings, setSettings] = useState4(null);
|
|
730
|
+
const [isLoading, setIsLoading] = useState4(autoFetch);
|
|
731
|
+
const [error, setError] = useState4(null);
|
|
732
|
+
const fetchSettings = useCallback4(async () => {
|
|
733
|
+
try {
|
|
734
|
+
setIsLoading(true);
|
|
735
|
+
setError(null);
|
|
736
|
+
const appSettings = await client.admin.settings.app.get();
|
|
737
|
+
setSettings(appSettings);
|
|
738
|
+
} catch (err) {
|
|
739
|
+
setError(err);
|
|
740
|
+
} finally {
|
|
741
|
+
setIsLoading(false);
|
|
742
|
+
}
|
|
743
|
+
}, [client]);
|
|
744
|
+
const updateSettings = useCallback4(
|
|
745
|
+
async (update) => {
|
|
746
|
+
await client.admin.settings.app.update(update);
|
|
747
|
+
await fetchSettings();
|
|
748
|
+
},
|
|
749
|
+
[client, fetchSettings]
|
|
750
|
+
);
|
|
751
|
+
useEffect5(() => {
|
|
752
|
+
if (autoFetch) {
|
|
753
|
+
fetchSettings();
|
|
754
|
+
}
|
|
755
|
+
}, [autoFetch, fetchSettings]);
|
|
756
|
+
return {
|
|
757
|
+
settings,
|
|
758
|
+
isLoading,
|
|
759
|
+
error,
|
|
760
|
+
refetch: fetchSettings,
|
|
761
|
+
updateSettings
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
function useSystemSettings(options = {}) {
|
|
765
|
+
const { autoFetch = true } = options;
|
|
766
|
+
const client = useFluxbaseClient();
|
|
767
|
+
const [settings, setSettings] = useState4([]);
|
|
768
|
+
const [isLoading, setIsLoading] = useState4(autoFetch);
|
|
769
|
+
const [error, setError] = useState4(null);
|
|
770
|
+
const fetchSettings = useCallback4(async () => {
|
|
771
|
+
try {
|
|
772
|
+
setIsLoading(true);
|
|
773
|
+
setError(null);
|
|
774
|
+
const response = await client.admin.settings.system.list();
|
|
775
|
+
setSettings(response.settings);
|
|
776
|
+
} catch (err) {
|
|
777
|
+
setError(err);
|
|
778
|
+
} finally {
|
|
779
|
+
setIsLoading(false);
|
|
780
|
+
}
|
|
781
|
+
}, [client]);
|
|
782
|
+
const getSetting = useCallback4(
|
|
783
|
+
(key) => {
|
|
784
|
+
return settings.find((s) => s.key === key);
|
|
785
|
+
},
|
|
786
|
+
[settings]
|
|
787
|
+
);
|
|
788
|
+
const updateSetting = useCallback4(
|
|
789
|
+
async (key, update) => {
|
|
790
|
+
await client.admin.settings.system.update(key, update);
|
|
791
|
+
await fetchSettings();
|
|
792
|
+
},
|
|
793
|
+
[client, fetchSettings]
|
|
794
|
+
);
|
|
795
|
+
const deleteSetting = useCallback4(
|
|
796
|
+
async (key) => {
|
|
797
|
+
await client.admin.settings.system.delete(key);
|
|
798
|
+
await fetchSettings();
|
|
799
|
+
},
|
|
800
|
+
[client, fetchSettings]
|
|
801
|
+
);
|
|
802
|
+
useEffect5(() => {
|
|
803
|
+
if (autoFetch) {
|
|
804
|
+
fetchSettings();
|
|
805
|
+
}
|
|
806
|
+
}, [autoFetch, fetchSettings]);
|
|
807
|
+
return {
|
|
808
|
+
settings,
|
|
809
|
+
isLoading,
|
|
810
|
+
error,
|
|
811
|
+
refetch: fetchSettings,
|
|
812
|
+
getSetting,
|
|
813
|
+
updateSetting,
|
|
814
|
+
deleteSetting
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
function useWebhooks(options = {}) {
|
|
818
|
+
const { autoFetch = true, refetchInterval = 0 } = options;
|
|
819
|
+
const client = useFluxbaseClient();
|
|
820
|
+
const [webhooks, setWebhooks] = useState4([]);
|
|
821
|
+
const [isLoading, setIsLoading] = useState4(autoFetch);
|
|
822
|
+
const [error, setError] = useState4(null);
|
|
823
|
+
const fetchWebhooks = useCallback4(async () => {
|
|
824
|
+
try {
|
|
825
|
+
setIsLoading(true);
|
|
826
|
+
setError(null);
|
|
827
|
+
const response = await client.admin.management.webhooks.list();
|
|
828
|
+
setWebhooks(response.webhooks);
|
|
829
|
+
} catch (err) {
|
|
830
|
+
setError(err);
|
|
831
|
+
} finally {
|
|
832
|
+
setIsLoading(false);
|
|
833
|
+
}
|
|
834
|
+
}, [client]);
|
|
835
|
+
const createWebhook = useCallback4(
|
|
836
|
+
async (webhook) => {
|
|
837
|
+
const created = await client.admin.management.webhooks.create(webhook);
|
|
838
|
+
await fetchWebhooks();
|
|
839
|
+
return created;
|
|
840
|
+
},
|
|
841
|
+
[client, fetchWebhooks]
|
|
842
|
+
);
|
|
843
|
+
const updateWebhook = useCallback4(
|
|
844
|
+
async (id, update) => {
|
|
845
|
+
const updated = await client.admin.management.webhooks.update(id, update);
|
|
846
|
+
await fetchWebhooks();
|
|
847
|
+
return updated;
|
|
848
|
+
},
|
|
849
|
+
[client, fetchWebhooks]
|
|
850
|
+
);
|
|
851
|
+
const deleteWebhook = useCallback4(
|
|
852
|
+
async (id) => {
|
|
853
|
+
await client.admin.management.webhooks.delete(id);
|
|
854
|
+
await fetchWebhooks();
|
|
855
|
+
},
|
|
856
|
+
[client, fetchWebhooks]
|
|
857
|
+
);
|
|
858
|
+
const testWebhook = useCallback4(
|
|
859
|
+
async (id) => {
|
|
860
|
+
await client.admin.management.webhooks.test(id);
|
|
861
|
+
},
|
|
862
|
+
[client]
|
|
863
|
+
);
|
|
864
|
+
useEffect5(() => {
|
|
865
|
+
if (autoFetch) {
|
|
866
|
+
fetchWebhooks();
|
|
867
|
+
}
|
|
868
|
+
if (refetchInterval > 0) {
|
|
869
|
+
const interval = setInterval(fetchWebhooks, refetchInterval);
|
|
870
|
+
return () => clearInterval(interval);
|
|
871
|
+
}
|
|
872
|
+
}, [autoFetch, refetchInterval, fetchWebhooks]);
|
|
873
|
+
return {
|
|
874
|
+
webhooks,
|
|
875
|
+
isLoading,
|
|
876
|
+
error,
|
|
877
|
+
refetch: fetchWebhooks,
|
|
878
|
+
createWebhook,
|
|
879
|
+
updateWebhook,
|
|
880
|
+
deleteWebhook,
|
|
881
|
+
testWebhook
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
export {
|
|
885
|
+
FluxbaseProvider,
|
|
886
|
+
useAPIKeys,
|
|
887
|
+
useAdminAuth,
|
|
888
|
+
useAppSettings,
|
|
889
|
+
useAuth,
|
|
890
|
+
useCreateBucket,
|
|
891
|
+
useDelete,
|
|
892
|
+
useDeleteBucket,
|
|
893
|
+
useFluxbaseClient,
|
|
894
|
+
useFluxbaseQuery,
|
|
895
|
+
useInsert,
|
|
896
|
+
useRPC,
|
|
897
|
+
useRPCBatch,
|
|
898
|
+
useRPCMutation,
|
|
899
|
+
useRealtime,
|
|
900
|
+
useSession,
|
|
901
|
+
useSignIn,
|
|
902
|
+
useSignOut,
|
|
903
|
+
useSignUp,
|
|
904
|
+
useStorageBuckets,
|
|
905
|
+
useStorageCopy,
|
|
906
|
+
useStorageDelete,
|
|
907
|
+
useStorageDownload,
|
|
908
|
+
useStorageList,
|
|
909
|
+
useStorageMove,
|
|
910
|
+
useStoragePublicUrl,
|
|
911
|
+
useStorageSignedUrl,
|
|
912
|
+
useStorageUpload,
|
|
913
|
+
useSystemSettings,
|
|
914
|
+
useTable,
|
|
915
|
+
useTableDeletes,
|
|
916
|
+
useTableInserts,
|
|
917
|
+
useTableSubscription,
|
|
918
|
+
useTableUpdates,
|
|
919
|
+
useUpdate,
|
|
920
|
+
useUpdateUser,
|
|
921
|
+
useUpsert,
|
|
922
|
+
useUser,
|
|
923
|
+
useUsers,
|
|
924
|
+
useWebhooks
|
|
925
|
+
};
|
|
926
|
+
//# sourceMappingURL=index.mjs.map
|