use super::{HttpBackend, HttpResponse};
use crate::nodes::function::v2::error::ResultExt;
use crate::nodes::function::v2::module::http::{HttpMethod, HttpRequestConfig};
use crate::nodes::function::v2::serde::rquickjs_conv;
use crate::nodes::http_handler::HttpHandlerRequest;
use rquickjs::promise::MaybePromise;
use rquickjs::{CatchResultExt, Ctx};
use std::future::Future;
use std::pin::Pin;
pub(crate) struct CallbackHttpBackend;
impl HttpBackend for CallbackHttpBackend {
fn execute_http<'js>(
&self,
ctx: Ctx<'js>,
method: HttpMethod,
url: String,
config: HttpRequestConfig,
) -> Pin<Box<dyn Future<Output = rquickjs::Result<HttpResponse<'js>>> + 'js>> {
Box::pin(async move {
let execute_http_fn: rquickjs::Function =
ctx.globals().get("__executeHttp").or_throw(&ctx)?;
let http_request = HttpHandlerRequest {
url,
method: method.to_string(),
body: config.data,
headers: config.headers.into_iter().map(|(k, v)| (k, v.0)).collect(),
params: config.params.into_iter().map(|(k, v)| (k, v.0)).collect(),
auth: config
.auth
.map(serde_json::to_value)
.transpose()
.or_throw(&ctx)?,
};
let http_request_js = rquickjs_conv::to_value(ctx.clone(), http_request)?;
let response_promise: MaybePromise = execute_http_fn
.call((http_request_js,))
.catch(&ctx)
.or_throw(&ctx)?;
let response: HttpResponse = response_promise
.into_future()
.await
.catch(&ctx)
.or_throw(&ctx)?;
Ok(response)
})
}
}