@taruvi/refine-providers 1.0.4 → 1.0.6

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 ADDED
@@ -0,0 +1,628 @@
1
+ # @taruvi/refine-providers
2
+
3
+ Refine.dev data providers for Taruvi Data Service. This package provides a complete integration layer between [Refine](https://refine.dev/) and the Taruvi backend platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @taruvi/refine-providers @taruvi/sdk @refinedev/core
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```tsx
14
+ import { Refine } from "@refinedev/core";
15
+ import {
16
+ Client,
17
+ dataProvider,
18
+ storageDataProvider,
19
+ authProvider,
20
+ accessControlProvider,
21
+ } from "@taruvi/refine-providers";
22
+
23
+ // Initialize the Taruvi client
24
+ const client = new Client({
25
+ apiKey: "your-api-key",
26
+ appSlug: "your-app-slug",
27
+ baseUrl: "https://your-site.taruvi.cloud",
28
+ });
29
+
30
+ function App() {
31
+ return (
32
+ <Refine
33
+ dataProvider={dataProvider(client)}
34
+ authProvider={authProvider(client)}
35
+ accessControlProvider={accessControlProvider(client)}
36
+ resources={[
37
+ { name: "users" },
38
+ { name: "posts" },
39
+ ]}
40
+ >
41
+ {/* Your app */}
42
+ </Refine>
43
+ );
44
+ }
45
+ ```
46
+
47
+ ## Data Providers
48
+
49
+ This package includes multiple specialized data providers:
50
+
51
+ | Provider | Purpose | SDK Class |
52
+ |----------|---------|-----------|
53
+ | `dataProvider` | Database CRUD operations | `Database` |
54
+ | `storageDataProvider` | File storage operations | `Storage` |
55
+ | `functionsDataProvider` | Edge function execution | `Functions` |
56
+ | `appDataProvider` | App-level data (roles) | `App` |
57
+ | `analyticsDataProvider` | Analytics queries | `Analytics` |
58
+
59
+ ---
60
+
61
+ ## Database Data Provider
62
+
63
+ The main data provider for CRUD operations on database tables.
64
+
65
+ ### Basic Usage
66
+
67
+ ```tsx
68
+ import { dataProvider, Client } from "@taruvi/refine-providers";
69
+
70
+ const client = new Client({ apiKey, appSlug, baseUrl });
71
+
72
+ <Refine
73
+ dataProvider={dataProvider(client)}
74
+ resources={[{ name: "posts" }]}
75
+ />
76
+ ```
77
+
78
+ ### Supported Operations
79
+
80
+ All standard Refine CRUD operations are supported:
81
+
82
+ ```tsx
83
+ // List records
84
+ const { data } = useList({ resource: "posts" });
85
+
86
+ // Get single record
87
+ const { data } = useOne({ resource: "posts", id: 1 });
88
+
89
+ // Get multiple records
90
+ const { data } = useMany({ resource: "posts", ids: [1, 2, 3] });
91
+
92
+ // Create record
93
+ const { mutate } = useCreate();
94
+ mutate({ resource: "posts", values: { title: "Hello" } });
95
+
96
+ // Update record
97
+ const { mutate } = useUpdate();
98
+ mutate({ resource: "posts", id: 1, values: { title: "Updated" } });
99
+
100
+ // Delete record
101
+ const { mutate } = useDelete();
102
+ mutate({ resource: "posts", id: 1 });
103
+ ```
104
+
105
+ ### Filtering
106
+
107
+ Full support for Refine filter operators:
108
+
109
+ ```tsx
110
+ const { data } = useList({
111
+ resource: "posts",
112
+ filters: [
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"] },
117
+ ],
118
+ });
119
+ ```
120
+
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]` |
134
+
135
+ ### Sorting & Pagination
136
+
137
+ ```tsx
138
+ const { data } = useList({
139
+ resource: "posts",
140
+ sorters: [
141
+ { field: "created_at", order: "desc" },
142
+ { field: "title", order: "asc" },
143
+ ],
144
+ pagination: {
145
+ currentPage: 1,
146
+ pageSize: 20,
147
+ },
148
+ });
149
+ ```
150
+
151
+ ### Meta Options
152
+
153
+ Use the `meta` parameter for Taruvi-specific features:
154
+
155
+ ```tsx
156
+ const { data } = useList({
157
+ resource: "posts",
158
+ meta: {
159
+ // Override table name (when resource differs from table)
160
+ tableName: "blog_posts",
161
+
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
+ },
172
+ });
173
+ ```
174
+
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
+ },
189
+ });
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Storage Data Provider
195
+
196
+ For file upload, download, and management operations.
197
+
198
+ ### Setup
199
+
200
+ ```tsx
201
+ import { storageDataProvider, Client } from "@taruvi/refine-providers";
202
+
203
+ const client = new Client({ apiKey, appSlug, baseUrl });
204
+
205
+ <Refine
206
+ dataProvider={{
207
+ default: dataProvider(client),
208
+ storage: storageDataProvider(client),
209
+ }}
210
+ />
211
+ ```
212
+
213
+ ### List Files
214
+
215
+ ```tsx
216
+ const { data } = useList({
217
+ resource: "documents", // bucket name
218
+ dataProviderName: "storage",
219
+ });
220
+ ```
221
+
222
+ ### Upload Files
223
+
224
+ ```tsx
225
+ import { useCreate } from "@refinedev/core";
226
+ import type { StorageUploadVariables } from "@taruvi/refine-providers";
227
+
228
+ const { mutate } = useCreate<any, any, StorageUploadVariables>();
229
+
230
+ // Single file upload
231
+ mutate({
232
+ resource: "documents",
233
+ dataProviderName: "storage",
234
+ values: {
235
+ files: [file],
236
+ paths: ["uploads/document.pdf"],
237
+ metadatas: [{ description: "My document" }],
238
+ },
239
+ });
240
+
241
+ // Multiple files
242
+ mutate({
243
+ resource: "documents",
244
+ dataProviderName: "storage",
245
+ values: {
246
+ files: [file1, file2],
247
+ paths: ["file1.pdf", "file2.pdf"],
248
+ metadatas: [{}, {}],
249
+ },
250
+ });
251
+ ```
252
+
253
+ ### Delete Files
254
+
255
+ ```tsx
256
+ const { mutate } = useDeleteMany();
257
+
258
+ mutate({
259
+ resource: "documents",
260
+ dataProviderName: "storage",
261
+ ids: ["path/to/file1.pdf", "path/to/file2.pdf"],
262
+ });
263
+ ```
264
+
265
+ ### Filter Files
266
+
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
+ });
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Functions Data Provider
285
+
286
+ For executing Taruvi edge functions.
287
+
288
+ ### Setup
289
+
290
+ ```tsx
291
+ import { functionsDataProvider, Client } from "@taruvi/refine-providers";
292
+
293
+ <Refine
294
+ dataProvider={{
295
+ default: dataProvider(client),
296
+ functions: functionsDataProvider(client),
297
+ }}
298
+ />
299
+ ```
300
+
301
+ ### Execute Function
302
+
303
+ ```tsx
304
+ import { useCustom } from "@refinedev/core";
305
+
306
+ const { data } = useCustom({
307
+ dataProviderName: "functions",
308
+ url: "my-function-slug",
309
+ method: "post",
310
+ config: {
311
+ payload: {
312
+ param1: "value1",
313
+ param2: 123,
314
+ },
315
+ },
316
+ meta: {
317
+ async: false, // Set to true for async execution
318
+ },
319
+ });
320
+ ```
321
+
322
+ ---
323
+
324
+ ## App Data Provider
325
+
326
+ For fetching app-level data like roles.
327
+
328
+ ### Setup
329
+
330
+ ```tsx
331
+ import { appDataProvider, Client } from "@taruvi/refine-providers";
332
+
333
+ <Refine
334
+ dataProvider={{
335
+ default: dataProvider(client),
336
+ app: appDataProvider(client),
337
+ }}
338
+ />
339
+ ```
340
+
341
+ ### Fetch Roles
342
+
343
+ ```tsx
344
+ const { data } = useList({
345
+ resource: "roles",
346
+ dataProviderName: "app",
347
+ });
348
+
349
+ // Returns: { data: [{ id, name, permissions, ... }], total: number }
350
+ ```
351
+
352
+ ---
353
+
354
+ ## Analytics Data Provider
355
+
356
+ For executing predefined analytics queries.
357
+
358
+ ### Setup
359
+
360
+ ```tsx
361
+ import { analyticsDataProvider, Client } from "@taruvi/refine-providers";
362
+
363
+ <Refine
364
+ dataProvider={{
365
+ default: dataProvider(client),
366
+ analytics: analyticsDataProvider(client),
367
+ }}
368
+ />
369
+ ```
370
+
371
+ ### Execute Analytics Query
372
+
373
+ ```tsx
374
+ import { useCustom } from "@refinedev/core";
375
+
376
+ const { data } = useCustom({
377
+ dataProviderName: "analytics",
378
+ url: "monthly-sales-report", // query slug
379
+ method: "post",
380
+ config: {
381
+ payload: {
382
+ start_date: "2024-01-01",
383
+ end_date: "2024-12-31",
384
+ region: "US",
385
+ },
386
+ },
387
+ });
388
+ ```
389
+
390
+ ---
391
+
392
+ ## Auth Provider
393
+
394
+ Redirect-based authentication using Taruvi's Web UI Flow.
395
+
396
+ ### Setup
397
+
398
+ ```tsx
399
+ import { authProvider, Client } from "@taruvi/refine-providers";
400
+
401
+ const client = new Client({ apiKey, appSlug, baseUrl });
402
+
403
+ <Refine
404
+ authProvider={authProvider(client)}
405
+ />
406
+ ```
407
+
408
+ ### Login
409
+
410
+ ```tsx
411
+ import { useLogin } from "@refinedev/core";
412
+
413
+ const { mutate: login } = useLogin();
414
+
415
+ // Redirect to login page
416
+ login({ callbackUrl: "/dashboard" });
417
+ ```
418
+
419
+ ### Logout
420
+
421
+ ```tsx
422
+ import { useLogout } from "@refinedev/core";
423
+
424
+ const { mutate: logout } = useLogout();
425
+
426
+ logout({ callbackUrl: "/login" });
427
+ ```
428
+
429
+ ### Register/Signup
430
+
431
+ ```tsx
432
+ import { useRegister } from "@refinedev/core";
433
+
434
+ const { mutate: register } = useRegister();
435
+
436
+ register({ callbackUrl: "/welcome" });
437
+ ```
438
+
439
+ ### Get Current User
440
+
441
+ ```tsx
442
+ import { useGetIdentity } from "@refinedev/core";
443
+ import type { TaruviUser } from "@taruvi/refine-providers";
444
+
445
+ const { data: user } = useGetIdentity<TaruviUser>();
446
+
447
+ console.log(user?.username);
448
+ console.log(user?.email);
449
+ ```
450
+
451
+ ### Check Permissions
452
+
453
+ ```tsx
454
+ import { usePermissions } from "@refinedev/core";
455
+
456
+ const { data: permissions } = usePermissions();
457
+
458
+ console.log(permissions?.roles);
459
+ console.log(permissions?.is_staff);
460
+ ```
461
+
462
+ ---
463
+
464
+ ## Access Control Provider
465
+
466
+ Resource-based authorization using Cerbos policies.
467
+
468
+ ### Setup
469
+
470
+ ```tsx
471
+ import { accessControlProvider, Client } from "@taruvi/refine-providers";
472
+
473
+ <Refine
474
+ authProvider={authProvider(client)}
475
+ accessControlProvider={accessControlProvider(client)}
476
+ />
477
+ ```
478
+
479
+ ### Check Permissions
480
+
481
+ ```tsx
482
+ import { useCan } from "@refinedev/core";
483
+
484
+ const { data } = useCan({
485
+ resource: "posts",
486
+ action: "edit",
487
+ params: { id: 1 },
488
+ });
489
+
490
+ if (data?.can) {
491
+ // User can edit this post
492
+ }
493
+ ```
494
+
495
+ ### CanAccess Component
496
+
497
+ ```tsx
498
+ import { CanAccess } from "@refinedev/core";
499
+
500
+ <CanAccess resource="posts" action="delete" params={{ id: 1 }}>
501
+ <DeleteButton />
502
+ </CanAccess>
503
+ ```
504
+
505
+ ### Define Entity Type
506
+
507
+ For Cerbos, specify the entity type in resource meta:
508
+
509
+ ```tsx
510
+ <Refine
511
+ resources={[
512
+ {
513
+ name: "posts",
514
+ meta: {
515
+ entityType: "blog", // Used in Cerbos policy
516
+ },
517
+ },
518
+ ]}
519
+ />
520
+ ```
521
+
522
+ ---
523
+
524
+ ## Multiple Data Providers
525
+
526
+ Use multiple providers together:
527
+
528
+ ```tsx
529
+ import {
530
+ Client,
531
+ dataProvider,
532
+ storageDataProvider,
533
+ functionsDataProvider,
534
+ appDataProvider,
535
+ analyticsDataProvider,
536
+ } from "@taruvi/refine-providers";
537
+
538
+ const client = new Client({ apiKey, appSlug, baseUrl });
539
+
540
+ <Refine
541
+ dataProvider={{
542
+ default: dataProvider(client),
543
+ storage: storageDataProvider(client),
544
+ functions: functionsDataProvider(client),
545
+ app: appDataProvider(client),
546
+ analytics: analyticsDataProvider(client),
547
+ }}
548
+ />
549
+
550
+ // Then specify which provider to use:
551
+ useList({ resource: "posts" }); // Uses default
552
+ useList({ resource: "images", dataProviderName: "storage" });
553
+ useCustom({ url: "process", dataProviderName: "functions", method: "post" });
554
+ ```
555
+
556
+ ---
557
+
558
+ ## TypeScript Types
559
+
560
+ All types are exported for TypeScript users:
561
+
562
+ ```tsx
563
+ import type {
564
+ // Meta types
565
+ TaruviMeta,
566
+ TaruviListResponse,
567
+ AnalyticsMeta,
568
+ FunctionMeta,
569
+ StorageUploadVariables,
570
+
571
+ // Auth types
572
+ TaruviUser,
573
+ LoginParams,
574
+ LogoutParams,
575
+ RegisterParams,
576
+
577
+ // SDK types (re-exported)
578
+ TaruviConfig,
579
+ RoleResponse,
580
+ AnalyticsRequest,
581
+ AnalyticsResponse,
582
+ } from "@taruvi/refine-providers";
583
+ ```
584
+
585
+ ---
586
+
587
+ ## SDK Re-exports
588
+
589
+ For convenience, SDK classes are re-exported:
590
+
591
+ ```tsx
592
+ import {
593
+ Client,
594
+ Auth,
595
+ Policy,
596
+ Functions,
597
+ App,
598
+ Analytics,
599
+ } from "@taruvi/refine-providers";
600
+
601
+ // Use SDK directly when needed
602
+ const auth = new Auth(client);
603
+ const isLoggedIn = auth.isUserAuthenticated();
604
+ ```
605
+
606
+ ---
607
+
608
+ ## Utility Functions
609
+
610
+ Advanced users can access utility functions:
611
+
612
+ ```tsx
613
+ import {
614
+ REFINE_OPERATOR_MAP,
615
+ convertRefineFilters,
616
+ convertRefineSorters,
617
+ convertRefinePagination,
618
+ buildRefineQueryParams,
619
+ buildQueryString,
620
+ handleError,
621
+ } from "@taruvi/refine-providers";
622
+ ```
623
+
624
+ ---
625
+
626
+ ## License
627
+
628
+ MIT