Git Product home page Git Product logo

axios-curlirize's Introduction

Codacy Badge CircleCI npm version

Versions

  • 2.0.0 - Uses ES Native Modules
  • 1.3.7 - Uses CommonJS Modules

Description

This module is an axios third-party module to log any axios request as a curl command in the console. It was originally posted as a suggestion on the axios repository, but since we believed it wasn't in the scope of axios to release such feature, we decided to make it as an independent module.

How it works

The module makes use of axios' interceptors to log the request as a cURL command. It also stores it in the response's config object. Therefore, the command can be seen in the app's console, as well as in the res.config.curlCommand property of the response.

How to use it

axios-curlirize is super easy to use. First you'll have to install it.

npm i --save axios-curlirize@latest

Then all you have to do is import and instanciate curlirize in your app. Here's a sample:

import axios from 'axios';
import express from 'express';
import curlirize from 'axios-curlirize';

const app = express();

// initializing axios-curlirize with your axios instance
curlirize(axios);

// creating dummy route
app.post('/', (req, res) => {
  res.send({ hello: 'world!' });
});

// starting server
app.listen(7500, () => {
  console.log('Dummy server started on port 7500');
  /*
             The output of this in the console will be :
             curl -X POST -H "Content-Type:application/x-www-form-urlencoded" --data {"dummy":"data"} http://localhost:7500/
        */
  axios
    .post('http://localhost:7500/', { dummy: 'data' })
    .then(res => {
      console.log('success');
    })
    .catch(err => {
      console.log(err);
    });
});

Features

Changing the logger

By default, axios-curlirize uses the console.log/error() functions. It is possible to change the logger by doing something similar to this:

// when initiating your curlirize instance
curlirize(axios, (result, err) => {
  const { command } = result;
  if (err) {
    // use your logger here
  } else {
    // use your logger here
  }
});

Curilirize additional axios instance

To curlirize any other instances of axios (aside from the base one), please call the curlirize() method on that instance.

const instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} });
curlirize(instance);

Disable the logger

By default, all requests will be logged. But you can disable this behaviour unitarily by setting the curlirize option to false within the axios request.

axios
  .post('http://localhost:7500/', { dummy: 'data' }, {
    curlirize: false
  })
  .then(res => {
    console.log('success');
  })
  .catch(err => {
    console.log(err);
  });

Clear a request

axios
  .post('http://localhost:7500/', { dummy: 'data' })
  .then(res => {
    res.config.clearCurl();
  })
  .catch(err => {
    console.log(err);
  });

axios-curlirize's People

Contributors

abhishekraje avatar agauthier-nbc avatar anthonygauthier avatar binggg avatar codacy-badger avatar colidarity avatar dependabot[bot] avatar harsh-singh-benefit-flow avatar iamacup avatar ikatun avatar jayceekay avatar sergeymild avatar thib3113 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

axios-curlirize's Issues

using axios-curlirize on node app

Hi,
I tried to use this in node app but it gives me an error

node_modules/axios-curlirize/src/curlirize.js:1
import { CurlHelper } from './lib/CurlHelper';
       ^

SyntaxError: Unexpected token {
    at Module._compile (internal/modules/cjs/loader.js:811:22)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:879:10)
    at Module.load (internal/modules/cjs/loader.js:731:32)
    at Function.Module._load (internal/modules/cjs/loader.js:644:12)
    at Module.require (internal/modules/cjs/loader.js:771:19)
    at require (internal/modules/cjs/helpers.js:68:18)

Not sure what's going on. Is is suppose to work only in js engine that supports es modules?

Incorrect headers

