-
-
Notifications
You must be signed in to change notification settings - Fork 12
Implement RequestInit via FetchOptions #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import gleam/dynamic.{type Dynamic} | ||
|
||
duzda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// Gleam equivalent of JavaScript [`RequestInit`](https://developer.mozilla.org/docs/Web/API/RequestInit). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrap doc comments at 80 lines like regular Gleam code, and included documentation for each option rather solely linking to an external resource 🙏 |
||
pub type FetchOptions | ||
|
||
/// Cache options, for details see [`cache`](https://developer.mozilla.org/docs/Web/API/RequestInit#cache). | ||
pub type Cache { | ||
Default | ||
NoStore | ||
Reload | ||
NoCache | ||
ForceCache | ||
OnlyIfCached | ||
} | ||
|
||
/// Credentials options, for details see [`credentials`](https://developer.mozilla.org/docs/Web/API/RequestInit#credentials). | ||
pub type Credentials { | ||
CredentialsOmit | ||
CredentialsSameOrigin | ||
CredentialsInclude | ||
} | ||
|
||
/// Cors options, for details see [`mode`](https://developer.mozilla.org/docs/Web/API/RequestInit#mode). | ||
duzda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub type Cors { | ||
SameOrigin | ||
Cors | ||
NoCors | ||
Navigate | ||
} | ||
|
||
/// Priority options, for details see [`priority`](https://developer.mozilla.org/docs/Web/API/RequestInit#priority). | ||
pub type Priority { | ||
High | ||
Low | ||
Auto | ||
} | ||
|
||
/// Redirect options, for details see [`redirect`](https://developer.mozilla.org/docs/Web/API/RequestInit#redirect). | ||
pub type Redirect { | ||
Follow | ||
Error | ||
Manual | ||
} | ||
|
||
/// Creates new empty `FetchOptions` object. | ||
/// | ||
/// Useful if more precise control over fetch is required, such as | ||
/// using signals, cache options and so on. | ||
/// | ||
/// ```gleam | ||
/// let options = fetch_options.new() | ||
/// |> fetch_options.set_cache(fetch_options.NoStore) | ||
/// ``` | ||
@external(javascript, "../../gleam_fetch_ffi.mjs", "newFetchOptions") | ||
pub fn new() -> FetchOptions | ||
|
||
/// Sets the [`cache`](https://developer.mozilla.org/docs/Web/API/RequestInit#cache) option of `FetchOptions`. | ||
/// | ||
/// ```gleam | ||
/// let options = fetch_options.new() | ||
/// |> fetch_options.set_cache(fetch_options.NoStore) | ||
/// ``` | ||
pub fn set_cache(fetch_options: FetchOptions, cache: Cache) -> FetchOptions { | ||
set_key( | ||
fetch_options, | ||
"cache", | ||
dynamic.from(case cache { | ||
Default -> "default" | ||
NoStore -> "no-store" | ||
Reload -> "reload" | ||
NoCache -> "no-cache" | ||
ForceCache -> "force-cache" | ||
OnlyIfCached -> "only-if-cached" | ||
}), | ||
) | ||
} | ||
|
||
/// Sets the [`credentials`](https://developer.mozilla.org/docs/Web/API/RequestInit#credentials) option of `FetchOptions`. | ||
/// | ||
/// ```gleam | ||
/// let options = fetch_options.new() | ||
/// |> fetch_options.set_credentials(fetch_options.CredentialsOmit) | ||
/// ``` | ||
pub fn set_credentials( | ||
fetch_options: FetchOptions, | ||
credentials: Credentials, | ||
) -> FetchOptions { | ||
set_key( | ||
fetch_options, | ||
"credentials", | ||
dynamic.from(case credentials { | ||
CredentialsOmit -> "omit" | ||
CredentialsSameOrigin -> "same-origin" | ||
CredentialsInclude -> "include" | ||
}), | ||
) | ||
} | ||
|
||
/// Sets the [`keepalive`](https://developer.mozilla.org/docs/Web/API/RequestInit#keepalive) option of `FetchOptions`. | ||
/// | ||
/// ```gleam | ||
/// let options = fetch_options.new() | ||
/// |> fetch_options.set_keepalive(True) | ||
/// ``` | ||
pub fn set_keepalive( | ||
fetch_options: FetchOptions, | ||
keepalive: Bool, | ||
) -> FetchOptions { | ||
set_key(fetch_options, "keepalive", dynamic.from(keepalive)) | ||
} | ||
|
||
/// Sets the [`cors`](https://developer.mozilla.org/docs/Web/API/RequestInit#mode) option of `FetchOptions`. | ||
/// | ||
/// ```gleam | ||
/// let options = fetch_options.new() | ||
/// |> fetch_options.set_cors(fetch_options.SameOrigin) | ||
/// ``` | ||
pub fn set_cors(fetch_options: FetchOptions, cors: Cors) -> FetchOptions { | ||
set_key( | ||
fetch_options, | ||
"mode", | ||
dynamic.from(case cors { | ||
SameOrigin -> "same-origin" | ||
Cors -> "cors" | ||
NoCors -> "no-cors" | ||
Navigate -> "navigate" | ||
}), | ||
) | ||
} | ||
|
||
/// Sets the [`priority`](https://developer.mozilla.org/docs/Web/API/RequestInit#priority) option of `FetchOptions`. | ||
/// | ||
/// ```gleam | ||
/// let options = fetch_options.new() | ||
/// |> fetch_options.set_cors(fetch_options.High) | ||
/// ``` | ||
pub fn set_priority( | ||
fetch_options: FetchOptions, | ||
priority: Priority, | ||
) -> FetchOptions { | ||
set_key( | ||
fetch_options, | ||
"priority", | ||
dynamic.from(case priority { | ||
High -> "high" | ||
Low -> "low" | ||
Auto -> "auto" | ||
}), | ||
) | ||
} | ||
|
||
/// Sets the [`redirect`](https://developer.mozilla.org/docs/Web/API/RequestInit#redirect) option of `FetchOptions`. | ||
/// | ||
/// ```gleam | ||
/// let options = fetch_options.new() | ||
/// |> fetch_options.set_redirect(fetch_options.Follow) | ||
/// ``` | ||
pub fn set_redirect( | ||
fetch_options: FetchOptions, | ||
redirect: Redirect, | ||
) -> FetchOptions { | ||
set_key( | ||
fetch_options, | ||
"redirect", | ||
dynamic.from(case redirect { | ||
Follow -> "follow" | ||
Error -> "error" | ||
Manual -> "manual" | ||
}), | ||
) | ||
} | ||
|
||
/// Generic function that sets specified option in the `FetchOptions` object. | ||
/// | ||
/// In JavaScript, this object is simply represented as `{}` with no type-checking, | ||
/// so when implementing new features, you should consult | ||
/// [documentation](https://developer.mozilla.org/docs/Web/API/RequestInit) | ||
/// for valid and sensible keys and values. | ||
@external(javascript, "../../gleam_fetch_ffi.mjs", "setKeyFetchOptions") | ||
fn set_key( | ||
fetch_options: FetchOptions, | ||
key: String, | ||
value: Dynamic, | ||
) -> FetchOptions |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import gleam/fetch.{type FetchError} | ||
import gleam/fetch/fetch_options | ||
import gleam/fetch/form_data | ||
import gleam/http.{Get, Head, Options} | ||
import gleam/http/request | ||
|
@@ -194,3 +195,25 @@ fn setup_form_data() { | |
|> form_data.append("second-key", "second-value") | ||
|> form_data.append_bits("second-key", <<"second-value-bits":utf8>>) | ||
} | ||
|
||
pub fn complex_fetch_options_test() { | ||
let req = | ||
request.new() | ||
|> request.set_method(Get) | ||
|> request.set_host("test-api.service.hmrc.gov.uk") | ||
|> request.set_path("/hello/world") | ||
|> request.prepend_header("accept", "application/vnd.hmrc.1.0+json") | ||
|
||
let options = | ||
fetch_options.new() | ||
|> fetch_options.set_cache(fetch_options.NoStore) | ||
|> fetch_options.set_cors(fetch_options.Cors) | ||
|> fetch_options.set_credentials(fetch_options.CredentialsOmit) | ||
|> fetch_options.set_keepalive(True) | ||
|> fetch_options.set_priority(fetch_options.High) | ||
|> fetch_options.set_redirect(fetch_options.Follow) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this test verify? Doesn't seem like there's assertions for any of these? |
||
|
||
use result <- promise.await(fetch.send_with(req, options)) | ||
let assert Ok(_) = result | ||
promise.resolve(Nil) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dynamic is for data coming from the outside work, for data going to FFI one should use an accurate type.
Removing the dynamic use here will also fix the warnings that
dynamic.from
emits in currentgleam_stdlib