// `npm run dev:mock`: no network, no login. Serves a fixture page and the mock API. import type { Plugin } from 'vite' import { createMockCms } from '../mock/server' import { injectDevEntry } from './shared' export function cmsMockPlugin(): Plugin { // CMS_MOCK_AUTH=1 makes the mock require the device-login flow (approve on the mock /device page) so the login UI can be developed. const cms = createMockCms(process.env.CMS_MOCK_AUTH ? { auth: true } : {}) return { name: 'cms-mock', configureServer(server) { server.middlewares.use(async (req, res, next) => { const url = req.url ?? '/' if (url.startsWith('/__dev/')) return void ((res.statusCode = 204), res.end()) const isApi = url.startsWith('/api/') const isReset = url === '/__mock/reset' && req.method === 'POST' const isMock = url === '/device' || url.startsWith('/device?') || url === '/__mock/approve' const isPage = req.method === 'GET' && !/^\/(@|src\/|node_modules\/|mock\/|__)/.test(url) && String(req.headers.accept ?? '').includes('text/html') if (!isApi && !isReset && !isPage && !isMock) return next() if (isReset) { cms.reset() res.statusCode = 204 return void res.end() } const chunks: Buffer[] = [] for await (const c of req) chunks.push(c as Buffer) const body = chunks.length ? Buffer.concat(chunks) : undefined const resp = await cms.handle( new Request(new URL(url, `http://${req.headers.host ?? 'localhost'}`), { method: req.method, headers: req.headers as Record, body: body && req.method !== 'GET' ? body : undefined }), ) res.statusCode = resp.status resp.headers.forEach((v, k) => res.setHeader(k, v)) let text = await resp.text() if (resp.headers.get('x-cms-page')) text = await server.transformIndexHtml(url, injectDevEntry(text)) res.end(text) }) }, } }