use async_trait::async_trait;
#[cfg(feature = "cache")]
mod cache;
mod error;
mod extractor;
mod fetcher;
#[cfg(feature = "github")]
mod github_types;
#[cfg(feature = "logging")]
mod logging;
mod preview_generator;
mod preview_service;
mod security;
mod utils;
#[cfg(feature = "browser")]
mod mcp_client;
#[cfg(feature = "browser")]
mod browser_fetcher;
#[cfg(feature = "llm")]
mod llm_extractor;
#[cfg(feature = "llm")]
mod llm_providers;
#[cfg(feature = "llm")]
mod llm_config;
#[cfg(feature = "cache")]
pub use cache::Cache;
pub use error::PreviewError;
pub use extractor::MetadataExtractor;
pub use fetcher::{FetchResult, Fetcher, FetcherConfig};
#[cfg(feature = "github")]
pub use github_types::{is_github_url, GitHubBasicPreview, GitHubDetailedInfo, GitHubRepository};
#[cfg(feature = "logging")]
pub use logging::{log_error_card, log_preview_card, setup_logging, LogConfig, LogLevelGuard};
pub use preview_generator::{CacheStrategy, UrlPreviewGenerator};
pub use preview_service::{PreviewService, PreviewServiceConfig, MAX_CONCURRENT_REQUESTS};
pub use security::{ContentLimits, UrlValidationConfig, UrlValidator};
#[cfg(feature = "browser")]
pub use mcp_client::{McpClient, McpConfig, McpTransport, BrowserUsagePolicy};
#[cfg(feature = "browser")]
pub use browser_fetcher::{BrowserFetcher, BrowserPreviewService};
#[cfg(feature = "llm")]
pub use llm_extractor::{LLMExtractor, LLMExtractorConfig, ContentFormat, ProcessedContent, ExtractionResult, LLMProvider, TokenUsage};
#[cfg(feature = "llm")]
pub use llm_providers::MockProvider;
#[cfg(feature = "llm")]
pub use llm_providers::openai::OpenAIProvider;
#[cfg(feature = "llm")]
pub use llm_providers::anthropic::AnthropicProvider;
#[cfg(feature = "llm")]
pub use llm_providers::claude_compat::ClaudeCompatProvider;
#[cfg(all(feature = "llm", feature = "cc-sdk"))]
pub use llm_providers::claude_code::ClaudeCodeProvider;
#[cfg(feature = "llm")]
pub use llm_providers::LocalProvider;
#[cfg(feature = "llm")]
pub use llm_config::{ApiKeyValidator, LLMConfig};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Preview {
pub url: String,
pub title: Option<String>,
pub description: Option<String>,
pub image_url: Option<String>,
pub favicon: Option<String>,
pub site_name: Option<String>,
}
#[async_trait]
pub trait PreviewGenerator {
async fn generate_preview(&self, url: &str) -> Result<Preview, PreviewError>;
}
#[cfg(feature = "twitter")]
pub fn is_twitter_url(url: &str) -> bool {
url.contains("twitter.com") || url.contains("x.com")
}
#[cfg(not(feature = "twitter"))]
pub fn is_twitter_url(_url: &str) -> bool {
false
}