// defineConfig comes from vitest/config (a superset of vite's) so the `test` // block typechecks; vitest itself must be pointed at this file explicitly // (package.json test script) because it only auto-discovers vite.config.*. import { defineConfig } from "vitest/config"; import type { Plugin } from "vite"; import { fileURLToPath, URL } from "node:url"; import { TanStackRouterVite } from "@tanstack/router-plugin/vite"; import react from "@vitejs/plugin-react"; import tailwindcss from "@tailwindcss/vite"; // CSP for the built renderer. The daemon is loopback-only, so network access is // pinned to 127.0.0.1 (REST + SSE over http, terminal mux over ws). Injected at // build time rather than written into index.html because the dev server needs // inline scripts (react-refresh preamble) that a static meta tag would block. const CONTENT_SECURITY_POLICY = [ "default-src 'self'", "script-src 'self'", "style-src 'self' 'unsafe-inline'", "img-src 'self' data:", "font-src 'self' data:", "connect-src 'self' http://127.0.0.1:* ws://127.0.0.1:*", "object-src 'none'", "base-uri 'self'", "frame-src 'none'", ].join("; "); const injectCspMeta: Plugin = { name: "inject-csp-meta", apply: "build", transformIndexHtml() { return [ { tag: "meta", attrs: { "http-equiv": "Content-Security-Policy", content: CONTENT_SECURITY_POLICY }, injectTo: "head-prepend", }, ]; }, }; export default defineConfig({ // "@/" → the renderer root (src/renderer), the shadcn/ui import convention. resolve: { alias: { "@": fileURLToPath(new URL("./src/renderer", import.meta.url)), }, }, // Dev proxy for VITE_NO_ELECTRON=1 browser preview — forwards /api and /mux // to the daemon so the renderer can be tested against a running daemon from // a plain browser without an Electron shell. server: { proxy: { "/api": { target: process.env.AO_DEV_API_TARGET ?? "http://127.0.0.1:3001", changeOrigin: false, }, "/mux": { target: process.env.AO_DEV_API_TARGET ?? "http://127.0.0.1:3001", changeOrigin: false, ws: true, }, }, }, plugins: [ TanStackRouterVite({ routesDirectory: "./src/renderer/routes", generatedRouteTree: "./src/renderer/routeTree.gen.ts", target: "react", autoCodeSplitting: true, }), react(), tailwindcss(), injectCspMeta, ], test: { environment: "jsdom", exclude: ["node_modules/**", "dist/**", "dist-electron/**", "e2e/**"], globals: true, setupFiles: "./src/renderer/test/setup.ts", }, });