ts-spec / tspec

Type-driven API Documentation library. Auto-generating REST API document based on TypeScript types.
https://ts-spec.github.io/tspec/
MIT License
108 stars 5 forks source link

Hardcoded values for `application/json`: requestBody.content & responses #31

Closed theWickedWebDev closed 12 months ago

theWickedWebDev commented 1 year ago

There are two places that application/json is hardcoded as values which makes it impossible to provide others. ie. multipart/form-data for request body, or image/jpeg for response body.

requestBody: bodyParams && {
        description: bodyParams.description,
        required: true,
        content: {
          'application/json': {
            schema: bodyParams,
          },
        },
      },
      responses: Object.fromEntries(
        Object.entries(responses).map(([code, schema]) => {
          const resSchema = {
            description: (schema as any).description || '',
            content: {
              'application/json': {
                schema,
              },
            },
          };
          return [code, resSchema];
        }),
      ),

I have made the changes locally for myself to use, but it is not PR ready - I would be willing to assist with this if given a little bit of guidance.

Note Would be excellent if somehow we could forgo passing in Typescript types in some cases and just provide some raw OpenAPI specs to some of these key/values :)

hyeonss0417 commented 12 months ago

I also think it's natural to support specifying media types like multipart/form-data in requestBody.content and responses to handle file uploads and downloads. After thinking about how to support mediaType, I decided to make it possible to set it using JSDoc tags. For example:

export type FileApiSpec = Tspec.DefineApiSpec<{
  paths: {
    '/files/upload': {
      post: {
        summary: 'Upload File',
        /** @mediaType multipart/form-data */
        body: {
          file: Tspec.BinaryString;
        },
        responses: { 200: { fileName: string } },
      },
    },
    '/files/download': {
      get: {
        summary: 'Download File',
        responses: {
          /** @mediaType application/octet-stream */
          200: Tspec.BinaryString
        },
      },
    },
  },
}>;

I'd be very grateful if you could post a PR, but for now I've done it the way I think it should be done and posted the PR below:

I've also added the usage to the official documentation and included an example project.

If you want to use this feature right now, you should upgrade Tspec version to v0.1.104🎉

Thank you for your proposal👍