"""Most do modułów opcjonalnych — CELOWO nic o nich nie wie. Ten plik jest w każdym obrazie, także tam, gdzie żadnego modułu nie ma. Dlatego nie wolno w nim wymienić z nazwy ani jednej funkcji, którą moduł wnosi: nazwa w moście byłaby dokładnie tym śladem, którego wydzielanie ma się pozbyć. Most odpowiada wyłącznie na pytanie „czy coś jest podpięte i co wnosi". Gdy nie ma nic, wszystkie odpowiedzi są puste, a aplikacja zachowuje się tak, jakby takiego pojęcia nigdy nie było — nie jak aplikacja z wyłączoną funkcją. """ from __future__ import annotations from typing import Any try: # pragma: no cover - zależy od obrazu from app import dodatki as _modul except ImportError: # obraz zbudowany bez tego katalogu _modul = None # type: ignore[assignment] DOSTEPNY = _modul is not None def funkcje() -> tuple[tuple[str, str, str, str], ...]: """Pozycje do katalogu funkcji — jako surowe krotki, nie obiekty. Surowe, bo katalog buduje `features`, a gdyby moduł importował stamtąd klasę, powstałby cykl: features → most → moduł → features.""" return _modul.FUNKCJA if _modul else () def trasy() -> dict[tuple[str, str], str]: return _modul.TRASY if _modul else {} def zasoby() -> dict[str, Any]: return _modul.ZASOBY if _modul else {} def akcje() -> dict[str, str]: """Akcje formularza wnoszone przez moduł: nazwa → wymagane uprawnienie.""" return _modul.AKCJE if _modul else {} def pola_formularza(): """Zależność FastAPI deklarująca dodatkowe pola formularza. Pola muszą być zadeklarowane w SYGNATURZE, żeby FastAPI je odczytało, a sygnatura wspólnego handlera nie może ich wymieniać. Zależność rozwiązuje jedno i drugie: moduł deklaruje własne pola u siebie, a handler wie tylko, że dostaje słownik.""" if _modul: return _modul.pola return lambda: {} def kontekst_szablonu(request) -> dict: """Co moduł dokłada do kontekstu szablonu. Bez modułu — nic.""" return _modul.katalog_dla(request) if _modul else {} def obsluz(akcja: str, **dane) -> dict | None: """Wykonanie akcji modułu. None = to nie jest jego akcja.""" return _modul.obsluz(akcja, **dane) if _modul else None def zamontuj(app, **zaleznosci) -> None: """Podpięcie tras modułu i przekazanie mu tego, czego potrzebuje.""" if _modul: _modul.zamontuj(app, **zaleznosci) def katalog_szablonow() -> list[str]: """Katalogi szablonów modułu — nakładane PRZED wspólnymi.""" if not _modul: return [] import pathlib return [str(pathlib.Path(_modul.__file__).parent / "templates")] def katalog_zasobow() -> list[str]: if not _modul: return [] import pathlib return [str(pathlib.Path(_modul.__file__).parent / "static")]