UNPKG

@danstackme/apity

Version:

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

134 lines (127 loc) 4.03 kB
'use strict'; var reactQuery = require('@tanstack/react-query'); var react = require('react'); var jsxRuntime = require('react/jsx-runtime'); var axios = require('axios'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var axios__default = /*#__PURE__*/_interopDefault(axios); // src/useFetch.ts var ApiContext = react.createContext(null); function useApiContext() { const context = react.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 reactQuery.QueryClient(); const value = { client: api.client, queryClient, config: api.config }; return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.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 reactQuery.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 reactQuery.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 reactQuery.QueryClient(); const client = config.client || axios__default.default.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 }; } exports.ApiProvider = ApiProvider; exports.createApi = createApi; exports.createApiEndpoint = createApiEndpoint; exports.useApiContext = useApiContext; exports.useFetch = useFetch; exports.useMutate = useMutate; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map