UNPKG

jackson

Version:

Jackson, the web application framework

260 lines (218 loc) 8.69 kB
// 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);