@taruvi/refine-providers
v1.0.10
Published
Refine.dev data provider for Taruvi Data Service
Maintainers
Readme
@taruvi/refine-providers
Refine.dev data providers for Taruvi Data Service. This package provides a complete integration layer between Refine and the Taruvi backend platform.
Installation
npm install @taruvi/refine-providers @taruvi/sdk @refinedev/coreQuick Start
import { Refine } from "@refinedev/core";
import {
Client,
dataProvider,
storageDataProvider,
authProvider,
accessControlProvider,
} from "@taruvi/refine-providers";
// Initialize the Taruvi client
const client = new Client({
apiKey: "your-api-key",
appSlug: "your-app-slug",
baseUrl: "https://your-site.taruvi.cloud",
});
function App() {
return (
<Refine
dataProvider={dataProvider(client)}
authProvider={authProvider(client)}
accessControlProvider={accessControlProvider(client)}
resources={[
{ name: "users" },
{ name: "posts" },
]}
>
{/* Your app */}
</Refine>
);
}Data Providers
This package includes multiple specialized data providers:
| Provider | Purpose | SDK Class | Hook |
|----------|---------|-----------|------|
| dataProvider | Database CRUD operations | Database | useList, useOne, useCreate, etc. |
| storageDataProvider | File storage operations | Storage | useList, useCreate, useDelete |
| functionsDataProvider | Edge function execution | Functions | useCreate |
| appDataProvider | App-level data (roles) | App | useList |
| analyticsDataProvider | Analytics queries | Analytics | useCreate |
Database Data Provider
The main data provider for CRUD operations on database tables.
Basic Usage
import { dataProvider, Client } from "@taruvi/refine-providers";
const client = new Client({ apiKey, appSlug, baseUrl });
<Refine
dataProvider={dataProvider(client)}
resources={[{ name: "posts" }]}
/>Supported Operations
All standard Refine CRUD operations are supported:
// List records
const { data } = useList({ resource: "posts" });
// Get single record
const { data } = useOne({ resource: "posts", id: 1 });
// Get multiple records
const { data } = useMany({ resource: "posts", ids: [1, 2, 3] });
// Create record
const { mutate } = useCreate();
mutate({ resource: "posts", values: { title: "Hello" } });
// Update record
const { mutate } = useUpdate();
mutate({ resource: "posts", id: 1, values: { title: "Updated" } });
// Delete record
const { mutate } = useDelete();
mutate({ resource: "posts", id: 1 });Filtering
Full support for Refine filter operators:
const { data } = useList({
resource: "posts",
filters: [
{ field: "status", operator: "eq", value: "published" },
{ field: "views", operator: "gte", value: 100 },
{ field: "title", operator: "contains", value: "refine" },
{ field: "category", operator: "in", value: ["tech", "news"] },
],
});Supported Operators:
| Operator | Description | Example |
|----------|-------------|---------|
| eq | Equal | status = "active" |
| ne | Not equal | status != "deleted" |
| lt, gt, lte, gte | Comparison | age >= 18 |
| contains, ncontains | Contains (case-sensitive) | title contains "hello" |
| containss, ncontainss | Contains (case-insensitive) | title icontains "hello" |
| startswith, endswith | String matching | email endswith "@gmail.com" |
| in, nin | Array membership | status in ["active", "pending"] |
| null, nnull | Null checks | deleted_at is null |
| between, nbetween | Range | price between [10, 100] |
Sorting & Pagination
const { data } = useList({
resource: "posts",
sorters: [
{ field: "created_at", order: "desc" },
{ field: "title", order: "asc" },
],
pagination: {
currentPage: 1,
pageSize: 20,
},
});Meta Options
Use the meta parameter for Taruvi-specific features:
const { data } = useList({
resource: "posts",
meta: {
// Override table name (when resource differs from table)
tableName: "blog_posts",
// Populate foreign key relations
populate: ["author", "category"],
// or populate all: populate: "*"
// Select specific fields
select: ["id", "title", "status"],
// Custom ID column
idColumnName: "post_id",
},
});Aggregations
Support for aggregate queries with grouping:
const { data } = useList({
resource: "orders",
meta: {
aggregate: ["sum(total)", "count(*)", "avg(quantity)"],
groupBy: ["status", "category"],
having: [
{ field: "sum(total)", operator: "gte", value: 1000 },
],
},
});Storage Data Provider
For file upload, download, and management operations.
Setup
import { storageDataProvider, Client } from "@taruvi/refine-providers";
const client = new Client({ apiKey, appSlug, baseUrl });
<Refine
dataProvider={{
default: dataProvider(client),
storage: storageDataProvider(client),
}}
/>List Files
const { data } = useList({
resource: "documents", // bucket name
dataProviderName: "storage",
});Upload Files
import { useCreate } from "@refinedev/core";
import type { StorageUploadVariables } from "@taruvi/refine-providers";
const { mutate } = useCreate<any, any, StorageUploadVariables>();
// Single file upload
mutate({
resource: "documents",
dataProviderName: "storage",
values: {
files: [file],
paths: ["uploads/document.pdf"],
metadatas: [{ description: "My document" }],
},
});
// Multiple files
mutate({
resource: "documents",
dataProviderName: "storage",
values: {
files: [file1, file2],
paths: ["file1.pdf", "file2.pdf"],
metadatas: [{}, {}],
},
});Delete Files
const { mutate } = useDeleteMany();
mutate({
resource: "documents",
dataProviderName: "storage",
ids: ["path/to/file1.pdf", "path/to/file2.pdf"],
});Filter Files
const { data } = useList({
resource: "documents",
dataProviderName: "storage",
filters: [
{ field: "mimetype_category", operator: "eq", value: "image" },
{ field: "size", operator: "lte", value: 5242880 }, // 5MB
{ field: "visibility", operator: "eq", value: "public" },
],
meta: {
bucketName: "uploads", // Override bucket name
},
});Functions Data Provider
For executing Taruvi edge functions.
Setup
import { functionsDataProvider, Client } from "@taruvi/refine-providers";
<Refine
dataProvider={{
default: dataProvider(client),
functions: functionsDataProvider(client),
}}
/>Execute Function
Use the useCreate hook with the function slug as the resource:
import { useCreate } from "@refinedev/core";
const { mutate, mutation } = useCreate();
// Execute function
mutate({
dataProviderName: "functions",
resource: "process-order", // function slug
values: {
orderId: 123,
action: "confirm",
},
meta: {
async: false, // Set to true for async execution
},
});
// Check loading state
if (mutation.isPending) {
console.log("Executing function...");
}With Callbacks
mutate(
{
dataProviderName: "functions",
resource: "send-notification",
values: { userId: 456, message: "Hello" },
},
{
onSuccess: (data) => console.log("Function result:", data),
onError: (error) => console.error("Function failed:", error),
}
);Async Function Execution
// Long-running task - returns immediately with job ID
mutate({
dataProviderName: "functions",
resource: "long-running-task",
values: { taskId: 789 },
meta: { async: true },
});App Data Provider
For fetching app-level data like roles.
Setup
import { appDataProvider, Client } from "@taruvi/refine-providers";
<Refine
dataProvider={{
default: dataProvider(client),
app: appDataProvider(client),
}}
/>Fetch Roles
const { data } = useList({
resource: "roles",
dataProviderName: "app",
});
// Returns: { data: [{ id, name, permissions, ... }], total: number }Analytics Data Provider
For executing predefined analytics queries.
Setup
import { analyticsDataProvider, Client } from "@taruvi/refine-providers";
<Refine
dataProvider={{
default: dataProvider(client),
analytics: analyticsDataProvider(client),
}}
/>Execute Analytics Query
Use the useCreate hook with the query slug as the resource:
import { useCreate } from "@refinedev/core";
const { mutate, mutation } = useCreate();
// Execute analytics query
mutate({
dataProviderName: "analytics",
resource: "monthly-sales-report", // query slug
values: {
start_date: "2024-01-01",
end_date: "2024-12-31",
region: "US",
},
});
// Check loading state
if (mutation.isPending) {
console.log("Running query...");
}With Callbacks
mutate(
{
dataProviderName: "analytics",
resource: "dashboard-metrics",
values: { period: "last_30_days" },
},
{
onSuccess: (data) => console.log("Query result:", data),
onError: (error) => console.error("Query failed:", error),
}
);Query with Aggregations
mutate({
dataProviderName: "analytics",
resource: "revenue-by-region",
values: {
year: 2024,
group_by: "region",
include_forecast: true,
},
});Auth Provider
Redirect-based authentication using Taruvi's Web UI Flow.
Setup
import { authProvider, Client } from "@taruvi/refine-providers";
const client = new Client({ apiKey, appSlug, baseUrl });
<Refine
authProvider={authProvider(client)}
/>Login
import { useLogin } from "@refinedev/core";
const { mutate: login } = useLogin();
// Redirect to login page
login({ callbackUrl: "/dashboard" });Logout
import { useLogout } from "@refinedev/core";
const { mutate: logout } = useLogout();
logout({ callbackUrl: "/login" });Register/Signup
import { useRegister } from "@refinedev/core";
const { mutate: register } = useRegister();
register({ callbackUrl: "/welcome" });Get Current User
import { useGetIdentity } from "@refinedev/core";
import type { TaruviUser } from "@taruvi/refine-providers";
const { data: user } = useGetIdentity<TaruviUser>();
console.log(user?.username);
console.log(user?.email);Check Permissions
import { usePermissions } from "@refinedev/core";
const { data: permissions } = usePermissions();
console.log(permissions?.roles);
console.log(permissions?.is_staff);Access Control Provider
Resource-based authorization using Cerbos policies.
Setup
import { accessControlProvider, Client } from "@taruvi/refine-providers";
<Refine
authProvider={authProvider(client)}
accessControlProvider={accessControlProvider(client)}
/>Check Permissions
import { useCan } from "@refinedev/core";
const { data } = useCan({
resource: "posts",
action: "edit",
params: { id: 1 },
});
if (data?.can) {
// User can edit this post
}CanAccess Component
import { CanAccess } from "@refinedev/core";
<CanAccess resource="posts" action="delete" params={{ id: 1 }}>
<DeleteButton />
</CanAccess>Define Entity Type
For Cerbos, specify the entity type in resource meta:
<Refine
resources={[
{
name: "posts",
meta: {
entityType: "blog", // Used in Cerbos policy
},
},
]}
/>Multiple Data Providers
Use multiple providers together:
import {
Client,
dataProvider,
storageDataProvider,
functionsDataProvider,
appDataProvider,
analyticsDataProvider,
} from "@taruvi/refine-providers";
const client = new Client({ apiKey, appSlug, baseUrl });
<Refine
dataProvider={{
default: dataProvider(client),
storage: storageDataProvider(client),
functions: functionsDataProvider(client),
app: appDataProvider(client),
analytics: analyticsDataProvider(client),
}}
/>
// Then specify which provider to use:
useList({ resource: "posts" }); // Uses default
useList({ resource: "images", dataProviderName: "storage" });
useList({ resource: "roles", dataProviderName: "app" });
// For functions and analytics, use useCreate:
const { mutate } = useCreate();
mutate({ dataProviderName: "functions", resource: "my-function", values: {...} });
mutate({ dataProviderName: "analytics", resource: "my-query", values: {...} });TypeScript Types
All types are exported for TypeScript users:
import type {
// Meta types
TaruviMeta,
TaruviListResponse,
AnalyticsMeta,
FunctionMeta,
StorageUploadVariables,
// Auth types
TaruviUser,
LoginParams,
LogoutParams,
RegisterParams,
// SDK types (re-exported)
TaruviConfig,
RoleResponse,
AnalyticsRequest,
AnalyticsResponse,
} from "@taruvi/refine-providers";SDK Re-exports
For convenience, SDK classes are re-exported:
import {
Client,
Auth,
Policy,
Functions,
App,
Analytics,
} from "@taruvi/refine-providers";
// Use SDK directly when needed
const auth = new Auth(client);
const isLoggedIn = auth.isUserAuthenticated();Utility Functions
Advanced users can access utility functions:
import {
REFINE_OPERATOR_MAP,
convertRefineFilters,
convertRefineSorters,
convertRefinePagination,
buildRefineQueryParams,
buildQueryString,
handleError,
} from "@taruvi/refine-providers";License
MIT
