From 4612f139686293e53caf31660cb2e24274dbac55 Mon Sep 17 00:00:00 2001 From: Christian Vidal Wolf Date: Wed, 20 May 2026 13:40:51 +0200 Subject: [PATCH] feat(dev): support Vercel serverless API handlers locally in Vite dev server --- vite.config.ts | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/vite.config.ts b/vite.config.ts index bb4e4fa..40d2a47 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,6 +4,14 @@ import path from 'path'; import {defineConfig, loadEnv} from 'vite'; import { getBcConfig, getBCToken, findItem, patchItemCpnpNo, fetchAllItems, buildWorkbook } from './bc-runtime.js'; import * as XLSX from 'xlsx'; +// @ts-ignore +import dropboxProxyHandler from './api/dropbox-proxy.js'; +// @ts-ignore +import dropboxSyncHandler from './api/dropbox-sync.js'; +// @ts-ignore +import backupHandler from './api/backup.js'; +// @ts-ignore +import usersAdminHandler from './api/users-admin.js'; async function readJsonBody(req: any): Promise { return await new Promise((resolve, reject) => { @@ -35,6 +43,58 @@ export default defineConfig(({mode}) => { const url = new URL(req.url || '/', 'http://localhost'); const config = getBcConfig(env); + // Populate process.env with loaded env variables for serverless handlers + Object.assign(process.env, env); + + // Helper to adapt Node.js req/res to Vercel signature + const adaptVercelHandler = async (handler: any) => { + (req as any).query = Object.fromEntries(url.searchParams.entries()); + try { + (req as any).body = await readJsonBody(req); + } catch { + (req as any).body = {}; + } + (res as any).status = (code: number) => { + res.statusCode = code; + return res; + }; + (res as any).json = (data: any) => { + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify(data)); + }; + (res as any).send = (data: any) => { + if (data instanceof Buffer) { + res.end(data); + } else if (typeof data === 'object') { + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify(data)); + } else { + res.end(data); + } + }; + await handler(req, res); + }; + + if (url.pathname === '/api/dropbox-proxy') { + await adaptVercelHandler(dropboxProxyHandler); + return; + } + + if (url.pathname === '/api/dropbox-sync') { + await adaptVercelHandler(dropboxSyncHandler); + return; + } + + if (url.pathname === '/api/backup') { + await adaptVercelHandler(backupHandler); + return; + } + + if (url.pathname === '/api/users-admin') { + await adaptVercelHandler(usersAdminHandler); + return; + } + if (url.pathname === '/api/bc-proxy') { if (req.method === 'OPTIONS') { res.statusCode = 204;