use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct User {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub clerk_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub avatar_url: Option<String>,
pub created_at: DateTime<Utc>,
#[serde(default)]
pub teams: Vec<TeamMembership>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Project {
pub id: String,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub slug: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub team_id: String,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
#[serde(default)]
pub environments: Vec<Environment>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Environment {
pub id: String,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub project_id: String,
#[serde(skip_serializing_if = "Option::is_none", alias = "inherits_from_id")]
pub inherits_from: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub order: Option<i32>,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Secret {
pub id: String,
pub key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub environment_id: String,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub secret_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SecretWithValue {
pub id: String,
pub key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub environment_id: String,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub secret_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub value: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SecretWithInheritance {
pub id: String,
pub key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub environment_id: String,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub secret_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inherited_from: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SecretWithValueAndInheritance {
pub id: String,
pub key: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub environment_id: String,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub secret_type: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub value: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub inherited_from: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SecretInput {
pub key: String,
pub value: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
impl SecretInput {
pub fn new(key: impl Into<String>, value: impl Into<String>) -> Self {
Self {
key: key.into(),
value: value.into(),
description: None,
}
}
pub fn with_description(
key: impl Into<String>,
value: impl Into<String>,
description: impl Into<String>,
) -> Self {
Self {
key: key.into(),
value: value.into(),
description: Some(description.into()),
}
}
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct BulkImportOptions {
pub overwrite: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BulkImportResult {
pub created: i32,
pub updated: i32,
pub skipped: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Permission {
pub id: String,
pub user_id: String,
pub user_email: String,
pub environment_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub environment_name: Option<String>,
pub role: String,
pub can_write: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PermissionInput {
pub user_id: String,
pub role: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MyPermissionsResponse {
pub permissions: Vec<Permission>,
pub is_team_admin: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DefaultPermission {
pub environment_name: String,
pub default_role: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SecretHistory {
pub id: String,
pub secret_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub key: Option<String>,
pub version: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub changed_by: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub change_type: Option<String>,
#[serde(alias = "created_at")]
pub changed_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Team {
pub id: String,
pub name: String,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct TeamMembership {
pub team_id: String,
pub user_id: String,
pub role: String,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub team: Option<Team>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ServiceToken {
pub id: String,
pub name: String,
pub project_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub project_name: Option<String>,
pub permissions: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct CurrentUserResponse {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub clerk_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(default)]
pub teams: Vec<TeamMembership>,
#[serde(skip_serializing_if = "Option::is_none")]
pub team_id: Option<String>,
#[serde(default)]
pub project_ids: Vec<String>,
#[serde(default)]
pub scopes: Vec<String>,
}
impl CurrentUserResponse {
pub fn is_service_token(&self) -> bool {
self.auth_type.as_deref() == Some("service_token")
}
pub fn is_user(&self) -> bool {
!self.is_service_token()
}
}
#[derive(Debug, Deserialize)]
pub(crate) struct DataResponse<T> {
pub data: T,
}
#[derive(Debug, Deserialize)]
pub(crate) struct ProjectsResponse {
#[serde(rename = "data")]
pub projects: Vec<Project>,
}
#[derive(Debug, Deserialize)]
pub(crate) struct EnvironmentsResponse {
#[serde(rename = "data")]
pub environments: Vec<Environment>,
}
#[derive(Debug, Deserialize)]
pub(crate) struct SecretsResponse {
#[serde(rename = "data")]
pub secrets: Vec<SecretWithInheritance>,
}
#[derive(Debug, Deserialize)]
pub(crate) struct SecretsExportResponse {
#[serde(rename = "data")]
pub secrets: Vec<SecretWithValueAndInheritance>,
}
#[derive(Debug, Deserialize)]
pub(crate) struct PermissionsResponse {
#[serde(rename = "data")]
pub permissions: Vec<Permission>,
}
#[derive(Debug, Deserialize)]
pub(crate) struct DefaultsResponse {
#[serde(rename = "data")]
pub defaults: Vec<DefaultPermission>,
}
#[derive(Debug, Deserialize)]
pub(crate) struct HistoryResponse {
#[serde(rename = "data")]
pub history: Vec<SecretHistory>,
}
#[derive(Debug, Deserialize)]
pub(crate) struct SecretResponse {
#[serde(rename = "data")]
pub secret: SecretWithValueAndInheritance,
}
#[derive(Debug, Deserialize)]
pub(crate) struct ApiErrorResponse {
pub error: Option<String>,
pub message: Option<String>,
pub code: Option<String>,
}