UNPKG

npm-check-updates

Version:

Find newer versions of dependencies than what your package.json allows

287 lines 11.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.printIgnoredUpdates = exports.printUpgrades = exports.printUpgradesTable = exports.toDependencyTable = exports.printSorted = exports.printSimpleJoinedString = exports.printJson = exports.print = void 0; /** * Loggin functions. */ const cli_table3_1 = __importDefault(require("cli-table3")); const transform_1 = __importDefault(require("lodash/transform")); const chalk_1 = __importDefault(require("./chalk")); const filterObject_1 = __importDefault(require("./filterObject")); const getRepoUrl_1 = __importDefault(require("./getRepoUrl")); const version_util_1 = require("./version-util"); // maps string levels to numeric levels const logLevels = { silent: 0, error: 1, minimal: 2, warn: 3, info: 4, verbose: 5, silly: 6, }; /** Returns true if the dependency spec is not fetchable from the registry and is ignored. */ const isFetchable = (spec) => !spec.startsWith('file:') && !spec.startsWith('link:') && !spec.startsWith('workspace:') && // short github urls that are ignored, e.g. raineorshine/foo !/^[^/:@]+\/\w+/.test(spec); /** * Prints a message if it is included within options.loglevel. * * @param options Command line options. These will be compared to the loglevel parameter to determine if the message gets printed. * @param message The message to print * @param loglevel silent|error|warn|info|verbose|silly * @param method The console method to call. Default: 'log'. */ function print(options, message, loglevel = null, method = 'log') { var _a; // not in json mode // not silent // not at a loglevel under minimum specified if (!options.json && options.loglevel !== 'silent' && (loglevel == null || logLevels[((_a = options.loglevel) !== null && _a !== void 0 ? _a : 'warn')] >= logLevels[loglevel])) { console[method](message); } } exports.print = print; /** Pretty print a JSON object. */ function printJson(options, object) { if (options.loglevel !== 'silent') { console.log(JSON.stringify(object, null, 2)); } } exports.printJson = printJson; /** Print JSON object keys as string joined by character. */ function printSimpleJoinedString(object, join) { console.log(Object.keys(object) .map(pkg => pkg + '@' + object[pkg]) .join(join)); } exports.printSimpleJoinedString = printSimpleJoinedString; /** Prints an object sorted by key. */ function printSorted(options, obj, loglevel) { // eslint-disable-next-line fp/no-mutating-methods const sortedKeys = Object.keys(obj).sort(); const objSorted = (0, transform_1.default)(sortedKeys, (accum, key) => { accum[key] = obj[key]; }, {}); print(options, objSorted, loglevel); } exports.printSorted = printSorted; /** Create a table with the appropriate columns and alignment to render dependency upgrades. */ function renderDependencyTable(rows) { const table = new cli_table3_1.default({ colAligns: ['left', 'right', 'right', 'right', 'left', 'left'], chars: { top: '', 'top-mid': '', 'top-left': '', 'top-right': '', bottom: '', 'bottom-mid': '', 'bottom-left': '', 'bottom-right': '', left: '', 'left-mid': '', mid: '', 'mid-mid': '', right: '', 'right-mid': '', middle: '', }, }); // eslint-disable-next-line fp/no-mutating-methods table.push(...rows); // when border is removed, whitespace remains // trim the end of each line to remove whitespace // this makes no difference visually, but the whitespace interacts poorly with .editorconfig in tests return table .toString() .split('\n') .map(line => line.trimEnd()) .join('\n'); } /** * Extract just the version number from a package.json dep * * @param dep Raw dependency, could be version / npm: string / Git url */ function getVersion(dep) { return (0, version_util_1.isGithubUrl)(dep) ? (0, version_util_1.getGithubUrlTag)(dep) : (0, version_util_1.isNpmAlias)(dep) ? (0, version_util_1.parseNpmAlias)(dep)[1] : dep; } /** * Renders a color-coded table of upgrades. * * @param args * @param args.from * @param args.to * @param args.ownersChangedDeps * @param args.format */ async function toDependencyTable({ from: fromDeps, to: toDeps, format, ownersChangedDeps, pkgFile, time, }) { const table = renderDependencyTable(await Promise.all( // eslint-disable-next-line fp/no-mutating-methods Object.keys(toDeps) .sort() .map(async (dep) => { const from = fromDeps[dep] || ''; const toRaw = toDeps[dep] || ''; const to = getVersion(toRaw); const ownerChanged = ownersChangedDeps ? dep in ownersChangedDeps ? ownersChangedDeps[dep] ? '*owner changed*' : '' : '*unknown*' : ''; const toColorized = (0, version_util_1.colorizeDiff)(getVersion(from), to); const repoUrl = (format === null || format === void 0 ? void 0 : format.includes('repo')) ? (await (0, getRepoUrl_1.default)(dep, undefined, { pkgFile })) || '' : ''; const publishTime = (format === null || format === void 0 ? void 0 : format.includes('time')) && (time === null || time === void 0 ? void 0 : time[dep]) ? time[dep] : ''; return [dep, from, '→', toColorized, ownerChanged, ...[repoUrl, publishTime].filter(x => x)]; }))); return table; } exports.toDependencyTable = toDependencyTable; /** * Renders one or more color-coded tables with all upgrades. Supports different formats from the --format option. * * @param args * @param args.current * @param args.upgraded * @param args.ownersChangedDeps * @param options */ async function printUpgradesTable({ current, upgraded, ownersChangedDeps, pkgFile, time, }, options) { var _a, _b; // group if ((_a = options.format) === null || _a === void 0 ? void 0 : _a.includes('group')) { const groups = (0, version_util_1.getDependencyGroups)(upgraded, current, options); // eslint-disable-next-line fp/no-loops -- We must await in each iteration of the loop for (const { heading, packages } of groups) { print(options, '\n' + heading); print(options, await toDependencyTable({ from: current, to: packages, format: options.format, ownersChangedDeps, pkgFile, time, })); } } else { if ((_b = options.format) === null || _b === void 0 ? void 0 : _b.includes('lines')) { printSimpleJoinedString(upgraded, '\n'); } else { print(options, await toDependencyTable({ from: current, to: upgraded, format: options.format, ownersChangedDeps, pkgFile, time, })); } } } exports.printUpgradesTable = printUpgradesTable; /** Prints errors. */ function printErrors(options, errors) { if (!errors) return; if (Object.keys(errors).length > 0) { const errorTable = new cli_table3_1.default({ colAligns: ['left', 'right', 'right', 'right', 'left', 'left'], chars: { top: '', 'top-mid': '', 'top-left': '', 'top-right': '', bottom: '', 'bottom-mid': '', 'bottom-left': '', 'bottom-right': '', left: '', 'left-mid': '', mid: '', 'mid-mid': '', right: '', 'right-mid': '', middle: '', }, }); // eslint-disable-next-line fp/no-mutating-methods errorTable.push(...Object.entries(errors).map(([dep, error]) => [dep, chalk_1.default.yellow(error)])); print(options, '\n' + errorTable.toString()); } } /** * @param args.current - * @param args.latest - * @param args.upgraded - * @param args.total - * @param args.ownersChangedDeps - */ async function printUpgrades(options, { current, latest, upgraded, total, ownersChangedDeps, pkgFile, time, errors, }) { var _a; if (!((_a = options.format) === null || _a === void 0 ? void 0 : _a.includes('group'))) { print(options, ''); } const smiley = chalk_1.default.green.bold(':)'); const numErrors = Object.keys(errors || {}).length; const target = typeof options.target === 'string' ? options.target : 'target'; const numUpgraded = Object.keys(upgraded).length; if (numUpgraded === 0 && total === 0 && numErrors === 0) { if (Object.keys(current).length === 0) { print(options, 'No dependencies.'); } else if (latest && Object.keys(latest).length === 0 && // some specs are ignored by ncu, like the file: protocol, so they should be ignored when detecting fetch issues Object.values((0, filterObject_1.default)(current, (name, spec) => isFetchable(spec))).length > 0) { print(options, `No package versions were returned. This may be a problem with your installed ${options.packageManager}, the npm registry, or your Internet connection. Make sure ${chalk_1.default.cyan('npx pacote packument ncu-test-v2')} is working before reporting an issue.`); } else if (options.global) { print(options, `All global packages are up-to-date ${smiley}`); } else { print(options, `All dependencies match the ${target} package versions ${smiley}`); } } else if (numUpgraded === 0 && total > 0) { print(options, `No dependencies upgraded ${smiley}`); } // print table else if (numUpgraded > 0) { await printUpgradesTable({ current, upgraded, ownersChangedDeps, pkgFile, time, }, options); } printErrors(options, errors); } exports.printUpgrades = printUpgrades; /** Print updates that were ignored due to incompatible peer dependencies. */ function printIgnoredUpdates(options, ignoredUpdates) { print(options, `\nIgnored incompatible updates (peer dependencies):\n`); const table = renderDependencyTable(Object.entries(ignoredUpdates).map(([pkgName, { from, to, reason }]) => { const strReason = 'reason: ' + Object.entries(reason) .map(([pkgReason, requirement]) => pkgReason + ' requires ' + requirement) .join(', '); return [pkgName, from, '→', (0, version_util_1.colorizeDiff)(from, to), strReason]; })); print(options, table); } exports.printIgnoredUpdates = printIgnoredUpdates; //# sourceMappingURL=logging.js.map