diff --git a/packages/better-fetch/src/test/fetch.test.ts b/packages/better-fetch/src/test/fetch.test.ts index 5bdde68..83a08da 100644 --- a/packages/better-fetch/src/test/fetch.test.ts +++ b/packages/better-fetch/src/test/fetch.test.ts @@ -601,3 +601,26 @@ describe("url", () => { expect(url.toString()).toBe("http://localhost:4000/test?foo=bar"); }); }); + +describe("form data", async () => { + it("should parse json to form data", async () => { + const { data } = await betterFetch("/echo", { + body: { + name: "John Doe", + age: 30, + }, + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + onRequest(context) { + console.log(context.body); + }, + customFetchImpl: async (req, init) => { + return new Response(JSON.stringify(init?.body), { + status: 200, + }); + }, + }); + expect(data).toBe("name=John+Doe&age=30"); + }); +}); diff --git a/packages/better-fetch/src/utils.ts b/packages/better-fetch/src/utils.ts index d012f1e..e4b0c88 100644 --- a/packages/better-fetch/src/utils.ts +++ b/packages/better-fetch/src/utils.ts @@ -206,6 +206,16 @@ export function getBody(options?: BetterFetchOption) { return JSON.stringify(options.body); } + if ( + headers.has("content-type") && + headers.get("content-type") === "application/x-www-form-urlencoded" + ) { + if (isJSONSerializable(options.body)) { + return new URLSearchParams(options.body).toString(); + } + return options.body; + } + return options.body; } @@ -265,7 +275,7 @@ export async function parseStandardSchema( schema: TSchema, input: StandardSchemaV1.InferInput, ): Promise> { - let result = await schema["~standard"].validate(input); + const result = await schema["~standard"].validate(input); if (result.issues) { throw new ValidationError(result.issues);