Skip to content

Created Code Generator for React JS in reference to issue #351 #473

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
69 changes: 69 additions & 0 deletions codegens/reactjs-axios/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.DS_Store
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# temporarily generated file
run.js

# Prevent IDE stuff
.idea
.vscode
*.sublime-*

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
.coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

out/
67 changes: 67 additions & 0 deletions codegens/reactjs-axios/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# codegen-Reactjs-axios

> Converts Postman-SDK Request into code snippet for ReactJS-axios.

#### Prerequisites
To run the module, ensure that you have NodeJS >= v12. A copy of the NodeJS installable can be downloaded from https://nodejs.org/en/download/package-manager.

## Using the Module
The module will expose an object which will have property `convert` which is the function for converting the Postman-SDK request to nodejs-axios code snippet and `getOptions` function which returns an array of supported options.

### convert function
Convert function will take three parameters
* `request`- Postman-SDK Request object

* `options`- options is an object which can have following properties
* `indentType`- String denoting type of indentation for code snippet. eg: 'Space', 'Tab'
* `indentCount`- positiveInteger representing count of indentation required.
* `requestTimeout` : Integer denoting time after which the request will bail out in milli-seconds
* `trimRequestBody` : Trim request body fields
* `followRedirect` : Boolean denoting whether to redirect a request

* `callback`- callback function with first parameter as error and second parameter as string for code snippet

##### Example:
```js
var request = new sdk.Request('www.google.com'), //using postman sdk to create request
options = {
indentType: 'Space',
indentCount: 2,
ES6_enabled: true
};
convert(request, options, function(error, snippet) {
if (error) {
// handle error
}
// handle snippet
});
```

### getOptions function

This function returns a list of options supported by this codegen.

#### Example
```js
var options = getOptions();

console.log(options);
// output
// [
// {
// name: 'Set indentation count',
// id: 'indentCount',
// type: 'positiveInteger',
// default: 2,
// description: 'Set the number of indentation characters to add per code level'
// },
// ...
// ]
```

### Guideline for using generated snippet
* Generated snippet requires `axios`, `form-data`, `qs` and `fs` modules.

* Since Postman-SDK Request object doesn't provide complete path of the file, it needs to be manually inserted in case of uploading a file.

* This module doesn't support cookies.
1 change: 1 addition & 0 deletions codegens/reactjs-axios/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./lib');
227 changes: 227 additions & 0 deletions codegens/reactjs-axios/lib/axios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
const _ = require('./lodash');
const parseRequest = require('./parseRequest');
const sanitize = require('./util').sanitize;
const sanitizeOptions = require('./util').sanitizeOptions;
const addFormParam = require('./util').addFormParam;

