litestar-vite 0.1.1__py3-none-any.whl → 0.15.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- litestar_vite/__init__.py +54 -4
- litestar_vite/__metadata__.py +12 -7
- litestar_vite/cli.py +1048 -10
- litestar_vite/codegen/__init__.py +48 -0
- litestar_vite/codegen/_export.py +229 -0
- litestar_vite/codegen/_inertia.py +619 -0
- litestar_vite/codegen/_openapi.py +280 -0
- litestar_vite/codegen/_routes.py +720 -0
- litestar_vite/codegen/_ts.py +235 -0
- litestar_vite/codegen/_utils.py +141 -0
- litestar_vite/commands.py +73 -0
- litestar_vite/config/__init__.py +997 -0
- litestar_vite/config/_constants.py +97 -0
- litestar_vite/config/_deploy.py +70 -0
- litestar_vite/config/_inertia.py +241 -0
- litestar_vite/config/_paths.py +63 -0
- litestar_vite/config/_runtime.py +235 -0
- litestar_vite/config/_spa.py +93 -0
- litestar_vite/config/_types.py +94 -0
- litestar_vite/deploy.py +366 -0
- litestar_vite/doctor.py +1181 -0
- litestar_vite/exceptions.py +78 -0
- litestar_vite/executor.py +360 -0
- litestar_vite/handler/__init__.py +9 -0
- litestar_vite/handler/_app.py +612 -0
- litestar_vite/handler/_routing.py +130 -0
- litestar_vite/html_transform.py +569 -0
- litestar_vite/inertia/__init__.py +77 -0
- litestar_vite/inertia/_utils.py +119 -0
- litestar_vite/inertia/exception_handler.py +178 -0
- litestar_vite/inertia/helpers.py +1571 -0
- litestar_vite/inertia/middleware.py +54 -0
- litestar_vite/inertia/plugin.py +199 -0
- litestar_vite/inertia/precognition.py +274 -0
- litestar_vite/inertia/request.py +334 -0
- litestar_vite/inertia/response.py +802 -0
- litestar_vite/inertia/types.py +335 -0
- litestar_vite/loader.py +464 -123
- litestar_vite/plugin/__init__.py +687 -0
- litestar_vite/plugin/_process.py +185 -0
- litestar_vite/plugin/_proxy.py +689 -0
- litestar_vite/plugin/_proxy_headers.py +244 -0
- litestar_vite/plugin/_static.py +37 -0
- litestar_vite/plugin/_utils.py +489 -0
- litestar_vite/py.typed +0 -0
- litestar_vite/scaffolding/__init__.py +20 -0
- litestar_vite/scaffolding/generator.py +270 -0
- litestar_vite/scaffolding/templates.py +437 -0
- litestar_vite/templates/__init__.py +0 -0
- litestar_vite/templates/addons/tailwindcss/tailwind.css.j2 +1 -0
- litestar_vite/templates/angular/index.html.j2 +12 -0
- litestar_vite/templates/angular/openapi-ts.config.ts.j2 +18 -0
- litestar_vite/templates/angular/package.json.j2 +36 -0
- litestar_vite/templates/angular/src/app/app.component.css.j2 +3 -0
- litestar_vite/templates/angular/src/app/app.component.html.j2 +1 -0
- litestar_vite/templates/angular/src/app/app.component.ts.j2 +9 -0
- litestar_vite/templates/angular/src/app/app.config.ts.j2 +5 -0
- litestar_vite/templates/angular/src/main.ts.j2 +9 -0
- litestar_vite/templates/angular/src/styles.css.j2 +9 -0
- litestar_vite/templates/angular/tsconfig.app.json.j2 +34 -0
- litestar_vite/templates/angular/tsconfig.json.j2 +20 -0
- litestar_vite/templates/angular/vite.config.ts.j2 +21 -0
- litestar_vite/templates/angular-cli/.postcssrc.json.j2 +5 -0
- litestar_vite/templates/angular-cli/angular.json.j2 +36 -0
- litestar_vite/templates/angular-cli/openapi-ts.config.ts.j2 +18 -0
- litestar_vite/templates/angular-cli/package.json.j2 +28 -0
- litestar_vite/templates/angular-cli/proxy.conf.json.j2 +18 -0
- litestar_vite/templates/angular-cli/src/app/app.component.css.j2 +3 -0
- litestar_vite/templates/angular-cli/src/app/app.component.html.j2 +1 -0
- litestar_vite/templates/angular-cli/src/app/app.component.ts.j2 +9 -0
- litestar_vite/templates/angular-cli/src/app/app.config.ts.j2 +5 -0
- litestar_vite/templates/angular-cli/src/index.html.j2 +13 -0
- litestar_vite/templates/angular-cli/src/main.ts.j2 +6 -0
- litestar_vite/templates/angular-cli/src/styles.css.j2 +10 -0
- litestar_vite/templates/angular-cli/tailwind.config.js.j2 +4 -0
- litestar_vite/templates/angular-cli/tsconfig.app.json.j2 +16 -0
- litestar_vite/templates/angular-cli/tsconfig.json.j2 +26 -0
- litestar_vite/templates/angular-cli/tsconfig.spec.json.j2 +9 -0
- litestar_vite/templates/astro/astro.config.mjs.j2 +28 -0
- litestar_vite/templates/astro/openapi-ts.config.ts.j2 +15 -0
- litestar_vite/templates/astro/src/layouts/Layout.astro.j2 +63 -0
- litestar_vite/templates/astro/src/pages/index.astro.j2 +36 -0
- litestar_vite/templates/astro/src/styles/global.css.j2 +1 -0
- litestar_vite/templates/base/.gitignore.j2 +42 -0
- litestar_vite/templates/base/openapi-ts.config.ts.j2 +15 -0
- litestar_vite/templates/base/package.json.j2 +39 -0
- litestar_vite/templates/base/resources/vite-env.d.ts.j2 +1 -0
- litestar_vite/templates/base/tsconfig.json.j2 +37 -0
- litestar_vite/templates/htmx/src/main.js.j2 +8 -0
- litestar_vite/templates/htmx/templates/base.html.j2.j2 +56 -0
- litestar_vite/templates/htmx/templates/index.html.j2.j2 +13 -0
- litestar_vite/templates/htmx/vite.config.ts.j2 +40 -0
- litestar_vite/templates/nuxt/app.vue.j2 +29 -0
- litestar_vite/templates/nuxt/composables/useApi.ts.j2 +33 -0
- litestar_vite/templates/nuxt/nuxt.config.ts.j2 +31 -0
- litestar_vite/templates/nuxt/openapi-ts.config.ts.j2 +15 -0
- litestar_vite/templates/nuxt/pages/index.vue.j2 +54 -0
- litestar_vite/templates/react/index.html.j2 +13 -0
- litestar_vite/templates/react/src/App.css.j2 +56 -0
- litestar_vite/templates/react/src/App.tsx.j2 +19 -0
- litestar_vite/templates/react/src/main.tsx.j2 +10 -0
- litestar_vite/templates/react/vite.config.ts.j2 +39 -0
- litestar_vite/templates/react-inertia/index.html.j2 +14 -0
- litestar_vite/templates/react-inertia/package.json.j2 +47 -0
- litestar_vite/templates/react-inertia/resources/App.css.j2 +68 -0
- litestar_vite/templates/react-inertia/resources/main.tsx.j2 +17 -0
- litestar_vite/templates/react-inertia/resources/pages/Home.tsx.j2 +18 -0
- litestar_vite/templates/react-inertia/resources/ssr.tsx.j2 +19 -0
- litestar_vite/templates/react-inertia/vite.config.ts.j2 +59 -0
- litestar_vite/templates/react-router/index.html.j2 +12 -0
- litestar_vite/templates/react-router/src/App.css.j2 +17 -0
- litestar_vite/templates/react-router/src/App.tsx.j2 +7 -0
- litestar_vite/templates/react-router/src/main.tsx.j2 +10 -0
- litestar_vite/templates/react-router/vite.config.ts.j2 +39 -0
- litestar_vite/templates/react-tanstack/index.html.j2 +12 -0
- litestar_vite/templates/react-tanstack/openapi-ts.config.ts.j2 +18 -0
- litestar_vite/templates/react-tanstack/src/App.css.j2 +17 -0
- litestar_vite/templates/react-tanstack/src/main.tsx.j2 +21 -0
- litestar_vite/templates/react-tanstack/src/routeTree.gen.ts.j2 +7 -0
- litestar_vite/templates/react-tanstack/src/routes/__root.tsx.j2 +9 -0
- litestar_vite/templates/react-tanstack/src/routes/books.tsx.j2 +9 -0
- litestar_vite/templates/react-tanstack/src/routes/index.tsx.j2 +9 -0
- litestar_vite/templates/react-tanstack/vite.config.ts.j2 +39 -0
- litestar_vite/templates/svelte/index.html.j2 +13 -0
- litestar_vite/templates/svelte/src/App.svelte.j2 +30 -0
- litestar_vite/templates/svelte/src/app.css.j2 +45 -0
- litestar_vite/templates/svelte/src/main.ts.j2 +8 -0
- litestar_vite/templates/svelte/src/vite-env.d.ts.j2 +2 -0
- litestar_vite/templates/svelte/svelte.config.js.j2 +5 -0
- litestar_vite/templates/svelte/vite.config.ts.j2 +39 -0
- litestar_vite/templates/svelte-inertia/index.html.j2 +14 -0
- litestar_vite/templates/svelte-inertia/resources/app.css.j2 +21 -0
- litestar_vite/templates/svelte-inertia/resources/main.ts.j2 +11 -0
- litestar_vite/templates/svelte-inertia/resources/pages/Home.svelte.j2 +43 -0
- litestar_vite/templates/svelte-inertia/resources/vite-env.d.ts.j2 +2 -0
- litestar_vite/templates/svelte-inertia/svelte.config.js.j2 +5 -0
- litestar_vite/templates/svelte-inertia/vite.config.ts.j2 +37 -0
- litestar_vite/templates/sveltekit/openapi-ts.config.ts.j2 +15 -0
- litestar_vite/templates/sveltekit/src/app.css.j2 +40 -0
- litestar_vite/templates/sveltekit/src/app.html.j2 +12 -0
- litestar_vite/templates/sveltekit/src/hooks.server.ts.j2 +55 -0
- litestar_vite/templates/sveltekit/src/routes/+layout.svelte.j2 +12 -0
- litestar_vite/templates/sveltekit/src/routes/+page.svelte.j2 +34 -0
- litestar_vite/templates/sveltekit/svelte.config.js.j2 +12 -0
- litestar_vite/templates/sveltekit/tsconfig.json.j2 +14 -0
- litestar_vite/templates/sveltekit/vite.config.ts.j2 +31 -0
- litestar_vite/templates/vue/env.d.ts.j2 +7 -0
- litestar_vite/templates/vue/index.html.j2 +13 -0
- litestar_vite/templates/vue/src/App.vue.j2 +28 -0
- litestar_vite/templates/vue/src/main.ts.j2 +5 -0
- litestar_vite/templates/vue/src/style.css.j2 +45 -0
- litestar_vite/templates/vue/vite.config.ts.j2 +39 -0
- litestar_vite/templates/vue-inertia/env.d.ts.j2 +7 -0
- litestar_vite/templates/vue-inertia/index.html.j2 +14 -0
- litestar_vite/templates/vue-inertia/package.json.j2 +50 -0
- litestar_vite/templates/vue-inertia/resources/main.ts.j2 +18 -0
- litestar_vite/templates/vue-inertia/resources/pages/Home.vue.j2 +22 -0
- litestar_vite/templates/vue-inertia/resources/ssr.ts.j2 +21 -0
- litestar_vite/templates/vue-inertia/resources/style.css.j2 +21 -0
- litestar_vite/templates/vue-inertia/vite.config.ts.j2 +59 -0
- litestar_vite-0.15.0.dist-info/METADATA +230 -0
- litestar_vite-0.15.0.dist-info/RECORD +164 -0
- {litestar_vite-0.1.1.dist-info → litestar_vite-0.15.0.dist-info}/WHEEL +1 -1
- litestar_vite/config.py +0 -100
- litestar_vite/plugin.py +0 -45
- litestar_vite/template_engine.py +0 -103
- litestar_vite-0.1.1.dist-info/METADATA +0 -68
- litestar_vite-0.1.1.dist-info/RECORD +0 -11
- {litestar_vite-0.1.1.dist-info → litestar_vite-0.15.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""Runtime execution settings."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from litestar_vite.config._constants import TRUE_VALUES
|
|
8
|
+
|
|
9
|
+
__all__ = ("ExternalDevServer", "RuntimeConfig", "resolve_trusted_proxies")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def resolve_trusted_proxies() -> "list[str] | str | None":
|
|
13
|
+
"""Resolve trusted_proxies from environment variable.
|
|
14
|
+
|
|
15
|
+
Reads LITESTAR_TRUSTED_PROXIES env var. Examples:
|
|
16
|
+
- "*" -> Trust all proxies (for container environments)
|
|
17
|
+
- "127.0.0.1" -> Trust localhost only
|
|
18
|
+
- "10.0.0.0/8,172.16.0.0/12" -> Trust private networks
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
The trusted proxies configuration, or None if not set.
|
|
22
|
+
"""
|
|
23
|
+
env_value = os.getenv("LITESTAR_TRUSTED_PROXIES")
|
|
24
|
+
if env_value is None:
|
|
25
|
+
return None
|
|
26
|
+
env_value = env_value.strip()
|
|
27
|
+
if env_value == "*":
|
|
28
|
+
return "*"
|
|
29
|
+
if not env_value:
|
|
30
|
+
return None
|
|
31
|
+
return [h.strip() for h in env_value.split(",") if h.strip()]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def resolve_proxy_mode() -> "Literal['vite', 'direct', 'proxy'] | None":
|
|
35
|
+
"""Resolve proxy_mode from environment variable.
|
|
36
|
+
|
|
37
|
+
Reads VITE_PROXY_MODE env var. Valid values:
|
|
38
|
+
- "vite" (default): Proxy to internal Vite server (allow list - assets only)
|
|
39
|
+
- "direct": Expose Vite port directly (no proxy)
|
|
40
|
+
- "proxy": Proxy everything except Litestar routes (deny list)
|
|
41
|
+
- "none": Disable proxy (for production)
|
|
42
|
+
|
|
43
|
+
Raises:
|
|
44
|
+
ValueError: If an invalid value is provided.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
The resolved proxy mode, or None if disabled.
|
|
48
|
+
"""
|
|
49
|
+
env_value = os.getenv("VITE_PROXY_MODE")
|
|
50
|
+
match env_value.strip().lower() if env_value is not None else None:
|
|
51
|
+
case None:
|
|
52
|
+
return "vite"
|
|
53
|
+
case "none":
|
|
54
|
+
return None
|
|
55
|
+
case "direct":
|
|
56
|
+
return "direct"
|
|
57
|
+
case "proxy":
|
|
58
|
+
return "proxy"
|
|
59
|
+
case "vite":
|
|
60
|
+
return "vite"
|
|
61
|
+
case _:
|
|
62
|
+
msg = f"Invalid VITE_PROXY_MODE: {env_value!r}. Expected one of: vite, direct, proxy, none"
|
|
63
|
+
raise ValueError(msg)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass
|
|
67
|
+
class ExternalDevServer:
|
|
68
|
+
"""Configuration for external (non-Vite) dev servers.
|
|
69
|
+
|
|
70
|
+
Use this when your frontend uses a framework with its own dev server
|
|
71
|
+
(Angular CLI, Next.js, Create React App, etc.) instead of Vite.
|
|
72
|
+
|
|
73
|
+
For SSR frameworks (Astro, Nuxt, SvelteKit) using Vite internally, leave
|
|
74
|
+
target as None - the proxy will read the dynamic port from the hotfile.
|
|
75
|
+
|
|
76
|
+
Attributes:
|
|
77
|
+
target: The URL of the external dev server (e.g., "http://localhost:4200").
|
|
78
|
+
If None, the proxy reads the target URL from the Vite hotfile.
|
|
79
|
+
command: Custom command to start the dev server (e.g., ["ng", "serve"]).
|
|
80
|
+
If None and start_dev_server=True, uses executor's default start command.
|
|
81
|
+
build_command: Custom command to build for production (e.g., ["ng", "build"]).
|
|
82
|
+
If None, uses executor's default build command (e.g., "npm run build").
|
|
83
|
+
http2: Enable HTTP/2 for proxy connections.
|
|
84
|
+
enabled: Whether the external proxy is enabled.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
target: "str | None" = None
|
|
88
|
+
command: "list[str] | None" = None
|
|
89
|
+
build_command: "list[str] | None" = None
|
|
90
|
+
http2: bool = False
|
|
91
|
+
enabled: bool = True
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dataclass
|
|
95
|
+
class RuntimeConfig:
|
|
96
|
+
"""Runtime execution settings.
|
|
97
|
+
|
|
98
|
+
Attributes:
|
|
99
|
+
dev_mode: Enable development mode with HMR/watch.
|
|
100
|
+
proxy_mode: Proxy handling mode:
|
|
101
|
+
- "vite" (default): Proxy Vite assets only (allow list - SPA mode)
|
|
102
|
+
- "direct": Expose Vite port directly (no proxy)
|
|
103
|
+
- "proxy": Proxy everything except Litestar routes (deny list - framework mode)
|
|
104
|
+
- None: No proxy (production mode)
|
|
105
|
+
external_dev_server: Configuration for external dev server (used with proxy_mode="proxy").
|
|
106
|
+
host: Vite dev server host.
|
|
107
|
+
port: Vite dev server port.
|
|
108
|
+
protocol: Protocol for dev server (http/https).
|
|
109
|
+
executor: JavaScript runtime executor (node, bun, deno).
|
|
110
|
+
run_command: Custom command to run Vite dev server (auto-detect if None).
|
|
111
|
+
build_command: Custom command to build with Vite (auto-detect if None).
|
|
112
|
+
build_watch_command: Custom command for watch mode build.
|
|
113
|
+
serve_command: Custom command to run production server (for SSR frameworks).
|
|
114
|
+
install_command: Custom command to install dependencies.
|
|
115
|
+
is_react: Enable React Fast Refresh support.
|
|
116
|
+
health_check: Enable health check for dev server startup.
|
|
117
|
+
detect_nodeenv: Detect and use nodeenv in virtualenv (opt-in).
|
|
118
|
+
set_environment: Set Vite environment variables from config.
|
|
119
|
+
set_static_folders: Automatically configure static file serving.
|
|
120
|
+
csp_nonce: Content Security Policy nonce for inline scripts.
|
|
121
|
+
spa_handler: Auto-register catch-all SPA route when mode="spa".
|
|
122
|
+
http2: Enable HTTP/2 for proxy HTTP requests (better multiplexing).
|
|
123
|
+
WebSocket traffic (HMR) uses a separate connection and is unaffected.
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
dev_mode: bool = field(default_factory=lambda: os.getenv("VITE_DEV_MODE", "False") in TRUE_VALUES)
|
|
127
|
+
proxy_mode: "Literal['vite', 'direct', 'proxy'] | None" = field(default_factory=resolve_proxy_mode)
|
|
128
|
+
external_dev_server: "ExternalDevServer | str | None" = None
|
|
129
|
+
host: str = field(default_factory=lambda: os.getenv("VITE_HOST", "127.0.0.1"))
|
|
130
|
+
port: int = field(default_factory=lambda: int(os.getenv("VITE_PORT", "5173")))
|
|
131
|
+
protocol: Literal["http", "https"] = "http"
|
|
132
|
+
executor: "Literal['node', 'bun', 'deno', 'yarn', 'pnpm'] | None" = None
|
|
133
|
+
run_command: "list[str] | None" = None
|
|
134
|
+
build_command: "list[str] | None" = None
|
|
135
|
+
build_watch_command: "list[str] | None" = None
|
|
136
|
+
serve_command: "list[str] | None" = None
|
|
137
|
+
install_command: "list[str] | None" = None
|
|
138
|
+
is_react: bool = False
|
|
139
|
+
health_check: bool = field(default_factory=lambda: os.getenv("VITE_HEALTH_CHECK", "False") in TRUE_VALUES)
|
|
140
|
+
detect_nodeenv: bool = False
|
|
141
|
+
set_environment: bool = True
|
|
142
|
+
set_static_folders: bool = True
|
|
143
|
+
csp_nonce: "str | None" = None
|
|
144
|
+
spa_handler: bool = True
|
|
145
|
+
http2: bool = True
|
|
146
|
+
start_dev_server: bool = True
|
|
147
|
+
trusted_proxies: "list[str] | str | None" = field(default_factory=resolve_trusted_proxies)
|
|
148
|
+
"""Trusted proxy hosts for X-Forwarded-* header processing.
|
|
149
|
+
|
|
150
|
+
When set, the ProxyHeadersMiddleware will read and apply X-Forwarded-Proto,
|
|
151
|
+
X-Forwarded-For, and X-Forwarded-Host headers only from requests originating
|
|
152
|
+
from these hosts.
|
|
153
|
+
|
|
154
|
+
Accepted values:
|
|
155
|
+
- None (default): Disabled - do not trust any proxy headers
|
|
156
|
+
- "*": Trust all proxies (use in controlled environments like Docker/Railway)
|
|
157
|
+
- List of IP addresses: ["127.0.0.1", "10.0.0.0/8"]
|
|
158
|
+
- Comma-separated string: "127.0.0.1, 10.0.0.0/8"
|
|
159
|
+
|
|
160
|
+
Supports:
|
|
161
|
+
- IPv4 addresses: "192.168.1.1"
|
|
162
|
+
- IPv6 addresses: "::1"
|
|
163
|
+
- CIDR notation: "10.0.0.0/8", "fd00::/8"
|
|
164
|
+
- Unix socket literals (for advanced setups)
|
|
165
|
+
|
|
166
|
+
Security Note:
|
|
167
|
+
Only enable this when your application is behind a trusted reverse proxy.
|
|
168
|
+
Never enable in environments where clients can directly connect to the app.
|
|
169
|
+
Using "*" should only be done in controlled environments where direct client
|
|
170
|
+
connections are blocked by network configuration.
|
|
171
|
+
|
|
172
|
+
Environment Variable: LITESTAR_TRUSTED_PROXIES
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
def __post_init__(self) -> None:
|
|
176
|
+
"""Normalize runtime settings and apply derived defaults."""
|
|
177
|
+
if isinstance(self.external_dev_server, str):
|
|
178
|
+
self.external_dev_server = ExternalDevServer(target=self.external_dev_server)
|
|
179
|
+
|
|
180
|
+
if self.external_dev_server is not None and self.proxy_mode in {None, "vite"}:
|
|
181
|
+
self.proxy_mode = "proxy"
|
|
182
|
+
|
|
183
|
+
if self.executor is None:
|
|
184
|
+
self.executor = "node"
|
|
185
|
+
|
|
186
|
+
executor_commands = {
|
|
187
|
+
"node": {
|
|
188
|
+
"run": ["npm", "run", "dev"],
|
|
189
|
+
"build": ["npm", "run", "build"],
|
|
190
|
+
"build_watch": ["npm", "run", "watch"],
|
|
191
|
+
"serve": ["npm", "run", "serve"],
|
|
192
|
+
"install": ["npm", "install"],
|
|
193
|
+
},
|
|
194
|
+
"bun": {
|
|
195
|
+
"run": ["bun", "run", "dev"],
|
|
196
|
+
"build": ["bun", "run", "build"],
|
|
197
|
+
"build_watch": ["bun", "run", "watch"],
|
|
198
|
+
"serve": ["bun", "run", "serve"],
|
|
199
|
+
"install": ["bun", "install"],
|
|
200
|
+
},
|
|
201
|
+
"deno": {
|
|
202
|
+
"run": ["deno", "task", "dev"],
|
|
203
|
+
"build": ["deno", "task", "build"],
|
|
204
|
+
"build_watch": ["deno", "task", "watch"],
|
|
205
|
+
"serve": ["deno", "task", "serve"],
|
|
206
|
+
"install": ["deno", "install"],
|
|
207
|
+
},
|
|
208
|
+
"yarn": {
|
|
209
|
+
"run": ["yarn", "dev"],
|
|
210
|
+
"build": ["yarn", "build"],
|
|
211
|
+
"build_watch": ["yarn", "watch"],
|
|
212
|
+
"serve": ["yarn", "serve"],
|
|
213
|
+
"install": ["yarn", "install"],
|
|
214
|
+
},
|
|
215
|
+
"pnpm": {
|
|
216
|
+
"run": ["pnpm", "dev"],
|
|
217
|
+
"build": ["pnpm", "build"],
|
|
218
|
+
"build_watch": ["pnpm", "watch"],
|
|
219
|
+
"serve": ["pnpm", "serve"],
|
|
220
|
+
"install": ["pnpm", "install"],
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if self.executor in executor_commands:
|
|
225
|
+
cmds = executor_commands[self.executor]
|
|
226
|
+
if self.run_command is None:
|
|
227
|
+
self.run_command = cmds["run"]
|
|
228
|
+
if self.build_command is None:
|
|
229
|
+
self.build_command = cmds["build"]
|
|
230
|
+
if self.build_watch_command is None:
|
|
231
|
+
self.build_watch_command = cmds["build_watch"]
|
|
232
|
+
if self.serve_command is None:
|
|
233
|
+
self.serve_command = cmds["serve"]
|
|
234
|
+
if self.install_command is None:
|
|
235
|
+
self.install_command = cmds["install"]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""SPA and logging configuration."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
__all__ = ("LoggingConfig", "SPAConfig")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class SPAConfig:
|
|
12
|
+
"""Configuration for SPA HTML transformations.
|
|
13
|
+
|
|
14
|
+
This configuration controls how the SPA HTML is transformed before serving,
|
|
15
|
+
including CSRF token injection.
|
|
16
|
+
|
|
17
|
+
Note:
|
|
18
|
+
Route metadata is now generated as TypeScript (routes.ts) at build time
|
|
19
|
+
instead of runtime injection. Use TypeGenConfig.generate_routes to enable.
|
|
20
|
+
|
|
21
|
+
For Inertia-specific settings like ``use_script_element``, see ``InertiaConfig``.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
inject_csrf: Whether to inject CSRF token into HTML (as window.__LITESTAR_CSRF__).
|
|
25
|
+
csrf_var_name: Global variable name for CSRF token (e.g., window.__LITESTAR_CSRF__).
|
|
26
|
+
app_selector: CSS selector for the app root element (used for data attributes).
|
|
27
|
+
cache_transformed_html: Cache transformed HTML in production; disabled when inject_csrf=True because CSRF tokens are per-request.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
inject_csrf: bool = True
|
|
31
|
+
csrf_var_name: str = "__LITESTAR_CSRF__"
|
|
32
|
+
app_selector: str = "#app"
|
|
33
|
+
cache_transformed_html: bool = True
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_default_log_level() -> "Literal['quiet', 'normal', 'verbose']":
|
|
37
|
+
"""Get default log level from environment variable.
|
|
38
|
+
|
|
39
|
+
Checks LITESTAR_VITE_LOG_LEVEL environment variable.
|
|
40
|
+
Falls back to "normal" if not set or invalid.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
The log level from environment or "normal" default.
|
|
44
|
+
"""
|
|
45
|
+
env_level = os.getenv("LITESTAR_VITE_LOG_LEVEL", "").lower()
|
|
46
|
+
match env_level:
|
|
47
|
+
case "quiet" | "normal" | "verbose":
|
|
48
|
+
return env_level
|
|
49
|
+
case _:
|
|
50
|
+
return "normal"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass
|
|
54
|
+
class LoggingConfig:
|
|
55
|
+
"""Logging configuration for console output.
|
|
56
|
+
|
|
57
|
+
Controls the verbosity and style of console output from both Python
|
|
58
|
+
and TypeScript (via .litestar.json bridge).
|
|
59
|
+
|
|
60
|
+
Attributes:
|
|
61
|
+
level: Logging verbosity level.
|
|
62
|
+
- "quiet": Minimal output (errors only)
|
|
63
|
+
- "normal": Standard operational messages (default)
|
|
64
|
+
- "verbose": Detailed debugging information
|
|
65
|
+
Can also be set via LITESTAR_VITE_LOG_LEVEL environment variable.
|
|
66
|
+
Precedence: explicit config > env var > default ("normal")
|
|
67
|
+
show_paths_absolute: Show absolute paths instead of relative paths.
|
|
68
|
+
Default False shows cleaner relative paths in output.
|
|
69
|
+
suppress_npm_output: Suppress npm/yarn/pnpm script echo lines.
|
|
70
|
+
When True, hides lines like "> dev" / "> vite" from output.
|
|
71
|
+
suppress_vite_banner: Suppress the Vite startup banner.
|
|
72
|
+
When True, only the LITESTAR banner is shown.
|
|
73
|
+
timestamps: Include timestamps in log messages.
|
|
74
|
+
|
|
75
|
+
Example:
|
|
76
|
+
Quiet mode for CI/CD::
|
|
77
|
+
|
|
78
|
+
ViteConfig(logging=LoggingConfig(level="quiet"))
|
|
79
|
+
|
|
80
|
+
Verbose debugging::
|
|
81
|
+
|
|
82
|
+
ViteConfig(logging=LoggingConfig(level="verbose", show_paths_absolute=True))
|
|
83
|
+
|
|
84
|
+
Environment variable::
|
|
85
|
+
|
|
86
|
+
export LITESTAR_VITE_LOG_LEVEL=quiet
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
level: "Literal['quiet', 'normal', 'verbose']" = field(default_factory=get_default_log_level)
|
|
90
|
+
show_paths_absolute: bool = False
|
|
91
|
+
suppress_npm_output: bool = False
|
|
92
|
+
suppress_vite_banner: bool = False
|
|
93
|
+
timestamps: bool = False
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Type generation configuration."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Literal, cast
|
|
6
|
+
|
|
7
|
+
__all__ = ("TypeGenConfig",)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class TypeGenConfig:
|
|
12
|
+
"""Type generation settings.
|
|
13
|
+
|
|
14
|
+
Presence of this config enables type generation. Use ``types=None`` or
|
|
15
|
+
``types=False`` in ViteConfig to disable.
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
output: Output directory for generated types.
|
|
19
|
+
openapi_path: Path to export OpenAPI schema.
|
|
20
|
+
routes_path: Path to export routes metadata (JSON format).
|
|
21
|
+
routes_ts_path: Path to export typed routes TypeScript file.
|
|
22
|
+
generate_zod: Generate Zod schemas from OpenAPI.
|
|
23
|
+
generate_sdk: Generate SDK client from OpenAPI.
|
|
24
|
+
generate_routes: Generate typed routes.ts file (Ziggy-style).
|
|
25
|
+
generate_page_props: Generate Inertia page props TypeScript file.
|
|
26
|
+
Auto-enabled when both types and inertia are configured.
|
|
27
|
+
page_props_path: Path to export page props metadata (JSON format).
|
|
28
|
+
global_route: Register route() function globally on window object.
|
|
29
|
+
When True, adds ``window.route = route`` to generated routes.ts,
|
|
30
|
+
providing global access without imports.
|
|
31
|
+
fallback_type: Fallback value type for untyped containers in generated Inertia props.
|
|
32
|
+
Controls whether untyped dict/list become `unknown` (default) or `any`.
|
|
33
|
+
type_import_paths: Map schema/type names to TypeScript import paths for props types
|
|
34
|
+
that are not present in OpenAPI (e.g., internal/excluded schemas).
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
output: Path = field(default_factory=lambda: Path("src/generated"))
|
|
38
|
+
openapi_path: "Path | None" = field(default=None)
|
|
39
|
+
routes_path: "Path | None" = field(default=None)
|
|
40
|
+
routes_ts_path: "Path | None" = field(default=None)
|
|
41
|
+
generate_zod: bool = False
|
|
42
|
+
generate_sdk: bool = True
|
|
43
|
+
generate_routes: bool = True
|
|
44
|
+
generate_page_props: bool = True
|
|
45
|
+
global_route: bool = False
|
|
46
|
+
"""Register route() function globally on window object.
|
|
47
|
+
|
|
48
|
+
When True, the generated routes.ts will include code that registers
|
|
49
|
+
the type-safe route() function on ``window.route``, similar to Laravel's
|
|
50
|
+
Ziggy library. This allows using route() without imports:
|
|
51
|
+
|
|
52
|
+
.. code-block:: typescript
|
|
53
|
+
|
|
54
|
+
// With global_route=True, no import needed:
|
|
55
|
+
window.route('user-profile', { userId: 123 })
|
|
56
|
+
|
|
57
|
+
// TypeScript users should add to global.d.ts:
|
|
58
|
+
// declare const route: typeof import('@/generated/routes').route
|
|
59
|
+
|
|
60
|
+
Default is False to encourage explicit imports for better tree-shaking.
|
|
61
|
+
"""
|
|
62
|
+
fallback_type: "Literal['unknown', 'any']" = "unknown"
|
|
63
|
+
type_import_paths: dict[str, str] = field(default_factory=lambda: cast("dict[str, str]", {}))
|
|
64
|
+
"""Map schema/type names to TypeScript import paths for Inertia props.
|
|
65
|
+
|
|
66
|
+
Use this for prop types that are not present in OpenAPI (e.g., internal schemas).
|
|
67
|
+
"""
|
|
68
|
+
page_props_path: "Path | None" = field(default=None)
|
|
69
|
+
"""Path to export page props metadata JSON.
|
|
70
|
+
|
|
71
|
+
The Vite plugin reads this file to generate page-props.ts.
|
|
72
|
+
Defaults to output / "inertia-pages.json".
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __post_init__(self) -> None:
|
|
76
|
+
"""Normalize path types and compute defaults based on output directory."""
|
|
77
|
+
if isinstance(self.output, str):
|
|
78
|
+
self.output = Path(self.output)
|
|
79
|
+
if self.openapi_path is None:
|
|
80
|
+
self.openapi_path = self.output / "openapi.json"
|
|
81
|
+
elif isinstance(self.openapi_path, str):
|
|
82
|
+
self.openapi_path = Path(self.openapi_path)
|
|
83
|
+
if self.routes_path is None:
|
|
84
|
+
self.routes_path = self.output / "routes.json"
|
|
85
|
+
elif isinstance(self.routes_path, str):
|
|
86
|
+
self.routes_path = Path(self.routes_path)
|
|
87
|
+
if self.routes_ts_path is None:
|
|
88
|
+
self.routes_ts_path = self.output / "routes.ts"
|
|
89
|
+
elif isinstance(self.routes_ts_path, str):
|
|
90
|
+
self.routes_ts_path = Path(self.routes_ts_path)
|
|
91
|
+
if self.page_props_path is None:
|
|
92
|
+
self.page_props_path = self.output / "inertia-pages.json"
|
|
93
|
+
elif isinstance(self.page_props_path, str):
|
|
94
|
+
self.page_props_path = Path(self.page_props_path)
|