diff --git a/lib/commands/info/index.js b/lib/commands/info/index.js index 6aebbaed..abee2416 100644 --- a/lib/commands/info/index.js +++ b/lib/commands/info/index.js @@ -115,6 +115,7 @@ function setupCommand (name, description, argv, importMeta) { * @typedef PackageData * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getIssuesByNPMPackage'>["data"]} data * @property {Record} severityCount + * @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getScoreByNPMPackage'>["data"]} score */ /** @@ -127,11 +128,16 @@ async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues, strict const socketSdk = await setupSdk(getDefaultKey() || FREE_API_KEY) const spinner = ora(`Looking up data for version ${pkgVersion} of ${pkgName}`).start() const result = await handleApiCall(socketSdk.getIssuesByNPMPackage(pkgName, pkgVersion), 'looking up package') + const scoreResult = await handleApiCall(socketSdk.getScoreByNPMPackage(pkgName, pkgVersion), 'looking up package score') if (result.success === false) { return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result, spinner) } + if (scoreResult.success === false) { + return handleUnsuccessfulApiResponse('getScoreByNPMPackage', scoreResult, spinner) + } + // Conclude the status of the API call const severityCount = getSeverityCount(result.data, includeAllIssues ? undefined : 'high') @@ -146,6 +152,7 @@ async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues, strict return { data: result.data, severityCount, + score: scoreResult.data } } @@ -154,10 +161,21 @@ async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues, strict * @param {{ name: string } & CommandContext} context * @returns {void} */ - function formatPackageDataOutput ({ data, severityCount }, { name, outputJson, outputMarkdown, pkgName, pkgVersion, strict }) { + function formatPackageDataOutput ({ data, severityCount, score }, { name, outputJson, outputMarkdown, pkgName, pkgVersion, strict }) { if (outputJson) { console.log(JSON.stringify(data, undefined, 2)) } else { + console.log('\nPackage report card:\n') + + const scoreResult = { + 'Supply Chain Risk': Math.floor(score.supplyChainRisk.score * 100), + 'Maintenance': Math.floor(score.maintenance.score * 100), + 'Quality': Math.floor(score.quality.score * 100), + 'Vulnerabilities': Math.floor(score.vulnerability.score * 100), + 'License': Math.floor(score.license.score * 100) + } + Object.entries(scoreResult).map(score => console.log(`- ${score[0]}: ${formatScore(score[1])}`)) + const format = new ChalkOrMarkdown(!!outputMarkdown) const url = `https://socket.dev/npm/package/${pkgName}/overview/${pkgVersion}` @@ -171,3 +189,21 @@ async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues, strict process.exit(1) } } + +/** + * @param {number} score + * @returns {string} + */ +function formatScore (score) { + const error = chalk.hex('#de7c7b') + const warning = chalk.hex('#e59361') + const success = chalk.hex('#a4cb9d') + + if (score > 80) { + return `${success(score)}` + } else if (score < 80 && score > 60) { + return `${warning(score)}` + } else { + return `${error(score)}` + } +}