import { defineConfig, loadEnv, type Plugin } from "vite"; import react from "@vitejs/plugin-react"; import path from "node:path"; function apiChatPlugin(): Plugin { return { name: "api-chat-middleware", configureServer(server) { server.middlewares.use("/api/chat", async (req, res, next) => { if (req.method !== "POST") return next(); try { const mod = await server.ssrLoadModule("/api/chat.ts"); const handler = (mod as { POST: (req: Request) => Promise }) .POST; const chunks: Buffer[] = []; for await (const c of req) chunks.push(c as Buffer); const body = chunks.length ? Buffer.concat(chunks) : undefined; const headers = new Headers(); for (const [k, v] of Object.entries(req.headers)) { if (Array.isArray(v)) headers.set(k, v.join(", ")); else if (typeof v === "string") headers.set(k, v); } const fetchReq = new Request( `http://localhost${req.url ?? "/api/chat"}`, { method: "POST", headers, body }, ); const response = await handler(fetchReq); res.statusCode = response.status; response.headers.forEach((value, key) => res.setHeader(key, value)); if (response.body) { const reader = response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; res.write(Buffer.from(value)); } } res.end(); } catch (err) { console.error("/api/chat error", err); res.statusCode = 500; res.end(err instanceof Error ? err.message : "internal error"); } }); }, }; } export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), ""); for (const k of Object.keys(env)) { if (process.env[k] === undefined) process.env[k] = env[k]; } return { plugins: [react(), apiChatPlugin()], resolve: { alias: { "@": path.resolve(__dirname, "."), "~": path.resolve(__dirname, "."), }, }, server: { port: 3001, }, }; });