@taruvi/refine-providers 1.0.7 → 1.0.8
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/README.md +218 -495
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
accessControlProvider,
|
|
21
21
|
} from "@taruvi/refine-providers";
|
|
22
22
|
|
|
23
|
+
// Initialize the Taruvi client
|
|
23
24
|
const client = new Client({
|
|
24
25
|
apiKey: "your-api-key",
|
|
25
26
|
appSlug: "your-app-slug",
|
|
@@ -43,47 +44,17 @@ function App() {
|
|
|
43
44
|
}
|
|
44
45
|
```
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
## Exports
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
// Data Providers
|
|
52
|
-
import { dataProvider } from "@taruvi/refine-providers"; // Database CRUD
|
|
53
|
-
import { storageDataProvider } from "@taruvi/refine-providers"; // File storage
|
|
54
|
-
import { functionsDataProvider } from "@taruvi/refine-providers"; // Edge functions
|
|
55
|
-
import { appDataProvider } from "@taruvi/refine-providers"; // App data (roles)
|
|
56
|
-
import { analyticsDataProvider } from "@taruvi/refine-providers"; // Analytics queries
|
|
57
|
-
|
|
58
|
-
// Auth Providers
|
|
59
|
-
import { authProvider } from "@taruvi/refine-providers"; // Authentication
|
|
60
|
-
import { accessControlProvider } from "@taruvi/refine-providers"; // Cerbos permissions
|
|
47
|
+
## Data Providers
|
|
61
48
|
|
|
62
|
-
|
|
63
|
-
import type {
|
|
64
|
-
TaruviMeta,
|
|
65
|
-
TaruviListResponse,
|
|
66
|
-
TaruviUser,
|
|
67
|
-
StorageUploadVariables,
|
|
68
|
-
FunctionMeta,
|
|
69
|
-
AnalyticsMeta,
|
|
70
|
-
} from "@taruvi/refine-providers";
|
|
49
|
+
This package includes multiple specialized data providers:
|
|
71
50
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
| Provider | Purpose | Hook | Resource Parameter |
|
|
81
|
-
|----------|---------|------|-------------------|
|
|
82
|
-
| `dataProvider` | Database CRUD | `useList`, `useOne`, `useCreate`, `useUpdate`, `useDelete` | Table name |
|
|
83
|
-
| `storageDataProvider` | File storage | `useList`, `useCreate`, `useDelete` | Bucket name |
|
|
84
|
-
| `functionsDataProvider` | Edge functions | `useCustom` | Function slug |
|
|
85
|
-
| `appDataProvider` | App roles | `useList` | `"roles"` |
|
|
86
|
-
| `analyticsDataProvider` | Analytics queries | `useCustom` | Query slug |
|
|
51
|
+
| Provider | Purpose | SDK Class | Hook |
|
|
52
|
+
|----------|---------|-----------|------|
|
|
53
|
+
| `dataProvider` | Database CRUD operations | `Database` | `useList`, `useOne`, `useCreate`, etc. |
|
|
54
|
+
| `storageDataProvider` | File storage operations | `Storage` | `useList`, `useCreate`, `useDelete` |
|
|
55
|
+
| `functionsDataProvider` | Edge function execution | `Functions` | `useCreate` |
|
|
56
|
+
| `appDataProvider` | App-level data (roles) | `App` | `useList` |
|
|
57
|
+
| `analyticsDataProvider` | Analytics queries | `Analytics` | `useCreate` |
|
|
87
58
|
|
|
88
59
|
---
|
|
89
60
|
|
|
@@ -91,229 +62,130 @@ import { Client, Auth, Policy, Functions, App, Analytics } from "@taruvi/refine-
|
|
|
91
62
|
|
|
92
63
|
The main data provider for CRUD operations on database tables.
|
|
93
64
|
|
|
94
|
-
###
|
|
65
|
+
### Basic Usage
|
|
95
66
|
|
|
96
|
-
```
|
|
67
|
+
```tsx
|
|
97
68
|
import { dataProvider, Client } from "@taruvi/refine-providers";
|
|
98
69
|
|
|
99
70
|
const client = new Client({ apiKey, appSlug, baseUrl });
|
|
100
71
|
|
|
101
|
-
<Refine
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
| Method | HTTP | Endpoint |
|
|
107
|
-
|--------|------|----------|
|
|
108
|
-
| `getList` | GET | `/api/apps/{app}/datatables/{table}/data/` |
|
|
109
|
-
| `getOne` | GET | `/api/apps/{app}/datatables/{table}/data/{id}/` |
|
|
110
|
-
| `getMany` | GET | `/api/apps/{app}/datatables/{table}/data/?id__in=1,2,3` |
|
|
111
|
-
| `create` | POST | `/api/apps/{app}/datatables/{table}/data/` |
|
|
112
|
-
| `update` | PATCH | `/api/apps/{app}/datatables/{table}/data/{id}/` |
|
|
113
|
-
| `deleteOne` | DELETE | `/api/apps/{app}/datatables/{table}/data/{id}/` |
|
|
114
|
-
|
|
115
|
-
### Usage Examples
|
|
116
|
-
|
|
117
|
-
#### List Records
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
import { useList } from "@refinedev/core";
|
|
121
|
-
|
|
122
|
-
const { data, isLoading } = useList({
|
|
123
|
-
resource: "users",
|
|
124
|
-
pagination: { currentPage: 1, pageSize: 10 },
|
|
125
|
-
filters: [
|
|
126
|
-
{ field: "status", operator: "eq", value: "active" },
|
|
127
|
-
{ field: "age", operator: "gte", value: 18 },
|
|
128
|
-
],
|
|
129
|
-
sorters: [
|
|
130
|
-
{ field: "created_at", order: "desc" },
|
|
131
|
-
],
|
|
132
|
-
meta: {
|
|
133
|
-
populate: ["department", "manager"],
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// Returns: { data: User[], total: number }
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
#### Get Single Record
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
import { useOne } from "@refinedev/core";
|
|
144
|
-
|
|
145
|
-
const { data } = useOne({
|
|
146
|
-
resource: "users",
|
|
147
|
-
id: 123,
|
|
148
|
-
meta: {
|
|
149
|
-
populate: ["department"],
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// Returns: { data: User }
|
|
72
|
+
<Refine
|
|
73
|
+
dataProvider={dataProvider(client)}
|
|
74
|
+
resources={[{ name: "posts" }]}
|
|
75
|
+
/>
|
|
154
76
|
```
|
|
155
77
|
|
|
156
|
-
|
|
78
|
+
### Supported Operations
|
|
157
79
|
|
|
158
|
-
|
|
159
|
-
import { useMany } from "@refinedev/core";
|
|
160
|
-
|
|
161
|
-
const { data } = useMany({
|
|
162
|
-
resource: "users",
|
|
163
|
-
ids: [1, 2, 3],
|
|
164
|
-
});
|
|
80
|
+
All standard Refine CRUD operations are supported:
|
|
165
81
|
|
|
166
|
-
|
|
167
|
-
|
|
82
|
+
```tsx
|
|
83
|
+
// List records
|
|
84
|
+
const { data } = useList({ resource: "posts" });
|
|
168
85
|
|
|
169
|
-
|
|
86
|
+
// Get single record
|
|
87
|
+
const { data } = useOne({ resource: "posts", id: 1 });
|
|
170
88
|
|
|
171
|
-
|
|
172
|
-
|
|
89
|
+
// Get multiple records
|
|
90
|
+
const { data } = useMany({ resource: "posts", ids: [1, 2, 3] });
|
|
173
91
|
|
|
92
|
+
// Create record
|
|
174
93
|
const { mutate } = useCreate();
|
|
94
|
+
mutate({ resource: "posts", values: { title: "Hello" } });
|
|
175
95
|
|
|
176
|
-
|
|
177
|
-
resource: "users",
|
|
178
|
-
values: {
|
|
179
|
-
name: "John Doe",
|
|
180
|
-
email: "john@example.com",
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
#### Update Record
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
import { useUpdate } from "@refinedev/core";
|
|
189
|
-
|
|
96
|
+
// Update record
|
|
190
97
|
const { mutate } = useUpdate();
|
|
98
|
+
mutate({ resource: "posts", id: 1, values: { title: "Updated" } });
|
|
191
99
|
|
|
192
|
-
|
|
193
|
-
resource: "users",
|
|
194
|
-
id: 123,
|
|
195
|
-
values: {
|
|
196
|
-
name: "Jane Doe",
|
|
197
|
-
},
|
|
198
|
-
});
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
#### Delete Record
|
|
202
|
-
|
|
203
|
-
```typescript
|
|
204
|
-
import { useDelete } from "@refinedev/core";
|
|
205
|
-
|
|
100
|
+
// Delete record
|
|
206
101
|
const { mutate } = useDelete();
|
|
207
|
-
|
|
208
|
-
mutate({
|
|
209
|
-
resource: "users",
|
|
210
|
-
id: 123,
|
|
211
|
-
});
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
### Meta Options
|
|
215
|
-
|
|
216
|
-
```typescript
|
|
217
|
-
useList({
|
|
218
|
-
resource: "posts",
|
|
219
|
-
meta: {
|
|
220
|
-
tableName: "blog_posts", // Override table name
|
|
221
|
-
populate: ["author", "comments.user"], // FK population (array or string)
|
|
222
|
-
select: ["id", "title", "status"], // Field selection
|
|
223
|
-
idColumnName: "post_id", // Custom ID column
|
|
224
|
-
aggregate: ["sum(views)", "count(*)"], // Aggregations
|
|
225
|
-
groupBy: ["category"], // Group by
|
|
226
|
-
having: [{ field: "sum(views)", operator: "gte", value: 100 }],
|
|
227
|
-
},
|
|
228
|
-
});
|
|
102
|
+
mutate({ resource: "posts", id: 1 });
|
|
229
103
|
```
|
|
230
104
|
|
|
231
105
|
### Filtering
|
|
232
106
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
| `ne` | `field__ne=value` | `status__ne=deleted` |
|
|
239
|
-
| `lt`, `gt`, `lte`, `gte` | `field__lt=value` | `age__gte=18` |
|
|
240
|
-
| `contains` | `field__contains=value` | `name__contains=john` |
|
|
241
|
-
| `containss` | `field__icontains=value` | `name__icontains=John` (case-insensitive) |
|
|
242
|
-
| `startswith` | `field__startswith=value` | `code__startswith=PRE` |
|
|
243
|
-
| `endswith` | `field__endswith=value` | `email__endswith=@gmail.com` |
|
|
244
|
-
| `in` | `field__in=a,b,c` | `status__in=active,pending` |
|
|
245
|
-
| `nin` | `field__nin=a,b` | `status__nin=deleted` |
|
|
246
|
-
| `null` | `field__null=true` | `deleted_at__null=true` |
|
|
247
|
-
| `nnull` | `field__nnull=true` | `email__nnull=true` |
|
|
248
|
-
| `between` | `field__between=min,max` | `price__between=10,100` |
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
useList({
|
|
252
|
-
resource: "products",
|
|
107
|
+
Full support for Refine filter operators:
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
const { data } = useList({
|
|
111
|
+
resource: "posts",
|
|
253
112
|
filters: [
|
|
254
|
-
{ field: "status", operator: "eq", value: "
|
|
255
|
-
{ field: "
|
|
256
|
-
{ field: "
|
|
257
|
-
{ field: "
|
|
258
|
-
{ field: "deleted_at", operator: "null", value: true },
|
|
113
|
+
{ field: "status", operator: "eq", value: "published" },
|
|
114
|
+
{ field: "views", operator: "gte", value: 100 },
|
|
115
|
+
{ field: "title", operator: "contains", value: "refine" },
|
|
116
|
+
{ field: "category", operator: "in", value: ["tech", "news"] },
|
|
259
117
|
],
|
|
260
118
|
});
|
|
261
119
|
```
|
|
262
120
|
|
|
263
|
-
|
|
121
|
+
**Supported Operators:**
|
|
122
|
+
|
|
123
|
+
| Operator | Description | Example |
|
|
124
|
+
|----------|-------------|---------|
|
|
125
|
+
| `eq` | Equal | `status = "active"` |
|
|
126
|
+
| `ne` | Not equal | `status != "deleted"` |
|
|
127
|
+
| `lt`, `gt`, `lte`, `gte` | Comparison | `age >= 18` |
|
|
128
|
+
| `contains`, `ncontains` | Contains (case-sensitive) | `title contains "hello"` |
|
|
129
|
+
| `containss`, `ncontainss` | Contains (case-insensitive) | `title icontains "hello"` |
|
|
130
|
+
| `startswith`, `endswith` | String matching | `email endswith "@gmail.com"` |
|
|
131
|
+
| `in`, `nin` | Array membership | `status in ["active", "pending"]` |
|
|
132
|
+
| `null`, `nnull` | Null checks | `deleted_at is null` |
|
|
133
|
+
| `between`, `nbetween` | Range | `price between [10, 100]` |
|
|
264
134
|
|
|
265
|
-
|
|
266
|
-
|
|
135
|
+
### Sorting & Pagination
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
const { data } = useList({
|
|
267
139
|
resource: "posts",
|
|
268
140
|
sorters: [
|
|
269
|
-
{ field: "created_at", order: "desc" },
|
|
270
|
-
{ field: "title", order: "asc" },
|
|
141
|
+
{ field: "created_at", order: "desc" },
|
|
142
|
+
{ field: "title", order: "asc" },
|
|
271
143
|
],
|
|
272
|
-
});
|
|
273
|
-
// Query: ?ordering=-created_at,title
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Pagination
|
|
277
|
-
|
|
278
|
-
```typescript
|
|
279
|
-
useList({
|
|
280
|
-
resource: "users",
|
|
281
144
|
pagination: {
|
|
282
|
-
currentPage:
|
|
283
|
-
pageSize:
|
|
145
|
+
currentPage: 1,
|
|
146
|
+
pageSize: 20,
|
|
284
147
|
},
|
|
285
148
|
});
|
|
286
|
-
// Query: ?page=2&page_size=25
|
|
287
|
-
|
|
288
|
-
// Disable pagination
|
|
289
|
-
useList({
|
|
290
|
-
resource: "users",
|
|
291
|
-
pagination: { mode: "off" },
|
|
292
|
-
});
|
|
293
149
|
```
|
|
294
150
|
|
|
295
|
-
###
|
|
151
|
+
### Meta Options
|
|
296
152
|
|
|
297
|
-
|
|
153
|
+
Use the `meta` parameter for Taruvi-specific features:
|
|
298
154
|
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
useList({
|
|
155
|
+
```tsx
|
|
156
|
+
const { data } = useList({
|
|
302
157
|
resource: "posts",
|
|
303
|
-
meta: {
|
|
304
|
-
|
|
158
|
+
meta: {
|
|
159
|
+
// Override table name (when resource differs from table)
|
|
160
|
+
tableName: "blog_posts",
|
|
305
161
|
|
|
306
|
-
//
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
162
|
+
// Populate foreign key relations
|
|
163
|
+
populate: ["author", "category"],
|
|
164
|
+
// or populate all: populate: "*"
|
|
165
|
+
|
|
166
|
+
// Select specific fields
|
|
167
|
+
select: ["id", "title", "status"],
|
|
168
|
+
|
|
169
|
+
// Custom ID column
|
|
170
|
+
idColumnName: "post_id",
|
|
171
|
+
},
|
|
310
172
|
});
|
|
173
|
+
```
|
|
311
174
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
175
|
+
### Aggregations
|
|
176
|
+
|
|
177
|
+
Support for aggregate queries with grouping:
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
const { data } = useList({
|
|
181
|
+
resource: "orders",
|
|
182
|
+
meta: {
|
|
183
|
+
aggregate: ["sum(total)", "count(*)", "avg(quantity)"],
|
|
184
|
+
groupBy: ["status", "category"],
|
|
185
|
+
having: [
|
|
186
|
+
{ field: "sum(total)", operator: "gte", value: 1000 },
|
|
187
|
+
],
|
|
188
|
+
},
|
|
317
189
|
});
|
|
318
190
|
```
|
|
319
191
|
|
|
@@ -325,8 +197,10 @@ For file upload, download, and management operations.
|
|
|
325
197
|
|
|
326
198
|
### Setup
|
|
327
199
|
|
|
328
|
-
```
|
|
329
|
-
import { storageDataProvider } from "@taruvi/refine-providers";
|
|
200
|
+
```tsx
|
|
201
|
+
import { storageDataProvider, Client } from "@taruvi/refine-providers";
|
|
202
|
+
|
|
203
|
+
const client = new Client({ apiKey, appSlug, baseUrl });
|
|
330
204
|
|
|
331
205
|
<Refine
|
|
332
206
|
dataProvider={{
|
|
@@ -336,30 +210,24 @@ import { storageDataProvider } from "@taruvi/refine-providers";
|
|
|
336
210
|
/>
|
|
337
211
|
```
|
|
338
212
|
|
|
339
|
-
**Note:** In storage operations, `resource` = bucket name, `id` = file path.
|
|
340
|
-
|
|
341
213
|
### List Files
|
|
342
214
|
|
|
343
|
-
```
|
|
215
|
+
```tsx
|
|
344
216
|
const { data } = useList({
|
|
345
|
-
resource: "documents",
|
|
217
|
+
resource: "documents", // bucket name
|
|
346
218
|
dataProviderName: "storage",
|
|
347
|
-
filters: [
|
|
348
|
-
{ field: "mimetype_category", operator: "eq", value: "image" },
|
|
349
|
-
{ field: "size", operator: "lte", value: 5242880 }, // 5MB
|
|
350
|
-
],
|
|
351
219
|
});
|
|
352
220
|
```
|
|
353
221
|
|
|
354
222
|
### Upload Files
|
|
355
223
|
|
|
356
|
-
```
|
|
224
|
+
```tsx
|
|
357
225
|
import { useCreate } from "@refinedev/core";
|
|
358
226
|
import type { StorageUploadVariables } from "@taruvi/refine-providers";
|
|
359
227
|
|
|
360
228
|
const { mutate } = useCreate<any, any, StorageUploadVariables>();
|
|
361
229
|
|
|
362
|
-
// Single file
|
|
230
|
+
// Single file upload
|
|
363
231
|
mutate({
|
|
364
232
|
resource: "documents",
|
|
365
233
|
dataProviderName: "storage",
|
|
@@ -382,38 +250,33 @@ mutate({
|
|
|
382
250
|
});
|
|
383
251
|
```
|
|
384
252
|
|
|
385
|
-
### Download/Get File
|
|
386
|
-
|
|
387
|
-
```typescript
|
|
388
|
-
const { data } = useOne({
|
|
389
|
-
resource: "documents",
|
|
390
|
-
dataProviderName: "storage",
|
|
391
|
-
id: "folder/myfile.pdf", // file path
|
|
392
|
-
});
|
|
393
|
-
```
|
|
394
|
-
|
|
395
253
|
### Delete Files
|
|
396
254
|
|
|
397
|
-
```
|
|
398
|
-
import { useDeleteMany } from "@refinedev/core";
|
|
399
|
-
|
|
255
|
+
```tsx
|
|
400
256
|
const { mutate } = useDeleteMany();
|
|
401
257
|
|
|
402
258
|
mutate({
|
|
403
259
|
resource: "documents",
|
|
404
260
|
dataProviderName: "storage",
|
|
405
|
-
ids: ["file1.pdf", "
|
|
261
|
+
ids: ["path/to/file1.pdf", "path/to/file2.pdf"],
|
|
406
262
|
});
|
|
407
263
|
```
|
|
408
264
|
|
|
409
|
-
###
|
|
265
|
+
### Filter Files
|
|
410
266
|
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
}
|
|
267
|
+
```tsx
|
|
268
|
+
const { data } = useList({
|
|
269
|
+
resource: "documents",
|
|
270
|
+
dataProviderName: "storage",
|
|
271
|
+
filters: [
|
|
272
|
+
{ field: "mimetype_category", operator: "eq", value: "image" },
|
|
273
|
+
{ field: "size", operator: "lte", value: 5242880 }, // 5MB
|
|
274
|
+
{ field: "visibility", operator: "eq", value: "public" },
|
|
275
|
+
],
|
|
276
|
+
meta: {
|
|
277
|
+
bucketName: "uploads", // Override bucket name
|
|
278
|
+
},
|
|
279
|
+
});
|
|
417
280
|
```
|
|
418
281
|
|
|
419
282
|
---
|
|
@@ -424,8 +287,8 @@ For executing Taruvi edge functions.
|
|
|
424
287
|
|
|
425
288
|
### Setup
|
|
426
289
|
|
|
427
|
-
```
|
|
428
|
-
import { functionsDataProvider } from "@taruvi/refine-providers";
|
|
290
|
+
```tsx
|
|
291
|
+
import { functionsDataProvider, Client } from "@taruvi/refine-providers";
|
|
429
292
|
|
|
430
293
|
<Refine
|
|
431
294
|
dataProvider={{
|
|
@@ -437,75 +300,56 @@ import { functionsDataProvider } from "@taruvi/refine-providers";
|
|
|
437
300
|
|
|
438
301
|
### Execute Function
|
|
439
302
|
|
|
440
|
-
Use `
|
|
303
|
+
Use the `useCreate` hook with the function slug as the resource:
|
|
441
304
|
|
|
442
|
-
```
|
|
443
|
-
import {
|
|
305
|
+
```tsx
|
|
306
|
+
import { useCreate } from "@refinedev/core";
|
|
444
307
|
|
|
445
|
-
|
|
446
|
-
|
|
308
|
+
const { mutate, mutation } = useCreate();
|
|
309
|
+
|
|
310
|
+
// Execute function
|
|
311
|
+
mutate({
|
|
447
312
|
dataProviderName: "functions",
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
orderId: 123,
|
|
453
|
-
action: "confirm",
|
|
454
|
-
},
|
|
313
|
+
resource: "process-order", // function slug
|
|
314
|
+
values: {
|
|
315
|
+
orderId: 123,
|
|
316
|
+
action: "confirm",
|
|
455
317
|
},
|
|
456
318
|
meta: {
|
|
457
|
-
async: false,
|
|
319
|
+
async: false, // Set to true for async execution
|
|
458
320
|
},
|
|
459
321
|
});
|
|
460
322
|
|
|
461
|
-
|
|
323
|
+
// Check loading state
|
|
324
|
+
if (mutation.isPending) {
|
|
462
325
|
console.log("Executing function...");
|
|
463
326
|
}
|
|
464
327
|
```
|
|
465
328
|
|
|
466
|
-
### Mutation Style
|
|
467
|
-
|
|
468
|
-
```typescript
|
|
469
|
-
import { useCustomMutation } from "@refinedev/core";
|
|
470
|
-
|
|
471
|
-
const { mutate, isLoading } = useCustomMutation();
|
|
472
|
-
|
|
473
|
-
mutate({
|
|
474
|
-
dataProviderName: "functions",
|
|
475
|
-
url: "send-notification",
|
|
476
|
-
method: "post",
|
|
477
|
-
values: { userId: 456, message: "Hello" },
|
|
478
|
-
});
|
|
479
|
-
```
|
|
480
|
-
|
|
481
329
|
### With Callbacks
|
|
482
330
|
|
|
483
|
-
```
|
|
331
|
+
```tsx
|
|
484
332
|
mutate(
|
|
485
333
|
{
|
|
486
334
|
dataProviderName: "functions",
|
|
487
|
-
|
|
488
|
-
method: "post",
|
|
335
|
+
resource: "send-notification",
|
|
489
336
|
values: { userId: 456, message: "Hello" },
|
|
490
337
|
},
|
|
491
338
|
{
|
|
492
|
-
onSuccess: (data) => console.log("
|
|
493
|
-
onError: (error) => console.error("
|
|
339
|
+
onSuccess: (data) => console.log("Function result:", data),
|
|
340
|
+
onError: (error) => console.error("Function failed:", error),
|
|
494
341
|
}
|
|
495
342
|
);
|
|
496
343
|
```
|
|
497
344
|
|
|
498
|
-
### Async Execution
|
|
345
|
+
### Async Function Execution
|
|
499
346
|
|
|
500
|
-
```
|
|
347
|
+
```tsx
|
|
501
348
|
// Long-running task - returns immediately with job ID
|
|
502
|
-
|
|
349
|
+
mutate({
|
|
503
350
|
dataProviderName: "functions",
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
config: {
|
|
507
|
-
payload: { taskId: 789 },
|
|
508
|
-
},
|
|
351
|
+
resource: "long-running-task",
|
|
352
|
+
values: { taskId: 789 },
|
|
509
353
|
meta: { async: true },
|
|
510
354
|
});
|
|
511
355
|
```
|
|
@@ -518,8 +362,8 @@ For fetching app-level data like roles.
|
|
|
518
362
|
|
|
519
363
|
### Setup
|
|
520
364
|
|
|
521
|
-
```
|
|
522
|
-
import { appDataProvider } from "@taruvi/refine-providers";
|
|
365
|
+
```tsx
|
|
366
|
+
import { appDataProvider, Client } from "@taruvi/refine-providers";
|
|
523
367
|
|
|
524
368
|
<Refine
|
|
525
369
|
dataProvider={{
|
|
@@ -531,12 +375,10 @@ import { appDataProvider } from "@taruvi/refine-providers";
|
|
|
531
375
|
|
|
532
376
|
### Fetch Roles
|
|
533
377
|
|
|
534
|
-
```
|
|
535
|
-
import { useList } from "@refinedev/core";
|
|
536
|
-
|
|
378
|
+
```tsx
|
|
537
379
|
const { data } = useList({
|
|
538
|
-
dataProviderName: "app",
|
|
539
380
|
resource: "roles",
|
|
381
|
+
dataProviderName: "app",
|
|
540
382
|
});
|
|
541
383
|
|
|
542
384
|
// Returns: { data: [{ id, name, permissions, ... }], total: number }
|
|
@@ -550,8 +392,8 @@ For executing predefined analytics queries.
|
|
|
550
392
|
|
|
551
393
|
### Setup
|
|
552
394
|
|
|
553
|
-
```
|
|
554
|
-
import { analyticsDataProvider } from "@taruvi/refine-providers";
|
|
395
|
+
```tsx
|
|
396
|
+
import { analyticsDataProvider, Client } from "@taruvi/refine-providers";
|
|
555
397
|
|
|
556
398
|
<Refine
|
|
557
399
|
dataProvider={{
|
|
@@ -561,64 +403,62 @@ import { analyticsDataProvider } from "@taruvi/refine-providers";
|
|
|
561
403
|
/>
|
|
562
404
|
```
|
|
563
405
|
|
|
564
|
-
### Execute Query
|
|
406
|
+
### Execute Analytics Query
|
|
407
|
+
|
|
408
|
+
Use the `useCreate` hook with the query slug as the resource:
|
|
565
409
|
|
|
566
|
-
|
|
410
|
+
```tsx
|
|
411
|
+
import { useCreate } from "@refinedev/core";
|
|
567
412
|
|
|
568
|
-
|
|
569
|
-
import { useCustom } from "@refinedev/core";
|
|
413
|
+
const { mutate, mutation } = useCreate();
|
|
570
414
|
|
|
571
|
-
//
|
|
572
|
-
|
|
415
|
+
// Execute analytics query
|
|
416
|
+
mutate({
|
|
573
417
|
dataProviderName: "analytics",
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
end_date: "2024-12-31",
|
|
580
|
-
region: "US",
|
|
581
|
-
},
|
|
418
|
+
resource: "monthly-sales-report", // query slug
|
|
419
|
+
values: {
|
|
420
|
+
start_date: "2024-01-01",
|
|
421
|
+
end_date: "2024-12-31",
|
|
422
|
+
region: "US",
|
|
582
423
|
},
|
|
583
424
|
});
|
|
584
425
|
|
|
585
|
-
|
|
426
|
+
// Check loading state
|
|
427
|
+
if (mutation.isPending) {
|
|
586
428
|
console.log("Running query...");
|
|
587
429
|
}
|
|
588
430
|
```
|
|
589
431
|
|
|
590
|
-
### Mutation Style
|
|
591
|
-
|
|
592
|
-
```typescript
|
|
593
|
-
import { useCustomMutation } from "@refinedev/core";
|
|
594
|
-
|
|
595
|
-
const { mutate, isLoading } = useCustomMutation();
|
|
596
|
-
|
|
597
|
-
mutate({
|
|
598
|
-
dataProviderName: "analytics",
|
|
599
|
-
url: "dashboard-metrics",
|
|
600
|
-
method: "post",
|
|
601
|
-
values: { period: "last_30_days" },
|
|
602
|
-
});
|
|
603
|
-
```
|
|
604
|
-
|
|
605
432
|
### With Callbacks
|
|
606
433
|
|
|
607
|
-
```
|
|
434
|
+
```tsx
|
|
608
435
|
mutate(
|
|
609
436
|
{
|
|
610
437
|
dataProviderName: "analytics",
|
|
611
|
-
|
|
612
|
-
method: "post",
|
|
438
|
+
resource: "dashboard-metrics",
|
|
613
439
|
values: { period: "last_30_days" },
|
|
614
440
|
},
|
|
615
441
|
{
|
|
616
|
-
onSuccess: (data) => console.log("
|
|
617
|
-
onError: (error) => console.error("
|
|
442
|
+
onSuccess: (data) => console.log("Query result:", data),
|
|
443
|
+
onError: (error) => console.error("Query failed:", error),
|
|
618
444
|
}
|
|
619
445
|
);
|
|
620
446
|
```
|
|
621
447
|
|
|
448
|
+
### Query with Aggregations
|
|
449
|
+
|
|
450
|
+
```tsx
|
|
451
|
+
mutate({
|
|
452
|
+
dataProviderName: "analytics",
|
|
453
|
+
resource: "revenue-by-region",
|
|
454
|
+
values: {
|
|
455
|
+
year: 2024,
|
|
456
|
+
group_by: "region",
|
|
457
|
+
include_forecast: true,
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
```
|
|
461
|
+
|
|
622
462
|
---
|
|
623
463
|
|
|
624
464
|
## Auth Provider
|
|
@@ -627,15 +467,19 @@ Redirect-based authentication using Taruvi's Web UI Flow.
|
|
|
627
467
|
|
|
628
468
|
### Setup
|
|
629
469
|
|
|
630
|
-
```
|
|
631
|
-
import { authProvider } from "@taruvi/refine-providers";
|
|
470
|
+
```tsx
|
|
471
|
+
import { authProvider, Client } from "@taruvi/refine-providers";
|
|
472
|
+
|
|
473
|
+
const client = new Client({ apiKey, appSlug, baseUrl });
|
|
632
474
|
|
|
633
|
-
<Refine
|
|
475
|
+
<Refine
|
|
476
|
+
authProvider={authProvider(client)}
|
|
477
|
+
/>
|
|
634
478
|
```
|
|
635
479
|
|
|
636
480
|
### Login
|
|
637
481
|
|
|
638
|
-
```
|
|
482
|
+
```tsx
|
|
639
483
|
import { useLogin } from "@refinedev/core";
|
|
640
484
|
|
|
641
485
|
const { mutate: login } = useLogin();
|
|
@@ -646,7 +490,7 @@ login({ callbackUrl: "/dashboard" });
|
|
|
646
490
|
|
|
647
491
|
### Logout
|
|
648
492
|
|
|
649
|
-
```
|
|
493
|
+
```tsx
|
|
650
494
|
import { useLogout } from "@refinedev/core";
|
|
651
495
|
|
|
652
496
|
const { mutate: logout } = useLogout();
|
|
@@ -654,9 +498,9 @@ const { mutate: logout } = useLogout();
|
|
|
654
498
|
logout({ callbackUrl: "/login" });
|
|
655
499
|
```
|
|
656
500
|
|
|
657
|
-
### Register
|
|
501
|
+
### Register/Signup
|
|
658
502
|
|
|
659
|
-
```
|
|
503
|
+
```tsx
|
|
660
504
|
import { useRegister } from "@refinedev/core";
|
|
661
505
|
|
|
662
506
|
const { mutate: register } = useRegister();
|
|
@@ -666,7 +510,7 @@ register({ callbackUrl: "/welcome" });
|
|
|
666
510
|
|
|
667
511
|
### Get Current User
|
|
668
512
|
|
|
669
|
-
```
|
|
513
|
+
```tsx
|
|
670
514
|
import { useGetIdentity } from "@refinedev/core";
|
|
671
515
|
import type { TaruviUser } from "@taruvi/refine-providers";
|
|
672
516
|
|
|
@@ -676,21 +520,9 @@ console.log(user?.username);
|
|
|
676
520
|
console.log(user?.email);
|
|
677
521
|
```
|
|
678
522
|
|
|
679
|
-
### Check
|
|
680
|
-
|
|
681
|
-
```typescript
|
|
682
|
-
import { useIsAuthenticated } from "@refinedev/core";
|
|
683
|
-
|
|
684
|
-
const { data } = useIsAuthenticated();
|
|
685
|
-
|
|
686
|
-
if (data?.authenticated) {
|
|
687
|
-
// User is logged in
|
|
688
|
-
}
|
|
689
|
-
```
|
|
690
|
-
|
|
691
|
-
### Get Permissions
|
|
523
|
+
### Check Permissions
|
|
692
524
|
|
|
693
|
-
```
|
|
525
|
+
```tsx
|
|
694
526
|
import { usePermissions } from "@refinedev/core";
|
|
695
527
|
|
|
696
528
|
const { data: permissions } = usePermissions();
|
|
@@ -699,19 +531,6 @@ console.log(permissions?.roles);
|
|
|
699
531
|
console.log(permissions?.is_staff);
|
|
700
532
|
```
|
|
701
533
|
|
|
702
|
-
### TaruviUser Interface
|
|
703
|
-
|
|
704
|
-
```typescript
|
|
705
|
-
interface TaruviUser {
|
|
706
|
-
user_id: number;
|
|
707
|
-
username: string;
|
|
708
|
-
email?: string;
|
|
709
|
-
exp?: number; // Token expiration
|
|
710
|
-
iat?: number; // Token issued at
|
|
711
|
-
[key: string]: unknown;
|
|
712
|
-
}
|
|
713
|
-
```
|
|
714
|
-
|
|
715
534
|
---
|
|
716
535
|
|
|
717
536
|
## Access Control Provider
|
|
@@ -720,8 +539,8 @@ Resource-based authorization using Cerbos policies.
|
|
|
720
539
|
|
|
721
540
|
### Setup
|
|
722
541
|
|
|
723
|
-
```
|
|
724
|
-
import { accessControlProvider } from "@taruvi/refine-providers";
|
|
542
|
+
```tsx
|
|
543
|
+
import { accessControlProvider, Client } from "@taruvi/refine-providers";
|
|
725
544
|
|
|
726
545
|
<Refine
|
|
727
546
|
authProvider={authProvider(client)}
|
|
@@ -731,7 +550,7 @@ import { accessControlProvider } from "@taruvi/refine-providers";
|
|
|
731
550
|
|
|
732
551
|
### Check Permissions
|
|
733
552
|
|
|
734
|
-
```
|
|
553
|
+
```tsx
|
|
735
554
|
import { useCan } from "@refinedev/core";
|
|
736
555
|
|
|
737
556
|
const { data } = useCan({
|
|
@@ -753,15 +572,6 @@ import { CanAccess } from "@refinedev/core";
|
|
|
753
572
|
<CanAccess resource="posts" action="delete" params={{ id: 1 }}>
|
|
754
573
|
<DeleteButton />
|
|
755
574
|
</CanAccess>
|
|
756
|
-
|
|
757
|
-
// With fallback
|
|
758
|
-
<CanAccess
|
|
759
|
-
resource="admin"
|
|
760
|
-
action="view"
|
|
761
|
-
fallback={<p>Access denied</p>}
|
|
762
|
-
>
|
|
763
|
-
<AdminPanel />
|
|
764
|
-
</CanAccess>
|
|
765
575
|
```
|
|
766
576
|
|
|
767
577
|
### Define Entity Type
|
|
@@ -774,7 +584,7 @@ For Cerbos, specify the entity type in resource meta:
|
|
|
774
584
|
{
|
|
775
585
|
name: "posts",
|
|
776
586
|
meta: {
|
|
777
|
-
entityType: "blog",
|
|
587
|
+
entityType: "blog", // Used in Cerbos policy
|
|
778
588
|
},
|
|
779
589
|
},
|
|
780
590
|
]}
|
|
@@ -785,7 +595,7 @@ For Cerbos, specify the entity type in resource meta:
|
|
|
785
595
|
|
|
786
596
|
## Multiple Data Providers
|
|
787
597
|
|
|
788
|
-
Use
|
|
598
|
+
Use multiple providers together:
|
|
789
599
|
|
|
790
600
|
```tsx
|
|
791
601
|
import {
|
|
@@ -795,8 +605,6 @@ import {
|
|
|
795
605
|
functionsDataProvider,
|
|
796
606
|
appDataProvider,
|
|
797
607
|
analyticsDataProvider,
|
|
798
|
-
authProvider,
|
|
799
|
-
accessControlProvider,
|
|
800
608
|
} from "@taruvi/refine-providers";
|
|
801
609
|
|
|
802
610
|
const client = new Client({ apiKey, appSlug, baseUrl });
|
|
@@ -809,42 +617,32 @@ const client = new Client({ apiKey, appSlug, baseUrl });
|
|
|
809
617
|
app: appDataProvider(client),
|
|
810
618
|
analytics: analyticsDataProvider(client),
|
|
811
619
|
}}
|
|
812
|
-
authProvider={authProvider(client)}
|
|
813
|
-
accessControlProvider={accessControlProvider(client)}
|
|
814
620
|
/>
|
|
815
621
|
|
|
816
|
-
//
|
|
817
|
-
useList({ resource: "posts" });
|
|
818
|
-
useList({ resource: "images", dataProviderName: "storage" });
|
|
819
|
-
useList({ resource: "roles", dataProviderName: "app" });
|
|
820
|
-
|
|
821
|
-
// Functions and Analytics use useCustom
|
|
822
|
-
const { data: funcResult } = useCustom({
|
|
823
|
-
dataProviderName: "functions",
|
|
824
|
-
url: "my-func",
|
|
825
|
-
method: "post",
|
|
826
|
-
config: { payload: { key: "value" } },
|
|
827
|
-
});
|
|
622
|
+
// Then specify which provider to use:
|
|
623
|
+
useList({ resource: "posts" }); // Uses default
|
|
624
|
+
useList({ resource: "images", dataProviderName: "storage" });
|
|
625
|
+
useList({ resource: "roles", dataProviderName: "app" });
|
|
828
626
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
config: { payload: { period: "last_30_days" } },
|
|
834
|
-
});
|
|
627
|
+
// For functions and analytics, use useCreate:
|
|
628
|
+
const { mutate } = useCreate();
|
|
629
|
+
mutate({ dataProviderName: "functions", resource: "my-function", values: {...} });
|
|
630
|
+
mutate({ dataProviderName: "analytics", resource: "my-query", values: {...} });
|
|
835
631
|
```
|
|
836
632
|
|
|
837
633
|
---
|
|
838
634
|
|
|
839
635
|
## TypeScript Types
|
|
840
636
|
|
|
841
|
-
|
|
637
|
+
All types are exported for TypeScript users:
|
|
638
|
+
|
|
639
|
+
```tsx
|
|
842
640
|
import type {
|
|
843
641
|
// Meta types
|
|
844
642
|
TaruviMeta,
|
|
845
643
|
TaruviListResponse,
|
|
846
|
-
FunctionMeta,
|
|
847
644
|
AnalyticsMeta,
|
|
645
|
+
FunctionMeta,
|
|
848
646
|
StorageUploadVariables,
|
|
849
647
|
|
|
850
648
|
// Auth types
|
|
@@ -861,26 +659,13 @@ import type {
|
|
|
861
659
|
} from "@taruvi/refine-providers";
|
|
862
660
|
```
|
|
863
661
|
|
|
864
|
-
### TaruviMeta Interface
|
|
865
|
-
|
|
866
|
-
```typescript
|
|
867
|
-
interface TaruviMeta {
|
|
868
|
-
tableName?: string; // Override table name
|
|
869
|
-
bucketName?: string; // Override bucket name
|
|
870
|
-
populate?: string | string[]; // FK population
|
|
871
|
-
select?: string | string[]; // Field selection
|
|
872
|
-
idColumnName?: string; // Custom ID column
|
|
873
|
-
aggregate?: string[]; // Aggregation expressions
|
|
874
|
-
groupBy?: string[]; // Group by fields
|
|
875
|
-
having?: CrudFilter[]; // Having clause
|
|
876
|
-
}
|
|
877
|
-
```
|
|
878
|
-
|
|
879
662
|
---
|
|
880
663
|
|
|
881
664
|
## SDK Re-exports
|
|
882
665
|
|
|
883
|
-
|
|
666
|
+
For convenience, SDK classes are re-exported:
|
|
667
|
+
|
|
668
|
+
```tsx
|
|
884
669
|
import {
|
|
885
670
|
Client,
|
|
886
671
|
Auth,
|
|
@@ -899,7 +684,9 @@ const isLoggedIn = auth.isUserAuthenticated();
|
|
|
899
684
|
|
|
900
685
|
## Utility Functions
|
|
901
686
|
|
|
902
|
-
|
|
687
|
+
Advanced users can access utility functions:
|
|
688
|
+
|
|
689
|
+
```tsx
|
|
903
690
|
import {
|
|
904
691
|
REFINE_OPERATOR_MAP,
|
|
905
692
|
convertRefineFilters,
|
|
@@ -909,70 +696,6 @@ import {
|
|
|
909
696
|
buildQueryString,
|
|
910
697
|
handleError,
|
|
911
698
|
} from "@taruvi/refine-providers";
|
|
912
|
-
|
|
913
|
-
// Convert filters to query params
|
|
914
|
-
const params = convertRefineFilters([
|
|
915
|
-
{ field: "status", operator: "eq", value: "active" },
|
|
916
|
-
]);
|
|
917
|
-
// Result: { status: "active" }
|
|
918
|
-
|
|
919
|
-
// Convert sorters
|
|
920
|
-
const ordering = convertRefineSorters([
|
|
921
|
-
{ field: "created_at", order: "desc" },
|
|
922
|
-
]);
|
|
923
|
-
// Result: "-created_at"
|
|
924
|
-
```
|
|
925
|
-
|
|
926
|
-
---
|
|
927
|
-
|
|
928
|
-
## Error Handling
|
|
929
|
-
|
|
930
|
-
```typescript
|
|
931
|
-
const { data, error, isError } = useList({ resource: "users" });
|
|
932
|
-
|
|
933
|
-
if (isError) {
|
|
934
|
-
console.error(error.message);
|
|
935
|
-
}
|
|
936
|
-
```
|
|
937
|
-
|
|
938
|
-
Auth errors are handled by `authProvider.onError`:
|
|
939
|
-
- **401**: Attempts token refresh, then redirects to login
|
|
940
|
-
- **403**: Returns error (user authenticated but not authorized)
|
|
941
|
-
|
|
942
|
-
---
|
|
943
|
-
|
|
944
|
-
## Architecture
|
|
945
|
-
|
|
946
|
-
```
|
|
947
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
948
|
-
│ React Application │
|
|
949
|
-
│ (using Refine hooks/components) │
|
|
950
|
-
└─────────────────────────────────────────────────────────────┘
|
|
951
|
-
│
|
|
952
|
-
▼
|
|
953
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
954
|
-
│ @refinedev/core │
|
|
955
|
-
│ (useList, useCreate, useLogin, CanAccess, etc.) │
|
|
956
|
-
└─────────────────────────────────────────────────────────────┘
|
|
957
|
-
│
|
|
958
|
-
▼
|
|
959
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
960
|
-
│ @taruvi/refine-providers │
|
|
961
|
-
│ Data: dataProvider, storageDataProvider, functionsData- │
|
|
962
|
-
│ Provider, appDataProvider, analyticsDataProvider │
|
|
963
|
-
│ Auth: authProvider, accessControlProvider │
|
|
964
|
-
└─────────────────────────────────────────────────────────────┘
|
|
965
|
-
│
|
|
966
|
-
▼
|
|
967
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
968
|
-
│ @taruvi/sdk │
|
|
969
|
-
│ Database, Storage, Functions, App, Analytics, Auth, Policy │
|
|
970
|
-
└─────────────────────────────────────────────────────────────┘
|
|
971
|
-
│
|
|
972
|
-
▼
|
|
973
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
974
|
-
│ Taruvi Backend API │
|
|
975
|
-
└─────────────────────────────────────────────────────────────┘
|
|
976
699
|
```
|
|
977
700
|
|
|
978
701
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taruvi/refine-providers",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Refine.dev data provider for Taruvi Data Service",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -65,6 +65,6 @@
|
|
|
65
65
|
"url": "https://github.com/taruvi-io/sdk/issues"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@taruvi/sdk": "^1.2.
|
|
68
|
+
"@taruvi/sdk": "^1.2.3"
|
|
69
69
|
}
|
|
70
70
|
}
|