@contrast/library-analysis
Advanced tools
Comparing version 1.13.0 to 1.13.1
@@ -18,2 +18,3 @@ /* | ||
const Module = require('module'); | ||
const path = require('path'); | ||
const { stat } = require('fs').promises; | ||
@@ -24,3 +25,11 @@ const { Event } = require('@contrast/common'); | ||
/** @typedef {listInstalled.Result} Result */ | ||
/** | ||
* @typedef {Object} FormattedResult | ||
* @property {string} name | ||
* @property {string} path | ||
* @property {string} version | ||
* @property {string[]} _requiredBy | ||
* @property {Record<string, FormattedResult>} dependencies | ||
* @property {Record<string, FormattedResult>} devDependencies | ||
*/ | ||
@@ -31,6 +40,6 @@ /** | ||
* | ||
* @param {Record<string, Result | string>} deps collection of dependencies from app root | ||
* @param {Record<string, listInstalled.Result | string>} deps collection of dependencies from app root | ||
* @param {Map<string, Set<string>>} requiredByMap | ||
* @param {string} parent the name of the module requiring the current when nested | ||
* @return {Record<string, Result>} formatted object | ||
* @param {string=} parent the name of the module requiring the current when nested | ||
* @return {Record<string, FormattedResult>} formatted object | ||
*/ | ||
@@ -67,2 +76,8 @@ const formatDependencies = (deps, requiredByMap, parent) => | ||
/** | ||
* @param {Record<string, FormattedResult>} deps | ||
* @param {Map<string, Set<string>>} requiredByMap | ||
* @param {Map<string, ReturnType<createLibData>>} libPathHashMap | ||
* @param {import('@contrast/logger').Logger} logger | ||
*/ | ||
const processDependencies = (deps, requiredByMap, libPathHashMap, logger) => { | ||
@@ -92,3 +107,3 @@ Object.values(deps).forEach((dep) => { | ||
module.exports = function (core) { | ||
module.exports = function init(core) { | ||
const { | ||
@@ -101,43 +116,63 @@ config, | ||
const libraryReporting = core.libraryAnalysis.libraryReporting = {}; | ||
const requiredByMap = new Map(); | ||
const libPathHashMap = new Map(); | ||
/** | ||
* @returns {Promise<string | undefined>} | ||
*/ | ||
async function getNodeModulesPath() { | ||
const projectPath = `${config.agent.node.app_root}/package.json`; | ||
const projectPath = path.resolve(config.agent.node.app_root, 'package.json'); | ||
const boundRequire = Module.createRequire(projectPath); | ||
const paths = boundRequire.resolve.paths(projectPath); | ||
return paths.reduce(async (prev, path) => { | ||
if (await prev) return prev; | ||
return paths?.reduce( | ||
/** | ||
* @param {Promise<string | undefined>} prev | ||
* @param {string} path | ||
* @returns | ||
*/ | ||
async (prev, path) => { | ||
if (await prev) return prev; | ||
return stat(path) | ||
.then(() => path) | ||
.catch(() => undefined); | ||
}, Promise.resolve()); | ||
return stat(path) | ||
.then(() => path) | ||
.catch(() => undefined); | ||
}, | ||
Promise.resolve(undefined)); | ||
} | ||
libraryReporting.install = async function () { | ||
const nodeModulesPath = await getNodeModulesPath(); | ||
const npmData = await listInstalled( | ||
nodeModulesPath, | ||
logger, | ||
npmVersionRange | ||
); | ||
const libraryReporting = core.libraryAnalysis.libraryReporting = { | ||
async install() { | ||
const nodeModulesPath = await getNodeModulesPath(); | ||
if (!nodeModulesPath) { | ||
logger.warn('Unable to determine the location of node_modules, aborting library analysis. Ensure `agent.node.app_root` is set to the directory containing your node_modules folder.'); | ||
return; | ||
} | ||
const dependencies = formatDependencies(npmData.dependencies, requiredByMap); | ||
processDependencies(dependencies, requiredByMap, libPathHashMap, logger); | ||
try { | ||
const npmData = await listInstalled( | ||
nodeModulesPath, | ||
logger, | ||
npmVersionRange | ||
); | ||
for (const library of libPathHashMap.values()) { | ||
const serializedLib = serializeLibrary(library); | ||
try { | ||
serializedLib.classCount = await getFileCount(library.path); | ||
const dependencies = formatDependencies(npmData.dependencies, requiredByMap); | ||
processDependencies(dependencies, requiredByMap, libPathHashMap, logger); | ||
} catch (err) { | ||
logger.warn('Unable to get file count for package "%s@%s"', library.name, library.version); | ||
logger.warn({ err }, 'Unable to perform library analysis.'); | ||
} | ||
messages.emit(Event.LIBRARY, serializedLib); | ||
for (const library of libPathHashMap.values()) { | ||
const serializedLib = serializeLibrary(library); | ||
try { | ||
serializedLib.classCount = await getFileCount(library.path); | ||
} catch (err) { | ||
logger.warn('Unable to get file count for package "%s@%s"', library.name, library.version); | ||
} | ||
messages.emit(Event.LIBRARY, serializedLib); | ||
} | ||
requiredByMap.clear(); | ||
libPathHashMap.clear(); | ||
} | ||
requiredByMap.clear(); | ||
libPathHashMap.clear(); | ||
}; | ||
@@ -144,0 +179,0 @@ |
{ | ||
"name": "@contrast/library-analysis", | ||
"version": "1.13.0", | ||
"version": "1.13.1", | ||
"description": "Handles library reporting and library usage analysis", | ||
@@ -5,0 +5,0 @@ "license": "SEE LICENSE IN LICENSE", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17937
458