react-api-kit 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/dist/react-api-kit.mjs +54 -0
- package/dist/react-api-kit.umd.js +1 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# 🚀 API Client (Axios + TanStack Query)
|
|
2
|
+
|
|
3
|
+
A lightweight, opinion-free API client built on **Axios** and **TanStack Query**, designed for modern React applications.
|
|
4
|
+
|
|
5
|
+
✔ No UI dependencies
|
|
6
|
+
✔ Global success & error hooks
|
|
7
|
+
✔ Works with any toast library
|
|
8
|
+
✔ React Query–ready
|
|
9
|
+
✔ Production-grade architecture
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 📦 Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install axios @tanstack/react-query
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
> **Peer requirements**
|
|
20
|
+
|
|
21
|
+
- React 18+
|
|
22
|
+
- TanStack Query v5+
|
|
23
|
+
|
|
24
|
+
## 🔧 Quick Start
|
|
25
|
+
|
|
26
|
+
### 1️⃣ Setup React Query Provider
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
30
|
+
|
|
31
|
+
const queryClient = new QueryClient();
|
|
32
|
+
|
|
33
|
+
export function AppProviders({ children }) {
|
|
34
|
+
return (
|
|
35
|
+
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### 2️⃣ Configure the API (Required)
|
|
43
|
+
|
|
44
|
+
Call `setupApi` **once**, ideally at application startup.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { setupApi } from "your-package-name";
|
|
48
|
+
import { toast } from "react-toastify";
|
|
49
|
+
|
|
50
|
+
setupApi({
|
|
51
|
+
baseURL: "/api",
|
|
52
|
+
|
|
53
|
+
getToken: () => localStorage.getItem("token"),
|
|
54
|
+
|
|
55
|
+
toast: {
|
|
56
|
+
success: (msg) => toast.success(msg),
|
|
57
|
+
error: (msg) => toast.error(msg),
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
errorMessages: {
|
|
61
|
+
401: "Session expired",
|
|
62
|
+
403: "Access denied",
|
|
63
|
+
500: "Server error",
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
onSuccess: (data) => {
|
|
67
|
+
console.log("Global success:", data);
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
onError: (error, message) => {
|
|
71
|
+
console.error("Global error:", message, error);
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
onLogout: () => {
|
|
75
|
+
localStorage.clear();
|
|
76
|
+
window.location.href = "/login";
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 🔔 Toast Integration (Optional)
|
|
84
|
+
|
|
85
|
+
This package **does not ship a toast library**.
|
|
86
|
+
|
|
87
|
+
You pass your own implementation.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 🪝 Hooks
|
|
92
|
+
|
|
93
|
+
### `useApiQuery`
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { useApiQuery, api } from "react-api-kit";
|
|
97
|
+
|
|
98
|
+
const fetchUsers = () => api.get("/users").then((res) => res.data);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### `useApiMutation`
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { useApiMutation, api } from "react-api-kit";
|
|
107
|
+
|
|
108
|
+
const createUser = (data) => api.post("/users", data).then((res) => res.data);
|
|
109
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import i from "axios";
|
|
2
|
+
import { useQuery as c, useQueryClient as p, useMutation as d } from "@tanstack/react-query";
|
|
3
|
+
let o;
|
|
4
|
+
const h = (e) => {
|
|
5
|
+
o = e;
|
|
6
|
+
}, n = i.create();
|
|
7
|
+
n.interceptors.request.use((e) => {
|
|
8
|
+
o?.baseURL && (e.baseURL = o.baseURL);
|
|
9
|
+
const t = o?.getToken?.();
|
|
10
|
+
return t && (e.headers.Authorization = `Token ${t}`), e;
|
|
11
|
+
});
|
|
12
|
+
n.interceptors.response.use(
|
|
13
|
+
(e) => (o?.onSuccess?.(e.data), e),
|
|
14
|
+
(e) => {
|
|
15
|
+
const t = e?.response?.status, s = {
|
|
16
|
+
400: "Bad request. Please check your input.",
|
|
17
|
+
401: "Session expired. Please login again.",
|
|
18
|
+
403: "You do not have permission to perform this action.",
|
|
19
|
+
404: "Requested resource not found.",
|
|
20
|
+
409: "Conflict occurred. Please try again.",
|
|
21
|
+
422: "Validation error. Please check the form.",
|
|
22
|
+
500: "Server error. Please try again later."
|
|
23
|
+
}, r = e?.response?.data?.message || t && o?.errorMessages?.[t] || t && s[t] || e?.message || "Network Error";
|
|
24
|
+
return o?.toast?.error(r, o.toastOptions), o?.onError?.(e, r), t === 401 && o?.onLogout?.(), Promise.reject(e);
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
const u = {
|
|
28
|
+
GET: (e, t) => n.get(e, { params: t }).then((s) => s.data),
|
|
29
|
+
POST: (e, t) => n.post(e, t).then((s) => s.data),
|
|
30
|
+
PATCH: (e, t) => n.patch(e, t).then((s) => s.data),
|
|
31
|
+
DELETE: (e) => n.delete(e).then((t) => t.data)
|
|
32
|
+
};
|
|
33
|
+
function m(e, t, s, r, a) {
|
|
34
|
+
return c({
|
|
35
|
+
queryKey: e,
|
|
36
|
+
queryFn: () => u[t](s, r),
|
|
37
|
+
...a
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function g(e, t, s) {
|
|
41
|
+
const r = p();
|
|
42
|
+
return d({
|
|
43
|
+
mutationFn: (a) => u[e](t, a),
|
|
44
|
+
onSuccess: () => {
|
|
45
|
+
s && r.invalidateQueries({ queryKey: s });
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
n as api,
|
|
51
|
+
h as setupApi,
|
|
52
|
+
g as useApiMutation,
|
|
53
|
+
m as useApiQuery
|
|
54
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(n,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("axios"),require("@tanstack/react-query")):typeof define=="function"&&define.amd?define(["exports","axios","@tanstack/react-query"],r):(n=typeof globalThis<"u"?globalThis:n||self,r(n.ReactApiKit={},n.axios,n.reactQuery))})(this,(function(n,r,u){"use strict";let o;const d=e=>{o=e},i=r.create();i.interceptors.request.use(e=>{o?.baseURL&&(e.baseURL=o.baseURL);const t=o?.getToken?.();return t&&(e.headers.Authorization=`Token ${t}`),e}),i.interceptors.response.use(e=>(o?.onSuccess?.(e.data),e),e=>{const t=e?.response?.status,s={400:"Bad request. Please check your input.",401:"Session expired. Please login again.",403:"You do not have permission to perform this action.",404:"Requested resource not found.",409:"Conflict occurred. Please try again.",422:"Validation error. Please check the form.",500:"Server error. Please try again later."},a=e?.response?.data?.message||t&&o?.errorMessages?.[t]||t&&s[t]||e?.message||"Network Error";return o?.toast?.error(a,o.toastOptions),o?.onError?.(e,a),t===401&&o?.onLogout?.(),Promise.reject(e)});const p={GET:(e,t)=>i.get(e,{params:t}).then(s=>s.data),POST:(e,t)=>i.post(e,t).then(s=>s.data),PATCH:(e,t)=>i.patch(e,t).then(s=>s.data),DELETE:e=>i.delete(e).then(t=>t.data)};function f(e,t,s,a,c){return u.useQuery({queryKey:e,queryFn:()=>p[t](s,a),...c})}function l(e,t,s){const a=u.useQueryClient();return u.useMutation({mutationFn:c=>p[e](t,c),onSuccess:()=>{s&&a.invalidateQueries({queryKey:s})}})}n.api=i,n.setupApi=d,n.useApiMutation=l,n.useApiQuery=f,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-api-kit",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Reusable Axios + TanStack Query API hooks for React",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"author": "Ajay kammar",
|
|
7
|
+
|
|
8
|
+
"main": "./dist/react-api-kit.umd.js",
|
|
9
|
+
"module": "./dist/react-api-kit.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/react-api-kit.mjs",
|
|
14
|
+
"require": "./dist/react-api-kit.umd.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@tanstack/react-query": ">=4",
|
|
22
|
+
"axios": ">=1",
|
|
23
|
+
"react": ">=17"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "vite build"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
30
|
+
"vite": "^7.3.0"
|
|
31
|
+
}
|
|
32
|
+
}
|