Skip to content

Instantly share code, notes, and snippets.

@sboli
Created March 21, 2025 18:57
Show Gist options
  • Save sboli/18342d1d079c4ed6cdb8993fa40ab4db to your computer and use it in GitHub Desktop.
Save sboli/18342d1d079c4ed6cdb8993fa40ab4db to your computer and use it in GitHub Desktop.
import { useMutation, useQuery, UseQueryOptions } from '@tanstack/react-query';
import { trimStart } from 'lodash';
import { parseTemplate } from 'url-template';
import { queryClient } from '.';
import axios from '../../config/axios';
const makeQueryKey = (pathOrPaths?: string[] | string) => {
if (!pathOrPaths) {
return [];
}
if (Array.isArray(pathOrPaths)) {
return pathOrPaths.join().split('/');
} else {
return trimStart(pathOrPaths, '/').split('/');
}
};
const UrlTemplate = {
parse: parseTemplate,
};
const invalidateOnSuccess = (path: string) => {
queryClient.invalidateQueries({
predicate: (q) =>
(q.queryKey.join('/') as string).startsWith(path.split('/')[0]),
});
};
export function useGet<ResultType>(
path?: string,
options?: UseQueryOptions<ResultType, Error, ResultType>
) {
return useQuery<ResultType, Error>(
makeQueryKey(path),
async (payload) => {
if (path) {
const { data } = await axios.get(
UrlTemplate.parse(path).expand(payload as any)
);
return data;
} else return null;
},
options
);
}
export function useGetBuffer<ResultType>(
path?: string,
options?: UseQueryOptions<ResultType, Error, ResultType>
) {
return useQuery<ResultType, Error>(
makeQueryKey(path),
async (payload) => {
if (path) {
const { data } = await axios.get(
UrlTemplate.parse(path).expand(payload as any),
{
responseType: 'arraybuffer',
}
);
return data;
} else return null;
},
options
);
}
export function useGetMany<ResultType>(
paths: string[],
options?: UseQueryOptions<ResultType, Error, ResultType>
) {
return useQuery<ResultType, Error>(
makeQueryKey(paths),
async (payload) => {
if (paths) {
const responses = await Promise.all(
paths.map((it) =>
axios.get(UrlTemplate.parse(it).expand(payload as any))
)
);
return responses.map((it) => it.data) as any;
} else return null;
},
options
);
}
export function usePost<ResultType, PayloadType>(path: string) {
return useMutation<ResultType, Error, PayloadType>(
makeQueryKey(path),
async (payload: any) => {
const { data } = await axios.post(
UrlTemplate.parse(path).expand(payload),
payload
);
return data;
},
{
onSuccess: () => {
invalidateOnSuccess(path);
},
}
);
}
export function usePatch<ResultType, PayloadType>(path: string) {
return useMutation<ResultType, Error, PayloadType>(
makeQueryKey(path),
async (payload: any) => {
const { data } = await axios.patch(
UrlTemplate.parse(path).expand(payload),
payload
);
return data;
},
{
onSuccess: () => {
invalidateOnSuccess(path);
},
}
);
}
export function usePut<ResultType, PayloadType>(path: string) {
return useMutation<ResultType, Error, PayloadType>(
makeQueryKey(path),
async (payload: any) => {
const { data } = await axios.put(
UrlTemplate.parse(path).expand(payload),
payload
);
return data;
},
{
onSuccess: () => {
invalidateOnSuccess(path);
},
}
);
}
export function useDelete<ResultType, PayloadType>(path: string) {
return useMutation<ResultType, Error, PayloadType>(
makeQueryKey(path),
async (payload?: any) => {
const { data } = await axios.delete(
UrlTemplate.parse(path).expand(payload),
payload
);
return data;
},
{
onSuccess: () => {
invalidateOnSuccess(path);
},
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment