Skip to content

Commit c51203d

Browse files
authored
feat: Support FormData in the TS fetcher generator (#117)
* Support FormData in the TS fetcher generator * Remove header defaults (so that content-type can be unset) * Remove ...headers * Update template so that only multipart/form-data gets stripped when specified
1 parent 13ca9b3 commit c51203d

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

plugins/typescript/src/templates/fetcher.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const getFetcher = ({
2020
: `export type ${pascal(prefix)}FetcherExtraProps = {
2121
/**
2222
* You can add some extra props to your generated fetchers.
23-
*
23+
*
2424
* Note: You need to re-gen after adding the first property to
2525
* have the \`${pascal(prefix)}FetcherExtraProps\` injected in \`${pascal(
2626
prefix
@@ -31,7 +31,7 @@ export const getFetcher = ({
3131
3232
const baseUrl = ${baseUrl ? `"${baseUrl}"` : `""; // TODO add your baseUrl`}
3333
34-
export type ErrorWrapper<TError> =
34+
export type ErrorWrapper<TError> =
3535
| TError
3636
| { status: "unknown"; payload: string };
3737
@@ -54,7 +54,7 @@ export type ${pascal(
5454
export async function ${camel(prefix)}Fetch<
5555
TData,
5656
TError,
57-
TBody extends {} | undefined | null,
57+
TBody extends {} | FormData | undefined | null,
5858
THeaders extends {},
5959
TQueryParams extends {},
6060
TPathParams extends {}
@@ -73,15 +73,27 @@ export async function ${camel(prefix)}Fetch<
7373
TPathParams
7474
>): Promise<TData> {
7575
try {
76+
const requestHeaders: HeadersInit = {
77+
"Content-Type": "application/json",
78+
...headers
79+
};
80+
81+
/**
82+
* As the fetch API is being used, when multipart/form-data is specified
83+
* the Content-Type header must be deleted so that the browser can set
84+
* the correct boundary.
85+
* https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects#sending_files_using_a_formdata_object
86+
*/
87+
if (requestHeaders["Content-Type"].toLowerCase().includes("multipart/form-data")) {
88+
delete requestHeaders["Content-Type"];
89+
}
90+
7691
const response = await window.fetch(\`\${baseUrl}\${resolveUrl(url, queryParams, pathParams)}\`,
7792
{
7893
signal,
7994
method: method.toUpperCase(),
80-
body: body ? JSON.stringify(body) : undefined,
81-
headers: {
82-
"Content-Type": "application/json",
83-
...headers,
84-
},
95+
body: body ? (body instanceof FormData ? body : JSON.stringify(body)) : undefined,
96+
headers: requestHeaders
8597
}
8698
);
8799
if (!response.ok) {

0 commit comments

Comments
 (0)