diff --git a/src/fetch/index.ts b/src/fetch/index.ts index a58de68..64b28a1 100644 --- a/src/fetch/index.ts +++ b/src/fetch/index.ts @@ -62,14 +62,6 @@ export const edenFetch = > endpoint = endpoint.replace(`:${key}`, value as string) }) - // @ts-ignore - const contentType = options.headers?.['Content-Type'] - - if (!contentType || contentType === 'application/json') - try { - body = JSON.stringify(body) - } catch (error) {} - const fetch = config?.fetcher || globalThis.fetch const nonNullishQuery = query @@ -85,14 +77,19 @@ export const edenFetch = > : '' const requestUrl = `${server}${endpoint}${queryStr}` - const headers = body - ? { - 'content-type': 'application/json', - // @ts-ignore - ...options.headers - } - : // @ts-ignore - options.headers + const headers = new Headers(options.headers || {}) + const contentType = headers.get('content-type') + if ( + !(body instanceof FormData) && + !(body instanceof URLSearchParams) && + (!contentType || contentType === 'application/json') + ) { + try { + body = JSON.stringify(body) + if (!contentType) headers.set('content-type', 'application/json') + } catch (error) {} + } + const init = { ...options, // @ts-ignore diff --git a/test/fetch.test.ts b/test/fetch.test.ts index 15f7d32..4a67c4f 100644 --- a/test/fetch.test.ts +++ b/test/fetch.test.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { Elysia, t } from 'elysia' +import { Elysia, form, t } from 'elysia' import { edenFetch } from '../src' import { describe, expect, it, beforeAll } from 'bun:test' @@ -13,6 +13,17 @@ const json = { const app = new Elysia() .get('/', () => 'hi') .post('/', () => 'post') + .post('/form-data', ({ body }) => { + return { + file: body.file.name, + size: body.file.size + } + }, { + body: t.Object({ + file: t.File() + }), + parse: 'formdata' + }) .get('/json', ({ body }) => json) .get( '/json-utf8', @@ -165,6 +176,22 @@ describe('Eden Fetch', () => { expect(data).toEqual(false) }) + it('parse form data', async () => { + const formData = new FormData(); + formData.append('file', new File(['test'], 'test.txt', { type: 'text/plain' })) + + const { data } = await fetch('/form-data', { + method: 'POST', + // @ts-ignore + body: formData + }) + + expect(data).toEqual({ + file: 'test.txt', + size: 4 + }) + }) + // ! FIX ME // it('handle throw error', async () => { // const { data, error } = await fetch('/throw-error', {