diff --git a/lib/hooks/moduleloader/index.js b/lib/hooks/moduleloader/index.js index 22ac4ea9e..2298458da 100644 --- a/lib/hooks/moduleloader/index.js +++ b/lib/hooks/moduleloader/index.js @@ -426,6 +426,8 @@ module.exports = function(sails) { */ loadUserHooks: function (cb) { + var defaultInstalledHooks = _.filter(_.values(require('../../app/configuration/default-hooks')), function(val) {return val !== true;}); + async.auto({ // Load apps from the "api/hooks" folder hooksFolder: function(cb) { @@ -464,8 +466,8 @@ module.exports = function(sails) { // http: {}, // 'package.json': true, // etc... - modules = (function _flatten(modules, foundPackageJsons, currentPath, level) { - foundPackageJsons = foundPackageJsons || {}; + modules = (function _flatten(modules, installedHooks, currentPath, level) { + installedHooks = installedHooks || {}; currentPath = currentPath || ''; level = level || 0; // Loop through the keys in the current map object @@ -481,7 +483,18 @@ module.exports = function(sails) { var resolved = require.resolve(filePath); if (require.cache[resolved]) {delete require.cache[resolved];} // Attempt to load the package.json file - foundPackageJsons[currentPath] = require(filePath); + var packageJson = require(filePath); + // If the module isn't declared as a Sails hook, ignore it. + if (!packageJson.sails || !packageJson.sails.isHook) { + return; + } + // If it's one of our default hooks, ignore it so that it can be safely overridden. + if (_.contains(defaultInstalledHooks, packageJson.name)) { + return; + } + // Save a reference to this installed hook, which we'll use to require + // the full module below. + installedHooks[currentPath] = packageJson; } catch(e) { sails.log.verbose('While searching for installable hooks, found invalid package.json file:', filePath); return; @@ -494,10 +507,10 @@ module.exports = function(sails) { if (currentPath) { nextPath = path.join(currentPath,identity); } else { nextPath = identity; } - _flatten(modules[identity], foundPackageJsons, nextPath, level + 1 ); + _flatten(modules[identity], installedHooks, nextPath, level + 1 ); } });// - return foundPackageJsons; + return installedHooks; })(modules);// return cb(null, modules); @@ -517,61 +530,60 @@ module.exports = function(sails) { try { - _.extend(hooks, _.reduce(results.nodeModulesFolder, function(memo, module, identity) { + // Loop through the package.json files of the hooks we found in the node_modules folder. + _.extend(hooks, _.reduce(results.nodeModulesFolder, function(memo, modulePackageJson, identity) { - // Hooks loaded from "node_modules" need to have "sails.isHook: true" in order for us - // to know that they are a sails hook - if (module.sails && module.sails.isHook) { - var hookConfig = module.sails; + // Any special config for this hook will be under the `sails` key in the package.json file. + var hookConfig = modulePackageJson.sails; - // Determine the name the hook should be added as - var hookName; + // Determine the name the hook should be added as + var hookName; - if (!_.isEmpty(hookConfig.hookName)) { - hookName = hookConfig.hookName; - } - // If an identity was specified in sails.config.installedHooks, use that - else if (sails.config.installedHooks && sails.config.installedHooks[identity] && sails.config.installedHooks[identity].name) { - hookName = sails.config.installedHooks[identity].name; - } - // Otherwise use the module name, with namespacing and initial "sails-hook-" stripped off if it exists - else { - // Strip off any NPM namespacing and/or sails-hook- prefix - hookName = identity.replace(/^(@.+?\/)?(sails-hook-)?/, ''); - } + if (!_.isEmpty(hookConfig.hookName)) { + hookName = hookConfig.hookName; + } + // If an identity was specified in sails.config.installedHooks, use that + else if (sails.config.installedHooks && sails.config.installedHooks[identity] && sails.config.installedHooks[identity].name) { + hookName = sails.config.installedHooks[identity].name; + } + // Otherwise use the module name, with namespacing and initial "sails-hook-" stripped off if it exists + else { + // Strip off any NPM namespacing and/or sails-hook- prefix + hookName = identity.replace(/^(@.+?\/)?(sails-hook-)?/, ''); + } - if (sails.config.hooks[hookName] === false || sails.config.hooks[hookName] === 'false') { - return memo; - } + if (sails.config.hooks[hookName] === false || sails.config.hooks[hookName] === 'false') { + return memo; + } - // Allow overriding core hooks - if (sails.hooks[hookName]) { - sails.log.verbose('Found hook: `'+hookName+'` in `node_modules/`. Overriding core hook w/ the same identity...'); - } + // Allow overriding core hooks + if (sails.hooks[hookName]) { + sails.log.verbose('Found hook: `'+hookName+'` in `node_modules/`. Overriding core hook w/ the same identity...'); + } - // If we have a hook in api/hooks with this name, throw an error - if (hooks[hookName]) { - var err = (function (){ - var msg = - 'Found hook: `' + hookName + '`, in `node_modules/`, but a hook with that identity already exists in `api/hooks/`. '+ - 'The hook defined in your `api/hooks/` folder will take precedence.'; - var err = new Error(msg); - err.code = 'E_INVALID_HOOK_NAME'; - return err; - })(); - sails.log.warn(err); - return memo; - } + // If we have a hook in api/hooks with this name, throw an error + if (hooks[hookName]) { + var err = (function (){ + var msg = + 'Found hook: `' + hookName + '`, in `node_modules/`, but a hook with that identity already exists in `api/hooks/`. '+ + 'The hook defined in your `api/hooks/` folder will take precedence.'; + var err = new Error(msg); + err.code = 'E_INVALID_HOOK_NAME'; + return err; + })(); + sails.log.warn(err); + return memo; + } - // Load the hook code - var hook = require(path.resolve(sails.config.appPath, 'node_modules', identity)); + // Load the hook code + var hook = require(path.resolve(sails.config.appPath, 'node_modules', identity)); - // Set its config key (defaults to the hook name) - hook.configKey = (sails.config.installedHooks && sails.config.installedHooks[identity] && sails.config.installedHooks[identity].configKey) || hookName; + // Set its config key (defaults to the hook name) + hook.configKey = (sails.config.installedHooks && sails.config.installedHooks[identity] && sails.config.installedHooks[identity].configKey) || hookName; + + // Add this to the list of hooks to load + memo[hookName] = hook; - // Add this to the list of hooks to load - memo[hookName] = hook; - } return memo; }, {}));//