Skip to content
This repository has been archived by the owner on Dec 27, 2024. It is now read-only.

Commit

Permalink
feat: path parameter convertion #15
Browse files Browse the repository at this point in the history
  • Loading branch information
joolfe committed Jul 28, 2020
1 parent 32024e5 commit 96a2ac5
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 5 deletions.
30 changes: 25 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ async function postmanToOpenApi (input, output, { save = true, info = {}, defaul
request: { url: { path, query }, method, body, description, header },
name: summary, tag = defaultTag
} = element
const compiledPath = '/' + path.join('/')
if (!paths[compiledPath]) paths[compiledPath] = {}
paths[compiledPath][method.toLowerCase()] = {
const joinedPath = calculatePath(path)
if (!paths[joinedPath]) paths[joinedPath] = {}
paths[joinedPath][method.toLowerCase()] = {
tags: [tag],
summary,
...(description ? { description } : {}),
...parseBody(body, method),
...parseParameters(query, header),
...parseParameters(query, header, joinedPath),
responses: {
200: {
description: 'Successful response',
Expand Down Expand Up @@ -108,11 +108,13 @@ function parseBody (body = {}, method) {
}

/* Parse the Postman query and header and transform into OpenApi parameters */
function parseParameters (query = [], header = []) {
function parseParameters (query = [], header = [], paths) {
// parse Headers
let parameters = header.reduce(mapParameters('header'), [])
// parse Query
parameters = query.reduce(mapParameters('query'), parameters)
// Path params
parameters.push(...extractPathParameters(paths))
return (parameters.length) ? { parameters } : {}
}

Expand All @@ -130,6 +132,16 @@ function mapParameters (type) {
}
}

function extractPathParameters (path) {
const matched = path.match(/{\s*[\w]+\s*}/g) || []
return matched.map(match => ({
name: match.slice(1, -1),
in: 'path',
schema: { type: 'string' },
required: true
}))
}

function getVarValue (variables, name, def) {
const variable = variables.find(({ key }) => key === name)
return variable ? variable.value : def
Expand Down Expand Up @@ -189,4 +201,12 @@ function parseOptsAuth (optAuth) {
security
}
}

/* From the path array compose the real path for OpenApi specs */
function calculatePath (paths) {
// replace repeated '{' and '}' chars
return '/' + paths.map(path => path.replace(/([{}])\1+/g, '$1'))
.join('/')
}

module.exports = postmanToOpenApi
7 changes: 7 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const COLLECTION_GET = './test/resources/input/GetMethods.json'
const COLLECTION_HEADERS = './test/resources/input/Headers.json'
const COLLECTION_AUTH_BEARER = './test/resources/input/AuthBearer.json'
const COLLECTION_AUTH_BASIC = './test/resources/input/AuthBasic.json'
const COLLECTION_PATH_PARAMS = './test/resources/input/PathParams.json'

const EXPECTED_BASIC = readFileSync('./test/resources/output/Basic.yml', 'utf8')
const EXPECTED_INFO_OPTS = readFileSync('./test/resources/output/InfoOpts.yml', 'utf8')
Expand All @@ -27,6 +28,7 @@ const EXPECTED_HEADERS = readFileSync('./test/resources/output/Headers.yml', 'ut
const EXPECTED_AUTH_BEARER = readFileSync('./test/resources/output/AuthBearer.yml', 'utf8')
const EXPECTED_AUTH_BASIC = readFileSync('./test/resources/output/AuthBasic.yml', 'utf8')
const EXPECTED_BASIC_WITH_AUTH = readFileSync('./test/resources/output/BasicWithAuth.yml', 'utf8')
const EXPECTED_PATH_PARAMS = readFileSync('./test/resources/output/PathParams.yml', 'utf8')

describe('Library specs', function () {
afterEach('remove file', function () {
Expand Down Expand Up @@ -109,4 +111,9 @@ describe('Library specs', function () {
const result = await postmanToOpenApi(COLLECTION_BASIC, OUTPUT_PATH, { auth: authDefinition })
equal(EXPECTED_BASIC_WITH_AUTH, result)
})

it('should parse path params', async function () {
const result = await postmanToOpenApi(COLLECTION_PATH_PARAMS, OUTPUT_PATH)
equal(EXPECTED_PATH_PARAMS, result)
})
})
54 changes: 54 additions & 0 deletions test/resources/input/PathParams.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"info": {
"_postman_id": "74fffb64-a73a-445f-aafc-3021f381a886",
"name": "Path Params",
"description": "Collection to test path parameters",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Get one users info",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "https://api.io/users/{{user_id}}",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"users",
"{{user_id}}"
]
},
"description": "Obtain a list of users that fullfill the conditions of the filters"
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "ce24dfe2-b234-4cb3-9930-ab0992f07671",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "749d3a75-8078-44bf-bd5e-4b0c7dc6125c",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"protocolProfileBehavior": {}
}
23 changes: 23 additions & 0 deletions test/resources/output/PathParams.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
openapi: 3.0.0
info:
title: Path Params
description: Collection to test path parameters
version: 1.0.0
paths:
'/users/{user_id}':
get:
tags:
- default
summary: Get one users info
description: Obtain a list of users that fullfill the conditions of the filters
parameters:
- name: user_id
in: path
schema:
type: string
required: true
responses:
'200':
description: Successful response
content:
application/json: {}

0 comments on commit 96a2ac5

Please sign in to comment.