Skip to content

Commit 5c9c951

Browse files
committed
refact: parser
1 parent 38e5437 commit 5c9c951

File tree

7 files changed

+68
-79
lines changed

7 files changed

+68
-79
lines changed

lua/kulala/cmd/init.lua

+10-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ local process_request
2222
local reset_task_queue = function()
2323
TASK_QUEUE = {} -- Clear the task queue and stop processing
2424
RUNNING_TASK = false
25+
return true
2526
end
2627

2728
local function run_next_task()
@@ -45,8 +46,10 @@ local function run_next_task()
4546
end)
4647
end
4748

48-
local function offload_task(fn, callback)
49+
local function offload_task(fn, pos, callback)
50+
pos = pos or #TASK_QUEUE + 1
4951
table.insert(TASK_QUEUE, { fn = fn, callback = callback })
52+
5053
if not RUNNING_TASK then run_next_task() end
5154
end
5255

@@ -167,9 +170,12 @@ local function process_response(request_status, parsed_request, callback)
167170
process_metadata(parsed_request)
168171
process_internal(parsed_request)
169172

170-
if process_external(parsed_request) then
171-
process_request({ parsed_request }, parsed_request, {}, callback)
172-
return true
173+
if process_external(parsed_request) then -- replay request
174+
parsed_request.processed = true
175+
176+
offload_task(function()
177+
process_request({ parsed_request }, parsed_request, {}, callback)
178+
end, 1)
173179
end
174180

175181
response_status = save_response(request_status, parsed_request)

lua/kulala/parser/document.lua

+24-19
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,53 @@ local PARSER_UTILS = require("kulala.parser.utils")
55

66
local M = {}
77

8-
---@class Scripts
9-
---@field pre_request ScriptData
10-
---@field post_request ScriptData
11-
12-
---@class ScriptData
13-
---@field inline string[]
14-
---@field files string[]
15-
168
---@class DocumentRequest
9+
---@field metadata table<{name: string, value: string}>
10+
---@field variables DocumentVariables
11+
---@field method string
12+
---@field url string
13+
---@field http_version string
1714
---@field headers table<string, string>
1815
---@field headers_raw table<string, string>
1916
---@field cookie string
20-
---@field metadata table<{name: string, value: string}>
2117
---@field body string
2218
---@field body_display string
2319
---@field start_line number
2420
---@field end_line number
2521
---@field show_icon_line_number number
26-
---@field variables DocumentVariables
2722
---@field redirect_response_body_to_files ResponseBodyToFile[]
2823
---@field scripts Scripts
29-
---@field url string
30-
---@field method string
31-
---@field http_version string
24+
---@field processed boolean -- Whether the request has been processed, used by replay()
3225

3326
---@alias DocumentVariables table<string, string|number|boolean>
3427

3528
---@class ResponseBodyToFile
3629
---@field file string -- The file path to write the response body to
3730
---@field overwrite boolean -- Whether to overwrite the file if it already exists
3831

