// @ts-expect-error Vite config executes in Node; the application tsconfig intentionally excludes Node globals. import { readFile, writeFile } from 'node:fs/promises' // @ts-expect-error Vite config executes in Node; the application tsconfig intentionally excludes Node globals. import { resolve } from 'node:path' import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' declare const process: { cwd(): string } const securityHeaders = { 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp', 'Cross-Origin-Resource-Policy': 'same-origin', 'Content-Security-Policy': "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' data: blob:; font-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'none'", 'Permissions-Policy': 'camera=(), microphone=(), geolocation=(), payment=()', } const serviceWorkerPrecachePlugin = () => ({ name: 'bitbybit-service-worker-precache', async writeBundle(options: { dir?: string }, bundle: Record) { const outputDirectory = options.dir ?? resolve(process.cwd(), 'dist') const shell = ['/', '/index.html', '/manifest.webmanifest', '/vendor/camotics/camotics-sweep.wasm', ...Object.keys(bundle).filter((fileName) => fileName.startsWith('assets/')).map((fileName) => `/${fileName}`)] const templatePath = resolve(process.cwd(), 'public/sw.js') const outputPath = resolve(outputDirectory, 'sw.js') const template = await readFile(templatePath, 'utf8') const generated = template.replace(/const SHELL = \[[^\n]*\]/, `const SHELL = ${JSON.stringify([...new Set(shell)])}`) await writeFile(outputPath, generated) }, }) export default defineConfig({ plugins: [react(), serviceWorkerPrecachePlugin()], server: { port: 5173, strictPort: false, proxy: { '/linuxcnc-machine': { target: 'https://localhost:5190', changeOrigin: true, secure: false, rewrite: (path: string) => path.replace(/^\/linuxcnc-machine/, ''), }, }, headers: { 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp', }, watch: { ignored: ['**/.cache/**', '**/.runtime/**', '**/cnc_wams_gpt6/**', '**/CAMotics/**', '**/OpenCAMLib/**'], }, }, preview: { headers: securityHeaders, }, optimizeDeps: { exclude: ['@sqlite.org/sqlite-wasm', '@bitbybit-dev/occt', '@bitbybit-dev/occt-worker'], }, worker: { format: 'es', }, build: { chunkSizeWarningLimit: 600, rollupOptions: { output: { manualChunks: { three: ['three'], }, }, }, }, })