@taruvi/refine-providers 1.0.10 → 1.1.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/README.md CHANGED
@@ -16,6 +16,8 @@ import {
16
16
  Client,
17
17
  dataProvider,
18
18
  storageDataProvider,
19
+ appDataProvider,
20
+ userDataProvider,
19
21
  authProvider,
20
22
  accessControlProvider,
21
23
  } from "@taruvi/refine-providers";
@@ -53,7 +55,8 @@ This package includes multiple specialized data providers:
53
55
  | `dataProvider` | Database CRUD operations | `Database` | `useList`, `useOne`, `useCreate`, etc. |
54
56
  | `storageDataProvider` | File storage operations | `Storage` | `useList`, `useCreate`, `useDelete` |
55
57
  | `functionsDataProvider` | Edge function execution | `Functions` | `useCreate` |
56
- | `appDataProvider` | App-level data (roles) | `App` | `useList` |
58
+ | `appDataProvider` | App-level data (roles, settings) | `App` | `useList`, `useOne` |
59
+ | `userDataProvider` | User-level data (users list, current user) | `User` | `useList`, `useOne` |
57
60
  | `analyticsDataProvider` | Analytics queries | `Analytics` | `useCreate` |
58
61
 
59
62
  ---
@@ -358,7 +361,7 @@ mutate({
358
361
 
359
362
  ## App Data Provider
360
363
 
361
- For fetching app-level data like roles.
364
+ For fetching app-level data like roles and settings.
362
365
 
363
366
  ### Setup
364
367
 
@@ -384,6 +387,76 @@ const { data } = useList({
384
387
  // Returns: { data: [{ id, name, permissions, ... }], total: number }
385
388
  ```
386
389
 
390
+ ### Fetch Settings
391
+
392
+ ```tsx
393
+ const { data } = useOne({
394
+ resource: "settings",
395
+ dataProviderName: "app",
396
+ id: "", // id is ignored for settings
397
+ });
398
+
399
+ // Returns: { data: { ...app settings object } }
400
+ ```
401
+
402
+ ---
403
+
404
+ ## User Data Provider
405
+
406
+ For fetching user-level data including users list and current user details.
407
+
408
+ ### Setup
409
+
410
+ ```tsx
411
+ import { userDataProvider, Client } from "@taruvi/refine-providers";
412
+
413
+ <Refine
414
+ dataProvider={{
415
+ default: dataProvider(client),
416
+ user: userDataProvider(client),
417
+ }}
418
+ />
419
+ ```
420
+
421
+ ### Fetch Users List
422
+
423
+ ```tsx
424
+ const { data } = useList({
425
+ resource: "users",
426
+ dataProviderName: "user",
427
+ pagination: { currentPage: 1, pageSize: 10 },
428
+ filters: [
429
+ { field: "is_active", operator: "eq", value: true },
430
+ { field: "search", operator: "eq", value: "john" },
431
+ ],
432
+ sorters: [{ field: "username", order: "asc" }],
433
+ });
434
+
435
+ // Returns: { data: [{ id, username, email, first_name, last_name, ... }], total: number }
436
+ ```
437
+
438
+ **Supported Filters:**
439
+
440
+ | Filter | Type | Description |
441
+ |--------|------|-------------|
442
+ | `search` | string | Search by username, email, or name |
443
+ | `is_active` | boolean | Filter by active status |
444
+ | `is_staff` | boolean | Filter by staff status |
445
+ | `is_superuser` | boolean | Filter by superuser status |
446
+ | `is_deleted` | boolean | Filter by deleted status |
447
+
448
+ ### Get Current User
449
+
450
+ ```tsx
451
+ const { data } = useOne({
452
+ resource: "me",
453
+ dataProviderName: "user",
454
+ id: "", // id is ignored for "me" resource
455
+ });
456
+
457
+ // Returns: { data: { id, username, email, first_name, last_name, full_name, is_active, is_staff, ... } }
458
+ ```
459
+
387
460
  ---
388
461
 
389
462
  ## Analytics Data Provider
@@ -591,6 +664,27 @@ For Cerbos, specify the entity type in resource meta:
591
664
  />
592
665
  ```
593
666
 
667
+ ### Override Entity Type at Runtime
668
+
669
+ You can override the entity type directly in `useCan` params:
670
+
671
+ ```tsx
672
+ // Override entityType for this specific check
673
+ const { data } = useCan({
674
+ resource: "posts",
675
+ action: "edit",
676
+ params: {
677
+ id: 1,
678
+ entityType: "article", // Overrides resource.meta.entityType
679
+ },
680
+ });
681
+ ```
682
+
683
+ **Entity Type Resolution Priority:**
684
+ 1. `params.entityType` (direct override)
685
+ 2. `resource.meta.entityType` (from Refine config)
686
+ 3. Resource name (fallback)
687
+
594
688
  ---
595
689
 
596
690
  ## Multiple Data Providers
@@ -604,6 +698,7 @@ import {
604
698
  storageDataProvider,
605
699
  functionsDataProvider,
606
700
  appDataProvider,
701
+ userDataProvider,
607
702
  analyticsDataProvider,
608
703
  } from "@taruvi/refine-providers";
609
704
 
@@ -615,6 +710,7 @@ const client = new Client({ apiKey, appSlug, baseUrl });
615
710
  storage: storageDataProvider(client),
616
711
  functions: functionsDataProvider(client),
617
712
  app: appDataProvider(client),
713
+ user: userDataProvider(client),
618
714
  analytics: analyticsDataProvider(client),
619
715
  }}
620
716
  />
@@ -623,6 +719,8 @@ const client = new Client({ apiKey, appSlug, baseUrl });
623
719
  useList({ resource: "posts" }); // Uses default
624
720
  useList({ resource: "images", dataProviderName: "storage" });
625
721
  useList({ resource: "roles", dataProviderName: "app" });
722
+ useList({ resource: "users", dataProviderName: "user" });
723
+ useOne({ resource: "me", dataProviderName: "user", id: "" });
626
724
 
627
725
  // For functions and analytics, use useCreate:
628
726
  const { mutate } = useCreate();
package/dist/index.cjs CHANGED
@@ -517,10 +517,18 @@ function appDataProvider(client) {
517
517
  throw new Error(`Unknown app resource: ${resource}. Supported resources: roles`);
518
518
  },
519
519
  getApiUrl: () => baseApiUrl,
520
- // App resources are read-only
521
- getOne: async () => {
522
- throw new Error("getOne is not supported for app resources");
520
+ getOne: async (params) => {
521
+ const { resource } = params;
522
+ if (resource === "settings") {
523
+ const app = new sdk.App(client);
524
+ const response = await app.settings().execute();
525
+ return {
526
+ data: response
527
+ };
528
+ }
529
+ throw new Error(`Unknown app resource for getOne: ${resource}. Supported resources: settings`);
523
530
  },
531
+ // App resources are read-only
524
532
  getMany: async () => {
525
533
  throw new Error("getMany is not supported for app resources");
526
534
  },
@@ -547,32 +555,74 @@ function appDataProvider(client) {
547
555
  }
548
556
  };
549
557
  }
558
+ function buildUserListFilters(filters, sorters, pagination) {
559
+ const result = {};
560
+ if (pagination && pagination.mode !== "off") {
561
+ if (pagination.currentPage) {
562
+ result.page = pagination.currentPage;
563
+ }
564
+ if (pagination.pageSize) {
565
+ result.page_size = pagination.pageSize;
566
+ }
567
+ }
568
+ if (filters) {
569
+ for (const filter of filters) {
570
+ if ("field" in filter) {
571
+ const field = filter.field;
572
+ const value = filter.value;
573
+ switch (field) {
574
+ case "search":
575
+ result.search = String(value);
576
+ break;
577
+ case "is_active":
578
+ result.is_active = Boolean(value);
579
+ break;
580
+ case "is_staff":
581
+ result.is_staff = Boolean(value);
582
+ break;
583
+ case "is_superuser":
584
+ result.is_superuser = Boolean(value);
585
+ break;
586
+ case "is_deleted":
587
+ result.is_deleted = Boolean(value);
588
+ break;
589
+ }
590
+ }
591
+ }
592
+ }
593
+ if (sorters && sorters.length > 0) {
594
+ const sorter = sorters[0];
595
+ result.ordering = sorter.order === "desc" ? `-${sorter.field}` : sorter.field;
596
+ }
597
+ return result;
598
+ }
550
599
  function userDataProvider(client) {
551
600
  const config = client.getConfig();
552
601
  const baseApiUrl = `${config.baseUrl}/api/apps/${config.appSlug}`;
553
602
  return {
554
603
  getList: async (params) => {
555
- const { resource } = params;
556
- if (resource === "roles") {
557
- const app = new sdk.App(client);
558
- const response = await app.roles().execute();
604
+ const { resource, pagination, filters, sorters } = params;
605
+ if (resource === "users") {
606
+ const user = new sdk.User(client);
607
+ const userFilters = buildUserListFilters(filters, sorters, pagination);
608
+ const response = await user.list(userFilters);
559
609
  return {
560
610
  data: response.data || response,
561
- total: response.total ?? (Array.isArray(response) ? response.length : response.data?.length ?? 0)
611
+ total: response.total
562
612
  };
563
613
  }
564
- throw new Error(`Unknown user resource for getList: ${resource}. Supported resources: roles`);
614
+ throw new Error(`Unknown user resource for getList: ${resource}. Supported resources: users`);
565
615
  },
566
616
  getOne: async (params) => {
567
- const { resource } = params;
568
- if (resource === "me") {
617
+ const { resource, id } = params;
618
+ if (resource === "users") {
569
619
  const user = new sdk.User(client);
570
- const response = await user.getUserData();
620
+ const response = await user.getUser(String(id));
571
621
  return {
572
622
  data: response
573
623
  };
574
624
  }
575
- throw new Error(`Unknown user resource for getOne: ${resource}. Supported resources: me`);
625
+ throw new Error(`Unknown user resource for getOne: ${resource}. Supported resources: me, users`);
576
626
  },
577
627
  getApiUrl: () => baseApiUrl,
578
628
  // User resources are mostly read-only
@@ -863,7 +913,7 @@ function accessControlProvider(client, options) {
863
913
  if (!resource) {
864
914
  return { can: false, reason: "Resource not specified" };
865
915
  }
866
- const entityType = params?.resource?.meta?.entityType;
916
+ const entityType = params?.entityType ?? params?.resource?.meta?.entityType;
867
917
  return permissionLoader.load({
868
918
  resource,
869
919
  action,