diff --git a/docs/docs/http_file_spec.md b/docs/docs/http_file_spec.md index 4071bb8..5e37038 100644 --- a/docs/docs/http_file_spec.md +++ b/docs/docs/http_file_spec.md @@ -1,4 +1,4 @@ -## HTTP File Specification +# HTTP File Specification - The .http file syntax. - How to create an .http file. diff --git a/docs/docs/install.md b/docs/docs/install.md index bb92ebe..8e6bd17 100644 --- a/docs/docs/install.md +++ b/docs/docs/install.md @@ -1,4 +1,4 @@ -## Install +# Install > Requires Neovim 0.10.0+ @@ -12,33 +12,9 @@ require('lazy').setup({ { 'mistweaverco/kulala.nvim' config = function() - require('kulala').setup({ - -- default_view, body or headers - default_view = "body", - -- dev, test, prod, can be anything - -- see: https://learn.microsoft.com/en-us/aspnet/core/test/http-files?view=aspnetcore-8.0#environment-files - default_env = "dev", - -- enable/disable debug mode - debug = false, - -- default formatters for different content types - formatters = { - json = { "jq", "." }, - xml = { "xmllint", "--format", "-" }, - html = { "xmllint", "--format", "--html", "-" }, - }, - -- default icons - icons = { - inlay = { - loading = "⏳", - done = "✅ " - }, - lualine = "🐼", - }, - -- additional cURL options - -- e.g. { "--insecure", "-A", "Mozilla/5.0" } - additional_curl_options = {}, - }) + require('kulala').setup() end }, }) ``` + diff --git a/docs/docs/public_methods.md b/docs/docs/public_methods.md index d22edd3..9772e88 100644 --- a/docs/docs/public_methods.md +++ b/docs/docs/public_methods.md @@ -1,4 +1,4 @@ -## Public methods +# Public methods ### run diff --git a/docs/docs/requirements.md b/docs/docs/requirements.md index 00c6dae..5516c66 100644 --- a/docs/docs/requirements.md +++ b/docs/docs/requirements.md @@ -1,4 +1,4 @@ -## Requirements +# Requirements ### Neovim diff --git a/docs/docs/setup-options.md b/docs/docs/setup-options.md new file mode 100644 index 0000000..6d4f585 --- /dev/null +++ b/docs/docs/setup-options.md @@ -0,0 +1,183 @@ +# Setup Options + +The following options can be set in the setup function: + +### Full example + +Here is a full example of setting up the Kulala plugin with the `setup` function: + +```lua title="setup.lua" +require("kulala").setup({ + -- default_view, body or headers + default_view = "body", + -- dev, test, prod, can be anything + -- see: https://learn.microsoft.com/en-us/aspnet/core/test/http-files?view=aspnetcore-8.0#environment-files + default_env = "dev", + -- enable/disable debug mode + debug = false, + -- default formatters for different content types + formatters = { + json = { "jq", "." }, + xml = { "xmllint", "--format", "-" }, + html = { "xmllint", "--format", "--html", "-" }, + }, + -- default icons + icons = { + inlay = { + loading = "⏳", + done = "✅", + error = "❌", + }, + lualine = "🐼", + }, + -- additional cURL options + -- see: https://curl.se/docs/manpage.html + additional_curl_options = {}, +}) +``` + +### default_view + +Default view. + +Possible values: + +- `body` +- `headers` + +Default: `body` + +Example: + +```lua +require("kulala").setup({ + default_view = "body", +}) +``` + +### default_env + +Default environment. + +See: https://learn.microsoft.com/en-us/aspnet/core/test/http-files?view=aspnetcore-8.0#environment-files + +Possible values: + +- `[any string]` + +Default: `dev` + +Example: + +```lua +require("kulala").setup({ + default_env = "body", +}) +``` + +### debug + +Enable debug mode. + +Possible values: + +- `true` +- `false` + +Default: `false` + +Example: + +```lua +require("kulala").setup({ + debug = false, +}) +``` + +### formatters + +Default formatters for different content types. + +Possible values: + +- `json = [command-table]` +- `xml = [command-table]` +- `html = [command-table]` + +Default: + +```lua +formatters = { + json = { "jq", "." }, + xml = { "xmllint", "--format", "-" }, + html = { "xmllint", "--format", "--html", "-" }, +} +``` + +Example: + +```lua +require("kulala").setup({ + formatters = { + json = { "jq", "." }, + xml = { "xmllint", "--format", "-" }, + html = { "xmllint", "--format", "--html", "-" }, + }, +}) +``` + +### icons + +Default icons. + +Possible values: + +- `inlay = { loading = [string], done = [string], error = [string] }` +- `lualine = [string]` + +Default: + +```lua +icons = { + inlay = { + loading = "⏳", + done = "✅" + error = "❌", + }, + lualine = "🐼", +} +``` + +Example: + +```lua +require("kulala").setup({ + icons = { + inlay = { + loading = "⏳", + done = "✅" + error = "❌", + }, + lualine = "🐼", + }, +}) +``` + +### Additional cURL options + +Additional cURL options. + +Possible values: + +- `[table of strings]` + +Default: `{}` + +Example: + +```lua +require("kulala").setup({ + additional_curl_options = { "--insecure", "-A", "Mozilla/5.0" }, +}) +``` + diff --git a/docs/docs/usage.md b/docs/docs/usage.md deleted file mode 100644 index b9170a6..0000000 --- a/docs/docs/usage.md +++ /dev/null @@ -1,62 +0,0 @@ -## Usage - -Create a file with the `.http` extension and write your HTTP requests in it. - -```http title="examples.http" - -@name=John -@age=30 - -GET https://pokeapi.co/api/v2/pokemon/{{pokemon}} HTTP/1.1 -accept: application/json - -### - -POST https://httpbin.org/post HTTP/1.1 -content-type: application/x-www-form-urlencoded -accept: application/json - -name={{name}} -&age={{age}} - -### - -POST https://httpbin.org/post HTTP/1.1 -content-type: application/json -accept: application/json -# @env-stdin-cmd AUTH_TOKEN jq -rcj .json.token -# @env-stdin-cmd AUTH_USERNAME jq -rcj .json.username - -{ - "username": "{{USERNAME}}", - "password": "{{PASSWORD}}", - "token": "foobar" -} - -### - -POST https://httpbin.org/post HTTP/1.1 -content-type: application/json -accept: application/json -authorization: Bearer {{AUTH_TOKEN}} - -{ - "success": true, - "username": "{{AUTH_USERNAME}}" -} - -### - -POST https://httpbin.org/post?grant_type=password&client_id=here_goes_client_id&client_secret=here_goes_client_secret&username=mysfusername&password=mysfpasswordplustoken HTTP/1.1 -accept: application/json -``` - -Place the cursor on any item -in the `examples.http` and -run `:lua require('kulala').run()`. - -> Want to see the response headers instead of the response body? - -With `require('kulala').toggle_view()` you can switch between the `body` and `headers` view of the last run request. - -This persists across restarts. diff --git a/docs/docs/usage/authentication.md b/docs/docs/usage/authentication.md new file mode 100644 index 0000000..6564bac --- /dev/null +++ b/docs/docs/usage/authentication.md @@ -0,0 +1,7 @@ +# Authentication + +See these topics for more information: + +- [Sending form data](sending-form-data.md) +- [Dynamic environment variables](dynamically-setting-environment-variables-based-on-response-json.md) +- [Dotenv and environment files](dotenv-and-http-client.env.json-support) diff --git a/docs/docs/usage/dotenv-and-http-client.env.json-support.md b/docs/docs/usage/dotenv-and-http-client.env.json-support.md new file mode 100644 index 0000000..552caf8 --- /dev/null +++ b/docs/docs/usage/dotenv-and-http-client.env.json-support.md @@ -0,0 +1,90 @@ +# DotEnv and HTTP client environment variables support + +Kulala supports environment variables in `.http` files. + +It allows you to define environment variables in a `.env` file or +in a `http-client.env.json` file (preferred) and reference them in your HTTP requests. + +If you define the same environment variable in both the `.env` and the `http-client.env.json` file, +the value from the `http-client.env.json` file will be used. + +The order of the environment variables resolution is as follows: + +1. System environment variables +2. `http-client.env.json` file +3. `.env` file + +### DotEnv + +You can create a `.env` file in the root of your `.http` files directory and +define environment variables in it. + +The file should look like this: + +```env title=".env" +API_KEY=your-api-key +``` + +Then, you can reference the environment variables in your HTTP requests like this: + +```http title="examples.http" +POST https://httpbin.org/post HTTP/1.1 +content-type: application/json +Authorization: Bearer {{API_KEY}} + +{ + "name": "John" +} +``` + +### HTTP client environment variables support + +You can also define environment variables in the HTTP client settings. + +Create a file `http-client.env.json` in the root of your `.http` files directory and +define environment variables in it. + +```json title="http-client.env.json" +{ + "dev": { + "API_KEY": "your-api-key" + }, + "testing": { + "API_KEY": "your-api-key" + }, + "staging": { + "API_KEY": "your-api-key" + }, + "prod": { + "API_KEY": "your-api-key" + } +} +``` +The keys like `dev`, `testing`, `staging`, and `prod` are the environment names. + +They can be used to switch between different environments. + +You can freely define your own environment names. + +By default the `dev` environment is used. + +This can be overridden by [setting the `default_env` setup option](../setup-options). + +To change the environment, you can use the `:lua require('kulala').set_selected_env('prod')` command. + +> TIP: +> You can also use the `:lua require('kulala').set_selected_env()` +> command to select an environment using a telescope prompt. + +Then, you can reference the environment variables in your HTTP requests like this: + +```http title="examples.http" +POST https://httpbin.org/post HTTP/1.1 +content-type: application/json +Authorization: Bearer {{API_KEY}} + +{ + "name": "John" +} +``` + diff --git a/docs/docs/usage/dynamically-setting-environment-variables-based-on-response-json.md b/docs/docs/usage/dynamically-setting-environment-variables-based-on-response-json.md new file mode 100644 index 0000000..0b8b2c4 --- /dev/null +++ b/docs/docs/usage/dynamically-setting-environment-variables-based-on-response-json.md @@ -0,0 +1,63 @@ +# Dynamically setting environment variables based on response JSON + +Create a file with the `.http` extension and write your HTTP requests in it. + +```http title="examples.http" + +POST https://httpbin.org/post HTTP/1.1 +content-type: application/json +accept: application/json +# Setting the environment variables to be used in the next request. +# Any external command can be used to set the environment variables. +# The command should output the environment variable as string. +# @env-stdin-cmd AUTH_TOKEN jq -rcj .json.token +# @env-stdin-cmd AUTH_USERNAME jq -rcj .json.username + +{ + "username": "{{USERNAME}}", + "password": "{{PASSWORD}}", + "token": "foobar" +} + +### + +POST https://httpbin.org/post HTTP/1.1 +content-type: application/json +accept: application/json +authorization: Bearer {{AUTH_TOKEN}} + +{ + "success": true, + "username": "{{AUTH_USERNAME}}" +} + +### +POST https://httpbin.org/post HTTP/1.1 +content-type: application/json +accept: application/json +# Setting the environment variables to be used in the next request. +# Only dot notation is supported for JSON objects. +# If you need more fancy stuff you can use a script or jq command. +# See the example below. +# @env-json-key AUTH_TOKEN json.token +# @env-json-key AUTH_USERNAME json.username + +{ + "username": "{{USERNAME}}", + "password": "{{PASSWORD}}", + "token": "foobar" +} + +### + +POST https://httpbin.org/post HTTP/1.1 +content-type: application/json +accept: application/json +authorization: Bearer {{AUTH_TOKEN}} + +{ + "success": true, + "username": "{{AUTH_USERNAME}}" +} + +``` diff --git a/docs/docs/usage/index.md b/docs/docs/usage/index.md new file mode 100644 index 0000000..8f04b05 --- /dev/null +++ b/docs/docs/usage/index.md @@ -0,0 +1 @@ +# Usage diff --git a/docs/docs/usage/sending-form-data.md b/docs/docs/usage/sending-form-data.md new file mode 100644 index 0000000..a69a912 --- /dev/null +++ b/docs/docs/usage/sending-form-data.md @@ -0,0 +1,18 @@ +# Sending Form Data + +Create a file with the `.http` extension and write your HTTP requests in it. + +```http title="examples.http" + +@name=John +@age=30 + +POST https://httpbin.org/post HTTP/1.1 +content-type: application/x-www-form-urlencoded +accept: application/json + +name={{name}} +&age={{age}} + +``` + diff --git a/docs/docs/usage/using-environment-variables.md b/docs/docs/usage/using-environment-variables.md new file mode 100644 index 0000000..74715f0 --- /dev/null +++ b/docs/docs/usage/using-environment-variables.md @@ -0,0 +1,16 @@ +# Using Environment Variables + +Create a file with the `.http` extension and write your HTTP requests in it. + +```http title="examples.http" + +POST https://httpbin.org/post HTTP/1.1 +content-type: application/json +accept: application/json + +{ + "username": "{{AUTH_USERNAME}}", + "password": "{{AUTH_PASSWORD}}", +} + +``` diff --git a/docs/docs/usage/using-variables.md b/docs/docs/usage/using-variables.md new file mode 100644 index 0000000..5758437 --- /dev/null +++ b/docs/docs/usage/using-variables.md @@ -0,0 +1,20 @@ +# Using Variables + +Create a file with the `.http` extension and write your HTTP requests in it. + +```http title="examples.http" + +@pokemon=pikachu +@pokemon2=bulbasaur + + +GET https://pokeapi.co/api/v2/pokemon/{{pokemon}} HTTP/1.1 +accept: application/json + +### + +GET https://pokeapi.co/api/v2/pokemon/{{pokemon2}} HTTP/1.1 +accept: application/json + +### +``` diff --git a/lua/kulala/cmd/init.lua b/lua/kulala/cmd/init.lua index 541cc60..a03f068 100644 --- a/lua/kulala/cmd/init.lua +++ b/lua/kulala/cmd/init.lua @@ -2,6 +2,7 @@ local GLOBALS = require("kulala.globals") local FS = require("kulala.utils.fs") local FORMATTER = require("kulala.formatter") local EXT_PROCESSING = require("kulala.external_processing") +local INT_PROCESSING = require("kulala.internal_processing") local M = {} @@ -22,10 +23,11 @@ M.run = function(result, callback) if result.ft ~= "text" then FS.write_file(GLOBALS.BODY_FILE, FORMATTER.format(result.ft, body)) end - vim.notify(vim.inspect(result.metadata), vim.log.levels.INFO) for _, metadata in ipairs(result.metadata) do if metadata then - if metadata.name == "stdin-cmd" then + if metadata.name == "env-json-key" then + INT_PROCESSING.env_json_key(metadata.value, body) + elseif metadata.name == "stdin-cmd" then EXT_PROCESSING.stdin_cmd(metadata.value, body) elseif metadata.name == "env-stdin-cmd" then EXT_PROCESSING.env_stdin_cmd(metadata.value, body) diff --git a/lua/kulala/globals/init.lua b/lua/kulala/globals/init.lua index 992d906..de97314 100644 --- a/lua/kulala/globals/init.lua +++ b/lua/kulala/globals/init.lua @@ -2,7 +2,7 @@ local FS = require("kulala.utils.fs") local M = {} -M.VERSION = "2.1.0" +M.VERSION = "2.2.0" M.UI_ID = "kulala://ui" M.HEADERS_FILE = FS.get_plugin_tmp_dir() .. "/headers.txt" M.BODY_FILE = FS.get_plugin_tmp_dir() .. "/body.txt" diff --git a/lua/kulala/internal_processing/init.lua b/lua/kulala/internal_processing/init.lua new file mode 100644 index 0000000..6fefb00 --- /dev/null +++ b/lua/kulala/internal_processing/init.lua @@ -0,0 +1,27 @@ +local M = {} + +-- Function to access a nested key in a table dynamically +local function get_nested_value(t, key) + local keys = vim.split(key, "%.") + local value = t + for _, k in ipairs(keys) do + value = value[k] + if value == nil then + return nil + end + end + return value +end + +M.env_json_key = function(cmd, body) + local json = vim.fn.json_decode(body) + if json == nil then + vim.notify("env-json-key --> JSON parsing failed.", vim.log.levels.ERROR) + else + local kv = vim.split(cmd, " ") + local value = get_nested_value(json, kv[2]) + vim.fn.setenv(kv[1], value) + end +end + +return M diff --git a/package.json b/package.json index 443e31b..e798d14 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,4 @@ { "name": "kulala.nvim", - "version": "2.1.0" + "version": "2.2.0" } diff --git a/scripts/set-version.sh b/scripts/set-version.sh index 88738bf..6586a2a 100755 --- a/scripts/set-version.sh +++ b/scripts/set-version.sh @@ -14,12 +14,5 @@ update_package_json_version() { jq --arg v "$VERSION" '.version = $v' package.json > "$tmp" && mv "$tmp" package.json } -update_docsify_version() { - local tmp - tmp=$(mktemp) - sed -e "s/.*<\/small>/$VERSION<\/small>/" docs/_coverpage.md > "$tmp" && mv "$tmp" docs/_coverpage.md -} - update_lua_globals_version update_package_json_version -update_docsify_version