acacode / swagger-typescript-api

Generate the API Client for Fetch or Axios from an OpenAPI Specification
MIT License
3.27k stars 354 forks source link

'multipart/form-data' formatter isn't recursive #462

Open Clovel opened 1 year ago

Clovel commented 1 year ago

When using a multipart/form-data content type, the generated API code provides a private function to format certain types : contentFormatters.

Currently on version 12.0.2 the function is :

private contentFormatters: Record<ContentType, (input: any) => any> = {
  [ContentType.Json]: (input: any) =>
    input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
  [ContentType.FormData]: (input: any) =>
    Object.keys(input || {}).reduce((formData, key) => {
      const property = input[key];
      formData.append(
        key,
        property instanceof Blob
          ? property
          : typeof property === "object" && property !== null
          ? JSON.stringify(property)
          : `${property}`,
      );
      return formData;
    }, new FormData()),
  [ContentType.UrlEncoded]: (input: any) => this.toQueryString(input),
};

If we concentrate on the ContentType.FormData section of the formatter, we have

(input: any) =>
    Object.keys(input || {}).reduce((formData, key) => {
      const property = input[key];
      formData.append(
        key,
        property instanceof Blob
          ? property
          : typeof property === "object" && property !== null
          ? JSON.stringify(property)
          : `${property}`,
      );
      return formData;
    }, new FormData()),

This section is no recursive on objects.

For example, if my backend expects the following type for the payload

interface PayloadWithData {
  items: {
    name: string;
    content: Blob;
    appSpecificData: '1234567896',
  }[];
}

The files aren't correctly set in the fetch request because they aren't serializable.

This should be updated to support File in subfields of the payload type.

EDIT 1 : Indentation EDIT 2 : this looks like it's the continuation of the work done here : #293 EDIT 3 : Typo

thomsocialbrothers commented 1 year ago

Also, it doesn't support arrays.. Maybe adding object-to-formdata as a dependency would be a good idea?

Clovel commented 1 year ago

Any news on this ? Has anyone taken a look at how this would be fixed ?

MKraust commented 3 months ago

I think it would be okay to make contentFormatters property at least protected to be able to override it easily.