Skip to content

Commit 6ffe451

Browse files
ghivertlpil
authored andcommitted
Add support for FormData
1 parent 61bc591 commit 6ffe451

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

src/gleam/fetch.gleam

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import gleam/dynamic.{type Dynamic}
2+
import gleam/form_data.{type FormData}
13
import gleam/http/request.{type Request}
24
import gleam/http/response.{type Response}
3-
import gleam/dynamic.{type Dynamic}
45
import gleam/javascript/promise.{type Promise}
56

67
pub type FetchError {
@@ -29,6 +30,17 @@ pub fn send(
2930
})
3031
}
3132

33+
pub fn send_form_data(
34+
request: Request(FormData),
35+
) -> Promise(Result(Response(FetchBody), FetchError)) {
36+
request
37+
|> form_data_to_fetch_request
38+
|> raw_send
39+
|> promise.try_await(fn(resp) {
40+
promise.resolve(Ok(from_fetch_response(resp)))
41+
})
42+
}
43+
3244
pub fn send_bits(
3345
request: Request(BitArray),
3446
) -> Promise(Result(Response(FetchBody), FetchError)) {
@@ -43,6 +55,9 @@ pub fn send_bits(
4355
@external(javascript, "../gleam_fetch_ffi.mjs", "to_fetch_request")
4456
pub fn to_fetch_request(a: Request(String)) -> FetchRequest
4557

58+
@external(javascript, "../gleam_fetch_ffi.mjs", "form_data_to_fetch_request")
59+
pub fn form_data_to_fetch_request(a: Request(FormData)) -> FetchRequest
60+
4661
@external(javascript, "../gleam_fetch_ffi.mjs", "bitarray_request_to_fetch_request")
4762
pub fn bitarray_request_to_fetch_request(a: Request(BitArray)) -> FetchRequest
4863

src/gleam/form_data.gleam

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
pub type FormData
2+
3+
@external(javascript, "../gleam_fetch_ffi.mjs", "newFormData")
4+
pub fn new() -> FormData
5+
6+
@external(javascript, "../gleam_fetch_ffi.mjs", "appendFormData")
7+
pub fn append(form_data: FormData, key: String, value: String) -> FormData
8+
9+
@external(javascript, "../gleam_fetch_ffi.mjs", "appendBitsFormData")
10+
pub fn append_bits(
11+
form_data: FormData,
12+
key: String,
13+
value: BitArray,
14+
) -> FormData
15+
16+
@external(javascript, "../gleam_fetch_ffi.mjs", "setFormData")
17+
pub fn set(form_data: FormData, key: String, value: String) -> FormData
18+
19+
@external(javascript, "../gleam_fetch_ffi.mjs", "setBitsFormData")
20+
pub fn set_bits(form_data: FormData, key: String, value: BitArray) -> FormData

src/gleam_fetch_ffi.mjs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ export function to_fetch_request(request) {
4141
return new globalThis.Request(url, options);
4242
}
4343

44+
export function form_data_to_fetch_request(request) {
45+
let [url, options] = request_common(request)
46+
if (options.method !== "GET" && options.method !== "HEAD") options.body = request.body;
47+
// Remove `content-type`, because the browser will add the correct header by itself.
48+
delete options.headers['content-type']
49+
return new globalThis.Request(url, options);
50+
}
51+
4452
export function bitarray_request_to_fetch_request(request) {
4553
let [url, options] = request_common(request)
4654
if (options.method !== "GET" && options.method !== "HEAD") options.body = request.body.buffer;
@@ -81,3 +89,37 @@ export async function read_json_body(response) {
8189
return new Error(new InvalidJsonBody());
8290
}
8391
}
92+
93+
export function newFormData() {
94+
return new FormData()
95+
}
96+
97+
function cloneFormData(formData) {
98+
const f = new FormData()
99+
for (const [key, value] of formData.entries()) f.append(key, value)
100+
return f
101+
}
102+
103+
export function appendFormData(formData, key, value) {
104+
const f = cloneFormData(formData)
105+
f.append(key, value)
106+
return f
107+
}
108+
109+
export function setFormData(formData, key, value) {
110+
const f = cloneFormData(formData)
111+
f.set(key, value)
112+
return f
113+
}
114+
115+
export function appendBitsFormData(formData, key, value) {
116+
const f = cloneFormData(formData)
117+
f.append(key, new Blob([value.buffer]))
118+
return f
119+
}
120+
121+
export function setBitsFormData(formData, key, value) {
122+
const f = cloneFormData(formData)
123+
f.set(key, new Blob([value.buffer]))
124+
return f
125+
}

0 commit comments

Comments
 (0)