Utilities

cURL Conversion

Rezo provides bidirectional conversion between its request configuration and cURL command strings. Use toCurl() to generate cURL commands for debugging and sharing, and fromCurl() to import cURL commands copied from browser DevTools or documentation.

import { toCurl, fromCurl } from 'rezo';

toCurl(config) — Config to cURL

Convert a Rezo request configuration into a cURL command string:

import { toCurl } from 'rezo';

const curl = toCurl({
  url: 'https://api.example.com/users',
  method: 'POST',
  headers: {
    'content-type': 'application/json',
    'authorization': 'Bearer my-token',
  },
  data: { name: 'Alice', email: 'alice@example.com' },
  timeout: 30000,
});

console.log(curl);
// curl -X POST -H 'content-type: application/json' -H 'authorization: Bearer my-token'
//   --data-raw '{"name":"Alice","email":"alice@example.com"}' --max-time 30
//   --compressed -L 'https://api.example.com/users'

Supported Features

FeaturecURL Flag
HTTP method (non-GET)-X POST
Headers-H 'key: value'
JSON body--data-raw '{...}'
URL-encoded body--data-raw 'key=value'
FormData body--data-urlencode
Timeout--max-time N
Auth (basic)-u 'user:pass'
Proxy (HTTP)-x 'http://proxy:port'
Proxy (SOCKS)--socks5 'host:port'
Follow redirects-L (default)
No redirects--no-location
Max redirects--max-redirs N
Insecure (skip TLS)-k
Compression--compressed (always added)

Request Body Handling

The body is serialized based on its type:

// Object body -> JSON (auto-adds content-type if not set)
toCurl({ url: '...', method: 'POST', data: { key: 'value' } });
// --data-raw '{"key":"value"}' -H 'content-type: application/json'

// String body
toCurl({ url: '...', method: 'POST', data: 'raw body content' });
// --data-raw 'raw body content'

// URL-encoded (when content-type is set)
toCurl({
  url: '...',
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data: { user: 'alice', pass: 'secret' },
});
// --data-raw 'user=alice&pass=secret'

// GET with body uses -G flag
toCurl({ url: '...', method: 'GET', data: { q: 'search' } });
// -G --data-raw '{"q":"search"}'

Proxy Handling

// String proxy
toCurl({ url: '...', proxy: 'http://proxy.example.com:8080' });
// -x 'http://proxy.example.com:8080'

// Object proxy
toCurl({
  url: '...',
  proxy: {
    protocol: 'socks5',
    host: '127.0.0.1',
    port: 1080,
    auth: { username: 'user', password: 'pass' },
  },
});
// --socks5 'user:pass@127.0.0.1:1080'

Shell Escaping

All arguments are properly shell-escaped. Single quotes in values are escaped with the '\'' pattern:

toCurl({
  url: 'https://example.com/',
  headers: { 'x-data': "it's a test" },
});
// -H 'x-data: it'''s a test'

fromCurl(command) — cURL to Config

Parse a cURL command string into a Rezo request configuration:

import { fromCurl } from 'rezo';

const config = fromCurl(`
  curl 'https://api.example.com/users' \
    -X POST \
    -H 'content-type: application/json' \
    -H 'authorization: Bearer token123' \
    --data-raw '{"name":"Alice"}' \
    --compressed
`);

// config:
// {
//   url: 'https://api.example.com/users',
//   method: 'POST',
//   headers: {
//     'content-type': 'application/json',
//     'authorization': 'Bearer token123',
//   },
//   body: { name: 'Alice' },
// }

Use With Rezo

Import a cURL command from browser DevTools and execute it immediately:

import rezo, { fromCurl } from 'rezo';

// Paste from Chrome DevTools "Copy as cURL"
const config = fromCurl(`curl 'https://api.example.com/data' -H 'cookie: session=abc'`);
const response = await rezo.request(config);

Supported cURL Flags

FlagMapped To
-X, --requestmethod
-H, --headerheaders
-d, --data, --data-raw, --data-binarybody (auto-detects JSON)
--data-urlencodebody + content-type header
-G, --getForces method: 'GET'
-b, --cookieheaders.cookie
-u, --userauth: { username, password }
-x, --proxyproxy
--socks5, --socks4, --socks4a, --socks5-hostnameproxy (with protocol prefix)
-A, --user-agentheaders['user-agent']
-L, --locationEnables redirect following
--no-locationDisables redirect following
--max-redirsmaxRedirects
--max-time, -mtimeout (converted from seconds to ms)
-k, --insecurerejectUnauthorized: false
--compressed(noted, no config change)
-I, --headmethod: 'HEAD'
-s, -S, --silent, --show-errorIgnored
-o, --outputIgnored

JSON Body Detection

If the body starts with { or [, fromCurl attempts to parse it as JSON. If parsing fails, the raw string is preserved:

const config = fromCurl(`curl -X POST -d '{"key":"value"}' https://api.example.com`);
config.body; // { key: 'value' }  (parsed object)

const config = fromCurl(`curl -X POST -d 'not json' https://api.example.com`);
config.body; // 'not json'  (raw string)

Implicit POST

If -d/--data is used without -X, the method is automatically set to POST:

const config = fromCurl(`curl -d 'data=value' https://api.example.com`);
config.method; // 'POST'

CurlParseResult Interface

The intermediate parse result (used internally) contains all extracted fields:

interface CurlParseResult {
  url: string;
  method: string;
  headers: Record<string, string>;
  body?: string | Record<string, unknown>;
  cookies?: string;
  proxy?: string;
  auth?: { username: string; password: string };
  compressed?: boolean;
  insecure?: boolean;
  followRedirects?: boolean;
  maxRedirects?: number;
  timeout?: number;
  userAgent?: string;
}

Tokenizer

The cURL parser includes a full shell tokenizer that correctly handles:

  • Single-quoted strings ('value')
  • Double-quoted strings ("value")
  • Backslash escaping (\", \\)
  • Multi-line commands with \ continuation
  • Mixed quoting styles
// All of these parse correctly:
fromCurl(`curl -H "content-type: application/json" https://example.com`);
fromCurl(`curl -H 'it'''s escaped' https://example.com`);
fromCurl(`curl \
  -X POST \
  https://example.com`);

Round-Trip Example

import rezo, { toCurl, fromCurl } from 'rezo';

// Generate a cURL command from a request config
const curl = toCurl({
  url: 'https://api.example.com/search',
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  data: { query: 'rezo http client' },
  timeout: 10000,
});

console.log(curl);
// Share this cURL command with a teammate

// Parse it back and execute
const config = fromCurl(curl);
const response = await rezo.request(config);