use reqwest::{Client, Response};
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::env;
use crate::api::traits::Fetch;
use crate::api::vercel::{VERCEL_ACCESS_TOKEN};
use crate::error::FluxError;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum VariableType {
#[serde(rename = "system")]
System,
#[serde(rename = "secret")]
Secret,
#[serde(rename = "encrypted")]
Encrypted,
#[serde(rename = "plain")]
Plain,
#[serde(rename = "sensitive")]
Sensitive,
}
#[derive(Serialize, Debug, Deserialize)]
pub struct VercelEnvironmentUpsert {
pub id_or_name: String,
pub token: Option<String>,
pub key: String,
pub value: String,
#[serde(rename = "type")]
pub var_type: VariableType,
pub target: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub git_branch: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub slug: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub team_id: Option<String>,
pub upsert: bool,
}
#[async_trait]
impl Fetch for VercelEnvironmentUpsert {
async fn fetch(&self, client: &Client) -> Result<Response, FluxError> {
let mut query_params = HashMap::new();
if let Some(slug) = &self.slug {
query_params.insert("slug", slug.clone());
}
if let Some(team_id) = &self.team_id {
query_params.insert("teamId", team_id.clone());
}
query_params.insert("upsert", self.upsert.to_string());
let response = client.post(&format!("https://api.vercel.com/v10/projects/{}/env", self.id_or_name))
.bearer_auth(env::var(VERCEL_ACCESS_TOKEN).unwrap_or_else(|_| self.token.clone().unwrap_or_default()))
.query(&query_params)
.json(&self)
.send()
.await
.map_err(FluxError::from_reqwest_error)?;
if !response.status().is_success() {
let error_text = response.text().await.unwrap_or_default();
println!("Error response: {}", error_text); return Err(FluxError::BadRequest(format!("Bad request: {}", error_text)));
}
Ok(response)
}
}