/ client / src / components / dataProvider.ts
dataProvider.ts
  1  import { DataProvider } from "@refinedev/core";
  2  import { axiosInstance } from "@refinedev/simple-rest";
  3  import { AxiosInstance } from "axios";
  4  import { stringify } from "query-string";
  5  
  6  type MethodTypes = "get" | "delete" | "head" | "options";
  7  type MethodTypesWithBody = "post" | "put" | "patch";
  8  
  9  const dataProvider = (
 10    apiUrl: string,
 11    httpClient: AxiosInstance = axiosInstance,
 12  ): Omit<Required<DataProvider>, "createMany" | "updateMany" | "deleteMany"> => ({
 13    getList: async ({ resource, meta, pagination, sorters, filters }) => {
 14      const url = `${apiUrl}/${resource}`;
 15  
 16      const { headers: headersFromMeta, method } = meta ?? {};
 17      const queryParams: Record<string, string | number> = meta?.queryParams ?? {};
 18      const requestMethod = (method as MethodTypes) ?? "get";
 19  
 20      if (pagination && pagination.mode == "server") {
 21        const pageSize = pagination.pageSize ?? 10;
 22        const offset = ((pagination.currentPage ?? 1) - 1) * pageSize;
 23        queryParams["limit"] = pageSize;
 24        queryParams["offset"] = offset;
 25      }
 26  
 27      if (sorters && sorters.length > 0) {
 28        queryParams["sort"] = sorters
 29          .map((sort) => {
 30            const field = sort.field;
 31            return `${field}:${sort.order}`;
 32          })
 33          .join(",");
 34      }
 35  
 36      if (filters && filters.length > 0) {
 37        filters.forEach((filter) => {
 38          if (!("field" in filter)) {
 39            throw Error("Filter must be a LogicalFilter.");
 40          }
 41          const field = filter.field;
 42          if (filter.value.length > 0) {
 43            const filterValueArray = Array.isArray(filter.value) ? filter.value : [filter.value];
 44  
 45            const filterValue = filterValueArray
 46              .map((value) => {
 47                if (value === "<empty>") {
 48                  return "";
 49                }
 50                return value;
 51              })
 52              .join(",");
 53  
 54            queryParams[field] = filterValue;
 55          }
 56        });
 57      }
 58  
 59      const { data, headers } = await httpClient[requestMethod](`${url}`, {
 60        headers: headersFromMeta,
 61        params: queryParams,
 62      });
 63  
 64      return {
 65        data,
 66        total: parseInt(headers["x-total-count"]) ?? 100,
 67      };
 68    },
 69  
 70    getMany: async () => {
 71      throw new Error("getMany not implemented");
 72    },
 73  
 74    create: async ({ resource, variables, meta }) => {
 75      const url = `${apiUrl}/${resource}`;
 76  
 77      const { headers, method } = meta ?? {};
 78      const requestMethod = (method as MethodTypesWithBody) ?? "post";
 79  
 80      const { data } = await httpClient[requestMethod](url, variables, {
 81        headers,
 82      });
 83  
 84      return {
 85        data,
 86      };
 87    },
 88  
 89    update: async ({ resource, id, variables, meta }) => {
 90      const url = `${apiUrl}/${resource}/${id}`;
 91  
 92      const { headers, method } = meta ?? {};
 93      const requestMethod = (method as MethodTypesWithBody) ?? "patch";
 94  
 95      const { data } = await httpClient[requestMethod](url, variables, {
 96        headers,
 97      });
 98  
 99      return {
100        data,
101      };
102    },
103  
104    getOne: async ({ resource, id, meta }) => {
105      const url = `${apiUrl}/${resource}/${id}`;
106  
107      const { headers, method } = meta ?? {};
108      const requestMethod = (method as MethodTypes) ?? "get";
109  
110      const { data } = await httpClient[requestMethod](url, { headers });
111  
112      return {
113        data,
114      };
115    },
116  
117    deleteOne: async ({ resource, id, variables, meta }) => {
118      const url = `${apiUrl}/${resource}/${id}`;
119  
120      const { headers, method } = meta ?? {};
121      const requestMethod = (method as MethodTypesWithBody) ?? "delete";
122  
123      const { data } = await httpClient[requestMethod](url, {
124        data: variables,
125        headers,
126      });
127  
128      return {
129        data,
130      };
131    },
132  
133    getApiUrl: () => {
134      return apiUrl;
135    },
136  
137    custom: async ({ url, method, payload, query, headers }) => {
138      let requestUrl = `${url}?`;
139  
140      if (query) {
141        requestUrl = `${requestUrl}&${stringify(query)}`;
142      }
143  
144      if (headers) {
145        httpClient.defaults.headers.common = {
146          ...httpClient.defaults.headers.common,
147          ...headers,
148        };
149      }
150  
151      let axiosResponse;
152      switch (method) {
153        case "put":
154        case "post":
155        case "patch":
156          axiosResponse = await httpClient[method](url, payload);
157          break;
158        case "delete":
159          axiosResponse = await httpClient.delete(url, {
160            data: payload,
161          });
162          break;
163        default:
164          axiosResponse = await httpClient.get(requestUrl);
165          break;
166      }
167  
168      const { data } = axiosResponse;
169  
170      return Promise.resolve({ data });
171    },
172  });
173  
174  export default dataProvider;