Last active
September 17, 2024 19:28
-
-
Save josippapez/c83c4517fd92bc00b9267555e2a53a6e to your computer and use it in GitHub Desktop.
Tanstack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Axios, { AxiosError, AxiosHeaders, AxiosRequestConfig } from 'axios'; | |
| import { getAuth, getIdToken, signOut } from 'firebase/auth'; | |
| export const AXIOS_INSTANCE = Axios.create({ | |
| baseURL: process.env.NEXT_PUBLIC_BACKEND_API, | |
| }); // use your own URL here or environment variable | |
| // add a second `options` argument here if you want to pass extra options to each generated query | |
| export const customClient = async <T>( | |
| config: AxiosRequestConfig, | |
| options?: AxiosRequestConfig, | |
| ): Promise<T> => { | |
| const headers = new AxiosHeaders(); | |
| // This is an example of how you can add firebase AUTH token to the request | |
| // const auth = getAuth(); | |
| // const user = auth.currentUser; | |
| // let token: undefined | string = undefined; | |
| // if (user) { | |
| // token = await getIdToken(user); | |
| // headers.set('Authorization', `Bearer ${token}`); | |
| // } | |
| const source = Axios.CancelToken.source(); | |
| const promise = AXIOS_INSTANCE({ | |
| ...config, | |
| ...options, | |
| cancelToken: source.token, | |
| headers: { | |
| ...config.headers, | |
| ...headers, | |
| }, | |
| }).then(({ data }) => data); | |
| // eslint-disable-next-line @typescript-eslint/ban-ts-comment | |
| // @ts-ignore | |
| promise.cancel = () => { | |
| source.cancel('Query was cancelled'); | |
| }; | |
| return promise; | |
| }; | |
| AXIOS_INSTANCE.interceptors.response.use( | |
| (response) => { | |
| return response; | |
| }, | |
| (error) => { | |
| if (error.response?.status === 401) { | |
| const auth = getAuth(); | |
| signOut(auth); | |
| } | |
| return Promise.reject(error); | |
| }, | |
| ); | |
| // In some case with react-query and swr you want to be able to override the return error type so you can also do it here like this | |
| export type ErrorType<Error> = AxiosError<Error>; | |
| export type BodyType<BodyData> = BodyData; | |
| // custom client with proxy to server actions | |
| // export const customClient = async <T>( | |
| // config: AxiosRequestConfig, | |
| // options?: AxiosRequestConfig, | |
| // ): Promise<T> => { | |
| // // Singla needs to be deleted since intance of class cannot be passed to server side function, only pain objects | |
| // delete config.signal; | |
| // return serverFetch(config, options); | |
| // }; | |
| // server side function to for proxy | |
| // 'use server'; | |
| // import Axios, { AxiosHeaders, AxiosRequestConfig, AxiosResponse } from 'axios'; | |
| // export const AXIOS_INSTANCE = Axios.create({ | |
| // baseURL: process.env.NEXT_PUBLIC_BACKEND_API, | |
| // }); | |
| // export const serverFetch = async <T>( | |
| // config: AxiosRequestConfig, | |
| // options?: AxiosRequestConfig, | |
| // ) => { | |
| // const headers = new AxiosHeaders(); | |
| // // let clientId = ''; | |
| // // /** hardcoded for dev. Should be passed as a postMessage() on iframe. */ | |
| // // clientId = localStorage.getItem('fehr-client-id') || ''; | |
| // const clientId = '8dd218c8-3ccd-45fb-8456-f4995fc1cff6'; | |
| // headers.set('client-id', clientId); | |
| // return AXIOS_INSTANCE({ | |
| // ...config, | |
| // ...options, | |
| // headers: { | |
| // ...config.headers, | |
| // ...headers, | |
| // }, | |
| // }) | |
| // .then((response: AxiosResponse<T>) => response.data) | |
| // .catch((err) => err); | |
| // }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| openapi: | |
| curl http://localhost:3000/api-docs-json > ./libs/api/src/openapi.json | |
| rm -rf ./libs/api/src/openapi-config | |
| rm -rf ./libs/api/src/openapi-schemas | |
| npx orval --config ./libs/api/orval.config.ts | |
| npx prettier --write ./libs/api/src | |
| rm ./libs/api/src/openapi.json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { defineConfig } from "orval"; | |
| const defaultQueryOverride = { | |
| useQuery: true, | |
| signal: true, | |
| useSuspenseQuery: true, | |
| }; | |
| // USE Makefile or npm scripts to run orval | |
| // makefile: make -f ./Makefile | |
| // OR | |
| // script: curl http://localhost:[port]/api-json > ./api/openapi.json && rm -rf ./api/openapi-config && rm -rf ./api/openapi-schemas && npx orval --config ./apps/fe/orval.config.ts && npx prettier --write ./api/ && rm ./api/openapi.json | |
| export default defineConfig({ | |
| backOffice: { | |
| input: { | |
| target: "./src/openapi.json", | |
| filters: { | |
| // match all strings that don't contain healthcheck | |
| //@ts-ignore-next-line | |
| tags: [/^(?!.*healthcheck).*$/], | |
| }, | |
| }, | |
| output: { | |
| mode: "tags-split", | |
| target: "./openapi-config", | |
| schemas: "./openapi-schemas", | |
| workspace: "./src/", | |
| indexFiles: true, | |
| client: "react-query", | |
| prettier: true, | |
| mock: false, | |
| override: { | |
| query: { | |
| useQuery: true, | |
| signal: true, | |
| useSuspenseQuery: true, | |
| }, | |
| operations: { | |
| // GuideController_findAll: { | |
| // query: { | |
| // ...defaultQueryOverride, | |
| // useInfinite: true, | |
| // useInfiniteQueryParam: 'page', | |
| // }, | |
| // }, | |
| }, | |
| mutator: { | |
| path: "./custom-client.ts", | |
| name: "customClient", | |
| }, | |
| }, | |
| }, | |
| }, | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use client'; | |
| import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'; | |
| import { QueryClient } from '@tanstack/react-query'; | |
| import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; | |
| import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'; | |
| import { PropsWithChildren } from 'react'; | |
| import 'react-toastify/dist/ReactToastify.css'; | |
| const isServer = typeof window === 'undefined'; | |
| const persister = createSyncStoragePersister({ | |
| storage: isServer ? null : window?.localStorage, | |
| }); | |
| // remove queryMounted information on first render | |
| const storage = !isServer ? localStorage : null; | |
| storage?.removeItem('queryMounted'); | |
| export const queryClient = new QueryClient({ | |
| defaultOptions: { | |
| queries: { | |
| refetchOnMount(query) { | |
| const queryMounted: Record<string, boolean> = JSON.parse( | |
| storage?.getItem('queryMounted') ?? '{}', | |
| ); | |
| // on first mount invalidate the query (refetch the data) | |
| if (!queryMounted[query.queryHash]) { | |
| // Mark the query as mounted | |
| storage?.setItem( | |
| 'queryMounted', | |
| JSON.stringify({ ...queryMounted, [query.queryHash]: true }), | |
| ); | |
| query.invalidate(); | |
| } | |
| return true; | |
| }, | |
| gcTime: 1000 * 60 * 60 * 24, // 24 hours | |
| staleTime: 1000 * 20, // 20 seconds | |
| }, | |
| mutations: { | |
| gcTime: 1000 * 60, | |
| }, | |
| }, | |
| }); | |
| export const TanstackQueryProvider: React.FC<PropsWithChildren> = ({ | |
| children, | |
| }) => { | |
| return ( | |
| <PersistQueryClientProvider | |
| client={queryClient} | |
| persistOptions={{ persister }} | |
| > | |
| {children} | |
| {process.env.NODE_ENV === 'development' && ( | |
| <ReactQueryDevtools initialIsOpen={false} /> | |
| )} | |
| </PersistQueryClientProvider> | |
| ); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment