@nimbleflux/fluxbase-sdk-react 2026.3.6-rc.1
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/.nvmrc +1 -0
- package/README-ADMIN.md +1076 -0
- package/README.md +195 -0
- package/examples/AdminDashboard.tsx +513 -0
- package/examples/README.md +163 -0
- package/package.json +66 -0
- package/src/context.test.tsx +147 -0
- package/src/context.tsx +33 -0
- package/src/index.test.ts +255 -0
- package/src/index.ts +175 -0
- package/src/test-setup.ts +22 -0
- package/src/test-utils.tsx +215 -0
- package/src/use-admin-auth.test.ts +175 -0
- package/src/use-admin-auth.ts +187 -0
- package/src/use-admin-hooks.test.ts +457 -0
- package/src/use-admin-hooks.ts +309 -0
- package/src/use-auth-config.test.ts +145 -0
- package/src/use-auth-config.ts +101 -0
- package/src/use-auth.test.ts +313 -0
- package/src/use-auth.ts +164 -0
- package/src/use-captcha.test.ts +273 -0
- package/src/use-captcha.ts +250 -0
- package/src/use-client-keys.test.ts +286 -0
- package/src/use-client-keys.ts +185 -0
- package/src/use-graphql.test.ts +424 -0
- package/src/use-graphql.ts +392 -0
- package/src/use-query.test.ts +348 -0
- package/src/use-query.ts +211 -0
- package/src/use-realtime.test.ts +359 -0
- package/src/use-realtime.ts +180 -0
- package/src/use-saml.test.ts +269 -0
- package/src/use-saml.ts +221 -0
- package/src/use-storage.test.ts +549 -0
- package/src/use-storage.ts +508 -0
- package/src/use-table-export.ts +481 -0
- package/src/use-users.test.ts +264 -0
- package/src/use-users.ts +198 -0
- package/tsconfig.json +28 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsup.config.ts +11 -0
- package/typedoc.json +33 -0
- package/vitest.config.ts +22 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table Export Hooks
|
|
3
|
+
*
|
|
4
|
+
* React hooks for exporting database tables to knowledge bases and managing sync configurations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useEffect, useCallback } from 'react'
|
|
8
|
+
import { useFluxbaseClient } from './context'
|
|
9
|
+
import type {
|
|
10
|
+
ExportTableOptions,
|
|
11
|
+
ExportTableResult,
|
|
12
|
+
TableDetails,
|
|
13
|
+
TableExportSyncConfig,
|
|
14
|
+
CreateTableExportSyncConfig,
|
|
15
|
+
UpdateTableExportSyncConfig,
|
|
16
|
+
} from '@fluxbase/sdk'
|
|
17
|
+
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// useTableDetails Hook
|
|
20
|
+
// ============================================================================
|
|
21
|
+
|
|
22
|
+
export interface UseTableDetailsOptions {
|
|
23
|
+
schema?: string
|
|
24
|
+
table?: string
|
|
25
|
+
autoFetch?: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface UseTableDetailsReturn {
|
|
29
|
+
data: TableDetails | null
|
|
30
|
+
isLoading: boolean
|
|
31
|
+
error: Error | null
|
|
32
|
+
refetch: () => Promise<void>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Hook for fetching detailed table information including columns
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* function TableColumnsList({ schema, table }: { schema: string; table: string }) {
|
|
41
|
+
* const { data, isLoading, error } = useTableDetails({ schema, table })
|
|
42
|
+
*
|
|
43
|
+
* if (isLoading) return <div>Loading...</div>
|
|
44
|
+
* if (error) return <div>Error: {error.message}</div>
|
|
45
|
+
*
|
|
46
|
+
* return (
|
|
47
|
+
* <ul>
|
|
48
|
+
* {data?.columns.map(col => (
|
|
49
|
+
* <li key={col.name}>
|
|
50
|
+
* {col.name} ({col.data_type})
|
|
51
|
+
* {col.is_primary_key && ' 🔑'}
|
|
52
|
+
* </li>
|
|
53
|
+
* ))}
|
|
54
|
+
* </ul>
|
|
55
|
+
* )
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function useTableDetails(options: UseTableDetailsOptions): UseTableDetailsReturn {
|
|
60
|
+
const { schema, table, autoFetch = true } = options
|
|
61
|
+
const client = useFluxbaseClient()
|
|
62
|
+
|
|
63
|
+
const [data, setData] = useState<TableDetails | null>(null)
|
|
64
|
+
const [isLoading, setIsLoading] = useState(autoFetch && !!schema && !!table)
|
|
65
|
+
const [error, setError] = useState<Error | null>(null)
|
|
66
|
+
|
|
67
|
+
const fetchData = useCallback(async () => {
|
|
68
|
+
if (!schema || !table) return
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
setIsLoading(true)
|
|
72
|
+
setError(null)
|
|
73
|
+
const result = await client.admin.ai.getTableDetails(schema, table)
|
|
74
|
+
if (result.error) {
|
|
75
|
+
throw result.error
|
|
76
|
+
}
|
|
77
|
+
setData(result.data)
|
|
78
|
+
} catch (err) {
|
|
79
|
+
setError(err as Error)
|
|
80
|
+
} finally {
|
|
81
|
+
setIsLoading(false)
|
|
82
|
+
}
|
|
83
|
+
}, [client, schema, table])
|
|
84
|
+
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (autoFetch && schema && table) {
|
|
87
|
+
fetchData()
|
|
88
|
+
}
|
|
89
|
+
}, [autoFetch, fetchData, schema, table])
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
data,
|
|
93
|
+
isLoading,
|
|
94
|
+
error,
|
|
95
|
+
refetch: fetchData,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// useExportTable Hook
|
|
101
|
+
// ============================================================================
|
|
102
|
+
|
|
103
|
+
export interface UseExportTableReturn {
|
|
104
|
+
exportTable: (options: ExportTableOptions) => Promise<ExportTableResult | null>
|
|
105
|
+
isLoading: boolean
|
|
106
|
+
error: Error | null
|
|
107
|
+
reset: () => void
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Hook for exporting a table to a knowledge base
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```tsx
|
|
115
|
+
* function ExportTableButton({ kbId, schema, table }: Props) {
|
|
116
|
+
* const { exportTable, isLoading, error } = useExportTable(kbId)
|
|
117
|
+
*
|
|
118
|
+
* const handleExport = async () => {
|
|
119
|
+
* const result = await exportTable({
|
|
120
|
+
* schema,
|
|
121
|
+
* table,
|
|
122
|
+
* columns: ['id', 'name', 'email'],
|
|
123
|
+
* include_foreign_keys: true,
|
|
124
|
+
* })
|
|
125
|
+
* if (result) {
|
|
126
|
+
* console.log('Exported document:', result.document_id)
|
|
127
|
+
* }
|
|
128
|
+
* }
|
|
129
|
+
*
|
|
130
|
+
* return (
|
|
131
|
+
* <button onClick={handleExport} disabled={isLoading}>
|
|
132
|
+
* {isLoading ? 'Exporting...' : 'Export Table'}
|
|
133
|
+
* </button>
|
|
134
|
+
* )
|
|
135
|
+
* }
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export function useExportTable(knowledgeBaseId: string): UseExportTableReturn {
|
|
139
|
+
const client = useFluxbaseClient()
|
|
140
|
+
|
|
141
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
142
|
+
const [error, setError] = useState<Error | null>(null)
|
|
143
|
+
|
|
144
|
+
const exportTable = useCallback(
|
|
145
|
+
async (options: ExportTableOptions): Promise<ExportTableResult | null> => {
|
|
146
|
+
try {
|
|
147
|
+
setIsLoading(true)
|
|
148
|
+
setError(null)
|
|
149
|
+
const result = await client.admin.ai.exportTable(knowledgeBaseId, options)
|
|
150
|
+
if (result.error) {
|
|
151
|
+
throw result.error
|
|
152
|
+
}
|
|
153
|
+
return result.data
|
|
154
|
+
} catch (err) {
|
|
155
|
+
setError(err as Error)
|
|
156
|
+
return null
|
|
157
|
+
} finally {
|
|
158
|
+
setIsLoading(false)
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
[client, knowledgeBaseId],
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
const reset = useCallback(() => {
|
|
165
|
+
setError(null)
|
|
166
|
+
setIsLoading(false)
|
|
167
|
+
}, [])
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
exportTable,
|
|
171
|
+
isLoading,
|
|
172
|
+
error,
|
|
173
|
+
reset,
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// useTableExportSyncs Hook
|
|
179
|
+
// ============================================================================
|
|
180
|
+
|
|
181
|
+
export interface UseTableExportSyncsOptions {
|
|
182
|
+
autoFetch?: boolean
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface UseTableExportSyncsReturn {
|
|
186
|
+
configs: TableExportSyncConfig[]
|
|
187
|
+
isLoading: boolean
|
|
188
|
+
error: Error | null
|
|
189
|
+
refetch: () => Promise<void>
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Hook for listing table export sync configurations
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```tsx
|
|
197
|
+
* function SyncConfigsList({ kbId }: { kbId: string }) {
|
|
198
|
+
* const { configs, isLoading, error } = useTableExportSyncs(kbId)
|
|
199
|
+
*
|
|
200
|
+
* if (isLoading) return <div>Loading...</div>
|
|
201
|
+
*
|
|
202
|
+
* return (
|
|
203
|
+
* <ul>
|
|
204
|
+
* {configs.map(config => (
|
|
205
|
+
* <li key={config.id}>
|
|
206
|
+
* {config.schema_name}.{config.table_name} ({config.sync_mode})
|
|
207
|
+
* </li>
|
|
208
|
+
* ))}
|
|
209
|
+
* </ul>
|
|
210
|
+
* )
|
|
211
|
+
* }
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export function useTableExportSyncs(
|
|
215
|
+
knowledgeBaseId: string,
|
|
216
|
+
options: UseTableExportSyncsOptions = {},
|
|
217
|
+
): UseTableExportSyncsReturn {
|
|
218
|
+
const { autoFetch = true } = options
|
|
219
|
+
const client = useFluxbaseClient()
|
|
220
|
+
|
|
221
|
+
const [configs, setConfigs] = useState<TableExportSyncConfig[]>([])
|
|
222
|
+
const [isLoading, setIsLoading] = useState(autoFetch)
|
|
223
|
+
const [error, setError] = useState<Error | null>(null)
|
|
224
|
+
|
|
225
|
+
const fetchData = useCallback(async () => {
|
|
226
|
+
try {
|
|
227
|
+
setIsLoading(true)
|
|
228
|
+
setError(null)
|
|
229
|
+
const result = await client.admin.ai.listTableExportSyncs(knowledgeBaseId)
|
|
230
|
+
if (result.error) {
|
|
231
|
+
throw result.error
|
|
232
|
+
}
|
|
233
|
+
setConfigs(result.data || [])
|
|
234
|
+
} catch (err) {
|
|
235
|
+
setError(err as Error)
|
|
236
|
+
} finally {
|
|
237
|
+
setIsLoading(false)
|
|
238
|
+
}
|
|
239
|
+
}, [client, knowledgeBaseId])
|
|
240
|
+
|
|
241
|
+
useEffect(() => {
|
|
242
|
+
if (autoFetch) {
|
|
243
|
+
fetchData()
|
|
244
|
+
}
|
|
245
|
+
}, [autoFetch, fetchData])
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
configs,
|
|
249
|
+
isLoading,
|
|
250
|
+
error,
|
|
251
|
+
refetch: fetchData,
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// ============================================================================
|
|
256
|
+
// useCreateTableExportSync Hook
|
|
257
|
+
// ============================================================================
|
|
258
|
+
|
|
259
|
+
export interface UseCreateTableExportSyncReturn {
|
|
260
|
+
createSync: (config: CreateTableExportSyncConfig) => Promise<TableExportSyncConfig | null>
|
|
261
|
+
isLoading: boolean
|
|
262
|
+
error: Error | null
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Hook for creating a table export sync configuration
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```tsx
|
|
270
|
+
* function CreateSyncForm({ kbId }: { kbId: string }) {
|
|
271
|
+
* const { createSync, isLoading, error } = useCreateTableExportSync(kbId)
|
|
272
|
+
*
|
|
273
|
+
* const handleSubmit = async (e: React.FormEvent) => {
|
|
274
|
+
* e.preventDefault()
|
|
275
|
+
* const config = await createSync({
|
|
276
|
+
* schema_name: 'public',
|
|
277
|
+
* table_name: 'users',
|
|
278
|
+
* columns: ['id', 'name', 'email'],
|
|
279
|
+
* sync_mode: 'automatic',
|
|
280
|
+
* sync_on_insert: true,
|
|
281
|
+
* sync_on_update: true,
|
|
282
|
+
* })
|
|
283
|
+
* if (config) {
|
|
284
|
+
* console.log('Created sync config:', config.id)
|
|
285
|
+
* }
|
|
286
|
+
* }
|
|
287
|
+
*
|
|
288
|
+
* return <form onSubmit={handleSubmit}>...</form>
|
|
289
|
+
* }
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export function useCreateTableExportSync(knowledgeBaseId: string): UseCreateTableExportSyncReturn {
|
|
293
|
+
const client = useFluxbaseClient()
|
|
294
|
+
|
|
295
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
296
|
+
const [error, setError] = useState<Error | null>(null)
|
|
297
|
+
|
|
298
|
+
const createSync = useCallback(
|
|
299
|
+
async (config: CreateTableExportSyncConfig): Promise<TableExportSyncConfig | null> => {
|
|
300
|
+
try {
|
|
301
|
+
setIsLoading(true)
|
|
302
|
+
setError(null)
|
|
303
|
+
const result = await client.admin.ai.createTableExportSync(knowledgeBaseId, config)
|
|
304
|
+
if (result.error) {
|
|
305
|
+
throw result.error
|
|
306
|
+
}
|
|
307
|
+
return result.data
|
|
308
|
+
} catch (err) {
|
|
309
|
+
setError(err as Error)
|
|
310
|
+
return null
|
|
311
|
+
} finally {
|
|
312
|
+
setIsLoading(false)
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
[client, knowledgeBaseId],
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
createSync,
|
|
320
|
+
isLoading,
|
|
321
|
+
error,
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// ============================================================================
|
|
326
|
+
// useUpdateTableExportSync Hook
|
|
327
|
+
// ============================================================================
|
|
328
|
+
|
|
329
|
+
export interface UseUpdateTableExportSyncReturn {
|
|
330
|
+
updateSync: (syncId: string, updates: UpdateTableExportSyncConfig) => Promise<TableExportSyncConfig | null>
|
|
331
|
+
isLoading: boolean
|
|
332
|
+
error: Error | null
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Hook for updating a table export sync configuration
|
|
337
|
+
*/
|
|
338
|
+
export function useUpdateTableExportSync(knowledgeBaseId: string): UseUpdateTableExportSyncReturn {
|
|
339
|
+
const client = useFluxbaseClient()
|
|
340
|
+
|
|
341
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
342
|
+
const [error, setError] = useState<Error | null>(null)
|
|
343
|
+
|
|
344
|
+
const updateSync = useCallback(
|
|
345
|
+
async (syncId: string, updates: UpdateTableExportSyncConfig): Promise<TableExportSyncConfig | null> => {
|
|
346
|
+
try {
|
|
347
|
+
setIsLoading(true)
|
|
348
|
+
setError(null)
|
|
349
|
+
const result = await client.admin.ai.updateTableExportSync(knowledgeBaseId, syncId, updates)
|
|
350
|
+
if (result.error) {
|
|
351
|
+
throw result.error
|
|
352
|
+
}
|
|
353
|
+
return result.data
|
|
354
|
+
} catch (err) {
|
|
355
|
+
setError(err as Error)
|
|
356
|
+
return null
|
|
357
|
+
} finally {
|
|
358
|
+
setIsLoading(false)
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
[client, knowledgeBaseId],
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
updateSync,
|
|
366
|
+
isLoading,
|
|
367
|
+
error,
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ============================================================================
|
|
372
|
+
// useDeleteTableExportSync Hook
|
|
373
|
+
// ============================================================================
|
|
374
|
+
|
|
375
|
+
export interface UseDeleteTableExportSyncReturn {
|
|
376
|
+
deleteSync: (syncId: string) => Promise<boolean>
|
|
377
|
+
isLoading: boolean
|
|
378
|
+
error: Error | null
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Hook for deleting a table export sync configuration
|
|
383
|
+
*/
|
|
384
|
+
export function useDeleteTableExportSync(knowledgeBaseId: string): UseDeleteTableExportSyncReturn {
|
|
385
|
+
const client = useFluxbaseClient()
|
|
386
|
+
|
|
387
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
388
|
+
const [error, setError] = useState<Error | null>(null)
|
|
389
|
+
|
|
390
|
+
const deleteSync = useCallback(
|
|
391
|
+
async (syncId: string): Promise<boolean> => {
|
|
392
|
+
try {
|
|
393
|
+
setIsLoading(true)
|
|
394
|
+
setError(null)
|
|
395
|
+
const result = await client.admin.ai.deleteTableExportSync(knowledgeBaseId, syncId)
|
|
396
|
+
if (result.error) {
|
|
397
|
+
throw result.error
|
|
398
|
+
}
|
|
399
|
+
return true
|
|
400
|
+
} catch (err) {
|
|
401
|
+
setError(err as Error)
|
|
402
|
+
return false
|
|
403
|
+
} finally {
|
|
404
|
+
setIsLoading(false)
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
[client, knowledgeBaseId],
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
return {
|
|
411
|
+
deleteSync,
|
|
412
|
+
isLoading,
|
|
413
|
+
error,
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// ============================================================================
|
|
418
|
+
// useTriggerTableExportSync Hook
|
|
419
|
+
// ============================================================================
|
|
420
|
+
|
|
421
|
+
export interface UseTriggerTableExportSyncReturn {
|
|
422
|
+
triggerSync: (syncId: string) => Promise<ExportTableResult | null>
|
|
423
|
+
isLoading: boolean
|
|
424
|
+
error: Error | null
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Hook for manually triggering a table export sync
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```tsx
|
|
432
|
+
* function TriggerSyncButton({ kbId, syncId }: Props) {
|
|
433
|
+
* const { triggerSync, isLoading, error } = useTriggerTableExportSync(kbId)
|
|
434
|
+
*
|
|
435
|
+
* const handleTrigger = async () => {
|
|
436
|
+
* const result = await triggerSync(syncId)
|
|
437
|
+
* if (result) {
|
|
438
|
+
* console.log('Sync completed:', result.document_id)
|
|
439
|
+
* }
|
|
440
|
+
* }
|
|
441
|
+
*
|
|
442
|
+
* return (
|
|
443
|
+
* <button onClick={handleTrigger} disabled={isLoading}>
|
|
444
|
+
* {isLoading ? 'Syncing...' : 'Sync Now'}
|
|
445
|
+
* </button>
|
|
446
|
+
* )
|
|
447
|
+
* }
|
|
448
|
+
* ```
|
|
449
|
+
*/
|
|
450
|
+
export function useTriggerTableExportSync(knowledgeBaseId: string): UseTriggerTableExportSyncReturn {
|
|
451
|
+
const client = useFluxbaseClient()
|
|
452
|
+
|
|
453
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
454
|
+
const [error, setError] = useState<Error | null>(null)
|
|
455
|
+
|
|
456
|
+
const triggerSync = useCallback(
|
|
457
|
+
async (syncId: string): Promise<ExportTableResult | null> => {
|
|
458
|
+
try {
|
|
459
|
+
setIsLoading(true)
|
|
460
|
+
setError(null)
|
|
461
|
+
const result = await client.admin.ai.triggerTableExportSync(knowledgeBaseId, syncId)
|
|
462
|
+
if (result.error) {
|
|
463
|
+
throw result.error
|
|
464
|
+
}
|
|
465
|
+
return result.data
|
|
466
|
+
} catch (err) {
|
|
467
|
+
setError(err as Error)
|
|
468
|
+
return null
|
|
469
|
+
} finally {
|
|
470
|
+
setIsLoading(false)
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
[client, knowledgeBaseId],
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
return {
|
|
477
|
+
triggerSync,
|
|
478
|
+
isLoading,
|
|
479
|
+
error,
|
|
480
|
+
}
|
|
481
|
+
}
|