From 05dc2b08e18771b1d5ab0ae0c9b6df31abaa413f Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Mon, 2 Feb 2026 17:20:52 +0000 Subject: [PATCH] Add detectors module --- i18n_guardian/detectors/i18next.py | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 i18n_guardian/detectors/i18next.py diff --git a/i18n_guardian/detectors/i18next.py b/i18n_guardian/detectors/i18next.py new file mode 100644 index 0000000..f251cde --- /dev/null +++ b/i18n_guardian/detectors/i18next.py @@ -0,0 +1,75 @@ +"""i18next detector.""" + +import json +from pathlib import Path +from typing import Optional + +from i18n_guardian.detectors.base import Detector + + +class I18NextDetector(Detector): + """Detect i18next library usage.""" + + @property + def name(self) -> str: + return "i18next" + + @property + def patterns(self) -> list: + return ["package.json", "i18next.config.js", "i18n.config.js"] + + def detect(self, path: Path) -> Optional[str]: + """Check for i18next usage.""" + package_json = path / "package.json" + if package_json.exists(): + try: + with open(package_json, "r", encoding="utf-8") as f: + data = json.load(f) + dependencies = data.get("dependencies", {}) + dev_dependencies = data.get("devDependencies", {}) + all_deps = {**dependencies, **dev_dependencies} + if "i18next" in all_deps: + return self.name + except (json.JSONDecodeError, OSError): + pass + + i18next_config = path / "i18next.config.js" + if i18next_config.exists(): + return self.name + + i18n_config = path / "i18n.config.js" + if i18n_config.exists(): + content = i18n_config.read_text(encoding="utf-8") + if "i18next" in content: + return self.name + + locales_dir = path / "locales" + if locales_dir.exists(): + for lang_file in locales_dir.glob("*.json"): + content = lang_file.read_text(encoding="utf-8") + try: + data = json.loads(content) + if isinstance(data, dict) and len(data) > 0: + return self.name + except json.JSONDecodeError: + continue + + for js_file in path.rglob("*.js"): + try: + content = js_file.read_text(encoding="utf-8") + if "i18n.t(" in content or "i18next.t(" in content: + return self.name + except OSError: + continue + + return None + + def get_i18n_functions(self) -> list: + """Get i18next function names.""" + return [ + "t", + "i18n.t", + "i18next.t", + "useTranslation", + "withTranslation", + ]