litestar-vite 0.8.2__tar.gz → 0.9.0__tar.gz
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-0.8.2 → litestar_vite-0.9.0}/PKG-INFO +1 -1
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/pyproject.toml +2 -2
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/src/index.ts +41 -5
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/src/inertia-helpers/index.ts +2 -1
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/tests/index.test.ts +221 -144
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/commands.py +1 -1
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/.gitignore +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/LICENSE +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/README.md +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/LICENSE +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/Makefile +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/NOTICE +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/README.md +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/src/dev-server-index.html +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/tests/__data__/dummy.ts +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/tsconfig.inertia-helpers.json +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/tsconfig.json +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/vitest.config.ts +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/js/vitest.workspace.ts +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/__metadata__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/cli.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/config.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/_utils.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/config.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/exception_handler.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/middleware.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/plugin.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/request.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/response.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/routes.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/types.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/loader.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/plugin.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/py.typed +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/template_engine.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/index.html.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/main.ts.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/package.json.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/styles.css.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/tsconfig.json.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/vite.config.ts.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/conftest.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/templates/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/templates/index.html.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/app.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/public/.gitkeep +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/public/assets/main-l0sNRNKZ.js +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/public/assets/styles-l0sNRNKZ.js +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/public/manifest.json +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/resources/.gitkeep +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/resources/main.ts +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/resources/styles.css +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/templates/.gitkeep +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/templates/index.html +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_cli/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_cli/conftest.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_cli/test_init.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_commands.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_config.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/__init__.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/conftest.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/templates/index.html.j2 +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/test_inertia_request.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/test_inertia_response.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/test_routes.py +0 -0
- {litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_template_engine.py +0 -0
|
@@ -25,7 +25,7 @@ license = { text = "MIT" }
|
|
|
25
25
|
name = "litestar-vite"
|
|
26
26
|
readme = "README.md"
|
|
27
27
|
requires-python = ">=3.8"
|
|
28
|
-
version = "0.
|
|
28
|
+
version = "0.9.0"
|
|
29
29
|
|
|
30
30
|
[project.urls]
|
|
31
31
|
Changelog = "https://cofin.github.io/litestar-vite/latest/changelog"
|
|
@@ -85,7 +85,7 @@ test = [
|
|
|
85
85
|
allow_dirty = true
|
|
86
86
|
commit = true
|
|
87
87
|
commit_args = "--no-verify"
|
|
88
|
-
current_version = "0.
|
|
88
|
+
current_version = "0.9.0"
|
|
89
89
|
ignore_missing_files = false
|
|
90
90
|
ignore_missing_version = false
|
|
91
91
|
message = "chore(release): bump to v{new_version}"
|
|
@@ -63,6 +63,12 @@ interface PluginConfig {
|
|
|
63
63
|
* @default null
|
|
64
64
|
*/
|
|
65
65
|
detectTls?: string | boolean | null
|
|
66
|
+
/**
|
|
67
|
+
* Automatically detect the index.html file.
|
|
68
|
+
*
|
|
69
|
+
* @default true
|
|
70
|
+
*/
|
|
71
|
+
autoDetectIndex?: boolean
|
|
66
72
|
/**
|
|
67
73
|
* Transform the code while serving.
|
|
68
74
|
*/
|
|
@@ -82,7 +88,7 @@ type DevServerUrl = `${"http" | "https"}://${string}:${number}`
|
|
|
82
88
|
|
|
83
89
|
let exitHandlersBound = false
|
|
84
90
|
|
|
85
|
-
export const refreshPaths = ["
|
|
91
|
+
export const refreshPaths = ["src/**", "resources/**", "assets/**"].filter((path) => fs.existsSync(path.replace(/\*\*$/, "")))
|
|
86
92
|
|
|
87
93
|
/**
|
|
88
94
|
* Litestar plugin for Vite.
|
|
@@ -184,10 +190,30 @@ function resolveLitestarPlugin(pluginConfig: Required<PluginConfig>): LitestarPl
|
|
|
184
190
|
}
|
|
185
191
|
return undefined
|
|
186
192
|
},
|
|
187
|
-
configureServer(server) {
|
|
193
|
+
async configureServer(server) {
|
|
188
194
|
const envDir = resolvedConfig.envDir || process.cwd()
|
|
189
195
|
const appUrl = loadEnv(resolvedConfig.mode, envDir, "APP_URL").APP_URL ?? "undefined"
|
|
190
196
|
|
|
197
|
+
// Check if we should serve SPA directly
|
|
198
|
+
const shouldServeIndex = () => {
|
|
199
|
+
if (!pluginConfig.autoDetectIndex) return false
|
|
200
|
+
|
|
201
|
+
// Check various common locations for index.html
|
|
202
|
+
const possiblePaths = [
|
|
203
|
+
path.join(server.config.root, "index.html"),
|
|
204
|
+
path.join(server.config.root, pluginConfig.resourceDirectory, "index.html"),
|
|
205
|
+
path.join(server.config.root, "public", "index.html"),
|
|
206
|
+
]
|
|
207
|
+
|
|
208
|
+
for (const indexPath of possiblePaths) {
|
|
209
|
+
try {
|
|
210
|
+
fs.accessSync(indexPath)
|
|
211
|
+
return true
|
|
212
|
+
} catch {}
|
|
213
|
+
}
|
|
214
|
+
return false
|
|
215
|
+
}
|
|
216
|
+
|
|
191
217
|
server.httpServer?.once("listening", () => {
|
|
192
218
|
const address = server.httpServer?.address()
|
|
193
219
|
|
|
@@ -197,14 +223,23 @@ function resolveLitestarPlugin(pluginConfig: Required<PluginConfig>): LitestarPl
|
|
|
197
223
|
fs.mkdirSync(path.dirname(pluginConfig.hotFile), { recursive: true })
|
|
198
224
|
fs.writeFileSync(pluginConfig.hotFile, viteDevServerUrl)
|
|
199
225
|
|
|
226
|
+
const hasIndex = shouldServeIndex()
|
|
227
|
+
|
|
200
228
|
setTimeout(() => {
|
|
201
229
|
server.config.logger.info(`\n ${colors.red(`${colors.bold("LITESTAR")} ${litestarVersion()}`)} ${colors.dim("plugin")} ${colors.bold(`v${pluginVersion()}`)}`)
|
|
202
230
|
server.config.logger.info("")
|
|
203
|
-
|
|
231
|
+
if (hasIndex) {
|
|
232
|
+
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("Serve Index")}: Serving application index with Vite`)
|
|
233
|
+
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("DEV URL")}: ${colors.cyan(viteDevServerUrl)}`)
|
|
234
|
+
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("APP_URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))}`)
|
|
235
|
+
} else {
|
|
236
|
+
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("Serve Index")}: Serving Litestar index with Vite`)
|
|
237
|
+
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("DEV URL")}: ${colors.cyan(viteDevServerUrl)}`)
|
|
238
|
+
server.config.logger.info(` ${colors.green("➜")} ${colors.bold("APP_URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))}`)
|
|
239
|
+
}
|
|
204
240
|
}, 100)
|
|
205
241
|
}
|
|
206
242
|
})
|
|
207
|
-
|
|
208
243
|
if (!exitHandlersBound) {
|
|
209
244
|
const clean = () => {
|
|
210
245
|
if (fs.existsSync(pluginConfig.hotFile)) {
|
|
@@ -222,7 +257,7 @@ function resolveLitestarPlugin(pluginConfig: Required<PluginConfig>): LitestarPl
|
|
|
222
257
|
|
|
223
258
|
return () =>
|
|
224
259
|
server.middlewares.use((req, res, next) => {
|
|
225
|
-
if (req.url === "/index.html") {
|
|
260
|
+
if (!shouldServeIndex() && req.url === "/index.html") {
|
|
226
261
|
res.statusCode = 404
|
|
227
262
|
|
|
228
263
|
res.end(
|
|
@@ -325,6 +360,7 @@ function resolvePluginConfig(config: string | string[] | PluginConfig): Required
|
|
|
325
360
|
refresh: resolvedConfig.refresh ?? false,
|
|
326
361
|
hotFile: resolvedConfig.hotFile ?? path.join(resolvedConfig.bundleDirectory ?? "public", "hot"),
|
|
327
362
|
detectTls: resolvedConfig.detectTls ?? false,
|
|
363
|
+
autoDetectIndex: resolvedConfig.autoDetectIndex ?? true,
|
|
328
364
|
transformOnServe: resolvedConfig.transformOnServe ?? ((code) => code),
|
|
329
365
|
}
|
|
330
366
|
}
|
|
@@ -125,8 +125,9 @@ export function isRoute(url: string, routeName: string): boolean {
|
|
|
125
125
|
const regexPattern = routePattern.replace(/\//g, "\\/").replace(/\{([^}]+):([^}]+)\}/g, (match, paramName, paramType) => {
|
|
126
126
|
switch (paramType) {
|
|
127
127
|
case "str":
|
|
128
|
-
case "path":
|
|
129
128
|
return "([^/]+)"
|
|
129
|
+
case "path":
|
|
130
|
+
return "(.*)"
|
|
130
131
|
case "uuid":
|
|
131
132
|
return "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
132
133
|
default:
|
|
@@ -1,13 +1,93 @@
|
|
|
1
|
+
import fs from "node:fs"
|
|
2
|
+
import path from "node:path"
|
|
3
|
+
import { loadEnv } from "vite"
|
|
4
|
+
import { Plugin } from "vite"
|
|
1
5
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
|
2
6
|
import litestar from "../src"
|
|
3
|
-
import {
|
|
7
|
+
import { getRelativeUrlPath, isCurrentRoute, isRoute, resolvePageComponent, route, toRoute } from "../src/inertia-helpers"
|
|
8
|
+
|
|
9
|
+
// Mock the fs module
|
|
10
|
+
vi.mock("fs", async () => {
|
|
11
|
+
const actual = await vi.importActual<typeof import("fs")>("fs")
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
default: {
|
|
15
|
+
...actual,
|
|
16
|
+
existsSync: (path: string) => ["resources/", "assets/", "src/"].includes(path) || actual.existsSync(path),
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
// Mock process.env
|
|
21
|
+
const originalEnv = process.env
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
vi.resetModules()
|
|
24
|
+
process.env = { ...originalEnv }
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
process.env = originalEnv
|
|
29
|
+
vi.clearAllMocks()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// Mock routes for testing
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
globalThis.routes = {
|
|
35
|
+
home: "/",
|
|
36
|
+
about: "/about",
|
|
37
|
+
"users:assign-role": "/api/roles/{role_slug:str}/assign",
|
|
38
|
+
"users:revoke-role": "/api/roles/{role_slug:str}/revoke",
|
|
39
|
+
"tags:create": "/api/tags",
|
|
40
|
+
"tags:list": "/api/tags",
|
|
41
|
+
"tags:get": "/api/tags/{tag_id:uuid}",
|
|
42
|
+
"tags:update": "/api/tags/{tag_id:uuid}",
|
|
43
|
+
"tags:delete": "/api/tags/{tag_id:uuid}",
|
|
44
|
+
"teams:add-member": "/api/teams/{team_id:uuid}/members/add",
|
|
45
|
+
"teams:remove-member": "/api/teams/{team_id:uuid}/members/remove",
|
|
46
|
+
"users:create": "/api/users/create",
|
|
47
|
+
"users:list": "/api/users/list",
|
|
48
|
+
"users:update": "/api/users/update/{user_id:uuid}",
|
|
49
|
+
"users:delete": "/api/users/delete/{user_id:uuid}",
|
|
50
|
+
"users:get": "/api/users/get/{user_id:uuid}",
|
|
51
|
+
dashboard: "/dashboard",
|
|
52
|
+
favicon: "/favicon.ico",
|
|
53
|
+
landing: "/landing",
|
|
54
|
+
"login.check": "/login/check",
|
|
55
|
+
login: "/login",
|
|
56
|
+
logout: "/logout",
|
|
57
|
+
"github.complete": "/o/github/complete",
|
|
58
|
+
"google.complete": "/o/google/complete",
|
|
59
|
+
"privacy-policy": "/privacy-policy",
|
|
60
|
+
"account.remove": "/profile/remove",
|
|
61
|
+
"profile.show": "/profile",
|
|
62
|
+
"profile.update": "/profile/update",
|
|
63
|
+
"password.update": "/profile/password-update",
|
|
64
|
+
register: "/register",
|
|
65
|
+
"register.add": "/register/add",
|
|
66
|
+
"github.register": "/register/github",
|
|
67
|
+
"google.register": "/register/google",
|
|
68
|
+
"worker:index": "/saq/queues/{queue_id:str}/jobs/{job_id:str}",
|
|
69
|
+
"worker:queue-list": "/saq/api/queues/list",
|
|
70
|
+
"worker:queue-detail": "/saq/api/queues/{queue_id:str}",
|
|
71
|
+
"worker:job-detail": "/saq/api/queues/{queue_id:str}/jobs/{job_id:str}",
|
|
72
|
+
"worker:job-abort": "/saq/api/queues/{queue_id:str}/jobs/{job_id:str}/abort",
|
|
73
|
+
"worker:job-retry": "/saq/api/queues/{queue_id:str}/jobs/{job_id:str}/retry",
|
|
74
|
+
saq: "/saq/static/{file_path:path}",
|
|
75
|
+
vite: "/static/{file_path:path}",
|
|
76
|
+
"teams.add": "/teams/add",
|
|
77
|
+
"teams.list": "/teams/list",
|
|
78
|
+
"teams.show": "/teams/show/{team_id:uuid}",
|
|
79
|
+
"teams.remove": "/teams/remove/{team_id:uuid}",
|
|
80
|
+
"teams.edit": "/teams/edit/{team_id:uuid}",
|
|
81
|
+
"terms-of-service": "/terms-of-service",
|
|
82
|
+
}
|
|
83
|
+
})
|
|
4
84
|
|
|
5
85
|
describe("litestar-vite-plugin", () => {
|
|
6
86
|
const originalEnv = { ...process.env }
|
|
7
87
|
|
|
8
88
|
afterEach(() => {
|
|
9
89
|
process.env = { ...originalEnv }
|
|
10
|
-
vi.
|
|
90
|
+
vi.resetAllMocks()
|
|
11
91
|
})
|
|
12
92
|
|
|
13
93
|
it("handles missing configuration", () => {
|
|
@@ -43,20 +123,20 @@ describe("litestar-vite-plugin", () => {
|
|
|
43
123
|
it("accepts a full configuration", () => {
|
|
44
124
|
const plugin = litestar({
|
|
45
125
|
input: "resources/js/app.ts",
|
|
46
|
-
assetUrl: "other-
|
|
126
|
+
assetUrl: "other-static",
|
|
47
127
|
bundleDirectory: "other-build",
|
|
48
128
|
ssr: "resources/js/ssr.ts",
|
|
49
129
|
ssrOutputDirectory: "other-ssr-output",
|
|
50
130
|
})[0]
|
|
51
131
|
|
|
52
132
|
const config = plugin.config({}, { command: "build", mode: "production" })
|
|
53
|
-
expect(config.base).toBe("other-
|
|
133
|
+
expect(config.base).toBe("other-static/")
|
|
54
134
|
expect(config.build?.manifest).toBe("manifest.json")
|
|
55
135
|
expect(config.build?.outDir).toBe("other-build")
|
|
56
136
|
expect(config.build?.rollupOptions?.input).toBe("resources/js/app.ts")
|
|
57
137
|
|
|
58
138
|
const ssrConfig = plugin.config({ build: { ssr: true } }, { command: "build", mode: "production" })
|
|
59
|
-
expect(ssrConfig.base).toBe("other-
|
|
139
|
+
expect(ssrConfig.base).toBe("other-static/")
|
|
60
140
|
expect(ssrConfig.build?.manifest).toBe(false)
|
|
61
141
|
expect(ssrConfig.build?.outDir).toBe("other-ssr-output")
|
|
62
142
|
expect(ssrConfig.build?.rollupOptions?.input).toBe("resources/js/ssr.ts")
|
|
@@ -233,7 +313,7 @@ describe("litestar-vite-plugin", () => {
|
|
|
233
313
|
])
|
|
234
314
|
})
|
|
235
315
|
|
|
236
|
-
it("configures the Vite server when running remotely
|
|
316
|
+
it("configures the Vite server when running remotely", () => {
|
|
237
317
|
process.env.VITE_ALLOW_REMOTE = "1"
|
|
238
318
|
const plugin = litestar("resources/js/app.js")[0]
|
|
239
319
|
|
|
@@ -241,9 +321,11 @@ describe("litestar-vite-plugin", () => {
|
|
|
241
321
|
expect(config.server?.host).toBe("0.0.0.0")
|
|
242
322
|
expect(config.server?.port).toBe(5173)
|
|
243
323
|
expect(config.server?.strictPort).toBe(true)
|
|
324
|
+
|
|
325
|
+
process.env.VITE_ALLOW_REMOTE = undefined
|
|
244
326
|
})
|
|
245
327
|
|
|
246
|
-
it("allows the Vite port to be configured when
|
|
328
|
+
it("allows the Vite port to be configured when running remotely", () => {
|
|
247
329
|
process.env.VITE_ALLOW_REMOTE = "1"
|
|
248
330
|
process.env.VITE_PORT = "1234"
|
|
249
331
|
const plugin = litestar("resources/js/app.js")[0]
|
|
@@ -328,7 +410,7 @@ describe("litestar-vite-plugin", () => {
|
|
|
328
410
|
expect(plugins.length).toBe(1)
|
|
329
411
|
})
|
|
330
412
|
|
|
331
|
-
it("configures full reload with
|
|
413
|
+
it("configures full reload with python and template files when refresh is true", () => {
|
|
332
414
|
const plugins = litestar({
|
|
333
415
|
input: "resources/js/app.js",
|
|
334
416
|
refresh: true,
|
|
@@ -337,7 +419,7 @@ describe("litestar-vite-plugin", () => {
|
|
|
337
419
|
expect(plugins.length).toBe(2)
|
|
338
420
|
/** @ts-ignore */
|
|
339
421
|
expect(plugins[1].__litestar_plugin_config).toEqual({
|
|
340
|
-
paths: ["
|
|
422
|
+
paths: ["src/**", "resources/**", "assets/**"],
|
|
341
423
|
})
|
|
342
424
|
})
|
|
343
425
|
|
|
@@ -411,204 +493,199 @@ describe("litestar-vite-plugin", () => {
|
|
|
411
493
|
config: { delay: 123 },
|
|
412
494
|
})
|
|
413
495
|
})
|
|
414
|
-
})
|
|
415
496
|
|
|
497
|
+
it("handles TLS configuration", () => {
|
|
498
|
+
process.env.VITE_SERVER_KEY = "path/to/key"
|
|
499
|
+
process.env.VITE_SERVER_CERT = "path/to/cert"
|
|
500
|
+
process.env.APP_URL = "https://example.com"
|
|
501
|
+
|
|
502
|
+
const plugin = litestar("resources/js/app.js")[0]
|
|
503
|
+
|
|
504
|
+
expect(() => plugin.config({}, { command: "serve", mode: "development" })).toThrow(/Unable to find the certificate files/)
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
it("handles invalid APP_URL", () => {
|
|
508
|
+
process.env.VITE_SERVER_KEY = "path/to/key"
|
|
509
|
+
process.env.VITE_SERVER_CERT = "path/to/cert"
|
|
510
|
+
process.env.APP_URL = "invalid-url"
|
|
511
|
+
|
|
512
|
+
const plugin = litestar("resources/js/app.js")[0]
|
|
513
|
+
|
|
514
|
+
expect(() => plugin.config({}, { command: "serve", mode: "development" })).toThrow(/Unable to find the certificate files specified in your environment/)
|
|
515
|
+
})
|
|
516
|
+
|
|
517
|
+
it("handles missing config directory", () => {
|
|
518
|
+
const plugin = litestar({
|
|
519
|
+
input: "resources/js/app.js",
|
|
520
|
+
detectTls: true,
|
|
521
|
+
})[0]
|
|
522
|
+
|
|
523
|
+
expect(() => plugin.config({}, { command: "serve", mode: "development" })).toThrow(/Unable to find the configuration file/)
|
|
524
|
+
})
|
|
525
|
+
})
|
|
416
526
|
describe("inertia-helpers", () => {
|
|
417
|
-
const
|
|
527
|
+
const testPath = "./__data__/dummy.ts"
|
|
528
|
+
|
|
529
|
+
beforeEach(() => {
|
|
530
|
+
vi.resetModules()
|
|
531
|
+
// Mock the import.meta.glob functionality
|
|
532
|
+
vi.mock("./__data__/dummy.ts", () => ({
|
|
533
|
+
default: "Dummy File",
|
|
534
|
+
}))
|
|
535
|
+
})
|
|
536
|
+
|
|
418
537
|
it("pass glob value to resolvePageComponent", async () => {
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
)
|
|
538
|
+
const pages = {
|
|
539
|
+
[testPath]: Promise.resolve({ default: "Dummy File" }),
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const file = await resolvePageComponent<{ default: string }>(testPath, pages)
|
|
424
543
|
expect(file.default).toBe("Dummy File")
|
|
425
544
|
})
|
|
426
545
|
|
|
427
546
|
it("pass eagerly globed value to resolvePageComponent", async () => {
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
)
|
|
547
|
+
const pages = {
|
|
548
|
+
[testPath]: { default: "Dummy File" },
|
|
549
|
+
}
|
|
550
|
+
// @ts-ignore
|
|
551
|
+
const file = await resolvePageComponent<{ default: string }>(testPath, pages)
|
|
433
552
|
expect(file.default).toBe("Dummy File")
|
|
434
553
|
})
|
|
435
554
|
|
|
436
555
|
it("accepts array of paths", async () => {
|
|
556
|
+
const pages = {
|
|
557
|
+
[testPath]: { default: "Dummy File" },
|
|
558
|
+
}
|
|
559
|
+
|
|
437
560
|
const file = await resolvePageComponent<{ default: string }>(
|
|
438
|
-
["missing-page",
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
/* @ts-ignore */
|
|
442
|
-
path,
|
|
561
|
+
["missing-page", testPath],
|
|
562
|
+
// @ts-ignore
|
|
563
|
+
pages,
|
|
443
564
|
)
|
|
444
565
|
expect(file.default).toBe("Dummy File")
|
|
445
566
|
})
|
|
446
567
|
|
|
447
568
|
it("throws an error when a page is not found", async () => {
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
"missing-page",
|
|
451
|
-
/* @ts-ignore */
|
|
452
|
-
import.meta.glob("./__data__/*.ts"),
|
|
453
|
-
)
|
|
454
|
-
await expect(callback).rejects.toThrowError(new Error("Page not found: missing-page"))
|
|
569
|
+
const pages = {}
|
|
570
|
+
await expect(resolvePageComponent<{ default: string }>("missing-page", pages)).rejects.toThrow("Page not found: missing-page")
|
|
455
571
|
})
|
|
456
572
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
/* @ts-ignore */
|
|
462
|
-
import.meta.glob("./__data__/*.ts"),
|
|
463
|
-
)
|
|
464
|
-
await expect(callback).rejects.toThrowError(new Error("Page not found: missing-page-1,missing-page-2"))
|
|
465
|
-
})
|
|
466
|
-
})
|
|
467
|
-
|
|
468
|
-
describe("route helpers", () => {
|
|
469
|
-
beforeEach(() => {
|
|
470
|
-
// Setup mock routes based on the provided JSON
|
|
471
|
-
globalThis.routes = {
|
|
472
|
-
home: "/",
|
|
473
|
-
about: "/about",
|
|
474
|
-
"users:assign-role": "/api/roles/{role_slug:str}/assign",
|
|
475
|
-
"users:revoke-role": "/api/roles/{role_slug:str}/revoke",
|
|
476
|
-
"tags:create": "/api/tags",
|
|
477
|
-
"tags:list": "/api/tags",
|
|
478
|
-
"tags:get": "/api/tags/{tag_id:uuid}",
|
|
479
|
-
"tags:update": "/api/tags/{tag_id:uuid}",
|
|
480
|
-
"tags:delete": "/api/tags/{tag_id:uuid}",
|
|
481
|
-
"teams:add-member": "/api/teams/{team_id:uuid}/members/add",
|
|
482
|
-
"teams:remove-member": "/api/teams/{team_id:uuid}/members/remove",
|
|
483
|
-
"users:create": "/api/users/create",
|
|
484
|
-
"users:list": "/api/users/list",
|
|
485
|
-
"users:update": "/api/users/update/{user_id:uuid}",
|
|
486
|
-
"users:delete": "/api/users/delete/{user_id:uuid}",
|
|
487
|
-
"users:get": "/api/users/get/{user_id:uuid}",
|
|
488
|
-
dashboard: "/dashboard",
|
|
489
|
-
favicon: "/favicon.ico",
|
|
490
|
-
landing: "/landing",
|
|
491
|
-
"login.check": "/login/check",
|
|
492
|
-
login: "/login",
|
|
493
|
-
logout: "/logout",
|
|
494
|
-
"github.complete": "/o/github/complete",
|
|
495
|
-
"google.complete": "/o/google/complete",
|
|
496
|
-
"privacy-policy": "/privacy-policy",
|
|
497
|
-
"account.remove": "/profile/remove",
|
|
498
|
-
"profile.show": "/profile",
|
|
499
|
-
"profile.update": "/profile/update",
|
|
500
|
-
"password.update": "/profile/password-update",
|
|
501
|
-
register: "/register",
|
|
502
|
-
"register.add": "/register/add",
|
|
503
|
-
"github.register": "/register/github",
|
|
504
|
-
"google.register": "/register/google",
|
|
505
|
-
"worker:index": "/saq/queues/{queue_id:str}/jobs/{job_id:str}",
|
|
506
|
-
"worker:queue-list": "/saq/api/queues/list",
|
|
507
|
-
"worker:queue-detail": "/saq/api/queues/{queue_id:str}",
|
|
508
|
-
"worker:job-detail": "/saq/api/queues/{queue_id:str}/jobs/{job_id:str}",
|
|
509
|
-
"worker:job-abort": "/saq/api/queues/{queue_id:str}/jobs/{job_id:str}/abort",
|
|
510
|
-
"worker:job-retry": "/saq/api/queues/{queue_id:str}/jobs/{job_id:str}/retry",
|
|
511
|
-
saq: "/saq/static/{file_path:path}",
|
|
512
|
-
vite: "/static/{file_path:path}",
|
|
513
|
-
"teams.add": "/teams/add",
|
|
514
|
-
"teams.list": "/teams/list",
|
|
515
|
-
"teams.show": "/teams/show/{team_id:uuid}",
|
|
516
|
-
"teams.remove": "/teams/remove/{team_id:uuid}",
|
|
517
|
-
"teams.edit": "/teams/edit/{team_id:uuid}",
|
|
518
|
-
"terms-of-service": "/terms-of-service",
|
|
519
|
-
}
|
|
520
|
-
})
|
|
521
|
-
|
|
522
|
-
describe("route()", () => {
|
|
523
|
-
it("generates URLs from route names with named parameters", () => {
|
|
524
|
-
expect(route("users:get", { user_id: "123e4567-e89b-12d3-a456-426614174000" })).toContain("/api/users/get/123e4567-e89b-12d3-a456-426614174000")
|
|
573
|
+
describe("route() edge cases", () => {
|
|
574
|
+
it("handles missing route names", () => {
|
|
575
|
+
expect(route("non-existent-route")).toBe("#")
|
|
576
|
+
})
|
|
525
577
|
|
|
526
|
-
|
|
578
|
+
it("handles array arguments", () => {
|
|
579
|
+
const result = route("users:get", ["123e4567-e89b-12d3-a456-426614174000"])
|
|
580
|
+
expect(result).toContain("/api/users/get/123e4567-e89b-12d3-a456-426614174000")
|
|
527
581
|
})
|
|
528
582
|
|
|
529
|
-
it(
|
|
530
|
-
expect(route("
|
|
583
|
+
it("handles wrong number of arguments", () => {
|
|
584
|
+
expect(route("users:get", [])).toBe("#")
|
|
531
585
|
})
|
|
532
586
|
|
|
533
|
-
it("handles missing
|
|
534
|
-
expect(route("users:get")).toBe("#")
|
|
587
|
+
it("handles missing arguments in object", () => {
|
|
588
|
+
expect(route("users:get", { wrong_id: "123" })).toBe("#")
|
|
535
589
|
})
|
|
536
590
|
})
|
|
537
591
|
|
|
538
592
|
describe("getRelativeUrlPath()", () => {
|
|
539
|
-
it("
|
|
540
|
-
expect(getRelativeUrlPath("
|
|
541
|
-
"/api/users/get/123e4567-e89b-12d3-a456-426614174000?page=1#section",
|
|
542
|
-
)
|
|
593
|
+
it("handles invalid URLs", () => {
|
|
594
|
+
expect(getRelativeUrlPath("invalid-url")).toBe("invalid-url")
|
|
543
595
|
})
|
|
544
596
|
|
|
545
|
-
it("
|
|
546
|
-
expect(getRelativeUrlPath("/
|
|
597
|
+
it("preserves query parameters and hash", () => {
|
|
598
|
+
expect(getRelativeUrlPath("http://example.com/path?query=1#hash")).toBe("/path?query=1#hash")
|
|
547
599
|
})
|
|
548
600
|
})
|
|
549
601
|
|
|
550
602
|
describe("toRoute()", () => {
|
|
551
|
-
it("
|
|
552
|
-
expect(toRoute("/
|
|
603
|
+
it("handles root path", () => {
|
|
604
|
+
expect(toRoute("/")).toBe("home")
|
|
605
|
+
})
|
|
606
|
+
|
|
607
|
+
it("handles UUID parameters", () => {
|
|
553
608
|
expect(toRoute("/api/users/get/123e4567-e89b-12d3-a456-426614174000")).toBe("users:get")
|
|
554
|
-
expect(toRoute("/teams/list")).toBe("teams.list")
|
|
555
|
-
expect(toRoute("/teams/show/123e4567-e89b-12d3-a456-426614174000")).toBe("teams.show")
|
|
556
|
-
expect(toRoute("/saq/api/queues/list")).toBe("worker:queue-list")
|
|
557
|
-
expect(toRoute("/saq/api/queues/default/jobs/123")).toBe("worker:job-detail")
|
|
558
|
-
expect(toRoute("/saq/static/path/to/file.pdf")).toBe("saq")
|
|
559
609
|
})
|
|
560
610
|
|
|
561
|
-
it("
|
|
562
|
-
expect(toRoute("/
|
|
611
|
+
it("handles path parameters", () => {
|
|
612
|
+
expect(toRoute("/saq/static/some/deep/path")).toBe("saq")
|
|
613
|
+
})
|
|
614
|
+
|
|
615
|
+
it("handles non-matching routes", () => {
|
|
616
|
+
expect(toRoute("/non-existent")).toBe(null)
|
|
617
|
+
})
|
|
618
|
+
|
|
619
|
+
it("handles trailing slashes", () => {
|
|
620
|
+
expect(toRoute("/api/users/list/")).toBe("users:list")
|
|
563
621
|
})
|
|
564
622
|
})
|
|
565
623
|
|
|
566
624
|
describe("currentRoute()", () => {
|
|
567
|
-
|
|
625
|
+
beforeEach(() => {
|
|
568
626
|
// Mock window.location
|
|
569
627
|
Object.defineProperty(window, "location", {
|
|
570
|
-
value: {
|
|
628
|
+
value: {
|
|
629
|
+
pathname: "/api/users/list",
|
|
630
|
+
},
|
|
571
631
|
writable: true,
|
|
572
632
|
})
|
|
573
|
-
|
|
574
|
-
expect(currentRoute()).toBe("users:get")
|
|
575
633
|
})
|
|
576
634
|
|
|
577
|
-
it("returns
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
writable: true,
|
|
581
|
-
})
|
|
635
|
+
it("returns current route name", () => {
|
|
636
|
+
expect(currentRoute()).toBe("users:list")
|
|
637
|
+
})
|
|
582
638
|
|
|
583
|
-
|
|
639
|
+
it("returns null for non-matching routes", () => {
|
|
640
|
+
window.location.pathname = "/non-existent"
|
|
641
|
+
expect(currentRoute()).toBe(null)
|
|
584
642
|
})
|
|
585
643
|
})
|
|
586
644
|
|
|
587
645
|
describe("isRoute()", () => {
|
|
588
|
-
it("
|
|
589
|
-
expect(isRoute("/api/users/
|
|
590
|
-
|
|
646
|
+
it("matches exact routes", () => {
|
|
647
|
+
expect(isRoute("/api/users/list", "users:list")).toBe(true)
|
|
648
|
+
})
|
|
649
|
+
|
|
650
|
+
it("matches routes with parameters", () => {
|
|
651
|
+
expect(isRoute("/api/users/get/123e4567-e89b-12d3-a456-426614174000", "users:*")).toBe(true)
|
|
652
|
+
})
|
|
653
|
+
|
|
654
|
+
it("handles non-matching routes", () => {
|
|
655
|
+
expect(isRoute("/non-existent", "users:*")).toBe(false)
|
|
656
|
+
})
|
|
657
|
+
|
|
658
|
+
it("matches routes with path parameters", () => {
|
|
659
|
+
expect(isRoute("/saq/static/deep/nested/path", "saq")).toBe(true)
|
|
591
660
|
})
|
|
592
661
|
})
|
|
593
662
|
|
|
594
663
|
describe("isCurrentRoute()", () => {
|
|
595
|
-
|
|
664
|
+
beforeEach(() => {
|
|
665
|
+
// Mock window.location
|
|
596
666
|
Object.defineProperty(window, "location", {
|
|
597
|
-
value: {
|
|
667
|
+
value: {
|
|
668
|
+
pathname: "/api/users/list",
|
|
669
|
+
},
|
|
598
670
|
writable: true,
|
|
599
671
|
})
|
|
672
|
+
})
|
|
600
673
|
|
|
601
|
-
|
|
602
|
-
expect(isCurrentRoute("users
|
|
674
|
+
it("matches current route with pattern", () => {
|
|
675
|
+
expect(isCurrentRoute("users:*")).toBe(true)
|
|
603
676
|
})
|
|
604
677
|
|
|
605
|
-
it("
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
678
|
+
it("handles exact matches", () => {
|
|
679
|
+
expect(isCurrentRoute("users:list")).toBe(true)
|
|
680
|
+
})
|
|
681
|
+
|
|
682
|
+
it("handles non-matching routes", () => {
|
|
683
|
+
expect(isCurrentRoute("teams:*")).toBe(false)
|
|
684
|
+
})
|
|
610
685
|
|
|
611
|
-
|
|
686
|
+
it("handles invalid current route", () => {
|
|
687
|
+
window.location.pathname = "/non-existent"
|
|
688
|
+
expect(isCurrentRoute("users:*")).toBe(false)
|
|
612
689
|
})
|
|
613
690
|
})
|
|
614
691
|
})
|
|
@@ -14,7 +14,7 @@ DEFAULT_RESOURCES: set[str] = {"styles.css.j2", "main.ts.j2"}
|
|
|
14
14
|
DEFAULT_DEV_DEPENDENCIES: dict[str, str] = {
|
|
15
15
|
"typescript": "^5.7.2",
|
|
16
16
|
"vite": "^6.0.3",
|
|
17
|
-
"litestar-vite-plugin": "^0.
|
|
17
|
+
"litestar-vite-plugin": "^0.9.0",
|
|
18
18
|
"@types/node": "^22.10.1",
|
|
19
19
|
}
|
|
20
20
|
DEFAULT_DEPENDENCIES: dict[str, str] = {"axios": "^1.7.2"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/inertia/exception_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/litestar_vite/templates/vite.config.ts.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_app/web/public/assets/main-l0sNRNKZ.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/templates/index.html.j2
RENAMED
|
File without changes
|
{litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/test_inertia_request.py
RENAMED
|
File without changes
|
{litestar_vite-0.8.2 → litestar_vite-0.9.0}/src/py/tests/test_inertia/test_inertia_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|