@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
JavaScript
;
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