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

Commit

Permalink
feat: adding x-www-form-urlencoded support
Browse files Browse the repository at this point in the history
feat: form data encoding support
refactor: form data accumulator functions move to named functions
  • Loading branch information
devNoiseConsulting committed Jul 25, 2021
1 parent 8a26c69 commit 8311563
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 31 deletions.
76 changes: 54 additions & 22 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ function parseContact (variables, optsContact = {}) {
const { name = nameVar, url = urlVar, email = emailVar } = optsContact
return [name, url, email].some(e => e != null)
? {
contact: {
...(name ? { name } : {}),
...(url ? { url } : {}),
...(email ? { email } : {})
}
contact: {
...(name ? { name } : {}),
...(url ? { url } : {}),
...(email ? { email } : {})
}
}
: {}
}

Expand Down Expand Up @@ -169,26 +169,58 @@ function parseBody (body = {}, method) {
case "formdata":
content = {
"multipart/form-data": {
schema: {
type: "object",
properties: body.formdata.reduce((acc, v) => {
acc[v.key] = { type: v.type === 'text' ? 'string' : v.type };
if (v.hasOwnProperty("description")) {
acc[v.key].description = v.description == '' ? 'Description' : v.description;
}
if (v.hasOwnProperty("value") && v.value !== '') {
acc[v.key].example = v.value;
};
return acc;
}, {})
}
schema: {
type: "object",
properties: body.formdata.reduce(mapFormData(), {}),
encoding: body.formdata.reduce(mapFormDataEencoding(), {})
}
};
}
};
break;
case "urlencoded":
content = {
"application/x-www-form-urlencoded": {
schema: {
properties: body.urlencoded.reduce(mapFormData(), {})
}
}
};
break;
}
return { requestBody: { content } }
}

function mapFormData () {
return (data, { key, value, description, type }) => {
data[key] = { type: inferType (value) };
if (type == "file") {
data[key].type = "string";
data[key].format = "base64";
}
if (description && description !== '') {
data[key].description = description;
}
if (value && value !== '') {
data[key].example = value;
};
if (/\[required\]/gi.test(description)) {
data[key].require = true;
}
return data
}
}

function mapFormDataEencoding () {
return (data, { key, contentType }) => {
if (contentType) {
data[key] = { contentType: contentType };
} else {
data[key] = { contentType: 'text/plain' };
}
return data
}
}

/* Parse the Postman query and header and transform into OpenApi parameters */
function parseParameters (query = [], header, paths, paramsMeta = {}) {
// parse Headers
Expand Down Expand Up @@ -307,9 +339,9 @@ function parseOptsAuth (optAuth) {
return Object.keys(securitySchemes).length === 0
? {}
: {
components: { securitySchemes },
security
}
components: { securitySchemes },
security
}
}

