clickup_cli/commands/
attachment.rs1use crate::client::ClickUpClient;
2use crate::commands::auth::resolve_token;
3use crate::error::CliError;
4use crate::git;
5use crate::output::OutputConfig;
6use crate::Cli;
7use clap::Subcommand;
8
9#[derive(Subcommand)]
10pub enum AttachmentCommands {
11 Upload {
13 file: std::path::PathBuf,
15 #[arg(long)]
17 task: Option<String>,
18 },
19 List {
21 #[arg(long)]
23 task: Option<String>,
24 },
25}
26
27const ATTACHMENT_FIELDS: &[&str] = &["id", "title", "url", "date"];
28
29pub async fn execute(command: AttachmentCommands, cli: &Cli) -> Result<(), CliError> {
30 let token = resolve_token(cli)?;
31 let client = ClickUpClient::new(&token, cli.timeout)?;
32 let output = OutputConfig::from_cli(&cli.output, &cli.fields, cli.no_header, cli.quiet);
33
34 match command {
35 AttachmentCommands::Upload { task, file } => {
36 let task = git::require_task(cli, task.as_deref(), true)?;
37 let resp = client
38 .upload_file(&format!("/v2/task/{}/attachment", task.id), &file)
39 .await?;
40 output.print_single(&resp, ATTACHMENT_FIELDS, "id");
41 Ok(())
42 }
43 AttachmentCommands::List { task } => {
44 let task = git::require_task(cli, task.as_deref(), true)?;
47 let resp = client.get(&format!("/v2/task/{}", task.id)).await?;
48 let attachments = resp
49 .get("attachments")
50 .and_then(|a| a.as_array())
51 .cloned()
52 .unwrap_or_default();
53 output.print_items(&attachments, ATTACHMENT_FIELDS, "id");
54 Ok(())
55 }
56 }
57}