Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
bb02d5f
feat: initialize for v5
BatuhanW Sep 15, 2025
54caee8
feat: init ky
BatuhanW Sep 16, 2025
01c0d61
fix: tests
BatuhanW Sep 16, 2025
b3d5a75
chore: update pnpm-lock
BatuhanW Sep 16, 2025
b4d9047
chore: use mts extension for vitest config
BatuhanW Sep 16, 2025
4fd2da6
chore: cleanup
BatuhanW Sep 16, 2025
6bd5dec
chore: cleanup some types
BatuhanW Sep 16, 2025
62926bd
chore: cleanup wretch
BatuhanW Sep 16, 2025
b70191a
fix: pnpm-lock
BatuhanW Sep 16, 2025
8581a69
fix: remove response.ok from getList
BatuhanW Sep 16, 2025
4077f06
fix: data-provider-strapi-v4 e2e test
BatuhanW Sep 16, 2025
be090da
feat(examples): use @refinedev/rest in data-provider-strapi-v4 example
BatuhanW Sep 16, 2025
ab64225
fix: data provider options types
BatuhanW Sep 16, 2025
555b023
feat(nestjsx-crud): add @refinedev/rest options and migrate to vitest
BatuhanW Sep 16, 2025
9fa72ba
feat(refine-hr-ce): use @refinedev/rest in example
BatuhanW Sep 16, 2025
e064845
feat(rest): add multiple requests support for updateMany and deleteMany
BatuhanW Sep 16, 2025
5e5850c
refactor(rest): each is true by default and it uses update and delete…
BatuhanW Sep 16, 2025
dc6176b
feat(rest): add transformError option to create and update methods
BatuhanW Sep 16, 2025
c435ff8
refactor(rest): remove updateMany, createMany and deleteMany from def…
BatuhanW Sep 17, 2025
9e2ab7d
refactor(rest): folder structure
BatuhanW Sep 17, 2025
ddfa05e
refactor(rest): rename middlewares to hooks
BatuhanW Sep 17, 2025
5259fd8
test(rest): move strapi-v4 tests to rest package
BatuhanW Sep 17, 2025
545cfa2
chore(rest): small cleanup on strapi-v4
BatuhanW Sep 17, 2025
cb9ccb9
chore(rest): refactor test file
BatuhanW Sep 17, 2025
c131fc5
feat(rest): add nestjsx-crud options
BatuhanW Sep 17, 2025
757c6db
chore(rest): add @nestjsx-crud-request as an optional peer dependency
BatuhanW Sep 17, 2025
c7be9cb
Merge branch 'main' into add-rest-data-provider-for-v5
BatuhanW Sep 17, 2025
114106e
chore(nestjsx-crud): revert changes
BatuhanW Sep 17, 2025
151df28
refactor(rest): return kyInstance and dataProvider from createDataPro…
BatuhanW Sep 17, 2025
0efebdc
feat(rest): add sub package exports
BatuhanW Sep 17, 2025
5de6d50
chore: remove leftover files
BatuhanW Sep 17, 2025
1f65880
chore: update pnpm-lock.yaml
BatuhanW Sep 17, 2025
50a2b1f
fix(rest): add entry files in the dist root
BatuhanW Sep 17, 2025
d575521
chore: set @refinedev/rest package version to 2.0.0
BatuhanW Sep 19, 2025
e7d75fc
fix(data-provider-strapi-v4): e2e spec
BatuhanW Sep 19, 2025
13cc422
Revert "fix(data-provider-strapi-v4): e2e spec"
BatuhanW Sep 19, 2025
08d432f
Merge branch 'main' into add-rest-data-provider-for-v5
BatuhanW Sep 19, 2025
775177f
refactor: delete createmany, updateMany, deleteMany
BatuhanW Sep 23, 2025
2d0464a
refactor: remove buildPagination, buildFilters, buildSorters methods …
BatuhanW Sep 23, 2025
c47dcef
feat: add refine.config.js for swizzle
BatuhanW Sep 23, 2025
d106f6f
Merge branch 'main' into add-rest-data-provider-for-v5
BatuhanW Sep 23, 2025
6cf9bfa
feat: add createMany, updateMany, deleteMany optional methods
BatuhanW Sep 24, 2025
d2badf4
docs(rest): create rest data provider page
BatuhanW Sep 24, 2025
cec075a
docs(rest): add hooks section
BatuhanW Sep 24, 2025
7c5017d
chore(rest): node 22 for vitest target
BatuhanW Sep 24, 2025
0f68e59
feat(strapi-v4): intercept login requests and mock in e2e tests
BatuhanW Sep 24, 2025
c89b26f
fix(rest): return undefined from deleteOne mapResponse for strapi-v4
BatuhanW Sep 24, 2025
6015086
fix(rest): deleteOne test
BatuhanW Sep 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint:staged
pnpm run lint:staged
15 changes: 13 additions & 2 deletions .syncpackrc
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,22 @@
{
"dependencies": ["nock"],
"dependencyTypes": ["dev"],
"packages": ["@refinedev/appwrite", "@refinedev/graphql"],
"packages": [
"@refinedev/appwrite",
"@refinedev/graphql",
"@refinedev/rest",
"@refinedev/nestjsx-crud"
],
"isIgnored": true
},
{
"dependencies": ["next", "react", "react-dom", "@types/react", "@types/react-dom"],
"dependencies": [
"next",
"react",
"react-dom",
"@types/react",
"@types/react-dom"
],
"packages": ["with-nextjs-headless"],
"isIgnored": true
}
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/data-provider-strapi-v4/all.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ describe("data-provider-strapi-v4", () => {
cy.wait("@strapiV4GetPosts").then(({ request }) => {
const query = request.query;
console.log(query);
expect(query?.["filters["]).to.deep.equal({
expect(query?.filters).to.deep.equal({
category: {
id: {
$in: ["1"],
Expand Down
2 changes: 2 additions & 0 deletions examples/data-provider-strapi-v4/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
"@refinedev/cli": "^2.16.48",
"@refinedev/core": "^5.0.1",
"@refinedev/react-router": "^2.0.0",
"@refinedev/rest": "^1.0.0",
"@refinedev/strapi-v4": "^7.0.0",
"@uiw/react-md-editor": "^4.0.8",
"antd": "^5.23.0",
"axios": "^1.11.0",
"ky": "^1.10.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-router": "^7.0.2"
Expand Down
109 changes: 4 additions & 105 deletions examples/data-provider-strapi-v4/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
import {
GitHubBanner,
Refine,
type AuthProvider,
Authenticated,
} from "@refinedev/core";
import { GitHubBanner, Refine, Authenticated } from "@refinedev/core";
import {
useNotificationProvider,
ThemedLayout,
ErrorComponent,
AuthPage,
RefineThemes,
} from "@refinedev/antd";
import { DataProvider, AuthHelper } from "@refinedev/strapi-v4";
import routerProvider, {
CatchAllNavigate,
NavigateToResource,
UnsavedChangesNotifier,
DocumentTitleHandler,
} from "@refinedev/react-router";
import axios from "axios";
import { BrowserRouter, Routes, Route, Outlet } from "react-router";

import "@ant-design/v5-patch-for-react-19";
Expand All @@ -32,113 +25,19 @@ import {
CategoryEdit,
} from "../src/pages/categories";

import { TOKEN_KEY, API_URL } from "./constants";
import { ConfigProvider, App as AntdApp } from "antd";
import { authProvider } from "./providers/auth";
import { dataProvider } from "./providers/data";

const App: React.FC = () => {
const axiosInstance = axios.create();
const strapiAuthHelper = AuthHelper(`${API_URL}/api`);

const authProvider: AuthProvider = {
login: async ({ email, password }) => {
try {
const { data, status } = await strapiAuthHelper.login(email, password);
if (status === 200) {
localStorage.setItem(TOKEN_KEY, data.jwt);

// set header axios instance
axiosInstance.defaults.headers.common["Authorization"] =
`Bearer ${data.jwt}`;

return {
success: true,
redirectTo: "/",
};
}
} catch (error: any) {
const errorObj = error?.response?.data?.message?.[0]?.messages?.[0];
return {
success: false,
error: {
message: errorObj?.message || "Login failed",
name: errorObj?.id || "Invalid email or password",
},
};
}

return {
success: false,
error: {
message: "Login failed",
name: "Invalid email or password",
},
};
},
logout: async () => {
localStorage.removeItem(TOKEN_KEY);
return {
success: true,
redirectTo: "/login",
};
},
onError: async (error) => {
if (error.response?.status === 401) {
return {
logout: true,
};
}

return { error };
},
check: async () => {
const token = localStorage.getItem(TOKEN_KEY);
if (token) {
axiosInstance.defaults.headers.common["Authorization"] =
`Bearer ${token}`;
return {
authenticated: true,
};
}

return {
authenticated: false,
error: {
message: "Authentication failed",
name: "Token not found",
},
logout: true,
redirectTo: "/login",
};
},
getPermissions: async () => null,
getIdentity: async () => {
const token = localStorage.getItem(TOKEN_KEY);
if (!token) {
return null;
}

const { data, status } = await strapiAuthHelper.me(token);
if (status === 200) {
const { id, username, email } = data;
return {
id,
username,
email,
};
}

return null;
},
};

return (
<BrowserRouter>
<GitHubBanner />
<ConfigProvider theme={RefineThemes.Blue}>
<AntdApp>
<Refine
authProvider={authProvider}
dataProvider={DataProvider(`${API_URL}/api`, axiosInstance)}
dataProvider={dataProvider}
routerProvider={routerProvider}
resources={[
{
Expand Down
91 changes: 91 additions & 0 deletions examples/data-provider-strapi-v4/src/providers/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import type { AuthProvider } from "@refinedev/core";
import { AuthHelper } from "@refinedev/strapi-v4";
import { API_URL, TOKEN_KEY } from "../constants";

const strapiAuthHelper = AuthHelper(`${API_URL}/api`);

export const authProvider: AuthProvider = {
login: async ({ email, password }) => {
try {
const { data, status } = await strapiAuthHelper.login(email, password);
if (status === 200) {
localStorage.setItem(TOKEN_KEY, data.jwt);

return {
success: true,
redirectTo: "/",
};
}
} catch (error: any) {
const errorObj = error?.response?.data?.message?.[0]?.messages?.[0];
return {
success: false,
error: {
message: errorObj?.message || "Login failed",
name: errorObj?.id || "Invalid email or password",
},
};
}

return {
success: false,
error: {
message: "Login failed",
name: "Invalid email or password",
},
};
},
logout: async () => {
localStorage.removeItem(TOKEN_KEY);
return {
success: true,
redirectTo: "/login",
};
},
onError: async (error) => {
if (error.response?.status === 401) {
return {
logout: true,
};
}

return { error };
},
check: async () => {
const token = localStorage.getItem(TOKEN_KEY);
if (token) {
return {
authenticated: true,
};
}

return {
authenticated: false,
error: {
message: "Authentication failed",
name: "Token not found",
},
logout: true,
redirectTo: "/login",
};
},
getPermissions: async () => null,
getIdentity: async () => {
const token = localStorage.getItem(TOKEN_KEY);
if (!token) {
return null;
}

const { data, status } = await strapiAuthHelper.me(token);
if (status === 200) {
const { id, username, email } = data;
return {
id,
username,
email,
};
}

return null;
},
};
16 changes: 16 additions & 0 deletions examples/data-provider-strapi-v4/src/providers/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {
authHeaderMiddleware,
createDataProvider,
strapiV4DataProviderOptions,
} from "@refinedev/rest";
import { API_URL, TOKEN_KEY } from "../constants";

export const dataProvider = createDataProvider(
`${API_URL}/api`,
strapiV4DataProviderOptions,
{
hooks: {
beforeRequest: [authHeaderMiddleware({ ACCESS_TOKEN_KEY: TOKEN_KEY })],
},
},
);
2 changes: 2 additions & 0 deletions examples/refine-hr-ce/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
"@refinedev/nestjsx-crud": "^6.0.0",
"@refinedev/react-hook-form": "^5.0.0",
"@refinedev/react-router": "^2.0.0",
"@refinedev/rest": "^1.0.0",
"@tanstack/react-query": "^5.81.5",
"dayjs": "^1.10.7",
"ky": "^1.10.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-hook-form": "^7.57.0",
Expand Down
9 changes: 3 additions & 6 deletions examples/refine-hr-ce/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
Refine,
} from "@refinedev/core";
import { DevtoolsProvider, DevtoolsPanel } from "@refinedev/devtools";
import dataProvider from "@refinedev/nestjsx-crud";
import routerProvider, {
UnsavedChangesNotifier,
DocumentTitleHandler,
Expand All @@ -27,9 +26,7 @@ import { authProvider } from "@/providers/auth-provider";
import { accessControlProvider } from "@/providers/access-control";
import { useNotificationProvider } from "@/providers/notification-provider";
import { queryClient } from "@/providers/query-client";

import { BASE_URL } from "@/utilities/constants";
import { axiosInstance } from "@/utilities/axios";
import { dataProvider } from "@/providers/data";

import { RequestsIcon, TimeOffIcon } from "@/icons";

Expand All @@ -43,9 +40,10 @@ const App: React.FC = () => {
<ThemeProvider>
<DevtoolsProvider>
<Refine
accessControlProvider={accessControlProvider}
authProvider={authProvider}
routerProvider={routerProvider}
dataProvider={dataProvider(BASE_URL, axiosInstance)}
dataProvider={dataProvider}
notificationProvider={useNotificationProvider}
resources={[
{
Expand Down Expand Up @@ -85,7 +83,6 @@ const App: React.FC = () => {
},
},
]}
accessControlProvider={accessControlProvider}
options={{
reactQuery: {
clientConfig: queryClient,
Expand Down
Loading
Loading