use night_fury_core::BrowserSession;
use serde_json::Value;
use crate::error::TailFinError;
pub async fn ensure_on_domain(session: &BrowserSession, domains: &[&str]) -> Result<(), TailFinError> {
let current_url = session.get_url().await?;
if !domains.iter().any(|d| current_url.contains(d)) {
session.navigate(&format!("https://{}", domains[0])).await?;
let _ = session.wait_for_network_idle(15000, 1000).await;
}
Ok(())
}
pub async fn page_fetch(
session: &BrowserSession,
url: &str,
method: &str,
headers: &Value,
) -> Result<Value, TailFinError> {
page_fetch_with_body(session, url, method, headers, None).await
}
pub async fn page_fetch_with_body(
session: &BrowserSession,
url: &str,
method: &str,
headers: &Value,
body: Option<&Value>,
) -> Result<Value, TailFinError> {
let url_escaped = serde_json::to_string(url).unwrap_or_default();
let method_escaped = serde_json::to_string(method).unwrap_or_default();
let headers_json = serde_json::to_string(headers).unwrap_or_default();
let body_part = match body {
Some(b) => {
let body_json = serde_json::to_string(b).unwrap_or_default();
format!(r#", body: JSON.stringify({})"#, body_json)
}
None => String::new(),
};
let js = format!(
r#"
(async () => {{
const resp = await fetch({url_escaped}, {{
method: {method_escaped},
headers: {headers_json},
credentials: "include"{body_part}
}});
if (!resp.ok) {{
return {{ __error: true, status: resp.status, statusText: resp.statusText }};
}}
return await resp.json();
}})()
"#
);
let result = session.eval(&js).await?;
if result
.get("__error")
.and_then(|v| v.as_bool())
.unwrap_or(false)
{
let status = result.get("status").and_then(|v| v.as_u64()).unwrap_or(0);
let text = result
.get("statusText")
.and_then(|v| v.as_str())
.unwrap_or("unknown");
return Err(TailFinError::Api(format!("HTTP {} {}", status, text)));
}
Ok(result)
}