11import MockedResponses from './responses/mockedResponses' ;
2- import PendingRequestBody from './pendingRequest/pendingRequestBody' ;
3- import { Options } from './types/options' ;
4- import { HttpMethods } from './types/httpMethods' ;
5- import { RequestAuthorization } from './types/requestAuthorization' ;
6- import { InvalidHeaderFormatException } from './exceptions' ;
7- import { FetchOptions } from './types/fetchOptions' ;
8- import { RequestOptions } from './types/requestOptions' ;
2+ import { FetchOptions , HttpMethods , Options , RequestAuthorization , RequestBodyFormat , RequestOptions } from './types' ;
3+ import {
4+ EmptyRequestBodyException ,
5+ InvalidHeaderFormatException ,
6+ InvalidRequestBodyFormatException ,
7+ } from './exceptions' ;
98
109export default class HttpClient {
1110 /**
@@ -15,6 +14,20 @@ export default class HttpClient {
1514 */
1615 private baseUrl : string = '' ;
1716
17+ /**
18+ * The request body data.
19+ *
20+ * @var {object | string | undefined}
21+ */
22+ private body ?: object | string ;
23+
24+ /**
25+ * The request body format.
26+ *
27+ * @var {RequestBodyFormat}
28+ */
29+ private bodyFormat : RequestBodyFormat = 'String' ;
30+
1831 /**
1932 * The mocked responses instance.
2033 *
@@ -29,13 +42,6 @@ export default class HttpClient {
2942 */
3043 private requestAttempts : number = 0 ;
3144
32- /**
33- * The request body instance.
34- *
35- * @var {PendingRequestBody}
36- */
37- private requestBody : PendingRequestBody ;
38-
3945 /**
4046 * The request options object.
4147 *
@@ -86,7 +92,6 @@ export default class HttpClient {
8692 */
8793 constructor ( baseUrl ?: string , options ?: object ) {
8894 this . mockedResponses = new MockedResponses ( ) ;
89- this . requestBody = new PendingRequestBody ( ) ;
9095
9196 this . setBaseUrl ( baseUrl ) ;
9297 this . setOptions ( options ) ;
@@ -118,7 +123,7 @@ export default class HttpClient {
118123 * @return {this }
119124 */
120125 public asJson ( ) : this {
121- this . requestBody . asJson ( ) ;
126+ this . setBodyFormat ( 'Json' ) ;
122127 this . contentType ( 'application/json' ) ;
123128
124129 return this ;
@@ -130,7 +135,7 @@ export default class HttpClient {
130135 * @return {this }
131136 */
132137 public asForm ( ) : this {
133- this . requestBody . asForm ( ) ;
138+ this . setBodyFormat ( 'FormData' ) ;
134139 this . contentType ( 'multipart/form-data' ) ;
135140
136141 return this ;
@@ -142,7 +147,7 @@ export default class HttpClient {
142147 * @return {this }
143148 */
144149 public asUrlEncoded ( ) : this {
145- this . requestBody . asUrlEncoded ( ) ;
150+ this . setBodyFormat ( 'URLSearchParams' ) ;
146151 this . contentType ( 'application/x-www-form-urlencoded' ) ;
147152
148153 return this ;
@@ -171,8 +176,8 @@ export default class HttpClient {
171176 * @returns {FetchOptions }
172177 */
173178 private buildRequestOptions ( method : HttpMethods ) : FetchOptions {
174- if ( this . requestBody . hasBody ( ) ) {
175- this . requestOptions . body = this . requestBody . parseRequestBody ( ) ;
179+ if ( this . hasBody ( ) ) {
180+ this . requestOptions . body = this . parseRequestBody ( ) ;
176181
177182 if ( ! this . requestOptions . headers ?. has ( 'Content-Type' ) ) {
178183 this . withHeader ( 'Content-Type' , 'text/plain' ) ;
@@ -273,6 +278,15 @@ export default class HttpClient {
273278 return this . sendRequest ( 'GET' ) ;
274279 }
275280
281+ /**
282+ * Check if the body data has been set for the pending request.
283+ *
284+ * @returns {boolean }
285+ */
286+ private hasBody ( ) : boolean {
287+ return this . body !== undefined ;
288+ }
289+
276290 /**
277291 * Check if the headers have been set for the pending request.
278292 *
@@ -311,6 +325,43 @@ export default class HttpClient {
311325 return this . sendRequest ( 'OPTIONS' ) ;
312326 }
313327
328+ /**
329+ * Process request body contents to desirable format.
330+ *
331+ * @throws {EmptyRequestBodyException | InvalidRequestBodyFormatException }
332+ *
333+ * @returns {string | FormData | URLSearchParams }
334+ */
335+ private parseRequestBody ( ) : string | FormData | URLSearchParams {
336+ if ( this . body === undefined ) {
337+ throw new EmptyRequestBodyException ( 'Request body has no data.' ) ;
338+ }
339+
340+ if ( this . bodyFormat === 'FormData' ) {
341+ if ( typeof this . body === 'string' ) {
342+ throw new InvalidRequestBodyFormatException ( 'Cannot parse a string as FormData.' ) ;
343+ }
344+
345+ const formData = new FormData ( ) ;
346+
347+ for ( const [ key , value ] of Object . entries ( this . body ) ) {
348+ formData . append ( key , value ) ;
349+ }
350+
351+ return formData ;
352+ }
353+
354+ if ( this . bodyFormat === 'URLSearchParams' ) {
355+ if ( typeof this . body === 'string' ) {
356+ throw new InvalidRequestBodyFormatException ( 'Cannot parse a string as URLSearchParams.' ) ;
357+ }
358+
359+ return new URLSearchParams ( { ...this . body } ) ;
360+ }
361+
362+ return typeof this . body === 'object' ? JSON . stringify ( this . body ) : this . body ;
363+ }
364+
314365 /**
315366 * Process a PATCH request to the given URL.
316367 *
@@ -460,6 +511,28 @@ export default class HttpClient {
460511 this . baseUrl = baseUrl ;
461512 }
462513
514+ /**
515+ * Specify the body data of the request.
516+ *
517+ * @param {object | string } body
518+ *
519+ * @return {void }
520+ */
521+ private setBody ( body : object | string ) : void {
522+ this . body = body ;
523+ }
524+
525+ /**
526+ * Specify the body format of the request.
527+ *
528+ * @param {RequestBodyFormat } format
529+ *
530+ * @return {void }
531+ */
532+ private setBodyFormat ( format : RequestBodyFormat ) : void {
533+ this . bodyFormat = format ;
534+ }
535+
463536 /**
464537 * Set the default options for the request.
465538 *
@@ -508,7 +581,7 @@ export default class HttpClient {
508581 * @returns {void }
509582 */
510583 private withBody ( body : object | string ) : void {
511- this . requestBody . setBody ( body ) ;
584+ this . setBody ( body ) ;
512585 }
513586
514587 /**
@@ -559,6 +632,8 @@ export default class HttpClient {
559632 * @param {string } key
560633 * @param {RequestOptions } value
561634 *
635+ * @throws {InvalidHeaderFormatException }
636+ *
562637 * @returns {this }
563638 */
564639 public withOption ( key : string , value : RequestOptions ) : this {
0 commit comments