openapi-typescript-codegen icon indicating copy to clipboard operation
openapi-typescript-codegen copied to clipboard

Question: is there a way to override the generated Blob type to be File?

Open rossmacarthur opened this issue 1 year ago • 8 comments

I have a {"type": "string", "format": "binary"} in my OpenAPI spec and it is being generated like this

export type UploadFileRequest = {
  file: Blob
}

I'd like this to be

export type UploadFileRequest = {
  file: File
}

Is there anyway to override this, perhaps by changing something in the OpenAPI spec?

rossmacarthur avatar Oct 11 '23 10:10 rossmacarthur

Shouldn't you be able to just pass any File object there, as File inherits from Blob?

mbergen avatar Oct 18 '23 08:10 mbergen

Shouldn't you be able to just pass any File object there, as File inherits from Blob?

Yes, but I want to require a file because the server requires a filename and content-type.

rossmacarthur avatar Oct 18 '23 15:10 rossmacarthur

To pass a filename, you will need to use multipart upload, as described here: https://swagger.io/docs/specification/describing-request-body/file-upload/

mbergen avatar Oct 19 '23 06:10 mbergen

@mbergen At the document you linked, single file uploads are described as:

requestBody:
  content:
    multipart/form-data:
      schema:
        filename:
          type: string
          format: binary

and multi file uploads as:

requestBody:
  content:
    multipart/form-data:
      schema:
        type: array
        items:
          filename:
            type: string
            format: binary

Both of which are described to correspond to an HTTP request like this:

POST /upload
Host: example.com
Content-Length: 2740
Content-Type: multipart/form-data; boundary=abcde12345
--abcde12345
Content-Disposition: form-data; name="fileName"; filename="file1.txt"
Content-Type: text/plain

Without openapi-typescript-codegen supporting sending File objects, filename and Content-Type really cant be included in the request as @rossmacarthur said.

As I need to upload file in my API, I have only three options:

  1. fork the tool and fix the issue myself, making me lose the deadline
  2. use the official java based generator
  3. single out file handling options into their own manually written functions

tajnymag avatar Mar 02 '24 15:03 tajnymag

@rossmacarthur It's been 5 months. What did you use in the end?

tajnymag avatar Mar 02 '24 15:03 tajnymag

@mbergen At the document you linked, single file uploads are described as:

requestBody:
  content:
    multipart/form-data:
      schema:
        filename:
          type: string
          format: binary

and multi file uploads as:

requestBody:
  content:
    multipart/form-data:
      schema:
        type: array
        items:
          filename:
            type: string
            format: binary

Both of which are described to correspond to an HTTP request like this:

These are both the versions that specify to take a additional filename property in the spec, which the original comment here did not include (that's also documented in the link, the first example)

mbergen avatar Mar 02 '24 15:03 mbergen

@mbergen Sorry, embarrassed I missed that, you are right.

My point still stands though. I've tried the example specifications and the generated client only accepts Blob either way.

/hosted/core/files/{path}:
    post:
      operationId: uploadContent
      parameters:
        - $ref: '#/components/parameters/path'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                filename:
                  type: string
                  format: binary

|| V

public static uploadContent(
        formData: {
            filename?: Blob;
        },
        path: string = '',
    ): CancelablePromise<(FileMetadata | DirectoryMetadata)> {
        return __request(OpenAPI, {
            method: 'POST',
            url: '/hosted/core/files/{path}',
            path: {
                'path': path,
            },
            formData: formData,
            mediaType: 'multipart/form-data',
            errors: {
                409: `Path already exists`,
            },
        });
    }

tajnymag avatar Mar 02 '24 16:03 tajnymag

Check out our fork of this repository @hey-api/openapi-ts. We have updated the type to be Blob | File (since File extends Blob). If you need to narrow the type, you can do so in your code. Please let us know if you run into any further issue by creating an issue in our repository. Thanks.

jordanshatford avatar Mar 30 '24 23:03 jordanshatford