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

Commit

Permalink
Merge pull request #67 from joolfe/develop
Browse files Browse the repository at this point in the history
Improvements for issue #61
  • Loading branch information
joolfe authored Aug 25, 2020
2 parents b6db3f7 + 9b9ed56 commit d6e98b3
Show file tree
Hide file tree
Showing 11 changed files with 411 additions and 9 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## [1.4.0](https://github.com/joolfe/postman-to-openapi/compare/1.3.0...1.4.0) (2020-08-25)


### Features

* support DELETE operations [#66](https://github.com/joolfe/postman-to-openapi/issues/66) ([38eb357](https://github.com/joolfe/postman-to-openapi/commit/38eb3570a7afababd725b3dfe266ac98565d6e20))
* support hyphen character in path variables [#65](https://github.com/joolfe/postman-to-openapi/issues/65) ([ea1671e](https://github.com/joolfe/postman-to-openapi/commit/ea1671e355e17816664455c4807c3b75c056017d))


### Bug Fixes

* error when no "options" in body [#64](https://github.com/joolfe/postman-to-openapi/issues/64) ([a4e8af4](https://github.com/joolfe/postman-to-openapi/commit/a4e8af4e10b4bd568adaa2612693155aeda52f68))
* should support root paths [#63](https://github.com/joolfe/postman-to-openapi/issues/63) ([aff566b](https://github.com/joolfe/postman-to-openapi/commit/aff566b27b3d87884dd66d2aac7aa030aff2da1c))

## [1.3.0](https://github.com/joolfe/postman-to-openapi/compare/1.2.0...1.3.0) (2020-08-23)


Expand Down
10 changes: 5 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ async function postmanToOpenApi (input, output, { info = {}, defaultTag = 'defau
paths
}

const openApiYml = safeDump(openApi)
const openApiYml = safeDump(openApi, { skipInvalid: true })
if (output != null) {
await writeFile(output, openApiYml, 'utf8')
}
Expand Down Expand Up @@ -98,8 +98,8 @@ function parseContact (variables, optsContact = {}) {

function parseBody (body = {}, method) {
// Swagger validation return an error if GET has body
if (['GET'].includes(method)) return {}
const { mode, raw, options } = body
if (['GET', 'DELETE'].includes(method)) return {}
const { mode, raw, options = { raw: { language: 'json' } } } = body
let content = {}
switch (mode) {
case 'raw': {
Expand Down Expand Up @@ -162,7 +162,7 @@ function mapParameters (type) {
}

function extractPathParameters (path, paramsMeta) {
const matched = path.match(/{\s*[\w]+\s*}/g) || []
const matched = path.match(/{\s*[\w-]+\s*}/g) || []
return matched.map(match => {
const name = match.slice(1, -1)
const { type = 'string', description, example } = paramsMeta[name] || {}
Expand Down Expand Up @@ -239,7 +239,7 @@ function parseOptsAuth (optAuth) {
}

/* From the path array compose the real path for OpenApi specs */
function calculatePath (paths, pathDepth) {
function calculatePath (paths = [], pathDepth) {
paths = paths.slice(pathDepth) // path depth
// replace repeated '{' and '}' chars
return '/' + paths.map(path => path.replace(/([{}])\1+/g, '$1'))
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "postman-to-openapi",
"version": "1.3.0",
"version": "1.4.0",
"description": "Convert postman collection to OpenAPI spec",
"main": "lib/index.js",
"scripts": {
Expand Down
20 changes: 20 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ const COLLECTION_MULTIPLE_SERVERS = './test/resources/input/MultipleServers.json
const COLLECTION_LICENSE_CONTACT = './test/resources/input/LicenseContact.json'
const COLLECTION_DEPTH_PATH_PARAMS = './test/resources/input/DepthPathParams.json'
const COLLECTION_PARSE_STATUS_CODE = './test/resources/input/ParseStatusCode.json'
const COLLECTION_NO_PATH = './test/resources/input/NoPath.json'
const COLLECTION_NO_OPTIONS = './test/resources/input/NoOptionsInBody.json'
const COLLECTION_DELETE = './test/resources/input/DeleteOperation.json'

const EXPECTED_BASIC = readFileSync('./test/resources/output/Basic.yml', 'utf8')
const EXPECTED_INFO_OPTS = readFileSync('./test/resources/output/InfoOpts.yml', 'utf8')
Expand All @@ -42,6 +45,8 @@ const EXPECTED_LICENSE_CONTACT_PARTIAL = readFileSync('./test/resources/output/L
const EXPECTED_LICENSE_CONTACT_PARTIAL_2 = readFileSync('./test/resources/output/LicenseContactPartial2.yml', 'utf8')
const EXPECTED_DEPTH_PATH_PARAMS = readFileSync('./test/resources/output/DepthPathParams.yml', 'utf8')
const EXPECTED_PARSE_STATUS_CODE = readFileSync('./test/resources/output/ParseStatus.yml', 'utf8')
const EXPECTED_NO_PATH = readFileSync('./test/resources/output/NoPath.yml', 'utf8')
const EXPECTED_DELETE = readFileSync('./test/resources/output/DeleteOperation.yml', 'utf8')

describe('Library specs', function () {
afterEach('remove file', function () {
Expand Down Expand Up @@ -223,4 +228,19 @@ describe('Library specs', function () {
const result = await postmanToOpenApi(COLLECTION_PARSE_STATUS_CODE)
equal(result, EXPECTED_PARSE_STATUS_CODE)
})

it('should parse operation when no path (only domain)', async function () {
const result = await postmanToOpenApi(COLLECTION_NO_PATH)
equal(result, EXPECTED_NO_PATH)
})

it('should work if no options in request body', async function () {
const result = await postmanToOpenApi(COLLECTION_NO_OPTIONS, OUTPUT_PATH, {})
equal(result, EXPECTED_BASIC)
})

it('should support "DELETE" operations', async function () {
const result = await postmanToOpenApi(COLLECTION_DELETE)
equal(result, EXPECTED_DELETE)
})
})
60 changes: 60 additions & 0 deletions test/resources/input/DeleteOperation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"info": {
"_postman_id": "469344e4-4c85-45fe-b0a6-246575a018bc",
"name": "Delete Operation",
"description": "Mi super test collection from postman",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Delete all users",
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "https://api.io/users",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"users"
]
},
"description": "Delete all the existing users"
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "9f8baaad-642e-48c6-b5d3-6ec59d2df6b1",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "61df081f-afb8-4e8a-8a32-66db8b22f887",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"variable": [
{
"id": "b8ff9254-81e3-432f-9e5a-aea92cf34d7c",
"key": "version",
"value": "1.1.0"
}
],
"protocolProfileBehavior": {}
}
121 changes: 121 additions & 0 deletions test/resources/input/NoOptionsInBody.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
"info": {
"_postman_id": "2a45baa5-352f-4831-8483-1a0fcbc7da37",
"name": "Postman to OpenAPI",
"description": "Mi super test collection from postman",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Create new User",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"example\": \"field\",\n \"other\": {\n \"data1\": \"yes\",\n \"data2\": \"no\"\n }\n}"
},
"url": {
"raw": "https://api.io/users",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"users"
]
},
"description": "Create a new user into your amazing API"
},
"response": []
},
{
"name": "Create a post",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "file",
"file": {},
"options": {
"raw": {
"language": "text"
}
}
},
"url": {
"raw": "https://api.io/posts",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"posts"
]
}
},
"response": []
},
{
"name": "Create a note",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "This is an example Note",
"options": {
"raw": {
"language": "text"
}
}
},
"url": {
"raw": "https://api.io/note",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"note"
]
},
"description": "Just an example of text raw body"
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "ef248fcc-2944-4cba-837f-680b10a45b30",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "8e7453aa-5712-4a90-bc32-965c7d47906a",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"variable": [
{
"id": "d04439bd-c604-4758-bde2-3c873140f38c",
"key": "version",
"value": "1.1.0"
}
],
"protocolProfileBehavior": {}
}
77 changes: 77 additions & 0 deletions test/resources/input/NoPath.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"info": {
"_postman_id": "074ac938-087e-4762-8a33-feadabfa1145",
"name": "No Path",
"description": "API to manage GET methods",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Get list of users",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "https://api.io?age=45&name=Jhon&review=true&number=23.56&required=my value",
"protocol": "https",
"host": [
"api",
"io"
],
"query": [
{
"key": "age",
"value": "45",
"description": "Filter by age [required]"
},
{
"key": "name",
"value": "Jhon",
"description": "Filter by name [REQUIRED]"
},
{
"key": "review",
"value": "true",
"description": "Indicate if should be reviewed or not"
},
{
"key": "number",
"value": "23.56",
"description": "This is a number"
},
{
"key": "required",
"value": "my value",
"description": "[required] mandatory paraemeter"
}
]
},
"description": "Obtain a list of users that fullfill the conditions of the filters"
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "e5a590b1-117c-4050-9541-926b7188ebe0",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "6fb7b705-a3fc-45e0-8a80-3f2b5ce4bf9f",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"protocolProfileBehavior": {}
}
Loading

0 comments on commit d6e98b3

Please sign in to comment.