Skip to content

Commit 2f947bd

Browse files
PatrickDelancyiamthesiz
authored andcommitted
enable support for accepting an array for request body (#165)
1 parent 91972d9 commit 2f947bd

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

src/__tests__/makeRouteAndOptions.test.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,27 @@ describe('makeRouteAndOptions: general usages', (): void => {
3030
})
3131
})
3232

33+
it('should accept an array for the body of a request', async (): Promise<void> => {
34+
const controller = new AbortController()
35+
const { options } = await makeRouteAndOptions(
36+
{},
37+
'',
38+
'',
39+
HTTPMethod.POST,
40+
controller,
41+
'/test',
42+
[],
43+
)
44+
expect(options).toStrictEqual({
45+
body: '[]',
46+
headers: {
47+
'Content-Type': 'application/json',
48+
},
49+
method: 'POST',
50+
signal: controller.signal,
51+
})
52+
})
53+
3354
it('should correctly modify the options with the request interceptor', async (): Promise<void> => {
3455
const controller = new AbortController()
3556
const interceptors = {
@@ -72,6 +93,18 @@ describe('makeRouteAndOptions: Errors', (): void => {
7293
expect(err.message).toBe('If first argument of get() is an object, you cannot have a 2nd argument. 😜')
7394
}
7495
})
96+
97+
it('should error if 1st and 2nd arg of doFetch are both arrays', async (): Promise<void> => {
98+
const controller = new AbortController()
99+
// AKA, the last 2 arguments of makeRouteAndOptions are both arrays
100+
try {
101+
await makeRouteAndOptions({}, '', '', HTTPMethod.GET, controller, [], [])
102+
} catch(err) {
103+
expect(err.name).toBe('Invariant Violation')
104+
expect(err.message).toBe('If first argument of get() is an object, you cannot have a 2nd argument. 😜')
105+
}
106+
})
107+
75108
// ADD TESTS:
76109
// - request.get('/test', {})
77110
// - request.get('/test', '')

src/makeRouteAndOptions.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { HTTPMethod, Interceptors, ValueOf, RouteAndOptions } from './types'
2-
import { isObject, invariant, isBrowser, isString } from './utils'
2+
import { invariant, isBrowser, isString, isBodyObject } from './utils'
33

44
const { GET } = HTTPMethod
55

@@ -14,11 +14,11 @@ export default async function makeRouteAndOptions(
1414
requestInterceptor?: ValueOf<Pick<Interceptors, 'request'>>
1515
): Promise<RouteAndOptions> {
1616
invariant(
17-
!(isObject(routeOrBody) && isObject(bodyAs2ndParam)),
17+
!(isBodyObject(routeOrBody) && isBodyObject(bodyAs2ndParam)),
1818
`If first argument of ${method.toLowerCase()}() is an object, you cannot have a 2nd argument. 😜`,
1919
)
2020
invariant(
21-
!(method === GET && isObject(routeOrBody)),
21+
!(method === GET && isBodyObject(routeOrBody)),
2222
`You can only have query params as 1st argument of request.get()`,
2323
)
2424
invariant(
@@ -33,15 +33,15 @@ export default async function makeRouteAndOptions(
3333
})()
3434

3535
const body = ((): BodyInit | null => {
36-
if (isObject(routeOrBody)) return JSON.stringify(routeOrBody)
37-
if (isObject(bodyAs2ndParam)) return JSON.stringify(bodyAs2ndParam)
36+
if (isBodyObject(routeOrBody)) return JSON.stringify(routeOrBody)
37+
if (isBodyObject(bodyAs2ndParam)) return JSON.stringify(bodyAs2ndParam)
3838
if (
3939
isBrowser &&
4040
((bodyAs2ndParam as any) instanceof FormData ||
4141
(bodyAs2ndParam as any) instanceof URLSearchParams)
4242
)
4343
return bodyAs2ndParam as string
44-
if (isObject(initialOptions.body)) return JSON.stringify(initialOptions.body)
44+
if (isBodyObject(initialOptions.body)) return JSON.stringify(initialOptions.body)
4545
return null
4646
})()
4747

src/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ export const isString = (x: any): x is string => typeof x === 'string' // eslint
7474
*/
7575
export const isObject = (obj: any): obj is object => Object.prototype.toString.call(obj) === '[object Object]' // eslint-disable-line
7676

77+
/**
78+
* Determines if the given param is an object that can be used as a request body.
79+
* Returns true for native objects or arrays.
80+
* @param obj
81+
*/
82+
export const isBodyObject = (obj: any): boolean => isObject(obj) || Array.isArray(obj)
83+
7784
export const isFunction = (v: any): boolean => typeof v === 'function'
7885

7986
// TODO: come back and fix the "anys" in this http://bit.ly/2Lm3OLi

0 commit comments

Comments
 (0)