Skip to content

Commit c070c50

Browse files
authored
Merge pull request #135 from wolfpackthatcodes/refactoring/clean-up-code
Refactor of PendingRequestBody code
2 parents 809ed1b + c398b82 commit c070c50

File tree

5 files changed

+109
-135
lines changed

5 files changed

+109
-135
lines changed

code/src/http/httpClient.ts

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import 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

109
export 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 {

code/src/http/pendingRequest/pendingRequestBody.ts

Lines changed: 0 additions & 113 deletions
This file was deleted.

code/src/http/types/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { FetchOptions } from './fetchOptions';
2+
import { HttpMethods } from './httpMethods';
3+
import { Options } from './options';
4+
import { RequestAuthorization } from './requestAuthorization';
5+
import { RequestBodyFormat } from './requestBodyFormat';
6+
import { RequestOptions } from './requestOptions';
7+
8+
export type { FetchOptions, HttpMethods, Options, RequestAuthorization, RequestBodyFormat, RequestOptions };
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export type RequestOptions = boolean | FormData | Headers | object | string | undefined | URLSearchParams;
1+
export type RequestOptions = boolean | FormData | Headers | object | AbortSignal | string | undefined | URLSearchParams;

code/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import HttpClient from '@/http/httpClient';
2+
import { RequestOptions } from '@/http/types';
3+
24
import {
35
EmptyRequestBodyException,
46
InvalidHeaderFormatException,
@@ -13,3 +15,5 @@ export {
1315
InvalidRequestBodyFormatException,
1416
MissingMockedResponseException,
1517
};
18+
19+
export type { RequestOptions };

0 commit comments

Comments
 (0)