AXERA-TECH/lite_webui
13
1import { defineConfig } from 'vite';2import http from 'node:http';3import https from 'node:https';4 5/**6 * Dev-only CORS proxy middleware.7 * Browser fetches /lw-proxy/<path> with X-LW-Target header → Vite server forwards to target (no CORS).8 */9const lwProxyPlugin = {10 name: 'lw-proxy',11 configureServer(server) {12 server.middlewares.use('/lw-proxy', (req, res) => {13 const target = req.headers['x-lw-target'];14 if (!target) {15 res.writeHead(400, { 'Content-Type': 'application/json' });16 res.end(JSON.stringify({ error: 'Missing X-LW-Target header' }));17 return;18 }19 20 let targetUrl;21 try {22 // req.url is the path AFTER /lw-proxy (Connect strips the mount point)23 targetUrl = new URL(req.url ?? '/', target);24 } catch {25 res.writeHead(400, { 'Content-Type': 'application/json' });26 res.end(JSON.stringify({ error: 'Invalid target URL' }));27 return;28 }29 30 const httpModule = targetUrl.protocol === 'https:' ? https : http;31 32 // Forward headers, stripping browser/CORS-related ones33 const fwdHeaders = {};34 for (const [k, v] of Object.entries(req.headers)) {35 const kl = k.toLowerCase();36 if (kl === 'x-lw-target' || kl === 'host' || kl === 'origin' || kl === 'referer') continue;37 fwdHeaders[k] = v;38 }39 fwdHeaders['host'] = targetUrl.host;40 41 const options = {42 hostname: targetUrl.hostname,43 port: targetUrl.port || (targetUrl.protocol === 'https:' ? 443 : 80),44 path: targetUrl.pathname + (targetUrl.search || ''),45 method: req.method,46 headers: fwdHeaders,47 };48 49 const proxyReq = httpModule.request(options, (proxyRes) => {50 res.writeHead(proxyRes.statusCode ?? 200, proxyRes.headers);51 proxyRes.pipe(res); // stream response directly (supports SSE)52 });53 54 proxyReq.on('error', (err) => {55 if (!res.headersSent) {56 res.writeHead(502, { 'Content-Type': 'application/json' });57 }58 res.end(JSON.stringify({ error: err.message }));59 });60 61 req.pipe(proxyReq); // forward request body (needed for POST /v1/chat/completions)62 });63 },64};65 66export default defineConfig({67 plugins: [lwProxyPlugin],68 build: {69 target: 'esnext',70 minify: 'esbuild',71 chunkSizeWarningLimit: 600,72 rollupOptions: {73 output: {74 manualChunks(id) {75 if (id.includes('highlight.js')) return 'hljs';76 if (id.includes('marked')) return 'marked';77 },78 },79 },80 },81 test: {82 environment: 'jsdom',83 globals: true,84 setupFiles: ['./tests/setup.js'],85 },86});87 