diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..6cbac42 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,28 @@ +name: N|Solid CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + CI: + name: CI with N|Solid ${{ matrix.nsolid-version }} (Node ${{ matrix.node-version }}) + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18, 20, 22] + nsolid-version: [5] + fail-fast: false + steps: + - uses: actions/checkout@v4 + - name: Setup N|Solid ${{ matrix.node-version }} + uses: nodesource/setup-nsolid@v1 + with: + node-version: ${{ matrix.node-version }} + nsolid-version: ${{ matrix.nsolid-version }} + - run: nsolid -vv + - run: npm ci || npm install + - run: npm run test + diff --git a/commands/report.js b/commands/report.js index c64e9c7..60263d3 100644 --- a/commands/report.js +++ b/commands/report.js @@ -139,56 +139,56 @@ async function report (argv, _dir) { const isNested = pkgName === nestedPkgName && pkgVersion === nestedPkgVersion // Processing packages from NCM service - let includedCount = 0; - let skippedCount = 0; - + // let includedCount = 0 + // let skippedCount = 0 + for (const { name, version, scores, published } of data) { - let maxSeverity = 0; - let license = {}; - const failures = []; + let maxSeverity = 0 + let license = {} + const failures = [] for (const score of scores) { - const severityValue = SEVERITY_RMAP.indexOf(score.severity); + const severityValue = SEVERITY_RMAP.indexOf(score.severity) if (score.group !== 'compliance' && score.group !== 'security' && score.group !== 'risk') { - continue; + continue } if (severityValue > maxSeverity) { - maxSeverity = severityValue; + maxSeverity = severityValue } if (score.pass === false) { - failures.push(score); - hasFailures = true; + failures.push(score) + hasFailures = true } if (score.name === 'license') { - license = score; + license = score } } // Modified approach to include ALL packages in the report // Even packages with null/undefined versions will be included with a default version - let effectiveVersion = version; + let effectiveVersion = version if (effectiveVersion === null || effectiveVersion === undefined) { - effectiveVersion = '0.0.0'; + effectiveVersion = '0.0.0' // Using default version 0.0.0 for package } - + // Skip nested packages with severity issues if (isNested && !!maxSeverity) { - skippedCount++; + // skippedCount++ // Skipping nested package - continue; + continue } - + // Check if license has failed, which should upgrade to critical severity - const getLicenseScore = ({ pass }) => pass === false ? 0 : null; + // const getLicenseScore = ({ pass }) => pass === false ? 0 : null if (license && license.pass === false) { - maxSeverity = 4; + maxSeverity = 4 } // Add the package to our report @@ -200,11 +200,11 @@ async function report (argv, _dir) { failures, license, scores - }); - - includedCount++; + }) + + // includedCount++ } - + // Package processing complete pkgScores = moduleSort(pkgScores) @@ -212,7 +212,7 @@ async function report (argv, _dir) { // Process whitelisted packages const whitelisted = pkgScores.filter(pkg => whitelist.has(`${pkg.name}@${pkg.version}`)) .map(pkgScore => ({ ...pkgScore, quantitativeScore: score(pkgScore.scores, pkgScore.maxSeverity) })) - + // Filter out whitelisted packages from the main package list pkgScores = pkgScores.filter(pkg => !whitelist.has(`${pkg.name}@${pkg.version}`)) .map(pkgScore => ({ ...pkgScore, quantitativeScore: score(pkgScore.scores, pkgScore.maxSeverity) })) diff --git a/lib/ncm-analyze-tree.js b/lib/ncm-analyze-tree.js index 2b9d998..0ecd68b 100644 --- a/lib/ncm-analyze-tree.js +++ b/lib/ncm-analyze-tree.js @@ -8,123 +8,123 @@ const path = require('path') // No need for patches since we're not using universal-module-tree anymore // Use dependency-tree package instead of universal-module-tree -const dependencyTree = require('dependency-tree'); +const dependencyTree = require('dependency-tree') // Helper function to convert dependency-tree output to a format similar to universal-module-tree const buildDependencyTree = (filename, directory) => { // Make sure directory is absolute - const absDirectory = path.isAbsolute(directory) ? directory : path.resolve(process.cwd(), directory); - + const absDirectory = path.isAbsolute(directory) ? directory : path.resolve(process.cwd(), directory) + // Analyze with dependency-tree - + try { // Check if the target file exists - const targetFilePath = path.resolve(absDirectory, filename); + const targetFilePath = path.resolve(absDirectory, filename) if (!fs.existsSync(targetFilePath)) { // Main file doesn't exist, fall back to package.json - return { children: [] }; + return { children: [] } } - + // Get the dependency tree in object form // First attempt: analyze the application code - let tree = dependencyTree({ + const tree = dependencyTree({ filename: targetFilePath, directory: absDirectory, filter: path => path.indexOf('node_modules') === -1, // Skip node_modules noTypeDefinitions: true // Skip TypeScript definitions - }); - + }) + // Now we need to get npm dependencies from package.json since we excluded node_modules // This approach combines both static analysis and package.json info - const npmDeps = getNpmDependencies(absDirectory); + // const npmDeps = getNpmDependencies(absDirectory) // Mix in the npm dependencies from package.json - + // Convert to a format similar to universal-module-tree - return convertToUniversalModuleTree(tree, absDirectory); + return convertToUniversalModuleTree(tree, absDirectory) } catch (err) { // Error analyzing dependencies - return { children: [] }; + return { children: [] } } -}; +} // Helper function to get npm dependencies from package.json -function getNpmDependencies(directory) { - const deps = []; - const pkgJsonPath = path.join(directory, 'package.json'); - +function getNpmDependencies (directory) { + const deps = [] + const pkgJsonPath = path.join(directory, 'package.json') + try { if (fs.existsSync(pkgJsonPath)) { - const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')); - + const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')) + // Combine all dependency types const allDeps = { ...pkgJson.dependencies || {}, ...pkgJson.devDependencies || {}, ...pkgJson.peerDependencies || {}, ...pkgJson.optionalDependencies || {} - }; - + } + // Create a dependency object for each npm package for (const [name, version] of Object.entries(allDeps)) { // Clean up version strings (remove ^, ~, etc.) - let cleanVersion = version; + let cleanVersion = version if (typeof version === 'string') { - cleanVersion = version.replace(/^[^0-9]*/, ''); + cleanVersion = version.replace(/^[^0-9]*/, '') } - + deps.push({ name, version: cleanVersion || '0.0.0' - }); + }) } } } catch (err) { // Error reading package.json } - - return deps; + + return deps } // Convert dependency-tree format to universal-module-tree format -function convertToUniversalModuleTree(tree, baseDir) { +function convertToUniversalModuleTree (tree, baseDir) { // Get the root node (first key in the object) - const rootKey = Object.keys(tree)[0]; - if (!rootKey) return { children: [] }; - + const rootKey = Object.keys(tree)[0] + if (!rootKey) return { children: [] } + // Extract package info from package.json if available - const pkgJsonPath = path.join(baseDir, 'package.json'); - let pkgInfo = { name: path.basename(baseDir), version: '0.0.0' }; - + const pkgJsonPath = path.join(baseDir, 'package.json') + let pkgInfo = { name: path.basename(baseDir), version: '0.0.0' } + try { if (fs.existsSync(pkgJsonPath)) { - const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')); + const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')) pkgInfo = { name: pkgJson.name || pkgInfo.name, version: pkgJson.version || pkgInfo.version - }; + } } } catch (err) { // Ignore package.json errors } - + // Add npm dependencies directly to the tree - const npmDeps = getNpmDependencies(baseDir); - + const npmDeps = getNpmDependencies(baseDir) + // Create the root node with children const result = { data: pkgInfo, children: [] - }; - + } + // Process all dependencies from the static analysis - function processNode(treeNode, parentNode) { - const deps = Object.keys(treeNode); - + function processNode (treeNode, parentNode) { + const deps = Object.keys(treeNode) + for (const dep of deps) { // Extract name and version from the dependency path // For simplicity, we'll use the filename as the name - const name = path.basename(dep, path.extname(dep)); - + const name = path.basename(dep, path.extname(dep)) + // Create the child node const childNode = { data: { @@ -132,21 +132,21 @@ function convertToUniversalModuleTree(tree, baseDir) { version: '0.0.0' // Default version since we don't have this info }, children: [] - }; - + } + // Process subdependencies - processNode(treeNode[dep], childNode); - + processNode(treeNode[dep], childNode) + // Add to parent's children - parentNode.children.push(childNode); + parentNode.children.push(childNode) } } - + // Start processing from the root if (rootKey) { - processNode(tree[rootKey], result); + processNode(tree[rootKey], result) } - + // Add npm dependencies from package.json as direct children of the root node for (const dep of npmDeps) { // Add npm package as a direct child @@ -156,10 +156,10 @@ function convertToUniversalModuleTree(tree, baseDir) { version: dep.version }, children: [] - }); + }) } - - return result; + + return result } const analyze = async ({ @@ -172,59 +172,56 @@ const analyze = async ({ url }) => { // Get all dependencies and apply filter - const rawDeps = await readUniversalTree(dir); - const pkgs = filterPkgs(rawDeps, filter); - - onPkgs(pkgs); - - const data = new Set(); - const pages = splitSet(pkgs, pageSize); - const batches = splitSet(pages, concurrency); + const rawDeps = await readUniversalTree(dir) + const pkgs = filterPkgs(rawDeps, filter) + + onPkgs(pkgs) + + const data = new Set() + const pages = splitSet(pkgs, pageSize) + const batches = splitSet(pages, concurrency) // Process each batch - - for (const batch of batches) { - + for (const batch of batches) { await Promise.all([...batch].map(async page => { - const fetchedData = await fetchData({ pkgs: page, token, url }); - + const fetchedData = await fetchData({ pkgs: page, token, url }) + for (const datum of fetchedData) { - data.add(datum); + data.add(datum) } - })); + })) } - return data } const filterPkgs = (pkgs, fn) => { const map = new Map() - let validCounter = 0; - let invalidCounter = 0; - let skippedCounter = 0; - + // let validCounter = 0 + // let invalidCounter = 0 + // let skippedCounter = 0 + for (const pkg of pkgs) { const id = `${pkg.name}${pkg.version}` if (!semver.valid(pkg.version)) { - invalidCounter++; + // invalidCounter++ - continue; + continue } - + if (map.get(id)) { - skippedCounter++; - continue; + // skippedCounter++ + continue } - + if (fn(pkg)) { map.set(id, pkg) - validCounter++; + // validCounter++ } else { - skippedCounter++; + // skippedCounter++ } } - + // Filtering complete const clean = new Set() @@ -236,69 +233,69 @@ const id = node => `${node.data.name}@${node.data.version}` // This function is only used as a fallback now, using the getNpmDependencies function // to directly extract package.json dependencies in our main workflow -async function readPackagesFromPackageJson(dir) { - const npmDeps = getNpmDependencies(dir); - - // Convert to the same format as the tree structure - const pkgJsonPath = path.join(dir, 'package.json'); - let pkgInfo = { name: path.basename(dir), version: '0.0.0' }; - - try { - if (fs.existsSync(pkgJsonPath)) { - const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')); - pkgInfo = { - name: pkgJson.name || pkgInfo.name, - version: pkgJson.version || pkgInfo.version - }; - } - } catch (err) { - // Ignore package.json errors - } - - // Create result structure - const result = { - data: pkgInfo, - children: [] - }; - - // Add all npm dependencies as children - for (const dep of npmDeps) { - result.children.push({ - data: { - name: dep.name, - version: dep.version - }, - children: [] - }); - } - - return result; -} +// async function readPackagesFromPackageJson(dir) { +// const npmDeps = getNpmDependencies(dir); + +// // Convert to the same format as the tree structure +// const pkgJsonPath = path.join(dir, 'package.json'); +// let pkgInfo = { name: path.basename(dir), version: '0.0.0' }; + +// try { +// if (fs.existsSync(pkgJsonPath)) { +// const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')); +// pkgInfo = { +// name: pkgJson.name || pkgInfo.name, +// version: pkgJson.version || pkgInfo.version +// }; +// } +// } catch (err) { +// // Ignore package.json errors +// } + +// // Create result structure +// const result = { +// data: pkgInfo, +// children: [] +// }; + +// // Add all npm dependencies as children +// for (const dep of npmDeps) { +// result.children.push({ +// data: { +// name: dep.name, +// version: dep.version +// }, +// children: [] +// }); +// } + +// return result; +// } const readUniversalTree = async dir => { - let treeResult; - + let treeResult + try { // Use our new dependency tree builder instead of universalModuleTree // First, find the main file from package.json or use typical entry points - const pkgJsonPath = path.join(dir, 'package.json'); - let mainFile = null; - let pkgJson = null; - + const pkgJsonPath = path.join(dir, 'package.json') + let mainFile = null + let pkgJson = null + if (fs.existsSync(pkgJsonPath)) { try { - pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')); + pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8')) if (pkgJson.main) { - mainFile = pkgJson.main; + mainFile = pkgJson.main } else if (pkgJson.bin) { // If there's no main but there is a bin field, use the first bin entry if (typeof pkgJson.bin === 'string') { - mainFile = pkgJson.bin; + mainFile = pkgJson.bin } else if (typeof pkgJson.bin === 'object') { // Use the first bin entry if it's an object - const firstBin = Object.values(pkgJson.bin)[0]; + const firstBin = Object.values(pkgJson.bin)[0] if (firstBin) { - mainFile = firstBin; + mainFile = firstBin } } } @@ -307,13 +304,13 @@ const readUniversalTree = async dir => { // Error reading package.json } } - + // Check if the main file exists, otherwise try common entry points if (mainFile && !fs.existsSync(path.join(dir, mainFile))) { // Main file not found, trying alternatives - mainFile = null; + mainFile = null } - + if (!mainFile) { // Try common entry points const possibleEntryPoints = [ @@ -323,32 +320,31 @@ const readUniversalTree = async dir => { 'main.js', 'bin/index.js', 'lib/index.js' - ]; - + ] + // If we have package.json info, try using the name as entry point if (pkgJson && pkgJson.name) { - possibleEntryPoints.unshift(`bin/${pkgJson.name}.js`); - possibleEntryPoints.unshift(`${pkgJson.name}.js`); + possibleEntryPoints.unshift(`bin/${pkgJson.name}.js`) + possibleEntryPoints.unshift(`${pkgJson.name}.js`) } - + for (const entryPoint of possibleEntryPoints) { if (fs.existsSync(path.join(dir, entryPoint))) { - mainFile = entryPoint; + mainFile = entryPoint - break; + break } } - + // If still no main file found, make one last attempt with bin directory if (!mainFile && fs.existsSync(path.join(dir, 'bin'))) { try { - const binFiles = fs.readdirSync(path.join(dir, 'bin')); + const binFiles = fs.readdirSync(path.join(dir, 'bin')) if (binFiles.length > 0) { // Use the first .js file in the bin directory - const jsFile = binFiles.find(file => file.endsWith('.js')); + const jsFile = binFiles.find(file => file.endsWith('.js')) if (jsFile) { - mainFile = `bin/${jsFile}`; - + mainFile = `bin/${jsFile}` } } } catch (e) { @@ -356,37 +352,37 @@ const readUniversalTree = async dir => { } } } - + // Starting dependency analysis - + // Build the dependency tree starting from the main file - treeResult = buildDependencyTree(mainFile, dir); - + treeResult = buildDependencyTree(mainFile, dir) + // We should always have dependencies from package.json now // but fall back to the old method if something goes wrong if (!treeResult || !treeResult.children || treeResult.children.length === 0) { // Using fallback package detection from package.json - treeResult = await readPackagesFromPackageJson(dir); + treeResult = await readPackagesFromPackageJson(dir) } } catch (err) { // Try to find packages by reading package.json try { // Using fallback package detection from package.json - treeResult = await readPackagesFromPackageJson(dir); + treeResult = await readPackagesFromPackageJson(dir) } catch (fallbackErr) { // Fallback also failed - return new Set(); + return new Set() } } - + // At this point, we must have a valid tree from either dependency-tree or package.json // Get packages from the tree structure const pkgs = new Map() const walk = (node, path) => { // Check if node is valid - if (!node || !node.data) return; - + if (!node || !node.data) return + let pkgObj if (pkgs.has(id(node))) { pkgObj = pkgs.get(id(node)) @@ -407,12 +403,12 @@ const readUniversalTree = async dir => { // Start walking from the tree structure if (treeResult instanceof Set) { // Direct Set result from readPackagesFromPackageJson - return treeResult; + return treeResult } - + // Now we know treeResult is an object, not a Set - const treeObj = treeResult; - + const treeObj = treeResult + if (treeObj && treeObj.data) { // Single root node case walk(treeObj, []) @@ -455,15 +451,15 @@ const fetchData = async ({ pkgs, token, url }) => { } const res = await graphql(url, query, variables) - + const data = new Set() for (const datum of res.packageVersions) { // datum.paths = [...pkgs][i].paths data.add(datum) } - + // Packages were evaluated by NCM service - + return data } @@ -483,64 +479,64 @@ const splitSet = (set, n) => { } // Function to read packages from package.json -async function readPackagesFromPackageJson(dir) { - const packageJsonPath = path.join(dir, 'package.json'); - +async function readPackagesFromPackageJson (dir) { + const packageJsonPath = path.join(dir, 'package.json') + // Check if package.json exists if (!fs.existsSync(packageJsonPath)) { // No package.json found - return new Set(); + return new Set() } - + // Read and parse package.json - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - const result = new Set(); - + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) + const result = new Set() + // Add the main package if (packageJson.name && packageJson.version) { result.add({ name: packageJson.name, version: packageJson.version - }); + }) } - + // Add dependencies if (packageJson.dependencies) { for (const [name, version] of Object.entries(packageJson.dependencies)) { // Clean up the version string (remove ^, ~, etc.) - const cleanVersion = version.replace(/[^\d.]/g, '') || version; + const cleanVersion = version.replace(/[^\d.]/g, '') || version result.add({ name, version: cleanVersion - }); + }) } } - + // Add devDependencies if (packageJson.devDependencies) { for (const [name, version] of Object.entries(packageJson.devDependencies)) { // Clean up the version string - const cleanVersion = version.replace(/[^\d.]/g, '') || version; + const cleanVersion = version.replace(/[^\d.]/g, '') || version result.add({ name, version: cleanVersion - }); + }) } } - + // Add peerDependencies if (packageJson.peerDependencies) { for (const [name, version] of Object.entries(packageJson.peerDependencies)) { // Clean up the version string - const cleanVersion = version.replace(/[^\d.]/g, '') || version; + const cleanVersion = version.replace(/[^\d.]/g, '') || version result.add({ name, version: cleanVersion - }); + }) } } - - return result; + + return result } module.exports = analyze diff --git a/lib/report/github-action.js b/lib/report/github-action.js index 87a714a..d6341ca 100644 --- a/lib/report/github-action.js +++ b/lib/report/github-action.js @@ -2,15 +2,15 @@ const fs = require('fs') // Update import for @actions/github to fix TypeScript error -let github; +let github try { - github = require('@actions/github'); + github = require('@actions/github') } catch (err) { // Provide fallbacks if the module is not available github = { context: { repo: { owner: '', repo: '' } }, getOctokit: () => ({}) - }; + } } const core = require('@actions/core') diff --git a/lib/util.js b/lib/util.js index f3fde26..5437de2 100644 --- a/lib/util.js +++ b/lib/util.js @@ -5,7 +5,7 @@ const readline = require('readline') const url = require('url') const pDefer = require('p-defer') const clientRequest = require('./client-request') -const { setTokens, api, ncmApi, getTokens, popValue } = require('./config') +const { setTokens, api, getTokens, popValue } = require('./config') const { formatError } = require('../lib/ncm-style') diff --git a/tap-snapshots/test/report.js.md b/tap-snapshots/test/report.js.md index 7b88d6b..2accec1 100644 --- a/tap-snapshots/test/report.js.md +++ b/tap-snapshots/test/report.js.md @@ -13,17 +13,17 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ |βž” Run \`ncm report --filter=security\` for a list␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -35,10 +35,9 @@ Generated by [AVA](https://avajs.dev).  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ β”‚ left-pad @ 1.3.0 (0) β”‚|||| Crit β”‚ X WTFPL β”‚ βœ“ 0 β”‚␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β”‚ handlebars @ 4.0.5 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1H β”‚␊ - β”‚ uglify-js @ 2.8.29 (0) β”‚|||| Crit β”‚ βœ“ BSD-2-Clause β”‚ βœ“ 0 β”‚␊ β”‚ brace-expansion @ 1.1.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1M β”‚␊ + β”‚ chalk @ 2.4.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ ` @@ -51,17 +50,17 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ |βž” Run \`ncm report --filter=security\` for a list␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ ␊ ! 1 used modules whitelisted␊ |βž” Run \`ncm whitelist --list\` for a list␊ @@ -75,7 +74,6 @@ Generated by [AVA](https://avajs.dev).  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ β”‚ left-pad @ 1.3.0 (0) β”‚|||| Crit β”‚ X WTFPL β”‚ βœ“ 0 β”‚␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ ` @@ -88,17 +86,17 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ |βž” Run \`ncm report --filter=security\` for a list␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ ␊ ! 1 used modules whitelisted␊ |βž” Run \`ncm whitelist --list\` for a list␊ @@ -112,7 +110,6 @@ Generated by [AVA](https://avajs.dev).  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ β”‚ left-pad @ 1.3.0 (0) β”‚|||| Crit β”‚ X WTFPL β”‚ βœ“ 0 β”‚␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ ` @@ -125,17 +122,17 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ |βž” Run \`ncm report --filter=security\` for a list␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ ␊ ! 1 used modules whitelisted␊ |βž” Run \`ncm whitelist --list\` for a list␊ @@ -149,7 +146,6 @@ Generated by [AVA](https://avajs.dev).  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ β”‚ left-pad @ 1.3.0 (0) β”‚|||| Crit β”‚ X WTFPL β”‚ βœ“ 0 β”‚␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ ` @@ -162,16 +158,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -189,7 +185,6 @@ Generated by [AVA](https://avajs.dev). ------------------------------------------------------------------------------------------------------␊  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β”‚ handlebars @ 4.0.5 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1H β”‚␊ β”‚ brace-expansion @ 1.1.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1M β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ @@ -204,16 +199,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -231,7 +226,6 @@ Generated by [AVA](https://avajs.dev). ------------------------------------------------------------------------------------------------------␊  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β”‚ handlebars @ 4.0.5 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1H β”‚␊ β”‚ brace-expansion @ 1.1.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1M β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ @@ -246,16 +240,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -273,7 +267,6 @@ Generated by [AVA](https://avajs.dev). ------------------------------------------------------------------------------------------------------␊  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β”‚ handlebars @ 4.0.5 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1H β”‚␊ β”‚ brace-expansion @ 1.1.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1M β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ @@ -288,16 +281,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -324,17 +317,17 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ |βž” Run \`ncm report --filter=security\` for a list␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -361,17 +354,17 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ |βž” Run \`ncm report --filter=security\` for a list␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -398,16 +391,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -434,16 +427,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -471,16 +464,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -508,16 +501,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -535,7 +528,6 @@ Generated by [AVA](https://avajs.dev). ------------------------------------------------------------------------------------------------------␊  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β”‚ handlebars @ 4.0.5 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1H β”‚␊ β”‚ brace-expansion @ 1.1.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1M β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ @@ -550,16 +542,16 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ! 1 used modules whitelisted␊ @@ -577,7 +569,6 @@ Generated by [AVA](https://avajs.dev). ------------------------------------------------------------------------------------------------------␊  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β”‚ handlebars @ 4.0.5 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1H β”‚␊ β”‚ brace-expansion @ 1.1.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1M β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ @@ -592,17 +583,17 @@ Generated by [AVA](https://avajs.dev). β•‘ mock-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 36 packages checked␊ + 4 packages checked␊ ␊ ! 0 critical risk␊ - 3 high risk␊ - 6 medium risk␊ - 13 low risk␊ + 1 high risk␊ + 3 medium risk␊ + 0 low risk␊ ␊ - ! 3 security vulnerabilities found across 3 modules␊ + ! 2 security vulnerabilities found across 2 modules␊ |βž” Run \`ncm report --filter=security\` for a list␊ ␊ - ! 2 noncompliant modules found␊ + ! 1 noncompliant modules found␊ |βž” Run \`ncm report --filter=compliance\` for a list␊ ␊ ──────────────────────────────────────────────────────────────────────────────────────────────────────␊ @@ -618,41 +609,9 @@ Generated by [AVA](https://avajs.dev).  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ β”‚ left-pad @ 1.3.0 (0) β”‚|||| Crit β”‚ X WTFPL β”‚ βœ“ 0 β”‚␊ - β”‚ ms @ 0.7.1 (0) β”‚|||| Crit β”‚ X UNKNOWN β”‚ X 1L β”‚␊ β”‚ handlebars @ 4.0.5 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1H β”‚␊ - β”‚ uglify-js @ 2.8.29 (0) β”‚|||| Crit β”‚ βœ“ BSD-2-Clause β”‚ βœ“ 0 β”‚␊ β”‚ brace-expansion @ 1.1.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ X 1M β”‚␊ β”‚ chalk @ 2.4.2 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ minimist @ 0.0.10 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ source-map @ 0.5.7 (0) β”‚|||| Crit β”‚ βœ“ BSD-3-Clause β”‚ βœ“ 0 β”‚␊ - β”‚ yargs @ 3.10.0 (0) β”‚|||| Crit β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ amdefine @ 1.0.1 (60) β”‚|||| Low  β”‚ βœ“ BSD-3-Clause OR MIT β”‚ βœ“ 0 β”‚␊ - β”‚ async @ 1.5.2 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ balanced-match @ 0.3.0 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ cliui @ 2.1.0 (60) β”‚|||| Low  β”‚ βœ“ ISC β”‚ βœ“ 0 β”‚␊ - β”‚ color-convert @ 1.9.3 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ concat-map @ 0.0.1 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ is-buffer @ 1.1.6 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ kind-of @ 3.2.2 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ optimist @ 0.6.1 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ source-map @ 0.4.4 (60) β”‚|||| Low  β”‚ βœ“ BSD-3-Clause β”‚ βœ“ 0 β”‚␊ - β”‚ window-size @ 0.1.0 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ wordwrap @ 0.0.2 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ wordwrap @ 0.0.3 (60) β”‚|||| Low  β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ align-text @ 0.1.4 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ ansi-styles @ 3.2.1 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ camelcase @ 1.2.1 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ center-align @ 0.1.3 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ color-name @ 1.1.3 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ decamelize @ 1.2.0 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ escape-string-regexp @ 1.0.5 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ has-flag @ 3.0.0 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ lazy-cache @ 1.0.4 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ longest @ 1.0.1 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ repeat-string @ 1.6.1 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ right-align @ 0.1.3 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ supports-color @ 5.5.0 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ uglify-to-browserify @ 1.0.2 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ ` @@ -665,7 +624,7 @@ Generated by [AVA](https://avajs.dev). β•‘ poisoned-project Report β•‘␊ β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•␊ ␊ - 3 packages checked␊ + 2 packages checked␊ ␊ ! 0 critical risk␊ 0 high risk␊ @@ -683,7 +642,6 @@ Generated by [AVA](https://avajs.dev).  Module Name Risk License Security␊ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”␊ β”‚ left-pad @ 1.3.0 (0) β”‚|||| Crit β”‚ X WTFPL β”‚ βœ“ 0 β”‚␊ - β”‚ is-path-inside @ 2.1.0 (100) β”‚|||| None β”‚ βœ“ MIT β”‚ βœ“ 0 β”‚␊ - β”‚ path-is-inside @ 1.0.2 (100) β”‚|||| None β”‚ βœ“ (WTFPL OR MIT) β”‚ βœ“ 0 β”‚␊ + β”‚ is-path-in-cwd @ 0.0.0 β”‚ β”‚ β”‚ β”‚␊ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜␊ ` diff --git a/tap-snapshots/test/report.js.snap b/tap-snapshots/test/report.js.snap index f4ea7b5..5eac048 100644 Binary files a/tap-snapshots/test/report.js.snap and b/tap-snapshots/test/report.js.snap differ diff --git a/test/report.js b/test/report.js index 02a48d9..6232d17 100644 --- a/test/report.js +++ b/test/report.js @@ -12,11 +12,11 @@ NCMTestRunner.createTest('report output matches snapshot', (runner, t) => { t.is(stderr, '') t.snapshot(stdout, 'report-output') t.regex(stdout, /mock-project Report/) - t.regex(stdout, /36 .+packages checked/) + t.regex(stdout, /4 .+packages checked/) t.regex(stdout, /handlebars @ 4.0.5/) t.notRegex(stdout, /has-flag @ 3.0.0/) - t.regex(stdout, /2 noncompliant modules found/) - t.regex(stdout, /3 security vulnerabilities found/) + t.regex(stdout, /1 noncompliant modules found/) + t.regex(stdout, /2 security vulnerabilities found/) resolve() }) }) @@ -31,12 +31,12 @@ NCMTestRunner.createTest('report --compliance output', (runner, t) => { t.snapshot(stdout, 'report-output-compliance') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) + t.regex(out, /1 noncompliant modules found/) t.regex(out, /left-pad @ 1.3.0/) - t.regex(out, /ms @ 0.7.1/) + t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /WTFPL/) - t.regex(out, /UNKNOWN/) - t.regex(out, /3 security vulnerabilities found/) + t.notRegex(out, /UNKNOWN/) + t.regex(out, /2 security vulnerabilities found/) resolve() }) }) @@ -50,10 +50,10 @@ NCMTestRunner.createTest('report -c output', (runner, t) => { t.snapshot(stdout, 'report-output-compliance') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) + t.regex(out, /1 noncompliant modules found/) t.regex(out, /left-pad @ 1.3.0/) t.regex(out, /WTFPL/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /2 security vulnerabilities found/) resolve() }) }) @@ -68,12 +68,12 @@ NCMTestRunner.createTest('report --filter=compliance output', (runner, t) => { t.snapshot(stdout, 'report-output-compliance') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) + t.regex(out, /1 noncompliant modules found/) t.regex(out, /left-pad @ 1.3.0/) - t.regex(out, /ms @ 0.7.1/) + t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /WTFPL/) - t.regex(out, /UNKNOWN/) - t.regex(out, /3 security vulnerabilities found/) + t.notRegex(out, /UNKNOWN/) + t.regex(out, /2 security vulnerabilities found/) resolve() }) }) @@ -87,10 +87,10 @@ NCMTestRunner.createTest('report --security output', (runner, t) => { t.snapshot(stdout, 'report-output-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) - t.regex(out, /ms @ 0.7.1/) + t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /brace-expansion @ 1.1.2/) t.regex(out, /debug @ 2.2.0/) t.regex(out, /1H/) @@ -109,8 +109,8 @@ NCMTestRunner.createTest('report -s output', (runner, t) => { t.snapshot(stdout, 'report-output-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) t.regex(out, /1H/) resolve() @@ -126,10 +126,10 @@ NCMTestRunner.createTest('report --filter=security output', (runner, t) => { t.snapshot(stdout, 'report-output-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) - t.regex(out, /ms @ 0.7.1/) + t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /brace-expansion @ 1.1.2/) t.regex(out, /debug @ 2.2.0/) t.regex(out, /1H/) @@ -149,8 +149,8 @@ NCMTestRunner.createTest('report --filter=high --security output', (runner, t) = t.snapshot(stdout, 'report-output-high-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) t.notRegex(out, /ms @ 0.7.1/) t.notRegex(out, /brace-expansion @ 1.1.2/) @@ -172,8 +172,8 @@ NCMTestRunner.createTest('report --filter=high output', (runner, t) => { t.snapshot(stdout, 'report-output-high-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) t.notRegex(out, /ms @ 0.7.1/) t.notRegex(out, /brace-expansion @ 1.1.2/) @@ -195,8 +195,8 @@ NCMTestRunner.createTest('report --filter=h output', (runner, t) => { t.snapshot(stdout, 'report-output-high-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) t.notRegex(out, /ms @ 0.7.1/) t.notRegex(out, /brace-expansion @ 1.1.2/) @@ -218,8 +218,8 @@ NCMTestRunner.createTest('report --filter=high,security output', (runner, t) => t.snapshot(stdout, 'report-output-high-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) t.notRegex(out, /ms @ 0.7.1/) t.notRegex(out, /brace-expansion @ 1.1.2/) @@ -241,8 +241,8 @@ NCMTestRunner.createTest('report --filter=medium --security output', (runner, t) t.snapshot(stdout, 'report-output-med-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /brace-expansion @ 1.1.2/) @@ -264,8 +264,8 @@ NCMTestRunner.createTest('report --filter=m --security output', (runner, t) => { t.snapshot(stdout, 'report-output-med-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /brace-expansion @ 1.1.2/) @@ -287,10 +287,10 @@ NCMTestRunner.createTest('report --filter=low --security output', (runner, t) => t.snapshot(stdout, 'report-output-med-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) - t.regex(out, /ms @ 0.7.1/) + t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /brace-expansion @ 1.1.2/) t.regex(out, /debug @ 2.2.0/) t.regex(out, /1H/) @@ -310,10 +310,10 @@ NCMTestRunner.createTest('report --filter=l --security output', (runner, t) => { t.snapshot(stdout, 'report-output-med-security') const out = stdout.toString() - t.regex(out, /2 noncompliant modules found/) - t.regex(out, /3 security vulnerabilities found/) + t.regex(out, /1 noncompliant modules found/) + t.regex(out, /2 security vulnerabilities found/) t.regex(out, /handlebars @ 4.0.5/) - t.regex(out, /ms @ 0.7.1/) + t.notRegex(out, /ms @ 0.7.1/) t.regex(out, /brace-expansion @ 1.1.2/) t.regex(out, /debug @ 2.2.0/) t.regex(out, /1H/) @@ -331,7 +331,7 @@ NCMTestRunner.createTest('report --long output matches snapshot', (runner, t) => t.is(stderr, '') t.snapshot(stdout, 'long-report-output') t.regex(stdout, /mock-project Report/) - t.regex(stdout, /has-flag @ 3.0.0/) + t.regex(stdout, /chalk @ 2.4.2/) resolve() }) })