Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow static file config options #65

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,4 @@ cython_debug/
.vscode

node_modules
.aider*
61 changes: 45 additions & 16 deletions src/py/litestar_vite/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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."""

Expand Down Expand Up @@ -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

Expand All @@ -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:
Expand Down Expand Up @@ -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}
app_config.route_handlers.append(create_static_files_router(**static_files_config))
return app_config

@contextmanager
Expand Down
Loading