use serde::{Deserialize, Serialize};
use crate::api::client::ApiClient;
use crate::error::OlError;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorToolRow {
#[serde(default)]
pub id: Option<String>,
pub slug: String,
#[serde(default)]
pub version: Option<String>,
#[serde(default)]
pub lifecycle_state: Option<String>,
#[serde(default)]
pub routing_score: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorProviderRow {
#[serde(default)]
pub id: Option<String>,
pub slug: String,
#[serde(default)]
pub display_name: Option<String>,
#[serde(default)]
pub region: Option<String>,
#[serde(default)]
pub total_capacity_qps: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EditorBindingRow {
pub id: String,
pub tool: String,
pub provider: String,
#[serde(default)]
pub state: Option<String>,
#[serde(default)]
pub routing_score: Option<f64>,
}
#[derive(Debug, Deserialize)]
pub struct ListResponse<T> {
#[serde(default = "Vec::new")]
pub data: Vec<T>,
#[serde(default)]
pub total: Option<u64>,
#[serde(default)]
pub page: Option<u64>,
#[serde(default)]
pub page_size: Option<u64>,
}
#[derive(Debug, Serialize, Default)]
pub struct EditorProfilePatch {
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub homepage_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub docs_url: Option<String>,
}
pub async fn update_profile(
client: &ApiClient,
patch: &EditorProfilePatch,
) -> Result<serde_json::Value, OlError> {
client.patch("/api/v1/editor/profile", patch).await
}
pub async fn list_tools(client: &ApiClient) -> Result<Vec<EditorToolRow>, OlError> {
let resp: ListResponse<EditorToolRow> = client.get("/api/v1/editor/tools").await?;
Ok(resp.data)
}
pub async fn delete_tool(client: &ApiClient, slug: &str) -> Result<(), OlError> {
let _: serde_json::Value = client
.delete(&format!("/api/v1/editor/tools/{slug}"))
.await?;
Ok(())
}
pub async fn deprecate_tool(
client: &ApiClient,
slug: &str,
message: &str,
) -> Result<serde_json::Value, OlError> {
#[derive(Serialize)]
struct Body<'a> {
lifecycle_state: &'a str,
message: &'a str,
}
client
.patch(
&format!("/api/v1/editor/tools/{slug}"),
&Body {
lifecycle_state: "deprecated",
message,
},
)
.await
}
pub async fn list_providers(client: &ApiClient) -> Result<Vec<EditorProviderRow>, OlError> {
let resp: ListResponse<EditorProviderRow> = client.get("/api/v1/editor/providers").await?;
Ok(resp.data)
}
pub async fn delete_provider(client: &ApiClient, slug: &str) -> Result<(), OlError> {
let _: serde_json::Value = client
.delete(&format!("/api/v1/editor/providers/{slug}"))
.await?;
Ok(())
}
pub async fn update_provider(
client: &ApiClient,
slug: &str,
patch: &serde_json::Value,
) -> Result<serde_json::Value, OlError> {
client
.patch(&format!("/api/v1/editor/providers/{slug}"), patch)
.await
}
pub async fn list_bindings(client: &ApiClient) -> Result<Vec<EditorBindingRow>, OlError> {
let resp: ListResponse<EditorBindingRow> = client.get("/api/v1/editor/bindings").await?;
Ok(resp.data)
}
pub async fn upsert_tool(
client: &ApiClient,
body: &serde_json::Value,
) -> Result<serde_json::Value, OlError> {
client.post("/api/v1/editor/tools", body).await
}
pub async fn upsert_provider(
client: &ApiClient,
body: &serde_json::Value,
) -> Result<serde_json::Value, OlError> {
client.post("/api/v1/editor/providers", body).await
}
#[derive(Debug, Clone, Deserialize)]
pub struct UpsertBindingResponse {
pub id: String,
#[serde(default)]
pub state: Option<String>,
#[serde(default)]
pub secret: Option<String>,
}
pub async fn upsert_binding(
client: &ApiClient,
body: &serde_json::Value,
) -> Result<UpsertBindingResponse, OlError> {
client.post("/api/v1/editor/bindings", body).await
}
async fn validate(client: &ApiClient, path: &str, body: &serde_json::Value) -> Result<(), OlError> {
let _: serde_json::Value = client.post(path, body).await?;
Ok(())
}
pub async fn validate_editor_slug(client: &ApiClient, slug: &str) -> Result<(), OlError> {
validate(
client,
"/api/v1/auth/editor-slug:validate",
&serde_json::json!({ "slug": slug }),
)
.await
}
pub async fn validate_tool(client: &ApiClient, body: &serde_json::Value) -> Result<(), OlError> {
validate(client, "/api/v1/editor/tools:validate", body).await
}
pub async fn validate_provider(
client: &ApiClient,
body: &serde_json::Value,
) -> Result<(), OlError> {
validate(client, "/api/v1/editor/providers:validate", body).await
}
pub async fn validate_binding(
client: &ApiClient,
tool_slug: &str,
provider_slug: &str,
) -> Result<(), OlError> {
validate(
client,
"/api/v1/editor/bindings:validate",
&serde_json::json!({ "tool_slug": tool_slug, "provider_slug": provider_slug }),
)
.await
}