"""Base detector interface and registry.""" from abc import ABC, abstractmethod from pathlib import Path from typing import Dict, List, Optional class Detector(ABC): """Base class for i18n library detectors.""" @property @abstractmethod def name(self) -> str: """Detector name.""" pass @property @abstractmethod def patterns(self) -> List[str]: """File patterns to scan.""" pass @abstractmethod def detect(self, path: Path) -> Optional[str]: """Detect if the i18n library is used.""" pass @abstractmethod def get_i18n_functions(self) -> List[str]: """Get list of i18n function names.""" pass class DetectorRegistry: """Registry for i18n library detectors.""" def __init__(self) -> None: self._detectors: Dict[str, Detector] = {} def register(self, detector: Detector) -> None: """Register a detector.""" self._detectors[detector.name] = detector def get(self, name: str) -> Optional[Detector]: """Get a detector by name.""" return self._detectors.get(name) def detect_library(self, path: Path) -> Optional[str]: """Detect which i18n library is used in the path.""" for detector in self._detectors.values(): if detector.detect(path): return detector.name return None def list_detectors(self) -> List[str]: """List all registered detector names.""" return list(self._detectors.keys()) def get_default_registry() -> DetectorRegistry: """Get the default detector registry with all built-in detectors.""" registry = DetectorRegistry() from i18n_guardian.detectors.react_intl import ReactIntlDetector from i18n_guardian.detectors.i18next import I18NextDetector from i18n_guardian.detectors.vue_i18n import VueI18nDetector from i18n_guardian.detectors.gettext import GettextDetector from i18n_guardian.detectors.python_gettext import PythonGettextDetector registry.register(ReactIntlDetector()) registry.register(I18NextDetector()) registry.register(VueI18nDetector()) registry.register(GettextDetector()) registry.register(PythonGettextDetector()) return registry