fetch-request-browser 1.0.6 → 1.0.8

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 CHANGED
@@ -22,7 +22,7 @@ Send a `GET` request that will retry (up to 3 times) on failure to [HTTPBin](htt
22
22
  ```typescript
23
23
  import { sendGET } from 'fetch-request-browser';
24
24
 
25
- await sendGET(
25
+ await sendGET<IHTTPBinResponse>(
26
26
  'https://httpbin.org/get?someUid=5',
27
27
  {
28
28
  requestOptions: {
@@ -65,7 +65,7 @@ Send a `POST` request that will retry (up to 3 times) on failure to [HTTPBin](ht
65
65
  ```typescript
66
66
  import { sendGET } from 'fetch-request-browser';
67
67
 
68
- await sendPOST(
68
+ await sendPOST<IHTTPBinResponse>(
69
69
  'https://httpbin.org/post?id=1',
70
70
  {
71
71
  requestOptions: {
@@ -126,7 +126,7 @@ await sendPOST(
126
126
 
127
127
  Builds and sends an HTTP Request based on the provided input and options.
128
128
  ```typescript
129
- await send(
129
+ await send<IHTTPBinResponse>(
130
130
  'https://httpbin.org/get?foo=hey&bar=123', {
131
131
  requestOptions: { method: 'GET' }
132
132
  }
@@ -165,7 +165,7 @@ await sendPOST(
165
165
 
166
166
  Builds and sends a `GET` HTTP Request based on the provided input and options.
167
167
  ```typescript
168
- await sendGET('https://httpbin.org/get?foo=hey&bar=123');
168
+ await sendGET<IHTTPBinResponse>('https://httpbin.org/get?foo=hey&bar=123');
169
169
  // {
170
170
  // code: 200,
171
171
  // headers: Headers {
@@ -200,7 +200,7 @@ await sendPOST(
200
200
 
201
201
  Builds and sends a `POST` HTTP Request based on the provided input and options.
202
202
  ```typescript
203
- await sendPOST(
203
+ await sendPOST<IHTTPBinResponse>(
204
204
  'https://httpbin.org/post',
205
205
  {
206
206
  requestOptions: {
@@ -251,7 +251,7 @@ await sendPOST(
251
251
 
252
252
  Builds and sends a `PUT` HTTP Request based on the provided input and options.
253
253
  ```typescript
254
- await sendPUT(
254
+ await sendPUT<IHTTPBinResponse>(
255
255
  'https://httpbin.org/put',
256
256
  {
257
257
  requestOptions: {
@@ -302,7 +302,7 @@ await sendPOST(
302
302
 
303
303
  Builds and sends a `PATCH` HTTP Request based on the provided input and options.
304
304
  ```typescript
305
- await sendPATCH(
305
+ await sendPATCH<IHTTPBinResponse>(
306
306
  'https://httpbin.org/patch',
307
307
  {
308
308
  requestOptions: {
@@ -353,7 +353,7 @@ await sendPOST(
353
353
 
354
354
  Builds and sends a `DELETE` HTTP Request based on the provided input and options.
355
355
  ```typescript
356
- await sendDELETE('https://httpbin.org/delete?id=1');
356
+ await sendDELETE<IHTTPBinResponse>('https://httpbin.org/delete?id=1');
357
357
  // {
358
358
  // code: 200,
359
359
  // headers: Headers {
@@ -415,15 +415,6 @@ await sendPOST(
415
415
  ```
416
416
  </details>
417
417
 
418
- <details>
419
- <summary><code>IRequestMethod</code></summary>
420
-
421
- The HTTP Methods supported by this library. To make use of a different one, pass the method name directly in the request options.
422
- ```typescript
423
- type IRequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
424
- ```
425
- </details>
426
-
427
418
  <details>
428
419
  <summary><code>RequestInit</code></summary>
429
420
 
@@ -465,11 +456,15 @@ await sendPOST(
465
456
  <summary><code>IRequestOptions</code></summary>
466
457
 
467
458
  The options that can be applied when sending a Fetch Request.
468
- IMPORTANT: the reason RequestInit is extended is because in the original type, the body property does not accept plain objects. Even though this makes sense, utilities so the Request's body is always instantiated with a string.
459
+ IMPORTANT: the reason RequestInit is extended is because in the original type, the body property does not accept plain objects. Even though this makes sense, utilities so the Request's body is always going to have a valid type.
469
460
  ```typescript
470
- interface IRequestOptions extends RequestInit {
461
+ interface IRequestOptions extends Omit<RequestInit, 'body'> {
471
462
  method: IRequestMethod; // this lib only makes use of these methods
472
- body: any;
463
+ body: BodyInit | Record<string, unknown> | Array<unknown> | null;
464
+ }
465
+
466
+ interface IProcessedRequestOptions extends RequestInit {
467
+ method: IRequestMethod;
473
468
  }
474
469
  ```
475
470
  </details>
@@ -515,11 +510,11 @@ await sendPOST(
515
510
  </details>
516
511
 
517
512
  <details>
518
- <summary><code>IRequestResponse</code></summary>
513
+ <summary><code>IRequestResponse<T></code></summary>
519
514
 
520
515
  The object containing the result of the Request.
521
516
  ```typescript
522
- interface IRequestResponse {
517
+ interface IRequestResponse<T> {
523
518
  // the HTTP status code extracted from the Response
524
519
  code: number;
525
520
 
@@ -527,7 +522,7 @@ await sendPOST(
527
522
  headers: Headers;
528
523
 
529
524
  // the data extracted from the Response Instance
530
- data: any;
525
+ data: T;
531
526
  }
532
527
  ```
533
528
  </details>
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ import { IRequestInput, IRequestMethod, IRequestOptions, IResponseDataType, IOpt
14
14
  * - CONTENT_TYPE_MISSMATCH: if the Content-Type Headers don't match
15
15
  * - INVALID_RESPONSE_DTYPE: if the data type is not supported by the Response Instance
16
16
  */
17
- declare const send: (input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse>;
17
+ declare const send: <T>(input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse<T>>;
18
18
  /**
19
19
  * Builds and sends a GET HTTP Request based on the provided input and options.
20
20
  * IMPORTANT: The browser environment can be highly unreliable as the user can physically move
@@ -33,7 +33,7 @@ declare const send: (input: IRequestInput, options?: Partial<IOptions>, retryDel
33
33
  * - CONTENT_TYPE_MISSMATCH: if the Content-Type Headers don't match
34
34
  * - INVALID_RESPONSE_DTYPE: if the data type is not supported by the Response Instance
35
35
  */
36
- declare const sendGET: (input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse>;
36
+ declare const sendGET: <T>(input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse<T>>;
37
37
  /**
38
38
  * Builds and sends a POST HTTP Request based on the provided input and options.
39
39
  * @param input
@@ -49,7 +49,7 @@ declare const sendGET: (input: IRequestInput, options?: Partial<IOptions>, retry
49
49
  * - CONTENT_TYPE_MISSMATCH: if the Content-Type Headers don't match
50
50
  * - INVALID_RESPONSE_DTYPE: if the data type is not supported by the Response Instance
51
51
  */
52
- declare const sendPOST: (input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse>;
52
+ declare const sendPOST: <T>(input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse<T>>;
53
53
  /**
54
54
  * Builds and sends a PUT HTTP Request based on the provided input and options.
55
55
  * @param input
@@ -65,7 +65,7 @@ declare const sendPOST: (input: IRequestInput, options?: Partial<IOptions>, retr
65
65
  * - CONTENT_TYPE_MISSMATCH: if the Content-Type Headers don't match
66
66
  * - INVALID_RESPONSE_DTYPE: if the data type is not supported by the Response Instance
67
67
  */
68
- declare const sendPUT: (input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse>;
68
+ declare const sendPUT: <T>(input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse<T>>;
69
69
  /**
70
70
  * Builds and sends a PATCH HTTP Request based on the provided input and options.
71
71
  * @param input
@@ -81,7 +81,7 @@ declare const sendPUT: (input: IRequestInput, options?: Partial<IOptions>, retry
81
81
  * - CONTENT_TYPE_MISSMATCH: if the Content-Type Headers don't match
82
82
  * - INVALID_RESPONSE_DTYPE: if the data type is not supported by the Response Instance
83
83
  */
84
- declare const sendPATCH: (input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse>;
84
+ declare const sendPATCH: <T>(input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse<T>>;
85
85
  /**
86
86
  * Builds and sends a DELETE HTTP Request based on the provided input and options.
87
87
  * @param input
@@ -97,5 +97,5 @@ declare const sendPATCH: (input: IRequestInput, options?: Partial<IOptions>, ret
97
97
  * - CONTENT_TYPE_MISSMATCH: if the Content-Type Headers don't match
98
98
  * - INVALID_RESPONSE_DTYPE: if the data type is not supported by the Response Instance
99
99
  */
100
- declare const sendDELETE: (input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse>;
100
+ declare const sendDELETE: <T>(input: IRequestInput, options?: Partial<IOptions>, retryDelaySchedule?: number[]) => Promise<IRequestResponse<T>>;
101
101
  export { type IRequestInput, type IRequestMethod, type IRequestOptions, type IResponseDataType, type IOptions, type IRequestResponse, send, sendGET, sendPOST, sendPUT, sendPATCH, sendDELETE, };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{extractMessage}from"error-message-utils";import{isArrayValid,delay}from"web-utils-kit";import{buildOptions,buildRequest,extractResponseData}from"./utils/utils.js";import{validateResponse}from"./validations/validations.js";const __executeSend=async(e,s)=>{const t=buildOptions(s),n=buildRequest(e,t.requestOptions),r=await fetch(n);return validateResponse(n,r,t),r.redirected&&console.warn(`The request sent to '${n.url}' was redirected. Please update the implementation to avoid future redirections.`),{code:r.status,headers:r.headers,data:await extractResponseData(r,t.responseDataType)}},send=async(e,s,t)=>{try{return await __executeSend(e,s)}catch(n){if(extractMessage(n).includes("429")||!isArrayValid(t))throw n;return await delay(t[0]),send(e,s,t.slice(1))}},sendGET=async(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"GET"}},t),sendPOST=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"POST"}},t),sendPUT=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"PUT"}},t),sendPATCH=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"PATCH"}},t),sendDELETE=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"DELETE"}},t);export{send,sendGET,sendPOST,sendPUT,sendPATCH,sendDELETE};
1
+ import{extractMessage}from"error-message-utils";import{isArrayValid,delay}from"web-utils-kit";import{buildOptions,buildRequest,extractResponseData}from"./utils/utils.js";import{validateResponse}from"./validations/validations.js";const __executeSend=async(e,s)=>{const t=buildOptions(s),n=buildRequest(e,t.requestOptions),r=await fetch(n);return validateResponse(n,r,t),r.redirected&&console.warn(`The request sent to '${n.url}' was redirected. Please update the implementation to avoid future redirections.`),{code:r.status,headers:r.headers,data:await extractResponseData(r,t.responseDataType)}},send=async(e,s,t)=>{try{return await __executeSend(e,s)}catch(n){if(extractMessage(n).includes("429")||!isArrayValid(t))throw n;return await delay(t[0]),send(e,s,t.slice(1))}},sendGET=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"GET"}},t),sendPOST=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"POST"}},t),sendPUT=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"PUT"}},t),sendPATCH=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"PATCH"}},t),sendDELETE=(e,s,t)=>send(e,{...s,requestOptions:{...s?.requestOptions,method:"DELETE"}},t);export{send,sendGET,sendPOST,sendPUT,sendPATCH,sendDELETE};
@@ -8,11 +8,14 @@ type IRequestInput = string | URL;
8
8
  * The options that can be applied when sending a Fetch Request.
9
9
  * IMPORTANT: the reason RequestInit is extended is because in the original type, the body property
10
10
  * does not accept plain objects. Even though this makes sense, the body is processed in the
11
- * utilities so the Request's body is always instantiated with a string.
11
+ * utilities so the Request's body is always going to have a valid type.
12
12
  */
13
- interface IRequestOptions extends RequestInit {
13
+ interface IRequestOptions extends Omit<RequestInit, 'body'> {
14
+ method: IRequestMethod;
15
+ body: BodyInit | Record<string, unknown> | Array<unknown> | null;
16
+ }
17
+ interface IProcessedRequestOptions extends RequestInit {
14
18
  method: IRequestMethod;
15
- body: any;
16
19
  }
17
20
  /**
18
21
  * Request Method
@@ -25,11 +28,6 @@ type IRequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
25
28
  * The type of data that will be extracted from the HTTP Response body.
26
29
  */
27
30
  type IResponseDataType = 'arrayBuffer' | 'blob' | 'formData' | 'json' | 'text';
28
- /**
29
- * Response Data
30
- * The format of the data that can be extracted from the Response object.
31
- */
32
- type IResponseData<T> = T extends 'arrayBuffer' ? ArrayBuffer : T extends 'blob' ? Blob : T extends 'formData' ? FormData : T extends 'json' ? any : T extends 'text' ? string : never;
33
31
  /**
34
32
  * Options
35
33
  * The options object that can be passed and used for any request.
@@ -54,9 +52,9 @@ interface IOptions {
54
52
  * Request Response
55
53
  * The object containing the result of the Request.
56
54
  */
57
- interface IRequestResponse {
55
+ interface IRequestResponse<T> {
58
56
  code: number;
59
57
  headers: Headers;
60
- data: any;
58
+ data: T;
61
59
  }
62
- export type { IRequestInput, IRequestOptions, IRequestMethod, IResponseDataType, IResponseData, IOptions, IRequestResponse, };
60
+ export type { IRequestInput, IRequestOptions, IProcessedRequestOptions, IRequestMethod, IResponseDataType, IOptions, IRequestResponse, };
@@ -1,4 +1,4 @@
1
- import { IRequestInput, IResponseDataType, IResponseData, IRequestOptions, IOptions } from '../shared/types.js';
1
+ import { IRequestInput, IRequestOptions, IResponseDataType, IOptions } from '../shared/types.js';
2
2
  /**
3
3
  * Builds the Request Instance based on given input and options.
4
4
  * @param input
@@ -18,7 +18,7 @@ declare const buildRequest: (input: IRequestInput, options?: Partial<IRequestOpt
18
18
  * @throws
19
19
  * - INVALID_RESPONSE_DTYPE: if the data type is not supported by the Response Instance
20
20
  */
21
- declare const extractResponseData: <T extends IResponseDataType>(res: Response, dType: T) => Promise<IResponseData<T>>;
21
+ declare const extractResponseData: <T>(res: Response, dType: IResponseDataType) => Promise<T>;
22
22
  /**
23
23
  * Builds the main options object based on given args (if any).
24
24
  * @param options
@@ -1 +1 @@
1
- import{encodeError,isEncodedError}from"error-message-utils";import{ERRORS}from"../shared/errors.js";const __buildRequestInput=e=>{if(e instanceof URL)return e;try{return new URL(e)}catch(e){throw new Error(encodeError(e,ERRORS.INVALID_REQUEST_URL))}},__buildRequestHeaders=(e,r)=>{let t;if(e&&"object"==typeof e)try{t=new Headers(e)}catch(e){throw new Error(encodeError(e,ERRORS.INVALID_REQUEST_HEADERS))}else t=e instanceof Headers?e:"GET"===r?new Headers({Accept:"application/json"}):new Headers({Accept:"application/json","Content-Type":"application/json"});return t.has("Accept")||t.append("Accept","application/json"),t.has("Content-Type")||"GET"===r||t.append("Content-Type","application/json"),t},__buildRequestBody=e=>e?"object"==typeof e?JSON.stringify(e):e:null,__buildRequestOptions=(e={})=>{const r=e.method??"GET";return{method:r,mode:e.mode??"cors",cache:e.cache??"default",credentials:e.credentials??"same-origin",headers:__buildRequestHeaders(e.headers,r),priority:e.priority??"auto",redirect:e.redirect??"follow",referrer:e.referrer??"about:client",referrerPolicy:e.referrerPolicy??"no-referrer-when-downgrade",signal:e.signal,integrity:e.integrity||"",keepalive:e.keepalive??!1,body:"GET"===r?null:__buildRequestBody(e.body)}},buildRequest=(e,r)=>{try{return new Request(__buildRequestInput(e),__buildRequestOptions(r))}catch(e){if(isEncodedError(e))throw e;throw new Error(encodeError(e,ERRORS.INVALID_REQUEST_OPTIONS))}},extractResponseData=async(e,r)=>{switch(r){case"arrayBuffer":return e.arrayBuffer();case"blob":return e.blob();case"formData":return e.formData();case"json":return e.json();case"text":return e.text();default:throw new Error(encodeError(`The provided response data type '${r}' is invalid.`,ERRORS.INVALID_RESPONSE_DTYPE))}},buildOptions=(e={})=>({requestOptions:e.requestOptions,responseDataType:e.responseDataType??"json",acceptableStatusCodes:e.acceptableStatusCodes,acceptableStatusCodesRange:e.acceptableStatusCodesRange??{min:200,max:299},skipStatusCodeValidation:e.skipStatusCodeValidation??!1});export{buildRequest,extractResponseData,buildOptions};
1
+ import{encodeError,isEncodedError}from"error-message-utils";import{isArrayValid,isObjectValid}from"web-utils-kit";import{ERRORS}from"../shared/errors.js";const __buildRequestInput=e=>{if(e instanceof URL)return e;try{return new URL(e)}catch(e){throw new Error(encodeError(e,ERRORS.INVALID_REQUEST_URL))}},__buildRequestHeaders=(e,r)=>{let t;if(e&&"object"==typeof e)try{t=new Headers(e)}catch(e){throw new Error(encodeError(e,ERRORS.INVALID_REQUEST_HEADERS))}else t=e instanceof Headers?e:"GET"===r?new Headers({Accept:"application/json"}):new Headers({Accept:"application/json","Content-Type":"application/json"});return t.has("Accept")||t.append("Accept","application/json"),t.has("Content-Type")||"GET"===r||t.append("Content-Type","application/json"),t},__buildRequestBody=e=>e?isObjectValid(e,!0)||isArrayValid(e,!0)?JSON.stringify(e):e:null,__buildRequestOptions=(e={})=>{const r=e.method??"GET";return{method:r,mode:e.mode??"cors",cache:e.cache??"default",credentials:e.credentials??"same-origin",headers:__buildRequestHeaders(e.headers,r),priority:e.priority??"auto",redirect:e.redirect??"follow",referrer:e.referrer??"about:client",referrerPolicy:e.referrerPolicy??"no-referrer-when-downgrade",signal:e.signal,integrity:e.integrity||"",keepalive:e.keepalive??!1,body:"GET"===r?null:__buildRequestBody(e.body)}},buildRequest=(e,r)=>{try{return new Request(__buildRequestInput(e),__buildRequestOptions(r))}catch(e){if(isEncodedError(e))throw e;throw new Error(encodeError(e,ERRORS.INVALID_REQUEST_OPTIONS))}},extractResponseData=async(e,r)=>{switch(r){case"arrayBuffer":return e.arrayBuffer();case"blob":return e.blob();case"formData":return e.formData();case"json":return e.json();case"text":return e.text();default:throw new Error(encodeError(`The provided response data type '${r}' is invalid.`,ERRORS.INVALID_RESPONSE_DTYPE))}},buildOptions=(e={})=>({requestOptions:e.requestOptions,responseDataType:e.responseDataType??"json",acceptableStatusCodes:e.acceptableStatusCodes,acceptableStatusCodesRange:e.acceptableStatusCodesRange??{min:200,max:299},skipStatusCodeValidation:e.skipStatusCodeValidation??!1});export{buildRequest,extractResponseData,buildOptions};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fetch-request-browser",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "The fetch-request-browser package makes working with external APIs simple and efficient. This intuitive wrapper leverages the power of the Fetch API, providing a clean and concise interface for your API interactions.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",