import path from "path" import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { loadEnv } from "vite" import fs from 'fs-extra' import { execSync } from 'child_process' // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), "") const isDev = mode === 'development' return { plugins: [ react(), { name: 'copy-build', closeBundle: async () => { if (!isDev && process.env.COPY_BUILD === 'true') { const sourcePath = path.resolve(__dirname, 'build/'); // Check if we should use rsync (for remote deployment) const useRsync = process.env.DEPLOY_TARGET; if (useRsync) { // Use rsync over SSH - much faster than sshfs copying const deployTarget = process.env.DEPLOY_TARGET; const targetPath = process.env.DEPLOY_PATH || '/var/www/html/inventory/inventory-server/frontend'; try { console.log(`Deploying to ${deployTarget}:${targetPath}...`); // Delete remote directory first, then sync execSync(`ssh ${deployTarget} "rm -rf ${targetPath}"`, { stdio: 'inherit' }); execSync(`ssh ${deployTarget} "mkdir -p ${targetPath}"`, { stdio: 'inherit' }); execSync(`rsync -avz --delete ${sourcePath} ${deployTarget}:${targetPath}/`, { stdio: 'inherit' }); console.log('✓ Build deployed'); } catch (error) { console.error('Error deploying build files:', error); process.exit(1); } } else { // Local copy (original behavior) const targetPath = path.resolve(__dirname, '../inventory-server/frontend/build'); try { await fs.ensureDir(path.dirname(targetPath)); await fs.remove(targetPath); await fs.copy(sourcePath, targetPath); console.log('✓ Build copied to inventory-server/frontend/build'); } catch (error) { console.error('Error copying build files:', error); process.exit(1); } } } } } ], define: { 'process.env.NODE_ENV': JSON.stringify(mode) }, resolve: { alias: { "@": path.resolve(__dirname, "./src"), }, }, server: { host: "0.0.0.0", port: 5175, proxy: { "/api-testv2": { target: "https://work-test-backend.acherryontop.com", changeOrigin: true, secure: true, cookieDomainRewrite: "localhost", rewrite: (path) => path.replace(/^\/api-testv2/, "/apiv2"), }, "/apiv2": { target: "https://backend.acherryontop.com", changeOrigin: true, secure: true, cookieDomainRewrite: "localhost", }, "/login": { target: "https://backend.acherryontop.com", changeOrigin: true, secure: true, cookieDomainRewrite: "localhost", }, "/api/aircall": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, "/api/klaviyo": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, "/api/meta": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, "/api/gorgias": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, "/api/dashboard-analytics": { target: "https://acot.site", changeOrigin: true, secure: false, cookieDomainRewrite: { "inventory.kent.pw": "localhost" }, }, "/api/typeform": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, "/api/acot": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, "/api/clarity": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, "/api": { target: "https://acot.site", changeOrigin: true, secure: false, ws: true, xfwd: true, cookieDomainRewrite: "", withCredentials: true, rewrite: (path) => path.replace(/^\/api/, "/api"), configure: (proxy, _options) => { proxy.on("error", (err, req, res) => { console.error("API proxy error:", err) res.writeHead(500, { "Content-Type": "application/json", }) res.end( JSON.stringify({ error: "Proxy Error", message: err.message }) ) }) }, }, "/dashboard-auth": { target: "https://acot.site", changeOrigin: true, secure: false, ws: true, rewrite: (path) => path.replace("/dashboard-auth", "/auth"), }, "/auth-inv": { target: "https://acot.site", changeOrigin: true, secure: false, ws: true, xfwd: true, cookieDomainRewrite: { "inventory.kent.pw": "localhost" }, withCredentials: true, onProxyReq: (proxyReq, req) => { // Add origin header to match CORS policy proxyReq.setHeader('Origin', 'http://localhost:5175'); }, rewrite: (path) => path.replace(/^\/auth-inv/, "/auth-inv"), configure: (proxy, _options) => { proxy.on("error", (err, req, res) => { console.error("Auth proxy error:", err) res.writeHead(500, { "Content-Type": "application/json", }) res.end( JSON.stringify({ error: "Proxy Error", message: err.message }) ) }) }, }, "/chat-api": { target: "https://acot.site", changeOrigin: true, secure: false, ws: true, xfwd: true, cookieDomainRewrite: "", withCredentials: true, rewrite: (path) => path, configure: (proxy, _options) => { proxy.on("error", (err, req, res) => { console.error("Chat API proxy error:", err) res.writeHead(500, { "Content-Type": "application/json", }) res.end( JSON.stringify({ error: "Proxy Error", message: err.message }) ) }) }, }, "/uploads": { target: "https://acot.site", changeOrigin: true, secure: false, rewrite: (path) => path, }, }, }, build: { outDir: "build", sourcemap: true, chunkSizeWarningLimit: 1000, rollupOptions: { output: { manualChunks: { // Simple static chunking approach - safer than function-based chunking 'react-vendor': ['react', 'react-dom', 'react-router-dom'], 'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu', 'lucide-react'], 'query-vendor': ['@tanstack/react-query'], }, }, }, }, } })