import express from 'express'; import morgan from 'morgan'; import http from 'http'; import asyncHandler from 'express-async-handler'; import assert from 'assert'; import { homepage } from './constants.js'; import logger from './logger.js'; export default ({ port, onKeyboardAction }: { port: number, onKeyboardAction: (a: string) => Promise, }) => { const app = express(); // https://expressjs.com/en/resources/middleware/morgan.html const morganFormat = ':remote-addr :method :url HTTP/:http-version :status - :response-time ms'; // https://stackoverflow.com/questions/27906551/node-js-logging-use-morgan-and-winston app.use(morgan(morganFormat, { stream: { write: (message) => logger.info(message.trim()) }, })); const apiRouter = express.Router(); app.get('/', (_req, res) => res.send(`See ${homepage}`)); app.use('/api', apiRouter); apiRouter.post('/shortcuts/:action', express.json(), asyncHandler(async (req, res) => { // eslint-disable-next-line prefer-destructuring const action = req.params['action']; assert(action != null); await onKeyboardAction(action); res.end(); })); const server = http.createServer(app); server.on('error', (err) => logger.error('http server error', err)); const startHttpServer = async () => new Promise((resolve, reject) => { // force ipv4 const host = '127.0.0.1'; server.listen(port, host, () => { logger.info('HTTP API listening on', `http://${host}:${port}/`); // @ts-expect-error tod resolve(); }); server.once('error', reject); }); return { startHttpServer, }; };