UNPKG

@danstackme/apity

Version:

Type-safe API client generator for React applications with file-based routing and runtime validation

123 lines (119 loc) 3.71 kB
import { QueryClient, QueryClientProvider, useQuery, useMutation } from '@tanstack/react-query'; import { createContext, useContext } from 'react'; import { jsx } from 'react/jsx-runtime'; import axios from 'axios'; // src/useFetch.ts var ApiContext = createContext(null); function useApiContext() { const context = useContext(ApiContext); if (!context) { throw new Error("useApiContext must be used within an ApiProvider"); } return context; } function ApiProvider({ children, api }) { const queryClient = api.queryClient ?? new QueryClient(); const value = { client: api.client, queryClient, config: api.config }; return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(ApiContext.Provider, { value, children }) }); } // src/utils.ts function getParamName(path) { const match = path.match(/\[([^\]]+)\]/); return match ? match[1] : ""; } function interpolatePath(path, params) { return path.replace(/\[([^\]]+)\]/g, (_, key) => { if (!params[key]) { throw new Error(`Missing path parameter: ${key}`); } return params[key]; }); } // src/useFetch.ts function useFetch(options) { const { path, params, query, enabled = true, ...queryOptions } = options; const { client, config } = useApiContext(); if (path.includes("[") && (!params || Object.keys(params).length === 0)) { throw new Error(`Missing path parameter: ${getParamName(path)}`); } const url = interpolatePath(path, params || {}); return useQuery({ ...queryOptions, queryKey: [path, params, query], queryFn: async () => { const response = await client.get(url, { baseURL: config.baseUrl, params: query }); return response.data; }, enabled }); } function useMutate(options) { const { path, params, method, ...mutationOptions } = options; const { client, config } = useApiContext(); if (path.includes("[") && (!params || Object.keys(params).length === 0)) { throw new Error(`Missing path parameter: ${getParamName(path)}`); } const url = interpolatePath(path, params || {}); return useMutation({ ...mutationOptions, mutationFn: async (data) => { const response = await client.request({ method, url, baseURL: config.baseUrl, data }); return response.data; } }); } function createApiEndpoint(config) { return { ...config, method: config.method, response: config.response, body: config.body, query: config.query }; } function createApi(config) { const queryClient = config.queryClient || new QueryClient(); const client = config.client || axios.create(); client.defaults.baseURL = config.baseUrl; if (config.headers) { Object.assign(client.defaults.headers, config.headers); } const middlewareFns = []; if (config.middleware) { if (config.middleware.before) { middlewareFns.push(config.middleware.before); client.interceptors.request.use(config.middleware.before); } if (config.middleware.after) { middlewareFns.push(config.middleware.after); client.interceptors.response.use(config.middleware.after); } if (config.middleware.onError) { middlewareFns.push(config.middleware.onError); client.interceptors.response.use(void 0, config.middleware.onError); } } return { client, queryClient, config, middleware: middlewareFns, fetchEndpoints: config.fetchEndpoints, mutateEndpoints: config.mutateEndpoints }; } export { ApiProvider, createApi, createApiEndpoint, useApiContext, useFetch, useMutate }; //# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map