UNPKG

2.34 kBJavaScriptView Raw
1import { EventEmitter } from 'events';
2
3// Import a simple router that works anywhere.
4import Router from 'koa-router';
5
6// Custom errors for fun and profit.
7import RouteError from './routeError';
8
9import co from 'co';
10
11class App {
12 constructor (config) {
13 this.config = config;
14
15 // The router listens to web requests (or html5 history changes) and fires
16 // callbacks registered by plugins.
17 this.router = new Router();
18 this.emitter = new EventEmitter();
19
20 this.startRequest = config.startRequest || [];
21 this.endRequest = config.endRequest || [];
22
23 this.plugins = [];
24 }
25
26 // A nicer-looking way to load config values.
27 getConfig (c) {
28 return this.config[c];
29 }
30
31 // Accepts routes / history changes, and forwards on the req object and
32 // the response (a `defer` object). The last param, `function`, can be safely
33 // ignored - it's fired after handling.
34 route (ctx) {
35 this.emit('route:start', ctx);
36 var middleware = this.router.routes().call(ctx);
37 var app = this;
38
39 var match = this.router.match(ctx.path).filter((r) => {
40 return ~r.methods.indexOf(ctx.method);
41 }).length;
42
43 if (!match) {
44 return co(function * () {
45 app.error(new RouteError(ctx.path), ctx, app);
46 });
47 }
48
49 return co(function * () {
50 yield* middleware;
51 }).then(() => {
52 this.emit('route:end', ctx);
53 }, (err) => {
54 if(this.config.debug) {
55 console.log(err, err.stack);
56 }
57
58 this.error(err, ctx, app);
59 }.bind(this));
60 }
61
62 registerPlugin (plugin) {
63 if (this.plugins.indexOf(plugin) === -1) {
64 this.plugins.push(plugin);
65 }
66 }
67
68 emit (...args) {
69 this.emitter.emit.apply(this.emitter, args);
70 }
71
72 on (...args) {
73 this.emitter.on.apply(this.emitter, args);
74 }
75
76 off (...args) {
77 this.emitter.removeListener.apply(this.emitter, args);
78 }
79
80 error (err, ctx, app) {
81 this.emit('error', err, ctx, app);
82
83 var status = err.status || 500;
84 var message = err.message || 'Unkown error';
85
86 var reroute = '/' + status;
87 var url = '/' + status;
88
89 if (ctx.request.url !== url) {
90 ctx.set('Cache-Control', 'no-cache');
91 ctx.redirect(reroute, url);
92 } else {
93 // Critical failure! The error page is erroring! Abandon all hope
94 console.log(err);
95 }
96 }
97}
98
99export default App;