use crate::client::{OrdinaryApiClient, compress_zstd, ops};
use anyhow::bail;
use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD as b64};
use ordinary_config::OrdinaryConfig;
use std::path::Path;
pub async fn install(
api_client: &OrdinaryApiClient<'_>,
proj_path: &str,
action_name: &str,
) -> anyhow::Result<()> {
let config = OrdinaryConfig::get(proj_path)?;
let correlation_id = api_client
.correlation_id
.unwrap_or(uuid::Uuid::new_v4())
.to_string();
if let Some(actions) = &config.actions {
if let Some(action) = actions.iter().find(|t| t.name == action_name) {
let Some(dir_path) = &action.dir_path else {
tracing::error!("no dir_path provided for action");
bail!("no dir_path provided for action");
};
let access_token = api_client
.get_access(None, Some(correlation_id.clone()))
.await?;
ops::assets::write_frontend(
api_client,
proj_path,
&config,
&access_token,
&correlation_id,
)
.await?;
let access_token = api_client
.get_access(None, Some(correlation_id.clone()))
.await?;
let bin_path = Path::new(proj_path)
.join(dir_path)
.join("target/wasm32-wasip1/release/action.wasm");
tracing::info!("{:?}, {}", bin_path, bin_path.exists());
let action_bytes = fs_err::read(bin_path)?;
tracing::info!(
"installing action '{}' to {} with idx {}...",
action.name,
config.domain,
action.idx
);
api_client
.client
.put(format!("{}/v1/actions", api_client.addr))
.query(&[("d", config.domain), ("i", action.idx.to_string())])
.body(compress_zstd(&action_bytes[..])?)
.header("x-correlation-id", correlation_id.as_str())
.header("Content-Encoding", "zstd")
.header(
"Authorization",
format!("Bearer {}", b64.encode(&access_token)),
)
.send()
.await?
.bytes()
.await?;
tracing::info!("successfully installed action '{}'.", action.name);
}
} else {
tracing::warn!("no \"actions\" field in ordinary.json");
}
Ok(())
}
pub async fn install_all(
api_client: &OrdinaryApiClient<'_>,
proj_path: &str,
) -> anyhow::Result<()> {
let config = OrdinaryConfig::get(proj_path)?;
let correlation_id = api_client
.correlation_id
.unwrap_or(uuid::Uuid::new_v4())
.to_string();
if let Some(actions) = &config.actions {
let access_token = api_client
.get_access(None, Some(correlation_id.clone()))
.await?;
ops::assets::write_frontend(
api_client,
proj_path,
&config,
&access_token,
&correlation_id,
)
.await?;
for action in actions {
let Some(dir_path) = &action.dir_path else {
tracing::error!("no dir_path provided for action");
bail!("no dir_path provided for action");
};
let access_token = api_client
.get_access(None, Some(correlation_id.clone()))
.await?;
let bin_path = Path::new(proj_path)
.join(dir_path)
.join("target/wasm32-wasip1/release/action.wasm");
let action_bytes = fs_err::read(bin_path)?;
tracing::info!(
"installing action '{}' to {} with idx {}...",
&action.name,
&config.domain,
&action.idx
);
api_client
.client
.put(format!("{}/v1/actions", api_client.addr))
.body(compress_zstd(&action_bytes[..])?)
.query(&[("d", config.domain.clone()), ("i", action.idx.to_string())])
.header("x-correlation-id", correlation_id.as_str())
.header("Content-Encoding", "zstd")
.header(
"Authorization",
format!("Bearer {}", b64.encode(&access_token)),
)
.send()
.await?
.bytes()
.await?;
}
tracing::info!("all actions successfully installed.");
} else {
tracing::warn!("no \"actions\" field in ordinary.json");
}
Ok(())
}