jackson
Version:
Jackson, the web application framework
260 lines (218 loc) • 8.69 kB
JavaScript
// Generated by CoffeeScript 1.9.3
(function() {
var Application, CLI, Controller, ECT, Router, addClassHelpers, clone, extend, fs, http, jacksonVersion, path, ref, util,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
slice = [].slice,
extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
http = require('http');
fs = require('fs');
path = require('path');
util = require('util');
require('colors');
ECT = require('ect');
Router = require('./router');
Controller = require('./controller');
CLI = require('./cli');
ref = require('./util'), extend = ref.extend, clone = ref.clone, addClassHelpers = ref.addClassHelpers, jacksonVersion = ref.jacksonVersion;
Application = (function() {
addClassHelpers(Application);
Application.prototype.jacksonVersion = jacksonVersion;
Application.route = function() {
var ref1;
return (ref1 = (this.router || (this.router = new Router))).route.apply(ref1, arguments);
};
Application.resource = function() {
var ref1;
return (ref1 = (this.router || (this.router = new Router))).resource.apply(ref1, arguments);
};
Application.helper = function(name, fn) {
this.helpers = clone(this.helpers);
return this.helpers[name] = fn;
};
Application.prototype.options = {
logRequests: true
};
function Application(options) {
this.dispatchReq = bind(this.dispatchReq, this);
this.options = clone(this.options, options);
this.name || (this.name = this.constructor.name);
this.repl || (this.repl = {});
this._ectCache || (this._ectCache = {});
if (typeof this.initialize === "function") {
this.initialize();
}
}
Application.prototype.listen = function() {
var args, cb, desc, host, i, ref1, socketOrPort;
socketOrPort = arguments[0], args = 3 <= arguments.length ? slice.call(arguments, 1, i = arguments.length - 1) : (i = 1, []), cb = arguments[i++];
if (typeof cb !== 'function') {
args.push(cb);
cb = null;
}
if (typeof socketOrPort === 'number') {
host = args[0] || 'localhost';
desc = host.yellow + ":" + (socketOrPort.toString().green);
} else {
if (fs.existsSync(socketOrPort) && fs.statSync(socketOrPort).isSocket()) {
fs.unlinkSync(socketOrPort);
}
desc = socketOrPort.white;
}
this._server = http.createServer(this.dispatchReq);
return (ref1 = this._server).listen.apply(ref1, [socketOrPort].concat(slice.call(args), [(function(_this) {
return function() {
_this.log("Listening on " + desc + ", pid " + (process.pid.toString().red));
return typeof cb === "function" ? cb.apply(null, [socketOrPort].concat(slice.call(args))) : void 0;
};
})(this)]));
};
Application.prototype.startRepl = function() {
var Jackson, context, utils;
Jackson = require('..');
utils = require('./util');
context = require('repl').start({
prompt: this.name + "> ",
useGlobal: true,
useColors: true
}).context;
extend(context, Jackson, {
Jackson: Jackson,
jacksonVersion: jacksonVersion
}, utils, {
app: this
}, this.repl);
context[this.constructor.name] = this.constructor;
return context[this.name] = this.constructor;
};
Application.prototype.startCli = function() {
return new CLI(this).run();
};
Application.prototype.mount = function(urlPrefix, appOrFn) {
this._mounts || (this._mounts = {});
if (urlPrefix[urlPrefix.length - 1] !== '/') {
urlPrefix += '/';
}
return this._mounts[urlPrefix] = appOrFn;
};
Application.prototype.dispatchReq = function(req, res) {
req._timestamp = Date.now();
return this.dispatchUrl(req, res, req.method, req.url);
};
Application.prototype.dispatchUrl = function(req, res, method, url) {
var appOrFn, mountPrefix, ref1, ref2, route, urlWithSlash;
if (this._mounts != null) {
urlWithSlash = url[url.length - 1] === '/' ? url : url + '/';
ref1 = this._mounts;
for (mountPrefix in ref1) {
appOrFn = ref1[mountPrefix];
if (urlWithSlash === mountPrefix || url.slice(0, mountPrefix.length) === mountPrefix) {
url = url.slice(mountPrefix.length - 1) || '/';
if (appOrFn instanceof Jackson.Application) {
return appOrFn.dispatchUrl(req, res, method, url);
} else if (typeof appOrFn === 'function') {
req.url = url;
appOrFn(req, res);
}
}
}
}
route = (ref2 = this.constructor.router) != null ? ref2.match(method, url) : void 0;
if (this.options.logRequests) {
res.on('finish', this.bind(this.logRequest, req, res));
}
if (route) {
return this.dispatch(req, res, route);
} else {
return this.render(req, res, 'notFound');
}
};
Application.prototype.dispatch = function(req, res, route) {
var action, controller, fn;
fn = route.fn, controller = route.controller, action = route.action;
if ((controller != null) && action) {
controller = this.lookup(controller);
if (controller.prototype instanceof Controller) {
new controller(this, req, res, route).callAction(action);
} else {
fn = controller.prototype[action];
}
}
if (fn) {
controller = new Controller(this, req, res, route);
return controller.applyAsAction(fn);
}
};
Application.prototype.render = function() {
var action, args, ref1, req, res;
req = arguments[0], res = arguments[1], action = arguments[2], args = 4 <= arguments.length ? slice.call(arguments, 3) : [];
return (ref1 = new this.constructor.DefaultHandlers(this, req, res)).apply.apply(ref1, [action].concat(slice.call(args)));
};
Application.prototype.lookup = function(path) {
return path.split('.').reduce((function(obj, key) {
if (key) {
return obj[key];
} else {
return obj;
}
}), this.constructor);
};
Application.prototype.renderTemplate = function(templateRoot, tpl, context) {
var base;
templateRoot = templateRoot || this.templateRoot || path.join(process.cwd(), 'templates');
(base = this._ectCache)[templateRoot] || (base[templateRoot] = ECT({
watch: true,
root: templateRoot
}));
return this._ectCache[templateRoot].render(tpl, context);
};
Application.prototype.log = function() {
var msgs;
msgs = 1 <= arguments.length ? slice.call(arguments, 0) : [];
msgs = [new Date().toISOString().green, '|', this.name.yellow, '|'].concat(slice.call(msgs));
return console.log.apply(console, msgs);
};
Application.prototype.logRequest = function(req, res) {
var msTaken, status, statusColor;
status = res.statusCode.toString();
statusColor = (function() {
switch (status[0]) {
case '2':
return 'green';
case '4':
return 'yellow';
case '5':
return 'red';
default:
return 'blue';
}
})();
msTaken = Date.now() - req._timestamp;
return this.log(status[statusColor], req.method.yellow, req.url.white, (msTaken + "ms").yellow, req.connection.remoteAddress);
};
return Application;
})();
Application.DefaultHandlers = (function(superClass) {
extend1(DefaultHandlers, superClass);
function DefaultHandlers() {
return DefaultHandlers.__super__.constructor.apply(this, arguments);
}
DefaultHandlers.prototype.templateRoot = __dirname + '/../tpl';
DefaultHandlers.prototype.initialize = function() {
this.view.inspect = util.inspect;
return this.view.req = this.req;
};
DefaultHandlers.prototype.notFound = function() {
this.status = 404;
return this.render('404.html');
};
DefaultHandlers.prototype.error = function(error) {
this.status = 500;
return this.render('500.html', {
error: error
});
};
return DefaultHandlers;
})(Controller);
module.exports = Application;
}).call(this);