litestar-vite 0.12.1__py3-none-any.whl → 0.13.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.
Potentially problematic release.
This version of litestar-vite might be problematic. Click here for more details.
- litestar_vite/__init__.py +8 -0
- litestar_vite/__metadata__.py +18 -0
- litestar_vite/cli.py +320 -0
- litestar_vite/commands.py +139 -0
- litestar_vite/config.py +109 -0
- litestar_vite/inertia/__init__.py +37 -0
- litestar_vite/inertia/_utils.py +63 -0
- litestar_vite/inertia/config.py +29 -0
- litestar_vite/inertia/exception_handler.py +117 -0
- litestar_vite/inertia/helpers.py +329 -0
- litestar_vite/inertia/middleware.py +51 -0
- litestar_vite/inertia/plugin.py +96 -0
- litestar_vite/inertia/request.py +116 -0
- litestar_vite/inertia/response.py +319 -0
- litestar_vite/inertia/routes.py +54 -0
- litestar_vite/inertia/types.py +39 -0
- litestar_vite/loader.py +284 -0
- litestar_vite/plugin.py +214 -0
- litestar_vite/py.typed +0 -0
- litestar_vite/templates/__init__.py +0 -0
- litestar_vite/templates/index.html.j2 +16 -0
- litestar_vite/templates/main.ts.j2 +1 -0
- litestar_vite/templates/package.json.j2 +11 -0
- litestar_vite/templates/styles.css.j2 +0 -0
- litestar_vite/templates/tsconfig.json.j2 +30 -0
- litestar_vite/templates/vite.config.ts.j2 +37 -0
- {litestar_vite-0.12.1.dist-info → litestar_vite-0.13.0.dist-info}/METADATA +1 -1
- litestar_vite-0.13.0.dist-info/RECORD +30 -0
- litestar_vite-0.12.1.dist-info/RECORD +0 -4
- {litestar_vite-0.12.1.dist-info → litestar_vite-0.13.0.dist-info}/WHEEL +0 -0
- {litestar_vite-0.12.1.dist-info → litestar_vite-0.13.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from litestar_vite import inertia
|
|
4
|
+
from litestar_vite.config import ViteConfig
|
|
5
|
+
from litestar_vite.loader import ViteAssetLoader
|
|
6
|
+
from litestar_vite.plugin import VitePlugin
|
|
7
|
+
|
|
8
|
+
__all__ = ("ViteAssetLoader", "ViteConfig", "VitePlugin", "inertia")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Metadata for the Project."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib.metadata import PackageNotFoundError, metadata, version
|
|
6
|
+
|
|
7
|
+
__all__ = ("__project__", "__version__")
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
__version__ = version("litestar_vite")
|
|
11
|
+
"""Version of the project."""
|
|
12
|
+
__project__ = metadata("litestar_vite")["Name"]
|
|
13
|
+
"""Name of the project."""
|
|
14
|
+
except PackageNotFoundError: # pragma: no cover
|
|
15
|
+
__version__ = "0.0.0"
|
|
16
|
+
__project__ = "Litestar Vite"
|
|
17
|
+
finally:
|
|
18
|
+
del version, PackageNotFoundError, metadata
|
litestar_vite/cli.py
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from click import Context, group, option
|
|
7
|
+
from click import Path as ClickPath
|
|
8
|
+
from litestar.cli._utils import (
|
|
9
|
+
LitestarEnv,
|
|
10
|
+
LitestarGroup,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from litestar import Litestar
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@group(cls=LitestarGroup, name="assets")
|
|
18
|
+
def vite_group() -> None:
|
|
19
|
+
"""Manage Vite Tasks."""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@vite_group.command(
|
|
23
|
+
name="init",
|
|
24
|
+
help="Initialize vite for your project.",
|
|
25
|
+
)
|
|
26
|
+
@option(
|
|
27
|
+
"--root-path",
|
|
28
|
+
type=ClickPath(dir_okay=True, file_okay=False, path_type=Path),
|
|
29
|
+
help="The path for the initial the Vite application. This is the equivalent to the top-level folder in a normal Vue or React application..",
|
|
30
|
+
default=None,
|
|
31
|
+
required=False,
|
|
32
|
+
)
|
|
33
|
+
@option(
|
|
34
|
+
"--bundle-path",
|
|
35
|
+
type=ClickPath(dir_okay=True, file_okay=False, path_type=Path),
|
|
36
|
+
help="The path for the built Vite assets. This is the where the output of `npm run build` will write files.",
|
|
37
|
+
default=None,
|
|
38
|
+
required=False,
|
|
39
|
+
)
|
|
40
|
+
@option(
|
|
41
|
+
"--resource-path",
|
|
42
|
+
type=ClickPath(dir_okay=True, file_okay=False, path_type=Path),
|
|
43
|
+
help="The path to your Javascript/Typescript source and associated assets. If this were a standalone Vue or React app, this would point to your `src/` folder.",
|
|
44
|
+
default=None,
|
|
45
|
+
required=False,
|
|
46
|
+
)
|
|
47
|
+
@option(
|
|
48
|
+
"--public-path",
|
|
49
|
+
type=ClickPath(dir_okay=True, file_okay=False, path_type=Path),
|
|
50
|
+
help="The optional path to your public/static JS assets. If this were a standalone Vue or React app, this would point to your `public/` folder.",
|
|
51
|
+
default=None,
|
|
52
|
+
required=False,
|
|
53
|
+
)
|
|
54
|
+
@option("--asset-url", type=str, help="Base url to serve assets from.", default=None, required=False)
|
|
55
|
+
@option(
|
|
56
|
+
"--vite-port",
|
|
57
|
+
type=int,
|
|
58
|
+
help="The port to run the vite server against.",
|
|
59
|
+
default=None,
|
|
60
|
+
is_flag=True,
|
|
61
|
+
required=False,
|
|
62
|
+
)
|
|
63
|
+
@option(
|
|
64
|
+
"--enable-ssr",
|
|
65
|
+
type=bool,
|
|
66
|
+
help="Enable SSR Support.",
|
|
67
|
+
required=False,
|
|
68
|
+
show_default=False,
|
|
69
|
+
is_flag=True,
|
|
70
|
+
)
|
|
71
|
+
@option("--overwrite", type=bool, help="Overwrite any files in place.", default=False, is_flag=True)
|
|
72
|
+
@option("--verbose", type=bool, help="Enable verbose output.", default=False, is_flag=True)
|
|
73
|
+
@option(
|
|
74
|
+
"--no-prompt",
|
|
75
|
+
help="Do not prompt for confirmation and use all defaults for initializing the project.",
|
|
76
|
+
type=bool,
|
|
77
|
+
default=False,
|
|
78
|
+
required=False,
|
|
79
|
+
show_default=True,
|
|
80
|
+
is_flag=True,
|
|
81
|
+
)
|
|
82
|
+
@option(
|
|
83
|
+
"--no-install",
|
|
84
|
+
help="Do not execute the installation commands after generating templates.",
|
|
85
|
+
type=bool,
|
|
86
|
+
default=False,
|
|
87
|
+
required=False,
|
|
88
|
+
show_default=True,
|
|
89
|
+
is_flag=True,
|
|
90
|
+
)
|
|
91
|
+
def vite_init(
|
|
92
|
+
ctx: Context,
|
|
93
|
+
vite_port: int | None,
|
|
94
|
+
enable_ssr: bool | None,
|
|
95
|
+
asset_url: str | None,
|
|
96
|
+
root_path: Path | None,
|
|
97
|
+
bundle_path: Path | None,
|
|
98
|
+
resource_path: Path | None,
|
|
99
|
+
public_path: Path | None,
|
|
100
|
+
overwrite: bool,
|
|
101
|
+
verbose: bool,
|
|
102
|
+
no_prompt: bool,
|
|
103
|
+
no_install: bool,
|
|
104
|
+
) -> None: # sourcery skip: low-code-quality
|
|
105
|
+
"""Run vite build."""
|
|
106
|
+
import os
|
|
107
|
+
import sys
|
|
108
|
+
from importlib.util import find_spec
|
|
109
|
+
from pathlib import Path
|
|
110
|
+
|
|
111
|
+
from litestar.cli._utils import (
|
|
112
|
+
console,
|
|
113
|
+
)
|
|
114
|
+
from rich.prompt import Confirm
|
|
115
|
+
|
|
116
|
+
from litestar_vite import VitePlugin
|
|
117
|
+
from litestar_vite.commands import execute_command, init_vite
|
|
118
|
+
|
|
119
|
+
if callable(ctx.obj):
|
|
120
|
+
ctx.obj = ctx.obj()
|
|
121
|
+
elif verbose:
|
|
122
|
+
ctx.obj.app.debug = True
|
|
123
|
+
env: LitestarEnv = ctx.obj
|
|
124
|
+
plugin = env.app.plugins.get(VitePlugin)
|
|
125
|
+
config = plugin._config # pyright: ignore[reportPrivateUsage]
|
|
126
|
+
|
|
127
|
+
console.rule("[yellow]Initializing Vite[/]", align="left")
|
|
128
|
+
root_path = Path(root_path or config.root_dir or Path.cwd())
|
|
129
|
+
resource_path = Path(resource_path or config.resource_dir)
|
|
130
|
+
public_path = Path(public_path or config.public_dir)
|
|
131
|
+
bundle_path = Path(bundle_path or config.bundle_dir)
|
|
132
|
+
enable_ssr = enable_ssr or config.ssr_enabled
|
|
133
|
+
asset_url = asset_url or config.asset_url
|
|
134
|
+
vite_port = vite_port or config.port
|
|
135
|
+
hot_file = Path(bundle_path / config.hot_file)
|
|
136
|
+
|
|
137
|
+
if any(output_path.exists() for output_path in (bundle_path, resource_path)) and not any(
|
|
138
|
+
[overwrite, no_prompt],
|
|
139
|
+
):
|
|
140
|
+
confirm_overwrite = Confirm.ask(
|
|
141
|
+
"Files were found in the paths specified. Are you sure you wish to overwrite the contents?",
|
|
142
|
+
)
|
|
143
|
+
if not confirm_overwrite:
|
|
144
|
+
console.print("Skipping Vite initialization")
|
|
145
|
+
sys.exit(2)
|
|
146
|
+
|
|
147
|
+
enable_ssr = (
|
|
148
|
+
True
|
|
149
|
+
if enable_ssr
|
|
150
|
+
else False
|
|
151
|
+
if no_prompt
|
|
152
|
+
else Confirm.ask(
|
|
153
|
+
"Do you intend to use Litestar with any SSR framework?",
|
|
154
|
+
)
|
|
155
|
+
)
|
|
156
|
+
init_vite(
|
|
157
|
+
app=env.app,
|
|
158
|
+
root_path=root_path,
|
|
159
|
+
enable_ssr=enable_ssr,
|
|
160
|
+
vite_port=vite_port,
|
|
161
|
+
asset_url=asset_url,
|
|
162
|
+
resource_path=resource_path,
|
|
163
|
+
public_path=public_path,
|
|
164
|
+
bundle_path=bundle_path,
|
|
165
|
+
hot_file=hot_file,
|
|
166
|
+
litestar_port=env.port or 8000,
|
|
167
|
+
)
|
|
168
|
+
if not no_install:
|
|
169
|
+
if find_spec("nodeenv") is not None and plugin.config.detect_nodeenv:
|
|
170
|
+
"""Detect nodeenv installed in the current python env before using a global version"""
|
|
171
|
+
nodeenv_command = (
|
|
172
|
+
str(Path(Path(sys.executable) / "nodeenv"))
|
|
173
|
+
if Path(Path(sys.executable) / "nodeenv").exists()
|
|
174
|
+
else "nodeenv"
|
|
175
|
+
)
|
|
176
|
+
install_dir = os.environ.get("VIRTUAL_ENV", sys.prefix)
|
|
177
|
+
console.rule("[yellow]Starting Nodeenv installation process[/]", align="left")
|
|
178
|
+
console.print(f"Installing Node environment into {install_dir}")
|
|
179
|
+
execute_command(command_to_run=[nodeenv_command, install_dir, "--force", "--quiet"], cwd=root_path)
|
|
180
|
+
|
|
181
|
+
console.rule("[yellow]Starting package installation process[/]", align="left")
|
|
182
|
+
|
|
183
|
+
execute_command(command_to_run=plugin.config.install_command, cwd=root_path)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@vite_group.command(
|
|
187
|
+
name="install",
|
|
188
|
+
help="Install frontend packages.",
|
|
189
|
+
)
|
|
190
|
+
@option("--verbose", type=bool, help="Enable verbose output.", default=False, is_flag=True)
|
|
191
|
+
def vite_install(app: Litestar, verbose: bool) -> None:
|
|
192
|
+
"""Run vite build."""
|
|
193
|
+
import os
|
|
194
|
+
import sys
|
|
195
|
+
from importlib.util import find_spec
|
|
196
|
+
from pathlib import Path
|
|
197
|
+
|
|
198
|
+
from litestar.cli._utils import console
|
|
199
|
+
|
|
200
|
+
from litestar_vite.commands import execute_command
|
|
201
|
+
from litestar_vite.plugin import VitePlugin
|
|
202
|
+
|
|
203
|
+
if verbose:
|
|
204
|
+
app.debug = True
|
|
205
|
+
plugin = app.plugins.get(VitePlugin)
|
|
206
|
+
|
|
207
|
+
if find_spec("nodeenv") is not None and plugin.config.detect_nodeenv:
|
|
208
|
+
"""Detect nodeenv installed in the current python env before using a global version"""
|
|
209
|
+
nodeenv_command = (
|
|
210
|
+
str(Path(Path(sys.executable) / "nodeenv"))
|
|
211
|
+
if Path(Path(sys.executable) / "nodeenv").exists()
|
|
212
|
+
else "nodeenv"
|
|
213
|
+
)
|
|
214
|
+
install_dir = os.environ.get("VIRTUAL_ENV", sys.prefix)
|
|
215
|
+
console.rule("[yellow]Starting Nodeenv installation process[/]", align="left")
|
|
216
|
+
console.print("Installing Node environment to %s:", install_dir)
|
|
217
|
+
execute_command(command_to_run=[nodeenv_command, install_dir, "--force", "--quiet"], cwd=plugin.config.root_dir)
|
|
218
|
+
|
|
219
|
+
console.rule("[yellow]Starting package installation process[/]", align="left")
|
|
220
|
+
|
|
221
|
+
execute_command(command_to_run=plugin.config.install_command, cwd=plugin.config.root_dir)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@vite_group.command(
|
|
225
|
+
name="build",
|
|
226
|
+
help="Building frontend assets with Vite.",
|
|
227
|
+
)
|
|
228
|
+
@option("--verbose", type=bool, help="Enable verbose output.", default=False, is_flag=True)
|
|
229
|
+
def vite_build(app: Litestar, verbose: bool) -> None:
|
|
230
|
+
"""Run vite build."""
|
|
231
|
+
from litestar.cli._utils import (
|
|
232
|
+
console,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
from litestar_vite.commands import execute_command
|
|
236
|
+
from litestar_vite.plugin import VitePlugin, set_environment
|
|
237
|
+
|
|
238
|
+
if verbose:
|
|
239
|
+
app.debug = True
|
|
240
|
+
console.rule("[yellow]Starting Vite build process[/]", align="left")
|
|
241
|
+
plugin = app.plugins.get(VitePlugin)
|
|
242
|
+
if plugin.config.set_environment:
|
|
243
|
+
set_environment(config=plugin.config)
|
|
244
|
+
p = execute_command(command_to_run=plugin.config.build_command, cwd=plugin.config.root_dir)
|
|
245
|
+
if p.returncode == 0:
|
|
246
|
+
console.print("[bold green] Assets built.[/]")
|
|
247
|
+
else:
|
|
248
|
+
console.print("[bold red] There was an error building the assets.[/]")
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@vite_group.command(
|
|
252
|
+
name="serve",
|
|
253
|
+
help="Serving frontend assets with Vite.",
|
|
254
|
+
)
|
|
255
|
+
@option("--verbose", type=bool, help="Enable verbose output.", default=False, is_flag=True)
|
|
256
|
+
def vite_serve(app: Litestar, verbose: bool) -> None:
|
|
257
|
+
"""Run vite serve."""
|
|
258
|
+
from litestar.cli._utils import (
|
|
259
|
+
console,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
from litestar_vite.commands import execute_command
|
|
263
|
+
from litestar_vite.plugin import VitePlugin, set_environment
|
|
264
|
+
|
|
265
|
+
if verbose:
|
|
266
|
+
app.debug = True
|
|
267
|
+
|
|
268
|
+
plugin = app.plugins.get(VitePlugin)
|
|
269
|
+
if plugin.config.set_environment:
|
|
270
|
+
set_environment(config=plugin.config)
|
|
271
|
+
if plugin.config.hot_reload:
|
|
272
|
+
console.rule("[yellow]Starting Vite process with HMR Enabled[/]", align="left")
|
|
273
|
+
else:
|
|
274
|
+
console.rule("[yellow]Starting Vite watch and build process[/]", align="left")
|
|
275
|
+
command_to_run = plugin.config.run_command if plugin.config.hot_reload else plugin.config.build_watch_command
|
|
276
|
+
execute_command(command_to_run=command_to_run, cwd=plugin.config.root_dir)
|
|
277
|
+
console.print("[yellow]Vite process stopped.[/]")
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@vite_group.command(
|
|
281
|
+
name="generate-routes",
|
|
282
|
+
help="Generate a JSON file with the route configuration",
|
|
283
|
+
)
|
|
284
|
+
@option(
|
|
285
|
+
"--output",
|
|
286
|
+
help="output file path",
|
|
287
|
+
type=ClickPath(dir_okay=False, path_type=Path),
|
|
288
|
+
default=Path("routes.json"),
|
|
289
|
+
show_default=True,
|
|
290
|
+
)
|
|
291
|
+
@option("--verbose", type=bool, help="Enable verbose output.", default=False, is_flag=True)
|
|
292
|
+
def generate_js_routes(app: Litestar, output: Path, verbose: bool) -> None:
|
|
293
|
+
"""Run vite serve."""
|
|
294
|
+
import msgspec
|
|
295
|
+
from litestar.cli._utils import (
|
|
296
|
+
LitestarCLIException,
|
|
297
|
+
console,
|
|
298
|
+
)
|
|
299
|
+
from litestar.serialization import encode_json, get_serializer
|
|
300
|
+
|
|
301
|
+
from litestar_vite.plugin import VitePlugin, set_environment
|
|
302
|
+
|
|
303
|
+
if verbose:
|
|
304
|
+
app.debug = True
|
|
305
|
+
serializer = get_serializer(app.type_encoders)
|
|
306
|
+
plugin = app.plugins.get(VitePlugin)
|
|
307
|
+
if plugin.config.set_environment:
|
|
308
|
+
set_environment(config=plugin.config)
|
|
309
|
+
content = msgspec.json.format(
|
|
310
|
+
encode_json(app.openapi_schema.to_schema(), serializer=serializer),
|
|
311
|
+
indent=4,
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
try:
|
|
315
|
+
output.write_bytes(content)
|
|
316
|
+
except OSError as e: # pragma: no cover
|
|
317
|
+
msg = f"failed to write schema to path {output}"
|
|
318
|
+
raise LitestarCLIException(msg) from e
|
|
319
|
+
|
|
320
|
+
console.print("[yellow]Vite process stopped.[/]")
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import platform
|
|
4
|
+
import subprocess
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import TYPE_CHECKING, Any, MutableMapping
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from jinja2 import Environment, Template
|
|
10
|
+
from litestar import Litestar
|
|
11
|
+
|
|
12
|
+
VITE_INIT_TEMPLATES: set[str] = {"package.json.j2", "tsconfig.json.j2", "vite.config.ts.j2"}
|
|
13
|
+
DEFAULT_RESOURCES: set[str] = {"styles.css.j2", "main.ts.j2"}
|
|
14
|
+
DEFAULT_DEV_DEPENDENCIES: dict[str, str] = {
|
|
15
|
+
"typescript": "^5.7.2",
|
|
16
|
+
"vite": "^6.0.6",
|
|
17
|
+
"litestar-vite-plugin": "^0.13.0",
|
|
18
|
+
"@types/node": "^22.10.2",
|
|
19
|
+
}
|
|
20
|
+
DEFAULT_DEPENDENCIES: dict[str, str] = {"axios": "^1.7.9"}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def to_json(value: Any) -> str:
|
|
24
|
+
"""Serialize JSON field values.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
value: Any json serializable value.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
JSON string.
|
|
31
|
+
"""
|
|
32
|
+
from litestar.serialization import encode_json
|
|
33
|
+
|
|
34
|
+
return encode_json(value).decode("utf-8")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def init_vite(
|
|
38
|
+
app: Litestar,
|
|
39
|
+
root_path: Path,
|
|
40
|
+
resource_path: Path,
|
|
41
|
+
asset_url: str,
|
|
42
|
+
public_path: Path,
|
|
43
|
+
bundle_path: Path,
|
|
44
|
+
enable_ssr: bool,
|
|
45
|
+
vite_port: int,
|
|
46
|
+
hot_file: Path,
|
|
47
|
+
litestar_port: int,
|
|
48
|
+
) -> None:
|
|
49
|
+
"""Initialize a new Vite project.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
app: The Litestar application instance.
|
|
53
|
+
root_path: Root directory for the Vite project.
|
|
54
|
+
resource_path: Directory containing source files.
|
|
55
|
+
asset_url: Base URL for serving assets.
|
|
56
|
+
public_path: Directory for static files.
|
|
57
|
+
bundle_path: Output directory for built files.
|
|
58
|
+
enable_ssr: Enable server-side rendering.
|
|
59
|
+
vite_port: Port for Vite dev server.
|
|
60
|
+
hot_file: Path to hot reload manifest.
|
|
61
|
+
litestar_port: Port for Litestar server.
|
|
62
|
+
"""
|
|
63
|
+
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
|
64
|
+
from litestar.cli._utils import console
|
|
65
|
+
from litestar.utils import module_loader
|
|
66
|
+
|
|
67
|
+
template_path = module_loader.module_to_os_path("litestar_vite.templates")
|
|
68
|
+
vite_template_env = Environment(
|
|
69
|
+
loader=FileSystemLoader([template_path]),
|
|
70
|
+
autoescape=select_autoescape(),
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
enabled_templates: set[str] = VITE_INIT_TEMPLATES
|
|
74
|
+
enabled_resources: set[str] = DEFAULT_RESOURCES
|
|
75
|
+
dependencies: dict[str, str] = DEFAULT_DEPENDENCIES
|
|
76
|
+
dev_dependencies: dict[str, str] = DEFAULT_DEV_DEPENDENCIES
|
|
77
|
+
templates: dict[str, Template] = {
|
|
78
|
+
template_name: get_template(environment=vite_template_env, name=template_name)
|
|
79
|
+
for template_name in enabled_templates
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# Prepare root_path
|
|
83
|
+
root_path.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
for template_name, template in templates.items():
|
|
85
|
+
target_file_name = template_name[:-3] if template_name.endswith(".j2") else template_name
|
|
86
|
+
target_file_path = root_path / target_file_name
|
|
87
|
+
with target_file_path.open(mode="w") as file:
|
|
88
|
+
console.print(f" * Writing {target_file_name} to {target_file_path!s}")
|
|
89
|
+
|
|
90
|
+
file.write(
|
|
91
|
+
template.render(
|
|
92
|
+
entry_point=[
|
|
93
|
+
f"{resource_path!s}/{resource_name[:-3] if resource_name.endswith('.j2') else resource_name}"
|
|
94
|
+
for resource_name in enabled_resources
|
|
95
|
+
],
|
|
96
|
+
enable_ssr=enable_ssr,
|
|
97
|
+
asset_url=asset_url,
|
|
98
|
+
root_path=root_path,
|
|
99
|
+
resource_path=str(resource_path),
|
|
100
|
+
public_path=str(public_path),
|
|
101
|
+
bundle_path=str(bundle_path),
|
|
102
|
+
hot_file=str(hot_file),
|
|
103
|
+
vite_port=str(vite_port),
|
|
104
|
+
litestar_port=litestar_port,
|
|
105
|
+
dependencies=to_json(dependencies),
|
|
106
|
+
dev_dependencies=to_json(dev_dependencies),
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
(root_path / bundle_path).mkdir(parents=True, exist_ok=True)
|
|
111
|
+
(root_path / public_path).mkdir(parents=True, exist_ok=True)
|
|
112
|
+
(root_path / resource_path).mkdir(parents=True, exist_ok=True)
|
|
113
|
+
for resource_name in enabled_resources:
|
|
114
|
+
template = get_template(environment=vite_template_env, name=resource_name)
|
|
115
|
+
target_file_name = f"{resource_name[:-3] if resource_name.endswith('.j2') else resource_name}"
|
|
116
|
+
target_file_path = root_path / resource_path / target_file_name
|
|
117
|
+
with target_file_path.open(mode="w") as file:
|
|
118
|
+
console.print(
|
|
119
|
+
f" * Writing {resource_name[:-3] if resource_name.endswith('.j2') else resource_name} to {target_file_path!s}",
|
|
120
|
+
)
|
|
121
|
+
file.write(template.render())
|
|
122
|
+
console.print("[yellow]Vite initialization completed.[/]")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def get_template(
|
|
126
|
+
environment: Environment,
|
|
127
|
+
name: str | Template,
|
|
128
|
+
parent: str | None = None,
|
|
129
|
+
globals: MutableMapping[str, Any] | None = None, # noqa: A002
|
|
130
|
+
) -> Template:
|
|
131
|
+
return environment.get_template(name=name, parent=parent, globals=globals)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def execute_command(command_to_run: list[str], cwd: str | Path | None = None) -> subprocess.CompletedProcess[bytes]:
|
|
135
|
+
"""Run Vite in a subprocess."""
|
|
136
|
+
kwargs = {}
|
|
137
|
+
if cwd is not None:
|
|
138
|
+
kwargs["cwd"] = Path(cwd)
|
|
139
|
+
return subprocess.run(command_to_run, check=False, shell=platform.system() == "Windows", **kwargs) # type: ignore[call-overload]
|
litestar_vite/config.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
__all__ = ("ViteConfig",)
|
|
8
|
+
TRUE_VALUES = {"True", "true", "1", "yes", "Y", "T"}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class ViteConfig:
|
|
13
|
+
"""Configuration for ViteJS support.
|
|
14
|
+
|
|
15
|
+
To enable Vite integration, pass an instance of this class to the
|
|
16
|
+
:class:`Litestar <litestar.app.Litestar>` constructor using the
|
|
17
|
+
'plugins' key.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
bundle_dir: Path | str = field(default="public")
|
|
21
|
+
"""Location of the compiled assets from Vite.
|
|
22
|
+
|
|
23
|
+
The manifest file will also be found here.
|
|
24
|
+
"""
|
|
25
|
+
resource_dir: Path | str = field(default="resources")
|
|
26
|
+
"""The directory where all typescript/javascript source are written.
|
|
27
|
+
|
|
28
|
+
In a standalone Vue or React application, this would be equivalent to the ``./src`` directory.
|
|
29
|
+
"""
|
|
30
|
+
public_dir: Path | str = field(default="public")
|
|
31
|
+
"""The optional public directory Vite serves assets from.
|
|
32
|
+
|
|
33
|
+
In a standalone Vue or React application, this would be equivalent to the ``./public`` directory.
|
|
34
|
+
"""
|
|
35
|
+
manifest_name: str = "manifest.json"
|
|
36
|
+
"""Name of the manifest file."""
|
|
37
|
+
hot_file: str = "hot"
|
|
38
|
+
"""Name of the hot file.
|
|
39
|
+
|
|
40
|
+
This file contains a single line containing the host, protocol, and port the Vite server is running.
|
|
41
|
+
"""
|
|
42
|
+
hot_reload: bool = field(
|
|
43
|
+
default_factory=lambda: os.getenv("VITE_HOT_RELOAD", "True") in TRUE_VALUES,
|
|
44
|
+
)
|
|
45
|
+
"""Enable HMR for Vite development server."""
|
|
46
|
+
ssr_enabled: bool = False
|
|
47
|
+
"""Enable SSR."""
|
|
48
|
+
ssr_output_dir: Path | str | None = None
|
|
49
|
+
"""SSR Output path"""
|
|
50
|
+
root_dir: Path | str | None = None
|
|
51
|
+
"""The is the base path to your application.
|
|
52
|
+
|
|
53
|
+
In a standalone Vue or React application, this would be equivalent to the top-level project folder containing the ``./src`` directory.
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
is_react: bool = False
|
|
57
|
+
"""Enable React components."""
|
|
58
|
+
asset_url: str = field(default_factory=lambda: os.getenv("ASSET_URL", "/static/"))
|
|
59
|
+
"""Base URL to generate for static asset references.
|
|
60
|
+
|
|
61
|
+
This URL will be prepended to anything generated from Vite.
|
|
62
|
+
"""
|
|
63
|
+
host: str = field(default_factory=lambda: os.getenv("VITE_HOST", "localhost"))
|
|
64
|
+
"""Default host to use for Vite server."""
|
|
65
|
+
protocol: str = "http"
|
|
66
|
+
"""Protocol to use for communication"""
|
|
67
|
+
port: int = field(default_factory=lambda: int(os.getenv("VITE_PORT", "5173")))
|
|
68
|
+
"""Default port to use for Vite server."""
|
|
69
|
+
run_command: list[str] = field(default_factory=lambda: ["npm", "run", "dev"])
|
|
70
|
+
"""Default command to use for running Vite."""
|
|
71
|
+
build_watch_command: list[str] = field(default_factory=lambda: ["npm", "run", "watch"])
|
|
72
|
+
"""Default command to use for dev building with Vite."""
|
|
73
|
+
build_command: list[str] = field(default_factory=lambda: ["npm", "run", "build"])
|
|
74
|
+
"""Default command to use for building with Vite."""
|
|
75
|
+
install_command: list[str] = field(default_factory=lambda: ["npm", "install"])
|
|
76
|
+
"""Default command to use for installing Vite."""
|
|
77
|
+
use_server_lifespan: bool = field(
|
|
78
|
+
default_factory=lambda: os.getenv("VITE_USE_SERVER_LIFESPAN", "False") in TRUE_VALUES,
|
|
79
|
+
)
|
|
80
|
+
"""Utilize the server lifespan hook to run Vite."""
|
|
81
|
+
dev_mode: bool = field(
|
|
82
|
+
default_factory=lambda: os.getenv("VITE_DEV_MODE", "False") in TRUE_VALUES,
|
|
83
|
+
)
|
|
84
|
+
"""When True, Vite will run with HMR or watch build"""
|
|
85
|
+
detect_nodeenv: bool = True
|
|
86
|
+
"""When True, The initializer will install and configure nodeenv if present"""
|
|
87
|
+
set_environment: bool = True
|
|
88
|
+
"""When True, configuration in this class will be set into environment variables.
|
|
89
|
+
|
|
90
|
+
This can be useful to ensure Vite always uses the configuration supplied to the plugin
|
|
91
|
+
"""
|
|
92
|
+
set_static_folders: bool = True
|
|
93
|
+
"""When True, Litestar will automatically serve assets at the `ASSET_URL` path.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
def __post_init__(self) -> None:
|
|
97
|
+
"""Ensure that directory is set if engine is a class."""
|
|
98
|
+
if self.root_dir is not None and isinstance(self.root_dir, str):
|
|
99
|
+
self.root_dir = Path(self.root_dir)
|
|
100
|
+
elif self.root_dir is None:
|
|
101
|
+
self.root_dir = Path()
|
|
102
|
+
if self.public_dir and isinstance(self.public_dir, str):
|
|
103
|
+
self.public_dir = Path(self.public_dir)
|
|
104
|
+
if isinstance(self.resource_dir, str):
|
|
105
|
+
self.resource_dir = Path(self.resource_dir)
|
|
106
|
+
if isinstance(self.bundle_dir, str):
|
|
107
|
+
self.bundle_dir = Path(self.bundle_dir)
|
|
108
|
+
if isinstance(self.ssr_output_dir, str):
|
|
109
|
+
self.ssr_output_dir = Path(self.ssr_output_dir)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from litestar_vite.inertia import helpers
|
|
2
|
+
from litestar_vite.inertia.config import InertiaConfig
|
|
3
|
+
from litestar_vite.inertia.exception_handler import create_inertia_exception_response, exception_to_http_response
|
|
4
|
+
from litestar_vite.inertia.helpers import error, get_shared_props, js_routes_script, lazy, share
|
|
5
|
+
from litestar_vite.inertia.middleware import InertiaMiddleware
|
|
6
|
+
from litestar_vite.inertia.plugin import InertiaPlugin
|
|
7
|
+
from litestar_vite.inertia.request import InertiaDetails, InertiaHeaders, InertiaRequest
|
|
8
|
+
from litestar_vite.inertia.response import (
|
|
9
|
+
InertiaBack,
|
|
10
|
+
InertiaExternalRedirect,
|
|
11
|
+
InertiaRedirect,
|
|
12
|
+
InertiaResponse,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from .routes import generate_js_routes
|
|
16
|
+
|
|
17
|
+
__all__ = (
|
|
18
|
+
"InertiaBack",
|
|
19
|
+
"InertiaConfig",
|
|
20
|
+
"InertiaDetails",
|
|
21
|
+
"InertiaExternalRedirect",
|
|
22
|
+
"InertiaHeaders",
|
|
23
|
+
"InertiaMiddleware",
|
|
24
|
+
"InertiaPlugin",
|
|
25
|
+
"InertiaRedirect",
|
|
26
|
+
"InertiaRequest",
|
|
27
|
+
"InertiaResponse",
|
|
28
|
+
"create_inertia_exception_response",
|
|
29
|
+
"error",
|
|
30
|
+
"exception_to_http_response",
|
|
31
|
+
"generate_js_routes",
|
|
32
|
+
"get_shared_props",
|
|
33
|
+
"helpers",
|
|
34
|
+
"js_routes_script",
|
|
35
|
+
"lazy",
|
|
36
|
+
"share",
|
|
37
|
+
)
|