joolfe / postman-to-openapi

🛸 Convert postman collection to OpenAPI
MIT License
575 stars 99 forks source link

Missing requestBody media types #203

Closed ssduman closed 1 year ago

ssduman commented 1 year ago

Hello,

When I try with differents requestBody (other than application/json), the result will always be application/json no matter what. Here is a sample with all different test cases, text, javascript, json, html and xml:

{
    "info": {
        "_postman_id": "daeaed7e-5dee-4aa8-8828-3280afb2b11a",
        "name": "Raw Body",
        "description": "Mi super test collection from postman",
        "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
    },
    "item": [
        {
            "name": "Test Raw Body - Text",
            "request": {
                "method": "POST",
                "header": [],
                "body": {
                    "mode": "raw",
                    "raw": "testesttestest"
                },
                "url": {
                    "raw": "https://api.io/text",
                    "protocol": "https",
                    "host": [
                        "api",
                        "io"
                    ],
                    "path": [
                        "text"
                    ]
                },
                "description": "Test Raw Body"
            },
            "response": []
        },
        {
            "name": "Test Raw Body - JavaScript",
            "request": {
                "method": "POST",
                "header": [],
                "body": {
                    "mode": "raw",
                    "raw": "var test = true;",
                    "options": {
                        "raw": {
                            "language": "javascript"
                        }
                    }
                },
                "url": {
                    "raw": "https://api.io/js",
                    "protocol": "https",
                    "host": [
                        "api",
                        "io"
                    ],
                    "path": [
                        "js"
                    ]
                },
                "description": "Test Raw Body"
            },
            "response": []
        },
        {
            "name": "Test Raw Body - JSON",
            "request": {
                "method": "POST",
                "header": [],
                "body": {
                    "mode": "raw",
                    "raw": "{ \r\n    \"test\": 1\r\n}",
                    "options": {
                        "raw": {
                            "language": "json"
                        }
                    }
                },
                "url": {
                    "raw": "https://api.io/json",
                    "protocol": "https",
                    "host": [
                        "api",
                        "io"
                    ],
                    "path": [
                        "json"
                    ]
                },
                "description": "Test Raw Body"
            },
            "response": []
        },
        {
            "name": "Test Raw Body - HTML",
            "request": {
                "method": "POST",
                "header": [],
                "body": {
                    "mode": "raw",
                    "raw": "<html>\r\n    <body>\r\n        <p>test</p>\r\n    </body>\r\n</html>",
                    "options": {
                        "raw": {
                            "language": "html"
                        }
                    }
                },
                "url": {
                    "raw": "https://api.io/html",
                    "protocol": "https",
                    "host": [
                        "api",
                        "io"
                    ],
                    "path": [
                        "html"
                    ]
                },
                "description": "Test Raw Body"
            },
            "response": []
        },
        {
            "name": "Test Raw Body - XML",
            "request": {
                "method": "POST",
                "header": [],
                "body": {
                    "mode": "raw",
                    "raw": "<test>\r\n    <text>test</text>\r\n</test>",
                    "options": {
                        "raw": {
                            "language": "xml"
                        }
                    }
                },
                "url": {
                    "raw": "https://api.io/xml",
                    "protocol": "https",
                    "host": [
                        "api",
                        "io"
                    ],
                    "path": [
                        "xml"
                    ]
                },
                "description": "Test Raw Body"
            },
            "response": []
        }
    ],
    "event": [
        {
            "listen": "prerequest",
            "script": {
                "type": "text/javascript",
                "exec": [
                    ""
                ]
            }
        },
        {
            "listen": "test",
            "script": {
                "type": "text/javascript",
                "exec": [
                    ""
                ]
            }
        }
    ]
}

And the results are here:

openapi: 3.0.0
info:
  title: Raw Body
  description: Mi super test collection from postman
  version: 1.0.0
servers:
  - url: https://api.io
paths:
  /text:
    post:
      tags:
        - default
      summary: Test Raw Body - Text
      description: Test Raw Body
      requestBody:
        content:
          application/json:
            schema:
              type: object
              example: testesttestest
      responses:
        '200':
          description: Successful response
          content:
            application/json: {}
  /js:
    post:
      tags:
        - default
      summary: Test Raw Body - JavaScript
      description: Test Raw Body
      requestBody:
        content:
          application/json:
            schema:
              type: string
              example: var test = true;
      responses:
        '200':
          description: Successful response
          content:
            application/json: {}
  /json:
    post:
      tags:
        - default
      summary: Test Raw Body - JSON
      description: Test Raw Body
      requestBody:
        content:
          application/json:
            schema:
              type: object
              example:
                test: 1
      responses:
        '200':
          description: Successful response
          content:
            application/json: {}
  /html:
    post:
      tags:
        - default
      summary: Test Raw Body - HTML
      description: Test Raw Body
      requestBody:
        content:
          application/json:
            schema:
              type: string
              example: "<html>\r\n    <body>\r\n        <p>test</p>\r\n    </body>\r\n</html>"
      responses:
        '200':
          description: Successful response
          content:
            application/json: {}
  /xml:
    post:
      tags:
        - default
      summary: Test Raw Body - XML
      description: Test Raw Body
      requestBody:
        content:
          application/json:
            schema:
              type: string
              example: "<test>\r\n    <text>test</text>\r\n</test>"
      responses:
        '200':
          description: Successful response
          content:
            application/json: {}

However, Postman sometimes do not add options as shown here (also above): How can we infer such situations?

"body": {
    "mode": "raw",
    "raw": "testesttestest"
},

I tried to implement it in lib/index.js from lines 147 to 170, but a lot of tests failed.

Here is the code snippet for your reference:

  switch (mode) {
    case 'raw': {
      const { raw: { language } } = options

      let example = ''
      if (language === 'json') {
        if (raw) {
          const errors = []
          example = jsonc.parse(raw, errors)
          if (errors.length > 0) {
            example = raw
          }
        }

        content = {
          'application/json': {
            schema: {
              type: 'object',
              example
            }
          }
        }
      } else if (language === 'text') {
        content = {
          'text/plain': {
            schema: {
              type: 'string',
              example: raw
            }
          }
        }
      } else if (language === 'javascript') {
        content = {
          'application/javascript': {
            schema: {
              type: 'string',
              example: raw
            }
          }
        }
      } else if (language === 'html') {
        content = {
          'text/html': {
            schema: {
              type: 'string',
              example: raw
            }
          }
        }
      } else if (language === 'xml') {
        content = {
          'application/xml': {
            schema: {
              type: 'string',
              example: raw
            }
          }
        }
      }
      else {
        content = {
          '*/*': {
            schema: {
              type: 'string',
              example: raw
            }
          }
        }
      }
      break
    }

Note: I'm referring this example:

  1. https://spec.openapis.org/oas/v3.0.3.html#request-body-examples

Thanks in advance.

joolfe commented 1 year ago

Hi @ssduman,

As described in the documentation the library support the next body types

Support postman “raw” body (Json and Text), “form-data” and “x-www-form-urlencoded”.

The only one that maybe can be a bug is the text that should be text/plain, I will review this one, the rest are still not supported sorry

Best regards