Hi,
Thanks for this module. I had a problem with the headers however. The default content-type isn't set correctly and the common header ('Accept': 'application/json, text/plain, */*') is not included. I followed the axios code in lib/defaults.js and lib/core/dispatchRequest.js to come up with my own simplified version:

import axios from 'axios';
import {isURLSearchParams, isObject, merge} from 'axios/lib/utils';
import qs from 'qs';

declare module 'axios' {
    interface AxiosRequestConfig {
        curlCommand?: string;
    }
}

const filterKeys = new Set(['delete', 'get', 'head', 'post', 'put', 'patch', 'common']);

axios.interceptors.request.use(config => {
    try {
        const {method, url, params, data} = config;
        let {headers = {}} = config;
        let dataArg = '';
        const setsContentType = Object.keys(headers).some(key => key.toUpperCase() === 'CONTENT-TYPE');
        if(isURLSearchParams(data)) {
            dataArg = ` --data '${data}'`;
            if(!setsContentType)
                headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
        } else if(isObject(data)) {
            dataArg = ` --data '${JSON.stringify(data)}'`;
            if(!setsContentType)
                headers['Content-Type'] = 'application/json;charset=utf-8';
        }
        headers = merge(
            headers.common || {},
            headers[method] || {},
            headers,
        );
        config.curlCommand = `curl -X ${method.toUpperCase()} ${
            Object.keys(headers).filter(key => !filterKeys.has(key))
            .map(key => `-H "${key}:${headers[key]}"`)
            .join(' ')
        }${
            dataArg
        } "${url}${
            params && Object.keys(params).length ?
                `?${qs.stringify(params)}` :
                ''
        }"`;
    } catch (err) {
        console.error(err);
    } finally {
        return config;
    }
});

dist doesn't exist

when I try to include this I get:
Error: Can't resolve './dist/curlirize'

Feature request: axios request to curl command

Would be useful if ther would be a utility method exposed that translates an axios request without running it. So not intercepting the axios request, just doing the translation, and from the request passed in, not the normalised/extended version that the interceptor gets. Thanks a million, it's great to see if someone provides a solution to an issue one has - even without this extra feature I described.

Dependencies includes babel, etc.?

Was it intended for babel/cli, etc. to be included in the dependencies list?

Unless I missed it (or more likely don't understand why it's needed), I don't see where it's being used.

curlirize introduce a circular structure in axios

Here is the error I can see If my request produce an error in jest :

(node:32584) UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    |     property 'curlObject' -> object with constructor 'CurlHelper'
    --- property 'request' closes the circle
    at stringify (<anonymous>)
    at writeChannelMessage (internal/child_process/serialization.js:117:20)
    at process.target._send (internal/child_process.js:805:17)
    at process.target.send (internal/child_process.js:703:19)
    at reportSuccess (./node_modules/jest-worker/build/workers/processChild.js:67:11)

Getting error while importing axios-curlirize on ts + node

Getting error while importing axios-curlirize,

ts-node ver. 9.1.1, typescript ver. 4.2.4

[ERROR] 14:27:26 Error: Must use import to load ES Module: node_modules/axios-curlirize/src/main.js
require() of ES modules is not supported.
require() of node_modules/axios-curlirize/src/main.js from temp.ts is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename main.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from node_modules/axios-curlirize/package.json.

"Content-Type: undefined" when I do not set the content type

When I do not set the content type, like this:

let resp = await axios.post(baseUrl + '/page/init', data, {
  headers: {
    'nuwa-wings': 'env=osim232-v',
  }
})

The generated cURL code will be like:

curl -X POST -H "Accept:application/json, text/plain, */*" -H "Content-Type:undefined" -H "nuwa-wings:env=osim232-v" ...

The package.json is:

{
  "dependencies": {
    "axios": "^1.6.2",
    "axios-curlirize": "^2.0.0",
    // etc...
  }
}

Multiple calls to curlirize will output the curl command multiple times

Steps to reproduce:

  1. In file1.js (choose any filename), import Axios and Curlirize it. Set up a function to make an Axios request.
  2. In file2.js (choose any filename), import Axios again and Curlirize it. Set up another function to make an Axios request.
  3. Run the application.

Actual behaviour: The CURL output from Axios is displayed twice for each request
Expected behaviour: The CURL output is displayed only once (per request) no matter how many times Axios is curlirized.

Thanks!

Node 14, AC 2.0.0: error: Must use import to load ES Module

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/[email protected]/work/seed-association-service/node_modules/axios-curlirize/src/main.js
require() of ES modules is not supported.
require() of /Users/[email protected]/work/seed-association-service/node_modules/axios-curlirize/src/main.js from /Users/[email protected]/work/seed-association-service/dist/dao.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename main.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/[email protected]/work/seed-association-service/node_modules/axios-curlirize/package.json.
// dao.ts
import axios from 'axios';
...
import curlirize from 'axios-curlirize';
console.log(curlirize); // this line was suggested in a different ticket
// curlirize(axios); // using this instead didn't change the error
$ versions
Node v14.19.1
NPM 6.14.16
Yarn 1.22.18
OS:
ProductName:	macOS
ProductVersion:	12.5.1
BuildVersion:	21G83
$ cat package.json | grep "axios"
        "axios": "~0.27.2",
        "axios-curlirize": "~2.0.0",
        "@types/axios-curlirize": "~1.3.2",

Documentation doesn't cover some cases

The documentation should be updated to explain the "axios" parameter in "curlirize(axios)".

If you are using the syntax below:
const instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} }); (copied from axios readme)

Then you would need to invoke curlirize using "curlirize(instance)" after creating the instance. Even invoking it on "axios" before creating the instance doesn't cause the hook to be inherited.