/**
* returns snippet of nodejs(axios) by parsing data from Postman-SDK request object
*
* @param {Object} request - Postman SDK request object
* @param {String} indentString - indentation required for code snippet
* @param {Object} options
* @returns {String} - nodejs(axios) code snippet for given request object
*/
function makeSnippet (request, indentString, options) {

var snippet ="",
configArray = [],
dataSnippet = '',
body,
headers;

snippet += 'import axios from \'axios\' ;\n';
if (request.body && !request.headers.has('Content-Type')) {
if (request.body.mode === 'file') {
request.addHeader({
key: 'Content-Type',
value: 'text/plain'
});
}
else if (request.body.mode === 'graphql') {
request.addHeader({
key: 'Content-Type',
value: 'application/json'
});
}
}

// The following code handles multiple files in the same formdata param.
// It removes the form data params where the src property is an array of filepath strings
// Splits that array into different form data params with src set as a single filepath string
if (request.body && request.body.mode === 'formdata') {
let formdata = request.body.formdata,
formdataArray = [];
formdata.members.forEach((param) => {
let key = param.key,
type = param.type,
disabled = param.disabled,
contentType = param.contentType;
// check if type is file or text
if (type === 'file') {
// if src is not of type string we check for array(multiple files)
if (typeof param.src !== 'string') {
// if src is an array(not empty), iterate over it and add files as separate form fields
if (Array.isArray(param.src) && param.src.length) {
param.src.forEach((filePath) => {
addFormParam(formdataArray, key, param.type, filePath, disabled, contentType);
});
}
// if src is not an array or string, or is an empty array, add a placeholder for file path(no files case)
else {
addFormParam(formdataArray, key, param.type, '/path/to/file', disabled, contentType);
}
}
// if src is string, directly add the param with src as filepath
else {
addFormParam(formdataArray, key, param.type, param.src, disabled, contentType);
}
}
// if type is text, directly add it to formdata array
else {
addFormParam(formdataArray, key, param.type, param.value, disabled, contentType);
}
});

request.body.update({
mode: 'formdata',
formdata: formdataArray
});
}

body = request.body && request.body.toJSON();

dataSnippet = !_.isEmpty(body) ? parseRequest.parseBody(body,
options.trimRequestBody,
indentString,
request.headers.get('Content-Type'),
options.ES6_enabled) : '';
snippet += dataSnippet + '\n';

configArray.push(indentString + `method: '${request.method.toLowerCase()}'`);
configArray.push(indentString + `url: '${sanitize(request.url.toString())}'`);

headers = parseRequest.parseHeader(request, indentString);
// https://github.com/axios/axios/issues/789#issuecomment-577177492
if (!_.isEmpty(body) && body.formdata) {
// we can assume that data object is filled up
headers.push(`${indentString.repeat(2)}...data.getHeaders()`);
}
let headerSnippet = indentString + 'headers: { ';
if (headers.length > 0) {
headerSnippet += '\n';
headerSnippet += headers.join(', \n') + '\n';
headerSnippet += indentString + '}';
}
else {
headerSnippet += '}';
}

configArray.push(headerSnippet);

if (options.requestTimeout) {
configArray.push(indentString + `timeout: ${options.requestTimeout}`);
}
if (options.followRedirect === false) {
// setting the maxRedirects to 0 will disable any redirects.
// by default, maxRedirects are set to 5
configArray.push(indentString + 'maxRedirects: 0');
}
if (dataSnippet !== '') {
// although just data is enough, whatever :shrug:
configArray.push(indentString + 'data : data');
}
snippet+=(options.ES6_enabled?"let":"var");
snippet += ' config = {\n';
snippet += configArray.join(',\n') + '\n';
snippet += '};\n\n';
snippet+=(options.ES6_enabled?"let":"var");
snippet+=" Apicall = async ()=>{ \n";
snippet+=indentString+"try { \n";
snippet+=indentString+indentString+(options.ES6_enabled?"let":"var")+" response =";
snippet += 'await axios(config) ;\n';
snippet += indentString+indentString + 'console.log(JSON.stringify(response.data));\n';
snippet += indentString+'}catch(err){\n';
snippet += indentString +indentString+ 'console.log(err);\n';
snippet += indentString+'};\n';
snippet+='};\n\n';
snippet+="Apicall();";
return snippet;
}

/**
* Used to get the options specific to this codegen
*
* @returns {Array} - Returns an array of option objects
*/
function getOptions () {
return [
{
name: 'Set indentation count',
id: 'indentCount',
type: 'positiveInteger',
default: 2,
description: 'Set the number of indentation characters to add per code level'
},
{
name: 'Set indentation type',
id: 'indentType',
type: 'enum',
availableOptions: ['Tab', 'Space'],
default: 'Space',
description: 'Select the character used to indent lines of code'
},
{
name: 'Set request timeout',
id: 'requestTimeout',
type: 'positiveInteger',
default: 0,
description: 'Set number of milliseconds the request should wait for a response' +
' before timing out (use 0 for infinity)'
},
{
name: 'Follow redirects',
id: 'followRedirect',
type: 'boolean',
default: true,
description: 'Automatically follow HTTP redirects'
},
{
name: 'Trim request body fields',
id: 'trimRequestBody',
type: 'boolean',
default: false,
description: 'Remove white space and additional lines that may affect the server\'s response'
},
{
name: 'Enable ES6 features',
id: 'ES6_enabled',
type: 'boolean',
default: false,
description: 'Modifies code snippet to incorporate ES6 (EcmaScript) features'
}
];
}


/**
* Converts Postman sdk request object to nodejs axios code snippet
*
* @param {Object} request - postman-SDK request object
* @param {Object} options
* @param {String} options.indentType - type for indentation eg: Space, Tab
* @param {String} options.indentCount - number of spaces or tabs for indentation.
* @param {Boolean} options.followRedirect - whether to enable followredirect
* @param {Boolean} options.trimRequestBody - whether to trim fields in request body or not
* @param {Number} options.requestTimeout : time in milli-seconds after which request will bail out
* @param {Function} callback - callback function with parameters (error, snippet)
*/
function convert (request, options, callback) {
if (!_.isFunction(callback)) {
throw new Error('ReactJS-Axios-Converter : callback is not valid function');
}
options = sanitizeOptions(options, getOptions());

// String representing value of indentation required
var indentString;

indentString = options.indentType === 'Tab' ? '\t' : ' ';
indentString = indentString.repeat(options.indentCount);

return callback(null, makeSnippet(request, indentString, options));
}

module.exports = {
convert: convert,
getOptions: getOptions
};
4 changes: 4 additions & 0 deletions codegens/reactjs-axios/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
convert: require('./axios').convert,
getOptions: require('./axios').getOptions
};
Loading