-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrouter.js
More file actions
111 lines (101 loc) · 3.34 KB
/
router.js
File metadata and controls
111 lines (101 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
'use strict';
var _ = require('underscore');
var dir = require('node-dir');
// strip off controllerDir prefix and .js|.coffee suffix, then replace any
// slashes with _'s
function extractControllerName(path, controllerDir) {
var name = path.replace(controllerDir, '');
name = name.replace(/^\//, '');
name = name.replace(/.js$|.coffee$/, '');
name = name.replace(/\//g, '_');
return name;
}
// Collect route configurations from each controller beneath controllerDir
function controllerRouteInfo(controllerDir, callback) {
var routes = [];
var controller, controllerName;
// recursively find files from controllerDir
dir.files(controllerDir, function(err, files) {
if (err) {
return callback(err);
}
files.forEach(function(fullPath) {
// only accept files that end in .js or .coffee
if (fullPath.match(/.js$|.coffee$/)) {
// load resource and see if routes are defined
controller = require(fullPath);
if (controller.routes) {
controllerName = extractControllerName(fullPath, controllerDir);
controller.routes().forEach(function(r) {
if (r.path && r.action) {
// decorate the route with correct defaults
if (!r.method) {
r.method = 'get'; // set correct method
}
r.path = r.path; // apply route prefix to path
r.controller = controller; // render needs access to real controller
r.controllerPath = fullPath; // might be useful
r.controllerName = controllerName; // assign name, useful for autogen tests
routes.push(r); // collect it
}
});
}
}
});
return callback(null, routes);
});
}
// collect route summary
function routeSummary(app) {
var summary = [];
_.each(app.routes, function(routes, method) {
_.each(routes, function(r) {
summary.push(method + ' ' + r.path);
});
});
return summary;
}
// Given a function that retrieves the data, consistently send the response
function render(route) {
return function(req, res) {
// extract params from request
var params = req.query || {};
req.route.keys.forEach(function(routeKey) {
params[routeKey.name] = req.route.params[routeKey.name];
});
// get correct controller/action that will retrieve the data
route.controller[route.action](req, params, function(err, json, status) {
if (err) {
res.status(err.code);
res.send();
} else {
res.status(status);
res.json(json);
}
// DO NOT FORWARD TO NEXT -- END CHAIN HERE
});
};
}
// bind routes to our express app
module.exports.buildRoutes = function(app, controllerDir, callback) {
app.get('/api-docs', function(req, res) {
res.redirect('/swagger/index.html');
});
app.get('/hello', function(req, res) {
var body = 'Hello World';
res.setHeader('Content-Type', 'text/plain');
res.setHeader('Content-Length', body.length);
res.end(body);
});
app.get('/', function(req, res) {
res.json(routeSummary(app));
});
controllerRouteInfo(controllerDir, function(err, routes) {
if (routes) {
routes.forEach(function(r) {
app[r.method](r.path, render(r));
});
}
return callback(err, routes);
});
};