32+
---@class Scripts
33+
---@field pre_request ScriptData
34+
---@field post_request ScriptData
35+
36+
---@class ScriptData
37+
---@field inline string[]
38+
---@field files string[]
39+
3940
---@type DocumentRequest
4041
local default_document_request = {
42+
metadata = {},
43+
variables = {},
44+
method = "",
45+
url = "",
46+
http_version = "",
4147
headers = {},
4248
headers_raw = {},
4349
cookie = "",
44-
metadata = {},
4550
body = "",
4651
body_display = "",
4752
start_line = 0, -- 1-based
4853
end_line = 0, -- 1-based
4954
show_icon_line_number = 1,
50-
variables = {},
5155
redirect_response_body_to_files = {},
5256
scripts = {
5357
pre_request = {
@@ -59,9 +63,7 @@ local default_document_request = {
5963
files = {},
6064
},
6165
},
62-
url = "",
63-
http_version = "",
64-
method = "",
66+
processed = false,
6567
}
6668

6769
local function split_content_by_blocks(lines, line_offset)
@@ -237,6 +239,8 @@ local function parse_url(line)
237239
method, url = line:match("^([A-Z]+)%s+(.+)$")
238240
end
239241

242+
method = method or "GET"
243+
240244
return method, url, http_version
241245
end
242246

@@ -302,7 +306,8 @@ M.get_document = function()
302306
parse_metadata(request, line)
303307
-- skip comments and silently skip URLs that are commented out
304308
elseif line:match("^%s*#") or line:match("^%s*//") then
305-
if parse_url(line:match("^[^#/]+") or "") then skip_block = true end
309+
local _, url = parse_url(line:match("^%s*[#/]+%s*(.+)") or "")
310+
if url then skip_block = true end
306311
-- end of inline scripting
307312
elseif is_request_line and line:match("^%%}$") then
308313
is_prerequest_handler_script_inline = false

lua/kulala/parser/request.lua

+19-49
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ local STRING_UTILS = require("kulala.utils.string")
1010
local CURL_FORMAT_FILE = FS.get_plugin_path({ "parser", "curl-format.json" })
1111
local Logger = require("kulala.logger")
1212
local StringVariablesParser = require("kulala.parser.string_variables_parser")
13+
local utils = require("kulala.utils.table")
1314

1415
local M = {}
1516

@@ -18,27 +19,27 @@ M.scripts.javascript = require("kulala.parser.scripts.javascript")
1819

1920
---@class Request
2021
---@field metadata { name: string, value: string }[] -- Metadata of the request
22+
---@field environment table<string, string|number> -- The environment- and document-variables
2123
---@field method string -- The HTTP method of the request
22-
---@field grpc GrpcCommand|nil -- The gRPC command
23-
---@field url_raw string -- The raw URL as it appears in the document
2424
---@field url string -- The URL with variables and dynamic variables replaced
25+
---@field url_raw string -- The raw URL as it appears in the document
26+
---@field http_version string -- The HTTP version of the request
2527
---@field headers table<string, string> -- The headers with variables and dynamic variables replaced
26-
---@field headers_display table<string, string> -- The headers with variables and dynamic variables replaced and sanitized
2728
---@field headers_raw table<string, string> -- The headers as they appear in the document
29+
---@field headers_display table<string, string> -- The headers with variables and dynamic variables replaced and sanitized
30+
---@field ft string -- The filetype of the document
2831
---@field cookie string -- The cookie as it appears in the document
32+
---@field body string|nil -- The body with variables and dynamic variables replaced
2933
---@field body_raw string|nil -- The raw body as it appears in the document
3034
---@field body_computed string|nil -- The computed body as sent by curl; with variables and dynamic variables replaced
3135
---@field body_display string|nil -- The body with variables and dynamic variables replaced and sanitized
3236
---(e.g. with binary files replaced with a placeholder)
33-
---@field body string|nil -- The body with variables and dynamic variables replaced
34-
---@field environment table<string, string|number> -- The environment- and document-variables
35-
---@field cmd string[] -- The command to execute the request
36-
---@field ft string -- The filetype of the document
37-
---@field http_version string -- The HTTP version of the request
3837
---@field show_icon_line_number number|nil -- The line number to show the icon
39-
---@field scripts Scripts -- The scripts to run before and after the request
4038
---@field redirect_response_body_to_files ResponseBodyToFile[]
39+
---@field scripts Scripts -- The scripts to run before and after the request
40+
---@field cmd string[] -- The command to execute the request
4141
---@field body_temp_file string -- The path to the temporary file containing the body
42+
---@field grpc GrpcCommand|nil -- The gRPC command
4243
---@field processed boolean -- Indicates if request has been already processed, used by replay()
4344

4445
---@class GrpcCommand
@@ -54,38 +55,13 @@ local default_grpc_command = {
5455
}
5556

5657
---@type Request
58+
---@diagnostic disable-next-line: missing-fields
5759
local default_request = {
58-
metadata = {},
59-
method = "GET",
60-
grpc = nil,
61-
http_version = "",
62-
url = "",
63-
url_raw = "",
64-
headers = {},
60+
environment = {},
6561
headers_display = {},
66-
headers_raw = {},
67-
cookie = "",
68-
body = nil,
69-
body_raw = nil,
70-
body_computed = nil,
71-
body_display = nil,
72-
cmd = {},
7362
ft = "text",
74-
environment = {},
75-
redirect_response_body_to_files = {},
76-
scripts = {
77-
pre_request = {
78-
inline = {},
79-
files = {},
80-
},
81-
post_request = {
82-
inline = {},
83-
files = {},
84-
},
85-
},
86-
show_icon_line_number = 1,
63+
cmd = {},
8764
body_temp_file = "",
88-
processed = false
8965
}
9066

9167
local function process_grpc_flags(request, flag, value)
@@ -171,6 +147,8 @@ end
171147
---@param document_variables DocumentVariables -- The variables defined in the document
172148
---@param silent boolean|nil -- Whether to suppress not found variable warnings
173149
local process_variables = function(request, document_variables, silent)
150+
if request.processed then return end
151+
174152
local env = ENV_PARSER.get_env() or {}
175153
local params = { document_variables, env, silent }
176154

@@ -507,20 +485,12 @@ function M.get_basic_request_data(requests, line_nr)
507485

508486
if not document_request then return end
509487

510-
--TODO: replace with merge
511-
request.scripts.pre_request = document_request.scripts.pre_request
512-
request.scripts.post_request = document_request.scripts.post_request
513-
request.show_icon_line_number = document_request.show_icon_line_number
514-
request.headers = document_request.headers
515-
request.cookie = document_request.cookie
516-
request.headers_raw = document_request.headers_raw
488+
request = vim.tbl_extend("keep", request, document_request)
489+
517490
request.url_raw = document_request.url
518-
request.method = document_request.method
519-
request.http_version = document_request.http_version
520491
request.body_raw = document_request.body
521-
request.body_display = document_request.body_display
522-
request.metadata = document_request.metadata
523-
request.redirect_response_body_to_files = document_request.redirect_response_body_to_files
492+
493+
utils.remove_keys(request, { "body", "variables", "start_line", "end_line" })
524494

525495
return request
526496
end

lua/kulala/utils/table.lua

+6
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,10 @@ M.slice = function(tbl, first, last)
1717
return sliced
1818
end
1919

20+
M.remove_keys = function(tbl, keys)
21+
vim.iter(keys):each(function(key)
22+
tbl[key] = nil
23+
end)
24+
end
25+
2026
return M

scripts/tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ run() {
3131
if [[ -n $1 ]]; then
3232
nvim -l tests/minit.lua tests --filter "$1"
3333
else
34-
nvim -l tests/minit.lua tests
34+
nvim -l tests/minit.lua tests -o utfTerminal
3535
fi
3636
}
3737

tests/functional/parser_spec.lua

+7-5
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,18 @@ describe("requests", function()
8484
it("processes request only if it has not been processed yet", function()
8585
h.create_buf(
8686
([[
87-
POST https://httpbin.org/Time 12:00 Date 24/12
87+
GET https://typicode.com/todos?date=2020-01-01 12:34:56
8888
]]):to_table(true),
8989
"test.http"
9090
)
9191

9292
result = parser.parse() or {}
93-
assert.is_same(result.url, "https://httpbin.org/Time%2012%")
93+
assert.is_same("https://typicode.com/todos?date=2020-01-01%2012%3A34%3A56", result.url)
9494

95-
result = parser.parse({result})
96-
assert.is_same(result.url, "https://httpbin.org/Time%2012%")
95+
result.processed = true
96+
97+
result = parser.parse({ result })
98+
assert.is_same("https://typicode.com/todos?date=2020-01-01%2012%3A34%3A56", result.url)
9799
end)
98100

99101
it("skips requests commented out with # ", function()
@@ -126,7 +128,7 @@ describe("requests", function()
126128
)
127129

128130
result = parser.parse() or {}
129-
assert.is_same(result.body:gsub("\n",""), '{"test": "value"}')
131+
assert.is_same(result.body:gsub("\n", ""), '{"test": "value"}')
130132
end)
131133

132134
it("skips lines commented out with //", function()

tests/functional/ui_spec.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ describe("UI", function()
616616
GLOBALS.VERSION
617617
)
618618
result = vim.fn.getreg("+")
619-
assert.has_string(result, expected)
619+
assert.has_string(expected, result)
620620
end)
621621

622622
it("it shows help hint and window", function()

0 commit comments

Comments
 (0)