forked from cesardeazevedo/sails-hook-sequelize-blueprints
-
Notifications
You must be signed in to change notification settings - Fork 1
/
onRoute.js
139 lines (114 loc) · 3.91 KB
/
onRoute.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
/**
* Module dependencies.
*/
var _ = require('lodash'),
util = require('sails-util');
// NOTE:
// Since controllers load blueprint actions by default anyways, this route syntax handler
// can be replaced with `{action: 'find'}, {action: 'create'}, ...` etc.
/**
* Expose route parser.
* @type {Function}
*/
module.exports = function (sails) {
return interpretRouteSyntax;
/**
* interpretRouteSyntax
*
* "Teach" router to understand direct references to blueprints
* as a target to sails.router.bind()
* (i.e. in the `routes.js` file)
*
* @param {[type]} route [description]
* @return {[type]} [description]
* @api private
*/
function interpretRouteSyntax (route) {
var target = route.target,
path = route.path,
verb = route.verb,
options = route.options;
// Support referencing blueprints in explicit routes
// (`{ blueprint: 'create' }` et. al.)
if (
_.isObject(target) &&
!_.isFunction(target) &&
!_.isArray(target) &&
_.isString(target.blueprint)) {
// On a match, merge leftover items in the target object into route options:
options = _.merge(options, _.omit(target, 'blueprint'));
return bindBlueprintAction(path, target.blueprint, verb, options);
}
// Ignore unknown route syntax
// If it needs to be understood by another hook, the hook would have also received
// the typeUnknown event, so we're done.
return;
}
/**
* Bind explicit route to a blueprint action.
*
* @param {[type]} path [description]
* @param {[type]} blueprintActionID [description]
* @param {[type]} verb [description]
* @param {[type]} options [description]
* @return {[type]} [description]
* @api private
*/
function bindBlueprintAction ( path, blueprintActionID, verb, options ) {
// Look up appropriate blueprint action and make sure it exists
var blueprint = sails.middleware.blueprints[blueprintActionID];
// If a 'blueprint' was specified, but it doesn't exist, warn the user and ignore it.
if ( ! ( blueprint && _.isFunction(blueprint) )) {
sails.log.error(
blueprintActionID,
':: Ignoring attempt to bind route (' + path + ') to unknown blueprint action (`'+blueprintActionID+'`).'
);
return;
}
// If a model wasn't provided with the options, try and guess it
if (!options.model) {
var matches = path.match(/^\/(\w+).*$/);
if (matches && matches[1] && sails.models[matches[1]]) {
options.model = matches[1];
}
else {
sails.log.error(
blueprintActionID,
':: Ignoring attempt to bind route (' + path + ') to blueprint action (`'+blueprintActionID+'`), but no valid model was specified and we couldn\'t guess one based on the path.'
);
return;
}
}
// If associations weren't provided with the options, try and get them
if (!options.associations) {
options = _.merge({ associations: _.cloneDeep(sails.models[options.model].associations) }, options);
}
// Otherwise make sure it's an array of strings of valid association aliases
else {
options.associations = options.associations.map(function(alias) {
if (typeof(alias) != 'string') {
sails.log.error(
blueprintActionID,
':: Ignoring invalid association option for '+path+'.'
);
return;
}
var association;
if (!(association = _.findWhere(sails.models[options.model].associations, {alias: alias}))) {
sails.log.error(
blueprintActionID,
':: Ignoring invalid association option `'+alias+'` for '+path+'.'
);
return;
}
return association;
});
}
// If "populate" wasn't provided in the options, use the default
if (typeof (options.populate) == 'undefined') {
options.populate = sails.config.blueprints.populate;
}
sails.router.bind(path, blueprint, verb, options);
return;
}
};