"""Data models for depcheck.""" from dataclasses import dataclass, field from enum import Enum from typing import Optional class Severity(str, Enum): """Severity levels for vulnerabilities and updates.""" CRITICAL = "critical" HIGH = "high" MEDIUM = "medium" LOW = "low" INFO = "info" class PackageManager(str, Enum): """Supported package managers.""" NPM = "npm" PIP = "pip" GO = "go" CARGO = "cargo" @dataclass class Dependency: """Represents a single dependency.""" name: str current_version: str package_manager: PackageManager latest_version: Optional[str] = None is_outdated: bool = False vulnerabilities: list = field(default_factory=list) category: str = "dependencies" source_file: Optional[str] = None def __hash__(self): return hash((self.name, self.package_manager.value, self.current_version)) def __eq__(self, other): if not isinstance(other, Dependency): return False return ( self.name == other.name and self.package_manager == other.package_manager and self.current_version == other.current_version ) @dataclass class Vulnerability: """Represents a security vulnerability.""" cve_id: str severity: Severity description: str affected_versions: str fixed_version: Optional[str] = None references: list[str] = field(default_factory=list) @dataclass class ScanResult: """Result of a dependency scan.""" dependencies: list[Dependency] = field(default_factory=list) vulnerabilities: list[tuple[Dependency, Vulnerability]] = field(default_factory=list) scan_errors: list[str] = field(default_factory=list) package_manager: Optional[PackageManager] = None source_file: Optional[str] = None @property def outdated_count(self) -> int: return sum(1 for d in self.dependencies if d.is_outdated) @property def vulnerable_count(self) -> int: return len(self.vulnerabilities) def get_highest_severity(self) -> Optional[Severity]: if not self.vulnerabilities: return None severity_order = [Severity.CRITICAL, Severity.HIGH, Severity.MEDIUM, Severity.LOW] for severity in severity_order: for dep, vuln in self.vulnerabilities: if vuln.severity == severity: return severity return None