UNPKG

@balderdash/sails-edge

Version:

API-driven framework for building realtime apps, using MVC conventions (based on Express and Socket.io)

139 lines (113 loc) 3.96 kB
/** * Module dependencies. */ var _ = require('lodash'); // 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; } };