From 3a63eb8d4fc4c31e5743f132e93b75f10dcbea7e Mon Sep 17 00:00:00 2001 From: CJ Lazell Date: Thu, 2 Jan 2025 11:37:46 -0600 Subject: [PATCH] Patch to allow static file config options --- src/py/litestar_vite/plugin.py | 61 +++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/src/py/litestar_vite/plugin.py b/src/py/litestar_vite/plugin.py index c96193a..643d721 100644 --- a/src/py/litestar_vite/plugin.py +++ b/src/py/litestar_vite/plugin.py @@ -6,8 +6,9 @@ import subprocess import threading from contextlib import contextmanager +from dataclasses import dataclass from pathlib import Path -from typing import TYPE_CHECKING, Iterator, cast +from typing import TYPE_CHECKING, Any, Iterator, Sequence from litestar.cli._utils import console from litestar.contrib.jinja import JinjaTemplateEngine @@ -18,6 +19,16 @@ from click import Group from litestar import Litestar from litestar.config.app import AppConfig + from litestar.datastructures import CacheControlHeader + from litestar.openapi.spec import SecurityRequirement + from litestar.types import ( + AfterRequestHookHandler, # pyright: ignore[reportUnknownVariableType] + AfterResponseHookHandler, # pyright: ignore[reportUnknownVariableType] + BeforeRequestHookHandler, # pyright: ignore[reportUnknownVariableType] + ExceptionHandlersMap, + Guard, # pyright: ignore[reportUnknownVariableType] + Middleware, + ) from litestar_vite.config import ViteConfig from litestar_vite.loader import ViteAssetLoader @@ -35,6 +46,20 @@ def set_environment(config: ViteConfig) -> None: os.environ.setdefault("VITE_DEV_MODE", str(config.dev_mode)) +@dataclass +class StaticFilesConfig: + after_request: AfterRequestHookHandler | None = None + after_response: AfterResponseHookHandler | None = None + before_request: BeforeRequestHookHandler | None = None + cache_control: CacheControlHeader | None = None + exception_handlers: ExceptionHandlersMap | None = None + guards: list[Guard] | None = None + middleware: Sequence[Middleware] | None = None + opt: dict[str, Any] | None = None + security: Sequence[SecurityRequirement] | None = None + tags: Sequence[str] | None = None + + class ViteProcess: """Manages the Vite process.""" @@ -85,14 +110,20 @@ def stop(self, timeout: float = 5.0) -> None: class VitePlugin(InitPluginProtocol, CLIPlugin): """Vite plugin.""" - __slots__ = ("_asset_loader", "_config", "_vite_process") + __slots__ = ("_asset_loader", "_config", "_static_files_config", "_vite_process") - def __init__(self, config: ViteConfig | None = None, asset_loader: ViteAssetLoader | None = None) -> None: + def __init__( + self, + config: ViteConfig | None = None, + asset_loader: ViteAssetLoader | None = None, + static_files_config: StaticFilesConfig | None = None, + ) -> None: """Initialize ``Vite``. Args: config: configuration to use for starting Vite. The default configuration will be used if it is not provided. asset_loader: an initialized asset loader to use for rendering asset tags. + static_files_config: optional configuration dictionary for the static files router. """ from litestar_vite.config import ViteConfig @@ -101,6 +132,7 @@ def __init__(self, config: ViteConfig | None = None, asset_loader: ViteAssetLoad self._config = config self._asset_loader = asset_loader self._vite_process = ViteProcess() + self._static_files_config: dict[str, Any] = static_files_config.__dict__ if static_files_config else {} @property def config(self) -> ViteConfig: @@ -140,19 +172,16 @@ def on_app_init(self, app_config: AppConfig) -> AppConfig: static_dirs = [Path(self._config.bundle_dir), Path(self._config.resource_dir)] if Path(self._config.public_dir).exists() and self._config.public_dir != self._config.bundle_dir: static_dirs.append(Path(self._config.public_dir)) - app_config.route_handlers.append( - create_static_files_router( - directories=cast( # type: ignore[arg-type] - "list[Path]", - static_dirs if self._config.dev_mode else [Path(self._config.bundle_dir)], - ), - path=self._config.asset_url, - name="vite", - html_mode=False, - include_in_schema=False, - opt={"exclude_from_auth": True}, - ), - ) + base_config = { + "directories": static_dirs if self._config.dev_mode else [Path(self._config.bundle_dir)], + "path": self._config.asset_url, + "name": "vite", + "html_mode": False, + "include_in_schema": False, + "opt": {"exclude_from_auth": True}, + } + static_files_config: dict[str, Any] = {**base_config, **self._static_files_config.__dict__} + app_config.route_handlers.append(create_static_files_router(**static_files_config)) return app_config @contextmanager