Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Added flag to disable output. Support forms. #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# add git-ignore syntax here of things you don't want copied into docker image

.git
node_modules
lib
yarn-error.log
33 changes: 33 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
FROM node:12

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive

# Configure apt and install packages
RUN apt-get update \
&& apt-get -y install --no-install-recommends apt-utils dialog 2>&1 \
# Remove outdated yarn from /opt and install via package
# so it can be easily updated via apt-get upgrade yarn
&& rm -rf /opt/yarn-* \
&& rm -f /usr/local/bin/yarn \
&& rm -f /usr/local/bin/yarnpkg \
&& apt-get install -y curl apt-transport-https lsb-release \
&& curl -sS https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/pubkey.gpg | apt-key add - 2>/dev/null \
&& echo "deb https://dl.yarnpkg.com/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
&& apt-get update \
&& apt-get -y install --no-install-recommends yarn \
#
# Install eslint globally
&& npm install -g eslint \
# Clean up
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*

# Switch back to dialog for any ad-hoc use of apt-get
ENV DEBIAN_FRONTEND=

WORKDIR /app
COPY . /app

CMD yarn install && yarn test && yarn build
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,36 @@ const options = {
httpToCurl(options);
```


## 3. Disable output 👁
This flag defaults to `true` and displays the output `curl` commands. You may disable output from this library.
```js
const options = {
showOutput: false
}
httpToCurl(options);
```

# Building and using the library locally
To avoid the need for installing the necessary libraries, the build can be performed within a Docker container.

### Prequisite
- Docker

### Instructions
In the project root folder, run the following commands.
```bash
docker build -t http-to-curl .
docker run --name builder -it http-to-curl
docker cp builder:/app/lib .
docker container rm builder
```

You may now reference the project directly using
```js
require('<path to project>');
```

## Contributing

We'd ❤️ to have your helping hand on http-to-curl! Feel free to PR's, add issues or give feedback! Happy Hacking!! 😎
We'd ❤️ to have your helping hand on http-to-curl! Feel free to PR's, add issues or give feedback! Happy Hacking!! 😎
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"babel-jest": "^22.4.3",
"esm": "^3.0.27",
"jest": "^22.4.3",
"nock": "^12.0.3",
"regenerator-runtime": "^0.11.1",
"rollup": "^0.58.2",
"rollup-plugin-babel": "^3.0.4",
Expand Down
34 changes: 25 additions & 9 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ export function generateHeader(options) {
let headerParam = '';
Object.keys(headers).map((val, key) => {
if (val.toLocaleLowerCase() !== 'content-length') {
headerParam += `-H "${val}: ${headers[val].replace(/(\\|")/g, '\\$1')}" `;
// contents of headers[val] is a <Buffer>, so we need to convert that back to a string
headerParam += `-H "${val}: ${headers[val].toString('utf8').replace(/(\\|")/g, '\\$1')}" `;
}
if (val.toLocaleLowerCase() === 'accept-encoding') {
isEncode = true;
Expand All @@ -59,7 +60,10 @@ export function generateHeader(options) {
*/
export function generateUrl(options = {}) {
if (!options) return '';
const { protocol = 'http:', hostname = 'localhost', pathname = '/' } = options;
var { protocol, hostname, pathname, uri } = options;
protocol = protocol || uri && uri.protocol || 'http:';
hostname = hostname || uri && uri.hostname || 'localhost';
pathname = pathname || uri && uri.pathname || '/';
return `"${protocol}//${hostname}${pathname}"`;
}

Expand Down Expand Up @@ -129,11 +133,21 @@ export function curlGenerator(options, body = '', regex) {
* @param {any} cb
* @returns
*/
export function requestPatch(regex, request, options, cb, customCallback) {
export function requestPatch(regex, request, options, cb, customCallback, showOutput) {
// Note that options may be <Object> | <string> | <URL>
// https://nodejs.org/api/https.html#https_https_request_url_options_callback
// How `https` handles the params: https://github.com/nodejs/node/blob/v12.x/lib/https.js#L281

const bodyData = [];
const clientReq = request(options, cb);

monkeypatch(clientReq, 'write', (original, chunk, encoding, cb) => {
// `chunk` is expected to be <string> | <Buffer>
// Convert <string> into <Buffer>, because bodyData should be an array of <Buffer>
// https://nodejs.org/api/http.html#http_request_write_chunk_encoding_callback
if (typeof chunk === 'string' || chunk instanceof String) {
chunk = Buffer.from(chunk, 'utf8');
}
bodyData.push(chunk);
return original(chunk, encoding, cb);
});
Expand All @@ -148,9 +162,11 @@ export function requestPatch(regex, request, options, cb, customCallback) {
}

const command = curlGenerator(options, body, regex);
console.log(`${chalk.black.bgYellow.bold(' http-to-curl ')}
${command}
`);

if (showOutput){
console.log(`${chalk.black.bgYellow.bold(' http-to-curl ')}\n ${command}\n`);
}

customCallback(command);
return original(data, encoding, cb);
});
Expand All @@ -173,10 +189,10 @@ function httpToCurl(options) {
* @param {*} httpObject
* @param {*} { filter = '', customCallback = () => {} }
*/
function monkeyPatchHttp(httpObject, options = { filter: '', customCallback: () => {} }) {
function monkeyPatchHttp(httpObject, options = {}) {
monkeypatch(httpObject, 'request', (request, requestOptions, cb) => {
const { filter, customCallback } = options;
return requestPatch(filter, request, requestOptions, cb, customCallback);
const { filter = '', customCallback = () => {}, showOutput = true } = options;
return requestPatch(filter, request, requestOptions, cb, customCallback, showOutput);
});
}

Expand Down
59 changes: 59 additions & 0 deletions test/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,65 @@ import {
generateBody,
generateCompress
} from '../src/main';
import httpToCurl from '../src/main';

const request = require('request');
const nock = require('nock');


describe('Request using options object', () => {

const mock_callback = jest.fn();
const httpToCurlOptions = {
customCallback: mock_callback,
showOutput: false,
};
httpToCurl(httpToCurlOptions);

beforeEach(() => {
nock('https://api.httpcurl.com')
.post('/users/data')
.reply(200, '{ "response": true}');
});

it('POST form data', done => {
expect.assertions(7)

//Configuration options for request
var options = {
method: 'POST',
url: 'https://api.httpcurl.com/users/data',
headers: {
'Content-Type': ['application/x-www-form-urlencoded'],
'header1': "value1",
},
form: {
attrib1: 'attribvalue1',
attrib2: 'attribvalue2',
},
};

request.post(options);

//expect an object back
setTimeout(() => {
try {
expect(mock_callback).toBeCalled();
const result = mock_callback.mock.calls[0][0]; // first call, first parameter
expect(result).toContain("https://api.httpcurl.com");
expect(result).toContain("-X POST");
expect(result).toContain("attrib1=attribvalue1&attrib2=attribvalue2");
expect(result).toContain("Content-Type: application/x-www-form-urlencoded");
expect(result).toContain("header1: value1");
expect(result).toContain("host: api.httpcurl.com");
done()
} catch (err) {
done.fail(err)
}
})

});
});

describe('Generate method param', () => {
test('No method', () => {
Expand Down
31 changes: 29 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,13 @@ debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8:
dependencies:
ms "2.0.0"

debug@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"

decamelize@^1.1.1:
version "1.2.0"
resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
Expand Down Expand Up @@ -2519,7 +2526,7 @@ json-stable-stringify@^1.0.1:
dependencies:
jsonify "~0.0.0"

json-stringify-safe@~5.0.1:
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"

Expand Down Expand Up @@ -2610,7 +2617,7 @@ lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"

lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0:
lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.13, lodash@^4.17.4, lodash@^4.2.0:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"

Expand Down Expand Up @@ -2767,6 +2774,11 @@ [email protected]:
version "2.0.0"
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"

ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==

nan@^2.9.2:
version "2.10.0"
resolved "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
Expand Down Expand Up @@ -2804,6 +2816,16 @@ neo-async@^2.6.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"

nock@^12.0.3:
version "12.0.3"
resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9"
integrity sha512-QNb/j8kbFnKCiyqi9C5DD0jH/FubFGj5rt9NQFONXwQm3IPB0CULECg/eS3AU1KgZb/6SwUa4/DTRKhVxkGABw==
dependencies:
debug "^4.1.0"
json-stringify-safe "^5.0.1"
lodash "^4.17.13"
propagate "^2.0.0"

node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
Expand Down Expand Up @@ -3109,6 +3131,11 @@ process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"

propagate@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45"
integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==

pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
Expand Down