var _ = require('lodash'),
RUNTIME_PACKAGE = require('../package.json'),
/**
* List of postman packages to include while generating dependency object
*
* @const
* @type {String[]}
*/
PACKAGES_TO_CONSIDER = {
'chai-postman': true,
'postman-collection': true,
'postman-request': true,
'postman-sandbox': true,
'uniscope': true,
'uvm': true
},
/**
* Generate object containing version and dependencies of Runtime or given module.
*
* @param {String} [moduleName] - Module name
* @param {Boolean} [deepDependencies=true] - Do depth dependencies traversal or stop at root
* @param {Object} [moduleData={}] - Object to store module data
* @returns {Object}
*
* @example
Returned Object Structure
* var runtime = require('postman-runtime');
* runtime.version();
* {
* version: '7.6.1',
* dependencies: {
* 'postman-collection' : {
* version: '3.4.2',
* dependencies: {
* 'postman-request': {
* version: '2.88.1-postman.5'
* }
* }
* },
* 'postman-request': {
* version: '2.88.1-postman.5'
* }
* }
* }
*/
getVersionData = function (moduleName, deepDependencies, moduleData) {
// Set default values of function arguments if not given
// @note Argument moduleData is undefined if function is called directly.
// Otherwise moduleData will contain object if called recursively.
!moduleData && (moduleData = {});
// Include nested dependencies in moduleData object only if deepDependencies=true.
// Return only direct dependencies of module if deepDependencies=false.
(deepDependencies === undefined) && (deepDependencies = true);
var version,
// Runtime's package.json is considered by default
packageJson = RUNTIME_PACKAGE;
// bail out if either dependency not in PACKAGES_TO_CONSIDER
// or not Runtime's dependency
if (
moduleName &&
!(
PACKAGES_TO_CONSIDER[moduleName] &&
(
_.has(packageJson, ['dependencies', moduleName]) ||
_.has(packageJson, ['devDependencies', moduleName])
)
)
) {
return;
}
// if module name is given in function argument, consider that module's package.json instead of default
if (moduleName) {
// eslint-disable-next-line security/detect-non-literal-require
packageJson = require(require.resolve(`${moduleName}/package.json`));
}
// set version of dependency given as function argument or Runtime
moduleData.version = packageJson.version;
moduleData.dependencies = {};
_.forEach(PACKAGES_TO_CONSIDER, function (value, key) {
// if key is normal dependency
if (_.has(packageJson, ['dependencies', key])) {
version = packageJson.dependencies[key];
}
// else if key is devDependency
else if (_.has(packageJson, ['devDependencies', key])) {
version = packageJson.devDependencies[key];
}
// skip if key is not listed as dependency in packageJson
else {
return;
}
// include dependency in module data
moduleData.dependencies[key] = {
version: version,
dependencies: {}
};
// recursive call to include deep-dependency
if (!moduleName && deepDependencies) {
getVersionData(key, deepDependencies, moduleData.dependencies[key]);
}
// delete if no deep-dependency found
if (!_.size(moduleData.dependencies[key].dependencies)) {
delete moduleData.dependencies[key].dependencies;
}
});
return moduleData;
};
module.exports = getVersionData;