Lost of a bit of time to that gotcha.

Params are not dumped for GET requests

Axios automatically appends a querystring if { params } are given as second argument.

Curlirize prints just the url part of the config but it's not what axios is really sending, sent querystring is lost in the given curl printed.

Getting unexpected token on import.

I am getting the error below

import { CurlHelper } from "./lib/CurlHelper.js";
       ^

SyntaxError: Unexpected token {
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:789:10)

"dependencies": {
"axios": "^0.18.0",
"axios-curlirize": "^1.3.5",
.....

Let me know if anything else needed

support URLSearchParams as data

axios supports passing a URLSearchParams object as data, when you need a post with "application/x-www-form-urlencoded".
curlirize prints an empty data object in the console.

Exit code: 1 Command: if [ -e ./node_modules/.bin/babel ]; then ./node_modules/.bin/babel ./

[5/5] Building fresh packages...
error C:\FRONTEND\www\nuxt-dashboard\node_modules\axios-curlirize: Command failed.
Exit code: 1
Command: if [ -e ./node_modules/.bin/babel ]; then ./node_modules/.bin/babel ./src --experimental --source-maps-inline -d ./dist; fi
Arguments:
Directory: C:\FRONTEND\www\nuxt-dashboard\node_modules\axios-curlirize
Output:
���।�������� ������: -e.
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

Don't print "readable" stream info on Node

A POST request with a FormData object having a file binary in it results in the following:

curl -X POST -H "Content-Type:application/x-www-form-urlencoded" -H "content-type:multipart/form-data; boundary=--------------------------465935617733580427703067" --data '{"_overheadLength":412,"_valueLength":10,"_valuesToMeasure":[{"_readableState":{"objectMode":false,"highWaterMark":65536,"buffer":{"head":null,"tail":null,"length":0},"length":0,"pipes":null,"pipesCount":0,"flowing":false,"ended":false,"endEmitted":false,"reading":false,"sync":true,"needReadable":false,"emittedReadable":false,"readableListening":false,"resumeScheduled":false,"paused":true,"emitClose":false,"autoDestroy":false,"destroyed":false,"defaultEncoding":"utf8","awaitDrain":0,"readingMore":false,"decoder":null,"encoding":null},"readable":true,"_events":{"error":[null,null]},"_eventsCount":3,"path":"/tmp/1555512197006-en-GB-2-hello-world.txt","fd":null,"flags":"r","mode":438,"end":null,"autoClose":true,"bytesRead":0,"closed":false}],"writable":false,"readable":true,"dataSize":0,"maxDataSize":2097152,"pauseStreams":true,"_released":false,"_streams":["----------------------------465935617733580427703067\r\nContent-Disposition: form-data; name="sourceLocale"\r\n\r\n","it-IT",null,"----------------------------465935617733580427703067\r\nContent-Disposition: form-data; name="targetLocale"\r\n\r\n","en-GB",null,"----------------------------465935617733580427703067\r\nContent-Disposition: form-data; name="documentContent"; filename="1555512197006-en-GB-2-hello-world.txt"\r\nContent-Type: text/plain\r\n\r\n",{"source":{"_readableState":{"objectMode":false,"highWaterMark":65536,"buffer":{"head":null,"tail":null,"length":0},"length":0,"pipes":null,"pipesCount":0,"flowing":false,"ended":false,"endEmitted":false,"reading":false,"sync":true,"needReadable":false,"emittedReadable":false,"readableListening":false,"resumeScheduled":false,"paused":true,"emitClose":false,"autoDestroy":false,"destroyed":false,"defaultEncoding":"utf8","awaitDrain":0,"readingMore":false,"decoder":null,"encoding":null},"readable":true,"_events":{"error":[null,null]},"_eventsCount":3,"path":"/tmp/1555512197006-en-GB-2-hello-world.txt","fd":null,"flags":"r","mode":438,"end":null,"autoClose":true,"bytesRead":0,"closed":false},"dataSize":0,"maxDataSize":null,"pauseStream":true,"_maxDataSizeExceeded":false,"_released":false,"_bufferedEvents":[{"0":"pause"}],"_events":{},"_eventsCount":1},null],"_currentStream":null,"_boundary":"--------------------------465935617733580427703067"}' http://localhost:8080/dummyservice

Would you consider using the -F 'param=value' flag and the @ notation for file uploads?
Example:

curl -s 'https://localhost:8080' -F 'param=key' -F 'file=@"files/hello world.txt"'

Not logging the basic auth credentials

I have given the basic auth credentials inside the auth property in the config object of the axios but the credentials are not logging along with the curl command.
Pls help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.