jackson
Version:
Jackson, the web application framework
259 lines (217 loc) • 8.58 kB
JavaScript
// Generated by CoffeeScript 1.7.1
(function() {
var Application, CLI, ClassHelpers, Controller, ECT, Router, clone, extend, fs, http, jacksonVersion, path, util, _ref,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__slice = [].slice,
__hasProp = {}.hasOwnProperty,
__extends = 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; };
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, ClassHelpers = _ref.ClassHelpers, jacksonVersion = _ref.jacksonVersion;
Application = (function() {
ClassHelpers(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, socketOrPort, _i, _ref1;
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, app) {
this._mounts || (this._mounts = {});
if (urlPrefix[urlPrefix.length - 1] !== '/') {
urlPrefix += '/';
}
return this._mounts[urlPrefix] = app;
};
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 app, route, urlPrefix, urlWithSlash, _ref1, _ref2;
if (this._mounts != null) {
if (url[url.length - 1] !== '/') {
urlWithSlash = url + '/';
} else {
urlWithSlash = url;
}
_ref1 = this._mounts;
for (urlPrefix in _ref1) {
app = _ref1[urlPrefix];
if (urlWithSlash === urlPrefix || url.slice(0, urlPrefix.length) === urlPrefix) {
url = url.slice(urlPrefix.length - 1) || '/';
return app.dispatchUrl(req, res, method, url);
}
}
}
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, req, res, _ref1;
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(_super) {
__extends(DefaultHandlers, _super);
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);