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

Commit

Permalink
feat: paths deep by cfg #8
Browse files Browse the repository at this point in the history
Closes #8
  • Loading branch information
joolfe committed Aug 18, 2020
1 parent a90c4a1 commit 0110b59
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 7 deletions.
17 changes: 17 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- Global Authorization parse or by configuration (Basic and Bearer).
- Contact and License from variables or by configuration.
- Provide meta-information as a markdown table.
- Path depth configuration.

See [Features](#features) section for more details about how to use each of this features.

Expand Down Expand Up @@ -131,6 +132,22 @@ If you want to customize the default tag use the options `defaultTag` to indicat
const result = await postmanToOpenApi(postmanCollection, outputFile, { defaultTag: 'API' })
```

### pathDepth (number)

Sometimes the URL of an API depends of environments prefix or accounts id that are not part of the resource path, as for example `http://api.io/dev/users`, `http://api.io/acc/235647467/users` or `http://api.io/v2/users`, by default this will results in Paths as `/dev/users`, `/acc/235647467/users` and `/v2/users`.

To indicate the library that you want to avoid this prefixes to be part of the OpenAPI operation path you can use the `pathDepth` option, this option is a integer value that indicates how many paths/prefixs should be jump in the parse from the domain, as an example:

```js
// Having a postman request with the url "http://api.io/dev/users"
const result = await postmanToOpenApi(postmanCollection, outputFile, { pathDepth: 1 })
// Will result in a path of "/users"
const result = await postmanToOpenApi(postmanCollection, outputFile, { pathDepth: 0 })
// Will result in a path of "/dev/users"
```

The default value is `0`, so all prefix will be added to Open APi operations Paths.

### auth (Object)

The global authorization info can be parse from the Postman collection as described in [Global authorization](#global-authorization) section, but you can customize this info using the `auth` option, this param is a Object that follow the structure of OpenAPI [Security Scheme](https://swagger.io/specification/#security-scheme-object), in this moment only type `http` is supported and schemes `basic` and `bearer`, as an example of this option:
Expand Down
7 changes: 4 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { promises: { writeFile, readFile } } = require('fs')
const { safeDump } = require('js-yaml')
const { parseMdTable } = require('./md-utils')

async function postmanToOpenApi (input, output, { info = {}, defaultTag = 'default', auth, servers } = {}) {
async function postmanToOpenApi (input, output, { info = {}, defaultTag = 'default', pathDepth = 0, auth, servers } = {}) {
// TODO validate?
const collectionFile = await readFile(input)
const postmanJson = JSON.parse(collectionFile)
Expand All @@ -26,7 +26,7 @@ async function postmanToOpenApi (input, output, { info = {}, defaultTag = 'defau
name: summary, tag = defaultTag
} = element
domains.add(calculateDomains(protocol, host))
const joinedPath = calculatePath(path)
const joinedPath = calculatePath(path, pathDepth)
if (!paths[joinedPath]) paths[joinedPath] = {}
const { description, paramsMeta } = descriptionParse(rawDesc)

Expand Down Expand Up @@ -246,7 +246,8 @@ function parseOptsAuth (optAuth) {
}

/* From the path array compose the real path for OpenApi specs */
function calculatePath (paths) {
function calculatePath (paths, pathDepth) {
paths = paths.slice(pathDepth) // path depth
// replace repeated '{' and '}' chars
return '/' + paths.map(path => path.replace(/([{}])\1+/g, '$1'))
.join('/')
Expand Down
11 changes: 7 additions & 4 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const COLLECTION_AUTH_BASIC = './test/resources/input/AuthBasic.json'
const COLLECTION_PATH_PARAMS = './test/resources/input/PathParams.json'
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 EXPECTED_BASIC = readFileSync('./test/resources/output/Basic.yml', 'utf8')
const EXPECTED_INFO_OPTS = readFileSync('./test/resources/output/InfoOpts.yml', 'utf8')
Expand All @@ -38,6 +39,7 @@ const EXPECTED_LICENSE_CONTACT = readFileSync('./test/resources/output/LicenseCo
const EXPECTED_LICENSE_CONTACT_OPT = readFileSync('./test/resources/output/LicenseContactOpts.yml', 'utf8')
const EXPECTED_LICENSE_CONTACT_PARTIAL = readFileSync('./test/resources/output/LicenseContactPartial.yml', 'utf8')
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')

describe('Library specs', function () {
afterEach('remove file', function () {
Expand Down Expand Up @@ -128,7 +130,6 @@ describe('Library specs', function () {

it('should parse path params', async function () {
const result = await postmanToOpenApi(COLLECTION_PATH_PARAMS, OUTPUT_PATH)
console.log(result)
equal(result, EXPECTED_PATH_PARAMS)
})

Expand Down Expand Up @@ -211,7 +212,9 @@ describe('Library specs', function () {
equal(result, EXPECTED_LICENSE_CONTACT_PARTIAL_2)
})

it('should work with multiple params in path')

it('should work with multiple paths')
it('should use depth configuration for parse paths', async function () {
const result = await postmanToOpenApi(COLLECTION_DEPTH_PATH_PARAMS, OUTPUT_PATH, { pathDepth: 1 })
console.log(result)
equal(result, EXPECTED_DEPTH_PATH_PARAMS)
})
})
103 changes: 103 additions & 0 deletions test/resources/input/DepthPathParams.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"info": {
"_postman_id": "c2a620d9-979e-4f39-b6bc-22282ce4b21a",
"name": "Large 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/dev/users/{{user_id}}",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"dev",
"users",
"{{user_id}}"
]
},
"description": "Obtain a list of users that fullfill the conditions of the filters"
},
"response": []
},
{
"name": "Get descriptions of a user",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "https://api.io/dev/user/{{user_id}}/desc/",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"dev",
"user",
"{{user_id}}",
"desc",
""
]
},
"description": "Obtain a list of users descriptions\n\n# postman-to-openapi\n\n| object | name | description | required | type | example |\n|--------|----------|--------------------------------|----------|--------|-----------|\n| path | user_id | This is just a user identifier | true | number | 476587598 |"
},
"response": []
},
{
"name": "Get a description from an user",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "https://api.io/dev/user/{{user_id}}/desc/{{desc_id}}",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"dev",
"user",
"{{user_id}}",
"desc",
"{{desc_id}}"
]
},
"description": "Obtain a list of users descriptions\n\n# postman-to-openapi\n\n| object | name | description | required | type | example |\n|--------|----------|--------------------------------|----------|--------|-----------|\n| path | user_id | This is just a user identifier | true | number | 476587598 |\n| path | desc_id | Description id | true | string | ALMT |"
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "3d4c9432-87d0-46d1-8e0a-7bf78b95838f",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "bfa95668-f3ba-423f-93d3-152fbba765af",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"protocolProfileBehavior": {}
}
70 changes: 70 additions & 0 deletions test/resources/output/DepthPathParams.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
openapi: 3.0.0
info:
title: Large Path Params
description: Collection to test path parameters
version: 1.0.0
servers:
- url: 'https://api.io'
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: {}
'/user/{user_id}/desc/':
get:
tags:
- default
summary: Get descriptions of a user
description: Obtain a list of users descriptions
parameters:
- name: user_id
in: path
schema:
type: number
required: true
description: This is just a user identifier
example: '476587598'
responses:
'200':
description: Successful response
content:
application/json: {}
'/user/{user_id}/desc/{desc_id}':
get:
tags:
- default
summary: Get a description from an user
description: Obtain a list of users descriptions
parameters:
- name: user_id
in: path
schema:
type: number
required: true
description: This is just a user identifier
example: '476587598'
- name: desc_id
in: path
schema:
type: string
required: true
description: Description id
example: ALMT
responses:
'200':
description: Successful response
content:
application/json: {}

0 comments on commit 0110b59

Please sign in to comment.