UNPKG

mockaton

Version:
100 lines (77 loc) 2.68 kB
import { createServer } from 'node:http' import pkgJSON from '../../package.json' with { type: 'json' } import { logger } from './utils/logger.js' import { setCorsHeaders, isPreflight } from './utils/http-cors.js' import { BodyReaderError, hasControlChars } from './utils/http-request.js' import { setHeaders, sendNoContent, sendInternalServerError, sendUnprocessable, sendTooLongURI, sendBadRequest } from './utils/http-response.js' import { API } from './ApiConstants.js' import { config, setup } from './config.js' import { apiPatchReqs, apiGetReqs } from './Api.js' import { dispatchMock } from './MockDispatcher.js' import { dispatchStatic } from './StaticDispatcher.js' import * as staticCollection from './staticCollection.js' import * as mockBrokerCollection from './mockBrokersCollection.js' import { watchDevSPA } from './WatcherDevClient.js' import { watchMocksDir, watchStaticDir } from './Watcher.js' export function Mockaton(options) { return new Promise((resolve, reject) => { setup(options) mockBrokerCollection.init() staticCollection.init() if (config.watcherEnabled) { watchMocksDir() watchStaticDir() } if (config.hotReload) watchDevSPA() const server = createServer(onRequest) server.on('error', reject) server.listen(config.port, config.host, () => { const url = `http://${server.address().address}:${server.address().port}` const dashboardUrl = url + API.dashboard logger.info('Listening', url) logger.info('Dashboard', dashboardUrl) config.onReady(dashboardUrl) resolve(server) }) }) } async function onRequest(req, response) { response.on('error', logger.warn) setHeaders(response, ['Server', `Mockaton ${pkgJSON.version}`]) setHeaders(response, config.extraHeaders) const url = req.url || '' if (url.length > 2048) { sendTooLongURI(response) return } if (hasControlChars(url)) { sendBadRequest(response) return } try { if (config.corsAllowed) setCorsHeaders(req, response, config) const { method } = req const { pathname } = new URL(url, 'http://_') if (isPreflight(req)) sendNoContent(response) else if (method === 'PATCH' && apiPatchReqs.has(pathname)) await apiPatchReqs.get(pathname)(req, response) else if (method === 'GET' && apiGetReqs.has(pathname)) apiGetReqs.get(pathname)(req, response) else if (method === 'GET' && staticCollection.brokerByRoute(pathname)) await dispatchStatic(req, response) else await dispatchMock(req, response) } catch (error) { if (error instanceof BodyReaderError) sendUnprocessable(response, `${error.name}: ${error.message}`) else sendInternalServerError(response, error) } }