UNPKG

@b1kt0p/claudia-api-webpack

Version:
142 lines (141 loc) 4.44 kB
#!/usr/bin/env node "use strict"; var _fs = _interopRequireDefault(require("fs")); var _path = _interopRequireDefault(require("path")); var _http = _interopRequireDefault(require("http")); var _https = _interopRequireDefault(require("https")); var _commander = require("commander"); var _express = _interopRequireDefault(require("express")); var _cors = _interopRequireDefault(require("cors")); var _bodyParser = _interopRequireDefault(require("body-parser")); var _webpack = _interopRequireDefault(require("webpack")); var _pathParser = require("path-parser"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const port = 3000; const program = new _commander.Command(); program.requiredOption('--config <config>', 'Specify webpack config file').option('-p --port [port]', `Specify port to use [${port}]`, port).option('--cert [cert]', 'Specify certificate').option('--no-cors', 'Disable default cors').option('--key [key]', 'Specify key'); program.parse(process.argv); const options = program.opts(); if (!options.config || (options.cert || options.key) && !(options.cert && options.key)) { program.outputHelp(); process.exit(1); } const config = require(_path.default.join(process.cwd(), options.config)); const compiler = (0, _webpack.default)(config); compiler.hooks.assetEmitted.tap('claudia-api-webpack', (file, { content }) => { if (config.output.filename == file) { console.log('Reload claudia app...'); reloadClaudiaApp(content.toString(), file); } }); compiler.watch({}, (error, stats) => { console.log(stats.toString({ colors: true })); }); let claudiaApp = null; let routes = null; function reloadClaudiaApp(source, filename) { try { const m = new module.constructor(); m.paths = module.paths; m._compile(source, filename); claudiaApp = m.exports; const apiConfig = claudiaApp.apiConfig(); routes = getRoutes(apiConfig.routes); } catch (error) { routes = []; console.error('Failed to compile module', error); } } const app = (0, _express.default)(); if (options.cors) { app.use((0, _cors.default)()); } app.use(_bodyParser.default.text({ extended: true, limit: '50mb' })); app.use(_bodyParser.default.urlencoded({ extended: true, limit: '50mb' })); app.use(_bodyParser.default.json({ limit: '50mb' })); app.all("*", (req, res) => { var _claudiaApp; const params = getParams(req, routes); (_claudiaApp = claudiaApp) === null || _claudiaApp === void 0 || _claudiaApp.proxyRouter(params, { done: makeHandleResponse(res) }); }); let server; if (options.cert && options.key) { const key = _fs.default.readFileSync(options.key); const cert = _fs.default.readFileSync(options.cert); server = _https.default.createServer({ key, cert }, app); } else { server = _http.default.createServer(app); } server.listen(options.port, function () { console.log(`Server listening on port ${options.port}.`); }); function getPathParams(req, routes) { const parsedPath = req._parsedUrl.pathname; for (const route of routes) { const isSupported = route.supportedMethods.indexOf(req.method) !== -1; const pathParameters = route.path.test(parsedPath); if (isSupported && pathParameters) { return { resourcePath: route.resourcePath, pathParameters }; } } return { resourcePath: parsedPath, pathParameters: {} }; } function getParams(req, routes) { const pathParams = getPathParams(req, routes); return { requestContext: { resourcePath: pathParams.resourcePath, httpMethod: req.method }, headers: req.headers, queryStringParameters: req.query, body: req.body, pathParameters: pathParams.pathParameters }; } function getRoutes(routesObj) { const routePaths = Object.keys(routesObj); return routePaths.map(function (routePath) { const supportedMethods = Object.keys(routesObj[routePath] || {}); const route = `/${routePath}`; return { resourcePath: route, supportedMethods, path: _pathParser.Path.createPath(route.replace(/{(.+?)}/g, ':$1')) }; }); } function makeHandleResponse(res) { return function (err, response) { if (err) { const body = { message: err.message }; return res.status(500).send(body); } return res.set(response.headers || {}).status(response.statusCode || 200).send(response.body || {}); }; }