@ooneex/fetcher 0.0.1 → 0.3.0
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 +247 -326
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +3 -3
- package/package.json +13 -6
- package/dist/ooneex-fetcher-0.0.1.tgz +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ooneex/fetcher
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A lightweight HTTP client wrapper for making fetch requests with typed headers and response handling. This package provides a fluent API for HTTP operations with built-in support for authentication tokens, content types, request cancellation, and file uploads.
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|

|
|
@@ -11,29 +11,21 @@ A powerful and flexible TypeScript/JavaScript HTTP client library built on top o
|
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
|
-
✅ **
|
|
14
|
+
✅ **Simple API** - Intuitive methods for GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS
|
|
15
15
|
|
|
16
|
-
✅ **Type-Safe** -
|
|
16
|
+
✅ **Type-Safe Responses** - Generic response types with full TypeScript support
|
|
17
17
|
|
|
18
|
-
✅ **
|
|
18
|
+
✅ **Authentication** - Built-in support for Bearer and Basic authentication tokens
|
|
19
19
|
|
|
20
|
-
✅ **File
|
|
20
|
+
✅ **File Uploads** - Easy file upload with automatic FormData handling
|
|
21
21
|
|
|
22
|
-
✅ **
|
|
22
|
+
✅ **Request Cancellation** - Abort in-flight requests with AbortController integration
|
|
23
23
|
|
|
24
|
-
✅ **
|
|
24
|
+
✅ **Header Management** - Fluent API for managing request headers
|
|
25
25
|
|
|
26
|
-
✅ **
|
|
26
|
+
✅ **Base URL Support** - Configure base URL for cleaner API calls
|
|
27
27
|
|
|
28
|
-
✅ **
|
|
29
|
-
|
|
30
|
-
✅ **JSON Handling** - Automatic JSON serialization and deserialization
|
|
31
|
-
|
|
32
|
-
✅ **Error Handling** - Comprehensive error handling and response parsing
|
|
33
|
-
|
|
34
|
-
✅ **Cross-Platform** - Works in Browser, Node.js, Bun, and Deno
|
|
35
|
-
|
|
36
|
-
✅ **Zero Dependencies** - Minimal external dependencies
|
|
28
|
+
✅ **Cloneable** - Create independent copies of configured fetcher instances
|
|
37
29
|
|
|
38
30
|
## Installation
|
|
39
31
|
|
|
@@ -59,64 +51,53 @@ npm install @ooneex/fetcher
|
|
|
59
51
|
|
|
60
52
|
## Usage
|
|
61
53
|
|
|
62
|
-
### Basic
|
|
54
|
+
### Basic GET Request
|
|
63
55
|
|
|
64
56
|
```typescript
|
|
65
57
|
import { Fetcher } from '@ooneex/fetcher';
|
|
66
58
|
|
|
67
|
-
const
|
|
59
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
const response = await api.get('/users');
|
|
71
|
-
console.log(response.data); // parsed JSON data
|
|
72
|
-
console.log(response.isSuccessful); // true for 2xx status codes
|
|
61
|
+
const response = await fetcher.get<{ users: User[] }>('/users');
|
|
73
62
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
if (response.success) {
|
|
64
|
+
console.log(response.data.users);
|
|
65
|
+
} else {
|
|
66
|
+
console.error(response.message);
|
|
67
|
+
}
|
|
77
68
|
```
|
|
78
69
|
|
|
79
|
-
###
|
|
70
|
+
### POST Request with Data
|
|
80
71
|
|
|
81
72
|
```typescript
|
|
82
73
|
import { Fetcher } from '@ooneex/fetcher';
|
|
83
74
|
|
|
84
|
-
const
|
|
75
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
85
76
|
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
const response = await fetcher.post<{ user: User }>('/users', {
|
|
78
|
+
name: 'John Doe',
|
|
79
|
+
email: 'john@example.com'
|
|
80
|
+
});
|
|
88
81
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// Make authenticated requests
|
|
93
|
-
const response = await api.get('/protected-resource');
|
|
94
|
-
|
|
95
|
-
// Clear authentication
|
|
96
|
-
api.clearBearerToken();
|
|
97
|
-
api.clearBasicToken();
|
|
82
|
+
if (response.success) {
|
|
83
|
+
console.log('Created user:', response.data.user);
|
|
84
|
+
}
|
|
98
85
|
```
|
|
99
86
|
|
|
100
|
-
###
|
|
87
|
+
### With Authentication
|
|
101
88
|
|
|
102
89
|
```typescript
|
|
103
90
|
import { Fetcher } from '@ooneex/fetcher';
|
|
104
91
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
// Set content type
|
|
108
|
-
api.setContentType('application/json');
|
|
92
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
109
93
|
|
|
110
|
-
// Set
|
|
111
|
-
|
|
94
|
+
// Set Bearer token
|
|
95
|
+
fetcher.setBearerToken('your-jwt-token');
|
|
112
96
|
|
|
113
|
-
|
|
114
|
-
api.setBearerToken('token')
|
|
115
|
-
.setContentType('application/json')
|
|
116
|
-
.setLang('fr-FR');
|
|
97
|
+
const response = await fetcher.get<{ profile: Profile }>('/me');
|
|
117
98
|
|
|
118
|
-
//
|
|
119
|
-
|
|
99
|
+
// Clear token when done
|
|
100
|
+
fetcher.clearBearerToken();
|
|
120
101
|
```
|
|
121
102
|
|
|
122
103
|
### File Upload
|
|
@@ -124,431 +105,371 @@ api.header.set('X-Custom-Header', 'custom-value');
|
|
|
124
105
|
```typescript
|
|
125
106
|
import { Fetcher } from '@ooneex/fetcher';
|
|
126
107
|
|
|
127
|
-
const
|
|
108
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
128
109
|
|
|
129
|
-
|
|
130
|
-
const fileInput = document.querySelector('input[type="file"]');
|
|
131
|
-
const file = fileInput.files[0];
|
|
110
|
+
const file = document.querySelector('input[type="file"]').files[0];
|
|
132
111
|
|
|
133
|
-
const
|
|
112
|
+
const response = await fetcher.upload<{ url: string }>(
|
|
113
|
+
'/upload',
|
|
114
|
+
file,
|
|
115
|
+
'avatar' // form field name
|
|
116
|
+
);
|
|
134
117
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
118
|
+
if (response.success) {
|
|
119
|
+
console.log('Uploaded to:', response.data.url);
|
|
120
|
+
}
|
|
138
121
|
```
|
|
139
122
|
|
|
140
|
-
### Request
|
|
123
|
+
### Request Cancellation
|
|
141
124
|
|
|
142
125
|
```typescript
|
|
143
126
|
import { Fetcher } from '@ooneex/fetcher';
|
|
144
127
|
|
|
145
|
-
const
|
|
128
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
146
129
|
|
|
147
130
|
// Start a request
|
|
148
|
-
const
|
|
131
|
+
const promise = fetcher.get('/slow-endpoint');
|
|
149
132
|
|
|
150
|
-
//
|
|
151
|
-
|
|
133
|
+
// Cancel it
|
|
134
|
+
fetcher.abort();
|
|
152
135
|
|
|
136
|
+
// Handle the cancellation
|
|
153
137
|
try {
|
|
154
|
-
|
|
138
|
+
await promise;
|
|
155
139
|
} catch (error) {
|
|
156
|
-
|
|
140
|
+
if (error.name === 'AbortError') {
|
|
141
|
+
console.log('Request was cancelled');
|
|
142
|
+
}
|
|
157
143
|
}
|
|
158
144
|
```
|
|
159
145
|
|
|
160
|
-
|
|
146
|
+
## API Reference
|
|
161
147
|
|
|
162
|
-
|
|
163
|
-
import { Fetcher } from '@ooneex/fetcher';
|
|
148
|
+
### Classes
|
|
164
149
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
// Configure headers and authentication
|
|
168
|
-
api.setBearerToken('jwt-token')
|
|
169
|
-
.setContentType('application/json')
|
|
170
|
-
.setLang('en-US');
|
|
171
|
-
|
|
172
|
-
// Make various HTTP requests
|
|
173
|
-
const users = await api.get('/users');
|
|
174
|
-
const user = await api.post('/users', { name: 'Jane Doe' });
|
|
175
|
-
const updated = await api.put('/users/1', { name: 'Jane Smith' });
|
|
176
|
-
const patched = await api.patch('/users/1', { email: 'jane@example.com' });
|
|
177
|
-
await api.delete('/users/1');
|
|
178
|
-
|
|
179
|
-
// Check response status
|
|
180
|
-
if (user.isSuccessful) {
|
|
181
|
-
console.log('User created:', user.data);
|
|
182
|
-
} else if (user.isClientError) {
|
|
183
|
-
console.log('Client error:', user.message);
|
|
184
|
-
} else if (user.isServerError) {
|
|
185
|
-
console.log('Server error:', user.message);
|
|
186
|
-
}
|
|
150
|
+
#### `Fetcher`
|
|
187
151
|
|
|
188
|
-
|
|
189
|
-
|
|
152
|
+
HTTP client class for making fetch requests.
|
|
153
|
+
|
|
154
|
+
**Constructor:**
|
|
155
|
+
```typescript
|
|
156
|
+
new Fetcher(baseURL?: string)
|
|
190
157
|
```
|
|
191
158
|
|
|
192
|
-
|
|
159
|
+
**Parameters:**
|
|
160
|
+
- `baseURL` - Optional base URL to prepend to all request paths
|
|
193
161
|
|
|
194
|
-
|
|
162
|
+
**Properties:**
|
|
163
|
+
|
|
164
|
+
##### `header: Header`
|
|
195
165
|
|
|
196
|
-
|
|
166
|
+
Access to the underlying Header instance for advanced header manipulation.
|
|
197
167
|
|
|
198
|
-
|
|
168
|
+
**Methods:**
|
|
199
169
|
|
|
200
|
-
##### `
|
|
201
|
-
|
|
170
|
+
##### `get<T>(path: string): Promise<ResponseDataType<T>>`
|
|
171
|
+
|
|
172
|
+
Performs a GET request.
|
|
202
173
|
|
|
203
174
|
**Parameters:**
|
|
204
|
-
- `
|
|
175
|
+
- `path` - Request path (appended to base URL if set)
|
|
176
|
+
|
|
177
|
+
**Returns:** Promise resolving to typed response data
|
|
205
178
|
|
|
206
179
|
**Example:**
|
|
207
180
|
```typescript
|
|
208
|
-
const
|
|
181
|
+
const response = await fetcher.get<{ items: Item[] }>('/items');
|
|
209
182
|
```
|
|
210
183
|
|
|
211
|
-
|
|
184
|
+
##### `post<T>(path: string, data?: unknown): Promise<ResponseDataType<T>>`
|
|
212
185
|
|
|
213
|
-
|
|
214
|
-
Sets the Authorization header with a Bearer token.
|
|
186
|
+
Performs a POST request with optional body data.
|
|
215
187
|
|
|
216
188
|
**Parameters:**
|
|
217
|
-
- `
|
|
189
|
+
- `path` - Request path
|
|
190
|
+
- `data` - Optional request body (automatically JSON-stringified for objects)
|
|
218
191
|
|
|
219
|
-
**Returns:**
|
|
192
|
+
**Returns:** Promise resolving to typed response data
|
|
220
193
|
|
|
221
194
|
**Example:**
|
|
222
195
|
```typescript
|
|
223
|
-
|
|
196
|
+
const response = await fetcher.post<{ id: string }>('/items', { name: 'New Item' });
|
|
224
197
|
```
|
|
225
198
|
|
|
226
|
-
##### `
|
|
227
|
-
Sets the Authorization header with Basic authentication.
|
|
199
|
+
##### `put<T>(path: string, data?: unknown): Promise<ResponseDataType<T>>`
|
|
228
200
|
|
|
229
|
-
|
|
230
|
-
- `token` - The base64-encoded credentials
|
|
201
|
+
Performs a PUT request with optional body data.
|
|
231
202
|
|
|
232
|
-
|
|
203
|
+
##### `patch<T>(path: string, data?: unknown): Promise<ResponseDataType<T>>`
|
|
233
204
|
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
api.setBasicToken(btoa('username:password'));
|
|
237
|
-
```
|
|
205
|
+
Performs a PATCH request with optional body data.
|
|
238
206
|
|
|
239
|
-
##### `
|
|
240
|
-
Removes the Authorization header.
|
|
207
|
+
##### `delete<T>(path: string): Promise<ResponseDataType<T>>`
|
|
241
208
|
|
|
242
|
-
|
|
209
|
+
Performs a DELETE request.
|
|
243
210
|
|
|
244
|
-
##### `
|
|
245
|
-
Removes the Authorization header.
|
|
211
|
+
##### `head<T>(path: string): Promise<ResponseDataType<T>>`
|
|
246
212
|
|
|
247
|
-
|
|
213
|
+
Performs a HEAD request.
|
|
248
214
|
|
|
249
|
-
|
|
215
|
+
##### `options<T>(path: string): Promise<ResponseDataType<T>>`
|
|
250
216
|
|
|
251
|
-
|
|
252
|
-
Sets the Content-Type header.
|
|
217
|
+
Performs an OPTIONS request.
|
|
253
218
|
|
|
254
|
-
|
|
255
|
-
- `contentType` - The MIME type for the content
|
|
219
|
+
##### `request<T>(method: HttpMethodType, path: string, data?: unknown): Promise<ResponseDataType<T>>`
|
|
256
220
|
|
|
257
|
-
|
|
221
|
+
Performs a custom HTTP request.
|
|
222
|
+
|
|
223
|
+
**Parameters:**
|
|
224
|
+
- `method` - HTTP method (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)
|
|
225
|
+
- `path` - Request path
|
|
226
|
+
- `data` - Optional request body
|
|
258
227
|
|
|
259
228
|
**Example:**
|
|
260
229
|
```typescript
|
|
261
|
-
|
|
262
|
-
api.setContentType('multipart/form-data');
|
|
230
|
+
const response = await fetcher.request<{ result: string }>('POST', '/custom', { foo: 'bar' });
|
|
263
231
|
```
|
|
264
232
|
|
|
265
|
-
##### `
|
|
266
|
-
|
|
233
|
+
##### `upload<T>(path: string, file: File | Blob, name?: string): Promise<ResponseDataType<T>>`
|
|
234
|
+
|
|
235
|
+
Uploads a file using multipart/form-data.
|
|
267
236
|
|
|
268
237
|
**Parameters:**
|
|
269
|
-
- `
|
|
238
|
+
- `path` - Upload endpoint path
|
|
239
|
+
- `file` - File or Blob to upload
|
|
240
|
+
- `name` - Form field name (default: 'file')
|
|
270
241
|
|
|
271
|
-
**Returns:**
|
|
242
|
+
**Returns:** Promise resolving to typed response data
|
|
272
243
|
|
|
273
244
|
**Example:**
|
|
274
245
|
```typescript
|
|
275
|
-
|
|
276
|
-
api.setLang('fr-FR');
|
|
246
|
+
const response = await fetcher.upload<{ url: string }>('/upload', file, 'document');
|
|
277
247
|
```
|
|
278
248
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
##### `abort(): Fetcher`
|
|
282
|
-
Aborts the current request and creates a new AbortController.
|
|
249
|
+
##### `setBearerToken(token: string): this`
|
|
283
250
|
|
|
284
|
-
|
|
251
|
+
Sets the Authorization header with a Bearer token.
|
|
285
252
|
|
|
286
|
-
**
|
|
287
|
-
|
|
288
|
-
api.abort(); // Cancels any ongoing requests
|
|
289
|
-
```
|
|
253
|
+
**Parameters:**
|
|
254
|
+
- `token` - JWT or other bearer token
|
|
290
255
|
|
|
291
|
-
|
|
292
|
-
Creates a new Fetcher instance with the same base URL.
|
|
256
|
+
**Returns:** The fetcher instance for chaining
|
|
293
257
|
|
|
294
|
-
|
|
258
|
+
##### `setBasicToken(token: string): this`
|
|
295
259
|
|
|
296
|
-
|
|
297
|
-
```typescript
|
|
298
|
-
const newApi = api.clone();
|
|
299
|
-
```
|
|
260
|
+
Sets the Authorization header with Basic authentication.
|
|
300
261
|
|
|
301
|
-
|
|
262
|
+
**Parameters:**
|
|
263
|
+
- `token` - Base64-encoded credentials
|
|
302
264
|
|
|
303
|
-
|
|
304
|
-
Performs a GET request.
|
|
265
|
+
**Returns:** The fetcher instance for chaining
|
|
305
266
|
|
|
306
|
-
|
|
307
|
-
- `path` - The endpoint path
|
|
267
|
+
##### `clearBearerToken(): this`
|
|
308
268
|
|
|
309
|
-
|
|
269
|
+
Removes the Authorization header.
|
|
310
270
|
|
|
311
|
-
**
|
|
312
|
-
```typescript
|
|
313
|
-
const users = await api.get<User[]>('/users');
|
|
314
|
-
```
|
|
271
|
+
**Returns:** The fetcher instance for chaining
|
|
315
272
|
|
|
316
|
-
##### `
|
|
317
|
-
Performs a POST request.
|
|
273
|
+
##### `clearBasicToken(): this`
|
|
318
274
|
|
|
319
|
-
|
|
320
|
-
- `path` - The endpoint path
|
|
321
|
-
- `data` - Optional request body data
|
|
275
|
+
Removes the Authorization header.
|
|
322
276
|
|
|
323
|
-
**Returns:**
|
|
277
|
+
**Returns:** The fetcher instance for chaining
|
|
324
278
|
|
|
325
|
-
|
|
326
|
-
```typescript
|
|
327
|
-
const newUser = await api.post<User>('/users', { name: 'John' });
|
|
328
|
-
```
|
|
279
|
+
##### `setContentType(contentType: MimeType): this`
|
|
329
280
|
|
|
330
|
-
|
|
331
|
-
Performs a PUT request.
|
|
281
|
+
Sets the Content-Type header.
|
|
332
282
|
|
|
333
283
|
**Parameters:**
|
|
334
|
-
- `
|
|
335
|
-
- `data` - Optional request body data
|
|
284
|
+
- `contentType` - MIME type string
|
|
336
285
|
|
|
337
|
-
**Returns:**
|
|
286
|
+
**Returns:** The fetcher instance for chaining
|
|
338
287
|
|
|
339
|
-
|
|
340
|
-
```typescript
|
|
341
|
-
const updatedUser = await api.put<User>('/users/1', { name: 'Jane' });
|
|
342
|
-
```
|
|
288
|
+
##### `setLang(lang: string): this`
|
|
343
289
|
|
|
344
|
-
|
|
345
|
-
Performs a PATCH request.
|
|
290
|
+
Sets the Accept-Language or custom language header.
|
|
346
291
|
|
|
347
292
|
**Parameters:**
|
|
348
|
-
- `
|
|
349
|
-
- `data` - Optional request body data
|
|
293
|
+
- `lang` - Language code (e.g., 'en', 'fr')
|
|
350
294
|
|
|
351
|
-
**Returns:**
|
|
295
|
+
**Returns:** The fetcher instance for chaining
|
|
352
296
|
|
|
353
|
-
|
|
354
|
-
```typescript
|
|
355
|
-
const patchedUser = await api.patch<User>('/users/1', { email: 'new@email.com' });
|
|
356
|
-
```
|
|
297
|
+
##### `abort(): this`
|
|
357
298
|
|
|
358
|
-
|
|
359
|
-
Performs a DELETE request.
|
|
299
|
+
Cancels any in-flight requests and resets the AbortController.
|
|
360
300
|
|
|
361
|
-
**
|
|
362
|
-
- `path` - The endpoint path
|
|
301
|
+
**Returns:** The fetcher instance for chaining
|
|
363
302
|
|
|
364
|
-
|
|
303
|
+
##### `clone(): Fetcher`
|
|
365
304
|
|
|
366
|
-
|
|
367
|
-
```typescript
|
|
368
|
-
await api.delete('/users/1');
|
|
369
|
-
```
|
|
305
|
+
Creates a new Fetcher instance with the same base URL.
|
|
370
306
|
|
|
371
|
-
|
|
372
|
-
Performs a HEAD request.
|
|
307
|
+
**Returns:** New Fetcher instance
|
|
373
308
|
|
|
374
|
-
|
|
375
|
-
- `path` - The endpoint path
|
|
309
|
+
### Interfaces
|
|
376
310
|
|
|
377
|
-
|
|
311
|
+
#### `IFetcher`
|
|
378
312
|
|
|
379
|
-
**Example:**
|
|
380
313
|
```typescript
|
|
381
|
-
|
|
314
|
+
interface IFetcher {
|
|
315
|
+
readonly header: Header;
|
|
316
|
+
|
|
317
|
+
setBearerToken(token: string): IFetcher;
|
|
318
|
+
setBasicToken(token: string): IFetcher;
|
|
319
|
+
clearBearerToken(): IFetcher;
|
|
320
|
+
clearBasicToken(): IFetcher;
|
|
321
|
+
setContentType(contentType: MimeType): IFetcher;
|
|
322
|
+
setLang(lang: string): IFetcher;
|
|
323
|
+
abort(): IFetcher;
|
|
324
|
+
clone(): IFetcher;
|
|
325
|
+
|
|
326
|
+
get<T>(path: string): Promise<ResponseDataType<T>>;
|
|
327
|
+
post<T>(path: string, data?: unknown): Promise<ResponseDataType<T>>;
|
|
328
|
+
put<T>(path: string, data?: unknown): Promise<ResponseDataType<T>>;
|
|
329
|
+
patch<T>(path: string, data?: unknown): Promise<ResponseDataType<T>>;
|
|
330
|
+
delete<T>(path: string): Promise<ResponseDataType<T>>;
|
|
331
|
+
head<T>(path: string): Promise<ResponseDataType<T>>;
|
|
332
|
+
options<T>(path: string): Promise<ResponseDataType<T>>;
|
|
333
|
+
request<T>(method: HttpMethodType, path: string, data?: unknown): Promise<ResponseDataType<T>>;
|
|
334
|
+
upload<T>(path: string, file: File | Blob, name?: string): Promise<ResponseDataType<T>>;
|
|
335
|
+
}
|
|
382
336
|
```
|
|
383
337
|
|
|
384
|
-
|
|
385
|
-
Performs an OPTIONS request.
|
|
386
|
-
|
|
387
|
-
**Parameters:**
|
|
388
|
-
- `path` - The endpoint path
|
|
338
|
+
## Advanced Usage
|
|
389
339
|
|
|
390
|
-
|
|
340
|
+
### Creating API Client Classes
|
|
391
341
|
|
|
392
|
-
**Example:**
|
|
393
342
|
```typescript
|
|
394
|
-
|
|
395
|
-
```
|
|
343
|
+
import { Fetcher } from '@ooneex/fetcher';
|
|
396
344
|
|
|
397
|
-
|
|
398
|
-
|
|
345
|
+
class UserApi {
|
|
346
|
+
private fetcher: Fetcher;
|
|
399
347
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
348
|
+
constructor(baseUrl: string, token?: string) {
|
|
349
|
+
this.fetcher = new Fetcher(baseUrl);
|
|
350
|
+
if (token) {
|
|
351
|
+
this.fetcher.setBearerToken(token);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
404
354
|
|
|
405
|
-
|
|
355
|
+
public async getUsers() {
|
|
356
|
+
return this.fetcher.get<{ users: User[] }>('/users');
|
|
357
|
+
}
|
|
406
358
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
```
|
|
359
|
+
public async createUser(data: CreateUserDto) {
|
|
360
|
+
return this.fetcher.post<{ user: User }>('/users', data);
|
|
361
|
+
}
|
|
411
362
|
|
|
412
|
-
|
|
413
|
-
|
|
363
|
+
public async updateUser(id: string, data: UpdateUserDto) {
|
|
364
|
+
return this.fetcher.patch<{ user: User }>(`/users/${id}`, data);
|
|
365
|
+
}
|
|
414
366
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
367
|
+
public async deleteUser(id: string) {
|
|
368
|
+
return this.fetcher.delete<{ success: boolean }>(`/users/${id}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
419
372
|
|
|
420
|
-
|
|
373
|
+
### Request Interceptors with Header Manipulation
|
|
421
374
|
|
|
422
|
-
**Example:**
|
|
423
375
|
```typescript
|
|
424
|
-
|
|
425
|
-
const file = fileInput.files[0];
|
|
426
|
-
const response = await api.upload('/upload', file, 'document');
|
|
427
|
-
```
|
|
376
|
+
import { Fetcher } from '@ooneex/fetcher';
|
|
428
377
|
|
|
429
|
-
|
|
378
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
430
379
|
|
|
431
|
-
|
|
432
|
-
|
|
380
|
+
// Add custom headers
|
|
381
|
+
fetcher.header.set('X-Request-ID', generateRequestId());
|
|
382
|
+
fetcher.header.set('X-Client-Version', '1.0.0');
|
|
433
383
|
|
|
434
|
-
|
|
435
|
-
```typescript
|
|
436
|
-
api.header.set('X-API-Key', 'your-api-key');
|
|
437
|
-
const contentType = api.header.get('Content-Type');
|
|
384
|
+
const response = await fetcher.get('/endpoint');
|
|
438
385
|
```
|
|
439
386
|
|
|
440
|
-
###
|
|
387
|
+
### Error Handling
|
|
441
388
|
|
|
442
|
-
|
|
443
|
-
|
|
389
|
+
```typescript
|
|
390
|
+
import { Fetcher } from '@ooneex/fetcher';
|
|
444
391
|
|
|
445
|
-
|
|
446
|
-
- `data: T | null` - The parsed response data
|
|
447
|
-
- `message: string | null` - Error message if parsing failed
|
|
448
|
-
- `header: ReadonlyHeader` - Response headers
|
|
449
|
-
- `isInformational: boolean` - True for 1xx status codes
|
|
450
|
-
- `isSuccessful: boolean` - True for 2xx status codes
|
|
451
|
-
- `isRedirect: boolean` - True for 3xx status codes
|
|
452
|
-
- `isClientError: boolean` - True for 4xx status codes
|
|
453
|
-
- `isServerError: boolean` - True for 5xx status codes
|
|
454
|
-
- `isError: boolean` - True for 4xx or 5xx status codes
|
|
392
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
455
393
|
|
|
456
|
-
|
|
457
|
-
```typescript
|
|
458
|
-
const response = await api.get<User[]>('/users');
|
|
394
|
+
const response = await fetcher.get<{ data: string }>('/resource');
|
|
459
395
|
|
|
460
|
-
if (response.
|
|
461
|
-
|
|
396
|
+
if (response.success) {
|
|
397
|
+
// Handle successful response
|
|
398
|
+
console.log(response.data);
|
|
462
399
|
} else if (response.isClientError) {
|
|
400
|
+
// Handle 4xx errors
|
|
463
401
|
console.error('Client error:', response.message);
|
|
464
402
|
} else if (response.isServerError) {
|
|
403
|
+
// Handle 5xx errors
|
|
465
404
|
console.error('Server error:', response.message);
|
|
405
|
+
} else if (response.isNotFound) {
|
|
406
|
+
// Handle 404
|
|
407
|
+
console.error('Resource not found');
|
|
408
|
+
} else if (response.isUnauthorized) {
|
|
409
|
+
// Handle 401
|
|
410
|
+
console.error('Unauthorized - please login');
|
|
466
411
|
}
|
|
467
412
|
```
|
|
468
413
|
|
|
469
|
-
|
|
470
|
-
Interface defining the Fetcher contract.
|
|
414
|
+
### Chaining Configuration
|
|
471
415
|
|
|
472
|
-
**Example:**
|
|
473
416
|
```typescript
|
|
474
|
-
import {
|
|
417
|
+
import { Fetcher } from '@ooneex/fetcher';
|
|
475
418
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
419
|
+
const fetcher = new Fetcher('https://api.example.com')
|
|
420
|
+
.setBearerToken('your-token')
|
|
421
|
+
.setLang('en')
|
|
422
|
+
.setContentType('application/json');
|
|
480
423
|
|
|
481
|
-
|
|
424
|
+
const response = await fetcher.post('/data', { key: 'value' });
|
|
425
|
+
```
|
|
482
426
|
|
|
483
|
-
|
|
427
|
+
### Cloning for Different Contexts
|
|
484
428
|
|
|
485
429
|
```typescript
|
|
486
430
|
import { Fetcher } from '@ooneex/fetcher';
|
|
487
431
|
|
|
488
|
-
const
|
|
432
|
+
const baseFetcher = new Fetcher('https://api.example.com');
|
|
489
433
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
if (response.isSuccessful) {
|
|
494
|
-
// Handle successful response
|
|
495
|
-
console.log('Data:', response.data);
|
|
496
|
-
} else if (response.isClientError) {
|
|
497
|
-
// Handle 4xx errors
|
|
498
|
-
console.error('Client error:', response.message);
|
|
499
|
-
} else if (response.isServerError) {
|
|
500
|
-
// Handle 5xx errors
|
|
501
|
-
console.error('Server error:', response.message);
|
|
502
|
-
}
|
|
503
|
-
} catch (error) {
|
|
504
|
-
// Handle network errors or other exceptions
|
|
505
|
-
console.error('Request failed:', error);
|
|
506
|
-
}
|
|
507
|
-
```
|
|
434
|
+
// Create authenticated clone
|
|
435
|
+
const authFetcher = baseFetcher.clone();
|
|
436
|
+
authFetcher.setBearerToken('user-token');
|
|
508
437
|
|
|
509
|
-
|
|
438
|
+
// Create admin clone
|
|
439
|
+
const adminFetcher = baseFetcher.clone();
|
|
440
|
+
adminFetcher.setBearerToken('admin-token');
|
|
510
441
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
```typescript
|
|
515
|
-
const api = new Fetcher('https://api.example.com');
|
|
516
|
-
|
|
517
|
-
// These all work correctly
|
|
518
|
-
await api.get('/users'); // -> https://api.example.com/users
|
|
519
|
-
await api.get('users'); // -> https://api.example.com/users
|
|
520
|
-
await api.get('https://other.com/api'); // -> https://other.com/api (absolute URL)
|
|
521
|
-
|
|
522
|
-
// Base URL with trailing slash
|
|
523
|
-
const api2 = new Fetcher('https://api.example.com/');
|
|
524
|
-
await api2.get('/users'); // -> https://api.example.com/users
|
|
442
|
+
// Use independently
|
|
443
|
+
await authFetcher.get('/user/profile');
|
|
444
|
+
await adminFetcher.get('/admin/dashboard');
|
|
525
445
|
```
|
|
526
446
|
|
|
527
|
-
###
|
|
528
|
-
The fetcher automatically sets appropriate Content-Type headers:
|
|
447
|
+
### Uploading Multiple Files
|
|
529
448
|
|
|
530
449
|
```typescript
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
// Automatic JSON content type for objects
|
|
534
|
-
await api.post('/users', { name: 'John' }); // Content-Type: application/json
|
|
535
|
-
|
|
536
|
-
// FormData handling
|
|
537
|
-
const formData = new FormData();
|
|
538
|
-
formData.append('name', 'John');
|
|
539
|
-
await api.post('/users', formData); // Content-Type: multipart/form-data
|
|
540
|
-
|
|
541
|
-
// String data
|
|
542
|
-
await api.post('/users', 'raw string data');
|
|
450
|
+
import { Fetcher } from '@ooneex/fetcher';
|
|
543
451
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
452
|
+
const fetcher = new Fetcher('https://api.example.com');
|
|
453
|
+
|
|
454
|
+
async function uploadFiles(files: File[]) {
|
|
455
|
+
const results = [];
|
|
456
|
+
|
|
457
|
+
for (const file of files) {
|
|
458
|
+
const response = await fetcher.upload<{ url: string }>(
|
|
459
|
+
'/upload',
|
|
460
|
+
file,
|
|
461
|
+
'file'
|
|
462
|
+
);
|
|
463
|
+
results.push(response);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return results;
|
|
467
|
+
}
|
|
547
468
|
```
|
|
548
469
|
|
|
549
470
|
## License
|
|
550
471
|
|
|
551
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
472
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
552
473
|
|
|
553
474
|
## Contributing
|
|
554
475
|
|
package/dist/index.d.ts
CHANGED
|
@@ -27,10 +27,10 @@ interface IFetcher {
|
|
|
27
27
|
upload<T extends Record<string, unknown> = Record<string, unknown>>(path: string, file: File | Blob, name?: string): Promise<ResponseDataType<T>>;
|
|
28
28
|
}
|
|
29
29
|
declare class Fetcher implements IFetcher {
|
|
30
|
-
private baseURL
|
|
30
|
+
private baseURL?;
|
|
31
31
|
private abortController;
|
|
32
32
|
readonly header: Header2;
|
|
33
|
-
constructor(baseURL
|
|
33
|
+
constructor(baseURL?: string | undefined);
|
|
34
34
|
setBearerToken(token: string): this;
|
|
35
35
|
setBasicToken(token: string): this;
|
|
36
36
|
clearBearerToken(): this;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Header as c}from"@ooneex/http-header";class
|
|
1
|
+
import{Header as c}from"@ooneex/http-header";class t{baseURL;abortController;header=new c;constructor(e){this.baseURL=e;this.abortController=new AbortController}setBearerToken(e){return this.header.setBearerToken(e),this}setBasicToken(e){return this.header.setBasicAuth(e),this}clearBearerToken(){return this.header.remove("Authorization"),this}clearBasicToken(){return this.header.remove("Authorization"),this}setContentType(e){return this.header.contentType(e),this}setLang(e){return this.header.setLang(e),this}abort(){return this.abortController.abort(),this.abortController=new AbortController,this}clone(){return new t(this.baseURL)}async get(e){return this.request("GET",e)}async post(e,n){return this.request("POST",e,n)}async put(e,n){return this.request("PUT",e,n)}async patch(e,n){return this.request("PATCH",e,n)}async delete(e){return this.request("DELETE",e)}async head(e){return this.request("HEAD",e)}async options(e){return this.request("OPTIONS",e)}async request(e,n,r){let s=this.buildURL(n),o=this.buildRequestOptions(e,r),i=await fetch(s,o);try{return await i.json()}catch(T){throw Error(T instanceof Error?T.message:"Failed to parse JSON response")}}async upload(e,n,r="file"){let s=new FormData;s.append(r,n);let o=this.header.get("Content-Type");this.header.remove("Content-Type");let i=await this.request("POST",e,s);if(o)this.header.set("Content-Type",o);return i}buildURL(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;if(!this.baseURL)return e;let n=e.startsWith("/")?e:`/${e}`;return`${this.baseURL.endsWith("/")?this.baseURL.slice(0,-1):this.baseURL}${n}`}buildRequestOptions(e,n){let r=this.header.native,s;if(n!==void 0&&e!=="GET"&&e!=="HEAD"&&e!=="OPTIONS"){if(n instanceof FormData)s=n,this.header.clearContentType();else if(typeof n==="string")s=n;else if(n instanceof Blob||n instanceof ArrayBuffer)s=n;else if(s=JSON.stringify(n),!this.header.has("Content-Type"))this.header.setJson()}return{method:e,headers:r,...s!==void 0&&{body:s},signal:this.abortController.signal}}}export{t as Fetcher};
|
|
2
2
|
|
|
3
|
-
//# debugId=
|
|
3
|
+
//# debugId=FC0FC58E0FCC4CA964756E2164756E21
|
package/dist/index.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["src/Fetcher.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { Header } from \"@ooneex/http-header\";\nimport type { MimeType } from \"@ooneex/http-mimes\";\nimport type { ResponseDataType } from \"@ooneex/http-response\";\nimport type { HttpMethodType } from \"@ooneex/types\";\nimport type { IFetcher } from \"./types\";\n\nexport class Fetcher implements IFetcher {\n private abortController: AbortController;\n public readonly header: Header = new Header();\n\n constructor(private baseURL
|
|
5
|
+
"import { Header } from \"@ooneex/http-header\";\nimport type { MimeType } from \"@ooneex/http-mimes\";\nimport type { ResponseDataType } from \"@ooneex/http-response\";\nimport type { HttpMethodType } from \"@ooneex/types\";\nimport type { IFetcher } from \"./types\";\n\nexport class Fetcher implements IFetcher {\n private abortController: AbortController;\n public readonly header: Header = new Header();\n\n constructor(private baseURL?: string) {\n this.abortController = new AbortController();\n }\n\n public setBearerToken(token: string): this {\n this.header.setBearerToken(token);\n\n return this;\n }\n\n public setBasicToken(token: string): this {\n this.header.setBasicAuth(token);\n\n return this;\n }\n\n public clearBearerToken(): this {\n this.header.remove(\"Authorization\");\n\n return this;\n }\n\n public clearBasicToken(): this {\n this.header.remove(\"Authorization\");\n\n return this;\n }\n\n public setContentType(contentType: MimeType): this {\n this.header.contentType(contentType);\n\n return this;\n }\n\n public setLang(lang: string): this {\n this.header.setLang(lang);\n\n return this;\n }\n\n public abort(): this {\n this.abortController.abort();\n this.abortController = new AbortController();\n\n return this;\n }\n\n public clone(): Fetcher {\n const cloned = new Fetcher(this.baseURL);\n return cloned;\n }\n\n public async get<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n ): Promise<ResponseDataType<T>> {\n return this.request<T>(\"GET\", path);\n }\n\n public async post<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n data?: unknown,\n ): Promise<ResponseDataType<T>> {\n return this.request<T>(\"POST\", path, data);\n }\n\n public async put<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n data?: unknown,\n ): Promise<ResponseDataType<T>> {\n return this.request<T>(\"PUT\", path, data);\n }\n\n public async patch<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n data?: unknown,\n ): Promise<ResponseDataType<T>> {\n return this.request<T>(\"PATCH\", path, data);\n }\n\n public async delete<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n ): Promise<ResponseDataType<T>> {\n return this.request<T>(\"DELETE\", path);\n }\n\n public async head<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n ): Promise<ResponseDataType<T>> {\n return this.request<T>(\"HEAD\", path);\n }\n\n public async options<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n ): Promise<ResponseDataType<T>> {\n return this.request<T>(\"OPTIONS\", path);\n }\n\n public async request<T extends Record<string, unknown> = Record<string, unknown>>(\n method: HttpMethodType,\n path: string,\n data?: unknown,\n ): Promise<ResponseDataType<T>> {\n const fullURL = this.buildURL(path);\n const requestOptions = this.buildRequestOptions(method, data);\n const response = await fetch(fullURL, requestOptions);\n\n try {\n return await response.json();\n } catch (error) {\n throw new Error(error instanceof Error ? error.message : \"Failed to parse JSON response\");\n }\n }\n\n public async upload<T extends Record<string, unknown> = Record<string, unknown>>(\n path: string,\n file: File | Blob,\n name = \"file\",\n ): Promise<ResponseDataType<T>> {\n const formData = new FormData();\n formData.append(name, file);\n\n // Clear any existing Content-Type to let browser set multipart/form-data boundary\n const originalContentType = this.header.get(\"Content-Type\");\n this.header.remove(\"Content-Type\");\n\n const result = await this.request<T>(\"POST\", path, formData);\n\n // Restore original Content-Type if it existed\n if (originalContentType) {\n this.header.set(\"Content-Type\", originalContentType);\n }\n\n return result;\n }\n\n private buildURL(url: string): string {\n if (url.startsWith(\"http://\") || url.startsWith(\"https://\")) {\n return url;\n }\n\n if (!this.baseURL) {\n return url;\n }\n\n const path = url.startsWith(\"/\") ? url : `/${url}`;\n const baseURL = this.baseURL.endsWith(\"/\") ? this.baseURL.slice(0, -1) : this.baseURL;\n\n return `${baseURL}${path}`;\n }\n\n private buildRequestOptions(method: string, data?: unknown): RequestInit {\n const headers = this.header.native;\n\n let body: BodyInit | undefined;\n\n if (data !== undefined && method !== \"GET\" && method !== \"HEAD\" && method !== \"OPTIONS\") {\n if (data instanceof FormData) {\n body = data;\n this.header.clearContentType();\n } else if (typeof data === \"string\") {\n body = data;\n } else if (data instanceof Blob || data instanceof ArrayBuffer) {\n body = data;\n } else {\n body = JSON.stringify(data);\n // Set Content-Type to application/json if not already set\n if (!this.header.has(\"Content-Type\")) {\n this.header.setJson();\n }\n }\n }\n\n const requestOptions: RequestInit = {\n method,\n headers,\n ...(body !== undefined && { body }),\n signal: this.abortController.signal,\n };\n\n return requestOptions;\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "AAAA,iBAAS,4BAMF,MAAM,CAA4B,CAInB,QAHZ,gBACQ,OAAiB,IAAI,EAErC,WAAW,CAAS,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "FC0FC58E0FCC4CA964756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ooneex/fetcher",
|
|
3
|
-
"description": "",
|
|
4
|
-
"version": "0.0
|
|
3
|
+
"description": "A lightweight HTTP client wrapper for making fetch requests with typed headers and response handling",
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -25,9 +25,7 @@
|
|
|
25
25
|
"test": "bun test tests",
|
|
26
26
|
"build": "bunup",
|
|
27
27
|
"lint": "tsgo --noEmit && bunx biome lint",
|
|
28
|
-
"publish
|
|
29
|
-
"publish:pack": "bun pm pack --destination ./dist",
|
|
30
|
-
"publish:dry": "bun publish --dry-run"
|
|
28
|
+
"publish": "bun publish --access public || true"
|
|
31
29
|
},
|
|
32
30
|
"dependencies": {
|
|
33
31
|
"@ooneex/http-header": "0.0.1"
|
|
@@ -36,5 +34,14 @@
|
|
|
36
34
|
"@ooneex/http-response": "0.0.1",
|
|
37
35
|
"@ooneex/http-mimes": "0.0.1",
|
|
38
36
|
"@ooneex/types": "0.0.1"
|
|
39
|
-
}
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"api-client",
|
|
40
|
+
"bun",
|
|
41
|
+
"fetch",
|
|
42
|
+
"fetcher",
|
|
43
|
+
"http-client",
|
|
44
|
+
"ooneex",
|
|
45
|
+
"typescript"
|
|
46
|
+
]
|
|
40
47
|
}
|
|
Binary file
|