Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #121 from postmanlabs/feature/php-httprequest
Added PHP-HttpRequest2 codegen
- Loading branch information
Showing
20 changed files
with
2,265 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,43 @@ | |||
.DS_Store | |||
# Logs | |||
logs | |||
*.log | |||
npm-debug.log* | |||
yarn-debug.log* | |||
yarn-error.log* | |||
|
|||
# Coverage directory used by tools like istanbul | |||
.coverage | |||
|
|||
# node-waf configuration | |||
.lock-wscript | |||
|
|||
|
|||
# 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/ | |||
|
|||
codesnippet.php |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,76 @@ | |||
### NPM Specific: Disregard recursive project files | |||
### =============================================== | |||
/.editorconfig | |||
/.gitmodules | |||
/test | |||
|
|||
### Borrowed from .gitignore | |||
### ======================== | |||
|
|||
# Logs | |||
logs | |||
*.log | |||
npm-debug.log* | |||
yarn-debug.log* | |||
yarn-error.log* | |||
|
|||
# Runtime data | |||
pids | |||
*.pid | |||
*.seed | |||
*.pid.lock | |||
|
|||
# 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 | |||
|
|||
snippet.swift | |||
|
|||
out/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,42 @@ | |||
|
|||
> Converts Postman-SDK Request into code snippet for . | |||
#### Prerequisites | |||
To run Code-Gen, ensure that you have NodeJS >= v8. 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 swift code snippet. | |||
|
|||
### convert function | |||
Convert function takes three parameters | |||
|
|||
* `request` - Postman-SDK Request Object | |||
|
|||
* `options` - options is an object which hsa following properties | |||
* `indentType` - String denoting type of indentation for code snippet. eg: 'Space', 'Tab' | |||
* `indentCount` - The number of indentation characters to add per code level | |||
* `trimRequestBody` - Whether or not request body fields should be trimmed | |||
|
|||
* `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 = { | |||
indentCount: 3, | |||
indentType: 'Space', | |||
requestTimeout: 200, | |||
trimRequestBody: true | |||
}; | |||
convert(request, options, function(error, snippet) { | |||
if (error) { | |||
// handle error | |||
} | |||
// handle snippet | |||
}); | |||
``` | |||
### Guidelines for using generated snippet | |||
|
|||
* 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1 @@ | |||
module.exports = require('./lib'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,193 @@ | |||
var _ = require('./lodash'), | |||
parseBody = require('./util/parseBody'), | |||
sanitize = require('./util/sanitize').sanitize, | |||
sanitizeOptions = require('./util/sanitize').sanitizeOptions, | |||
addFormParam = require('./util/sanitize').addFormParam, | |||
self; | |||
const ALLOWED_METOHDS = [ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT']; | |||
|
|||
/** | |||
* Used to get the headers and put them in the desired form of the language | |||
* | |||
* @param {Object} request - postman SDK-request object | |||
* @param {String} indentation - used for indenting snippet's structure | |||
* @returns {String} - request headers in the desired format | |||
*/ | |||
function getHeaders (request, indentation) { | |||
var headerArray = request.toJSON().header, | |||
headerMap; | |||
|
|||
if (!_.isEmpty(headerArray)) { | |||
headerArray = _.reject(headerArray, 'disabled'); | |||
headerMap = _.map(headerArray, function (header) { | |||
return `${indentation}'${sanitize(header.key)}' => ` + | |||
`'${sanitize(header.value)}'`; | |||
}); | |||
return `$request->setHeader(array(\n${headerMap.join(',\n')}\n));\n`; | |||
} | |||
return ''; | |||
} | |||
self = module.exports = { | |||
/** | |||
* @returns {Array} plugin specific options | |||
*/ | |||
getOptions: function () { | |||
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', | |||
default: 'Space', | |||
availableOptions: ['Tab', '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: '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: 'Follow redirects', | |||
id: 'followRedirect', | |||
type: 'boolean', | |||
default: true, | |||
description: 'Automatically follow HTTP redirects' | |||
} | |||
]; | |||
}, | |||
convert: function (request, options, callback) { | |||
if (_.isFunction(options)) { | |||
callback = options; | |||
options = {}; | |||
} | |||
if (!_.isFunction(callback)) { | |||
throw new Error('PHP-HttpRequest2-Converter: callback is not valid function'); | |||
} | |||
options = sanitizeOptions(options, self.getOptions()); | |||
|
|||
var snippet, indentString; | |||
indentString = options.indentType === 'Tab' ? '\t' : ' '; | |||
indentString = indentString.repeat(options.indentCount); | |||
|
|||
snippet = '<?php\n'; | |||
snippet += 'require_once \'HTTP/Request2.php\';\n'; | |||
snippet += '$request = new HTTP_Request2();\n'; | |||
snippet += `$request->setUrl('${sanitize(request.url.toString())}');\n`; | |||
snippet += '$request->setMethod('; | |||
if (ALLOWED_METOHDS.includes(request.method)) { | |||
snippet += `HTTP_Request2::METHOD_${request.method});\n`; | |||
} | |||
else { | |||
snippet += `'${request.method}');\n`; | |||
} | |||
|
|||
if (options.requestTimeout !== 0 || options.followRedirect) { | |||
let configArray = []; | |||
|
|||
// PHP-HTTP_Request2 method accepts timeout in seconds and it must be an integer | |||
if (options.requestTimeout !== 0 && Number.isInteger(options.requestTimeout / 1000)) { | |||
let requestTimeout = options.requestTimeout; | |||
requestTimeout /= 1000; | |||
configArray.push(`${indentString}'timeout' => ${requestTimeout}`); | |||
} | |||
if (options.followRedirect) { | |||
configArray.push(`${indentString}'follow_redirects' => TRUE`); | |||
} | |||
if (configArray.length) { | |||
snippet += '$request->setConfig(array(\n'; | |||
snippet += configArray.join(',\n') + '\n'; | |||
} | |||
snippet += '));\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' | |||
}); | |||
} | |||
} | |||
// add the headers to snippet | |||
snippet += getHeaders(request, indentString); | |||
|
|||
// 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 | |||
}); | |||
} | |||
// add the body to snippet | |||
if (!_.isEmpty(request.body)) { | |||
snippet += `${parseBody(request.toJSON(), indentString, options.trimRequestBody)}`; | |||
} | |||
snippet += 'try {\n'; | |||
snippet += `${indentString}$response = $request->send();\n`; | |||
snippet += `${indentString}if ($response->getStatus() == 200) {\n`; | |||
snippet += `${indentString.repeat(2)}echo $response->getBody();\n`; | |||
snippet += `${indentString}}\n${indentString}else {\n`; | |||
snippet += `${indentString.repeat(2)}echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .\n`; | |||
snippet += `${indentString.repeat(2)}$response->getReasonPhrase();\n`; | |||
snippet += `${indentString}}\n`; | |||
snippet += '}\ncatch(HTTP_Request2_Exception $e) {\n'; | |||
snippet += `${indentString}echo 'Error: ' . $e->getMessage();\n}`; | |||
return callback(null, snippet); | |||
} | |||
}; |
Oops, something went wrong.