asasvirtuais 1.1.1 → 2.0.0
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/package.json +1 -1
- package/packages/hooks.tsx +2 -2
- package/packages/interface.ts +5 -3
- package/packages/react-interface.tsx +243 -322
package/package.json
CHANGED
package/packages/hooks.tsx
CHANGED
|
@@ -80,7 +80,7 @@ export function useIndex<T>(value: Record<string, any>) {
|
|
|
80
80
|
}))
|
|
81
81
|
}, [])
|
|
82
82
|
|
|
83
|
-
const
|
|
83
|
+
const unset = useCallback((...params: readable[]) => {
|
|
84
84
|
setIndex(prev => {
|
|
85
85
|
const newState = { ...prev }
|
|
86
86
|
for (const data of params) {
|
|
@@ -97,7 +97,7 @@ export function useIndex<T>(value: Record<string, any>) {
|
|
|
97
97
|
array,
|
|
98
98
|
set,
|
|
99
99
|
setIndex,
|
|
100
|
-
|
|
100
|
+
unset,
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
package/packages/interface.ts
CHANGED
|
@@ -8,12 +8,14 @@ export interface TableInterface<Readable, Writable = Readable> {
|
|
|
8
8
|
list (props: ListProps<Readable>) : Promise<Readable[]>
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export function tableInterface<Schema extends
|
|
11
|
+
export function tableInterface<Schema extends DatabaseSchema, Table extends keyof Schema & string>(schema: Schema, table?: Table | null, tableInterface?: TableInterface<z.infer<Schema[Table]['readable']>, z.infer<Schema[Table]['writable']>>) {
|
|
12
12
|
return tableInterface
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export interface
|
|
16
|
-
|
|
15
|
+
export interface TableSchema { readable: z.ZodObject<z.ZodRawShape>, writable: z.ZodObject<z.ZodRawShape> }
|
|
16
|
+
|
|
17
|
+
export interface DatabaseSchema {
|
|
18
|
+
[T: string]: TableSchema
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
export type BasicOperators<T, K extends keyof T> = {
|
|
@@ -1,394 +1,315 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
useEffect,
|
|
6
|
-
useMemo,
|
|
7
|
-
createContext,
|
|
8
|
-
useContext,
|
|
9
|
-
} from 'react'
|
|
10
|
-
import { useAction as useAsyncAction, useIndex } from './hooks'
|
|
1
|
+
import z from 'zod'
|
|
2
|
+
import { DatabaseSchema, ListProps, TableInterface, TableSchema } from './interface'
|
|
3
|
+
import { createContextFromHook, useAction as useAsyncAction, useIndex } from './hooks'
|
|
4
|
+
import { createContext, PropsWithChildren, useCallback, useContext, useEffect, useState } from 'react'
|
|
11
5
|
import { ActionProvider, useAction, useActionProvider } from './action'
|
|
12
|
-
import { TableInterface, ListProps, DatabaseInterface } from './interface'
|
|
13
6
|
import { FieldsProvider, useFields } from './fields'
|
|
14
7
|
|
|
15
|
-
export function
|
|
16
|
-
Database extends DatabaseInterface>(
|
|
17
|
-
database: Database,
|
|
18
|
-
{
|
|
19
|
-
find,
|
|
20
|
-
create,
|
|
21
|
-
update,
|
|
22
|
-
remove,
|
|
23
|
-
list,
|
|
24
|
-
}: TableInterface<
|
|
25
|
-
z.infer<Database[keyof Database]['readable']>,
|
|
26
|
-
z.infer<Database[keyof Database]['writable']>
|
|
27
|
-
>
|
|
28
|
-
) {
|
|
29
|
-
type TableKey = keyof Database & string
|
|
30
|
-
|
|
31
|
-
type TableProviderProps<Table extends TableKey> = {
|
|
32
|
-
table: Table
|
|
33
|
-
asAbove?: Record<string, z.infer<Database[Table]["readable"]>>
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function useTableProvider<Table extends TableKey>({
|
|
37
|
-
table,
|
|
38
|
-
asAbove,
|
|
39
|
-
}: TableProviderProps<Table>) {
|
|
40
|
-
type Readable = z.infer<Database[Table]['readable']>
|
|
41
|
-
type Writable = z.infer<Database[Table]['writable']>
|
|
42
|
-
|
|
43
|
-
const index = useIndex<Readable>({ ...(asAbove ?? {}) })
|
|
8
|
+
export function useDatabaseProvider() {
|
|
44
9
|
|
|
45
|
-
const
|
|
46
|
-
() => Object.values(index.index) as Readable[],
|
|
47
|
-
[index.index]
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
useEffect(function soBelow() {
|
|
51
|
-
index.setIndex((prev) => ({ ...prev, ...asAbove }))
|
|
52
|
-
}, [])
|
|
53
|
-
|
|
54
|
-
const methods = { find, create, update, remove, list } as TableInterface<
|
|
55
|
-
Readable,
|
|
56
|
-
Writable
|
|
57
|
-
>
|
|
10
|
+
const [database, setDatabase] = useState<Record<string, ReturnType<typeof useInterface<any>>>>({})
|
|
58
11
|
|
|
59
12
|
return {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
find: useAsyncAction(((props) => methods.find({ ...props, table }).then(res => {
|
|
63
|
-
index.set(res)
|
|
64
|
-
return res
|
|
65
|
-
})) as typeof find),
|
|
66
|
-
create: useAsyncAction(((props) => create({ ...props, table }).then(res => {
|
|
67
|
-
index.set(res)
|
|
68
|
-
return res
|
|
69
|
-
})) as typeof create),
|
|
70
|
-
update: useAsyncAction(((props) => update({ ...props, table }).then(res => {
|
|
71
|
-
index.set(res)
|
|
72
|
-
return res
|
|
73
|
-
})) as typeof update),
|
|
74
|
-
remove: useAsyncAction(((props) => remove({ ...props, table }).then(res => {
|
|
75
|
-
index.remove(res)
|
|
76
|
-
return res
|
|
77
|
-
})) as typeof remove),
|
|
78
|
-
list: useAsyncAction(((props) => list({ ...props, table }).then(arr => {
|
|
79
|
-
index.set(...arr)
|
|
80
|
-
return arr
|
|
81
|
-
})) as typeof list),
|
|
13
|
+
database,
|
|
14
|
+
setDatabase,
|
|
82
15
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
function useDatabaseProvider(tables: { [T in TableKey]: Record<string, z.infer<Database[T]['readable']>> }): {
|
|
86
|
-
[T in TableKey]: ReturnType<typeof useTableProvider<T>>
|
|
87
|
-
} {
|
|
88
|
-
return Object.fromEntries(
|
|
89
|
-
Object.entries(tables).map(([table, value]) => [
|
|
90
|
-
table, useTableProvider({ table: table as TableKey, asAbove: value })
|
|
91
|
-
])
|
|
92
|
-
) as {
|
|
93
|
-
[T in TableKey]: ReturnType<typeof useTableProvider<T>>
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// Create a separate context for each table dynamically
|
|
97
|
-
const tableContexts = new Map<TableKey, React.Context<ReturnType<typeof useTableProvider<any>> | undefined>>();
|
|
98
|
-
|
|
99
|
-
function getTableContext<T extends TableKey>(table: T) {
|
|
100
|
-
if (!tableContexts.has(table)) {
|
|
101
|
-
tableContexts.set(table, createContext<ReturnType<typeof useTableProvider<T>> | undefined>(undefined));
|
|
102
|
-
}
|
|
103
|
-
return tableContexts.get(table)!;
|
|
104
|
-
}
|
|
16
|
+
}
|
|
105
17
|
|
|
106
|
-
|
|
107
|
-
children: React.ReactNode | ((props: ReturnType<typeof useTableProvider<Table>>) => React.ReactNode)
|
|
108
|
-
}) {
|
|
109
|
-
const context = useTableProvider(props);
|
|
110
|
-
const TableContext = getTableContext(props.table);
|
|
18
|
+
export const [DatabaseProvider, useDatabase] = createContextFromHook(useDatabaseProvider)
|
|
111
19
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{typeof children === 'function' ? children(context) : children}
|
|
115
|
-
</TableContext.Provider>
|
|
116
|
-
)
|
|
117
|
-
}
|
|
20
|
+
export function useDatabaseTable<TSchema extends TableSchema>(table: string) {
|
|
21
|
+
const { database } = useDatabase()
|
|
118
22
|
|
|
119
|
-
|
|
120
|
-
children,
|
|
121
|
-
...tables
|
|
122
|
-
}: React.PropsWithChildren<{
|
|
123
|
-
[T in TableKey]?: Record<string, z.infer<Database[T]['readable']>>
|
|
124
|
-
}>) {
|
|
125
|
-
return Object.entries(tables).reduce(
|
|
126
|
-
(prev, [table, asAbove]) => {
|
|
127
|
-
return (
|
|
128
|
-
<TableProvider table={table as TableKey} asAbove={asAbove}>
|
|
129
|
-
{prev}
|
|
130
|
-
</TableProvider>
|
|
131
|
-
);
|
|
132
|
-
},
|
|
133
|
-
children as React.ReactNode
|
|
134
|
-
)
|
|
135
|
-
}
|
|
23
|
+
const tableMethods = database[table] as ReturnType<typeof useInterface<TSchema>> | undefined
|
|
136
24
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const context = useContext(TableContext);
|
|
25
|
+
if (!tableMethods)
|
|
26
|
+
throw new Error(`Table "${table}" is not defined in the database schema.`)
|
|
140
27
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
28
|
+
return tableMethods
|
|
29
|
+
}
|
|
144
30
|
|
|
145
|
-
|
|
146
|
-
|
|
31
|
+
export type TableProviderProps<TSchema extends TableSchema> = {
|
|
32
|
+
table: string
|
|
33
|
+
schema: TSchema
|
|
34
|
+
interface: TableInterface<z.infer<TSchema['readable']>, z.infer<TSchema['writable']>>
|
|
35
|
+
asAbove?: Record<string, z.infer<TSchema['readable']>>
|
|
36
|
+
}
|
|
147
37
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}: {
|
|
152
|
-
id: string
|
|
153
|
-
table: Table
|
|
154
|
-
}) {
|
|
155
|
-
const { index, find } = useTable(table)
|
|
156
|
-
const [single, setSingle] = useState<z.infer<Database[Table]['readable']>>(
|
|
157
|
-
() => index[id]
|
|
158
|
-
)
|
|
159
|
-
useEffect(() => {
|
|
160
|
-
if (!single) find.trigger({ id }).then(setSingle)
|
|
161
|
-
}, [])
|
|
162
|
-
useEffect(() => {
|
|
163
|
-
setSingle(index[id])
|
|
164
|
-
}, [index[id]])
|
|
38
|
+
export function useInterface<TSchema extends TableSchema>(table: string, {
|
|
39
|
+
find, create, update, remove, list
|
|
40
|
+
}: TableInterface<z.infer<TSchema['readable']>, z.infer<TSchema['writable']>>, index: ReturnType<typeof useIndex<z.infer<TSchema['readable']>>>) {
|
|
165
41
|
return {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
42
|
+
index,
|
|
43
|
+
find: useAsyncAction(((props) => find({ ...props, table }).then(res => {
|
|
44
|
+
index.set(res)
|
|
45
|
+
return res
|
|
46
|
+
})) as typeof find),
|
|
47
|
+
create: useAsyncAction(((props) => create({ ...props, table }).then(res => {
|
|
48
|
+
index.set(res)
|
|
49
|
+
return res
|
|
50
|
+
})) as typeof create),
|
|
51
|
+
update: useAsyncAction(((props) => update({ ...props, table }).then(res => {
|
|
52
|
+
index.set(res)
|
|
53
|
+
return res
|
|
54
|
+
})) as typeof update),
|
|
55
|
+
remove: useAsyncAction(((props) => remove({ ...props, table }).then(res => {
|
|
56
|
+
index.unset(res)
|
|
57
|
+
return res
|
|
58
|
+
})) as typeof remove),
|
|
59
|
+
list: useAsyncAction(((props) => list({ ...props, table }).then(arr => {
|
|
60
|
+
index.set(...arr)
|
|
61
|
+
return arr
|
|
62
|
+
})) as typeof list),
|
|
170
63
|
}
|
|
171
|
-
|
|
64
|
+
}
|
|
172
65
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
66
|
+
export function useTableProvider<TSchema extends TableSchema>({
|
|
67
|
+
table,
|
|
68
|
+
schema,
|
|
69
|
+
interface: tableInterface,
|
|
70
|
+
asAbove,
|
|
71
|
+
}: TableProviderProps<TSchema>) {
|
|
176
72
|
|
|
177
|
-
|
|
178
|
-
children,
|
|
179
|
-
...props
|
|
180
|
-
}: {
|
|
181
|
-
id: string
|
|
182
|
-
table: Table
|
|
183
|
-
children: React.ReactNode | ((props: ReturnType<typeof useSingleProvider<Table>>) => React.ReactNode)
|
|
184
|
-
}) {
|
|
185
|
-
const value = useSingleProvider(props)
|
|
186
|
-
if (!value.single) return null
|
|
187
|
-
return (
|
|
188
|
-
<SingleContext.Provider value={value}>
|
|
189
|
-
{typeof children === 'function' ? (
|
|
190
|
-
children(value)
|
|
191
|
-
) : (
|
|
192
|
-
children
|
|
193
|
-
)}
|
|
194
|
-
</SingleContext.Provider>
|
|
195
|
-
)
|
|
196
|
-
}
|
|
73
|
+
type Readable = z.infer<TableSchema['readable']>
|
|
197
74
|
|
|
198
|
-
|
|
199
|
-
useContext(SingleContext) as ReturnType<typeof useSingleProvider<Table>>
|
|
75
|
+
const index = useIndex<Readable>({ ...(asAbove ?? {}) })
|
|
200
76
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
77
|
+
useEffect(function soBelow() {
|
|
78
|
+
index.setIndex((prev) => ({ ...prev, ...asAbove }))
|
|
79
|
+
}, [])
|
|
80
|
+
|
|
81
|
+
return useInterface<TSchema>(table, tableInterface, index)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const [TableContextProvider, useTableContext] = createContextFromHook(useTableProvider<any>)
|
|
85
|
+
|
|
86
|
+
export function TableProvider<TSchema extends TableSchema>({ children, ...props }: PropsWithChildren<TableProviderProps<TSchema>>) {
|
|
87
|
+
return <TableContextProvider {...props}>{children}</TableContextProvider>
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function useTable<TSchema extends TableSchema>() {
|
|
91
|
+
return useTableContext() as ReturnType<typeof useTableProvider<TSchema>>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function CreateForm<TSchema extends TableSchema>({ table, defaults, onSuccess, children }: {
|
|
95
|
+
table: string
|
|
96
|
+
schema: TSchema
|
|
97
|
+
defaults?: Partial<z.infer<TSchema['writable']>>
|
|
98
|
+
onSuccess?: (result: z.infer<TSchema['readable']>) => void
|
|
212
99
|
children: React.ReactNode | (
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
100
|
+
(props: ReturnType<typeof useActionProvider<z.infer<TSchema['writable']>, z.infer<TSchema['readable']>>>
|
|
101
|
+
& ReturnType<typeof useFields<z.infer<TSchema['writable']>>>
|
|
102
|
+
) => React.ReactNode
|
|
216
103
|
)
|
|
217
|
-
|
|
218
|
-
type Readable = z.infer<
|
|
219
|
-
type Writable = z.infer<
|
|
104
|
+
}) {
|
|
105
|
+
type Readable = z.infer<TSchema['readable']>
|
|
106
|
+
type Writable = z.infer<TSchema['writable']>
|
|
220
107
|
|
|
221
|
-
const { create } =
|
|
108
|
+
const { create } = useDatabaseTable(table)
|
|
222
109
|
|
|
223
110
|
const callback = useCallback(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
111
|
+
async (fields: Writable) => {
|
|
112
|
+
const result = await create.trigger({ data: fields })
|
|
113
|
+
if (onSuccess) onSuccess(result as Readable)
|
|
114
|
+
return result
|
|
115
|
+
},
|
|
116
|
+
[create, onSuccess]
|
|
230
117
|
)
|
|
231
118
|
|
|
232
119
|
return (
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
120
|
+
<FieldsProvider<Writable> defaults={defaults || ({} as Writable)}>
|
|
121
|
+
{fields => (
|
|
122
|
+
<ActionProvider<Writable, Readable> action={callback} params={fields.fields}>
|
|
123
|
+
{typeof children === 'function' ? (
|
|
124
|
+
form => children({ ...form, ...fields })
|
|
125
|
+
) : (
|
|
126
|
+
children
|
|
127
|
+
)}
|
|
128
|
+
</ActionProvider>
|
|
240
129
|
)}
|
|
241
|
-
|
|
242
|
-
)}
|
|
243
|
-
</FieldsProvider>
|
|
130
|
+
</FieldsProvider>
|
|
244
131
|
)
|
|
245
|
-
|
|
132
|
+
}
|
|
246
133
|
|
|
247
|
-
|
|
134
|
+
export function UpdateForm<TSchema extends TableSchema>({
|
|
135
|
+
schema,
|
|
248
136
|
table,
|
|
249
137
|
id,
|
|
250
138
|
defaults,
|
|
251
139
|
onSuccess,
|
|
252
140
|
children,
|
|
253
|
-
|
|
254
|
-
|
|
141
|
+
}: {
|
|
142
|
+
schema: TSchema
|
|
143
|
+
table: string
|
|
255
144
|
id: string
|
|
256
|
-
defaults?: Partial<z.infer<
|
|
257
|
-
onSuccess?: (result: z.infer<
|
|
145
|
+
defaults?: Partial<z.infer<TSchema['writable']>>
|
|
146
|
+
onSuccess?: (result: z.infer<TSchema['readable']>) => void
|
|
258
147
|
children: React.ReactNode | (
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
148
|
+
(props: ReturnType<typeof useActionProvider<Partial<z.infer<TSchema['writable']>>, z.infer<TSchema['readable']>>>
|
|
149
|
+
& ReturnType<typeof useFields<z.infer<TSchema['writable']>>>
|
|
150
|
+
) => React.ReactNode
|
|
262
151
|
)
|
|
263
|
-
|
|
264
|
-
type Readable = z.infer<
|
|
265
|
-
type Writable = z.infer<
|
|
152
|
+
}) {
|
|
153
|
+
type Readable = z.infer<TSchema['readable']>
|
|
154
|
+
type Writable = z.infer<TSchema['writable']>
|
|
266
155
|
|
|
267
|
-
const { update } =
|
|
156
|
+
const { update } = useDatabaseTable(table)
|
|
268
157
|
|
|
269
158
|
const callback = useCallback(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
159
|
+
async (fields: Partial<Writable>) => {
|
|
160
|
+
const result = await update.trigger({ id, data: fields })
|
|
161
|
+
if (onSuccess) onSuccess(result as Readable)
|
|
162
|
+
return result
|
|
163
|
+
},
|
|
164
|
+
[update, id, onSuccess]
|
|
276
165
|
)
|
|
277
166
|
|
|
278
167
|
return (
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
168
|
+
<FieldsProvider<Writable>
|
|
169
|
+
defaults={defaults || ({} as Partial<Writable>)}
|
|
170
|
+
>
|
|
171
|
+
{fields => (
|
|
172
|
+
<ActionProvider<Partial<Writable>, Readable> action={callback} params={fields.fields}>
|
|
173
|
+
{typeof children === 'function' ? (
|
|
174
|
+
form => children({ ...form, ...fields })
|
|
175
|
+
) : (
|
|
176
|
+
children
|
|
177
|
+
)}
|
|
178
|
+
</ActionProvider>
|
|
288
179
|
)}
|
|
289
|
-
|
|
290
|
-
)}
|
|
291
|
-
</FieldsProvider>
|
|
180
|
+
</FieldsProvider>
|
|
292
181
|
)
|
|
293
|
-
|
|
182
|
+
}
|
|
294
183
|
|
|
295
|
-
|
|
184
|
+
export function FilterForm<TSchema extends TableSchema>({
|
|
185
|
+
schema,
|
|
296
186
|
table,
|
|
297
187
|
defaults,
|
|
298
188
|
onSuccess,
|
|
299
189
|
children,
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
190
|
+
}: {
|
|
191
|
+
schema: TSchema
|
|
192
|
+
table: string
|
|
193
|
+
defaults?: Partial<ListProps<z.infer<TSchema['readable']>>>
|
|
194
|
+
onSuccess?: (result: z.infer<TSchema['readable']>[]) => void
|
|
304
195
|
children: React.ReactNode | (
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
196
|
+
(props: ReturnType<typeof useActionProvider<ListProps<z.infer<TSchema['readable']>>, z.infer<TSchema['readable']>[]>>
|
|
197
|
+
& ReturnType<typeof useFields<ListProps<z.infer<TSchema['readable']>>>>
|
|
198
|
+
) => React.ReactNode
|
|
308
199
|
)
|
|
309
|
-
|
|
310
|
-
type Readable = z.infer<
|
|
311
|
-
type Writable = z.infer<Database[T]['writable']>
|
|
200
|
+
}) {
|
|
201
|
+
type Readable = z.infer<TSchema['readable']>
|
|
312
202
|
|
|
313
|
-
const { list } =
|
|
203
|
+
const { list } = useDatabaseTable(table)
|
|
314
204
|
|
|
315
205
|
const callback = useCallback(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
206
|
+
async (fields: Omit<ListProps<Readable>, 'table'>) => {
|
|
207
|
+
const result = await list.trigger(fields)
|
|
208
|
+
if (onSuccess) onSuccess(result)
|
|
209
|
+
return result
|
|
210
|
+
},
|
|
211
|
+
[list, onSuccess]
|
|
322
212
|
)
|
|
323
213
|
|
|
324
214
|
return (
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
215
|
+
<FieldsProvider<ListProps<Readable>>
|
|
216
|
+
defaults={(defaults || { query: {} }) as ListProps<Readable>}
|
|
217
|
+
>
|
|
218
|
+
{fields => (
|
|
219
|
+
<ActionProvider<ListProps<Readable>, Readable[]> action={callback} params={fields.fields}>
|
|
220
|
+
{typeof children === 'function' ? (
|
|
221
|
+
form => children({ ...form, ...fields })
|
|
222
|
+
) : (
|
|
223
|
+
children
|
|
224
|
+
)}
|
|
225
|
+
</ActionProvider>
|
|
334
226
|
)}
|
|
335
|
-
|
|
336
|
-
)}
|
|
337
|
-
</FieldsProvider>
|
|
227
|
+
</FieldsProvider>
|
|
338
228
|
)
|
|
339
|
-
|
|
229
|
+
}
|
|
340
230
|
|
|
341
|
-
|
|
231
|
+
export function useCreateForm<TSchema extends TableSchema>(schema: TSchema) {
|
|
342
232
|
return {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
233
|
+
...useFields<z.infer<TSchema['writable']>>(),
|
|
234
|
+
...useAction<
|
|
235
|
+
z.infer<TSchema['writable']>,
|
|
236
|
+
z.infer<TSchema['readable']>
|
|
237
|
+
>()
|
|
348
238
|
}
|
|
349
|
-
|
|
350
|
-
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export function useUpdateForm<TSchema extends TableSchema>(schema: TSchema) {
|
|
351
242
|
return {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
243
|
+
...useFields<Partial<z.infer<TSchema['writable']>>>(),
|
|
244
|
+
...useAction<
|
|
245
|
+
Partial<z.infer<TSchema['writable']>>,
|
|
246
|
+
z.infer<TSchema['readable']>
|
|
247
|
+
>()
|
|
357
248
|
}
|
|
358
|
-
|
|
359
|
-
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function useFiltersForm <TSchema extends TableSchema>(schema: TSchema) {
|
|
360
252
|
return {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
253
|
+
...useFields<z.infer<TSchema['readable']>>(),
|
|
254
|
+
...useAction<z.infer<TSchema['readable']>,
|
|
255
|
+
z.infer<TSchema['readable']>[]
|
|
256
|
+
>()
|
|
365
257
|
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
return {
|
|
369
|
-
DatabaseProvider,
|
|
370
|
-
useTable,
|
|
371
|
-
useTableProvider,
|
|
372
|
-
TableProvider,
|
|
373
|
-
SingleProvider,
|
|
374
|
-
useSingle,
|
|
375
|
-
CreateForm,
|
|
376
|
-
UpdateForm,
|
|
377
|
-
FilterForm,
|
|
378
|
-
useCreateForm,
|
|
379
|
-
useUpdateForm,
|
|
380
|
-
useFiltersForm,
|
|
381
|
-
}
|
|
382
258
|
}
|
|
383
259
|
|
|
384
|
-
export
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
260
|
+
export function useSingleProvider<T>({
|
|
261
|
+
id,
|
|
262
|
+
table,
|
|
263
|
+
}: {
|
|
264
|
+
id: string
|
|
265
|
+
table: string
|
|
266
|
+
}) {
|
|
267
|
+
const { index, find } = useDatabaseTable(table)
|
|
268
|
+
const [single, setSingle] = useState<T>(
|
|
269
|
+
// @ts-expect-error
|
|
270
|
+
() => index[id as keyof typeof index]
|
|
271
|
+
)
|
|
272
|
+
useEffect(() => {
|
|
273
|
+
// @ts-expect-error
|
|
274
|
+
if (!single) find.trigger({ id }).then(setSingle)
|
|
275
|
+
}, [])
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
// @ts-expect-error
|
|
278
|
+
setSingle(index[id as keyof typeof index])
|
|
279
|
+
}, [index[id as keyof typeof index]])
|
|
280
|
+
return {
|
|
281
|
+
id,
|
|
282
|
+
single,
|
|
283
|
+
setSingle,
|
|
284
|
+
loading: find.loading,
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export const SingleContext = createContext<
|
|
289
|
+
ReturnType<typeof useSingleProvider> | undefined
|
|
290
|
+
>(undefined)
|
|
291
|
+
|
|
292
|
+
export function SingleProvider<T>({
|
|
293
|
+
children,
|
|
294
|
+
...props
|
|
295
|
+
}: {
|
|
296
|
+
id: string
|
|
297
|
+
table: string
|
|
298
|
+
children: React.ReactNode | ((props: ReturnType<typeof useSingleProvider>) => React.ReactNode)
|
|
299
|
+
}) {
|
|
300
|
+
const value = useSingleProvider(props)
|
|
301
|
+
if (!value.single) return null
|
|
302
|
+
return (
|
|
303
|
+
<SingleContext.Provider value={value}>
|
|
304
|
+
{typeof children === 'function' ? (
|
|
305
|
+
children(value)
|
|
306
|
+
) : (
|
|
307
|
+
children
|
|
308
|
+
)}
|
|
309
|
+
</SingleContext.Provider>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function useSingle<T>() {
|
|
314
|
+
return useContext(SingleContext) as ReturnType<typeof useSingleProvider<T>>
|
|
394
315
|
}
|