litestar-vite 0.7.1__tar.gz → 0.8.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.

Files changed (78) hide show
  1. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/PKG-INFO +1 -1
  2. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/pyproject.toml +23 -2
  3. litestar_vite-0.8.0/src/js/src/index.ts +566 -0
  4. litestar_vite-0.8.0/src/js/src/inertia-helpers/index.ts +169 -0
  5. litestar_vite-0.8.0/src/js/tests/__data__/dummy.ts +1 -0
  6. litestar_vite-0.8.0/src/js/tests/index.test.ts +614 -0
  7. litestar_vite-0.8.0/src/js/tsconfig.inertia-helpers.json +7 -0
  8. litestar_vite-0.8.0/src/js/tsconfig.json +13 -0
  9. litestar_vite-0.8.0/src/js/vitest.config.ts +8 -0
  10. litestar_vite-0.8.0/src/js/vitest.workspace.ts +4 -0
  11. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/config.py +2 -0
  12. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/exception_handler.py +16 -2
  13. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/plugin.py +2 -2
  14. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_inertia/test_inertia_response.py +41 -0
  15. litestar_vite-0.7.1/src/js/src/index.ts +0 -730
  16. litestar_vite-0.7.1/src/js/src/inertia-helpers/index.ts +0 -179
  17. litestar_vite-0.7.1/src/js/tests/__data__/dummy.ts +0 -1
  18. litestar_vite-0.7.1/src/js/tests/index.test.ts +0 -562
  19. litestar_vite-0.7.1/src/js/tsconfig.inertia-helpers.json +0 -9
  20. litestar_vite-0.7.1/src/js/tsconfig.json +0 -15
  21. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/.gitignore +0 -0
  22. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/LICENSE +0 -0
  23. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/README.md +0 -0
  24. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/js/LICENSE +0 -0
  25. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/js/Makefile +0 -0
  26. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/js/NOTICE +0 -0
  27. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/js/README.md +0 -0
  28. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/js/src/dev-server-index.html +0 -0
  29. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/__init__.py +0 -0
  30. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/__metadata__.py +0 -0
  31. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/cli.py +0 -0
  32. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/commands.py +0 -0
  33. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/config.py +0 -0
  34. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/__init__.py +0 -0
  35. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/_utils.py +0 -0
  36. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/middleware.py +0 -0
  37. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/request.py +0 -0
  38. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/response.py +0 -0
  39. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/routes.py +0 -0
  40. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/inertia/types.py +0 -0
  41. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/loader.py +0 -0
  42. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/plugin.py +0 -0
  43. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/py.typed +0 -0
  44. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/template_engine.py +0 -0
  45. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/templates/__init__.py +0 -0
  46. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/templates/index.html.j2 +0 -0
  47. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/templates/main.ts.j2 +0 -0
  48. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/templates/package.json.j2 +0 -0
  49. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/templates/styles.css.j2 +0 -0
  50. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/templates/tsconfig.json.j2 +0 -0
  51. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/litestar_vite/templates/vite.config.ts.j2 +0 -0
  52. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/__init__.py +0 -0
  53. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/conftest.py +0 -0
  54. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/templates/__init__.py +0 -0
  55. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/templates/index.html.j2 +0 -0
  56. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/__init__.py +0 -0
  57. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/app.py +0 -0
  58. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/__init__.py +0 -0
  59. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/public/.gitkeep +0 -0
  60. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/public/assets/main-l0sNRNKZ.js +0 -0
  61. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/public/assets/styles-l0sNRNKZ.js +0 -0
  62. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/public/manifest.json +0 -0
  63. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/resources/.gitkeep +0 -0
  64. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/resources/main.ts +0 -0
  65. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/resources/styles.css +0 -0
  66. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/templates/.gitkeep +0 -0
  67. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_app/web/templates/index.html +0 -0
  68. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_cli/__init__.py +0 -0
  69. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_cli/conftest.py +0 -0
  70. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_cli/test_init.py +0 -0
  71. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_commands.py +0 -0
  72. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_config.py +0 -0
  73. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_inertia/__init__.py +0 -0
  74. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_inertia/conftest.py +0 -0
  75. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_inertia/templates/index.html.j2 +0 -0
  76. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_inertia/test_inertia_request.py +0 -0
  77. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_inertia/test_routes.py +0 -0
  78. {litestar_vite-0.7.1 → litestar_vite-0.8.0}/src/py/tests/test_template_engine.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: litestar-vite
