diff --git a/docs/docs/scripts/request-reference.md b/docs/docs/scripts/request-reference.md index 49cbdab..ae1030d 100644 --- a/docs/docs/scripts/request-reference.md +++ b/docs/docs/scripts/request-reference.md @@ -25,7 +25,8 @@ client.log(request.variables.get("SOME_TOKEN")); ## request.body.getRaw -Returns the request body in the raw format: +Returns the request body `string` in +the raw format (or `undefined` if there is no body). If the body contains variables, their names are displayed instead of their values. @@ -37,12 +38,85 @@ client.log(request.body.getRaw()); ## request.body.tryGetSubstituted -Returns the request body with variables substituted. +Returns the request body with variables substituted +(or `undefined` if there is no body). ```javascript client.log(request.body.tryGetSubstituted()); ``` +## request.body.getComputed + +Returns the `string` request body as sent via curl; with variables substituted, +or `undefined` if there is no body. + +:::tip + +Useful if you want to see the request body as it was sent to the server. + +The `tryGetSubstituted` method will substitute variables with their values, +but leave the rest of the body as is. + +If you have a GraphQL query in the body, for example, the `getComputed` +method will show the query as it was sent to the server, +which is quite different from the substituted version. + +::: + +As an example, if you have a request body like this: + +```graphql +query getRestClient($name: String!) { + restclient(name: $name) { + id + name + editorsSupported { + name + } + } +} + +{ + "variables": { + "name": "{{ENV_VAR_CLIENT_NAME}}" + } +} +``` + +Then the `getComputed` method will +return the body as it was sent to the server: + +```json +{"query": "query getRestClient($name: String!) { restclient(name: $name) { id name editorsSupported { name } } } ", "variables": {"variables": {"name": "kulala"}}} +``` + +whereas the `tryGetSubstituted` method will +return the body with variables substituted as seen in your script: + +```graphql +query getRestClient($name: String!) { + restclient(name: $name) { + id + name + editorsSupported { + name + } + } +} + +{ + "variables": { + "name": "kulala" + } +} +``` + +:::warning + +The `getComputed` method is always `undefined` for binary bodies. + +::: + ## request.environment.get diff --git a/lua/kulala/globals/init.lua b/lua/kulala/globals/init.lua index d9cf78e..55e87dd 100644 --- a/lua/kulala/globals/init.lua +++ b/lua/kulala/globals/init.lua @@ -4,7 +4,7 @@ local M = {} local plugin_tmp_dir = FS.get_plugin_tmp_dir() -M.VERSION = "4.0.4" +M.VERSION = "4.1.0" M.UI_ID = "kulala://ui" M.SCRATCHPAD_ID = "kulala://scratchpad" M.HEADERS_FILE = plugin_tmp_dir .. "/headers.txt" diff --git a/lua/kulala/parser/init.lua b/lua/kulala/parser/init.lua index c3b810f..029e31d 100644 --- a/lua/kulala/parser/init.lua +++ b/lua/kulala/parser/init.lua @@ -466,6 +466,7 @@ end ---@field headers table -- The headers with variables and dynamic variables replaced ---@field headers_raw table -- The headers as they appear in the document ---@field body_raw string|nil -- The raw body as it appears in the document +---@field body_computed string|nil -- The computed body as sent by curl; with variables and dynamic variables replaced ---@field body string|nil -- The body with variables and dynamic variables replaced ---@field environment table -- The environment- and document-variables ---@field cmd table -- The command to execute the request @@ -488,6 +489,7 @@ function M.get_basic_request_data(start_request_linenr) headers_raw = {}, body = nil, body_raw = nil, + body_computed = nil, cmd = {}, ft = "text", environment = {}, @@ -583,6 +585,23 @@ M.parse = function(start_request_linenr) end end + local is_graphql = PARSER_UTILS.contains_meta_tag(res, "graphql") + or PARSER_UTILS.contains_header(res.headers, "x-request-type", "graphql") + if res.body ~= nil then + if is_graphql then + local gql_json = GRAPHQL_PARSER.get_json(res.body) + if gql_json then + res.body_computed = gql_json + end + else + res.body_computed = res.body + end + end + if CONFIG.get().treesitter then + -- treesitter parser handles graphql requests before this point + is_graphql = false + end + FS.write_file(GLOBALS.REQUEST_FILE, vim.fn.json_encode(res), false) -- PERF: We only want to run the scripts if they exist -- Also we don't want to re-run the environment replace_variables_in_url_headers_body @@ -611,13 +630,6 @@ M.parse = function(start_request_linenr) table.insert(res.cmd, "-X") table.insert(res.cmd, res.method) - local is_graphql = PARSER_UTILS.contains_meta_tag(res, "graphql") - or PARSER_UTILS.contains_header(res.headers, "x-request-type", "graphql") - if CONFIG.get().treesitter then - -- treesitter parser handles graphql requests before this point - is_graphql = false - end - local content_type_header_name, content_type_header_value = PARSER_UTILS.get_header(res.headers, "content-type") if content_type_header_name and content_type_header_value and res.body ~= nil then @@ -651,7 +663,8 @@ M.parse = function(start_request_linenr) if gql_json then table.insert(res.cmd, "--data") table.insert(res.cmd, gql_json) - res.headers[content_type_header_name] = "application/json" + res.headers["content-type"] = "application/json" + res.body_computed = gql_json end end end diff --git a/lua/kulala/parser/scripts/engines/javascript/lib/src/lib/PreRequestRequest.ts b/lua/kulala/parser/scripts/engines/javascript/lib/src/lib/PreRequestRequest.ts index e845b3c..d8039db 100644 --- a/lua/kulala/parser/scripts/engines/javascript/lib/src/lib/PreRequestRequest.ts +++ b/lua/kulala/parser/scripts/engines/javascript/lib/src/lib/PreRequestRequest.ts @@ -9,6 +9,7 @@ interface RequestJson { headers: Record, headers_raw: Record, body_raw: string, + body_computed: string | undefined, body: string | object, method: string, url_raw: string, @@ -59,6 +60,9 @@ export const Request = { tryGetSubstituted: () => { return req.body; }, + getComputed: () => { + return req.body_computed; + }, }, headers: { findByName: (headerName: string) => { diff --git a/lua/kulala/utils/fs.lua b/lua/kulala/utils/fs.lua index 0796a6c..e7c4fe7 100644 --- a/lua/kulala/utils/fs.lua +++ b/lua/kulala/utils/fs.lua @@ -201,9 +201,10 @@ end ---Delete all files in a directory ---@param dir string ----@param verbose boolean|nil ----@usage fs.delete_files_in_directory('tmp', true) -M.delete_files_in_directory = function(dir, verbose) +---@usage fs.delete_files_in_directory('tmp') +---@return string[] deleted_files +M.delete_files_in_directory = function(dir) + local deleted_files = {} -- Open the directory for scanning local scandir = vim.loop.fs_scandir(dir) if scandir then @@ -219,15 +220,15 @@ M.delete_files_in_directory = function(dir, verbose) local success, err = vim.loop.fs_unlink(filepath) if not success then print("Error deleting file:", filepath, err) - end - if verbose and success then - Logger.info("Deleted file: " .. filepath) + else + table.insert(deleted_files, filepath) end end end else print("Error opening directory:", dir) end + return deleted_files end M.delete_request_scripts_files = function() @@ -330,10 +331,18 @@ M.clear_cached_files = function() local scripts_dir = M.get_tmp_scripts_dir() local request_scripts_dir = M.get_request_scripts_dir() local compiled_pre_request_scripts = M.join_paths(M.get_scripts_dir(), "engines", "javascript", "lib", "dist") - M.delete_files_in_directory(tmp_dir, true) - M.delete_files_in_directory(scripts_dir, true) - M.delete_files_in_directory(request_scripts_dir, true) - M.delete_files_in_directory(compiled_pre_request_scripts, true) + local deleted_files = {} + deleted_files = vim.tbl_extend("force", deleted_files, M.delete_files_in_directory(tmp_dir)) + deleted_files = vim.tbl_extend("force", deleted_files, M.delete_files_in_directory(scripts_dir)) + deleted_files = vim.tbl_extend("force", deleted_files, M.delete_files_in_directory(request_scripts_dir)) + deleted_files = vim.tbl_extend("force", deleted_files, M.delete_files_in_directory(compiled_pre_request_scripts)) + local string_list = vim.fn.join( + vim.tbl_map(function(file) + return "- " .. file + end, deleted_files), + "\n" + ) + Logger.info("Deleted files:\n" .. string_list) end return M