@foundatiofx/fetchclient 0.47.0 → 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/esm/src/FetchClient.js +7 -5
- package/package.json +2 -2
- package/readme.md +13 -275
- package/script/src/FetchClient.js +7 -5
- package/types/src/FetchClient.d.ts.map +1 -1
package/esm/src/FetchClient.js
CHANGED
|
@@ -248,7 +248,8 @@ export class FetchClient {
|
|
|
248
248
|
return this.problemToResponse(problem, url);
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
|
-
if (init?.body && typeof init.body === "object"
|
|
251
|
+
if (init?.body && typeof init.body === "object" &&
|
|
252
|
+
!(init.body instanceof FormData)) {
|
|
252
253
|
init.body = JSON.stringify(init.body);
|
|
253
254
|
}
|
|
254
255
|
const accessToken = this.options.accessTokenFunc?.() ?? null;
|
|
@@ -419,11 +420,12 @@ export class FetchClient {
|
|
|
419
420
|
return value;
|
|
420
421
|
}
|
|
421
422
|
buildRequestInit(method, body, options) {
|
|
422
|
-
const
|
|
423
|
-
body
|
|
424
|
-
|
|
423
|
+
const isFormData = typeof FormData !== "undefined" &&
|
|
424
|
+
body instanceof FormData;
|
|
425
|
+
const isJsonLikeObject = body !== undefined && body !== null &&
|
|
426
|
+
typeof body === "object" && !isFormData;
|
|
425
427
|
const headers = {};
|
|
426
|
-
if (
|
|
428
|
+
if (isJsonLikeObject) {
|
|
427
429
|
headers["Content-Type"] = "application/json";
|
|
428
430
|
}
|
|
429
431
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foundatiofx/fetchclient",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A typed JSON fetch client with middleware support for Deno, Node and the browser.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Fetch",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^20.9.0",
|
|
45
45
|
"picocolors": "^1.0.0",
|
|
46
|
-
"zod": "^4.1.
|
|
46
|
+
"zod": "^4.1.11",
|
|
47
47
|
"@deno/shim-deno": "~0.18.0"
|
|
48
48
|
},
|
|
49
49
|
"_generatedBy": "dnt@dev"
|
package/readme.md
CHANGED
|
@@ -6,298 +6,36 @@
|
|
|
6
6
|
[](https://github.com/foundatiofx/foundatio/actions)
|
|
7
7
|
[](https://discord.gg/6HxgFCx)
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
FetchClient is a library that makes it easier to use the fetch API for JSON
|
|
12
|
-
APIs. It provides the following features:
|
|
13
|
-
|
|
14
|
-
- [Typed Response](#typed-response) - Full TypeScript support with strongly
|
|
15
|
-
typed responses
|
|
16
|
-
- [Functional](#functional) - Standalone functions for simple usage
|
|
17
|
-
- [Model Validator](#model-validator) - Built-in validation with Problem Details
|
|
18
|
-
support
|
|
19
|
-
- [Caching](#caching) - Response caching with TTL and programmatic invalidation
|
|
20
|
-
- [Middleware](#middleware) - Extensible middleware pipeline for
|
|
21
|
-
request/response handling
|
|
22
|
-
- [Rate Limiting](#rate-limiting) - Built-in rate limiting with per-domain
|
|
23
|
-
support
|
|
24
|
-
- [Request Timeout](#request-timeout) - Configurable timeouts with AbortSignal
|
|
25
|
-
support
|
|
26
|
-
- [Error Handling](#error-handling) - Comprehensive error handling with Problem
|
|
27
|
-
Details
|
|
28
|
-
- [Authentication](#authentication) - Built-in Bearer token support
|
|
29
|
-
- [Base URL](#base-url) - Global base URL configuration
|
|
30
|
-
- [Loading State](#loading-state) - Track request loading state with events
|
|
9
|
+
FetchClient is a tiny, typed wrapper around `fetch` with JSON helpers, caching,
|
|
10
|
+
middleware, rate limiting, timeouts, and friendly error handling.
|
|
31
11
|
|
|
32
12
|
## Install
|
|
33
13
|
|
|
34
|
-
```
|
|
35
|
-
npm install
|
|
14
|
+
```bash
|
|
15
|
+
npm install @foundatiofx/fetchclient
|
|
36
16
|
```
|
|
37
17
|
|
|
38
|
-
##
|
|
39
|
-
|
|
40
|
-
[API Documentation](https://jsr.io/@foundatiofx/fetchclient/doc)
|
|
41
|
-
|
|
42
|
-
## Usage
|
|
43
|
-
|
|
44
|
-
### Typed Response
|
|
18
|
+
## Quick Example
|
|
45
19
|
|
|
46
20
|
```ts
|
|
47
21
|
import { FetchClient } from "@foundatiofx/fetchclient";
|
|
48
22
|
|
|
49
|
-
type Products = {
|
|
50
|
-
products: Array<{ id: number; name: string }>;
|
|
51
|
-
};
|
|
23
|
+
type Products = { products: Array<{ id: number; name: string }> };
|
|
52
24
|
|
|
53
25
|
const client = new FetchClient();
|
|
54
|
-
const
|
|
26
|
+
const { data } = await client.getJSON<Products>(
|
|
55
27
|
`https://dummyjson.com/products/search?q=iphone&limit=10`,
|
|
56
28
|
);
|
|
57
29
|
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### Functional
|
|
62
|
-
|
|
63
|
-
```ts
|
|
64
|
-
import { getJSON, postJSON } from "@foundatiofx/fetchclient";
|
|
65
|
-
|
|
66
|
-
type Product = { id: number; title: string };
|
|
67
|
-
type Products = { products: Product[] };
|
|
68
|
-
|
|
69
|
-
const response = await postJSON<Product>(
|
|
70
|
-
"https://dummyjson.com/products/add",
|
|
71
|
-
{
|
|
72
|
-
name: "iPhone 13",
|
|
73
|
-
},
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
const product = await getJSON<Product>(
|
|
77
|
-
`https://dummyjson.com/products/${response.data!.id}`,
|
|
78
|
-
);
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Model Validator
|
|
82
|
-
|
|
83
|
-
```ts
|
|
84
|
-
import { FetchClient, setModelValidator } from "@foundatiofx/fetchclient";
|
|
85
|
-
|
|
86
|
-
setModelValidator(async (data: object | null) => {
|
|
87
|
-
// use zod or any other validator
|
|
88
|
-
const problem = new ProblemDetails();
|
|
89
|
-
const d = data as { password: string };
|
|
90
|
-
if (d?.password?.length < 6) {
|
|
91
|
-
problem.errors.password = [
|
|
92
|
-
"Password must be longer than or equal to 6 characters.",
|
|
93
|
-
];
|
|
94
|
-
}
|
|
95
|
-
return problem;
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
const client = new FetchClient();
|
|
99
|
-
const data = {
|
|
100
|
-
email: "test@test",
|
|
101
|
-
password: "test",
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const response = await client.postJSON(
|
|
105
|
-
"https://jsonplaceholder.typicode.com/todos/1",
|
|
106
|
-
data,
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
if (!response.ok) {
|
|
110
|
-
// check response problem
|
|
111
|
-
console.log(response.problem.detail);
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Caching
|
|
116
|
-
|
|
117
|
-
```ts
|
|
118
|
-
import { FetchClient } from "@foundatiofx/fetchclient";
|
|
119
|
-
|
|
120
|
-
type Todo = { userId: number; id: number; title: string; completed: boolean };
|
|
121
|
-
|
|
122
|
-
const client = new FetchClient();
|
|
123
|
-
const response = await client.getJSON<Todo>(
|
|
124
|
-
`https://jsonplaceholder.typicode.com/todos/1`,
|
|
125
|
-
{
|
|
126
|
-
cacheKey: ["todos", "1"],
|
|
127
|
-
cacheDuration: 1000 * 60, // expires in 1 minute
|
|
128
|
-
},
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
// invalidate programmatically
|
|
132
|
-
client.cache.delete(["todos", "1"]);
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Middleware
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
import { FetchClient, useMiddleware } from "@foundatiofx/fetchclient";
|
|
139
|
-
|
|
140
|
-
type Products = {
|
|
141
|
-
products: Array<{ id: number; name: string }>;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
useMiddleware(async (ctx, next) => {
|
|
145
|
-
console.log("starting request");
|
|
146
|
-
await next();
|
|
147
|
-
console.log("completed request");
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
const client = new FetchClient();
|
|
151
|
-
const response = await client.getJSON<Products>(
|
|
152
|
-
`https://dummyjson.com/products/search?q=iphone&limit=10`,
|
|
153
|
-
);
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Rate Limiting
|
|
157
|
-
|
|
158
|
-
```ts
|
|
159
|
-
import { FetchClient, useRateLimit } from "@foundatiofx/fetchclient";
|
|
160
|
-
|
|
161
|
-
// Enable rate limiting globally with 100 requests per minute
|
|
162
|
-
useRateLimit({
|
|
163
|
-
maxRequests: 100,
|
|
164
|
-
windowSeconds: 60,
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
const client = new FetchClient();
|
|
168
|
-
const response = await client.getJSON(
|
|
169
|
-
`https://api.example.com/data`,
|
|
170
|
-
);
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Request Timeout
|
|
174
|
-
|
|
175
|
-
```ts
|
|
176
|
-
import { FetchClient } from "@foundatiofx/fetchclient";
|
|
177
|
-
|
|
178
|
-
const client = new FetchClient();
|
|
179
|
-
|
|
180
|
-
// Set timeout for individual requests
|
|
181
|
-
const response = await client.getJSON(
|
|
182
|
-
`https://api.example.com/data`,
|
|
183
|
-
{ timeout: 5000 }, // 5 seconds
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
// Use AbortSignal for cancellation
|
|
187
|
-
const controller = new AbortController();
|
|
188
|
-
setTimeout(() => controller.abort(), 1000);
|
|
189
|
-
|
|
190
|
-
const response2 = await client.getJSON(
|
|
191
|
-
`https://api.example.com/data`,
|
|
192
|
-
{ signal: controller.signal },
|
|
193
|
-
);
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Error Handling
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
import { FetchClient } from "@foundatiofx/fetchclient";
|
|
200
|
-
|
|
201
|
-
const client = new FetchClient();
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
const response = await client.getJSON(`https://api.example.com/data`);
|
|
205
|
-
} catch (error) {
|
|
206
|
-
// Handle HTTP errors (4xx, 5xx)
|
|
207
|
-
if (error.problem) {
|
|
208
|
-
console.log(error.problem.title);
|
|
209
|
-
console.log(error.problem.detail);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Or handle specific status codes
|
|
214
|
-
const response = await client.getJSON(
|
|
215
|
-
`https://api.example.com/data`,
|
|
216
|
-
{
|
|
217
|
-
expectedStatusCodes: [404, 500],
|
|
218
|
-
errorCallback: (response) => {
|
|
219
|
-
if (response.status === 404) {
|
|
220
|
-
console.log("Resource not found");
|
|
221
|
-
return true; // Don't throw
|
|
222
|
-
}
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
);
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Authentication
|
|
229
|
-
|
|
230
|
-
```ts
|
|
231
|
-
import { FetchClient, setAccessTokenFunc } from "@foundatiofx/fetchclient";
|
|
232
|
-
|
|
233
|
-
// Set global access token function
|
|
234
|
-
setAccessTokenFunc(() => localStorage.getItem("token"));
|
|
235
|
-
|
|
236
|
-
const client = new FetchClient();
|
|
237
|
-
const response = await client.getJSON(`https://api.example.com/data`);
|
|
238
|
-
// Automatically adds Authorization: Bearer <token> header
|
|
30
|
+
console.log(data?.products.length);
|
|
239
31
|
```
|
|
240
32
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
```ts
|
|
244
|
-
import { FetchClient, setBaseUrl } from "@foundatiofx/fetchclient";
|
|
33
|
+
## Documentation
|
|
245
34
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const client = new FetchClient();
|
|
250
|
-
const response = await client.getJSON(`/users/123`);
|
|
251
|
-
// Requests to https://api.example.com/users/123
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Loading State
|
|
255
|
-
|
|
256
|
-
```ts
|
|
257
|
-
import { FetchClient } from "@foundatiofx/fetchclient";
|
|
258
|
-
|
|
259
|
-
const client = new FetchClient();
|
|
260
|
-
|
|
261
|
-
// Track loading state
|
|
262
|
-
client.loading.on((isLoading) => {
|
|
263
|
-
console.log(`Loading: ${isLoading}`);
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
// Check current loading state
|
|
267
|
-
console.log(client.isLoading);
|
|
268
|
-
console.log(client.requestCount);
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
Also, take a look at the tests:
|
|
272
|
-
|
|
273
|
-
[FetchClient Tests](src/FetchClient.test.ts)
|
|
274
|
-
|
|
275
|
-
## Contributing
|
|
276
|
-
|
|
277
|
-
Run tests:
|
|
278
|
-
|
|
279
|
-
```shell
|
|
280
|
-
deno run test
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
Lint code:
|
|
284
|
-
|
|
285
|
-
```shell
|
|
286
|
-
deno lint
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
Format code:
|
|
290
|
-
|
|
291
|
-
```shell
|
|
292
|
-
deno fmt
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
Type check code:
|
|
296
|
-
|
|
297
|
-
```shell
|
|
298
|
-
deno run check
|
|
299
|
-
```
|
|
35
|
+
- Guide & Examples: <https://fetchclient.foundatio.dev>
|
|
36
|
+
- Getting Started, Usage Examples, Contributing
|
|
37
|
+
- API Reference: <https://jsr.io/@foundatiofx/fetchclient/doc>
|
|
300
38
|
|
|
301
|
-
|
|
39
|
+
---
|
|
302
40
|
|
|
303
41
|
MIT © [Foundatio](https://exceptionless.com)
|
|
@@ -251,7 +251,8 @@ class FetchClient {
|
|
|
251
251
|
return this.problemToResponse(problem, url);
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
|
-
if (init?.body && typeof init.body === "object"
|
|
254
|
+
if (init?.body && typeof init.body === "object" &&
|
|
255
|
+
!(init.body instanceof FormData)) {
|
|
255
256
|
init.body = JSON.stringify(init.body);
|
|
256
257
|
}
|
|
257
258
|
const accessToken = this.options.accessTokenFunc?.() ?? null;
|
|
@@ -422,11 +423,12 @@ class FetchClient {
|
|
|
422
423
|
return value;
|
|
423
424
|
}
|
|
424
425
|
buildRequestInit(method, body, options) {
|
|
425
|
-
const
|
|
426
|
-
body
|
|
427
|
-
|
|
426
|
+
const isFormData = typeof FormData !== "undefined" &&
|
|
427
|
+
body instanceof FormData;
|
|
428
|
+
const isJsonLikeObject = body !== undefined && body !== null &&
|
|
429
|
+
typeof body === "object" && !isFormData;
|
|
428
430
|
const headers = {};
|
|
429
|
-
if (
|
|
431
|
+
if (isJsonLikeObject) {
|
|
430
432
|
headers["Content-Type"] = "application/json";
|
|
431
433
|
}
|
|
432
434
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FetchClient.d.ts","sourceRoot":"","sources":["../../src/src/FetchClient.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"FetchClient.d.ts","sourceRoot":"","sources":["../../src/src/FetchClient.ts"],"names":[],"mappings":"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"}
|