bless_plugins/fetch/
mod.rs1mod 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 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}