react-middleware
Version:
Connect middleware for serving React components from a standard folder structure.
151 lines (120 loc) • 4.55 kB
JavaScript
;
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'; /* eslint global-require:0 */
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 = void 0;
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;
}
return undefined;
};
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;
};
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 host = req.get('host');
var params = Object.keys(req.params).forEach(function (key) {
req.params[key] = util.toType(req.params[key]);
});
var url = {
params: params,
path: req.url,
pathname: _url2.default.parse(req.url).pathname,
query: req.query,
pattern: route.pattern,
protocol: req.secure ? 'https:' : 'http',
host: host.split(':')[0],
port: host.split(':')[1]
};
var args = { url: url };
route = asValues(route, args);
// Prepare the page body.
var requestData = { url: url };
var layoutData = getData(route, url);
var pageProps = route.props || {};
var pageData = pageProps.data || layoutData;
if (pageData) {
pageProps.data = pageData;
}
pageProps.request = requestData;
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 },
request: requestData
};
// Convert the page-layout into HTML.
var layout = _react2.default.createElement(getLayout(route), layoutProps);
var html = _server2.default.renderToStaticMarkup(layout);
res.send(html);
};
// Register 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);
});
});
};
//# sourceMappingURL=router-html.js.map