Skip to content

Commit 196a248

Browse files
fix(ui): fix image upload
`openapi-fetch` does not handle non-JSON `body`s, always stringifying them, and sets the `content-type` to `application/json`. The patch here does two things: - Do not stringify `body` if it is one of the types that should not be stringified (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#body) - Do not add `content-type: application/json` unless it really is stringified JSON. Upstream issue: openapi-ts/openapi-typescript#1123 I'm not a bit lost on fixing the types and adding tests, so not raising a PR upstream.
1 parent 13a62a6 commit 196a248

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
diff --git a/node_modules/openapi-fetch/dist/index.js b/node_modules/openapi-fetch/dist/index.js
2+
index cd4528a..8976b51 100644
3+
--- a/node_modules/openapi-fetch/dist/index.js
4+
+++ b/node_modules/openapi-fetch/dist/index.js
5+
@@ -1,5 +1,5 @@
6+
// settings & const
7+
-const DEFAULT_HEADERS = {
8+
+const CONTENT_TYPE_APPLICATION_JSON = {
9+
"Content-Type": "application/json",
10+
};
11+
const TRAILING_SLASH_RE = /\/*$/;
12+
@@ -29,18 +29,29 @@ export function createFinalURL(url, options) {
13+
}
14+
return finalURL;
15+
}
16+
+function stringifyBody(body) {
17+
+ if (body instanceof ArrayBuffer || body instanceof File || body instanceof DataView || body instanceof Blob || ArrayBuffer.isView(body) || body instanceof URLSearchParams || body instanceof FormData) {
18+
+ return;
19+
+ }
20+
+
21+
+ if (typeof body === "string") {
22+
+ return body;
23+
+ }
24+
+
25+
+ return JSON.stringify(body);
26+
+ }
27+
+
28+
export default function createClient(clientOptions = {}) {
29+
const { fetch = globalThis.fetch, ...options } = clientOptions;
30+
- const defaultHeaders = new Headers({
31+
- ...DEFAULT_HEADERS,
32+
- ...(options.headers ?? {}),
33+
- });
34+
+ const defaultHeaders = new Headers(options.headers ?? {});
35+
async function coreFetch(url, fetchOptions) {
36+
const { headers, body: requestBody, params = {}, parseAs = "json", querySerializer = defaultSerializer, ...init } = fetchOptions || {};
37+
// URL
38+
const finalURL = createFinalURL(url, { baseUrl: options.baseUrl, params, querySerializer });
39+
+ // Stringify body if needed
40+
+ const stringifiedBody = stringifyBody(requestBody);
41+
// headers
42+
- const baseHeaders = new Headers(defaultHeaders); // clone defaults (don’t overwrite!)
43+
+ const baseHeaders = new Headers(stringifiedBody ? { ...CONTENT_TYPE_APPLICATION_JSON, ...defaultHeaders } : defaultHeaders); // clone defaults (don’t overwrite!)
44+
const headerOverrides = new Headers(headers);
45+
for (const [k, v] of headerOverrides.entries()) {
46+
if (v === undefined || v === null)
47+
@@ -54,7 +65,7 @@ export default function createClient(clientOptions = {}) {
48+
...options,
49+
...init,
50+
headers: baseHeaders,
51+
- body: typeof requestBody === "string" ? requestBody : JSON.stringify(requestBody),
52+
+ body: stringifiedBody ?? requestBody,
53+
});
54+
// handle empty content
55+
// note: we return `{}` because we want user truthy checks for `.data` or `.error` to succeed

invokeai/frontend/web/src/services/api/thunks/image.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ export const imageUploaded = createAppAsyncThunk<
151151
is_intermediate,
152152
session_id,
153153
} = arg;
154+
const formData = new FormData();
155+
formData.append('file', file);
154156
const { data, error, response } = await post('/api/v1/images/', {
155157
params: {
156158
query: {
@@ -161,8 +163,7 @@ export const imageUploaded = createAppAsyncThunk<
161163
},
162164
// TODO: Proper handling of `multipart/form-data` is coming soon, will fix type issues
163165
// https://github.com/drwpow/openapi-typescript/issues/1123
164-
// @ts-ignore
165-
body: file,
166+
body: formData,
166167
});
167168

168169
if (error || !data) {

0 commit comments

Comments
 (0)