diff --git a/lib/index.js b/lib/index.js index f0281d9..966942f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -17,14 +17,15 @@ async function postmanToOpenApi (input, output, { save = true, info = {}, defaul items.splice(i, 1, ...tagged) element = tagged.shift() } - const { request: { url: { path }, method, body, description }, name: summary, tag = defaultTag } = element + const { request: { url: { path, query }, method, body, description }, name: summary, tag = defaultTag } = element const compiledPath = '/' + path.join('/') if (!paths[compiledPath]) paths[compiledPath] = {} paths[compiledPath][method.toLowerCase()] = { tags: [tag], summary, ...(description ? { description } : {}), - requestBody: parseBody(body), + ...parseBody(body, method), + ...parseParams(query), responses: { 200: { description: 'Successful response', @@ -50,7 +51,7 @@ async function postmanToOpenApi (input, output, { save = true, info = {}, defaul } function compileInfo (postmanJson, optsInfo) { - const { info: { name, description: desc }, variable } = postmanJson + const { info: { name, description: desc }, variable = [] } = postmanJson const ver = getVarValue(variable, 'version', '1.0.0') const { title = name, description = desc, version = ver, termsOfService } = optsInfo return { @@ -61,25 +62,44 @@ function compileInfo (postmanJson, optsInfo) { } } -function parseBody (body) { - if (body.mode === 'raw') { - return { - content: { +function parseBody (body = {}, method) { + // Swagger validation return an error if GET has body + if (['GET'].includes(method)) return {} + const { mode, raw } = body + let content = {} + switch (mode) { + case 'raw': + content = { 'application/json': { schema: { type: 'object', - example: JSON.parse(body.raw) + example: JSON.parse(raw) } } } - } - } else { - return { - content: { + break + case 'file': + content = { 'text/plain': {} } - } + break + default: + content = {} + break } + return { requestBody: { content } } +} + +function parseParams (query = []) { + const parameters = query.map(({ key, description }) => ({ + name: key, + in: 'query', + schema: { + type: 'string' + }, + ...(description ? { description } : {}) + })) + return (parameters.length) ? { parameters } : {} } function getVarValue (variables, name, def) { diff --git a/test/index.spec.js b/test/index.spec.js index a6628c4..6b7770c 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -8,16 +8,18 @@ const { readFileSync, existsSync, unlinkSync } = require('fs') const OUTPUT_PATH = path.join(__dirname, '/openAPIRes.yml') -const COLLECTION_BASIC = './test/resources/input/PostmantoOpenAPI.postman_collection.json' +const COLLECTION_BASIC = './test/resources/input/PostmantoOpenAPI.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 COLLECTION_GET = './test/resources/input/GetMethods.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') +const EXPECTED_GET_METHODS = readFileSync('./test/resources/output/GetMethods.yml', 'utf8') describe('Library specs', function () { afterEach('remove file', function () { @@ -62,4 +64,12 @@ describe('Library specs', function () { const result = await postmanToOpenApi(COLLECTION_FOLDERS, OUTPUT_PATH) equal(EXPECTED_FOLDERS, result) }) + + it('should parse GET methods with query string', async function () { + const result = await postmanToOpenApi(COLLECTION_GET, OUTPUT_PATH) + equal(EXPECTED_GET_METHODS, result) + }) + + // other types of params + // do something about mandatory params? }) diff --git a/test/resources/input/GetMethods.json b/test/resources/input/GetMethods.json new file mode 100644 index 0000000..73b34f4 --- /dev/null +++ b/test/resources/input/GetMethods.json @@ -0,0 +1,70 @@ +{ + "info": { + "_postman_id": "2c1cccde-7a4d-4dea-bcd8-ce39544b0432", + "name": "Get Methods", + "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/users?age=45&name=Jhon&review=true", + "protocol": "https", + "host": [ + "api", + "io" + ], + "path": [ + "users" + ], + "query": [ + { + "key": "age", + "value": "45", + "description": "Filter by age" + }, + { + "key": "name", + "value": "Jhon", + "description": "Filter by name" + }, + { + "key": "review", + "value": "true", + "description": "Indicate if should be reviewed or not" + } + ] + }, + "description": "Obtain a list of users that fullfill the conditions of the filters" + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "id": "631b8a30-dcaf-449a-9f2e-83a9f13044ae", + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "id": "b43e5a36-2b9e-47a0-aab9-edc036b968a6", + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "protocolProfileBehavior": {} +} \ No newline at end of file diff --git a/test/resources/input/PostmantoOpenAPI.postman_collection.json b/test/resources/input/PostmantoOpenAPI.json similarity index 100% rename from test/resources/input/PostmantoOpenAPI.postman_collection.json rename to test/resources/input/PostmantoOpenAPI.json diff --git a/test/resources/output/GetMethods.yml b/test/resources/output/GetMethods.yml new file mode 100644 index 0000000..09eac1b --- /dev/null +++ b/test/resources/output/GetMethods.yml @@ -0,0 +1,33 @@ +openapi: 3.0.0 +info: + title: Get Methods + description: API to manage GET methods + version: 1.0.0 +paths: + /users: + get: + tags: + - default + summary: Get list of users + description: Obtain a list of users that fullfill the conditions of the filters + parameters: + - name: age + in: query + schema: + type: string + description: Filter by age + - name: name + in: query + schema: + type: string + description: Filter by name + - name: review + in: query + schema: + type: string + description: Indicate if should be reviewed or not + responses: + '200': + description: Successful response + content: + application/json: {}