11# dr-fetch
22
3- This is one more package for fetching. The difference with other packages is that this one does it right.
3+ This is not just one more wrapper for ` fetch() ` : This package promotes the idea of using customized data-fetching
4+ functions, which is the most maintainable option, and adds features no other wrapper provides to date.
45
56This package:
67
78+ Uses the modern, standardized ` fetch ` function.
89+ Does ** not** throw on non-OK HTTP responses.
9- + ** Allows to fully type all possible HTTP responses depending on the HTTP status code.**
10+ + ** Can fully type all possible HTTP responses depending on the HTTP status code, even non-standard ones like 499.**
11+ + Works in any runtime that implements ` fetch() ` (browsers, NodeJS, etc.).
1012+ Probably the tiniest fetch wrapper you'll ever need.
1113
1214## Does a Non-OK Status Code Warrant an Error?
@@ -33,7 +35,7 @@ smell: `try..catch` is being used as a branching mechanism.
3335npm i dr-fetch
3436```
3537
36- ### Create Custom Fetch Function
38+ ### Create a Custom Fetch Function
3739
3840This is optional and only needed if you need to do something before or after fetching. By far the most common task to
3941do is to add the ` authorization ` header and the ` accept ` header to every call.
@@ -47,10 +49,7 @@ export function myFetch(url: FetchFnUrl, init?: FetchFnInit) {
4749 const token = obtainToken ();
4850 // Make sure there's an object where headers can be added:
4951 init ?? = {};
50- // With setHeaders(), you can add headers to 'init' with a map, an array of tuples, a Headers
51- // object or a POJO object.
5252 setHeaders (init , { Accept: ' application/json' , Authorization: ` Bearer ${token } ` });
53- // Finally, do fetch.
5453 return fetch (url , init );
5554}
5655```
@@ -137,11 +136,29 @@ else {
137136}
138137```
139138
139+ ## Typing For Non-Standard Status Codes
140+
141+ > Since ** v0.8.0**
142+
143+ This library currently supports, out of the box, the OK status codes, client error status codes and server error status
144+ codes that the MDN website list, and are therefore considered standardized.
145+
146+ If you need to type a response based on any other status code not currently supported, just do something like this:
147+
148+ ``` typescript
149+ import { DrFetch , type StatusCode } from " dr-fetch" ;
150+
151+ type MyStatusCode = StatusCode | 499 ;
152+ export default new DrFetch <MyStatusCode >();
153+ ```
154+
155+ You will now be able to use non-standardized status code ` 499 ` to type the response body with ` DrFetch.for<>() ` .
156+
140157## Smarter Uses
141158
142159It is smart to create just one fetcher, configure it, then use it for every fetch call. Because generally speaking,
143- different URL's will carry a different body type, the fetcher object should be kept free of ` for<>() ` calls. However,
144- what if your API is standardized so all status ` 400 ` bodies look the same? Then configure that type:
160+ different URL's will carry a different body type, the fetcher object should be kept free of ` for<>() ` calls. But what
161+ if your API is standardized so all status ` 400 ` bodies look the same? Then configure that type:
145162
146163``` typescript
147164// root-fetcher.ts
@@ -226,7 +243,7 @@ end, call it.
226243
227244These are two helper functions that assist you in writing custom data-fetching functions.
228245
229- If you haven't realized, the ` init ` paramter in ` fetch() ` can have the headers specified in 3 different formats:
246+ If you haven't realized, the ` init ` parameter in ` fetch() ` can have the headers specified in 3 different formats:
230247
231248+ As a ` Headers ` object (an instance of the ` Headers ` class)
232249+ As a POJO object, where the property key is the header name, and the property value is the header value
@@ -261,7 +278,7 @@ export function myFetch(URL: FetchFnUrl, init?: FetchFnInit) {
261278}
262279```
263280
264- This would also get more complex if you account for multi-value headers.
281+ This would also get more complex if you account for multi-value headers. The bottom line is: This is complex.
265282
266283Now the same thing, using ` setHeaders() ` :
267284
@@ -280,14 +297,17 @@ export function myFetch(URL: FetchFnUrl, init?: FetchFnInit) {
280297 return fetch (url , init );
281298}
282299```
300+ > [ !NOTE]
301+ > With ` setHeaders() ` , you can add headers to 'init' with a map, an array of tuples, a ` Headers ` instance or a POJO
302+ > object.
283303
284304The difference is indeed pretty shocking: One line of code and you are done. Also note that adding arrays of values
285305doesn't increase the complexity of the code: It's still one line.
286306
287307### makeIterableHeaders
288308
289309This function is the magic trick that powers the ` setHeaders ` function, and is very handy for troubleshooting or unit
290- testing because it can take a collection of HTTP header specifications in the form of a map, a Headers object, a POJO
310+ testing because it can take a collection of HTTP header specifications in the form of a map, a ` Headers ` object, a POJO
291311object or an array of tuples and return an iterator object that iterates through the definitions in the same way: A
292312list of tuples.
293313
@@ -402,16 +422,14 @@ carry the class instance in the `body` property.
402422 .for<200, DownloadProgress>()
403423 .get('https://example.com/my-video.mp4')
404424 )
405- .body
406- ;
407- }
425+ .body;
426+ }
408427</script>
409428
410429<button type="button" onclick={startDownload}>
411430 Start Download
412431</button>
413432<progress value={download?.progress ?? 0}></progress>
414-
415433```
416434
417435When the button is clicked, the download is started. The custom processor simply creates the new instance of the
0 commit comments