joolfe / postman-to-openapi

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

Replace variables in description query parameters #131

Closed KillianLeroux closed 3 years ago

KillianLeroux commented 3 years ago

Hi!

When I use variables in the description of the query parameters these are not replaced by their value when exporting with p2o.

Example:

Postman interface - query: image

Postman interface - collection variable: image

Postman JSON Export:

"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",
    "disabled": true
}
],

...

"variable": [
{
    "key": "Desc - Format",
    "value": "Desired return format (json or xml). Default: json"
}
]

p2o result:

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'
KillianLeroux commented 3 years ago

I make some modifications:

I added one parameter for "parseParameters" in first for loop:

...parseParameters(query, header, joinedPath, paramsMeta, postmanJson),

I replaced the function "parseParameters" in "lib/index.js" by this:

function parseParameters (query = [], header, paths, paramsMeta = {}, postmanJson = {}) {
  // parse Headers
  let parameters = header.reduce(mapParameters('header'), [])
  // parse Query
  parameters = query.reduce(mapParameters('query'), parameters)
  // Path params
  parameters.push(...extractPathParameters(paths, paramsMeta))

  parameters.map(param => {
    if (param.description) {
      const { variable = [] } = postmanJson
      param.description = setVars(param.description, variable)
    }
  })

  return (parameters.length) ? { parameters } : {}
}

I added function "setVars" in "lib/index.js":

/**
 * Populate variables in provided string
 *
 * @param {string} string    String to process
 * @param {array}  variables Array of variables for replacements
 *
 * @returns {string} String with variables populated
 */
function setVars(string, variables) {
  if (~string.search(/{{\s*[\w\s-]+\s*}}/g)) {
    const varKey = string.replace(/[{*|}*]/g, '').trim()

    return getVarValue(variables, varKey)
  }

  return string
}

And from this Postman JSON Export:

{
  "name": "Companies",
  "item": [
  {
      "name": "Get Company",
      "protocolProfileBehavior": {
          "disableBodyPruning": true
      },
      "request": {
          "method": "GET",
          "header": [],
          "body": {
              "mode": "raw",
              "raw": "",
              "options": {
                  "raw": {
                      "language": "json"
                  }
              }
          },
          "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",
                      "disabled": true
                  }
              ],
              "variable": [
                  {
                      "key": "companyId",
                      "value": "",
                      "description": "Company ID"
                  }
              ]
          },
          "description": "Get Company informations from provided Company ID."
      },
      "response": []
  }
  ]
  },

I obtain this 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: 'Desired return format (json or xml). Default: json'
          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

Hi @KillianLeroux ,

There already exist a task for this feature #76 I will take into account this use case also, the feature is work in progress.

Best regards