UNPKG

hem

Version:

stitches CommonJS, and ties up other lose ends of web-app development.

192 lines (176 loc) 6.41 kB
// Generated by CoffeeScript 1.12.7 (function() { var checkForRedirect, connect, createRoutingProxy, fs, http, httpProxy, log, mime, patchServerResponseForRedirects, server, utils; connect = require('connect'); mime = require('connect')["static"].mime; httpProxy = require('http-proxy'); http = require('http'); fs = require('fs'); utils = require('./utils'); log = require('./log'); server = {}; server.start = function(hem) { var app, options; app = connect(); app.use(server.middleware(hem)); options = hem.options.hem; if (options.host === "*") { http.createServer(app).listen(options.port); } else { http.createServer(app).listen(options.port, options.host); } return app; }; server.middleware = function(hem) { var app, backend, display, i, j, k, l, len, len1, len2, len3, options, pkg, ref, ref1, ref2, ref3, ref4, route, statics, value; backend = connect(); options = hem.options.hem; statics = []; ref = options != null ? options["static"] : void 0; for (route in ref) { value = ref[route]; statics.push({ url: route, path: value }); } ref1 = hem.apps; for (i = 0, len = ref1.length; i < len; i++) { app = ref1[i]; log.info("> Apply route mappings for application: <green>" + app.name + "</green>"); ref2 = app.packages; for (j = 0, len1 = ref2.length; j < len1; j++) { pkg = ref2[j]; if (options.baseAppRoute) { pkg.route = utils.cleanRoute(options.baseAppRoute, pkg.route); } log.info(" - Mapping route <yellow>" + pkg.route + "</yellow> to <yellow>" + pkg.target + "</yellow>"); } ref3 = app["static"]; for (k = 0, len2 = ref3.length; k < len2; k++) { route = ref3[k]; if (options.baseAppRoute) { route.url = utils.cleanRoute(options.baseAppRoute, route.url); } log.info(" - Mapping static <yellow>" + route.url + "</yellow> to <yellow>" + route.path + "</yellow>"); statics.push(route); } } for (l = 0, len3 = statics.length; l < len3; l++) { route = statics[l]; if (!fs.existsSync(route.path)) { log.errorAndExit("The resource <yellow>" + route.path + "</yellow> not found for static mapping <yellow>" + route.url + "</yellow>"); } if (fs.lstatSync(route.path).isDirectory()) { backend.use(route.url, checkForRedirect()); backend.use(route.url, connect["static"](route.path)); } else { backend.use(route.url, (function(route) { return function(req, res) { return fs.readFile(route.path, function(err, data) { if (err) { res.writeHead(404); return res.end(JSON.stringify(err)); } else { res.writeHead(200); return res.end(data); } }); }; })(route)); } } ref4 = options.proxy; for (route in ref4) { value = ref4[route]; display = value.host + ":" + (value.port || 80) + value.path; log.info("> Proxy requests <yellow>" + route + "</yellow> to <yellow>" + display + "</yellow>"); backend.use(route, createRoutingProxy(value, options.host + ":" + options.port)); } return function(req, res, next) { var len4, m, ref5, ref6, str, url; url = ((ref5 = require("url").parse(req.url)) != null ? ref5.pathname.toLowerCase() : void 0) || ""; if (url.match(/(\.js|\.css)$/)) { ref6 = hem.apps; for (m = 0, len4 = ref6.length; m < len4; m++) { app = ref6[m]; if (pkg = app.isMatchingRoute(url)) { str = pkg.build(); res.charset = 'utf-8'; res.setHeader('Content-Type', mime.lookup(pkg.target)); res.setHeader('Content-Length', Buffer.byteLength(str)); res.end((req.method === 'HEAD' && null) || str); return; } } } return backend.handle(req, res, next); }; }; checkForRedirect = function() { return function(req, res, next) { var pathname; pathname = require("url").parse(req.originalUrl).pathname; if (req.url === "/" && !utils.endsWith(pathname, "/")) { pathname += '/'; res.statusCode = 301; res.setHeader('Location', pathname); return res.end('Redirecting to ' + pathname); } else { return next(); } }; }; createRoutingProxy = function(options, returnHost) { var defaultPort, proxy, routingProxyOptions; if (options.https) { routingProxyOptions = { target: { https: true } }; defaultPort = 443; } else { routingProxyOptions = {}; defaultPort = 80; } proxy = new httpProxy.RoutingProxy(routingProxyOptions); options.path || (options.path = ""); options.port || (options.port = defaultPort); options.patchRedirect || (options.patchRedirect = true); if (options.patchRedirect) { proxy.once("start", function(req, res) { return patchServerResponseForRedirects(options.host, returnHost); }); } return function(req, res, next) { req.url = "" + options.path + req.url; req.headers.host = options.host; return proxy.proxyRequest(req, res, options); }; }; patchServerResponseForRedirects = function(fromHost, returnHost) { var writeHead; writeHead = http.ServerResponse.prototype.writeHead; return http.ServerResponse.prototype.writeHead = function(status) { var cookie, headers, i, len, newLocation, newSetCookie, oldLocation, ref; headers = this._headers || {}; if (status === 301 || status === 302) { oldLocation = new RegExp("s?:\/\/" + fromHost + ":?[0-9]*"); newLocation = "://" + returnHost; headers.location = headers.location.replace(oldLocation, newLocation); } if ('set-cookie' in headers) { newSetCookie = []; ref = headers['set-cookie']; for (i = 0, len = ref.length; i < len; i++) { cookie = ref[i]; newSetCookie.push(cookie.replace(/; Secure; HttpOnly/, '')); } headers['set-cookie'] = newSetCookie; } return writeHead.apply(this, arguments); }; }; module.exports = server; }).call(this);