src/cordova/plugin/add.js
function getFetchVersion (projectRoot, pluginInfo, cordovaVersion) {
    // Figure out the project requirements
    if (pluginInfo.engines && pluginInfo.engines.cordovaDependencies) {
        // grab array of already installed plugins
        var pluginList = plugin_util.getInstalledPlugins(projectRoot);
        var pluginMap = {};
        pluginList.forEach(function (plugin) {
            pluginMap[plugin.id] = plugin.version;
        });
        return cordova_util.getInstalledPlatformsWithVersions(projectRoot)
            .then(function (platformVersions) {
                return module.exports.determinePluginVersionToFetch(
                    pluginInfo,
                    pluginMap,
                    platformVersions,
                    cordovaVersion);
            });
    } else {
        // If we have no engine, we want to fall back to the default behavior
        events.emit('verbose', 'npm info for ' + pluginInfo.name + ' did not contain any engine info. Fetching latest release');
        return Promise.resolve(null);
    }
}
function getFetchVersion (projectRoot, pluginInfo, cordovaVersion) {
    // Figure out the project requirements
    if (pluginInfo.engines && pluginInfo.engines.cordovaDependencies) {
        // grab array of already installed plugins
        var pluginList = plugin_util.getInstalledPlugins(projectRoot);
        var pluginMap = {};
        pluginList.forEach(function (plugin) {
            pluginMap[plugin.id] = plugin.version;
        });
        return cordova_util.getInstalledPlatformsWithVersions(projectRoot)
            .then(function (platformVersions) {
                return module.exports.determinePluginVersionToFetch(
                    pluginInfo,
                    pluginMap,
                    platformVersions,
                    cordovaVersion);
            });
    } else {
        // If we have no engine, we want to fall back to the default behavior
        events.emit('verbose', 'npm info for ' + pluginInfo.name + ' did not contain any engine info. Fetching latest release');
        return Promise.resolve(null);
    }
}
Gets the version of a plugin that should be fetched for a given project based
on the plugin's engine information from NPM and the platforms/plugins installed
in the project. The cordovaDependencies object in the package.json's engines
entry takes the form of an object that maps plugin versions to a series of
constraints and semver ranges. For example:

{ plugin-version: { constraint: semver-range, ...}, ...}

Constraint can be a plugin, platform, or cordova version. Plugin-version
can be either a single version (e.g. 3.0.0) or an upper bound (e.g. <3.0.0)

@param {string}  projectRoot     The path to the root directory of the project
@param {object}  pluginInfo      The NPM info of the plugin to be fetched (e.g. the
result of calling `registry.info()`)
@param {string}  cordovaVersion  The semver version of cordova-lib

@return {Promise}                A promise that will resolve to either a string
if there is a version of the plugin that this
project satisfies or null if there is not