diff --git a/src/core.ts b/src/core.ts index e4af137..88f0eb5 100644 --- a/src/core.ts +++ b/src/core.ts @@ -92,7 +92,11 @@ export const core: Wretch = { let base = this.url(url).options({ method }) // "Jsonify" the body if it is an object and if it is likely that the content type targets json. const contentType = extractContentType(base._options.headers) - const jsonify = typeof body === "object" && (!base._options.headers || !contentType || isLikelyJsonMime(contentType)) + const isFormDataInstance = body => { + const formData = this._config.polyfill("FormData", false) + return formData !== null && body instanceof formData + } + const jsonify = typeof body === "object" && !isFormDataInstance(body) && (!base._options.headers || !contentType || isLikelyJsonMime(contentType)) base = !body ? base : jsonify ? base.json(body, contentType) : diff --git a/test/browser/wretch.spec.js b/test/browser/wretch.spec.js index a7f9674..dcefa4d 100644 --- a/test/browser/wretch.spec.js +++ b/test/browser/wretch.spec.js @@ -134,6 +134,25 @@ describe("Wretch", function () { }) }) + it("should not Jasonify a FormData instance", async function () { + const FormData = wretch()._config.polyfill( + "FormData", + false + ); + + let formData = new FormData() + formData.append("hello", "world") + formData.append("duck", "Muscovy") + + let decoded = await wretch(`${_URL}/formData/decode`) + .post(formData) + .json() + expect(decoded).toEqual({ + hello: "world", + duck: "Muscovy", + }) + }) + it("should perform OPTIONS and HEAD requests", async function () { const optsRes = await wretch(_URL + "/options").opts().res() const optsRes2 = await wretch(_URL + "/options").opts("").res() diff --git a/test/deno/wretch_test.ts b/test/deno/wretch_test.ts index b7715ee..42fa100 100644 --- a/test/deno/wretch_test.ts +++ b/test/deno/wretch_test.ts @@ -163,6 +163,25 @@ describe("Wretch", function () { }) }) + it("should not Jasonify a FormData instance", async function () { + const FormData = wretch()._config.polyfill( + "FormData", + false + ); + + let formData = new FormData() + formData.append("hello", "world") + formData.append("duck", "Muscovy") + + let decoded = await wretch(`${_URL}/formData/decode`) + .post(formData) + .json() + assertEquals(decoded, { + hello: "world", + duck: "Muscovy", + }) + }) + it("should perform OPTIONS and HEAD requests", async function () { const optsRes = await wretch(_URL + "/options").opts().res() const optsRes2 = await wretch(_URL + "/options").opts("").res() diff --git a/test/node/wretch.spec.ts b/test/node/wretch.spec.ts index ff11b8e..8a50c2c 100644 --- a/test/node/wretch.spec.ts +++ b/test/node/wretch.spec.ts @@ -251,6 +251,30 @@ describe("Wretch", function () { }) }) + it("should not Jasonify a FormData instance", async function () { + const FormData = wretch()._config.polyfill( + "FormData", + false + ); + + let formData = new FormData() + formData.append("hello", "world") + formData.append("duck", "Muscovy") + formData.append("duckImage", fs.createReadStream(duckImagePath)) + + let decoded = await wretch(`${_URL}/formData/decode`) + .post(formData) + .json() + expect(decoded).toEqual({ + hello: "world", + duck: "Muscovy", + duckImage: { + data: duckImage, + type: "Buffer" + } + }) + }) + it("should perform OPTIONS and HEAD requests", async function () { const optsRes = await wretch(_URL + "/options").opts().res() const optsRes2 = await wretch(_URL + "/options").opts("").res()