forked from Yomguithereal/dolman
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
169 lines (134 loc) · 4.05 KB
/
index.js
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
* Dolman API Endpoint
* ====================
*
* Exposing the library's utilities.
*/
var responses = require('./src/responses.js'),
createLogger = require('./src/createLogger.js'),
middlewares = require('./src/middlewares.js'),
helpers = require('./src/helpers.js'),
express = require('express'),
Typology = require('typology'),
join = require('path').join,
util = require('util');
module.exports = function(app, opts) {
opts = opts || {};
// Creating the logger
var logger = opts.logger;
if (!logger)
logger = createLogger('logger' in opts && !opts.logger);
// Building internal typology
var types;
if (opts.typology instanceof Typology)
types = opts.typology;
else
types = new Typology(opts.typology || {});
// Applying responses to the express app
responses(app, logger, types);
// Internal route register
var routesMap = new Map();
// Internal RAM cache
var cache = {};
/**
* Router function.
*/
function makeRouter() {
// Solving arguments
var args = [].slice.call(arguments);
var beforeMiddlewares = args.slice(0, -1),
routes = args[args.length - 1];
var router = express.Router();
routes.forEach(function(route) {
if (!route.url)
throw Error('dolman.router: one route has no url: ' + util.inspect(route));
if (!route.action)
throw Error('dolman.router: the route for url ' + route.url + ' has no action.');
var actions = [].concat(route.action);
// Storing the route
routesMap.set(actions[0], route);
// Applying before middlewares
var routeMiddlewares = beforeMiddlewares.slice();
// Validation
if (route.validate)
routeMiddlewares.push(middlewares.validate(types, route.validate));
// Mask
if (route.mask)
routeMiddlewares.push(middlewares.mask(route.mask));
// RAM cache
if (route.cache)
routeMiddlewares.push(middlewares.cache(cache, route.cache));
// HTTP cache
if (route.httpCache)
routeMiddlewares.push(middlewares.httpCache(route.httpCache));
// Determining the method
var methods = [].concat(route.method || route.methods || 'ALL');
methods.forEach(function(method) {
router[method.toLowerCase()].apply(
router,
[route.url]
.concat(routeMiddlewares)
.concat(actions)
);
});
});
return router;
}
/**
* Specifications functions.
*/
function specs() {
var routes = {};
// Reducing the app's recursive stack
function reduceStack(path, items, item) {
var nextPath;
if (item.handle && item.handle.stack) {
nextPath = join(path, (item.path || helpers.unescapeRegex(item.regexp) || ''));
return items.concat(item.handle.stack.reduce(reduceStack.bind(null, nextPath), []));
}
if (item.route) {
nextPath = join(path, (item.route.path || ''));
return items.concat(item.route.stack.reduce(reduceStack.bind(null, nextPath), []));
}
return items.concat({
handle: item.handle,
path: path
});
}
// Filtering the actions coming from dolman
app._router.stack
.reduce(reduceStack.bind(null, ''), [])
.map(function(item) {
return {
route: routesMap.get(item.handle),
path: item.path
};
})
.filter(function(item) {
return item.route && item.route.name;
})
.forEach(function(item) {
var route = item.route,
method = [].concat(route.method || route.methods)[0];
var routeData = {
path: item.path,
name: route.name,
method: !method || method === 'ALL' ? 'GET' : method
};
['description'].forEach(function(k) {
if (route[k])
routeData[k] = route[k];
});
routes[route.name] = routeData;
});
return {
formats: ['json'],
methods: routes
};
}
// Returning an object to handle
return {
router: makeRouter,
specs: specs
};
};