-
Notifications
You must be signed in to change notification settings - Fork 0
/
controllers.js
93 lines (76 loc) · 2.94 KB
/
controllers.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
'use strict';
module.exports = (Grown, util) => {
function _defaultPipelines(conn, options) {
if (conn.req.handler.use && this.default_pipelines) {
return conn.req.handler.use.filter(Boolean).reduce((prev, fn) => {
if (typeof this.default_pipelines[fn] !== 'function') throw new Error(`Invalid ${fn} pipeline, given '${this.default_pipelines[fn]}'`);
return prev.then(() => this.default_pipelines[fn](conn, options));
}, Promise.resolve());
}
}
function _drawRoutes(ctx, routes) {
routes.forEach(route => {
/* istanbul ignore else */
if (!route.pipeline) {
const _handler = route.handler.slice();
const action = _handler.length > 1 ? _handler.pop() : 'index';
const controller = _handler.filter(x => /^[A-Z]/.test(x)).join('.');
/* istanbul ignore else */
if (route.use && !Array.isArray(route.use)) {
route.use = util.flattenArgs(route.use);
}
// route definition
route.controller = controller;
route.action = action;
if (!this._controllers[controller]) {
try {
const _controller = (route.lookup || '%Controlller').replace('%', controller);
const Ctrl = util.getProp(ctx.constructor, _controller,
new Error(`${_controller} is not defined`));
this._controllers[controller] = {
instance: typeof Ctrl === 'function' ? new Ctrl() : Ctrl,
definition: Ctrl,
};
} catch (e) {
throw new Error(`${controller} controller failed (${e.message})`);
}
}
/* istanbul ignore else */
if (!this._controllers[controller].instance[action] || typeof this._controllers[controller].instance[action] !== 'function') {
throw new Error(`Invalid callback for ${route.verb} ${route.path} (${controller}#${action})`);
}
route.pipeline = [];
/* istanbul ignore else */
if (typeof this._controllers[controller].definition.pipe === 'function') {
route.pipeline.push({
call: [this._controllers[controller].definition, 'pipe'],
name: `${controller}#pipe`,
type: 'method',
});
}
/* istanbul ignore else */
if (typeof this.before_pipeline === 'function') {
route.pipeline.unshift({
call: [this, 'before_pipeline'],
name: 'Pipeline',
type: 'method',
});
}
route.pipeline.push({
call: [this._controllers[controller].instance, action],
name: `${controller}#${action}`,
type: 'method',
});
route.Controller = this._controllers[controller].definition;
delete route.handler;
}
});
}
return Grown('Router.Controllers', {
_drawRoutes,
_controllers: {},
_defaultPipelines,
$before_routes: _drawRoutes,
before_pipeline: _defaultPipelines,
});
};