UNPKG

sails

Version:

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

77 lines (62 loc) 3.59 kB
/** * Module dependencies */ var util = require('util'); var assert = require('assert'); var _ = require('@sailshq/lodash'); var flaverr = require('flaverr'); var machineAsAction = require('machine-as-action'); /** * helpRegisterAction() * * @param {SailsApp} sails * @param {Function|Dictionary} action [either a req/res function, or an actions2 (i.e. machine-as-action) definition] * @param {String} identity [the identity to register this action as] * @param {Boolean} force * * @throws {Error} If there is a conflicting, previously-registered action * @property {String} code (==='E_CONFLICT') * @property {String} identity [the conflicting identity (always the same as what was passed in)] * * @throws {Error} If the action is invalid * @property {String} code (==='E_INVALID') * @property {String} identity [the action identity (always the same as what was passed in)] * @property {Error} origError [the original (raw/underlying) error from `machine-as-action`] */ module.exports = function helpRegisterAction(sails, action, identity, force) { assert(_.isObject(sails) && _.isObject(sails._actions), new Error('Consistency violation: `sails` (a Sails app instance) should be passed in as the first argument.')); assert(_.isFunction(action) || _.isObject(action), new Error('Consistency violation: `action` (2nd arg) should be provided as either a req/res/next function or a machine def (actions2), but instead, got: '+util.inspect(action,{depth:null}))); assert(_.isString(identity), new Error('Consistency violation: Identity should be provided as a string, but instead, got: '+util.inspect(identity,{depth:null}))); // Get a reference to the Sails private actions hash. var actions = sails._actions; // Make sure identity is lowercased. identity = identity.toLowerCase(); // Identities should only have letters, numbers, dots, dashes and slashes. var IS_VALID_ACTION_IDENTITY_RX = /^[a-z_\$][a-z0-9-_.\$]*(\/[a-z_\$][a-z0-9-_\$.]*)*$/; if (!identity.match(IS_VALID_ACTION_IDENTITY_RX)) { throw flaverr({ name: 'userError', code: 'E_INVALID_ACTION_IDENTITY' }, new Error('Could not register action with invalid identity `' + identity + '`')); } // If we already registered an action with this identity, bail unless `force` is true. if (actions[identity] && !force) { throw flaverr({ name: 'userError', code: 'E_CONFLICT', identity: identity}, new Error('The action `' + identity + '` could not be registered because it conflicts with a previously-registered action.')); } // If the action is already a function, hope it's a req/res function // and save it in our set of actions. if (_.isFunction(action)) { actions[identity] = action; } // Otherwise try to interpret it as an actions2 definition and build a Callable: else { try { actions[identity] = machineAsAction(_.extend({ implementationSniffingTactic: sails.config.implementationSniffingTactic||undefined, }, action)); } catch (e) { throw flaverr({ name: 'userError', code: 'E_INVALID', identity: identity, origError: e}, new Error('The action `' + identity + '` could not be registered. It looks like a machine definition (actions2), but it could not be used to build an action.\nDetails: '+e.stack)); } } // Set the _middlewareType, which is used when the log level is "silly" to // identify what kind of a thing a route address is bound to. actions[identity]._middlewareType = actions[identity]._middlewareType || 'ACTION: ' + identity; };