joolfe / postman-to-openapi

🛸 Convert postman collection to OpenAPI
MIT License
596 stars 104 forks source link

Allow to use path parameter #130

Closed KillianLeroux closed 3 years ago

KillianLeroux commented 3 years ago

Hi!

First of all: thanks for your work! ;)

I use path parameters in my requests and it's impossible to use in Swagger :(

Documentation: https://learning.postman.com/docs/sending-requests/requests/#sending-parameters

Example:

Postman interface: image

Postman JSON Export:

"url": {
    "raw": "{{base_url}}/companies/:companyId",
    "host": [
        "{{base_url}}"
    ],
    "path": [
        "companies",
        ":companyId"
    ],
    "query": [
        {
            "key": "format",
            "value": "xml",
            "description": "{{Desc - Format}}",
            "disabled": true
        },
        {
            "key": "withOffers",
            "value": "true",
            "description": "Indicates if you want Company informations with its offers or not"
        }
    ],
    "variable": [
        {
            "key": "companyId",
            "value": "2975",
            "description": "Company ID"
        }
    ]
},

p2o result:

/companies/:companyId:
    get:
      tags:
        - Companies
      summary: Get Company
      description: Get Company informations from provided Company ID.
      parameters:
        - name: format
          in: query
          schema:
            type: string
          description: '{{Desc - Format}}'
          example: xml
        - name: withOffers
          in: query
          schema:
            type: boolean
          description: Indicates if you want Company informations with its offers or not
          example: 'true'
      responses:
        '200':
          description: Successful response
          content:
            application/json: {}

Do you think it's difficult to add? I could try to add this :)

Thank you =)

KillianLeroux commented 3 years ago

I make some modifications:

  1. I replaced the function "extractPathParameters" in "lib/index.js" by this:
function extractPathParameters(path, paramsMeta) {
  const regexParamBraces = /{\s*[\w-]+\s*}/g
  const regexParamDoubleDots = /:\s*[\w-]+/g
  const matched = path.match(regexParamBraces) || path.match(regexParamDoubleDots) || []

  return matched.map(match => {
    let name = match.replace(':', '')

    if (match.match(regexParamBraces)) {
      name = match.slice(1, -1)
    }

    const { type = 'string', description, example } = paramsMeta[name] || {}

    return {
      name,
      in: 'path',
      schema: { type },
      required: true,
      ...(description ? { description } : {}),
      ...(example ? { example } : {})
    }
  })
}
  1. I replaced function "scrapeURL" in "lib/index.js" by this:
function scrapeURL (url) {
  if (url === '' || url.raw === '') {
    return { valid: false }
  }

  if (typeof url === 'string' || url instanceof String) {
    const objUrl = new URL(url)
    return {
      raw: url,
      path: decodeURIComponent(objUrl.pathname).slice(1).split('/'),
      query: [],
      protocol: objUrl.protocol.slice(0, -1),
      host: decodeURIComponent(objUrl.hostname).split('.'),
      port: objUrl.port,
      valid: true
    }
  }

  const regexParamDoubleDots = /:\s*[\w-]+/g

  if (url.raw && typeof url.raw === 'string' && url.raw.search(regexParamDoubleDots) > 0) {
    const paramsToReplace = url.raw.match(regexParamDoubleDots) || []

    paramsToReplace.map(match => {
      const paramFormatted = '{' + match.replace(':', '') + '}'
      url.raw = url.raw.replace(match, paramFormatted)

      const index = url.path.indexOf(match)
      if (~index) {
        url.path[index] = paramFormatted
      }
    })
  }

  return { ...url, valid: true }
}

And I obtain that in result:

/companies/{companyId}:
    get:
      tags:
        - Companies
      summary: Get Company
      description: Get Company informations from provided Company ID.
      parameters:
        - name: format
          in: query
          schema:
            type: string
          description: '{{Desc - Format}}'
          example: xml
        - name: withOffers
          in: query
          schema:
            type: boolean
          description: Indicates if you want Company informations with its offers or not
          example: 'true'
        - name: companyId
          in: path
          schema:
            type: string
          required: true
      responses:
        '200':
          description: Successful response
          content:
            application/json: {}

It seems to work :)

What do you think?

joolfe commented 3 years ago

@KillianLeroux hi!

Interesting I didn't know about the semi colon sintax in path parameters, is that a new feature from postman?

I will take into account your suggestions definitely and will add as soon as I have time or you can create a pull request with the changes and I will integrate faster ;-)

Best regards

KillianLeroux commented 3 years ago

Ahah I don't know if it's a new feature ^^

Fine I'll try to find time to make a PR ;)

joolfe commented 3 years ago

@KillianLeroux thanks! I will include anyway as I think is a cool feature, so if you have not time don't worry I will implement anyway for sure ;-)