UNPKG

@dbs-portal/tool-mock

Version:

API mocking toolkit using MSW for DBS Portal development workflows

251 lines (243 loc) 7.87 kB
/** * Development server utilities for MSW integration */ import { setupMocks } from '../core/setup'; /** * Create development server configuration with MSW support */ export function createMSWDevServerConfig(config = {}) { const { port = 3000, host = 'localhost', https = false, cors = true, proxy = {}, mswConfig = {}, hotReload = {}, } = config; return { server: { port, host, https, cors, proxy, // Configure middleware for MSW middlewareMode: false, // Custom middleware configureServer: (server) => { // Setup MSW if enabled if (mswConfig.enabled !== false) { setupMSWMiddleware(server, mswConfig); } // Setup hot reload if enabled if (hotReload.enabled !== false) { setupHotReloadMiddleware(server, hotReload); } }, }, // Optimizations for development optimizeDeps: { include: ['msw'], exclude: ['@dbs-portal/tool-mock'], }, // Define environment variables define: { __MSW_ENABLED__: JSON.stringify(mswConfig.enabled !== false), __MSW_LOGGING__: JSON.stringify(mswConfig.logging !== false), }, }; } /** * Setup MSW middleware for development server */ function setupMSWMiddleware(server, config) { const { handlers = [], logging = true, delay = [100, 300] } = config; // Serve MSW service worker server.middlewares.use('/mockServiceWorker.js', (req, res) => { if (req.method === 'GET') { res.setHeader('Content-Type', 'application/javascript'); res.setHeader('Service-Worker-Allowed', '/'); const serviceWorkerContent = generateDevServiceWorkerContent(); res.end(serviceWorkerContent); if (logging) { console.log('MSW: Served service worker'); } } }); // Add MSW status endpoint server.middlewares.use('/api/__msw/status', (req, res) => { if (req.method === 'GET') { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ enabled: true, mode: 'development', handlersCount: handlers.length, delay, timestamp: new Date().toISOString(), })); } }); // Add MSW control endpoints server.middlewares.use('/api/__msw/reload', (req, res) => { if (req.method === 'POST') { // Trigger MSW reload server.ws.send({ type: 'custom', event: 'msw:reload', data: { timestamp: Date.now() }, }); res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ success: true })); if (logging) { console.log('MSW: Handlers reloaded'); } } }); if (logging) { console.log('MSW: Development middleware configured'); } } /** * Setup hot reload middleware for mock files */ function setupHotReloadMiddleware(server, config) { const { watchPaths = ['src/**/*mock*', 'src/**/*handler*'], debounceDelay = 300, } = config; let reloadTimeout = null; // Watch for file changes server.watcher.on('change', (filePath) => { const shouldReload = watchPaths.some((pattern) => { // Simple pattern matching (in real implementation, use glob) return filePath.includes(pattern.replace('*', '')); }); if (shouldReload) { // Debounce reload if (reloadTimeout) { clearTimeout(reloadTimeout); } reloadTimeout = setTimeout(() => { server.ws.send({ type: 'custom', event: 'msw:file-changed', data: { filePath, timestamp: Date.now() }, }); console.log(`MSW: Mock file changed: ${filePath}`); }, debounceDelay); } }); console.log('MSW: Hot reload middleware configured'); } /** * Generate service worker content for development */ function generateDevServiceWorkerContent() { return ` /** * MSW Development Service Worker */ importScripts('https://unpkg.com/msw@2.6.4/lib/mockServiceWorker.js'); // Development-specific features self.addEventListener('message', async function (event) { const { type, payload } = event.data; switch (type) { case 'MOCK_ACTIVATE': { console.log('MSW: Activating mock service worker'); self.registration.addEventListener('activate', () => { event.ports[0].postMessage({ type: 'MOCK_ACTIVATED' }); }); break; } case 'MOCK_DEACTIVATE': { console.log('MSW: Deactivating mock service worker'); await self.registration.unregister(); event.ports[0].postMessage({ type: 'MOCK_DEACTIVATED' }); break; } case 'MOCK_RELOAD': { console.log('MSW: Reloading handlers'); // Trigger reload self.clients.matchAll().then(clients => { clients.forEach(client => { client.postMessage({ type: 'MSW_RELOAD' }); }); }); break; } default: { // Forward to MSW break; } } }); // Log requests in development self.addEventListener('fetch', (event) => { if (event.request.url.includes('/api/')) { console.log('MSW: Intercepting request:', event.request.method, event.request.url); } }); console.log('MSW: Development service worker loaded'); `; } /** * Development server utilities */ export const devServerUtils = { /** * Create proxy configuration for API endpoints */ createApiProxy: (apiBaseUrl) => ({ '/api': { target: apiBaseUrl, changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ''), }, }), /** * Create CORS configuration for development */ createCorsConfig: (allowedOrigins = ['http://localhost:3000']) => ({ origin: allowedOrigins, methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'], credentials: true, }), /** * Create development environment variables */ createDevEnvVars: (config = {}) => ({ __DEV__: true, __MSW_ENABLED__: config.mswEnabled !== false, __MSW_LOGGING__: config.mswLogging !== false, __API_BASE_URL__: config.apiBaseUrl || '/api', }), }; /** * Start development server with MSW */ export async function startDevServerWithMSW(config = {}) { console.log('Starting development server with MSW support...'); // Setup MSW first if (config.mswConfig?.enabled !== false) { await setupMocks({ config: { enabled: true, mode: 'development', logging: config.mswConfig?.logging !== false, delay: config.mswConfig?.delay || [100, 300], }, handlers: config.mswConfig?.handlers || [], }); } console.log('MSW development server ready!'); } /** * Development server health check */ export function createHealthCheck() { return { '/api/__health': (_req, res) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify({ status: 'healthy', timestamp: new Date().toISOString(), services: { msw: true, api: true, }, })); }, }; } //# sourceMappingURL=dev-server.js.map