import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { VitePWA } from 'vite-plugin-pwa' import { createReadStream } from 'fs' import { resolve } from 'path' // Serve maplibre CSP worker from node_modules in dev (production Dockerfile copies it to public/) const serveMaplibreWorker = { name: 'serve-maplibre-csp-worker', configureServer(server: { middlewares: { use: (path: string, handler: (req: unknown, res: { setHeader: (k: string, v: string) => void }, next: () => void) => void) => void } }) { server.middlewares.use('/maplibre-gl-csp-worker.js', (_req, res) => { res.setHeader('Content-Type', 'application/javascript') createReadStream(resolve('node_modules/maplibre-gl/dist/maplibre-gl-csp-worker.js')).pipe(res as unknown as NodeJS.WritableStream) }) }, } export default defineConfig({ plugins: [ react(), serveMaplibreWorker, VitePWA({ registerType: 'autoUpdate', workbox: { globPatterns: ['**/*.{js,css,html,ico,png,svg}'], runtimeCaching: [ { urlPattern: /^\/tiles\//, handler: 'CacheFirst', options: { cacheName: 'pmtiles-cache', expiration: { maxEntries: 10, maxAgeSeconds: 7 * 24 * 60 * 60 }, }, }, { urlPattern: /^\/api\//, handler: 'NetworkFirst', options: { cacheName: 'api-cache' }, }, ], }, manifest: { name: 'TruckNet', short_name: 'TruckNet', description: 'The Modern CB Radio for Truck Drivers', theme_color: '#1a1a2e', background_color: '#1a1a2e', display: 'fullscreen', orientation: 'any', icons: [ { src: '/icon-192.png', sizes: '192x192', type: 'image/png' }, { src: '/icon-512.png', sizes: '512x512', type: 'image/png' }, ], }, }), ], build: { rollupOptions: { external: ['maplibre-gl'], }, }, server: { proxy: { '/api': { target: `http://${process.env.API_HOST ?? 'localhost'}:3000`, rewrite: (p) => p.replace(/^\/api/, '') }, '/auth': { target: `http://${process.env.AUTH_HOST ?? 'localhost'}:3001`, rewrite: (p) => p.replace(/^\/auth/, '') }, '/tiles': { target: `http://${process.env.TILES_HOST ?? 'localhost'}:80` }, }, }, })