add createApi
This commit is contained in:
parent
cc19d8742a
commit
2f4a5f32f5
745
dist/index.js
vendored
745
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -10,7 +10,7 @@ import {
|
||||
|
||||
let configuredApi = null;
|
||||
|
||||
export const createApi = (config) => {
|
||||
const createApi = (config) => {
|
||||
const { api } = config;
|
||||
|
||||
// instances
|
||||
|
||||
118
src/core/createApi.js
Normal file
118
src/core/createApi.js
Normal file
@ -0,0 +1,118 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { api, fetcher as defaultFetcher } from "./api.js";
|
||||
|
||||
function getBaseKey(key) {
|
||||
return Array.isArray(key) ? key : [key];
|
||||
}
|
||||
|
||||
function getListKey(key) {
|
||||
return [...getBaseKey(key), "list"];
|
||||
}
|
||||
|
||||
function getItemKey(key, id) {
|
||||
return [...getBaseKey(key), id];
|
||||
}
|
||||
|
||||
function buildUrl(url, params) {
|
||||
if (!params) return url;
|
||||
|
||||
const searchParams = new URLSearchParams();
|
||||
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null && value !== "") {
|
||||
searchParams.append(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
const query = searchParams.toString();
|
||||
|
||||
return query ? `${url}?${query}` : url;
|
||||
}
|
||||
|
||||
function resolveUrl(url, data) {
|
||||
if (typeof url === "function") {
|
||||
return url(data?.id, data);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
function omitId(data = {}) {
|
||||
const { id, ...rest } = data;
|
||||
return rest;
|
||||
}
|
||||
|
||||
export function createApi({
|
||||
key,
|
||||
url,
|
||||
actions = {},
|
||||
axiosInstance = api,
|
||||
fetcher = defaultFetcher,
|
||||
}) {
|
||||
const baseKey = getBaseKey(key);
|
||||
const listKey = getListKey(key);
|
||||
|
||||
function useGet(params, options = {}) {
|
||||
return useQuery({
|
||||
queryKey: params ? [...listKey, params] : listKey,
|
||||
queryFn: () => fetcher(buildUrl(url, params)),
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
function useAction(actionName, options = {}) {
|
||||
const queryClient = useQueryClient();
|
||||
const action = actions[actionName];
|
||||
|
||||
if (!action) {
|
||||
throw new Error(`Action "${actionName}" is not defined.`);
|
||||
}
|
||||
|
||||
return useMutation({
|
||||
mutationKey: [...baseKey, actionName],
|
||||
|
||||
mutationFn: async (data = {}) => {
|
||||
const method = action.method || "post";
|
||||
const requestUrl = resolveUrl(action.url, data);
|
||||
|
||||
const payload = action.body
|
||||
? action.body(data)
|
||||
: action.withId
|
||||
? data
|
||||
: omitId(data);
|
||||
|
||||
const response = await axiosInstance[method](requestUrl, payload);
|
||||
|
||||
return response.data;
|
||||
},
|
||||
|
||||
onSuccess: (...args) => {
|
||||
const [responseData, variables] = args;
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: listKey,
|
||||
});
|
||||
|
||||
const id = variables?.id ?? responseData?.id;
|
||||
|
||||
if (id) {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: getItemKey(key, id),
|
||||
});
|
||||
}
|
||||
|
||||
options.onSuccess?.(...args);
|
||||
},
|
||||
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
key: baseKey,
|
||||
listKey,
|
||||
|
||||
useGet,
|
||||
useAction,
|
||||
};
|
||||
}
|
||||
124
src/core/crud.js
124
src/core/crud.js
@ -1,124 +0,0 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { api, fetcher as defaultFetcher } from "./api";
|
||||
|
||||
function getListKey(key) {
|
||||
return [`${key}-list`];
|
||||
}
|
||||
|
||||
function buildUrl(url, params) {
|
||||
if (!params) return url;
|
||||
|
||||
const searchParams = new URLSearchParams();
|
||||
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null && value !== "") {
|
||||
searchParams.append(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
const query = searchParams.toString();
|
||||
|
||||
return query ? `${url}?${query}` : url;
|
||||
}
|
||||
|
||||
function resolveUrl(url, data) {
|
||||
return typeof url === "function" ? url(data) : url;
|
||||
}
|
||||
|
||||
export function createCrud({
|
||||
key,
|
||||
url,
|
||||
urls = {},
|
||||
axiosInstance = api,
|
||||
fetcher = defaultFetcher,
|
||||
}) {
|
||||
const listKey = getListKey(key);
|
||||
|
||||
const listUrl = urls.list || url;
|
||||
const createUrl = urls.create || url;
|
||||
const updateUrl = urls.update || ((id) => `${url}/${id}`);
|
||||
const deleteUrl = urls.delete || ((id) => `${url}/${id}`);
|
||||
|
||||
function useGet(params, options = {}) {
|
||||
return useQuery({
|
||||
queryKey: params ? [...listKey, params] : listKey,
|
||||
|
||||
queryFn: () => {
|
||||
const resolvedListUrl = resolveUrl(listUrl, params);
|
||||
|
||||
return fetcher(
|
||||
typeof listUrl === "function"
|
||||
? resolvedListUrl
|
||||
: buildUrl(resolvedListUrl, params),
|
||||
);
|
||||
},
|
||||
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
function useCreate(options = {}) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (payload) => axiosInstance.post(createUrl, payload),
|
||||
|
||||
onSuccess: (...args) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: listKey,
|
||||
});
|
||||
|
||||
options.onSuccess?.(...args);
|
||||
},
|
||||
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
function useUpdate(options = {}) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ id, payload }) =>
|
||||
axiosInstance.patch(resolveUrl(updateUrl, id), payload),
|
||||
|
||||
onSuccess: (...args) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: listKey,
|
||||
});
|
||||
|
||||
options.onSuccess?.(...args);
|
||||
},
|
||||
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
function useDelete(options = {}) {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (id) => axiosInstance.delete(resolveUrl(deleteUrl, id)),
|
||||
|
||||
onSuccess: (...args) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: listKey,
|
||||
});
|
||||
|
||||
options.onSuccess?.(...args);
|
||||
},
|
||||
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
key,
|
||||
listKey,
|
||||
|
||||
useGet,
|
||||
useCreate,
|
||||
useUpdate,
|
||||
useDelete,
|
||||
};
|
||||
}
|
||||
@ -31,9 +31,9 @@ export {
|
||||
getPermissions,
|
||||
} from "./core/permission.jsx";
|
||||
|
||||
export { createApi, configureApi, getApi, api, fetcher } from "./core/api.js";
|
||||
export { configureApi, getApi, api, fetcher } from "./core/api.js";
|
||||
|
||||
export { createCrud } from "./core/crud";
|
||||
export { createApi } from "./core/createApi";
|
||||
|
||||
export { BiProvider } from "./provider/BiProvider.jsx";
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user