3
- Version: 0.7.1
3
+ Version: 0.8.0
4
4
  Summary: Vite plugin for Litestar
5
5
  Project-URL: Changelog, https://cofin.github.io/litestar-vite/latest/changelog
6
6
  Project-URL: Discord, https://discord.gg/X3FJqy8d2j
@@ -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.7.1"
28
+ version = "0.8.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.7.1"
88
+ current_version = "0.8.0"
89
89
  ignore_missing_files = false
90
90
  ignore_missing_version = false
91
91
  message = "chore(release): bump to v{new_version}"
@@ -120,6 +120,27 @@ name = "litestar-vite"
120
120
  version = "{current_version}"
121
121
  """
122
122
 
123
+ [[tool.bumpversion.files]]
124
+ filename = "package-lock.json"
125
+ replace = """
126
+ "name": "litestar-vite-plugin",
127
+ "version": "{new_version}",
128
+ """
129
+ search = """
130
+ "name": "litestar-vite-plugin",
131
+ "version": "{current_version}",
132
+ """
133
+ [[tool.bumpversion.files]]
134
+ filename = "package-lock.json"
135
+ replace = """
136
+ "name": "litestar-vite-plugin",
137
+ "version": "{new_version}",
138
+ """
139
+ search = """
140
+ "name": "litestar-vite-plugin",
141
+ "version": "{current_version}",
142
+ """
143
+
123
144
  [tool.pytest.ini_options]
124
145
  addopts = "--dist loadfile -n auto"
125
146
  filterwarnings = ["ignore::DeprecationWarning:pkg_resources.*"]
@@ -0,0 +1,566 @@
1
+ import fs from "node:fs"
2
+ import type { AddressInfo } from "node:net"
3
+ import path from "node:path"
4
+ import { fileURLToPath } from "node:url"
5
+ import colors from "picocolors"
6
+ import { type ConfigEnv, type Plugin, type PluginOption, type ResolvedConfig, type SSROptions, type UserConfig, loadEnv } from "vite"
7
+ import fullReload, { type Config as FullReloadConfig } from "vite-plugin-full-reload"
8
+
9
+ interface PluginConfig {
10
+ /**
11
+ * The path or paths of the entry points to compile.
12
+ */
13
+ input: string | string[]
14
+ /**
15
+ * The base path to use for all asset URLs.
16
+ *
17
+ * @default '/static/'
18
+ */
19
+ assetUrl?: string
20
+ /**
21
+ * The public directory where all compiled/bundled assets should be written.
22
+ *
23
+ * @default 'public/dist'
24
+ */
25
+ bundleDirectory?: string
26
+ /**
27
+ * Litestar's public assets directory. These are the assets that Vite will serve when developing.
28
+ *
29
+ * @default 'resources'
30
+ */
31
+ resourceDirectory?: string
32
+
33
+ /**
34
+ * The path to the "hot" file.
35
+ *
36
+ * @default `${bundleDirectory}/hot`
37
+ */
38
+ hotFile?: string
39
+
40
+ /**
41
+ * The path of the SSR entry point.
42
+ */
43
+ ssr?: string | string[]
44
+
45
+ /**
46
+ * The directory where the SSR bundle should be written.
47
+ *
48
+ * @default '${bundleDirectory}/bootstrap/ssr'
49
+ */
50
+ ssrOutputDirectory?: string
51
+
52
+ /**
53
+ * Configuration for performing full page refresh on python (or other) file changes.
54
+ *
55
+ * {@link https://github.com/ElMassimo/vite-plugin-full-reload}
56
+ * @default false
57
+ */
58
+ refresh?: boolean | string | string[] | RefreshConfig | RefreshConfig[]
59
+
60
+ /**
61
+ * Utilize TLS certificates.
62
+ *
63
+ * @default null
64
+ */
65
+ detectTls?: string | boolean | null
66
+ /**
67
+ * Transform the code while serving.
68
+ */
69
+ transformOnServe?: (code: string, url: DevServerUrl) => string
70
+ }
71
+
72
+ interface RefreshConfig {
73
+ paths: string[]
74
+ config?: FullReloadConfig
75
+ }
76
+
77
+ interface LitestarPlugin extends Plugin {
78
+ config: (config: UserConfig, env: ConfigEnv) => UserConfig
79
+ }
80
+
81
+ type DevServerUrl = `${"http" | "https"}://${string}:${number}`
82
+
83
+ let exitHandlersBound = false
84
+
85
+ export const refreshPaths = ["**/*.py", "**/*.j2", "**/*.html.j2", "**/*.html", "**/assets/**/*"]
86
+
87
+ /**
88
+ * Litestar plugin for Vite.
89
+ *
90
+ * @param config - A config object or relative path(s) of the scripts to be compiled.
91
+ */
92
+ export default function litestar(config: string | string[] | PluginConfig): [LitestarPlugin, ...Plugin[]] {
93
+ const pluginConfig = resolvePluginConfig(config)
94
+
95
+ return [resolveLitestarPlugin(pluginConfig), ...(resolveFullReloadConfig(pluginConfig) as Plugin[])]
96
+ }
97
+
98
+ /**
99
+ * Resolve the Litestar Plugin configuration.
100
+ */
101
+ function resolveLitestarPlugin(pluginConfig: Required<PluginConfig>): LitestarPlugin {
102
+ let viteDevServerUrl: DevServerUrl
103
+ let resolvedConfig: ResolvedConfig
104
+ let userConfig: UserConfig
105
+
106
+ const defaultAliases: Record<string, string> = {
107
+ "@": pluginConfig.resourceDirectory || "/resources/",
108
+ }
109
+
110
+ return {
111
+ name: "litestar",
112
+ enforce: "post",
113
+ config: (config, { command, mode }) => {
114
+ userConfig = config
115
+ const ssr = !!userConfig.build?.ssr
116
+ const env = loadEnv(mode, userConfig.envDir || process.cwd(), "")
117
+ const assetUrl = env.ASSET_URL || pluginConfig.assetUrl
118
+ const serverConfig = command === "serve" ? (resolveDevelopmentEnvironmentServerConfig(pluginConfig.detectTls) ?? resolveEnvironmentServerConfig(env)) : undefined
119
+
120
+ ensureCommandShouldRunInEnvironment(command, env)
121
+
122
+ return {
123
+ base: userConfig.base ?? (command === "build" ? resolveBase(pluginConfig, assetUrl) : pluginConfig.assetUrl),
124
+ publicDir: userConfig.publicDir ?? false,
125
+ clearScreen: false,
126
+ build: {
127
+ manifest: userConfig.build?.manifest ?? (ssr ? false : "manifest.json"),
128
+ ssrManifest: userConfig.build?.ssrManifest ?? (ssr ? "ssr-manifest.json" : false),
129
+ outDir: userConfig.build?.outDir ?? resolveOutDir(pluginConfig, ssr),
130
+ rollupOptions: {
131
+ input: userConfig.build?.rollupOptions?.input ?? resolveInput(pluginConfig, ssr),
132
+ },
133
+ assetsInlineLimit: userConfig.build?.assetsInlineLimit ?? 0,
134
+ },
135
+ server: {
136
+ origin: userConfig.server?.origin ?? "__litestar_vite_placeholder__",
137
+ ...(process.env.VITE_ALLOW_REMOTE
138
+ ? {
139
+ host: userConfig.server?.host ?? "0.0.0.0",
140
+ port: userConfig.server?.port ?? (env.VITE_PORT ? Number.parseInt(env.VITE_PORT) : 5173),
141
+ strictPort: userConfig.server?.strictPort ?? true,
142
+ }
143
+ : undefined),
144
+ ...(serverConfig
145
+ ? {
146
+ host: userConfig.server?.host ?? serverConfig.host,
147
+ hmr:
148
+ userConfig.server?.hmr === false
149
+ ? false
150
+ : {
151
+ ...serverConfig.hmr,
152
+ ...(userConfig.server?.hmr === true ? {} : userConfig.server?.hmr),
153
+ },
154
+ https: userConfig.server?.https ?? serverConfig.https,
155
+ }
156
+ : undefined),
157
+ },
158
+ resolve: {
159
+ alias: Array.isArray(userConfig.resolve?.alias)
160
+ ? [
161
+ ...(userConfig.resolve?.alias ?? []),
162
+ ...Object.keys(defaultAliases).map((alias) => ({
163
+ find: alias,
164
+ replacement: defaultAliases[alias],
165
+ })),
166
+ ]
167
+ : {
168
+ ...defaultAliases,
169
+ ...userConfig.resolve?.alias,
170
+ },
171
+ },
172
+ ssr: {
173
+ noExternal: noExternalInertiaHelpers(userConfig),
174
+ },
175
+ }
176
+ },
177
+ configResolved(config) {
178
+ resolvedConfig = config
179
+ },
180
+ transform(code: string): string | undefined {
181
+ if (resolvedConfig.command === "serve") {
182
+ const transformedCode = code.replace(/__litestar_vite_placeholder__/g, viteDevServerUrl)
183
+ return pluginConfig.transformOnServe(transformedCode, viteDevServerUrl)
184
+ }
185
+ return undefined
186
+ },
187
+ configureServer(server) {
188
+ const envDir = resolvedConfig.envDir || process.cwd()
189
+ const appUrl = loadEnv(resolvedConfig.mode, envDir, "APP_URL").APP_URL ?? "undefined"
190
+
191
+ server.httpServer?.once("listening", () => {
192
+ const address = server.httpServer?.address()
193
+
194
+ const isAddressInfo = (x: string | AddressInfo | null | undefined): x is AddressInfo => typeof x === "object"
195
+ if (isAddressInfo(address)) {
196
+ viteDevServerUrl = userConfig.server?.origin ? (userConfig.server.origin as DevServerUrl) : resolveDevServerUrl(address, server.config, userConfig)
197
+ fs.mkdirSync(path.dirname(pluginConfig.hotFile), { recursive: true })
198
+ fs.writeFileSync(pluginConfig.hotFile, viteDevServerUrl)
199
+
200
+ setTimeout(() => {
201
+ server.config.logger.info(`\n ${colors.red(`${colors.bold("LITESTAR")} ${litestarVersion()}`)} ${colors.dim("plugin")} ${colors.bold(`v${pluginVersion()}`)}`)
202
+ server.config.logger.info("")
203
+ server.config.logger.info(` ${colors.green("➜")} ${colors.bold("APP_URL")}: ${colors.cyan(appUrl.replace(/:(\d+)/, (_, port) => `:${colors.bold(port)}`))}`)
204
+ }, 100)
205
+ }
206
+ })
207
+
208
+ if (!exitHandlersBound) {
209
+ const clean = () => {
210
+ if (fs.existsSync(pluginConfig.hotFile)) {
211
+ fs.rmSync(pluginConfig.hotFile)
212
+ }
213
+ }
214
+
215
+ process.on("exit", clean)
216
+ process.on("SIGINT", () => process.exit())
217
+ process.on("SIGTERM", () => process.exit())
218
+ process.on("SIGHUP", () => process.exit())
219
+
220
+ exitHandlersBound = true
221
+ }
222
+
223
+ return () =>
224
+ server.middlewares.use((req, res, next) => {
225
+ if (req.url === "/index.html") {
226
+ res.statusCode = 404
227
+
228
+ res.end(
229
+ fs
230
+ .readFileSync(path.join(dirname(), "dev-server-index.html"))
231
+ .toString()
232
+ .replace(/{{ APP_URL }}/g, appUrl),
233
+ )
234
+ }
235
+
236
+ next()
237
+ })
238
+ },
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Validate the command can run in the given environment.
244
+ */
245
+ function ensureCommandShouldRunInEnvironment(command: "build" | "serve", env: Record<string, string>): void {
246
+ const validEnvironmentNames = ["dev", "development", "local", "docker"]
247
+ if (command === "build" || env.LITESTAR_BYPASS_ENV_CHECK === "1") {
248
+ return
249
+ }
250
+
251
+ if (typeof env.LITESTAR_MODE !== "undefined" && validEnvironmentNames.some((e) => e === env.LITESTAR_MODE)) {
252
+ throw Error(
253
+ "You should only run Vite dev server when Litestar is development mode. You should build your assets for production instead. To disable this ENV check you may set LITESTAR_BYPASS_ENV_CHECK=1",
254
+ )
255
+ }
256
+
257
+ if (typeof env.CI !== "undefined") {
258
+ throw Error(
259
+ "You should not run the Vite HMR server in CI environments. You should build your assets for production instead. To disable this ENV check you may set LITESTAR_BYPASS_ENV_CHECK=1",
260
+ )
261
+ }
262
+ }
263
+
264
+ /**
265
+ * The version of Litestar being run.
266
+ */
267
+ function litestarVersion(): string {
268
+ return ""
269
+ }
270
+
271
+ /**
272
+ * The version of the Litestar Vite plugin being run.
273
+ */
274
+ function pluginVersion(): string {
275
+ try {
276
+ return JSON.parse(fs.readFileSync(path.join(dirname(), "../package.json")).toString())?.version
277
+ } catch {
278
+ return ""
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Convert the users configuration into a standard structure with defaults.
284
+ */
285
+ function resolvePluginConfig(config: string | string[] | PluginConfig): Required<PluginConfig> {
286
+ if (typeof config === "undefined") {
287
+ throw new Error("litestar-vite-plugin: missing configuration.")
288
+ }
289
+ const resolvedConfig = typeof config === "string" || Array.isArray(config) ? { input: config, ssr: config } : config
290
+
291
+ if (typeof resolvedConfig.input === "undefined") {
292
+ throw new Error('litestar-vite-plugin: missing configuration for "input".')
293
+ }
294
+ if (typeof resolvedConfig.resourceDirectory === "string") {
295
+ resolvedConfig.resourceDirectory = resolvedConfig.resourceDirectory.trim().replace(/^\/+/, "")
296
+
297
+ if (resolvedConfig.resourceDirectory === "") {
298
+ throw new Error("litestar-vite-plugin: resourceDirectory must be a subdirectory. E.g. 'resources'.")
299
+ }
300
+ }
301
+
302
+ if (typeof resolvedConfig.bundleDirectory === "string") {
303
+ resolvedConfig.bundleDirectory = resolvedConfig.bundleDirectory.trim().replace(/^\/+/, "").replace(/\/+$/, "")
304
+
305
+ if (resolvedConfig.bundleDirectory === "") {
306
+ throw new Error("litestar-vite-plugin: bundleDirectory must be a subdirectory. E.g. 'public'.")
307
+ }
308
+ }
309
+
310
+ if (typeof resolvedConfig.ssrOutputDirectory === "string") {
311
+ resolvedConfig.ssrOutputDirectory = resolvedConfig.ssrOutputDirectory.trim().replace(/^\/+/, "").replace(/\/+$/, "")
312
+ }
313
+
314
+ if (resolvedConfig.refresh === true) {
315
+ resolvedConfig.refresh = [{ paths: refreshPaths }]
316
+ }
317
+
318
+ return {
319
+ input: resolvedConfig.input,
320
+ assetUrl: resolvedConfig.assetUrl ?? "static",
321
+ resourceDirectory: resolvedConfig.resourceDirectory ?? "/resources/",
322
+ bundleDirectory: resolvedConfig.bundleDirectory || (resolvedConfig.bundleDirectory ?? "public"),
323
+ ssr: resolvedConfig.ssr ?? resolvedConfig.input,
324
+ ssrOutputDirectory: resolvedConfig.ssrOutputDirectory ?? path.join(resolvedConfig.resourceDirectory ?? "resources", "bootstrap/ssr"),
325
+ refresh: resolvedConfig.refresh ?? false,
326
+ hotFile: resolvedConfig.hotFile ?? path.join(resolvedConfig.bundleDirectory ?? "public", "hot"),
327
+ detectTls: resolvedConfig.detectTls ?? false,
328
+ transformOnServe: resolvedConfig.transformOnServe ?? ((code) => code),
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Resolve the Vite base option from the configuration.
334
+ */
335
+ function resolveBase(config: Required<PluginConfig>, assetUrl: string): string {
336
+ return assetUrl + (assetUrl.endsWith("/") ? "" : "/")
337
+ }
338
+
339
+ /**
340
+ * Resolve the Vite input path from the configuration.
341
+ */
342
+ function resolveInput(config: Required<PluginConfig>, ssr: boolean): string | string[] | undefined {
343
+ if (ssr) {
344
+ return config.ssr
345
+ }
346
+
347
+ return config.input
348
+ }
349
+
350
+ /**
351
+ * Resolve the Vite outDir path from the configuration.
352
+ */
353
+ function resolveOutDir(config: Required<PluginConfig>, ssr: boolean): string | undefined {
354
+ if (ssr) {
355
+ return config.ssrOutputDirectory
356
+ }
357
+
358
+ return path.join(config.bundleDirectory)
359
+ }
360
+
361
+ function resolveFullReloadConfig({ refresh: config }: Required<PluginConfig>): PluginOption[] {
362
+ if (typeof config === "boolean") {
363
+ return []
364
+ }
365
+
366
+ if (typeof config === "string") {
367
+ config = [{ paths: [config] }]
368
+ }
369
+
370
+ if (!Array.isArray(config)) {
371
+ config = [config]
372
+ }
373
+
374
+ if (config.some((c) => typeof c === "string")) {
375
+ config = [{ paths: config }] as RefreshConfig[]
376
+ }
377
+
378
+ return (config as RefreshConfig[]).flatMap((c) => {
379
+ const plugin = fullReload(c.paths, c.config)
380
+
381
+ /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
382
+ /** @ts-ignore */
383
+ plugin.__litestar_plugin_config = c
384
+
385
+ return plugin
386
+ })
387
+ }
388
+
389
+ /**
390
+ * Resolve the dev server URL from the server address and configuration.
391
+ */
392
+ function resolveDevServerUrl(address: AddressInfo, config: ResolvedConfig, userConfig: UserConfig): DevServerUrl {
393
+ const configHmrProtocol = typeof config.server.hmr === "object" ? config.server.hmr.protocol : null
394
+ const clientProtocol = configHmrProtocol ? (configHmrProtocol === "wss" ? "https" : "http") : null
395
+ const serverProtocol = config.server.https ? "https" : "http"
396
+ const protocol = clientProtocol ?? serverProtocol
397
+
398
+ const configHmrHost = typeof config.server.hmr === "object" ? config.server.hmr.host : null
399
+ const configHost = typeof config.server.host === "string" ? config.server.host : null
400
+ const remoteHost = process.env.VITE_ALLOW_REMOTE && !userConfig.server?.host ? "localhost" : null
401
+ const serverAddress = isIpv6(address) ? `[${address.address}]` : address.address
402
+ const host = configHmrHost ?? remoteHost ?? configHost ?? serverAddress
403
+
404
+ const configHmrClientPort = typeof config.server.hmr === "object" ? config.server.hmr.clientPort : null
405
+ const port = configHmrClientPort ?? address.port
406
+
407
+ return `${protocol}://${host}:${port}`
408
+ }
409
+
410
+ function isIpv6(address: AddressInfo): boolean {
411
+ return (
412
+ address.family === "IPv6" ||
413
+ // In node >=18.0 <18.4 this was an integer value. This was changed in a minor version.
414
+ // See: https://github.com/laravel/vite-plugin/issues/103
415
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
416
+ // @ts-ignore-next-line
417
+ address.family === 6
418
+ )
419
+ }
420
+
421
+ /**
422
+ * Add the Inertia helpers to the list of SSR dependencies that aren't externalized.
423
+ *
424
+ * @see https://vitejs.dev/guide/ssr.html#ssr-externals
425
+ */
426
+ function noExternalInertiaHelpers(config: UserConfig): true | Array<string | RegExp> {
427
+ /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */
428
+ /* @ts-ignore */
429
+ const userNoExternal = (config.ssr as SSROptions | undefined)?.noExternal
430
+ const pluginNoExternal = ["litestar-vite-plugin"]
431
+
432
+ if (userNoExternal === true) {
433
+ return true
434
+ }
435
+
436
+ if (typeof userNoExternal === "undefined") {
437
+ return pluginNoExternal
438
+ }
439
+
440
+ return [...(Array.isArray(userNoExternal) ? userNoExternal : [userNoExternal]), ...pluginNoExternal]
441
+ }
442
+
443
+ /**
444
+ * Resolve the server config from the environment.
445
+ */
446
+ function resolveEnvironmentServerConfig(env: Record<string, string>):
447
+ | {
448
+ hmr?: { host: string }
449
+ host?: string
450
+ https?: { cert: Buffer; key: Buffer }
451
+ }
452
+ | undefined {
453
+ if (!env.VITE_SERVER_KEY && !env.VITE_SERVER_CERT) {
454
+ return
455
+ }
456
+
457
+ if (!fs.existsSync(env.VITE_SERVER_KEY) || !fs.existsSync(env.VITE_SERVER_CERT)) {
458
+ throw Error(
459
+ `Unable to find the certificate files specified in your environment. Ensure you have correctly configured VITE_SERVER_KEY: [${env.VITE_SERVER_KEY}] and VITE_SERVER_CERT: [${env.VITE_SERVER_CERT}].`,
460
+ )
461
+ }
462
+
463
+ const host = resolveHostFromEnv(env)
464
+
465
+ if (!host) {
466
+ throw Error(`Unable to determine the host from the environment's APP_URL: [${env.APP_URL}].`)
467
+ }
468
+
469
+ return {
470
+ hmr: { host },
471
+ host,
472
+ https: {
473
+ key: fs.readFileSync(env.VITE_DEV_SERVER_KEY),
474
+ cert: fs.readFileSync(env.VITE_DEV_SERVER_CERT),
475
+ },
476
+ }
477
+ }
478
+
479
+ /**
480
+ * Resolve the host name from the environment.
481
+ */
482
+ function resolveHostFromEnv(env: Record<string, string>): string | undefined {
483
+ try {
484
+ return new URL(env.APP_URL).host
485
+ } catch {
486
+ return
487
+ }
488
+ }
489
+
490
+ /**
491
+ * Resolve the Herd or Valet server config for the given host.
492
+ */
493
+ function resolveDevelopmentEnvironmentServerConfig(host: string | boolean | null):
494
+ | {
495
+ hmr?: { host: string }
496
+ host?: string
497
+ https?: { cert: string; key: string }
498
+ }
499
+ | undefined {
500
+ if (host === false) {
501
+ return
502
+ }
503
+
504
+ const configPath = determineDevelopmentEnvironmentConfigPath()
505
+
506
+ if (typeof configPath === "undefined" && host === null) {
507
+ return
508
+ }
509
+
510
+ if (typeof configPath === "undefined") {
511
+ throw Error("Unable to find the Herd or Valet configuration directory. Please check they are correctly installed.")
512
+ }
513
+
514
+ const resolvedHost = host === true || host === null ? `${path.basename(process.cwd())}.${resolveDevelopmentEnvironmentTld(configPath)}` : host
515
+
516
+ const keyPath = path.resolve(configPath, "certs", `${resolvedHost}.key`)
517
+ const certPath = path.resolve(configPath, "certs", `${resolvedHost}.crt`)
518
+
519
+ if ((!fs.existsSync(keyPath) || !fs.existsSync(certPath)) && host === null) {
520
+ throw Error(`Unable to find certificate files for your host [${host}] in the [${configPath}/certs] directory.`)
521
+ }
522
+
523
+ return {
524
+ hmr: { host: resolvedHost },
525
+ host: resolvedHost,
526
+ https: {
527
+ key: keyPath,
528
+ cert: certPath,
529
+ },
530
+ }
531
+ }
532
+
533
+ /**
534
+ * Resolve the path configuration directory.
535
+ */
536
+ function determineDevelopmentEnvironmentConfigPath(): string | undefined {
537
+ const envConfigPath = path.resolve(process.cwd(), ".config")
538
+
539
+ if (fs.existsSync(envConfigPath)) {
540
+ return envConfigPath
541
+ }
542
+
543
+ return path.resolve(process.cwd(), ".config")
544
+ }
545
+
546
+ /**
547
+ * Resolve the TLD via the config path.
548
+ */
549
+ function resolveDevelopmentEnvironmentTld(configPath: string): string {
550
+ const configFile = path.resolve(configPath, "config.json")
551
+
552
+ if (!fs.existsSync(configFile)) {
553
+ throw Error(`Unable to find the configuration file [${configFile}].`)
554
+ }
555
+
556
+ const config: { tld: string } = JSON.parse(fs.readFileSync(configFile, "utf-8"))
557
+
558
+ return config.tld
559
+ }
560
+
561
+ /**
562
+ * The directory of the current file.
563
+ */
564
+ function dirname(): string {
565
+ return fileURLToPath(new URL(".", import.meta.url))
566
+ }