@taruvi/refine-providers 1.1.5 → 1.1.7

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 CHANGED
@@ -12,8 +12,8 @@ npm install @taruvi/refine-providers @taruvi/sdk @refinedev/core
12
12
 
13
13
  ```tsx
14
14
  import { Refine } from "@refinedev/core";
15
+ import { Client } from "@taruvi/sdk";
15
16
  import {
16
- Client,
17
17
  dataProvider,
18
18
  storageDataProvider,
19
19
  appDataProvider,
@@ -52,7 +52,7 @@ This package includes multiple specialized data providers:
52
52
 
53
53
  | Provider | Purpose | SDK Class | Hook |
54
54
  |----------|---------|-----------|------|
55
- | `dataProvider` | Database CRUD operations | `Database` | `useList`, `useOne`, `useCreate`, etc. |
55
+ | `dataProvider` | Database CRUD & Graph operations | `Database`, `Graph` | `useList`, `useOne`, `useCreate`, etc. |
56
56
  | `storageDataProvider` | File storage operations | `Storage` | `useList`, `useCreate`, `useDelete` |
57
57
  | `functionsDataProvider` | Edge function execution | `Functions` | `useCreate` |
58
58
  | `appDataProvider` | App-level data (roles, settings) | `App` | `useList`, `useOne` |
@@ -68,7 +68,8 @@ The main data provider for CRUD operations on database tables.
68
68
  ### Basic Usage
69
69
 
70
70
  ```tsx
71
- import { dataProvider, Client } from "@taruvi/refine-providers";
71
+ import { Client } from "@taruvi/sdk";
72
+ import { dataProvider } from "@taruvi/refine-providers";
72
73
 
73
74
  const client = new Client({ apiKey, appSlug, baseUrl });
74
75
 
@@ -192,6 +193,93 @@ const { data } = useList({
192
193
  });
193
194
  ```
194
195
 
196
+ ### Graph Operations
197
+
198
+ The data provider supports graph traversal and edge management when graph meta options are provided.
199
+
200
+ #### Reading Graph Data
201
+
202
+ ```tsx
203
+ // Get graph structure for a record
204
+ const { data } = useOne({
205
+ resource: "employees",
206
+ id: "1",
207
+ meta: {
208
+ format: "graph", // 'tree' or 'graph'
209
+ include: "descendants", // 'descendants', 'ancestors', or 'both'
210
+ depth: 2, // traversal depth
211
+ graph_types: ["manager", "mentor"], // filter by edge types
212
+ },
213
+ });
214
+
215
+ // List with graph format
216
+ const { data } = useList({
217
+ resource: "employees",
218
+ meta: {
219
+ format: "tree",
220
+ include: "both",
221
+ depth: 3,
222
+ },
223
+ });
224
+ ```
225
+
226
+ #### Graph Meta Options
227
+
228
+ | Option | Type | Description |
229
+ |--------|------|-------------|
230
+ | `format` | `'tree' \| 'graph'` | Output format for graph data |
231
+ | `include` | `'descendants' \| 'ancestors' \| 'both'` | Direction of graph traversal |
232
+ | `depth` | `number` | How deep to traverse relationships |
233
+ | `graph_types` | `string[]` | Filter edges by type |
234
+
235
+ #### Managing Graph Edges
236
+
237
+ When any graph meta option is present, mutation operations work with edges:
238
+
239
+ ```tsx
240
+ // Create an edge
241
+ const { mutate: createEdge } = useCreate();
242
+ createEdge({
243
+ resource: "employees",
244
+ values: {
245
+ from_id: 1,
246
+ to_id: 2,
247
+ type: "manager",
248
+ metadata: { since: "2024-01-01" },
249
+ },
250
+ meta: { format: "graph" }, // triggers graph mode
251
+ });
252
+
253
+ // Update an edge
254
+ const { mutate: updateEdge } = useUpdate();
255
+ updateEdge({
256
+ resource: "employees",
257
+ id: "edge-123", // edge ID
258
+ values: {
259
+ from_id: 1,
260
+ to_id: 3,
261
+ type: "manager",
262
+ },
263
+ meta: { format: "graph" },
264
+ });
265
+
266
+ // Delete edges
267
+ const { mutate: deleteEdge } = useDelete();
268
+ deleteEdge({
269
+ resource: "employees",
270
+ id: "edge-123",
271
+ meta: { format: "graph" },
272
+ });
273
+
274
+ // Delete multiple edges
275
+ const { mutate: deleteEdges } = useDeleteMany();
276
+ deleteEdges({
277
+ resource: "employees",
278
+ ids: ["edge-123", "edge-456"],
279
+ meta: { format: "graph" },
280
+ });
281
+ ```
282
+
195
283
  ---
196
284
 
197
285
  ## Storage Data Provider
@@ -201,7 +289,8 @@ For file upload, download, and management operations.
201
289
  ### Setup
202
290
 
203
291
  ```tsx
