From a128a5c445d92ac6b80cca4370497c5e2b9998be Mon Sep 17 00:00:00 2001 From: Jorge Date: Sat, 25 Jul 2020 19:01:49 +0200 Subject: [PATCH] feat: Support postman folders #16 --- lib/index.js | 14 +- test/index.spec.js | 7 + test/resources/input/FolderCollection.json | 144 +++++++++++++++++++++ test/resources/output/Folders.yml | 78 +++++++++++ 4 files changed, 239 insertions(+), 4 deletions(-) create mode 100644 test/resources/input/FolderCollection.json create mode 100644 test/resources/output/Folders.yml diff --git a/lib/index.js b/lib/index.js index 010f266..f0281d9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -3,19 +3,25 @@ const { promises: { writeFile, readFile } } = require('fs') const { safeDump } = require('js-yaml') -async function postmanToOpenApi (input, output, { save = true, info = {}, defaultTag = 'default' }) { +async function postmanToOpenApi (input, output, { save = true, info = {}, defaultTag = 'default' } = {}) { // TODO validate? const collectionFile = await readFile(input) const postmanJson = JSON.parse(collectionFile) const { item: items } = postmanJson const paths = {} - for (const item of items) { - const { request: { url: { path }, method, body, description }, name: summary } = item + for (let [i, element] of items.entries()) { + const { item, name } = element + if (item != null) { // is a folder + const tagged = item.map(e => ({ ...e, tag: name })) + items.splice(i, 1, ...tagged) + element = tagged.shift() + } + const { request: { url: { path }, method, body, description }, name: summary, tag = defaultTag } = element const compiledPath = '/' + path.join('/') if (!paths[compiledPath]) paths[compiledPath] = {} paths[compiledPath][method.toLowerCase()] = { - tags: [defaultTag], + tags: [tag], summary, ...(description ? { description } : {}), requestBody: parseBody(body), diff --git a/test/index.spec.js b/test/index.spec.js index b53b6f0..a6628c4 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -11,11 +11,13 @@ const OUTPUT_PATH = path.join(__dirname, '/openAPIRes.yml') const COLLECTION_BASIC = './test/resources/input/PostmantoOpenAPI.postman_collection.json' const COLLECTION_SIMPLE = './test/resources/input/SimplePost.json' const COLLECTION_NO_VERSION = './test/resources/input/NoVersion.json' +const COLLECTION_FOLDERS = './test/resources/input/FolderCollection.json' const EXPECTED_BASIC = readFileSync('./test/resources/output/Basic.yml', 'utf8') const EXPECTED_INFO_OPTS = readFileSync('./test/resources/output/InfoOpts.yml', 'utf8') const EXPECTED_NO_VERSION = readFileSync('./test/resources/output/NoVersion.yml', 'utf8') const EXPECTED_CUSTOM_TAG = readFileSync('./test/resources/output/CustomTag.yml', 'utf8') +const EXPECTED_FOLDERS = readFileSync('./test/resources/output/Folders.yml', 'utf8') describe('Library specs', function () { afterEach('remove file', function () { @@ -55,4 +57,9 @@ describe('Library specs', function () { const result = await postmanToOpenApi(COLLECTION_SIMPLE, OUTPUT_PATH, { defaultTag: 'Custom Tag' }) equal(EXPECTED_CUSTOM_TAG, result) }) + + it('should work with folders and use as tags', async function () { + const result = await postmanToOpenApi(COLLECTION_FOLDERS, OUTPUT_PATH) + equal(EXPECTED_FOLDERS, result) + }) }) diff --git a/test/resources/input/FolderCollection.json b/test/resources/input/FolderCollection.json new file mode 100644 index 0000000..c23dbb6 --- /dev/null +++ b/test/resources/input/FolderCollection.json @@ -0,0 +1,144 @@ +{ + "info": { + "_postman_id": "3ad7e1b4-f3a1-4a8f-8bd0-56ff18f53339", + "name": "Folder Collection", + "description": "Just a simple collection for test", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Users", + "item": [ + { + "name": "Create a user", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"example\": \"field\",\n \"other\": {\n \"data1\": \"yes\",\n \"data2\": \"no\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://api.io/users", + "protocol": "https", + "host": [ + "api", + "io" + ], + "path": [ + "users" + ] + }, + "description": "This is a post request with json body" + }, + "response": [] + }, + { + "name": "Create a customer", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"example\": \"field\",\n \"other\": {\n \"data1\": \"yes\",\n \"data2\": \"no\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://api.io/customer", + "protocol": "https", + "host": [ + "api", + "io" + ], + "path": [ + "customer" + ] + }, + "description": "This is a post request with json body for create a customer" + }, + "response": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Posts", + "item": [ + { + "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": [] + } + ], + "protocolProfileBehavior": {} + }, + { + "name": "Create a info", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"test\":\"here\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://api.io/info", + "protocol": "https", + "host": [ + "api", + "io" + ], + "path": [ + "info" + ] + } + }, + "response": [] + } + ], + "variable": [ + { + "id": "e4619cfa-c046-413a-9e69-f40a20248a4d", + "key": "version", + "value": "2.3.0" + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/test/resources/output/Folders.yml b/test/resources/output/Folders.yml new file mode 100644 index 0000000..8a657fa --- /dev/null +++ b/test/resources/output/Folders.yml @@ -0,0 +1,78 @@ +openapi: 3.0.0 +info: + title: Folder Collection + description: Just a simple collection for test + version: 2.3.0 +paths: + /users: + post: + tags: + - Users + summary: Create a user + description: This is a post request with json body + requestBody: + content: + application/json: + schema: + type: object + example: + example: field + other: + data1: 'yes' + data2: 'no' + responses: + '200': + description: Successful response + content: + application/json: {} + /customer: + post: + tags: + - Users + summary: Create a customer + description: This is a post request with json body for create a customer + requestBody: + content: + application/json: + schema: + type: object + example: + example: field + other: + data1: 'yes' + data2: 'no' + responses: + '200': + description: Successful response + content: + application/json: {} + /posts: + post: + tags: + - Posts + summary: Create a post + requestBody: + content: + text/plain: {} + responses: + '200': + description: Successful response + content: + application/json: {} + /info: + post: + tags: + - default + summary: Create a info + requestBody: + content: + application/json: + schema: + type: object + example: + test: here + responses: + '200': + description: Successful response + content: + application/json: {}