UNPKG

react-middleware

Version:

Connect middleware for serving React components from a standard folder structure.

141 lines (111 loc) 4.22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _ramda = require("ramda"); var _ramda2 = _interopRequireDefault(_ramda); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _server = require("react-dom/server"); var _server2 = _interopRequireDefault(_server); var _fsExtra = require("fs-extra"); var _fsExtra2 = _interopRequireDefault(_fsExtra); var _path = require("path"); var _path2 = _interopRequireDefault(_path); var _url = require("url"); var _url2 = _interopRequireDefault(_url); var _jsUtil = require("js-util"); var util = _interopRequireWildcard(_jsUtil); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var NODE_ENV = process.env.NODE_ENV || "development"; var asValues = function asValues(obj, args) { var result = _ramda2.default.clone(obj); Object.keys(obj).forEach(function (key) { var value = obj[key]; if (_ramda2.default.is(Function, value)) { result[key] = value(args); // Convert the function into a value. } else if (_ramda2.default.is(Object, value)) { result[key] = asValues(value, args); // <== RECURSION. } }); return result; }; var getFilePath = function getFilePath(basePath, name, extension) { var path = undefined; name = name.charAt(0).toUpperCase() + name.slice(1); // Capitalize the file/folder name. // Look first for the existence of a stand-alone file. path = _path2.default.join(basePath, name + "." + extension); if (_fsExtra2.default.existsSync(path)) { return path; } // Look for the file within a folder. path = _path2.default.join(basePath, name, name + "." + extension); if (_fsExtra2.default.existsSync(path)) { return path; } }; exports.default = function (middleware, paths, routes, data) { var getLayout = function getLayout(route) { var layoutName = route.layout || "Html"; var path = getFilePath(paths.layouts, layoutName, "jsx"); if (!path) { throw new Error("A layout named '" + layoutName + "' does not exist."); } return require(path).default; }; var getPage = function getPage(route) { var pageName = route.page; var path = getFilePath(paths.pages, pageName, "jsx"); if (!path) { throw new Error("A page named '" + pageName + "' does not exist."); } return require(path).default; }; var getData = function getData(route, url) { return _ramda2.default.is(Function, data) ? data({ route: route, url: url }) : data; }; var render = function render(req, res, route) { // Setup initial conditions. var params = Object.keys(req.params).map(function (key) { req.params[key] = util.toType(req.params[key]); }); var url = { path: req.url, pathname: _url2.default.parse(req.url).pathname, query: req.query, pattern: route.pattern, params: params }; var args = { url: url }; route = asValues(route, args); // Prepare the page body. var layoutData = getData(route, url); var pageProps = route.props || {}; var pageData = pageProps.data || layoutData; if (pageData) { pageProps.data = pageData; } var pageBody = _react2.default.createElement(getPage(route), pageProps); // Prepare the root <Html> page props. var layoutProps = { title: route.title, body: pageBody, data: layoutData, env: NODE_ENV, page: { name: route.page } }; // Convert the page-layout into HTML. var layout = _react2.default.createElement(getLayout(route), layoutProps); var html = _server2.default.renderToStaticMarkup(layout); res.send(html); }; // Regsiter each route as a GET handler. Object.keys(routes).forEach(function (pattern) { var route = routes[pattern]; route.pattern = pattern; middleware.get(pattern, function (req, res) { render(req, res, route); }); }); };