Skip to content

Fix handling of input of type FormData for the Fetch client #1008

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/loud-dancers-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"swagger-typescript-api": patch
---

Fix handling of FormData inputs in Fetch HTTP client

Previously, when users passed a `FormData` object directly to the Fetch
client's `multipart/form-data` formatter, it would incorrectly attempt to use
`Object.keys()` on the FormData instance, which returns an empty array. This
caused the FormData to be processed incorrectly.

The fix adds a type check to return FormData instances unchanged, allowing
users to have full control over FormData construction when needed whilst
maintaining backwards compatibility for object inputs. This aligns the Fetch
client behaviour with the existing Axios client implementation.

This resolves issues where users needed to send multipart requests with
multiple entries for the same key, which is only possible with direct FormData
manipulation.
11 changes: 8 additions & 3 deletions templates/base/http-clients/fetch-http-client.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,12 @@ export class HttpClient<SecurityDataType = unknown> {
[ContentType.Json]: (input:any) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
[ContentType.JsonApi]: (input:any) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
[ContentType.Text]: (input:any) => input !== null && typeof input !== "string" ? JSON.stringify(input) : input,
[ContentType.FormData]: (input: any) =>
Object.keys(input || {}).reduce((formData, key) => {
[ContentType.FormData]: (input: any) => {
if (input instanceof FormData) {
return input;
}

return Object.keys(input || {}).reduce((formData, key) => {
const property = input[key];
formData.append(
key,
Expand All @@ -118,7 +122,8 @@ export class HttpClient<SecurityDataType = unknown> {
`${property}`
);
return formData;
}, new FormData()),
}, new FormData());
},
[ContentType.UrlEncoded]: (input: any) => this.toQueryString(input),
}

Expand Down
Loading