/* From the path array compose the real path for OpenApi specs */
Expand Down
7 changes: 7 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const EXPECTED_RESPONSES_MULTI_LANG = readFileSync('./test/resources/output/Resp
const EXPECTED_AUTH_REQUEST = readFileSync('./test/resources/output/AuthRequest.yml', 'utf8')
const EXPECTED_RESPONSES_NO_HEADERS = readFileSync('./test/resources/output/ResponsesNoHeaders.yml', 'utf8')
const EXPECTED_FORM_DATA = readFileSync('./test/resources/output/FormData.yml', 'utf8')
const EXPECTED_WWW_FORM_URLENCODED = readFileSync('./test/resources/output/WwwFormUrlencoded.yml', 'utf8')

const AUTH_DEFINITIONS = {
myCustomAuth: {
Expand Down Expand Up @@ -104,6 +105,7 @@ describe('Library specs', function () {
const COLLECTION_RESPONSES_MULTI_LANG = `./test/resources/input/${version}/ResponsesMultiLang.json`
const COLLECTION_AUTH_REQUEST = `./test/resources/input/${version}/AuthRequest.json`
const COLLECTION_FORM_DATA = `./test/resources/input/${version}/FormData.json`
const COLLECTION_WWW_FORM_URLENCODED = `./test/resources/input/${version}/WwwFormUrlencoded.json`

it('should work with a basic transform', async function () {
const result = await postmanToOpenApi(COLLECTION_BASIC, OUTPUT_PATH, {})
Expand Down Expand Up @@ -402,6 +404,11 @@ describe('Library specs', function () {
const result = await postmanToOpenApi(COLLECTION_FORM_DATA, OUTPUT_PATH, {})
equal(result, EXPECTED_FORM_DATA)
})

it('should parse POST methods with www form urlencoded', async function () {
const result = await postmanToOpenApi(COLLECTION_WWW_FORM_URLENCODED, OUTPUT_PATH, {})
equal(result, EXPECTED_WWW_FORM_URLENCODED)
})
})
})

Expand Down
12 changes: 9 additions & 3 deletions test/resources/input/v2/FormData.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,26 @@
{
"key": "name",
"value": "New User",
"description": "full name of the user (accepts spaces)",
"description": "full name of the user (accepts spaces) [required]",
"type": "text"
},
{
"key": "email",
"value": "newuser@example.com",
"description": "email of the user (for notifications and login)",
"description": "email of the user (for notifications and login) [required]",
"type": "text"
},
{
"key": "password",
"value": "pasword123",
"description": "password (to be used for logging in)",
"description": "password (to be used for logging in) [required]",
"type": "text"
},
{
"key": "avatar",
"contentType": "application/octet-stream",
"type": "file",
"src": []
}
]
},
Expand Down
41 changes: 41 additions & 0 deletions test/resources/input/v2/WwwFormUrlencoded.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"info": {
"_postman_id": "1eaa74c4-2d76-45f0-bd34-bff5d96f0ba8",
"name": "Form Data",
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
},
"item": [
{
"name": "Register New User",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "urlencoded",
"urlencoded": [
{
"key": "name",
"value": "New User",
"description": "full name of the user (accepts spaces) [required]",
"type": "text"
},
{
"key": "email",
"value": "newuser@example.com",
"description": "email of the user (for notifications and login) [required]",
"type": "text"
},
{
"key": "password",
"value": "pasword123",
"description": "password (to be used for logging in) [required]",
"type": "text"
}
]
},
"url": "https://api.io/register"
},
"response": []
}
]
}
12 changes: 9 additions & 3 deletions test/resources/input/v21/FormData.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,26 @@
{
"key": "name",
"value": "New User",
"description": "full name of the user (accepts spaces)",
"description": "full name of the user (accepts spaces) [required]",
"type": "text"
},
{
"key": "email",
"value": "newuser@example.com",
"description": "email of the user (for notifications and login)",
"description": "email of the user (for notifications and login) [required]",
"type": "text"
},
{
"key": "password",
"value": "pasword123",
"description": "password (to be used for logging in)",
"description": "password (to be used for logging in) [required]",
"type": "text"
},
{
"key": "avatar",
"contentType": "application/octet-stream",
"type": "file",
"src": []
}
]
},
Expand Down
51 changes: 51 additions & 0 deletions test/resources/input/v21/WwwFormUrlencoded.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"info": {
"_postman_id": "1eaa74c4-2d76-45f0-bd34-bff5d96f0ba8",
"name": "Form Data",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Register New User",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "urlencoded",
"urlencoded": [
{
"key": "name",
"value": "New User",
"description": "full name of the user (accepts spaces) [required]",
"type": "text"
},
{
"key": "email",
"value": "newuser@example.com",
"description": "email of the user (for notifications and login) [required]",
"type": "text"
},
{
"key": "password",
"value": "pasword123",
"description": "password (to be used for logging in) [required]",
"type": "text"
}
]
},
"url": {
"raw": "https://api.io/register",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"register"
]
}
},
"response": []
}
]
}
21 changes: 18 additions & 3 deletions test/resources/output/FormData.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,31 @@ paths:
properties:
name:
type: string
description: full name of the user (accepts spaces)
description: full name of the user (accepts spaces) [required]
example: New User
require: true
email:
type: string
description: email of the user (for notifications and login)
description: email of the user (for notifications and login) [required]
example: newuser@example.com
require: true
password:
type: string
description: password (to be used for logging in)
description: password (to be used for logging in) [required]
example: pasword123
require: true
avatar:
type: string
format: base64
encoding:
name:
contentType: text/plain
email:
contentType: text/plain
password:
contentType: text/plain
avatar:
contentType: application/octet-stream
responses:
'200':
description: Successful response
Expand Down
37 changes: 37 additions & 0 deletions test/resources/output/WwwFormUrlencoded.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
openapi: 3.0.0
info:
title: Form Data
version: 1.0.0
servers:
- url: https://api.io
paths:
/register:
post:
tags:
- default
summary: Register New User
requestBody:
content:
application/x-www-form-urlencoded:
schema:
properties:
name:
type: string
description: full name of the user (accepts spaces) [required]
example: New User
require: true
email:
type: string
description: email of the user (for notifications and login) [required]
example: newuser@example.com
require: true
password:
type: string
description: password (to be used for logging in) [required]
example: pasword123
require: true
responses:
'200':
description: Successful response
content:
application/json: {}

0 comments on commit 8311563

Please sign in to comment.