Skip to content

Commit

Permalink
fix: Detect more kinds of FormData objects (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
runeh authored Jun 23, 2021
1 parent b72d07d commit 6182413
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 3 deletions.
15 changes: 13 additions & 2 deletions src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import FormData from 'form-data';
import nock from 'nock';
import { Headers } from 'node-fetch';
import { buildCall } from '../index';
import { buildUrl, unwrapError } from '../common';
import { buildUrl, isFormData, unwrapError } from '../common';
import invariant from 'ts-invariant';
import { createReadStream } from 'fs';
import { TypicalHttpError } from '../types';
Expand Down Expand Up @@ -1195,7 +1195,6 @@ describe('call builder', () => {
.method('get')
.mapError((_) => 'error!')
.mapError(async (err) => {
console.log(err);
await new Promise((res) => setTimeout(res, 1));
return err.toUpperCase();
})
Expand Down Expand Up @@ -1311,4 +1310,16 @@ describe('buildUrl', () => {
expect(scope.isDone()).toEqual(true);
});
});

describe('isFormData', () => {
it('smoke test', () => {
expect(isFormData(Buffer.from('asdf'))).toEqual(false);
expect(isFormData(new URLSearchParams())).toEqual(false);
expect(isFormData(undefined)).toEqual(false);
expect(isFormData(new FormData())).toEqual(true);
expect(
isFormData({ toString: () => '[object FormData]' } as any),
).toEqual(true);
});
});
});
17 changes: 16 additions & 1 deletion src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ import { BodyInit, Headers, HeadersInit } from 'node-fetch';
import invariant from 'ts-invariant';
import { BodyType, CallRecord, QueryParam, TypicalWrappedError } from './types';

/**
* Tries to detect if something is a FormData object. Since the consuming code
* may be using a different version of form-data than this lib, we can't trust
* the instanceof check to always work. The `form-data` package explicitly sets
* the return value of `someFormData.toString()` to `[object FormData]`, so we
* use that for the extra check.
* @param thing
* @returns
*/
export function isFormData(thing: BodyType | undefined): thing is FormData {
return thing == null
? false
: thing instanceof FormData || thing.toString() === '[object FormData]';
}

export function getBodyInfo(data: BodyType | undefined): {
body?: BodyInit;
contentType?: string;
Expand All @@ -17,7 +32,7 @@ export function getBodyInfo(data: BodyType | undefined): {
Buffer.isBuffer(data) ||
data instanceof Readable ||
data instanceof URLSearchParams ||
data instanceof FormData
isFormData(data)
) {
return { body: data };
} else {
Expand Down

0 comments on commit 6182413

Please sign in to comment.