/// import type { ProxyOptions } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' import tailwindcss from '@tailwindcss/vite' import { readFileSync, existsSync } from 'fs' import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' // In Docker, VERSION is copied into the build WORKDIR (/build/web/VERSION). // In local dev, the cwd is web/ and VERSION is two dirs up (../../VERSION // from vite.config.ts location in web/). Try both. let version: string if (existsSync('../VERSION')) { version = readFileSync('../VERSION', 'utf-8').trim() } else { version = readFileSync('VERSION', 'utf-8').trim() } // Injects OIKOS_API_TOKEN into proxied /api requests in dev — the API no // longer has a dev-open bypass (plans/2026-07-12-wails-desktop-app.md 0.4), // so `OIKOS_API_TOKEN=dev-token npm run dev` needs this to reach it. function authProxy(target: string, rewrite?: (path: string) => string): ProxyOptions { return { target, ...(rewrite ? { rewrite } : {}), configure: (proxy) => { proxy.on('proxyReq', (proxyReq) => { const token = process.env.OIKOS_API_TOKEN if (token) proxyReq.setHeader('Authorization', `Bearer ${token}`) }) } } } export default defineConfig({ plugins: [tailwindcss(), svelte()], base: '/', define: { __OIKOS_VERSION__: JSON.stringify(`v${version}`), // Lets the dev server auto-configure the SPA with the same token it // already injects into proxied requests (see authProxy above), so `npm // run dev` skips the "Connect to Oikos" prompt instead of re-asking for // a token every time localStorage gets cleared. Empty string (never a // real prod secret — see main.ts, only consulted in import.meta.env.DEV) // when OIKOS_API_TOKEN isn't set, so the prompt still shows if unconfigured. __OIKOS_DEV_TOKEN__: JSON.stringify(process.env.OIKOS_API_TOKEN ?? ''), }, resolve: { alias: { $lib: '/src/lib', // svelte-splitpanes imports SvelteKit's browser-detection module; this // isn't a SvelteKit app, so point it at a plain shim (see the file). // Needs a real filesystem path (not the /src/... shorthand $lib uses) // so esbuild's dependency pre-bundler can resolve it too. '$app/environment': fileURLToPath(new URL('./src/lib/shims/app-environment.ts', import.meta.url)) } }, build: { outDir: 'dist', emptyOutDir: true }, optimizeDeps: { // svelte-splitpanes imports SvelteKit's $app/environment (aliased above // to a shim), but esbuild's dependency pre-bundler resolves that // differently and fails before the dev server even starts — skip // pre-bundling it so it goes through Vite's normal (alias-aware) // transform pipeline instead. exclude: ['svelte-splitpanes'] }, server: { proxy: { '/api': authProxy('http://localhost:8090'), // Production Caddy strips /agent before forwarding to nomos // (compose/caddy/Caddyfile.oikos handle_path /agent/*); match that // here so dev and prod agree on nomos's actual route paths. '/agent': authProxy('http://localhost:8092', (path) => path.replace(/^\/agent/, '')) } }, test: { environment: 'jsdom', globals: true, setupFiles: ['src/test-setup.ts'], include: ['src/**/*.{test,spec}.{ts,js}'] } })