1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
local log = require "mason-core.log"
local platform = require "mason-core.platform"
local Result = require "mason-core.result"
local spawn = require "mason-core.spawn"
local powershell = require "mason-core.managers.powershell"
local _ = require "mason-core.functional"
local USER_AGENT = "mason.nvim (+https://github.com/williamboman/mason.nvim)"
---@alias FetchMethod
---| '"GET"'
---| '"POST"'
---| '"PUT"'
---| '"PATCH"'
---| '"DELETE"'
---@alias FetchOpts {out_file: string?, method: FetchMethod?, headers: table<string, string>?, data: string?}
---@async
---@param url string The url to fetch.
---@param opts FetchOpts?
---@return Result # Result<string>
local function fetch(url, opts)
opts = opts or {}
if not opts.headers then
opts.headers = {}
end
if not opts.method then
opts.method = "GET"
end
opts.headers["User-Agent"] = USER_AGENT
log.fmt_debug("Fetching URL %s", url)
local platform_specific = Result.failure()
if platform.is_win then
local header_entries = _.join(
", ",
_.map(function(pair)
return ("%q = %q"):format(pair[1], pair[2])
end, _.to_pairs(opts.headers))
)
local headers = ("@{%s}"):format(header_entries)
if opts.out_file then
platform_specific = powershell.command(
([[iwr %s -UseBasicParsing -Method %q -Uri %q %s -OutFile %q;]]):format(
headers,
opts.method,
url,
opts.data and ("-Body %s"):format(opts.data) or "",
opts.out_file
)
)
else
platform_specific = powershell.command(
([[Write-Output (iwr %s -Method %q -UseBasicParsing %s -Uri %q).Content;]]):format(
headers,
opts.method,
opts.data and ("-Body %s"):format(opts.data) or "",
url
)
)
end
end
return platform_specific
:recover_catching(function()
local headers =
_.sort_by(_.identity, _.map(_.compose(_.format "--header='%s'", _.join ": "), _.to_pairs(opts.headers)))
return spawn
.wget({
headers,
"-nv",
"-O",
opts.out_file or "-",
("--method=%s"):format(opts.method),
opts.data and {
("--body-data=%s"):format(opts.data) or vim.NIL,
} or vim.NIL,
url,
})
:get_or_throw()
end)
:recover_catching(function()
local headers = _.sort_by(
_.nth(2),
_.map(
_.compose(function(header)
return { "-H", header }
end, _.join ": "),
_.to_pairs(opts.headers)
)
)
return spawn
.curl({
headers,
"-fsSL",
{
"-X",
opts.method,
},
opts.data and { "-d", "@-" } or vim.NIL,
opts.out_file and { "-o", opts.out_file } or vim.NIL,
url,
on_spawn = function(_, stdio)
local stdin = stdio[1]
if opts.data then
log.trace("Writing stdin to curl", opts.data)
stdin:write(opts.data)
end
stdin:close()
end,
})
:get_or_throw()
end)
:map(function(result)
if opts.out_file then
return result
else
return result.stdout
end
end)
end
return fetch
|