hey-api / openapi-ts

✨ Turn your OpenAPI specification into a beautiful TypeScript client
https://heyapi.vercel.app
MIT License
634 stars 44 forks source link

FormData/RequestBody not handled correctly with the standalone clients #721

Open gergan opened 4 days ago

gergan commented 4 days ago

Description

So we have a Post with the following format:

      "post": {
        "operationId": "archiveDocument",
        ...
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DocumentArchiveRequestV1"
              },
              "encoding": {
                "customerIndexes": {
                  "contentType": "application/json"
                }
              }
            }
          },
          "required": true
        },
      }

and

      "DocumentArchiveRequestV1": {
        "properties": {
          "customerIndexes": {
            "$ref": "#/components/schemas/CustomerIndexesV1"
          },
          "file": {
            "format": "binary",
            "type": "string"
          }
        },
        "required": [
          "file"
        ],
        "type": "object"
      },

The created type is missing the body:

export type ArchiveDocumentData = {
  headers: {
    'x-tenant-id': string;
  };
  path: {
    docId: string;
  };
};
export type DocumentArchiveRequestV1 = {
  customerIndexes?: CustomerIndexesV1;
  file: Blob | File;
};

I'm using "@hey-api/client-fetch" and "@hey-api/openapi-ts" built from the main branch.

So the problem seems to be that the standalone-client does not have formData fields anymore and https://github.com/hey-api/openapi-ts/blob/a2cb1b06b4a7c7bdcac36400a26a7e19fca15bd2/packages/openapi-ts/src/openApi/v3/parser/getOperationRequestBody.ts#L51 transforms the requestBody in formData if the requestBody type is either 'application/x-www-form-urlencoded' or 'multipart/form-data'. After that in https://github.com/hey-api/openapi-ts/blob/a2cb1b06b4a7c7bdcac36400a26a7e19fca15bd2/packages/openapi-ts/src/openApi/v3/parser/operation.ts#L119 the getOperationRequestBody-function is used and the requestBody is added to the parameters and the parametersBody property is set on the operation. After that in https://github.com/hey-api/openapi-ts/blob/a2cb1b06b4a7c7bdcac36400a26a7e19fca15bd2/packages/openapi-ts/src/utils/write/types.ts#L262 the parameters are only filtered on body and as such the formData types are ignored and the body is not set at all. I have a PullRequest, which will fix the problem, which I have - requestBody transformed in formData and consequently missing from the types, just by using the parametersBody property instead of filtering again the parameters. This probably will miss real formData parameters, which in this case still will not be handled correctly.

OpenAPI specification (optional)

No response

Configuration

No response

System information (optional)

No response