curlconverter
Version:
convert curl commands to Python, JavaScript, Go, PHP and more
333 lines (329 loc) • 17.3 kB
JavaScript
import { CCError, has } from "./utils.js";
import { Word } from "./shell/Word.js";
import { parseArgs, curlLongOpts, curlLongOptsShortened, curlShortOpts, } from "./curl/opts.js";
import { buildRequests } from "./Request.js";
import { _toAnsible, toAnsibleWarn, supportedArgs as supportedArgsAnsible, } from "./generators/ansible.js";
import { _toC, toCWarn, supportedArgs as supportedArgsC, } from "./generators/c.js";
import { _toCFML, toCFMLWarn, supportedArgs as supportedArgsCFML, } from "./generators/cfml.js";
import { _toClojure, toClojureWarn, supportedArgs as supportedArgsClojure, } from "./generators/clojure.js";
import { _toCSharp, toCSharpWarn, supportedArgs as supportedArgsCSharp, } from "./generators/csharp.js";
import { _toDart, toDartWarn, supportedArgs as supportedArgsDart, } from "./generators/dart.js";
import { _toElixir, toElixirWarn, supportedArgs as supportedArgsElixir, } from "./generators/elixir.js";
import { _toGo, toGoWarn, supportedArgs as supportedArgsGo, } from "./generators/go.js";
import { _toHarString, toHarStringWarn, supportedArgs as supportedArgsHarString, } from "./generators/har.js";
import { _toHTTP, toHTTPWarn, supportedArgs as supportedArgsHTTP, } from "./generators/http.js";
import { _toHttpie, toHttpieWarn, supportedArgs as supportedArgsHttpie, } from "./generators/httpie.js";
import { _toJava, toJavaWarn, supportedArgs as supportedArgsJava, } from "./generators/java/java.js";
import { _toJavaHttpUrlConnection, toJavaHttpUrlConnectionWarn, supportedArgs as supportedArgsJavaHttpUrlConnection, } from "./generators/java/httpurlconnection.js";
import { _toJavaJsoup, toJavaJsoupWarn, supportedArgs as supportedArgsJavaJsoup, } from "./generators/java/jsoup.js";
import { _toJavaOkHttp, toJavaOkHttpWarn, supportedArgs as supportedArgsJavaOkHttp, } from "./generators/java/okhttp.js";
import { _toJavaScript, toJavaScriptWarn, javaScriptSupportedArgs as supportedArgsJavaScript, } from "./generators/javascript/javascript.js";
import { _toJavaScriptJquery, toJavaScriptJqueryWarn, supportedArgs as supportedArgsJavaScriptJquery, } from "./generators/javascript/jquery.js";
import { _toJavaScriptXHR, toJavaScriptXHRWarn, supportedArgs as supportedArgsJavaScriptXHR, } from "./generators/javascript/xhr.js";
import { _toJsonString, toJsonStringWarn, supportedArgs as supportedArgsJsonString, } from "./generators/json.js";
import { _toJulia, toJuliaWarn, supportedArgs as supportedArgsJulia, } from "./generators/julia.js";
import { _toKotlin, toKotlinWarn, supportedArgs as supportedArgsKotlin, } from "./generators/kotlin.js";
import { _toLua, toLuaWarn, supportedArgs as supportedArgsLua, } from "./generators/lua.js";
import { _toMATLAB, toMATLABWarn, supportedArgs as supportedArgsMATLAB, } from "./generators/matlab/matlab.js";
import { _toNode, toNodeWarn, nodeSupportedArgs as supportedArgsNode, } from "./generators/javascript/javascript.js";
import { _toNodeAxios, toNodeAxiosWarn, supportedArgs as supportedArgsNodeAxios, } from "./generators/javascript/axios.js";
import { _toNodeGot, toNodeGotWarn, supportedArgs as supportedArgsNodeGot, } from "./generators/javascript/got.js";
import { _toNodeHttp, toNodeHttpWarn, supportedArgs as supportedArgsNodeHttp, } from "./generators/javascript/http.js";
import { _toNodeKy, toNodeKyWarn, supportedArgs as supportedArgsNodeKy, } from "./generators/javascript/ky.js";
import { _toNodeRequest, toNodeRequestWarn, supportedArgs as supportedArgsNodeRequest, } from "./generators/javascript/request.js";
import { _toNodeSuperAgent, toNodeSuperAgentWarn, supportedArgs as supportedArgsNodeSuperAgent, } from "./generators/javascript/superagent.js";
import { _toOCaml, toOCamlWarn, supportedArgs as supportedArgsOCaml, } from "./generators/ocaml.js";
import { _toObjectiveC, toObjectiveCWarn, supportedArgs as supportedArgsObjectiveC, } from "./generators/objectivec.js";
import { _toPerl, toPerlWarn, supportedArgs as supportedArgsPerl, } from "./generators/perl.js";
import { _toPhp, toPhpWarn, supportedArgs as supportedArgsPhp, } from "./generators/php/php.js";
import { _toPhpGuzzle, toPhpGuzzleWarn, supportedArgs as supportedArgsPhpGuzzle, } from "./generators/php/guzzle.js";
import { _toPhpRequests, toPhpRequestsWarn, supportedArgs as supportedArgsPhpRequests, } from "./generators/php/requests.js";
import { _toPowershellRestMethod, toPowershellRestMethodWarn, supportedArgs as supportedArgsPowershellRestMethod, } from "./generators/powershell.js";
import { _toPowershellWebRequest, toPowershellWebRequestWarn, supportedArgs as supportedArgsPowershellWebRequest, } from "./generators/powershell.js";
import { _toPython, toPythonWarn, supportedArgs as supportedArgsPython, } from "./generators/python/python.js";
import { _toPythonHttp, toPythonHttpWarn, supportedArgs as supportedArgsPythonHttp, } from "./generators/python/http.js";
import { _toR, toRWarn, supportedArgs as supportedArgsR, } from "./generators/r/httr.js";
import { _toRHttr2, toRHttr2Warn, supportedArgs as supportedArgsRHttr2, } from "./generators/r/httr2.js";
import { _toRuby, toRubyWarn, supportedArgs as supportedArgsRuby, } from "./generators/ruby/ruby.js";
import { _toRubyHttparty, toRubyHttpartyWarn, supportedArgs as supportedArgsRubyHttparty, } from "./generators/ruby/httparty.js";
import { _toRust, toRustWarn, supportedArgs as supportedArgsRust, } from "./generators/rust.js";
import { _toSwift, toSwiftWarn, supportedArgs as supportedArgsSwift, } from "./generators/swift.js";
import { _toWget, toWgetWarn, supportedArgs as supportedArgsWget, } from "./generators/wget.js";
import fs from "fs";
// This line is updated by extract_curl_args.py
const VERSION = "4.12.0 (curl 8.2.1)";
// sets a default in case --language isn't passed
const defaultLanguage = "python";
// Maps options for --language to functions
// NOTE: make sure to update this when adding language support
// prettier-ignore
const translate = {
ansible: [_toAnsible, toAnsibleWarn, supportedArgsAnsible],
c: [_toC, toCWarn, supportedArgsC],
cfml: [_toCFML, toCFMLWarn, supportedArgsCFML],
clojure: [_toClojure, toClojureWarn, supportedArgsClojure],
csharp: [_toCSharp, toCSharpWarn, supportedArgsCSharp],
"c#": [_toCSharp, toCSharpWarn, supportedArgsCSharp], // undocumented alias
browser: [_toJavaScript, toJavaScriptWarn, supportedArgsJavaScript], // for backwards compatibility, undocumented
dart: [_toDart, toDartWarn, supportedArgsDart],
elixir: [_toElixir, toElixirWarn, supportedArgsElixir],
go: [_toGo, toGoWarn, supportedArgsGo],
golang: [_toGo, toGoWarn, supportedArgsGo], // undocumented alias
har: [_toHarString, toHarStringWarn, supportedArgsHarString],
http: [_toHTTP, toHTTPWarn, supportedArgsHTTP],
httpie: [_toHttpie, toHttpieWarn, supportedArgsHttpie],
java: [_toJava, toJavaWarn, supportedArgsJava],
"java-httpurlconnection": [_toJavaHttpUrlConnection, toJavaHttpUrlConnectionWarn, supportedArgsJavaHttpUrlConnection],
"java-jsoup": [_toJavaJsoup, toJavaJsoupWarn, supportedArgsJavaJsoup],
"java-okhttp": [_toJavaOkHttp, toJavaOkHttpWarn, supportedArgsJavaOkHttp],
javascript: [_toJavaScript, toJavaScriptWarn, supportedArgsJavaScript],
"javascript-axios": [_toNodeAxios, toNodeAxiosWarn, supportedArgsNodeAxios], // undocumented alias
"javascript-fetch": [_toJavaScript, toJavaScriptWarn, supportedArgsJavaScript], // undocumented alias
"javascript-got": [_toNodeGot, toNodeGotWarn, supportedArgsNodeGot], // undocumented alias
"javascript-ky": [_toNodeKy, toNodeKyWarn, supportedArgsNodeKy], // undocumented alias
"javascript-jquery": [_toJavaScriptJquery, toJavaScriptJqueryWarn, supportedArgsJavaScriptJquery],
"javascript-request": [_toNodeRequest, toNodeRequestWarn, supportedArgsNodeRequest], // undocumented alias
"javascript-superagent": [_toNodeSuperAgent, toNodeSuperAgentWarn, supportedArgsNodeSuperAgent], // undocumented alias
"javascript-xhr": [_toJavaScriptXHR, toJavaScriptXHRWarn, supportedArgsJavaScriptXHR],
json: [_toJsonString, toJsonStringWarn, supportedArgsJsonString],
julia: [_toJulia, toJuliaWarn, supportedArgsJulia],
kotlin: [_toKotlin, toKotlinWarn, supportedArgsKotlin],
lua: [_toLua, toLuaWarn, supportedArgsLua],
matlab: [_toMATLAB, toMATLABWarn, supportedArgsMATLAB],
node: [_toNode, toNodeWarn, supportedArgsNode],
"node-axios": [_toNodeAxios, toNodeAxiosWarn, supportedArgsNodeAxios],
"node-fetch": [_toNode, toNodeWarn, supportedArgsNode], // undocumented alias
"node-got": [_toNodeGot, toNodeGotWarn, supportedArgsNodeGot],
"node-http": [_toNodeHttp, toNodeHttpWarn, supportedArgsNodeHttp], // undocumented alias
"node-ky": [_toNodeKy, toNodeKyWarn, supportedArgsNodeKy],
"node-jquery": [_toJavaScriptJquery, toJavaScriptJqueryWarn, supportedArgsJavaScriptJquery], // undocumented alias
"node-request": [_toNodeRequest, toNodeRequestWarn, supportedArgsNodeRequest],
"node-superagent": [_toNodeSuperAgent, toNodeSuperAgentWarn, supportedArgsNodeSuperAgent],
"node-xhr": [_toJavaScriptXHR, toJavaScriptXHRWarn, supportedArgsJavaScriptXHR], // undocumented alias
nodejs: [_toNode, toNodeWarn, supportedArgsNode], // undocumented alias
"nodejs-axios": [_toNodeAxios, toNodeAxiosWarn, supportedArgsNodeAxios], // undocumented alias
"nodejs-fetch": [_toNode, toNodeWarn, supportedArgsNode], // undocumented alias
"nodejs-got": [_toNodeGot, toNodeGotWarn, supportedArgsNodeGot], // undocumented alias
"nodejs-http": [_toNodeHttp, toNodeHttpWarn, supportedArgsNodeHttp], // undocumented alias
"nodejs-ky": [_toNodeKy, toNodeKyWarn, supportedArgsNodeKy], // undocumented alias
"nodejs-jquery": [_toJavaScriptJquery, toJavaScriptJqueryWarn, supportedArgsJavaScriptJquery], // undocumented alias
"nodejs-request": [_toNodeRequest, toNodeRequestWarn, supportedArgsNodeRequest], // undocumented alias
"nodejs-superagent": [_toNodeSuperAgent, toNodeSuperAgentWarn, supportedArgsNodeSuperAgent], // undocumented alias
"nodejs-xhr": [_toJavaScriptXHR, toJavaScriptXHRWarn, supportedArgsJavaScriptXHR], // undocumented alias
objc: [_toObjectiveC, toObjectiveCWarn, supportedArgsObjectiveC],
objectivec: [_toObjectiveC, toObjectiveCWarn, supportedArgsObjectiveC], // undocumented alias
"objective-c": [_toObjectiveC, toObjectiveCWarn, supportedArgsObjectiveC], // undocumented alias
ocaml: [_toOCaml, toOCamlWarn, supportedArgsOCaml],
perl: [_toPerl, toPerlWarn, supportedArgsPerl],
php: [_toPhp, toPhpWarn, supportedArgsPhp],
"php-curl": [_toPhp, toPhpWarn, supportedArgsPhp], // undocumented alias
"php-guzzle": [_toPhpGuzzle, toPhpGuzzleWarn, supportedArgsPhpGuzzle],
"php-requests": [_toPhpRequests, toPhpRequestsWarn, supportedArgsPhpRequests],
powershell: [_toPowershellRestMethod, toPowershellRestMethodWarn, supportedArgsPowershellRestMethod],
"powershell-restmethod": [_toPowershellRestMethod, toPowershellRestMethodWarn, supportedArgsPowershellRestMethod], // undocumented alias
"powershell-webrequest": [_toPowershellWebRequest, toPowershellWebRequestWarn, supportedArgsPowershellWebRequest],
python: [_toPython, toPythonWarn, supportedArgsPython],
"python-http": [_toPythonHttp, toPythonHttpWarn, supportedArgsPythonHttp],
"python-httpclient": [_toPythonHttp, toPythonHttpWarn, supportedArgsPythonHttp], // undocumented alias
r: [_toR, toRWarn, supportedArgsR],
"r-httr": [_toR, toRWarn, supportedArgsR], // undocumented alias
"r-httr2": [_toRHttr2, toRHttr2Warn, supportedArgsRHttr2],
ruby: [_toRuby, toRubyWarn, supportedArgsRuby],
"ruby-httparty": [_toRubyHttparty, toRubyHttpartyWarn, supportedArgsRubyHttparty],
rust: [_toRust, toRustWarn, supportedArgsRust],
swift: [_toSwift, toSwiftWarn, supportedArgsSwift],
wget: [_toWget, toWgetWarn, supportedArgsWget],
};
const USAGE = `Usage: curlconverter [--language <language>] [-] [curl_options...]
language: the language to convert the curl command to. The choices are
ansible
c
cfml
clojure
csharp
dart
elixir
go
har
http
httpie
java
java-httpurlconnection
java-jsoup
java-okhttp
javascript
javascript-jquery
javascript-xhr
json
julia
kotlin
lua
matlab
node
node-axios
node-http
node-got
node-ky
node-request
node-superagent
objc
ocaml
perl
php
php-guzzle
php-requests
powershell
powershell-webrequest
python (the default)
r
r-httr2
ruby
ruby-httparty
rust
swift
wget
-: read curl command from stdin
--verbose/-v: print warnings and error tracebacks
curl_options: these should be passed exactly as they would be passed to curl.
see 'curl --help' or 'curl --manual' for which options are allowed here`;
const curlconverterLongOpts = {
...curlLongOpts,
language: { type: "string", name: "language" },
stdin: { type: "bool", name: "stdin" },
};
const curlconverterShortOpts = {
...curlShortOpts,
// a single "-" (dash) tells curlconverter to read input from stdin
"": "stdin",
};
function printWarnings(warnings, verbose) {
if (!verbose) {
return warnings;
}
for (const w of warnings) {
for (const line of w[1].trim().split("\n")) {
console.error("warning: " + line);
}
}
return [];
}
function exitWithError(error, verbose = false) {
let errMsg = error;
if (!verbose) {
if (error instanceof CCError) {
errMsg = "";
for (const line of error.message.toString().split("\n")) {
errMsg += "error: " + line + "\n";
}
errMsg = errMsg.trimEnd();
}
else if (error instanceof Error) {
// .toString() removes the traceback
errMsg = error.toString();
}
}
console.error(errMsg);
process.exit(2); // curl exits with 2 so we do too
}
// argv is ['node', 'cli.js', ...]
// parseArgs() ignores the first argument but we need to remove "node"
const argv = process.argv.slice(1).map((arg) => new Word(arg));
let global_, seenArgs;
let warnings = [];
try {
[global_, seenArgs] = parseArgs(argv, curlconverterLongOpts, curlLongOptsShortened, curlconverterShortOpts, undefined, warnings);
}
catch (e) {
exitWithError(e);
}
if (global_.help) {
console.log(USAGE.trim());
process.exit(0);
}
if (global_.version) {
console.log("curlconverter " + VERSION);
process.exit(0);
}
const verbose = !!global_.verbose;
const commandFromStdin = global_.stdin;
const language = global_.language || defaultLanguage;
if (!has(translate, language)) {
exitWithError(new CCError("unexpected --language: " +
JSON.stringify(language) +
"\n" +
"must be one of: " +
Object.keys(translate).sort().join(", ")), verbose);
}
if (!seenArgs.length) {
console.log(USAGE.trim());
process.exit(2);
}
const [generator, warnGenerator, supportedArgs] = translate[language];
const extraArgs = seenArgs.filter((a) => {
const [arg, actual] = a;
const ignore = ["stdin", "verbose", "language"].includes(arg);
if (!ignore && !supportedArgs.has(arg)) {
warnings.push([
arg,
actual + " is not a supported option",
// + (longArg.removed ? ", it was removed in curl " + longArg.removed : ""),
]);
}
return !ignore;
});
let code;
if (commandFromStdin) {
// This lets you do
// echo curl example.com | curlconverter --verbose
// TODO: remove repeated args
if (extraArgs.length > 0) {
// Throw an error so that if user typos something like
// curlconverter - -data
// they aren't stuck with what looks like a hung terminal.
const extraArgsStr = extraArgs.map((a) => a[1]).join(", ");
exitWithError(new CCError("if you pass --stdin or -, you can't also pass " + extraArgsStr), verbose);
}
const input = fs.readFileSync(0, "utf8");
try {
[code, warnings] = warnGenerator(input, warnings);
}
catch (e) {
printWarnings(warnings, true); // print warnings to help figure out the error
exitWithError(e, verbose);
}
warnings = printWarnings(warnings, verbose);
}
else {
warnings = printWarnings(warnings, verbose);
let stdin;
if (!process.stdin.isTTY) {
// TODO: what if there's an EOF character? does curl read each @- until EOF?
stdin = new Word(fs.readFileSync(0).toString());
}
let requests;
try {
requests = buildRequests(global_, stdin);
}
catch (e) {
exitWithError(e, verbose);
}
warnings = printWarnings(warnings, verbose);
// Warning for users using the pre-4.0 CLI
if (requests[0].urls[0].originalUrl.startsWith("curl ")) {
console.error(`\
warning: Passing a whole curl command as a single argument?
warning: Pass options to curlconverter as if it was curl instead:
warning: curlconverter 'curl example.com' -> curlconverter example.com`);
}
try {
code = generator(requests, warnings);
}
catch (e) {
exitWithError(e, verbose);
}
warnings = printWarnings(warnings, verbose);
}
printWarnings(warnings, verbose);
process.stdout.write(code);
//# sourceMappingURL=cli.js.map