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;