const {createServer} = require('http'); const bodyParser = require('body-parser'); const {invokeHookReduce} = require('@truss/comm'); const {ActionEmitter} = require('./index'); const debug = require('debug')('truss:emitters:http'); const parser = bodyParser.json(); module.exports = class HttpActionEmitter extends ActionEmitter { constructor(executors, listeners) { super(executors, listeners); this.server = createServer(); } listen() { const port = process.env.GATEWAY_PORT || 8000; this.server.listen(port); this.server.on('listening', () => { debug(`listening on port ${port}...`); }) this.server.on('request', (req, res) => { parser(req, res, () => { const method = req.method.toLowerCase(); const url = req.url; debug(`${method} ${url}`); // map to action const headers = { ...req.headers, ...{ connection: undefined, host: undefined, } }; const action = { type: undefined, payload: { headers: headers, method: method, url: url, } }; switch (method) { case 'post': // truss action if (url.startsWith('/truss/action/')) { action.type = url.substr('/truss/action/'.length); } // @truss/http-post else { action.type = '@truss/http-post'; } action.payload = req.body; break; default: // @truss/http-(get|delete|...) action.type = `@truss/http-${method}`; break; } this.processAction(action, res); })}); } onExecutorResponse(action, res, eres) { const {payload: {headers: actionHeaders}} = action; const {status, headers, response} = eres; const reduced$ = invokeHookReduce( '@truss/emitters/http', eres, actionHeaders ); reduced$.then(({status, headers, response}) => { res.writeHead(status || 200, headers); res.end(response); }); } onNoExecutor(action, res) { res.writeHead(501); res.end( '

501 Not Implemented

' ); } unlisten() { this.server.close(); } }