create-request 0.0.1-beta.13 → 0.0.1-beta.14
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 +120 -127
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
`create-request` is a modern TypeScript library that transforms how you make API calls. Built as an elegant wrapper around the native Fetch API, it provides a chainable, fluent interface that dramatically reduces boilerplate while adding powerful features like automatic retries, timeout handling, and comprehensive error management.
|
|
8
8
|
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Core Features](#core-features)
|
|
12
|
+
- [Why create-request](#why-create-request)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Basic Usage](#basic-usage)
|
|
15
|
+
- [Advanced Usage](#advanced-usage)
|
|
16
|
+
- [CSRF Protection](#csrf-protection)
|
|
17
|
+
- [Browser Support](#browser-support)
|
|
18
|
+
- [License](#license)
|
|
19
|
+
|
|
9
20
|
## Core Features
|
|
10
21
|
|
|
11
22
|
- 🚀 **Performance** - Tiny bundle size with zero dependencies
|
|
@@ -29,13 +40,13 @@
|
|
|
29
40
|
// Before: Regular fetch
|
|
30
41
|
async function createUser(userData) {
|
|
31
42
|
try {
|
|
32
|
-
const response = await fetch(
|
|
33
|
-
method:
|
|
43
|
+
const response = await fetch("https://api.example.com/users", {
|
|
44
|
+
method: "POST",
|
|
34
45
|
headers: {
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
Authorization: "Basic " + btoa("username:password"),
|
|
37
48
|
},
|
|
38
|
-
body: JSON.stringify(userData)
|
|
49
|
+
body: JSON.stringify(userData),
|
|
39
50
|
});
|
|
40
51
|
|
|
41
52
|
if (!response.ok) {
|
|
@@ -44,22 +55,23 @@ async function createUser(userData) {
|
|
|
44
55
|
const data = await response.json();
|
|
45
56
|
return data;
|
|
46
57
|
} catch (error) {
|
|
47
|
-
console.error(
|
|
58
|
+
console.error("Fetch error:", error);
|
|
48
59
|
throw error;
|
|
49
60
|
}
|
|
50
61
|
}
|
|
51
62
|
|
|
52
63
|
// After: With create-request
|
|
53
|
-
import create from
|
|
64
|
+
import create from "create-request";
|
|
54
65
|
|
|
55
66
|
function createUser(userData) {
|
|
56
|
-
return create
|
|
57
|
-
.
|
|
67
|
+
return create
|
|
68
|
+
.post()
|
|
69
|
+
.withBasicAuth("username", "password")
|
|
58
70
|
.withBody(userData)
|
|
59
|
-
.sendTo(
|
|
71
|
+
.sendTo("https://api.example.com/users")
|
|
60
72
|
.getData<User>()
|
|
61
73
|
.catch(error => {
|
|
62
|
-
console.error(
|
|
74
|
+
console.error("Fetch error:", error);
|
|
63
75
|
throw error;
|
|
64
76
|
});
|
|
65
77
|
}
|
|
@@ -82,7 +94,7 @@ yarn add create-request
|
|
|
82
94
|
### Creating Requests
|
|
83
95
|
|
|
84
96
|
```typescript
|
|
85
|
-
import create from
|
|
97
|
+
import create from "create-request";
|
|
86
98
|
|
|
87
99
|
// Create different request types
|
|
88
100
|
const getRequest = create.get();
|
|
@@ -99,13 +111,14 @@ const optionsRequest = create.options();
|
|
|
99
111
|
The library provides a comprehensive set of configuration methods that can be chained together to customize your requests:
|
|
100
112
|
|
|
101
113
|
```typescript
|
|
102
|
-
import create, { RequestPriority, CredentialsPolicy, RequestMode, CacheMode, RedirectMode, ReferrerPolicy } from
|
|
114
|
+
import create, { RequestPriority, CredentialsPolicy, RequestMode, CacheMode, RedirectMode, ReferrerPolicy } from "create-request";
|
|
103
115
|
|
|
104
116
|
// Configure request options
|
|
105
|
-
const request = create
|
|
117
|
+
const request = create
|
|
118
|
+
.get()
|
|
106
119
|
// Basic headers
|
|
107
|
-
.withHeaders({
|
|
108
|
-
.withHeader(
|
|
120
|
+
.withHeaders({ "X-API-Key": "abc123", "Accept-Language": "en-US" })
|
|
121
|
+
.withHeader("Custom-Header", "value") // Add a single header
|
|
109
122
|
|
|
110
123
|
// Timeout settings
|
|
111
124
|
.withTimeout(5000) // Request will abort after 5 seconds
|
|
@@ -117,95 +130,89 @@ const request = create.get()
|
|
|
117
130
|
})
|
|
118
131
|
|
|
119
132
|
// Authentication methods
|
|
120
|
-
.withBearerToken(
|
|
121
|
-
.withBasicAuth(
|
|
133
|
+
.withBearerToken("your-token") // Adds Authorization: Bearer your-token
|
|
134
|
+
.withBasicAuth("username", "password") // HTTP Basic Authentication
|
|
122
135
|
|
|
123
136
|
// URL parameters
|
|
124
|
-
.withQueryParams({ search:
|
|
125
|
-
.withQueryParam(
|
|
137
|
+
.withQueryParams({ search: "term", page: 1, limit: 20 })
|
|
138
|
+
.withQueryParam("filter", "active") // Add a single query parameter
|
|
126
139
|
|
|
127
140
|
// Request body configuration (for POST/PUT/PATCH)
|
|
128
|
-
.withContentType(
|
|
141
|
+
.withContentType("application/json") // Set specific content type
|
|
129
142
|
|
|
130
143
|
// Fetch API options
|
|
131
144
|
.withCredentials(CredentialsPolicy.INCLUDE) // Includes cookies with cross-origin requests
|
|
132
145
|
.withMode(RequestMode.CORS) // Controls CORS behavior
|
|
133
146
|
.withRedirect(RedirectMode.FOLLOW) // Controls redirect behavior (follow, error, manual)
|
|
134
|
-
.withReferrer(
|
|
147
|
+
.withReferrer("https://example.com") // Sets request referrer
|
|
135
148
|
.withReferrerPolicy(ReferrerPolicy.NO_REFERRER_WHEN_DOWNGRADE) // Controls referrer policy
|
|
136
|
-
.withPriority(RequestPriority.HIGH) // Sets request priority
|
|
149
|
+
.withPriority(RequestPriority.HIGH); // Sets request priority
|
|
137
150
|
```
|
|
138
151
|
|
|
139
152
|
Each configuration method returns the request object, allowing for a fluent interface where methods can be chained together. You can configure only what you need for a specific request:
|
|
140
153
|
|
|
141
154
|
```typescript
|
|
142
155
|
// Simple example with just what's needed
|
|
143
|
-
const searchUsers = create.get()
|
|
144
|
-
.withBearerToken(userToken)
|
|
145
|
-
.withQueryParams({ q: searchTerm, limit: 20 })
|
|
146
|
-
.withTimeout(3000);
|
|
156
|
+
const searchUsers = create.get().withBearerToken(userToken).withQueryParams({ q: searchTerm, limit: 20 }).withTimeout(3000);
|
|
147
157
|
|
|
148
158
|
// Now execute the request
|
|
149
|
-
const users = await searchUsers.sendTo(
|
|
159
|
+
const users = await searchUsers.sendTo("https://api.example.com/users").getData();
|
|
150
160
|
```
|
|
151
161
|
|
|
152
162
|
You can also create reusable base requests with common settings:
|
|
153
163
|
|
|
154
164
|
```typescript
|
|
155
165
|
// Create base authenticated request
|
|
156
|
-
const apiBase = create
|
|
166
|
+
const apiBase = create
|
|
167
|
+
.get()
|
|
157
168
|
.withHeaders({
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
"X-API-Version": "1.2",
|
|
170
|
+
"Accept-Language": "en-US",
|
|
160
171
|
})
|
|
161
172
|
.withBearerToken(authToken)
|
|
162
173
|
.withTimeout(5000)
|
|
163
174
|
.withRetries(2);
|
|
164
175
|
|
|
165
176
|
// Use the base request for different endpoints
|
|
166
|
-
const users = await apiBase.sendTo(
|
|
167
|
-
const products = await apiBase.sendTo(
|
|
177
|
+
const users = await apiBase.sendTo("https://api.example.com/users").getData();
|
|
178
|
+
const products = await apiBase.sendTo("https://api.example.com/products").getData();
|
|
168
179
|
```
|
|
169
180
|
|
|
170
181
|
### Request Bodies (POST/PUT/PATCH)
|
|
171
182
|
|
|
172
183
|
```typescript
|
|
173
184
|
// JSON body
|
|
174
|
-
const jsonRequest = create.post()
|
|
175
|
-
.withBody({ name: 'John', age: 30 });
|
|
185
|
+
const jsonRequest = create.post().withBody({ name: "John", age: 30 });
|
|
176
186
|
|
|
177
187
|
// String body
|
|
178
|
-
const textRequest = create.post()
|
|
179
|
-
.withBody('Plain text content');
|
|
188
|
+
const textRequest = create.post().withBody("Plain text content");
|
|
180
189
|
|
|
181
190
|
// Form data
|
|
182
191
|
const formData = new FormData();
|
|
183
|
-
formData.append(
|
|
184
|
-
formData.append(
|
|
192
|
+
formData.append("name", "John");
|
|
193
|
+
formData.append("file", fileBlob);
|
|
185
194
|
|
|
186
|
-
const formRequest = create.post()
|
|
187
|
-
.withBody(formData);
|
|
195
|
+
const formRequest = create.post().withBody(formData);
|
|
188
196
|
```
|
|
189
197
|
|
|
190
198
|
### Executing Requests
|
|
191
199
|
|
|
192
200
|
```typescript
|
|
193
201
|
// Simple execution
|
|
194
|
-
const response = await request.sendTo(
|
|
202
|
+
const response = await request.sendTo("https://api.example.com/endpoint");
|
|
195
203
|
|
|
196
204
|
// With direct data extraction
|
|
197
|
-
const jsonData = await request.sendTo(
|
|
198
|
-
const textData = await request.sendTo(
|
|
199
|
-
const blobData = await request.sendTo(
|
|
200
|
-
const bodyStream = await request.sendTo(
|
|
201
|
-
const arrayBuffer = await request.sendTo(
|
|
205
|
+
const jsonData = await request.sendTo("https://api.example.com/endpoint").getJson();
|
|
206
|
+
const textData = await request.sendTo("https://api.example.com/endpoint").getText();
|
|
207
|
+
const blobData = await request.sendTo("https://api.example.com/endpoint").getBlob();
|
|
208
|
+
const bodyStream = await request.sendTo("https://api.example.com/endpoint").getBody();
|
|
209
|
+
const arrayBuffer = await request.sendTo("https://api.example.com/endpoint").getArrayBuffer();
|
|
202
210
|
|
|
203
211
|
// Using the data selector API to extract specific data
|
|
204
|
-
const userData = await request.sendTo(
|
|
205
|
-
.getData(data => data.results.users);
|
|
212
|
+
const userData = await request.sendTo("https://api.example.com/users").getData(data => data.results.users);
|
|
206
213
|
|
|
207
214
|
// Using the data selector without a selector function just returns the full JSON response
|
|
208
|
-
const fullData = await request.sendTo(
|
|
215
|
+
const fullData = await request.sendTo("https://api.example.com/data").getData();
|
|
209
216
|
```
|
|
210
217
|
|
|
211
218
|
### Data Selection
|
|
@@ -214,37 +221,27 @@ The `getData` method provides a powerful way to extract and transform specific d
|
|
|
214
221
|
|
|
215
222
|
```typescript
|
|
216
223
|
// Extract specific properties from nested structures
|
|
217
|
-
const posts = await request
|
|
218
|
-
.sendTo('https://api.example.com/feed')
|
|
219
|
-
.getData(data => data.feed.posts);
|
|
224
|
+
const posts = await request.sendTo("https://api.example.com/feed").getData(data => data.feed.posts);
|
|
220
225
|
|
|
221
226
|
// Transform data in the selector function
|
|
222
|
-
const usernames = await request
|
|
223
|
-
.sendTo('https://api.example.com/users')
|
|
224
|
-
.getData(data => data.users.map(user => user.username));
|
|
227
|
+
const usernames = await request.sendTo("https://api.example.com/users").getData(data => data.users.map(user => user.username));
|
|
225
228
|
|
|
226
229
|
// Apply filtering in the selector
|
|
227
|
-
const activeUsers = await request
|
|
228
|
-
.sendTo('https://api.example.com/users')
|
|
229
|
-
.getData(data => data.users.filter(user => user.isActive));
|
|
230
|
+
const activeUsers = await request.sendTo("https://api.example.com/users").getData(data => data.users.filter(user => user.isActive));
|
|
230
231
|
|
|
231
232
|
// Combine data from complex nested structures
|
|
232
|
-
const combinedData = await request
|
|
233
|
-
.
|
|
234
|
-
.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
notifications: data.user.notifications.unread
|
|
238
|
-
}));
|
|
233
|
+
const combinedData = await request.sendTo("https://api.example.com/dashboard").getData(data => ({
|
|
234
|
+
userCount: data.stats.users.total,
|
|
235
|
+
recentPosts: data.content.recent.slice(0, 5),
|
|
236
|
+
notifications: data.user.notifications.unread,
|
|
237
|
+
}));
|
|
239
238
|
```
|
|
240
239
|
|
|
241
240
|
When a selector fails, the error message will contain the original response data to help diagnose the issue:
|
|
242
241
|
|
|
243
242
|
```typescript
|
|
244
243
|
try {
|
|
245
|
-
const result = await request
|
|
246
|
-
.sendTo('https://api.example.com/data')
|
|
247
|
-
.getData(data => data.results.items); // Will fail if structure is different
|
|
244
|
+
const result = await request.sendTo("https://api.example.com/data").getData(data => data.results.items); // Will fail if structure is different
|
|
248
245
|
} catch (error) {
|
|
249
246
|
console.error(error);
|
|
250
247
|
// Error message includes the original response data
|
|
@@ -257,13 +254,13 @@ All errors from requests are instances of `RequestError` with detailed informati
|
|
|
257
254
|
|
|
258
255
|
```typescript
|
|
259
256
|
try {
|
|
260
|
-
const data = await request.sendTo(
|
|
257
|
+
const data = await request.sendTo("https://api.example.com/data").getJson();
|
|
261
258
|
} catch (error) {
|
|
262
259
|
// error will always be a RequestError
|
|
263
|
-
console.log(error.message);
|
|
264
|
-
console.log(error.status);
|
|
265
|
-
console.log(error.url);
|
|
266
|
-
console.log(error.method);
|
|
260
|
+
console.log(error.message); // Error message
|
|
261
|
+
console.log(error.status); // HTTP status code (if available)
|
|
262
|
+
console.log(error.url); // Request URL
|
|
263
|
+
console.log(error.method); // HTTP method
|
|
267
264
|
console.log(error.timeoutError); // Whether it was a timeout
|
|
268
265
|
|
|
269
266
|
// Access the original response if available
|
|
@@ -277,34 +274,37 @@ try {
|
|
|
277
274
|
### Caching Requests
|
|
278
275
|
|
|
279
276
|
```typescript
|
|
280
|
-
import create, { createMemoryStorage, createLocalStorageStorage, createSessionStorageStorage } from
|
|
277
|
+
import create, { createMemoryStorage, createLocalStorageStorage, createSessionStorageStorage } from "create-request";
|
|
281
278
|
|
|
282
279
|
// Simple in-memory caching
|
|
283
|
-
const request = create
|
|
280
|
+
const request = create
|
|
281
|
+
.get()
|
|
284
282
|
.withCache({
|
|
285
283
|
storage: createMemoryStorage(),
|
|
286
|
-
ttl: 60000 // 1 minute in milliseconds
|
|
284
|
+
ttl: 60000, // 1 minute in milliseconds
|
|
287
285
|
})
|
|
288
|
-
.sendTo(
|
|
286
|
+
.sendTo("https://api.example.com/data");
|
|
289
287
|
|
|
290
288
|
// Using localStorage storage
|
|
291
|
-
const request = create
|
|
289
|
+
const request = create
|
|
290
|
+
.get()
|
|
292
291
|
.withCache({
|
|
293
292
|
storage: createLocalStorageStorage(),
|
|
294
293
|
ttl: 5 * 60 * 1000, // 5 minutes
|
|
295
|
-
maxSize:
|
|
296
|
-
keyPrefix:
|
|
294
|
+
maxSize: "1MB",
|
|
295
|
+
keyPrefix: "user-data",
|
|
297
296
|
})
|
|
298
|
-
.sendTo(
|
|
297
|
+
.sendTo("https://api.example.com/users");
|
|
299
298
|
|
|
300
299
|
// Using sessionStorage for per-session caching
|
|
301
|
-
const request = create
|
|
300
|
+
const request = create
|
|
301
|
+
.get()
|
|
302
302
|
.withCache({
|
|
303
303
|
storage: createSessionStorageStorage(),
|
|
304
304
|
maxEntries: 50,
|
|
305
|
-
varyByHeaders: [
|
|
305
|
+
varyByHeaders: ["x-api-version"],
|
|
306
306
|
})
|
|
307
|
-
.sendTo(
|
|
307
|
+
.sendTo("https://api.example.com/data");
|
|
308
308
|
```
|
|
309
309
|
|
|
310
310
|
## Advanced Usage
|
|
@@ -313,14 +313,11 @@ const request = create.get()
|
|
|
313
313
|
|
|
314
314
|
```typescript
|
|
315
315
|
// Create a base authenticated request
|
|
316
|
-
const authRequest = create.get()
|
|
317
|
-
.withBearerToken('token123')
|
|
318
|
-
.withTimeout(5000)
|
|
319
|
-
.withRetries(2);
|
|
316
|
+
const authRequest = create.get().withBearerToken("token123").withTimeout(5000).withRetries(2);
|
|
320
317
|
|
|
321
318
|
// Reuse for different endpoints
|
|
322
|
-
const users = await authRequest.sendTo(
|
|
323
|
-
const products = await authRequest.sendTo(
|
|
319
|
+
const users = await authRequest.sendTo("https://api.example.com/users").getJson();
|
|
320
|
+
const products = await authRequest.sendTo("https://api.example.com/products").getJson();
|
|
324
321
|
```
|
|
325
322
|
|
|
326
323
|
### Request Cancellation
|
|
@@ -328,18 +325,16 @@ const products = await authRequest.sendTo('https://api.example.com/products').ge
|
|
|
328
325
|
```typescript
|
|
329
326
|
const controller = new AbortController();
|
|
330
327
|
|
|
331
|
-
const request = create.get()
|
|
332
|
-
.withTimeout(10000)
|
|
333
|
-
.withAbortController(controller);
|
|
328
|
+
const request = create.get().withTimeout(10000).withAbortController(controller);
|
|
334
329
|
|
|
335
330
|
// Later, cancel the request if needed
|
|
336
331
|
setTimeout(() => controller.abort(), 2000);
|
|
337
332
|
|
|
338
333
|
try {
|
|
339
|
-
const data = await request.sendTo(
|
|
334
|
+
const data = await request.sendTo("https://api.example.com/slow-endpoint").getJson();
|
|
340
335
|
} catch (error) {
|
|
341
336
|
// Check if request was cancelled
|
|
342
|
-
console.log(
|
|
337
|
+
console.log("Request was cancelled:", error.name === "AbortError");
|
|
343
338
|
}
|
|
344
339
|
```
|
|
345
340
|
|
|
@@ -357,25 +352,19 @@ interface ApiResponse {
|
|
|
357
352
|
pagination: {
|
|
358
353
|
total: number;
|
|
359
354
|
page: number;
|
|
360
|
-
}
|
|
355
|
+
};
|
|
361
356
|
}
|
|
362
357
|
|
|
363
358
|
const userRequest = create.get();
|
|
364
359
|
|
|
365
360
|
// Type the full response
|
|
366
|
-
const response = await userRequest
|
|
367
|
-
.sendTo('https://api.example.com/users')
|
|
368
|
-
.getJson<ApiResponse>();
|
|
361
|
+
const response = await userRequest.sendTo("https://api.example.com/users").getJson<ApiResponse>();
|
|
369
362
|
|
|
370
363
|
// Or use getData with type parameters
|
|
371
|
-
const users = await userRequest
|
|
372
|
-
.sendTo('https://api.example.com/users')
|
|
373
|
-
.getData<ApiResponse, User[]>(data => data.users);
|
|
364
|
+
const users = await userRequest.sendTo("https://api.example.com/users").getData<ApiResponse, User[]>(data => data.users);
|
|
374
365
|
|
|
375
366
|
// Or just get the full typed response
|
|
376
|
-
const fullData = await userRequest
|
|
377
|
-
.sendTo('https://api.example.com/users')
|
|
378
|
-
.getData<ApiResponse>();
|
|
367
|
+
const fullData = await userRequest.sendTo("https://api.example.com/users").getData<ApiResponse>();
|
|
379
368
|
|
|
380
369
|
// TypeScript knows the types
|
|
381
370
|
console.log(users[0].name);
|
|
@@ -386,37 +375,39 @@ console.log(users[0].name);
|
|
|
386
375
|
```typescript
|
|
387
376
|
const request = create.get();
|
|
388
377
|
|
|
389
|
-
request
|
|
378
|
+
request
|
|
379
|
+
.sendTo("https://api.example.com/data")
|
|
390
380
|
.then(response => {
|
|
391
|
-
console.log(
|
|
381
|
+
console.log("Status:", response.status);
|
|
392
382
|
return response.getJson();
|
|
393
383
|
})
|
|
394
384
|
.then(data => {
|
|
395
|
-
console.log(
|
|
385
|
+
console.log("Data:", data);
|
|
396
386
|
})
|
|
397
387
|
.catch(error => {
|
|
398
|
-
console.error(
|
|
388
|
+
console.error("Error:", error.message);
|
|
399
389
|
});
|
|
400
390
|
```
|
|
401
391
|
|
|
402
392
|
### Advanced Caching
|
|
403
393
|
|
|
404
394
|
```typescript
|
|
405
|
-
import create, { createMemoryStorage, StorageProvider } from
|
|
395
|
+
import create, { createMemoryStorage, StorageProvider } from "create-request";
|
|
406
396
|
|
|
407
397
|
// Custom key generation
|
|
408
|
-
const request = create
|
|
398
|
+
const request = create
|
|
399
|
+
.get()
|
|
409
400
|
.withCache({
|
|
410
401
|
storage: createMemoryStorage(),
|
|
411
402
|
keyGenerator: (url, method, headers) => {
|
|
412
403
|
// Include user ID from authorization header in the cache key
|
|
413
|
-
const authHeader = headers?.[
|
|
404
|
+
const authHeader = headers?.["Authorization"] || "";
|
|
414
405
|
const userMatch = authHeader.match(/User-(\d+)/);
|
|
415
|
-
const userId = userMatch ? userMatch[1] :
|
|
406
|
+
const userId = userMatch ? userMatch[1] : "anonymous";
|
|
416
407
|
return `${method}:${userId}:${url}`;
|
|
417
|
-
}
|
|
408
|
+
},
|
|
418
409
|
})
|
|
419
|
-
.sendTo(
|
|
410
|
+
.sendTo("https://api.example.com/data");
|
|
420
411
|
```
|
|
421
412
|
|
|
422
413
|
### Implementing Custom Storage Providers
|
|
@@ -424,7 +415,7 @@ const request = create.get()
|
|
|
424
415
|
You can create your own storage provider by implementing the `StorageProvider` interface:
|
|
425
416
|
|
|
426
417
|
```typescript
|
|
427
|
-
import { StorageProvider } from
|
|
418
|
+
import { StorageProvider } from "create-request";
|
|
428
419
|
|
|
429
420
|
// Create a simple custom storage provider
|
|
430
421
|
export function createNamespacedStorage(namespace: string): StorageProvider {
|
|
@@ -461,17 +452,18 @@ export function createNamespacedStorage(namespace: string): StorageProvider {
|
|
|
461
452
|
Object.keys(localStorage)
|
|
462
453
|
.filter(key => key.startsWith(`${namespace}:`))
|
|
463
454
|
.forEach(key => localStorage.removeItem(key));
|
|
464
|
-
}
|
|
455
|
+
},
|
|
465
456
|
};
|
|
466
457
|
}
|
|
467
458
|
|
|
468
459
|
// Usage:
|
|
469
|
-
const request = create
|
|
460
|
+
const request = create
|
|
461
|
+
.get()
|
|
470
462
|
.withCache({
|
|
471
|
-
storage: createNamespacedStorage(
|
|
472
|
-
ttl: 24 * 60 * 60 * 1000 // 24 hours
|
|
463
|
+
storage: createNamespacedStorage("api-cache"),
|
|
464
|
+
ttl: 24 * 60 * 60 * 1000, // 24 hours
|
|
473
465
|
})
|
|
474
|
-
.sendTo(
|
|
466
|
+
.sendTo("https://api.example.com/data");
|
|
475
467
|
```
|
|
476
468
|
|
|
477
469
|
With custom storage providers, you can integrate with any storage system, such as:
|
|
@@ -502,9 +494,9 @@ You can configure CSRF settings globally for all requests:
|
|
|
502
494
|
|
|
503
495
|
```typescript
|
|
504
496
|
// Configure CSRF settings for all requests
|
|
505
|
-
create.config.setCsrfToken(
|
|
506
|
-
create.config.setCsrfHeaderName(
|
|
507
|
-
create.config.setXsrfCookieName(
|
|
497
|
+
create.config.setCsrfToken("your-csrf-token");
|
|
498
|
+
create.config.setCsrfHeaderName("X-CSRF-Token"); // Default header name
|
|
499
|
+
create.config.setXsrfCookieName("XSRF-TOKEN"); // Default cookie name
|
|
508
500
|
create.config.setEnableAntiCsrf(true); // Enable/disable X-Requested-With header
|
|
509
501
|
create.config.setEnableAutoXsrf(true); // Enable/disable automatic cookie-to-header token
|
|
510
502
|
```
|
|
@@ -515,8 +507,9 @@ You can also configure CSRF protection on individual requests:
|
|
|
515
507
|
|
|
516
508
|
```typescript
|
|
517
509
|
// Configure CSRF for a specific request
|
|
518
|
-
const request = create
|
|
519
|
-
.
|
|
510
|
+
const request = create
|
|
511
|
+
.post()
|
|
512
|
+
.withCsrfToken("request-specific-token") // Set a specific token
|
|
520
513
|
.withAntiCsrfHeaders() // Explicitly add X-Requested-With header
|
|
521
514
|
.withoutCsrfProtection(); // Or disable all automatic CSRF protection
|
|
522
515
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-request",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.14",
|
|
4
4
|
"description": "A modern, chainable wrapper for fetch with automatic retries, timeouts, comprehensive error handling, and first-class TypeScript support",
|
|
5
5
|
"main": "dist/library/index.js",
|
|
6
6
|
"module": "dist/library/index.esm.js",
|