bless_plugins/fetch/
mod.rs

1mod blockless;
2
3use anyhow::{anyhow, bail, Result};
4use blockless::BlocklessHttp;
5use javy_plugin_api::javy::quickjs::{Object as JSObject, String as JSString, Value};
6use javy_plugin_api::javy::Args;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Serialize, Deserialize)]
10pub struct FetchOptions {
11    method: String,
12}
13
14impl FetchOptions {
15    pub fn new(method: &str) -> Self {
16        FetchOptions {
17            method: method.into(),
18        }
19    }
20
21    pub fn to_string(&self) -> String {
22        serde_json::to_string(&self).unwrap()
23    }
24}
25
26pub fn bless_fetch_request(args: Args<'_>) -> Result<Value<'_>> {
27    let (cx, args) = args.release();
28    let (url, options) = extract_http_args(&args, "Javy.Fetch.request")?;
29
30    let url: String = url
31        .as_string()
32        .ok_or_else(|| anyhow!("url must be a string"))?
33        .to_string()
34        .map_err(|_| anyhow!("invalid UTF-8 in url"))?;
35
36    let options: String = options
37        .as_string()
38        .ok_or_else(|| anyhow!("options must be a string"))?
39        .to_string()
40        .map_err(|_| anyhow!("invalid UTF-8 in options"))?;
41
42    let request_obj: FetchOptions = serde_json::from_str(&options)?;
43
44    // Prepare Response
45    // let mut response: HashMap<String, Value<'_>> = HashMap::new();
46    let response_obj = JSObject::new(cx.clone()).unwrap();
47
48    let http = BlocklessHttp::open(&url, &request_obj).unwrap();
49    let body = String::from_utf8(http.get_all_body().unwrap()).unwrap();
50    http.close();
51
52    response_obj.set("ok", Value::new_bool(cx.clone(), true))?;
53    response_obj.set(
54        "body",
55        Value::from_string(JSString::from_str(cx.clone(), &body)?),
56    )?;
57
58    Ok(Value::from_object(response_obj))
59}
60
61fn extract_http_args<'a, 'js: 'a>(
62    args: &'a [Value<'js>],
63    for_func: &str,
64) -> Result<(&'a Value<'js>, &'a Value<'js>)> {
65    let [url, options, ..] = args else {
66        bail!(
67            r#"{} expects 2 parameters: the URL, the TypedArray buffer,
68           the TypedArray byteOffset and the TypedArray byteLength.
69
70           Got: {} parameters."#,
71            for_func,
72            args.len()
73        );
74    };
75
76    Ok((url, options))
77}