@forgepack/request 1.0.4 → 1.0.6
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 +217 -86
- package/dist/api/client.d.ts +17 -10
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +18 -6
- package/dist/hooks/AuthContext.d.ts +6 -6
- package/dist/hooks/AuthContext.d.ts.map +1 -1
- package/dist/hooks/AuthContext.js +1 -1
- package/dist/hooks/AuthProvider.d.ts +34 -17
- package/dist/hooks/AuthProvider.d.ts.map +1 -1
- package/dist/hooks/AuthProvider.js +26 -15
- package/dist/hooks/useAuth.d.ts +33 -12
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +30 -12
- package/dist/hooks/useRequest.d.ts +37 -17
- package/dist/hooks/useRequest.d.ts.map +1 -1
- package/dist/hooks/useRequest.js +36 -13
- package/dist/index.d.ts +159 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +159 -14
- package/dist/services/api.d.ts +37 -15
- package/dist/services/api.d.ts.map +1 -1
- package/dist/services/api.js +40 -14
- package/dist/services/auth.d.ts +76 -19
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +94 -22
- package/dist/services/crud.d.ts +115 -62
- package/dist/services/crud.d.ts.map +1 -1
- package/dist/services/crud.js +132 -85
- package/dist/services/token.d.ts +83 -26
- package/dist/services/token.d.ts.map +1 -1
- package/dist/services/token.js +141 -52
- package/dist/types/auth.d.ts +20 -20
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/error.d.ts +3 -3
- package/dist/types/error.d.ts.map +1 -1
- package/dist/types/request.d.ts +8 -8
- package/dist/types/request.d.ts.map +1 -1
- package/dist/types/response.d.ts +15 -15
- package/dist/types/response.d.ts.map +1 -1
- package/dist/types/token.d.ts +15 -15
- package/dist/types/token.d.ts.map +1 -1
- package/dist/utils/constants.d.ts +7 -7
- package/dist/utils/constants.js +7 -7
- package/package.json +70 -56
- package/dist/api/api.d.ts +0 -8
- package/dist/api/api.d.ts.map +0 -1
- package/dist/api/api.js +0 -35
- package/dist/component/auth.d.ts +0 -8
- package/dist/component/auth.d.ts.map +0 -1
- package/dist/component/auth.js +0 -9
- package/dist/component/errorMessage.d.ts +0 -6
- package/dist/component/errorMessage.d.ts.map +0 -1
- package/dist/component/errorMessage.js +0 -7
- package/dist/component/request.d.ts +0 -13
- package/dist/component/request.d.ts.map +0 -1
- package/dist/component/request.js +0 -12
- package/dist/component/response.d.ts +0 -13
- package/dist/component/response.d.ts.map +0 -1
- package/dist/component/response.js +0 -13
- package/dist/component/token.d.ts +0 -32
- package/dist/component/token.d.ts.map +0 -1
- package/dist/component/token.js +0 -16
- package/dist/hook/useProvider.d.ts +0 -13
- package/dist/hook/useProvider.d.ts.map +0 -1
- package/dist/hook/useProvider.js +0 -51
- package/dist/hook/useRequest.d.ts +0 -11
- package/dist/hook/useRequest.d.ts.map +0 -1
- package/dist/hook/useRequest.js +0 -38
- package/dist/hook/useRequireAuth.d.ts +0 -4
- package/dist/hook/useRequireAuth.d.ts.map +0 -1
- package/dist/hook/useRequireAuth.js +0 -21
- package/dist/service/crud.d.ts +0 -15
- package/dist/service/crud.d.ts.map +0 -1
- package/dist/service/crud.js +0 -116
- package/dist/service/fetchPage.d.ts +0 -5
- package/dist/service/fetchPage.d.ts.map +0 -1
- package/dist/service/fetchPage.js +0 -22
- package/dist/service/token.d.ts +0 -10
- package/dist/service/token.d.ts.map +0 -1
- package/dist/service/token.js +0 -93
package/README.md
CHANGED
|
@@ -1,90 +1,85 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1> @forgepack/request </h1>
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
**Production-ready HTTP client with JWT authentication for React**
|
|
2
6
|
|
|
7
|
+
[](https://www.npmjs.com/package/@forgepack/request)
|
|
8
|
+
[](https://www.npmjs.com/package/@forgepack/request)
|
|
3
9
|
[](https://github.com/forgepack/request)
|
|
4
|
-
|
|
5
|
-

|
|
6
|
-

|
|
7
|
-

|
|
8
|
-

|
|
10
|
+
[](https://github.com/forgepack/request/blob/main/LICENSE)
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
[](https://react.dev/)
|
|
13
|
+
[](https://www.typescriptlang.org/)
|
|
14
|
+
[](https://axios-http.com/)
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
mkdir package-name
|
|
14
|
-
cd package-name
|
|
15
|
-
npm init
|
|
16
|
-
```
|
|
16
|
+
[Documentation](https://forgepack.dev/packages/request) • [NPM Package](https://www.npmjs.com/package/@forgepack/request) • [GitHub](https://github.com/forgepack/request) • [Report Bug](https://github.com/forgepack/request/issues)
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"name": "package-name",
|
|
22
|
-
"version": "1.0.0",
|
|
23
|
-
"description": "Package Description",
|
|
24
|
-
"main": "index.js",
|
|
25
|
-
"scripts": {
|
|
26
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
27
|
-
},
|
|
28
|
-
"keywords": ["palavra-chave1", "palavra-chave2"],
|
|
29
|
-
"author": "Name",
|
|
30
|
-
"license": "MIT"
|
|
31
|
-
}
|
|
32
|
-
```
|
|
18
|
+
## Summary
|
|
33
19
|
|
|
34
|
-
|
|
20
|
+
- [Installation](#installation)
|
|
21
|
+
- [Quick Start](#quick-start)
|
|
22
|
+
- [Using CRUD Operations](#using-crud-operations)
|
|
23
|
+
- [Route Protection](#route-protection)
|
|
24
|
+
- [When to Use](#when-to-use)
|
|
25
|
+
- [Works well with](#works-well-with)
|
|
26
|
+
- [Key Features](#key-features)
|
|
27
|
+
- [Contributing](#contributing)
|
|
28
|
+
- [Code of Conduct](#code-of-conduct)
|
|
29
|
+
- [Author and Developers](#author-and-developers)
|
|
30
|
+
- [License](#license)
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
# Login no npm
|
|
38
|
-
npm login
|
|
39
|
-
# Constrói
|
|
40
|
-
npm run build
|
|
41
|
-
# Simula publicação
|
|
42
|
-
npm pack
|
|
43
|
-
# Publicar o pacote, na primeira vez
|
|
44
|
-
npm publish --access public
|
|
45
|
-
```
|
|
32
|
+
## Description
|
|
46
33
|
|
|
47
|
-
|
|
48
|
-
> Quando fizer mudanças:
|
|
49
|
-
```bash
|
|
50
|
-
npm version patch # 1.0.0 -> 1.0.1
|
|
51
|
-
npm version minor # 1.0.0 -> 1.1.0
|
|
52
|
-
npm version major # 1.0.0 -> 2.0.0
|
|
34
|
+
`@forgepack/request` is a complete, opinionated HTTP client built on top of Axios for React applications. It provides automatic JWT authentication, request/response interceptors, React hooks for state management, and standardized CRUD operations—everything you need to handle API communication in modern React apps.
|
|
53
35
|
|
|
54
|
-
|
|
55
|
-
|
|
36
|
+
**Perfect for:** Teams building React applications with JWT-based backends who want a plug-and-play solution that handles authentication, authorization, and API requests with minimal boilerplate.
|
|
37
|
+
|
|
38
|
+
# Consumer use
|
|
56
39
|
|
|
57
|
-
##
|
|
40
|
+
## Installation
|
|
58
41
|
```bash
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
https://dev.to/
|
|
62
|
-
https://codesandbox.io/
|
|
63
|
-
https://stackblitz.com/
|
|
64
|
-
```
|
|
42
|
+
# npm
|
|
43
|
+
npm install @forgepack/request
|
|
65
44
|
|
|
66
|
-
|
|
45
|
+
# yarn
|
|
46
|
+
yarn add @forgepack/request
|
|
67
47
|
|
|
68
|
-
|
|
48
|
+
# pnpm
|
|
49
|
+
pnpm add @forgepack/request
|
|
50
|
+
```
|
|
69
51
|
|
|
70
|
-
|
|
71
|
-
|
|
52
|
+
### Peer Dependencies
|
|
53
|
+
|
|
54
|
+
Make sure you have these installed:
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"react": ">=16.8.0",
|
|
58
|
+
"react-dom": ">=16.8.0",
|
|
59
|
+
"axios": ">=1.0.0",
|
|
60
|
+
"react-router-dom": ">=6.0.0" // Optional, only if using RequireAuth
|
|
61
|
+
}
|
|
72
62
|
```
|
|
73
63
|
|
|
74
|
-
|
|
64
|
+
## Quick Start
|
|
75
65
|
|
|
66
|
+
### Configure the API client
|
|
76
67
|
```typescript
|
|
77
|
-
// 1. Configure o cliente da API
|
|
78
68
|
import { createApiClient } from "@forgepack/request"
|
|
79
69
|
|
|
80
70
|
export const api = createApiClient({
|
|
81
|
-
baseURL: "https://api.
|
|
71
|
+
baseURL: "https://api.service.com",
|
|
72
|
+
/** Called on 401 errors */
|
|
82
73
|
onUnauthorized: () => window.location.href = "/login",
|
|
74
|
+
/** Called on 403 errors */
|
|
83
75
|
onForbidden: () => window.location.href = "/notAllowed"
|
|
84
76
|
})
|
|
77
|
+
```
|
|
85
78
|
|
|
86
|
-
|
|
79
|
+
### Configure the authentication provider
|
|
80
|
+
```typescript
|
|
87
81
|
import { AuthProvider } from '@forgepack/request'
|
|
82
|
+
import { api } from './api/client'
|
|
88
83
|
|
|
89
84
|
function App() {
|
|
90
85
|
return (
|
|
@@ -95,43 +90,175 @@ function App() {
|
|
|
95
90
|
}
|
|
96
91
|
```
|
|
97
92
|
|
|
98
|
-
###
|
|
93
|
+
### Use in Components
|
|
94
|
+
```typescript
|
|
95
|
+
import { useAuth } from '@forgepack/request'
|
|
96
|
+
import { useNavigate } from 'react-router-dom'
|
|
97
|
+
|
|
98
|
+
function LoginPage() {
|
|
99
|
+
const { loginUser } = useAuth()
|
|
100
|
+
const navigate = useNavigate()
|
|
101
|
+
|
|
102
|
+
const handleLogin = async (credentials) => {
|
|
103
|
+
const result = await loginUser(credentials)
|
|
104
|
+
|
|
105
|
+
if (result.success) {
|
|
106
|
+
navigate('/dashboard')
|
|
107
|
+
} else {
|
|
108
|
+
console.error('Login failed:', result.errors)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<div>
|
|
114
|
+
{/* Your login form here */}
|
|
115
|
+
</div>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Using CRUD Operations
|
|
121
|
+
```typescript
|
|
122
|
+
import { create, retrieve, update, remove } from '@forgepack/request'
|
|
123
|
+
import { api } from './api/client'
|
|
124
|
+
|
|
125
|
+
// Create
|
|
126
|
+
const newUser = await create(api, 'users', {
|
|
127
|
+
name: 'John Snow',
|
|
128
|
+
email: 'john@example.com'
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
// Retrieve all
|
|
132
|
+
const allUsers = await retrieve(api, 'users')
|
|
133
|
+
|
|
134
|
+
// Retrieve paginated
|
|
135
|
+
const page = await retrieve(api, 'users', { page: 0, size: 10 })
|
|
136
|
+
|
|
137
|
+
// Update
|
|
138
|
+
const updated = await update(api, 'users', {
|
|
139
|
+
id: 1,
|
|
140
|
+
name: 'John Smith'
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Delete
|
|
144
|
+
await remove(api, 'users', '1')
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Route Protection
|
|
148
|
+
```typescript
|
|
149
|
+
import { RequireAuth } from '@forgepack/request'
|
|
150
|
+
import { Route, Routes } from 'react-router-dom'
|
|
151
|
+
|
|
152
|
+
function App() {
|
|
153
|
+
return (
|
|
154
|
+
<Routes>
|
|
155
|
+
{/* Public routes */}
|
|
156
|
+
<Route path="/login" element={<LoginPage />} />
|
|
157
|
+
|
|
158
|
+
{/* Protected routes - any authenticated user */}
|
|
159
|
+
<Route path="/dashboard" element={<RequireAuth allowedRoles={['USER', 'ADMIN']}><Dashboard /></RequireAuth>} />
|
|
160
|
+
|
|
161
|
+
{/* Admin-only routes */}
|
|
162
|
+
<Route path="/admin" element={<RequireAuth allowedRoles={['ADMIN']}><AdminPanel /></RequireAuth>} />
|
|
163
|
+
</Routes>
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Token Management
|
|
169
|
+
```typescript
|
|
170
|
+
import { getToken, getPayload, isValidToken } from '@forgepack/request'
|
|
171
|
+
|
|
172
|
+
/** Check if token is valid */
|
|
173
|
+
if (isValidToken()) {
|
|
174
|
+
console.log('User is authenticated')
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Get token data */
|
|
178
|
+
const auth = getToken()
|
|
179
|
+
console.log(auth.accessToken)
|
|
180
|
+
console.log(auth.role)
|
|
181
|
+
|
|
182
|
+
/** Decode payload */
|
|
183
|
+
const payload = getPayload()
|
|
184
|
+
console.log('User ID:', payload.sub)
|
|
185
|
+
console.log('Expires at:', new Date(payload.exp * 1000))
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## When to Use
|
|
189
|
+
|
|
190
|
+
### Perfect for:
|
|
191
|
+
- ✅ React applications (16.8+)
|
|
192
|
+
- ✅ JWT-based authentication
|
|
193
|
+
- ✅ RESTful APIs
|
|
194
|
+
- ✅ Applications requiring role-based access control
|
|
195
|
+
- ✅ Projects that need standardized CRUD operations
|
|
196
|
+
- ✅ Teams wanting to reduce authentication boilerplate
|
|
197
|
+
|
|
198
|
+
### Use not recommended when:
|
|
199
|
+
- ❌ GraphQL APIs (use Apollo Client instead)
|
|
200
|
+
- ❌ Non-JWT authentication (OAuth2, session-based, etc.)
|
|
201
|
+
- ❌ Server-side rendering with Next.js (token management relies on localStorage)
|
|
202
|
+
- ❌ React Native (localStorage not available)
|
|
99
203
|
|
|
100
|
-
|
|
101
|
-
- **🛡️ Proteção de Rotas** - Componente `RequireAuth` baseado em roles
|
|
102
|
-
- **📊 Hook de Requisições** - `useRequest` com paginação e busca
|
|
103
|
-
- **⚡ Operações CRUD** - Funções prontas para create, read, update, delete
|
|
104
|
-
- **🔑 Gerenciamento de Tokens** - Validação e decodificação automática
|
|
105
|
-
- **📱 Responsivo** - Estados de loading, erro e paginação
|
|
204
|
+
## Works well with
|
|
106
205
|
|
|
107
|
-
|
|
206
|
+
Complete your React stack with other @forgepack packages:
|
|
207
|
+
| Package | Description |
|
|
208
|
+
|---------|-------------|
|
|
209
|
+
| [@forgepack/auth-jwt](https://www.npmjs.com/package/@forgepack/auth-jwt) | Backend JWT authentication utilities |
|
|
210
|
+
| [@forgepack/crud](https://www.npmjs.com/package/@forgepack/crud) | Advanced CRUD components with forms |
|
|
211
|
+
| [@forgepack/layout](https://www.npmjs.com/package/@forgepack/layout) | Responsive layout components |
|
|
212
|
+
| [@forgepack/modal](https://www.npmjs.com/package/@forgepack/modal) | Modal dialogs for CRUD operations |
|
|
213
|
+
| [@forgepack/datatable](https://www.npmjs.com/package/@forgepack/datatable) | Data tables with pagination and sorting |
|
|
214
|
+
|
|
215
|
+
## Key Features
|
|
216
|
+
|
|
217
|
+
- **🔐 Autenticação JWT** - Automatic login with interceptors
|
|
218
|
+
- **🛡️ Route Protection** - Role-based `RequireAuth` component
|
|
219
|
+
- **📊 Request Hook** - `useRequest` with pagination and search
|
|
220
|
+
- **⚡ CRUD Operations** - Ready-to-use functions for create, read, update, delete.
|
|
221
|
+
- **🔑 Token Management** - Automatic validation and decoding
|
|
222
|
+
- **📱 Responsive** - Loading, error, and pagination states
|
|
223
|
+
|
|
224
|
+
## Complete Documentation
|
|
108
225
|
|
|
109
226
|
For detailed examples, usage guides, and API references, please visit:
|
|
110
227
|
**[Complete Documentation](./docs/README.md)**
|
|
111
228
|
|
|
112
|
-
|
|
229
|
+
# Developer usage
|
|
113
230
|
|
|
114
|
-
|
|
115
|
-
// Authentication hook
|
|
116
|
-
const { loginUser, isAuthenticated, role } = useAuth()
|
|
231
|
+
## Contributing
|
|
117
232
|
|
|
118
|
-
|
|
119
|
-
const { response, loading, error } = useRequest(api, 'users', {
|
|
120
|
-
page: 0, size: 10, value: 'busca'
|
|
121
|
-
})
|
|
233
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
122
234
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
235
|
+
### Development Setup
|
|
236
|
+
```bash
|
|
237
|
+
# Clone repository
|
|
238
|
+
git clone https://github.com/forgepack/request.git
|
|
239
|
+
cd request
|
|
240
|
+
|
|
241
|
+
# Install dependencies
|
|
242
|
+
npm install
|
|
243
|
+
|
|
244
|
+
# Run tests
|
|
245
|
+
npm test
|
|
246
|
+
|
|
247
|
+
# Build
|
|
248
|
+
npm run build
|
|
127
249
|
```
|
|
128
250
|
|
|
129
|
-
##
|
|
130
|
-
|
|
251
|
+
## Code of Conduct
|
|
252
|
+
|
|
253
|
+
Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
|
|
254
|
+
|
|
255
|
+
## Author and Developers
|
|
256
|
+
- GitHub: [Gadelha TI](https://github.com/gadelhati)
|
|
257
|
+
- Website: [forgepack.dev](https://forgepack.dev)
|
|
131
258
|
|
|
132
259
|
## **License**
|
|
133
260
|
|
|
134
|
-
|
|
261
|
+
This project is licensed under the **MIT License** - see the [MIT LICENSE]( https://choosealicense.com/licenses/mit/) file for details.
|
|
135
262
|
|
|
136
263
|
```text
|
|
137
264
|
MIT License
|
|
@@ -159,6 +286,10 @@ SOFTWARE.
|
|
|
159
286
|
|
|
160
287
|
<div align="center">
|
|
161
288
|
|
|
162
|
-
|
|
289
|
+
**⭐ Did you like the project? Leave a star! ⭐**
|
|
290
|
+
|
|
291
|
+
Made with ❤️ by the Forgepack team
|
|
292
|
+
|
|
293
|
+
[Documentation](https://forgepack.dev/packages/request) • [NPM](https://www.npmjs.com/package/@forgepack/request) • [GitHub](https://github.com/forgepack/request) • [Issues](https://github.com/forgepack/request/issues)
|
|
163
294
|
|
|
164
|
-
|
|
295
|
+
</div>
|
package/dist/api/client.d.ts
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
1
|
import { AxiosInstance } from "axios";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Configuration options for the API client
|
|
4
4
|
* @interface ApiClientOptions
|
|
5
5
|
*/
|
|
6
6
|
export type ApiClientOptions = {
|
|
7
|
-
/** URL
|
|
7
|
+
/** Base URL of the API (e.g., 'https://api.example.com') */
|
|
8
8
|
baseURL: string;
|
|
9
|
-
/** Callback
|
|
9
|
+
/** Callback executed when receiving 401 (Unauthorized) error - typically used to redirect to login */
|
|
10
10
|
onUnauthorized?: () => void;
|
|
11
|
-
/** Callback
|
|
11
|
+
/** Callback executed when receiving 403 (Forbidden) error - typically used to show access denied message */
|
|
12
12
|
onForbidden?: () => void;
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Creates a configured Axios client instance with interceptors for JWT authentication and error handling
|
|
16
16
|
*
|
|
17
|
-
* @param options -
|
|
18
|
-
* @
|
|
17
|
+
* @param {ApiClientOptions} options - Client configuration options
|
|
18
|
+
* @param {string} options.baseURL - Base URL for all API requests
|
|
19
|
+
* @param {Function} [options.onUnauthorized] - Optional callback for 401 errors
|
|
20
|
+
* @param {Function} [options.onForbidden] - Optional callback for 403 errors
|
|
21
|
+
* @returns {AxiosInstance} Configured Axios instance with request/response interceptors
|
|
19
22
|
*
|
|
20
23
|
* @example
|
|
21
24
|
* ```typescript
|
|
25
|
+
* // Basic usage
|
|
26
|
+
* const api = createApiClient({ baseURL: 'https://api.example.com' })
|
|
27
|
+
*
|
|
28
|
+
* // Usage with error handling callbacks
|
|
22
29
|
* const api = createApiClient({
|
|
23
|
-
* baseURL: 'https://api.
|
|
24
|
-
* onUnauthorized: () => window.location.href = '/login',
|
|
25
|
-
* onForbidden: () => alert('
|
|
30
|
+
* baseURL: 'https://api.example.com',
|
|
31
|
+
* onUnauthorized: () => { window.location.href = '/login' },
|
|
32
|
+
* onForbidden: () => { alert('Access denied') }
|
|
26
33
|
* })
|
|
27
34
|
* ```
|
|
28
35
|
*/
|
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAG5C;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAG5C;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC3B,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAA;IACf,sGAAsG;IACtG,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,4GAA4G;IAC5G,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;CAC3B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,gBAAgB,KAAG,aA+B3D,CAAA"}
|
package/dist/api/client.js
CHANGED
|
@@ -7,25 +7,34 @@ exports.createApiClient = void 0;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const token_1 = require("../services/token");
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Creates a configured Axios client instance with interceptors for JWT authentication and error handling
|
|
11
11
|
*
|
|
12
|
-
* @param options -
|
|
13
|
-
* @
|
|
12
|
+
* @param {ApiClientOptions} options - Client configuration options
|
|
13
|
+
* @param {string} options.baseURL - Base URL for all API requests
|
|
14
|
+
* @param {Function} [options.onUnauthorized] - Optional callback for 401 errors
|
|
15
|
+
* @param {Function} [options.onForbidden] - Optional callback for 403 errors
|
|
16
|
+
* @returns {AxiosInstance} Configured Axios instance with request/response interceptors
|
|
14
17
|
*
|
|
15
18
|
* @example
|
|
16
19
|
* ```typescript
|
|
20
|
+
* // Basic usage
|
|
21
|
+
* const api = createApiClient({ baseURL: 'https://api.example.com' })
|
|
22
|
+
*
|
|
23
|
+
* // Usage with error handling callbacks
|
|
17
24
|
* const api = createApiClient({
|
|
18
|
-
* baseURL: 'https://api.
|
|
19
|
-
* onUnauthorized: () => window.location.href = '/login',
|
|
20
|
-
* onForbidden: () => alert('
|
|
25
|
+
* baseURL: 'https://api.example.com',
|
|
26
|
+
* onUnauthorized: () => { window.location.href = '/login' },
|
|
27
|
+
* onForbidden: () => { alert('Access denied') }
|
|
21
28
|
* })
|
|
22
29
|
* ```
|
|
23
30
|
*/
|
|
24
31
|
const createApiClient = (options) => {
|
|
32
|
+
/** Create base Axios instance with default configuration */
|
|
25
33
|
const api = axios_1.default.create({
|
|
26
34
|
baseURL: options.baseURL,
|
|
27
35
|
headers: { 'content-type': 'application/json' }
|
|
28
36
|
});
|
|
37
|
+
/** Request interceptor: Add JWT token to all requests */
|
|
29
38
|
api.interceptors.request.use(async (config) => {
|
|
30
39
|
var _a;
|
|
31
40
|
const token = (_a = (0, token_1.getToken)()) === null || _a === void 0 ? void 0 : _a.accessToken;
|
|
@@ -34,12 +43,15 @@ const createApiClient = (options) => {
|
|
|
34
43
|
}
|
|
35
44
|
return config;
|
|
36
45
|
});
|
|
46
|
+
/** Response interceptor: Handle authentication and authorization errors */
|
|
37
47
|
api.interceptors.response.use((response) => response, (error) => {
|
|
38
48
|
var _a, _b, _c, _d;
|
|
49
|
+
/** Handle 401 Unauthorized errors: Token invalid/expired */
|
|
39
50
|
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 401) {
|
|
40
51
|
(0, token_1.removeToken)();
|
|
41
52
|
(_b = options.onUnauthorized) === null || _b === void 0 ? void 0 : _b.call(options);
|
|
42
53
|
}
|
|
54
|
+
/** Handle 403 Forbidden errors */
|
|
43
55
|
if (((_c = error.response) === null || _c === void 0 ? void 0 : _c.status) === 403) {
|
|
44
56
|
(_d = options.onForbidden) === null || _d === void 0 ? void 0 : _d.call(options);
|
|
45
57
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { Auth, LoginCredentials, LoginResponse } from '../types/auth';
|
|
1
|
+
import type { Auth, LoginCredentials, LoginResponse } from '../types/auth';
|
|
2
2
|
/**
|
|
3
|
-
* Interface
|
|
3
|
+
* Interface that extends Auth with authentication methods
|
|
4
4
|
* @interface AuthContextType
|
|
5
5
|
*/
|
|
6
6
|
export interface AuthContextType extends Auth {
|
|
7
|
-
/**
|
|
7
|
+
/** Function to authenticate a user */
|
|
8
8
|
loginUser: (credentials: LoginCredentials) => Promise<LoginResponse>;
|
|
9
|
-
/**
|
|
9
|
+
/** Function to logout the user */
|
|
10
10
|
logoutUser: () => void;
|
|
11
|
-
/**
|
|
11
|
+
/** Indicates if the user is authenticated */
|
|
12
12
|
isAuthenticated: boolean;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* React context for authentication management
|
|
16
16
|
* @constant
|
|
17
17
|
*/
|
|
18
18
|
export declare const AuthContext: import("react").Context<AuthContextType>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/hooks/AuthContext.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/hooks/AuthContext.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAG1E;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,IAAI;IACzC,sCAAsC;IACtC,SAAS,EAAE,CAAC,WAAW,EAAE,gBAAgB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;IACpE,kCAAkC;IAClC,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,6CAA6C;IAC7C,eAAe,EAAE,OAAO,CAAA;CAC3B;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,0CAAiE,CAAA"}
|
|
@@ -4,7 +4,7 @@ exports.AuthContext = void 0;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
const constants_1 = require("../utils/constants");
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* React context for authentication management
|
|
8
8
|
* @constant
|
|
9
9
|
*/
|
|
10
10
|
exports.AuthContext = (0, react_1.createContext)(constants_1.initialAuth);
|
|
@@ -1,27 +1,44 @@
|
|
|
1
1
|
import { AxiosInstance } from 'axios';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Properties of the AuthProvider
|
|
4
|
+
*/
|
|
5
|
+
export type AuthProviderProps = {
|
|
6
|
+
/** Axios instance for requests */
|
|
7
|
+
api: AxiosInstance;
|
|
8
|
+
/** Child components that will receive the context */
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Authentication context provider that manages authentication state globally
|
|
4
13
|
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
14
|
+
* Features:
|
|
15
|
+
* - Manages persistent authentication state
|
|
16
|
+
* - Automatically checks token expiration
|
|
17
|
+
* - Synchronizes state between browser tabs
|
|
18
|
+
* - Provides login/logout methods
|
|
19
|
+
* - Automatically redirects to /login when token expires
|
|
10
20
|
*
|
|
11
|
-
* @param props -
|
|
12
|
-
* @param props.api -
|
|
13
|
-
* @param props.children -
|
|
14
|
-
* @returns
|
|
21
|
+
* @param {AuthProviderProps} props - Component properties
|
|
22
|
+
* @param props.api - Axios instance for requests
|
|
23
|
+
* @param props.children - Child components that will receive the context
|
|
24
|
+
* @returns {JSX.Element} - Authentication context provider component
|
|
15
25
|
*
|
|
16
26
|
* @example
|
|
17
27
|
* ```tsx
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
28
|
+
* import { createApiClient } from '@forgepack/request'
|
|
29
|
+
*
|
|
30
|
+
* const api = createApiClient({ baseURL: 'https://api.example.com' })
|
|
31
|
+
*
|
|
32
|
+
* function App() {
|
|
33
|
+
* return (
|
|
34
|
+
* <AuthProvider api={api}>
|
|
35
|
+
* <Router>
|
|
36
|
+
* <Routes />
|
|
37
|
+
* </Router>
|
|
38
|
+
* </AuthProvider>
|
|
39
|
+
* )
|
|
40
|
+
* }
|
|
21
41
|
* ```
|
|
22
42
|
*/
|
|
23
|
-
export declare const AuthProvider: ({ api, children }:
|
|
24
|
-
api: AxiosInstance;
|
|
25
|
-
children: React.ReactNode;
|
|
26
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
|
43
|
+
export declare const AuthProvider: ({ api, children }: AuthProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
27
44
|
//# sourceMappingURL=AuthProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../src/hooks/AuthProvider.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAGrC
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sourceRoot":"","sources":["../../src/hooks/AuthProvider.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAGrC;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC5B,kCAAkC;IAClC,GAAG,EAAE,aAAa,CAAA;IAClB,qDAAqD;IACrD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC5B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,eAAO,MAAM,YAAY,GAAI,mBAAmB,iBAAiB,4CAiDhE,CAAA"}
|
|
@@ -8,24 +8,35 @@ const constants_1 = require("../utils/constants");
|
|
|
8
8
|
const auth_1 = require("../services/auth");
|
|
9
9
|
const AuthContext_1 = require("./AuthContext");
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Authentication context provider that manages authentication state globally
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
17
|
-
* -
|
|
13
|
+
* Features:
|
|
14
|
+
* - Manages persistent authentication state
|
|
15
|
+
* - Automatically checks token expiration
|
|
16
|
+
* - Synchronizes state between browser tabs
|
|
17
|
+
* - Provides login/logout methods
|
|
18
|
+
* - Automatically redirects to /login when token expires
|
|
18
19
|
*
|
|
19
|
-
* @param props -
|
|
20
|
-
* @param props.api -
|
|
21
|
-
* @param props.children -
|
|
22
|
-
* @returns
|
|
20
|
+
* @param {AuthProviderProps} props - Component properties
|
|
21
|
+
* @param props.api - Axios instance for requests
|
|
22
|
+
* @param props.children - Child components that will receive the context
|
|
23
|
+
* @returns {JSX.Element} - Authentication context provider component
|
|
23
24
|
*
|
|
24
25
|
* @example
|
|
25
26
|
* ```tsx
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* import { createApiClient } from '@forgepack/request'
|
|
28
|
+
*
|
|
29
|
+
* const api = createApiClient({ baseURL: 'https://api.example.com' })
|
|
30
|
+
*
|
|
31
|
+
* function App() {
|
|
32
|
+
* return (
|
|
33
|
+
* <AuthProvider api={api}>
|
|
34
|
+
* <Router>
|
|
35
|
+
* <Routes />
|
|
36
|
+
* </Router>
|
|
37
|
+
* </AuthProvider>
|
|
38
|
+
* )
|
|
39
|
+
* }
|
|
29
40
|
* ```
|
|
30
41
|
*/
|
|
31
42
|
const AuthProvider = ({ api, children }) => {
|
|
@@ -42,7 +53,7 @@ const AuthProvider = ({ api, children }) => {
|
|
|
42
53
|
setState(constants_1.initialAuth);
|
|
43
54
|
window.location.href = '/login';
|
|
44
55
|
}, []);
|
|
45
|
-
|
|
56
|
+
/** Checks for expired token every minute */
|
|
46
57
|
(0, react_1.useEffect)(() => {
|
|
47
58
|
const interval = setInterval(() => {
|
|
48
59
|
if (state.accessToken && !(0, token_1.isValidToken)()) {
|
|
@@ -51,7 +62,7 @@ const AuthProvider = ({ api, children }) => {
|
|
|
51
62
|
}, 60000);
|
|
52
63
|
return () => clearInterval(interval);
|
|
53
64
|
}, [state.accessToken, logoutUser]);
|
|
54
|
-
|
|
65
|
+
/** Listens for changes in localStorage (e.g., logout in another tab) */
|
|
55
66
|
(0, react_1.useEffect)(() => {
|
|
56
67
|
const handleStorageChange = (e) => {
|
|
57
68
|
if (e.key === 'token') {
|