UNPKG

msync

Version:

Easily manage building and syncing multiple node-modules in a flexibly defined workspace.

193 lines (192 loc) 9.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.audit = exports.cmd = exports.args = exports.description = exports.alias = exports.name = void 0; var tslib_1 = require("tslib"); var common_1 = require("../common"); exports.name = 'audit'; exports.alias = ['a']; exports.description = 'Runs an NPM security audit across all modules.'; exports.args = {}; function cmd(args) { return tslib_1.__awaiter(this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4, audit()]; case 1: _a.sent(); return [2]; } }); }); } exports.cmd = cmd; function audit() { return tslib_1.__awaiter(this, void 0, void 0, function () { var settings, startedAt, res, totalIssues, msg; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: return [4, (0, common_1.loadSettings)({ npm: true, spinner: true })]; case 1: settings = _a.sent(); if (!settings) { common_1.log.warn.yellow(common_1.constants.CONFIG_NOT_FOUND_ERROR); return [2]; } common_1.log.info.gray("Auditing modules:\n"); startedAt = new Date(); return [4, runAudits(settings.modules, { concurrent: true, exitOnError: false, })]; case 2: res = _a.sent(); totalIssues = res.data.reduce(function (acc, next) { return acc + next.issues; }, 0); if (totalIssues > 0) { printAudit(res.data); } if (res.success) { msg = totalIssues === 0 ? common_1.log.green("All modules are safe.") : 'Done'; common_1.log.info("\n\u2728\u2728 ".concat(msg, " ").concat(common_1.log.gray((0, common_1.elapsed)(startedAt)), "\n")); } else { common_1.log.info.yellow("\n\uD83D\uDCA9 Something went wrong while running the audit.\n"); } return [2]; } }); }); } exports.audit = audit; function levelColor(level) { switch (level) { case 'info': return common_1.log.white; case 'low': case 'moderate': return common_1.log.yellow; case 'high': case 'critical': return common_1.log.red; } } function printAudit(results) { var head = [common_1.log.gray('module'), common_1.log.red('vulnerabilities')]; var builder = common_1.log.table({ head: head, border: false }); results .filter(function (audit) { return !audit.ok; }) .forEach(function (audit) { var bullet = audit.ok ? common_1.log.green('✔') : common_1.log.red('✖'); var output = Object.keys(audit.vulnerabilities) .map(function (key) { return ({ key: key, value: audit.vulnerabilities[key] }); }) .reduce(function (acc, next) { var text = next.value > 0 ? common_1.log.gray("".concat(next.key, ": ").concat(levelColor(next.key)(next.value))) : ''; return text ? "".concat(acc, " ").concat(text) : acc; }, '') .trim(); builder.add([ common_1.log.gray("".concat(bullet, " ").concat(common_1.log.cyan(audit.module), " ").concat(audit.version, " ")), output || common_1.log.green('safe'), ]); }); common_1.log.info(); builder.log(); } function runAudits(modules, options) { return tslib_1.__awaiter(this, void 0, void 0, function () { var data, task, tasks, runner, error_1; var _this = this; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: data = []; task = function (pkg) { return { title: "".concat(common_1.log.cyan(pkg.name), " ").concat(common_1.log.gray('npm audit')), task: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { var npmLockFile, hasNpmLock, cmd, commands, json, vulnerabilities, issues, result; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: npmLockFile = common_1.fs.join(pkg.dir, 'package-lock.json'); return [4, common_1.fs.pathExists(npmLockFile)]; case 1: hasNpmLock = _a.sent(); cmd = function (text) { return "cd ".concat(pkg.dir, " && ").concat(text); }; commands = { install: cmd("npm install"), audit: cmd("npm audit --json"), }; return [4, common_1.exec.cmd.run(commands.install, { silent: true })]; case 2: _a.sent(); return [4, execToJson(commands.audit)]; case 3: json = _a.sent(); if (json && json.error) { throw new Error(json.error.summary); } vulnerabilities = json ? json.metadata.vulnerabilities : []; issues = Object.keys(vulnerabilities) .map(function (key) { return ({ key: key, value: vulnerabilities[key] }); }) .reduce(function (acc, next) { return (next.value > 0 ? acc + next.value : acc); }, 0); if (!!hasNpmLock) return [3, 5]; return [4, common_1.fs.remove(npmLockFile)]; case 4: _a.sent(); _a.label = 5; case 5: result = { module: pkg.name, version: pkg.version, ok: issues === 0, issues: issues, vulnerabilities: vulnerabilities, }; data = tslib_1.__spreadArray(tslib_1.__spreadArray([], data, true), [result], false); return [2, result]; } }); }); }, }; }; tasks = modules.map(function (pkg) { return task(pkg); }); runner = (0, common_1.listr)(tasks, options); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4, runner.run()]; case 2: _a.sent(); return [2, { success: true, data: data, error: null }]; case 3: error_1 = _a.sent(); return [2, { success: false, data: data, error: error_1 }]; case 4: return [2]; } }); }); } function execToJson(cmd) { return tslib_1.__awaiter(this, void 0, void 0, function () { var done, res, error_2; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: done = function (stdout, error) { return JSON.parse(stdout); }; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4, common_1.exec.cmd.run(cmd, { silent: true })]; case 2: res = _a.sent(); return [2, done(res.info.join('\n'))]; case 3: error_2 = _a.sent(); return [2, done(error_2.stdout)]; case 4: return [2]; } }); }); }