Feature: export Requests to cURL commands
Issues
- [x] I have checked existing issues and there are no existing ones with the same request.
Feature description
It would be great to have an option to export requests from a .http file to a cURL command format, similar to the functionality provided by the intelij Idea HTTP client.
As many clients like Postman supports importing curl commands, this can allow converting .http files as collections for other clients with scripts, thus can be shared
Would be cool if we can import curl commands as .http files too
Exporting http to curl command format is already builtin as experimental :Rest curl yank and :Rest curl comment commands.
For importing curl commands as http format, #415 might address that issue (I haven't work on it for a while, but I'll get back to it soon)
Made this script for converting the whole file into curl commands, utilizing rest-nvim.client.curl.cli command builder
Script
local function getEnvVars()
local dotenv = require("rest-nvim.parser.dotenv")
local env_file = vim.b._rest_nvim_env_file
local envVars = {}
if env_file then
local ok, vars = dotenv.parse(env_file)
if ok then
envVars = vars
else
vim.schedule(function()
vim.notify("Failed to load environment file: " .. env_file, vim.log.levels.WARN)
end)
end
end
return envVars
end
local function applySubstitutions(lines, useEnvVars)
if useEnvVars then
local env = getEnvVars()
if env then
for i, line in ipairs(lines) do
for k, v in pairs(env) do
line = line:gsub("{{" .. k .. "}}", v)
end
lines[i] = line
end
end
else
for i, line in ipairs(lines) do
-- escape brackets so the request parser doesn't remove them
line = line:gsub("{{", "\\{\\{"):gsub("}}", "\\}\\}")
lines[i] = line
end
end
return lines
end
local function extractCurlCommands(useEnvVars, format)
local parser = require("rest-nvim.parser")
local builder = require("rest-nvim.client.curl.cli").builder
local originalBuf = vim.api.nvim_get_current_buf()
local originalLines = vim.api.nvim_buf_get_lines(originalBuf, 0, -1, false)
vim.cmd("vnew")
local scratchBuf = vim.api.nvim_get_current_buf()
local modifiedLines = applySubstitutions(originalLines, useEnvVars)
vim.api.nvim_buf_set_lines(scratchBuf, 0, -1, false, modifiedLines)
local nodes = parser.get_all_request_nodes()
print("Extracting " .. #nodes .. " requests to curl commands")
local output = {}
for _, node in ipairs(nodes) do
local request = parser.parse(node, 0)
request.cookies = {}
if request.body and request.body.__TYPE == "json" and (not request.headers or not request.headers["content-type"]) then
request.headers = request.headers or {}
request.headers["content-type"] = { "application/json" }
end
table.insert(output, "# " .. request.name)
local curlCmd = builder.build_command(request)
curlCmd = curlCmd:gsub("%-sL", "-L")
if not useEnvVars then
-- revert the escaping for the final output.
curlCmd = curlCmd:gsub("\\{\\{", "{{"):gsub("\\}\\}", "}}")
end
if format then
for _, line in ipairs(vim.split(curlCmd, "\n", true)) do
table.insert(output, line)
end
else
curlCmd = curlCmd:gsub("\n", " ")
table.insert(output, curlCmd)
end
table.insert(output, "")
end
-- replace scratchpad content with the curl commands
vim.api.nvim_buf_set_lines(scratchBuf, 0, -1, false, output)
vim.bo.filetype = "sh"
end
vim.api.nvim_create_user_command("ExtractCommands", function(opts)
local unformatted = (opts.args == "compact")
extractCurlCommands(true, not unformatted)
end, { nargs = "?" })
vim.api.nvim_create_user_command("ExtractCommandsVar", function(opts)
local unformatted = (opts.args == "compact")
extractCurlCommands(false, not unformatted)
end, { nargs = "?" })
:ExtractCommands -> extracts all curl commands (formatted json) with variables replaced
:ExtractCommandsVar compact-> extracts all curl commands (without formatting) without variable substitution
I couldn't get rest-nvim.parser to automatically replace environment variables, I think it's because I don't pass the context argument to the parser, and I don't know how to get the current context
The output can be used to convert to, for example, postman collections with multiple-curl-to-postman
Workaround for importing curl format to http: see the bash script curlToHttp.sh mentioned here https://github.com/rest-nvim/rest.nvim/issues/144#issuecomment-2676292472