import { rmSync } from 'node:fs' import { fileURLToPath } from 'node:url' import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { VitePWA } from 'vite-plugin-pwa' // `vite build --mode native` builds the UI bundled inside the Capacitor app: // no service worker (the app ships its own files) and a separate output dir so // it never mixes with the web build served by the venue's nginx. export default defineConfig(({ mode }) => { const native = mode === 'native' return { build: { outDir: native ? 'dist-native' : 'dist', }, server: { host: '0.0.0.0', port: 5173, allowedHosts: ['all'], proxy: { '/api/ws': { target: 'ws://localhost:8000', ws: true, changeOrigin: true, }, '/api': { target: 'http://localhost:8000', changeOrigin: true, }, }, }, plugins: [ react(), // public/downloads/ holds the APK + UI bundle that venue servers hand out. // It belongs in the web build only — never inside the app or its bundle. native && { name: 'xenia-strip-downloads', closeBundle() { rmSync(fileURLToPath(new URL('./dist-native/downloads', import.meta.url)), { recursive: true, force: true }) }, }, VitePWA({ disable: native, registerType: 'prompt', manifest: { name: 'Xenia', short_name: 'Xenia', start_url: '/', display: 'standalone', background_color: '#0f172a', theme_color: '#0f172a', icons: [ { src: '/icons/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'any' }, { src: '/icons/icon-192.png', sizes: '192x192', type: 'image/png', purpose: 'maskable' }, { src: '/icons/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'any' }, { src: '/icons/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }, ], }, workbox: { globPatterns: ['**/*.{js,css,html,ico,png,svg}'], runtimeCaching: [], }, devOptions: { enabled: false, }, }), ], } })