use std::sync::Mutex;
use reqwest::Client;
use crate::auth::AuthState;
use crate::core::CliError;
use crate::net::http;
pub(crate) const BASE_URL: &str = "https://studio-api-prod.suno.com";
pub struct SunoClient {
pub(crate) client: Client,
base_url: String,
pub(crate) auth: Mutex<AuthState>,
}
impl SunoClient {
pub async fn new_with_refresh(mut auth: AuthState) -> Result<Self, CliError> {
let client = http::browser_client()?;
super::auth_retry::refresh_state_if_needed(&client, &mut auth).await?;
Ok(Self {
client,
base_url: BASE_URL.to_string(),
auth: Mutex::new(auth),
})
}
#[cfg(test)]
pub(crate) fn new_for_tests(base_url: String, auth: AuthState) -> Result<Self, CliError> {
Ok(Self {
client: http::browser_client()?,
base_url: base_url.trim_end_matches('/').to_string(),
auth: Mutex::new(auth),
})
}
fn url(&self, path: &str) -> String {
format!("{}{}", self.base_url, path)
}
pub(crate) fn get(&self, path: &str) -> reqwest::RequestBuilder {
self.client.get(self.url(path)).headers(self.headers())
}
pub(crate) fn post(&self, path: &str) -> reqwest::RequestBuilder {
self.client.post(self.url(path)).headers(self.headers())
}
pub(crate) fn patch(&self, path: &str) -> reqwest::RequestBuilder {
self.client.patch(self.url(path)).headers(self.headers())
}
pub(crate) fn put(&self, path: &str) -> reqwest::RequestBuilder {
self.client.put(self.url(path)).headers(self.headers())
}
pub(crate) fn delete(&self, path: &str) -> reqwest::RequestBuilder {
self.client.delete(self.url(path)).headers(self.headers())
}
}