re-uploading work
This commit is contained in:
346
crates/cli/src/commands/trigger.rs
Normal file
346
crates/cli/src/commands/trigger.rs
Normal file
@@ -0,0 +1,346 @@
|
||||
use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::client::ApiClient;
|
||||
use crate::config::CliConfig;
|
||||
use crate::output::{self, OutputFormat};
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum TriggerCommands {
|
||||
/// List all triggers
|
||||
List {
|
||||
/// Filter by pack name
|
||||
#[arg(long)]
|
||||
pack: Option<String>,
|
||||
},
|
||||
/// Show details of a specific trigger
|
||||
Show {
|
||||
/// Trigger reference (pack.trigger or ID)
|
||||
trigger_ref: String,
|
||||
},
|
||||
/// Update a trigger
|
||||
Update {
|
||||
/// Trigger reference (pack.trigger or ID)
|
||||
trigger_ref: String,
|
||||
|
||||
/// Update label
|
||||
#[arg(long)]
|
||||
label: Option<String>,
|
||||
|
||||
/// Update description
|
||||
#[arg(long)]
|
||||
description: Option<String>,
|
||||
|
||||
/// Update enabled status
|
||||
#[arg(long)]
|
||||
enabled: Option<bool>,
|
||||
},
|
||||
/// Delete a trigger
|
||||
Delete {
|
||||
/// Trigger reference (pack.trigger or ID)
|
||||
trigger_ref: String,
|
||||
|
||||
/// Skip confirmation prompt
|
||||
#[arg(short, long)]
|
||||
yes: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct Trigger {
|
||||
id: i64,
|
||||
#[serde(rename = "ref")]
|
||||
trigger_ref: String,
|
||||
#[serde(default)]
|
||||
pack: Option<i64>,
|
||||
#[serde(default)]
|
||||
pack_ref: Option<String>,
|
||||
label: String,
|
||||
description: Option<String>,
|
||||
enabled: bool,
|
||||
#[serde(default)]
|
||||
param_schema: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
out_schema: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
webhook_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
webhook_key: Option<String>,
|
||||
created: String,
|
||||
updated: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct TriggerDetail {
|
||||
id: i64,
|
||||
#[serde(rename = "ref")]
|
||||
trigger_ref: String,
|
||||
#[serde(default)]
|
||||
pack: Option<i64>,
|
||||
#[serde(default)]
|
||||
pack_ref: Option<String>,
|
||||
label: String,
|
||||
description: Option<String>,
|
||||
enabled: bool,
|
||||
#[serde(default)]
|
||||
param_schema: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
out_schema: Option<serde_json::Value>,
|
||||
#[serde(default)]
|
||||
webhook_enabled: Option<bool>,
|
||||
#[serde(default)]
|
||||
webhook_key: Option<String>,
|
||||
created: String,
|
||||
updated: String,
|
||||
}
|
||||
|
||||
pub async fn handle_trigger_command(
|
||||
profile: &Option<String>,
|
||||
command: TriggerCommands,
|
||||
api_url: &Option<String>,
|
||||
output_format: OutputFormat,
|
||||
) -> Result<()> {
|
||||
match command {
|
||||
TriggerCommands::List { pack } => handle_list(pack, profile, api_url, output_format).await,
|
||||
TriggerCommands::Show { trigger_ref } => {
|
||||
handle_show(trigger_ref, profile, api_url, output_format).await
|
||||
}
|
||||
TriggerCommands::Update {
|
||||
trigger_ref,
|
||||
label,
|
||||
description,
|
||||
enabled,
|
||||
} => {
|
||||
handle_update(
|
||||
trigger_ref,
|
||||
label,
|
||||
description,
|
||||
enabled,
|
||||
profile,
|
||||
api_url,
|
||||
output_format,
|
||||
)
|
||||
.await
|
||||
}
|
||||
TriggerCommands::Delete { trigger_ref, yes } => {
|
||||
handle_delete(trigger_ref, yes, profile, api_url, output_format).await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_list(
|
||||
pack: Option<String>,
|
||||
profile: &Option<String>,
|
||||
api_url: &Option<String>,
|
||||
output_format: OutputFormat,
|
||||
) -> Result<()> {
|
||||
let config = CliConfig::load_with_profile(profile.as_deref())?;
|
||||
let mut client = ApiClient::from_config(&config, api_url);
|
||||
|
||||
let path = if let Some(pack_name) = pack {
|
||||
format!("/triggers?pack={}", pack_name)
|
||||
} else {
|
||||
"/triggers".to_string()
|
||||
};
|
||||
|
||||
let triggers: Vec<Trigger> = client.get(&path).await?;
|
||||
|
||||
match output_format {
|
||||
OutputFormat::Json | OutputFormat::Yaml => {
|
||||
output::print_output(&triggers, output_format)?;
|
||||
}
|
||||
OutputFormat::Table => {
|
||||
if triggers.is_empty() {
|
||||
output::print_info("No triggers found");
|
||||
} else {
|
||||
let mut table = output::create_table();
|
||||
output::add_header(&mut table, vec!["ID", "Pack", "Name", "Description"]);
|
||||
|
||||
for trigger in triggers {
|
||||
table.add_row(vec![
|
||||
trigger.id.to_string(),
|
||||
trigger.pack_ref.as_deref().unwrap_or("").to_string(),
|
||||
trigger.label.clone(),
|
||||
output::truncate(&trigger.description.unwrap_or_default(), 50),
|
||||
]);
|
||||
}
|
||||
|
||||
println!("{}", table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_show(
|
||||
trigger_ref: String,
|
||||
profile: &Option<String>,
|
||||
api_url: &Option<String>,
|
||||
output_format: OutputFormat,
|
||||
) -> Result<()> {
|
||||
let config = CliConfig::load_with_profile(profile.as_deref())?;
|
||||
let mut client = ApiClient::from_config(&config, api_url);
|
||||
|
||||
let path = format!("/triggers/{}", trigger_ref);
|
||||
let trigger: TriggerDetail = client.get(&path).await?;
|
||||
|
||||
match output_format {
|
||||
OutputFormat::Json | OutputFormat::Yaml => {
|
||||
output::print_output(&trigger, output_format)?;
|
||||
}
|
||||
OutputFormat::Table => {
|
||||
output::print_section(&format!("Trigger: {}", trigger.trigger_ref));
|
||||
output::print_key_value_table(vec![
|
||||
("ID", trigger.id.to_string()),
|
||||
("Ref", trigger.trigger_ref.clone()),
|
||||
(
|
||||
"Pack",
|
||||
trigger.pack_ref.as_deref().unwrap_or("None").to_string(),
|
||||
),
|
||||
("Label", trigger.label.clone()),
|
||||
(
|
||||
"Description",
|
||||
trigger.description.unwrap_or_else(|| "None".to_string()),
|
||||
),
|
||||
("Enabled", output::format_bool(trigger.enabled)),
|
||||
(
|
||||
"Webhook Enabled",
|
||||
output::format_bool(trigger.webhook_enabled.unwrap_or(false)),
|
||||
),
|
||||
("Created", output::format_timestamp(&trigger.created)),
|
||||
("Updated", output::format_timestamp(&trigger.updated)),
|
||||
]);
|
||||
|
||||
if let Some(webhook_key) = &trigger.webhook_key {
|
||||
output::print_section("Webhook");
|
||||
output::print_info(&format!("Key: {}", webhook_key));
|
||||
}
|
||||
|
||||
if let Some(param_schema) = &trigger.param_schema {
|
||||
if !param_schema.is_null() {
|
||||
output::print_section("Parameter Schema");
|
||||
println!("{}", serde_json::to_string_pretty(param_schema)?);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(out_schema) = &trigger.out_schema {
|
||||
if !out_schema.is_null() {
|
||||
output::print_section("Output Schema");
|
||||
println!("{}", serde_json::to_string_pretty(out_schema)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_update(
|
||||
trigger_ref: String,
|
||||
label: Option<String>,
|
||||
description: Option<String>,
|
||||
enabled: Option<bool>,
|
||||
profile: &Option<String>,
|
||||
api_url: &Option<String>,
|
||||
output_format: OutputFormat,
|
||||
) -> Result<()> {
|
||||
let config = CliConfig::load_with_profile(profile.as_deref())?;
|
||||
let mut client = ApiClient::from_config(&config, api_url);
|
||||
|
||||
// Check that at least one field is provided
|
||||
if label.is_none() && description.is_none() && enabled.is_none() {
|
||||
anyhow::bail!("At least one field must be provided to update");
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct UpdateTriggerRequest {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
label: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
description: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
enabled: Option<bool>,
|
||||
}
|
||||
|
||||
let request = UpdateTriggerRequest {
|
||||
label,
|
||||
description,
|
||||
enabled,
|
||||
};
|
||||
|
||||
let path = format!("/triggers/{}", trigger_ref);
|
||||
let trigger: TriggerDetail = client.put(&path, &request).await?;
|
||||
|
||||
match output_format {
|
||||
OutputFormat::Json | OutputFormat::Yaml => {
|
||||
output::print_output(&trigger, output_format)?;
|
||||
}
|
||||
OutputFormat::Table => {
|
||||
output::print_success(&format!(
|
||||
"Trigger '{}' updated successfully",
|
||||
trigger.trigger_ref
|
||||
));
|
||||
output::print_key_value_table(vec![
|
||||
("ID", trigger.id.to_string()),
|
||||
("Ref", trigger.trigger_ref.clone()),
|
||||
(
|
||||
"Pack",
|
||||
trigger.pack_ref.as_deref().unwrap_or("None").to_string(),
|
||||
),
|
||||
("Label", trigger.label.clone()),
|
||||
(
|
||||
"Description",
|
||||
trigger.description.unwrap_or_else(|| "None".to_string()),
|
||||
),
|
||||
("Enabled", output::format_bool(trigger.enabled)),
|
||||
("Updated", output::format_timestamp(&trigger.updated)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_delete(
|
||||
trigger_ref: String,
|
||||
yes: bool,
|
||||
profile: &Option<String>,
|
||||
api_url: &Option<String>,
|
||||
output_format: OutputFormat,
|
||||
) -> Result<()> {
|
||||
let config = CliConfig::load_with_profile(profile.as_deref())?;
|
||||
let mut client = ApiClient::from_config(&config, api_url);
|
||||
|
||||
// Confirm deletion unless --yes is provided
|
||||
if !yes && matches!(output_format, OutputFormat::Table) {
|
||||
let confirm = dialoguer::Confirm::new()
|
||||
.with_prompt(format!(
|
||||
"Are you sure you want to delete trigger '{}'?",
|
||||
trigger_ref
|
||||
))
|
||||
.default(false)
|
||||
.interact()?;
|
||||
|
||||
if !confirm {
|
||||
output::print_info("Delete cancelled");
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let path = format!("/triggers/{}", trigger_ref);
|
||||
client.delete_no_response(&path).await?;
|
||||
|
||||
match output_format {
|
||||
OutputFormat::Json | OutputFormat::Yaml => {
|
||||
let msg = serde_json::json!({"message": "Trigger deleted successfully"});
|
||||
output::print_output(&msg, output_format)?;
|
||||
}
|
||||
OutputFormat::Table => {
|
||||
output::print_success(&format!("Trigger '{}' deleted successfully", trigger_ref));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user