import { sveltekit } from "@sveltejs/kit/vite"; import { defineConfig, loadEnv } from "vite"; import { readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; const pkg = JSON.parse( readFileSync( fileURLToPath(new URL("./package.json", import.meta.url)), "utf8", ), ) as { version: string }; // Parse the VITE_DEV_HOST override into the shape `server.host` // expects. `""` / `"false"` keeps Vite's safe default (loopback // only); `"true"` / `"1"` flips to "all interfaces" (`0.0.0.0` plus // IPv6); any other string is passed through verbatim so a developer // can pin a single LAN address (e.g. `"192.168.1.5"`). Returning // `undefined` lets Vite stay on its built-in default. function parseDevHost(raw: string | undefined): string | boolean | undefined { if (raw === undefined || raw === "") return undefined; const normalised = raw.toLowerCase(); if (normalised === "true" || normalised === "1" || normalised === "yes") { return true; } if (normalised === "false" || normalised === "0" || normalised === "no") { return false; } return raw; } export default defineConfig(({ mode }) => { // `loadEnv("", ...)` matches every `.env*` entry regardless of // the customary `VITE_` prefix so the config sees the same view // that client code sees via `import.meta.env`. Without this // `process.env` would carry only the shell's exports, and // per-developer files like `.env.development.local` would // silently miss the config — every override would have to be // passed on the `pnpm dev` command line. const env = loadEnv(mode, process.cwd(), ""); // Default upstream gateway addresses used by the dev proxy. // Override by pointing `VITE_DEV_PROXY_TARGET` (REST surface) // and `VITE_DEV_GRPC_PROXY_TARGET` (Connect-Web surface) at a // different gateway when working with a remote stack instead of // `tools/local-dev/`. In production the two surfaces sit behind // a single host; the split here exists only because local-dev // runs the REST listener on :8080 and the authenticated // Connect-Web listener on :9090. const DEV_PROXY_TARGET = env.VITE_DEV_PROXY_TARGET || "http://localhost:8080"; const DEV_GRPC_PROXY_TARGET = env.VITE_DEV_GRPC_PROXY_TARGET || "http://localhost:9090"; // `VITE_DEV_HOST` opts the dev server into wider listener // binding. Default stays at Vite's safe loopback-only behaviour // so an unattended `pnpm dev` on someone's laptop never exposes // the unauthenticated dev surface to the LAN by accident. Set // the value in `.env.development.local` (untracked) when // reaching the server through SSH port forwarding, a VM, or a // container needs a non-loopback bind. const devHost = parseDevHost(env.VITE_DEV_HOST); return { plugins: [sveltekit()], define: { __APP_VERSION__: JSON.stringify(pkg.version), }, server: { ...(devHost !== undefined ? { host: devHost } : {}), // Same-origin proxy so the browser sees only // `localhost:5173` and never trips a cross-origin // preflight against the gateway's REST + Connect-Web // surfaces. Production deployments serve the UI and the // gateway behind a single host, so the proxy is purely a // dev-time convenience. proxy: { "/api": { target: DEV_PROXY_TARGET, changeOrigin: false, }, "/galaxy.gateway.v1.EdgeGateway": { target: DEV_GRPC_PROXY_TARGET, changeOrigin: false, // Connect-Web server-streaming // (`SubscribeEvents`) uses chunked HTTP // responses; http-proxy passes them through // transparently as long as buffering stays off, // which is the default. }, }, }, }; });