204
- import { storageDataProvider, Client } from "@taruvi/refine-providers";
292
+ import { Client } from "@taruvi/sdk";
293
+ import { storageDataProvider } from "@taruvi/refine-providers";
205
294
 
206
295
  const client = new Client({ apiKey, appSlug, baseUrl });
207
296
 
@@ -291,7 +380,7 @@ For executing Taruvi edge functions.
291
380
  ### Setup
292
381
 
293
382
  ```tsx
294
- import { functionsDataProvider, Client } from "@taruvi/refine-providers";
383
+ import { functionsDataProvider } from "@taruvi/refine-providers";
295
384
 
296
385
  <Refine
297
386
  dataProvider={{
@@ -366,7 +455,7 @@ For fetching app-level data like roles and settings.
366
455
  ### Setup
367
456
 
368
457
  ```tsx
369
- import { appDataProvider, Client } from "@taruvi/refine-providers";
458
+ import { appDataProvider } from "@taruvi/refine-providers";
370
459
 
371
460
  <Refine
372
461
  dataProvider={{
@@ -408,7 +497,7 @@ For fetching user-level data including users list and current user details.
408
497
  ### Setup
409
498
 
410
499
  ```tsx
411
- import { userDataProvider, Client } from "@taruvi/refine-providers";
500
+ import { userDataProvider } from "@taruvi/refine-providers";
412
501
 
413
502
  <Refine
414
503
  dataProvider={{
@@ -466,7 +555,7 @@ For executing predefined analytics queries.
466
555
  ### Setup
467
556
 
468
557
  ```tsx
469
- import { analyticsDataProvider, Client } from "@taruvi/refine-providers";
558
+ import { analyticsDataProvider } from "@taruvi/refine-providers";
470
559
 
471
560
  <Refine
472
561
  dataProvider={{
@@ -541,7 +630,8 @@ Redirect-based authentication using Taruvi's Web UI Flow.
541
630
  ### Setup
542
631
 
543
632
  ```tsx
544
- import { authProvider, Client } from "@taruvi/refine-providers";
633
+ import { Client } from "@taruvi/sdk";
634
+ import { authProvider } from "@taruvi/refine-providers";
545
635
 
546
636
  const client = new Client({ apiKey, appSlug, baseUrl });
547
637
 
@@ -613,7 +703,7 @@ Resource-based authorization using Cerbos policies.
613
703
  ### Setup
614
704
 
615
705
  ```tsx
616
- import { accessControlProvider, Client } from "@taruvi/refine-providers";
706
+ import { accessControlProvider } from "@taruvi/refine-providers";
617
707
 
618
708
  <Refine
619
709
  authProvider={authProvider(client)}
@@ -692,8 +782,8 @@ const { data } = useCan({
692
782
  Use multiple providers together:
693
783
 
694
784
  ```tsx
785
+ import { Client } from "@taruvi/sdk";
695
786
  import {
696
- Client,
697
787
  dataProvider,
698
788
  storageDataProvider,
699
789
  functionsDataProvider,
@@ -744,42 +834,14 @@ import type {
744
834
  StorageUploadVariables,
745
835
 
746
836
  // Auth types
747
- TaruviUser,
748
837
  LoginParams,
749
838
  LogoutParams,
750
839
  RegisterParams,
751
-
752
- // SDK types (re-exported)
753
- TaruviConfig,
754
- RoleResponse,
755
- AnalyticsRequest,
756
- AnalyticsResponse,
757
840
  } from "@taruvi/refine-providers";
758
841
  ```
759
842
 
760
843
  ---
761
844
 
762
- ## SDK Re-exports
763
-
764
- For convenience, SDK classes are re-exported:
765
-
766
- ```tsx
767
- import {
768
- Client,
769
- Auth,
770
- Policy,
771
- Functions,
772
- App,
773
- Analytics,
774
- } from "@taruvi/refine-providers";
775
-
776
- // Use SDK directly when needed
777
- const auth = new Auth(client);
778
- const isLoggedIn = auth.isUserAuthenticated();
779
- ```
780
-
781
- ---
782
-
783
845
  ## Utility Functions
784
846
 
785
847
  Advanced users can access utility functions:
package/dist/index.cjs CHANGED
@@ -86,9 +86,21 @@ function applyPopulate(query, meta) {
86
86
  const populateArray = Array.isArray(meta.populate) ? meta.populate : meta.populate.split(",").map((s) => s.trim());
87
87
  return query.populate(populateArray);
88
88
  }
89
+ function isGraphQuery(meta) {
90
+ return !!(meta?.format || meta?.graph_types || meta?.include || meta?.depth);
91
+ }
92
+ function buildGraphQuery(client, tableName, meta, recordId) {
93
+ let query = new sdk.Graph(client).from(tableName);
94
+ if (recordId) query = query.get(recordId);
95
+ if (meta?.format) query = query.format(meta.format);
96
+ if (meta?.include) query = query.include(meta.include);
97
+ if (meta?.depth) query = query.depth(meta.depth);
98
+ if (meta?.graph_types) query = query.types(meta.graph_types);
99
+ return query;
100
+ }
89
101
  function dataProvider(client) {
90
102
  const config = client.getConfig();
91
- const baseApiUrl = `${config.apiUrl}/api/apps/${config.appSlug}`;
103
+ const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
92
104
  const getIdColumn = (meta) => meta?.idColumnName ?? "id";
93
105
  const getTableName = (resource, meta) => meta?.tableName ?? resource;
94
106
  return {
@@ -96,6 +108,12 @@ function dataProvider(client) {
96
108
  const { resource, pagination, filters, sorters, meta } = params;
97
109
  const taruviMeta = meta;
98
110
  const tableName = getTableName(resource, taruviMeta);
111
+ if (isGraphQuery(taruviMeta)) {
112
+ const response2 = await buildGraphQuery(client, tableName, taruviMeta).execute();
113
+ const data = Array.isArray(response2) ? response2 : response2?.data ?? [];
114
+ const total = response2?.total ?? data.length;
115
+ return { data, total };
116
+ }
99
117
  let query = new sdk.Database(client).from(tableName);
100
118
  query = applyFilters(query, filters);
101
119
  query = applySorters(query, sorters);
@@ -108,6 +126,11 @@ function dataProvider(client) {
108
126
  const { resource, id, meta } = params;
109
127
  const taruviMeta = meta;
110
128
  const tableName = getTableName(resource, taruviMeta);
129
+ if (isGraphQuery(taruviMeta)) {
130
+ const response2 = await buildGraphQuery(client, tableName, taruviMeta, String(id)).execute();
131
+ const data = Array.isArray(response2) ? response2[0] : response2?.data?.[0] ?? response2;
132
+ return { data };
133
+ }
111
134
  let query = new sdk.Database(client).from(tableName);
112
135
  query = applyPopulate(query, taruviMeta);
113
136
  const response = await query.get(String(id)).execute();
@@ -117,6 +140,15 @@ function dataProvider(client) {
117
140
  const { resource, ids, meta } = params;
118
141
  const taruviMeta = meta;
119
142
  const tableName = getTableName(resource, taruviMeta);
143
+ if (isGraphQuery(taruviMeta)) {
144
+ const data = await Promise.all(
145
+ ids.map(async (id) => {
146
+ const response2 = await buildGraphQuery(client, tableName, taruviMeta, String(id)).execute();
147
+ return Array.isArray(response2) ? response2[0] : response2?.data?.[0] ?? response2;
148
+ })
149
+ );
150
+ return { data };
151
+ }
120
152
  const idColumn = getIdColumn(taruviMeta);
121
153
  let query = new sdk.Database(client).from(tableName);
122
154
  query = query.filter(idColumn, "in", ids.map(String));
@@ -128,6 +160,10 @@ function dataProvider(client) {
128
160
  const { resource, variables, meta } = params;
129
161
  const taruviMeta = meta;
130
162
  const tableName = getTableName(resource, taruviMeta);
163
+ if (isGraphQuery(taruviMeta)) {
164
+ const data2 = await new sdk.Graph(client).from(tableName).createEdge(variables).execute();
165
+ return { data: data2 };
166
+ }
131
167
  const data = await new sdk.Database(client).from(tableName).create(variables).execute();
132
168
  return { data };
133
169
  },
@@ -146,6 +182,10 @@ function dataProvider(client) {
146
182
  const { resource, id, variables, meta } = params;
147
183
  const taruviMeta = meta;
148
184
  const tableName = getTableName(resource, taruviMeta);
185
+ if (isGraphQuery(taruviMeta)) {
186
+ const data2 = await new sdk.Graph(client).from(tableName).updateEdge(String(id), variables).execute();
187
+ return { data: data2 };
188
+ }
149
189
  const data = await new sdk.Database(client).from(tableName).get(String(id)).update(variables).execute();
150
190
  return { data };
151
191
  },
@@ -164,6 +204,10 @@ function dataProvider(client) {
164
204
  const { resource, id, meta } = params;
165
205
  const taruviMeta = meta;
166
206
  const tableName = getTableName(resource, taruviMeta);
207
+ if (isGraphQuery(taruviMeta)) {
208
+ const data2 = await new sdk.Graph(client).from(tableName).deleteEdge([String(id)]).execute();
209
+ return { data: data2 };
210
+ }
167
211
  const data = await new sdk.Database(client).from(tableName).delete(String(id)).execute();
168
212
  return { data };
169
213
  },
@@ -171,21 +215,28 @@ function dataProvider(client) {
171
215
  const { resource, ids, meta } = params;
172
216
  const taruviMeta = meta;
173
217
  const tableName = getTableName(resource, taruviMeta);
218
+ if (isGraphQuery(taruviMeta)) {
219
+ const data2 = await new sdk.Graph(client).from(tableName).deleteEdge(ids.map(String)).execute();
220
+ return { data: [data2] };
221
+ }
174
222
  const data = await Promise.all(
175
- ids.map(async (id) => {
176
- return new sdk.Database(client).from(tableName).delete(String(id)).execute();
177
- })
223
+ ids.map((id) => new sdk.Database(client).from(tableName).delete(String(id)).execute())
178
224
  );
179
225
  return { data };
180
226
  },
181
227
  custom: async (params) => {
182
- const { url, method, payload } = params;
183
- const fullUrl = url.startsWith("http") ? url : `${baseApiUrl}${url}`;
228
+ const { url, method, payload, query } = params;
229
+ let fullUrl = `api/apps/${config.appSlug}/datatables/${url}`;
184
230
  let data;
185
231
  switch (method.toLowerCase()) {
186
- case "get":
232
+ case "get": {
233
+ if (query && Object.keys(query).length > 0) {
234
+ const queryString = new URLSearchParams(query).toString();
235
+ fullUrl = `${fullUrl}${fullUrl.includes("?") ? "&" : "?"}${queryString}`;
236
+ }
187
237
  data = await client.httpClient.get(fullUrl);
188
238
  break;
239
+ }
189
240
  case "post":
190
241
  data = await client.httpClient.post(fullUrl, payload);
191
242
  break;
@@ -327,7 +378,7 @@ function handleError(error) {
327
378
  // src/storageDataProvider.ts
328
379
  function storageDataProvider(client) {
329
380
  const config = client.getConfig();
330
- const baseApiUrl = `${config.apiUrl}/api/apps/${config.appSlug}`;
381
+ const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
331
382
  const getBucketName = (resource, meta) => meta?.bucketName ?? resource;
332
383
  const buildFilters = (params) => {
333
384
  const filters = {
@@ -401,13 +452,18 @@ function storageDataProvider(client) {
401
452
  return { data: [data] };
402
453
  },
403
454
  custom: async (params) => {
404
- const { url, method, payload } = params;
405
- const fullUrl = url.startsWith("http") ? url : `${baseApiUrl}${url}`;
455
+ const { url, method, payload, query } = params;
456
+ let fullUrl = `api/apps/${config.appSlug}/storage/buckets/${url}`;
406
457
  let data;
407
458
  switch (method.toLowerCase()) {
408
- case "get":
459
+ case "get": {
460
+ if (query && Object.keys(query).length > 0) {
461
+ const queryString = new URLSearchParams(query).toString();
462
+ fullUrl = `${fullUrl}${fullUrl.includes("?") ? "&" : "?"}${queryString}`;
463
+ }
409
464
  data = await client.httpClient.get(fullUrl);
410
465
  break;
466
+ }
411
467
  case "post":
412
468
  data = await client.httpClient.post(fullUrl, payload);
413
469
  break;
@@ -428,7 +484,7 @@ function storageDataProvider(client) {
428
484
  }
429
485
  function functionsDataProvider(client) {
430
486
  const config = client.getConfig();
431
- const baseApiUrl = `${config.apiUrl}/api/apps/${config.appSlug}`;
487
+ const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
432
488
  const functions = new sdk.Functions(client);
433
489
  return {
434
490
  /**
@@ -502,7 +558,7 @@ function functionsDataProvider(client) {
502
558
  }
503
559
  function appDataProvider(client) {
504
560
  const config = client.getConfig();
505
- const baseApiUrl = `${config.apiUrl}/api/apps/${config.appSlug}`;
561
+ const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
506
562
  return {
507
563
  getList: async (params) => {
508
564
  const { resource } = params;
@@ -598,10 +654,10 @@ function buildUserListFilters(filters, sorters, pagination) {
598
654
  }
599
655
  function userDataProvider(client) {
600
656
  const config = client.getConfig();
601
- const baseApiUrl = `${config.apiUrl}/api/apps/${config.appSlug}`;
657
+ const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
602
658
  return {
603
659
  getList: async (params) => {
604
- const { resource, pagination, filters, sorters } = params;
660
+ const { resource, pagination, filters, sorters, meta } = params;
605
661
  if (resource === "users") {
606
662
  const user = new sdk.User(client);
607
663
  const userFilters = buildUserListFilters(filters, sorters, pagination);
@@ -611,18 +667,29 @@ function userDataProvider(client) {
611
667
  total: response.total
612
668
  };
613
669
  }
614
- throw new Error(`Unknown user resource for getList: ${resource}. Supported resources: users`);
670
+ if (resource === "roles") {
671
+ const username = meta?.username;
672
+ if (!username) {
673
+ throw new Error("roles resource requires meta.username");
674
+ }
675
+ const user = new sdk.User(client);
676
+ const response = await user.getUser(username);
677
+ const roles = response.roles || [];
678
+ return {
679
+ data: roles,
680
+ total: roles.length
681
+ };
682
+ }
683
+ throw new Error(`Unknown user resource for getList: ${resource}. Supported: users, roles`);
615
684
  },
616
685
  getOne: async (params) => {
617
686
  const { resource, id } = params;
618
687
  if (resource === "users") {
619
688
  const user = new sdk.User(client);
620
689
  const response = await user.getUser(String(id));
621
- return {
622
- data: response
623
- };
690
+ return { data: response };
624
691
  }
625
- throw new Error(`Unknown user resource for getOne: ${resource}. Supported resources: me, users`);
692
+ throw new Error(`Unknown user resource for getOne: ${resource}. Supported: users`);
626
693
  },
627
694
  getApiUrl: () => baseApiUrl,
628
695
  create: async (params) => {
@@ -682,7 +749,7 @@ function userDataProvider(client) {
682
749
  }
683
750
  function analyticsDataProvider(client) {
684
751
  const config = client.getConfig();
685
- const baseApiUrl = `${config.apiUrl}/api/apps/${config.appSlug}`;
752
+ const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
686
753
  const analytics = new sdk.Analytics(client);
687
754
  return {
688
755
  /**