import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import { VitePWA } from 'vite-plugin-pwa'; export default defineConfig({ plugins: [ react(), VitePWA({ registerType: 'autoUpdate', // ⚠️ CRITICAL (T-03-20): generateSW migrated to injectManifest so the custom // sw.ts can add push + notificationclick handlers while preserving the /callback // denylist. The denylist is re-implemented explicitly in src/sw.ts. strategies: 'injectManifest', srcDir: 'src', filename: 'sw.ts', // rolldownOptions: force the SW output to IIFE so the output file is sw.js // (not sw.mjs). Vite 8 + vite-plugin-pwa 1.3.x defaults to ES module SW format // when the source is .ts, producing sw.mjs. The registerSW.js generated by // the plugin registers '/sw.js', so the filenames must match. rolldownOptions: { output: { format: 'iife', }, }, injectManifest: { // Prevent /callback-related URLs from appearing in the precache manifest. globIgnores: ['**/node_modules/**', '**/callback**'], }, manifest: { name: 'FamilySync', short_name: 'FamilySync', description: 'Family calendar and lists', theme_color: '#4A90D9', background_color: '#ffffff', display: 'standalone', scope: '/', start_url: '/', icons: [ { src: '/icon-192.png', sizes: '192x192', type: 'image/png' }, { src: '/icon-512.png', sizes: '512x512', type: 'image/png' }, { src: '/icon-512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }, ], }, }), ], server: { // Allow the internal split-DNS domain (and any subdomain) to reach the dev // server through the reverse proxy / tunnel. A leading dot matches the apex // and all subdomains. Dev-server only — production builds ignore this. allowedHosts: ['.bergerhouse.net'], proxy: { '/health': 'http://localhost:3000', '/api': 'http://localhost:3000', '/callback': 'http://localhost:3000', }, }, });