use super::*;
impl ApiClient {
pub async fn import_project(
&self,
manifest: &serde_json::Value,
name: Option<&str>,
workspace_id: Option<&str>,
deploy: bool,
) -> Result<Answer<ImportResult>> {
let mut body = serde_json::Map::new();
body.insert("manifest".into(), manifest.clone());
body.insert("deploy".into(), deploy.into());
if let Some(name) = name {
body.insert("name".into(), name.into());
}
if let Some(workspace_id) = workspace_id {
body.insert("workspaceId".into(), workspace_id.into());
}
self.post_answer(
"/api/infra/projects/import",
&serde_json::Value::Object(body),
)
.await
}
pub async fn projects(&self) -> Result<Vec<Project>> {
Ok(self
.get::<ProjectsPage>("/api/infra/projects")
.await?
.projects)
}
pub async fn find_project(&self, reference: &str) -> Result<Project> {
one_named(self.projects().await?, reference, "projects", || {
format!("there is no project called `{reference}`")
})
}
pub async fn locate(
&self,
project_reference: &str,
service_reference: &str,
) -> Result<(Project, Service)> {
let project = self.find_project(project_reference).await?;
let service = self.find_service(&project.id, service_reference).await?;
Ok((project, service))
}
pub async fn services(&self, project_id: &str) -> Result<ServicesPage> {
self.get(&format!(
"/api/infra/projects/{project_id}/services{}",
self.environment_query('?')
))
.await
}
pub async fn canvas(&self, project_id: &str) -> Result<Canvas> {
self.get(&format!(
"/api/infra/projects/{project_id}/canvas{}",
self.environment_query('?')
))
.await
}
pub async fn place_on_canvas(
&self,
project_id: &str,
positions: &[CanvasPlacement],
) -> Result<Canvas> {
self.patch_for(
&format!(
"/api/infra/projects/{project_id}/canvas{}",
self.environment_query('?')
),
&serde_json::json!({ "positions": positions }),
)
.await
}
pub async fn arrange_canvas(&self, project_id: &str, layout: &str) -> Result<Canvas> {
self.post(
&format!(
"/api/infra/projects/{project_id}/canvas/arrange{}",
self.environment_query('?')
),
&serde_json::json!({ "layout": layout }),
)
.await
}
pub async fn find_service(&self, project_id: &str, reference: &str) -> Result<Service> {
service_named(self.services(project_id).await?.services, reference)
}
pub async fn find_services(
&self,
project_id: &str,
references: &[impl AsRef<str>],
) -> Result<Vec<Service>> {
if references.is_empty() {
return Ok(Vec::new());
}
let page = self.services(project_id).await?;
references
.iter()
.map(|reference| service_named(&page.services, reference.as_ref()).cloned())
.collect()
}
pub async fn create_service(&self, project_id: &str, draft: &NewService) -> Result<String> {
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct Created {
service_id: String,
}
Ok(self
.post::<Created, _>(&format!("/api/infra/projects/{project_id}/services"), draft)
.await?
.service_id)
}
pub async fn create_project(
&self,
name: &str,
description: Option<&str>,
workspace_id: Option<&str>,
) -> Result<Project> {
let mut body = serde_json::Map::new();
body.insert("name".into(), name.into());
if let Some(description) = description {
body.insert("description".into(), description.into());
}
if let Some(workspace_id) = workspace_id {
body.insert("workspaceId".into(), workspace_id.into());
}
Ok(self
.post::<ProjectCreated, _>("/api/infra/projects", &serde_json::Value::Object(body))
.await?
.project)
}
pub async fn rename_project(
&self,
project_id: &str,
name: Option<&str>,
description: Option<&str>,
) -> Result<()> {
let mut body = serde_json::Map::new();
if let Some(name) = name {
body.insert("name".into(), name.into());
}
if let Some(description) = description {
body.insert("description".into(), description.into());
}
self.patch(
&format!("/api/infra/projects/{project_id}"),
&serde_json::Value::Object(body),
)
.await
}
pub async fn delete_project(&self, project_id: &str, confirmation: &str) -> Result<()> {
self.delete(&format!(
"/api/infra/projects/{project_id}?confirm={}",
utf8_percent_encode(confirmation, NON_ALPHANUMERIC)
))
.await
}
pub async fn move_project(&self, project_id: &str, workspace_id: &str) -> Result<()> {
self.patch(
&format!("/api/infra/projects/{project_id}/workspace"),
&serde_json::json!({ "workspaceId": workspace_id }),
)
.await
}
pub async fn favorite_project(
&self,
project_id: &str,
favorite: bool,
) -> Result<Answer<FavoritePage>> {
self.answer(
Method::PUT,
&format!("/api/infra/projects/{project_id}/favorite"),
Some(&serde_json::json!({ "favorite": favorite })),
)
.await
}
pub async fn activity(&self, project_id: &str, limit: usize) -> Result<Vec<ActivityEntry>> {
Ok(self
.get::<ActivityPage>(&format!(
"/api/infra/projects/{project_id}/activity?limit={limit}"
))
.await?
.activity)
}
}