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

Commit 0ed6a0a

Browse files
committed
feat: Servers cfg #10 CONFIG
Final implementation of servers list
1 parent 07e68df commit 0ed6a0a

5 files changed

Lines changed: 236 additions & 18 deletions

File tree

docs/index.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,25 @@ The global authorization info can be parse from the Postman collection as descri
131131
}
132132
```
133133

134+
### servers (Array)
135+
136+
The global servers list can be parse from the Postman collection as described in [Global servers configuration](#global-servers-configuration) section, but you can customize this info using the `servers` option, this param is an array of objects that follow the structure of OpenAPI [Server Objects](https://swagger.io/specification/#server-object), only `url` and `description` field are supported in this moment, as an example of how to use this option:
137+
138+
```js
139+
{
140+
servers: [
141+
{
142+
url: 'https://awesome.api.sandbox.io',
143+
description: 'Sandbox environment server'
144+
},
145+
{
146+
url: 'https://awesome.api.io',
147+
description: 'Production environment server'
148+
}
149+
]
150+
}
151+
```
152+
134153
</div></div>
135154
<div class="tilted-section"><div markdown="1">
136155

@@ -178,6 +197,18 @@ You can customize the global authorization definition using the [Auth option](#a
178197

179198
Have a look to the collections [AuthBasic](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/AuthBasic.json) and [AuthBearer](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/AuthBearer.json) for examples of how to use this feature.
180199

200+
## Global servers configuration
201+
202+
The OpenAPI root [servers](https://swagger.io/specification/#openapi-object) definition is filled parsing the urls used in the Postman collections requests, the library use all the different urls for create an array of server (removing duplicated), but normally this is not to usefully as Postman collection only will have one environment url, for this reason you can customize the global servers definition using the [server option](#servers-(array))
203+
204+
If you don't want to include a `servers` array in your OpenAPI spec file you just need to pass an empty array as server option, as for example:
205+
206+
```js
207+
const result = await postmanToOpenApi(postmanCollection, outputFile, { servers: [] })
208+
```
209+
210+
This will remove the `servers` field from the yml specification result.
211+
181212
</div></div>
182213
<div class="tilted-section"><div markdown="1">
183214

lib/index.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const { promises: { writeFile, readFile } } = require('fs')
44
const { safeDump } = require('js-yaml')
55

6-
async function postmanToOpenApi (input, output, { save = true, info = {}, defaultTag = 'default', auth } = {}) {
6+
async function postmanToOpenApi (input, output, { save = true, info = {}, defaultTag = 'default', auth, servers } = {}) {
77
// TODO validate?
88
const collectionFile = await readFile(input)
99
const postmanJson = JSON.parse(collectionFile)
@@ -45,7 +45,7 @@ async function postmanToOpenApi (input, output, { save = true, info = {}, defaul
4545
const openApi = {
4646
openapi: '3.0.0',
4747
info: compileInfo(postmanJson, info),
48-
...parseServers(domains),
48+
...parseServers(domains, servers),
4949
...parseAuth(postmanJson, auth),
5050
paths
5151
}
@@ -216,10 +216,15 @@ function calculateDomains (protocol, hosts) {
216216
return protocol + '://' + hosts.join('.')
217217
}
218218

219-
/* Parse domains from operations for servers root array */
220-
function parseServers (domains) {
221-
const servers = Array.from(domains).map(domain => ({ url: domain }))
222-
return { servers }
219+
/* Parse domains from operations or options */
220+
function parseServers (domains, serversOpts) {
221+
let servers
222+
if (serversOpts != null) {
223+
servers = serversOpts.map(({ url, description }) => ({ url, description }))
224+
} else {
225+
servers = Array.from(domains).map(domain => ({ url: domain }))
226+
}
227+
return (servers.length > 0) ? { servers } : {}
223228
}
224229

225230
module.exports = postmanToOpenApi

test/index.spec.js

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const EXPECTED_AUTH_BASIC = readFileSync('./test/resources/output/AuthBasic.yml'
3131
const EXPECTED_BASIC_WITH_AUTH = readFileSync('./test/resources/output/BasicWithAuth.yml', 'utf8')
3232
const EXPECTED_PATH_PARAMS = readFileSync('./test/resources/output/PathParams.yml', 'utf8')
3333
const EXPECTED_MULTIPLE_SERVERS = readFileSync('./test/resources/output/MultipleServers.yml', 'utf8')
34+
const EXPECTED_SERVERS_OPTIONS = readFileSync('./test/resources/output/ServersOpts.yml', 'utf8')
35+
const EXPECTED_NO_SERVERS = readFileSync('./test/resources/output/NoServers.yml', 'utf8')
3436

3537
describe('Library specs', function () {
3638
afterEach('remove file', function () {
@@ -41,7 +43,7 @@ describe('Library specs', function () {
4143

4244
it('should work with a basic transform', async function () {
4345
const result = await postmanToOpenApi(COLLECTION_BASIC, OUTPUT_PATH, {})
44-
equal(EXPECTED_BASIC, result)
46+
equal(result, EXPECTED_BASIC)
4547
ok(existsSync(OUTPUT_PATH))
4648
})
4749

@@ -58,42 +60,42 @@ describe('Library specs', function () {
5860
termsOfService: 'http://tos.myweb.com'
5961
}
6062
})
61-
equal(EXPECTED_INFO_OPTS, result)
63+
equal(result, EXPECTED_INFO_OPTS)
6264
})
6365

6466
it('should use default version if not informed and not in postman variables', async function () {
6567
const result = await postmanToOpenApi(COLLECTION_NO_VERSION, OUTPUT_PATH, {})
66-
equal(EXPECTED_NO_VERSION, result)
68+
equal(result, EXPECTED_NO_VERSION)
6769
})
6870

6971
it('should use "defaultTag" provided by config', async function () {
7072
const result = await postmanToOpenApi(COLLECTION_SIMPLE, OUTPUT_PATH, { defaultTag: 'Custom Tag' })
71-
equal(EXPECTED_CUSTOM_TAG, result)
73+
equal(result, EXPECTED_CUSTOM_TAG)
7274
})
7375

7476
it('should work with folders and use as tags', async function () {
7577
const result = await postmanToOpenApi(COLLECTION_FOLDERS, OUTPUT_PATH)
76-
equal(EXPECTED_FOLDERS, result)
78+
equal(result, EXPECTED_FOLDERS)
7779
})
7880

7981
it('should parse GET methods with query string', async function () {
8082
const result = await postmanToOpenApi(COLLECTION_GET, OUTPUT_PATH)
81-
equal(EXPECTED_GET_METHODS, result)
83+
equal(result, EXPECTED_GET_METHODS)
8284
})
8385

8486
it('should parse HEADERS parameters', async function () {
8587
const result = await postmanToOpenApi(COLLECTION_HEADERS, OUTPUT_PATH)
86-
equal(EXPECTED_HEADERS, result)
88+
equal(result, EXPECTED_HEADERS)
8789
})
8890

8991
it('should parse global authorization (Bearer)', async function () {
9092
const result = await postmanToOpenApi(COLLECTION_AUTH_BEARER, OUTPUT_PATH)
91-
equal(EXPECTED_AUTH_BEARER, result)
93+
equal(result, EXPECTED_AUTH_BEARER)
9294
})
9395

9496
it('should parse global authorization (Basic)', async function () {
9597
const result = await postmanToOpenApi(COLLECTION_AUTH_BASIC, OUTPUT_PATH)
96-
equal(EXPECTED_AUTH_BASIC, result)
98+
equal(result, EXPECTED_AUTH_BASIC)
9799
})
98100

99101
it('should use global authorization by configuration', async function () {
@@ -111,16 +113,37 @@ describe('Library specs', function () {
111113
}
112114
}
113115
const result = await postmanToOpenApi(COLLECTION_BASIC, OUTPUT_PATH, { auth: authDefinition })
114-
equal(EXPECTED_BASIC_WITH_AUTH, result)
116+
equal(result, EXPECTED_BASIC_WITH_AUTH)
115117
})
116118

117119
it('should parse path params', async function () {
118120
const result = await postmanToOpenApi(COLLECTION_PATH_PARAMS, OUTPUT_PATH)
119-
equal(EXPECTED_PATH_PARAMS, result)
121+
equal(result, EXPECTED_PATH_PARAMS)
120122
})
121123

122124
it('should parse servers from existing host in postman collection', async function () {
123125
const result = await postmanToOpenApi(COLLECTION_MULTIPLE_SERVERS, OUTPUT_PATH)
124-
equal(EXPECTED_MULTIPLE_SERVERS, result)
126+
equal(result, EXPECTED_MULTIPLE_SERVERS)
127+
})
128+
129+
it('should use servers from options', async function () {
130+
const result = await postmanToOpenApi(COLLECTION_MULTIPLE_SERVERS, OUTPUT_PATH, {
131+
servers: [
132+
{
133+
url: 'https://awesome.api.sandbox.io',
134+
description: 'Sandbox environment server'
135+
},
136+
{
137+
url: 'https://awesome.api.io',
138+
description: 'Production env'
139+
}
140+
]
141+
})
142+
equal(result, EXPECTED_SERVERS_OPTIONS)
143+
})
144+
145+
it('should allow empty servers from options', async function () {
146+
const result = await postmanToOpenApi(COLLECTION_MULTIPLE_SERVERS, OUTPUT_PATH, { servers: [] })
147+
equal(result, EXPECTED_NO_SERVERS)
125148
})
126149
})
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
openapi: 3.0.0
2+
info:
3+
title: MultipleServers
4+
description: Collection to test multiples server parsing.
5+
version: 1.1.0
6+
paths:
7+
/users:
8+
post:
9+
tags:
10+
- default
11+
summary: Create new User
12+
description: Create a new user into your amazing API
13+
requestBody:
14+
content:
15+
application/json:
16+
schema:
17+
type: object
18+
example:
19+
example: field
20+
other:
21+
data1: 'yes'
22+
data2: 'no'
23+
responses:
24+
'200':
25+
description: Successful response
26+
content:
27+
application/json: {}
28+
put:
29+
tags:
30+
- default
31+
summary: Update User
32+
description: Update an existing user
33+
requestBody:
34+
content:
35+
application/json:
36+
schema:
37+
type: object
38+
example:
39+
example: field
40+
other:
41+
data1: 'yes'
42+
data2: 'no'
43+
responses:
44+
'200':
45+
description: Successful response
46+
content:
47+
application/json: {}
48+
/posts:
49+
post:
50+
tags:
51+
- default
52+
summary: Create a post
53+
requestBody:
54+
content:
55+
text/plain: {}
56+
responses:
57+
'200':
58+
description: Successful response
59+
content:
60+
application/json: {}
61+
/note:
62+
post:
63+
tags:
64+
- default
65+
summary: Create a note
66+
description: Just an example of text raw body
67+
requestBody:
68+
content:
69+
application/json:
70+
schema:
71+
type: string
72+
example: This is an example Note
73+
responses:
74+
'200':
75+
description: Successful response
76+
content:
77+
application/json: {}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
openapi: 3.0.0
2+
info:
3+
title: MultipleServers
4+
description: Collection to test multiples server parsing.
5+
version: 1.1.0
6+
servers:
7+
- url: 'https://awesome.api.sandbox.io'
8+
description: Sandbox environment server
9+
- url: 'https://awesome.api.io'
10+
description: Production env
11+
paths:
12+
/users:
13+
post:
14+
tags:
15+
- default
16+
summary: Create new User
17+
description: Create a new user into your amazing API
18+
requestBody:
19+
content:
20+
application/json:
21+
schema:
22+
type: object
23+
example:
24+
example: field
25+
other:
26+
data1: 'yes'
27+
data2: 'no'
28+
responses:
29+
'200':
30+
description: Successful response
31+
content:
32+
application/json: {}
33+
put:
34+
tags:
35+
- default
36+
summary: Update User
37+
description: Update an existing user
38+
requestBody:
39+
content:
40+
application/json:
41+
schema:
42+
type: object
43+
example:
44+
example: field
45+
other:
46+
data1: 'yes'
47+
data2: 'no'
48+
responses:
49+
'200':
50+
description: Successful response
51+
content:
52+
application/json: {}
53+
/posts:
54+
post:
55+
tags:
56+
- default
57+
summary: Create a post
58+
requestBody:
59+
content:
60+
text/plain: {}
61+
responses:
62+
'200':
63+
description: Successful response
64+
content:
65+
application/json: {}
66+
/note:
67+
post:
68+
tags:
69+
- default
70+
summary: Create a note
71+
description: Just an example of text raw body
72+
requestBody:
73+
content:
74+
application/json:
75+
schema:
76+
type: string
77+
example: This is an example Note
78+
responses:
79+
'200':
80+
description: Successful response
81+
content:
82+
application/json: {}

0 commit comments

Comments
 (0)