Skip to content

Commit 0d025d5

Browse files
author
nebarf
committed
Allow to provide unserialized req body to http client
1 parent ed976d4 commit 0d025d5

File tree

7 files changed

+80
-54
lines changed

7 files changed

+80
-54
lines changed

src/client/http-request.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { HttpMethod } from '../enum';
22

33
export interface HttpRequestProps {
44
baseUrl: string;
5-
body?: BodyInit | null;
5+
body?: unknown;
66
credentials?: RequestCredentials;
77
headers?: HeadersInit;
88
maxAge?: number;
@@ -28,7 +28,7 @@ export class HttpRequest implements HttpRequestProps {
2828
/**
2929
* The request body.
3030
*/
31-
private _body?: BodyInit;
31+
private _body?: unknown;
3232

3333
/**
3434
* The request credentials.
@@ -88,7 +88,7 @@ export class HttpRequest implements HttpRequestProps {
8888
return this._baseUrl;
8989
}
9090

91-
get body(): BodyInit | null {
91+
get body(): unknown {
9292
return this._body || null;
9393
}
9494

src/client/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export interface UseHttpClientReturn {
3939
abortableDelete: HttpClientAbortableRequest;
4040
}
4141

42-
export interface HttpRequestOptions<RequestBody = BodyInit> {
42+
export interface HttpRequestOptions<RequestBody = unknown> {
4343
body: RequestBody | null | undefined;
4444
credentials: RequestCredentials | undefined;
4545
headers?: HeadersInit;

src/client/use-http-client.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const useHttpClient = (): UseHttpClientReturn => {
5656
...defaultOptions.headers,
5757
...headers,
5858
},
59-
body: body && requestBodySerializer(body),
59+
body: body ? requestBodySerializer(body) : null,
6060
maxAge: maxAge || 0,
6161
queryParams,
6262
};
@@ -66,6 +66,7 @@ export const useHttpClient = (): UseHttpClientReturn => {
6666
*/
6767
const requestInfo: HttpRequest = new HttpRequest({
6868
...mergedOptions,
69+
body,
6970
baseUrl: computedBaseUrl,
7071
relativeUrl: relativeUrl || '',
7172
});

src/config/request-body-serializer.ts

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,15 @@
1+
import {
2+
isArrayBuffer,
3+
isBlob,
4+
isBoolean,
5+
isFormData,
6+
isNumber,
7+
isObject,
8+
isUrlSearchParams,
9+
} from '../shared';
110
import { ReqBodySerializerReturn } from './types';
211

3-
/**
4-
* Safely assert whether the given value is an ArrayBuffer.
5-
*
6-
* In some execution environments ArrayBuffer is not defined.
7-
*/
8-
function isArrayBuffer(value: unknown): value is ArrayBuffer {
9-
return typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer;
10-
}
11-
12-
/**
13-
* Safely assert whether the given value is a Blob.
14-
*
15-
* In some execution environments Blob is not defined.
16-
*/
17-
function isBlob(value: unknown): value is Blob {
18-
return typeof Blob !== 'undefined' && value instanceof Blob;
19-
}
20-
21-
/**
22-
* Safely assert whether the given value is a FormData instance.
23-
*
24-
* In some execution environments FormData is not defined.
25-
*/
26-
function isFormData(value: unknown): value is FormData {
27-
return typeof FormData !== 'undefined' && value instanceof FormData;
28-
}
29-
30-
/**
31-
* Safely assert whether the given value is a URLSearchParams instance.
32-
*
33-
* In some execution environments URLSearchParams is not defined.
34-
*/
35-
function isUrlSearchParams(value: unknown): value is URLSearchParams {
36-
return typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams;
37-
}
38-
39-
export function serializeRequestBody(body: BodyInit): ReqBodySerializerReturn {
12+
export function serializeRequestBody(body: unknown): ReqBodySerializerReturn {
4013
// If no body is present, no need to serialize it.
4114
if (body === null || typeof body === 'undefined') {
4215
return null;
@@ -54,11 +27,11 @@ export function serializeRequestBody(body: BodyInit): ReqBodySerializerReturn {
5427
return body;
5528
}
5629

57-
// Check whether the body is an object or array, and serialize with JSON if so.
58-
if (typeof body === 'object' || typeof body === 'boolean' || Array.isArray(body)) {
30+
// Check whether the body is an object, an array, a boolean or a number, and serialize with JSON if so.
31+
if (isObject(body) || isBoolean(body) || isNumber(body) || Array.isArray(body)) {
5932
return JSON.stringify(body);
6033
}
6134

62-
// Fall back to unmodified body.
63-
return body;
35+
// Fallback to body string literal.
36+
return `${body}`;
6437
}

src/config/types.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@ import { HttpCacheService, HttpCacheStore } from '../cache';
22
import { ReactElement } from 'react';
33
import { HttpRequestOptions, HttpResponseParser } from '../client';
44

5-
export type ReqBodySerializerReturn =
6-
| string
7-
| null
8-
| ArrayBuffer
9-
| Blob
10-
| FormData
11-
| URLSearchParams;
12-
export type HttpRequestBodySerializer = (body: BodyInit) => ReqBodySerializerReturn;
5+
export type ReqBodySerializerReturn = BodyInit | null;
6+
export type HttpRequestBodySerializer = (body: unknown) => ReqBodySerializerReturn;
137

148
export interface HttpClientConfig {
159
reqOptions: Partial<HttpRequestOptions>;

src/shared/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ export * from './use-compare-callback';
22
export * from './use-compare-effect';
33
export * from './use-compare-memo';
44
export * from './use-compare-ref';
5+
export * from './types';
6+
export * from './type-checker';

src/shared/type-checker.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Safely assert whether the given value is an ArrayBuffer.
3+
*
4+
* In some execution environments ArrayBuffer is not defined.
5+
*/
6+
export function isArrayBuffer(value: unknown): value is ArrayBuffer {
7+
return typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer;
8+
}
9+
10+
/**
11+
* Safely assert whether the given value is a Blob.
12+
*
13+
* In some execution environments Blob is not defined.
14+
*/
15+
export function isBlob(value: unknown): value is Blob {
16+
return typeof Blob !== 'undefined' && value instanceof Blob;
17+
}
18+
19+
/**
20+
* Safely assert whether the given value is a FormData instance.
21+
*
22+
* In some execution environments FormData is not defined.
23+
*/
24+
export function isFormData(value: unknown): value is FormData {
25+
return typeof FormData !== 'undefined' && value instanceof FormData;
26+
}
27+
28+
/**
29+
* Safely assert whether the given value is a URLSearchParams instance.
30+
*
31+
* In some execution environments URLSearchParams is not defined.
32+
*/
33+
export function isUrlSearchParams(value: unknown): value is URLSearchParams {
34+
return typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams;
35+
}
36+
37+
/**
38+
* Safely assert whether the given value is a number.
39+
*/
40+
export function isNumber(value: unknown): value is number {
41+
return typeof value === 'number';
42+
}
43+
44+
/**
45+
* Safely assert whether the given value is a boolean.
46+
*/
47+
export function isBoolean(value: unknown): value is number {
48+
return typeof value === 'boolean';
49+
}
50+
51+
/**
52+
* Safely assert whether the given value is an object.
53+
*/
54+
export function isObject(value: unknown): value is number {
55+
return typeof value === 'object';
56+
}

0 commit comments

Comments
 (0)