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;