| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- // NOTICE: This file is generated by Rollup. To modify it,
- // please instead edit the ESM counterpart and rebuild with Rollup (npm run build).
- 'use strict';
- const node_path = require('node:path');
- const process = require('node:process');
- const table = require('table');
- const picocolors = require('picocolors');
- const stringWidth = require('string-width');
- const validateTypes = require('../utils/validateTypes.cjs');
- const calcSeverityCounts = require('./calcSeverityCounts.cjs');
- const isUnicodeSupported = require('../utils/isUnicodeSupported.cjs');
- const pluralize = require('../utils/pluralize.cjs');
- const preprocessWarnings = require('./preprocessWarnings.cjs');
- const terminalLink = require('./terminalLink.cjs');
- const { yellow, dim, underline, blue, red, green } = picocolors;
- const NON_ASCII_PATTERN = /\P{ASCII}/u;
- const MARGIN_WIDTHS = 9;
- /**
- * @param {string} s
- * @returns {string}
- */
- function identity(s) {
- return s;
- }
- const levelColors = {
- info: blue,
- warning: yellow,
- error: red,
- success: identity,
- };
- const supportsUnicode = isUnicodeSupported();
- const symbols = {
- info: blue(supportsUnicode ? 'ℹ' : 'i'),
- warning: yellow(supportsUnicode ? '⚠' : '‼'),
- error: red(supportsUnicode ? '✖' : '×'),
- success: green(supportsUnicode ? '✔' : '√'),
- };
- /**
- * @param {import('stylelint').LintResult[]} results
- * @returns {string}
- */
- function deprecationsFormatter(results) {
- const allDeprecationWarnings = results.flatMap((result) => result.deprecations || []);
- if (allDeprecationWarnings.length === 0) {
- return '';
- }
- const seenText = new Set();
- const lines = [];
- for (const { text, reference } of allDeprecationWarnings) {
- if (seenText.has(text)) continue;
- seenText.add(text);
- let line = ` ${dim('-')} ${text}`;
- if (reference) {
- line += dim(` See: ${underline(reference)}`);
- }
- lines.push(line);
- }
- return ['', yellow('Deprecation warnings:'), ...lines, ''].join('\n');
- }
- /**
- * @param {import('stylelint').LintResult[]} results
- * @returns {string}
- */
- function invalidOptionsFormatter(results) {
- const allInvalidOptionWarnings = results.flatMap((result) =>
- (result.invalidOptionWarnings || []).map((warning) => warning.text),
- );
- const uniqueInvalidOptionWarnings = [...new Set(allInvalidOptionWarnings)];
- return uniqueInvalidOptionWarnings.reduce((output, warning) => {
- output += red('Invalid Option: ');
- output += warning;
- return `${output}\n`;
- }, '\n');
- }
- /**
- * @param {string} fromValue
- * @param {string} cwd
- * @returns {string}
- */
- function logFrom(fromValue, cwd) {
- if (fromValue.startsWith('<')) {
- return underline(fromValue);
- }
- const filePath = node_path.relative(cwd, fromValue).split(node_path.sep).join('/');
- return terminalLink(filePath, `file://${fromValue}`);
- }
- /**
- * @param {{[k: number]: number}} columnWidths
- * @returns {number}
- */
- function getMessageWidth(columnWidths) {
- const width = columnWidths[3];
- validateTypes.assertNumber(width);
- if (!process.stdout.isTTY) {
- return width;
- }
- const availableWidth = process.stdout.columns < 80 ? 80 : process.stdout.columns;
- const fullWidth = Object.values(columnWidths).reduce((a, b) => a + b);
- // If there is no reason to wrap the text, we won't align the last column to the right
- if (availableWidth > fullWidth + MARGIN_WIDTHS) {
- return width;
- }
- return availableWidth - (fullWidth - width + MARGIN_WIDTHS);
- }
- /**
- * @param {import('stylelint').Warning[]} messages
- * @param {string} source
- * @param {string} cwd
- * @returns {string}
- */
- function formatter(messages, source, cwd) {
- if (messages.length === 0) return '';
- /**
- * Create a list of column widths, needed to calculate
- * the size of the message column and if needed wrap it.
- * @type {{[k: string]: number}}
- */
- const columnWidths = { 0: 1, 1: 1, 2: 1, 3: 1, 4: 1 };
- /**
- * @param {[string, string, string, string, string]} columns
- * @returns {[string, string, string, string, string]}
- */
- function calculateWidths(columns) {
- for (const [key, value] of Object.entries(columns)) {
- const normalisedValue = value ? value.toString() : value;
- const width = columnWidths[key];
- validateTypes.assertNumber(width);
- columnWidths[key] = Math.max(width, stringWidth(normalisedValue));
- }
- return columns;
- }
- let output = '\n';
- if (source) {
- output += `${logFrom(source, cwd)}\n`;
- }
- /**
- * @param {import('stylelint').Warning} message
- * @returns {string}
- */
- function formatMessageText(message) {
- let result = message.text;
- result = result
- // Remove all control characters (newline, tab and etc)
- .replace(/[\u0001-\u001A]+/g, ' ') // eslint-disable-line no-control-regex
- .replace(/\.$/, '');
- const ruleString = ` (${message.rule})`;
- if (result.endsWith(ruleString)) {
- result = result.slice(0, result.lastIndexOf(ruleString));
- }
- return result;
- }
- const cleanedMessages = messages.map((message) => {
- const { line, column, severity } = message;
- /**
- * @type {[string, string, string, string, string]}
- */
- const row = [
- line ? line.toString() : '',
- column ? column.toString() : '',
- symbols[severity] ? levelColors[severity](symbols[severity]) : severity,
- formatMessageText(message),
- dim(message.rule || ''),
- ];
- calculateWidths(row);
- return row;
- });
- const messageWidth = getMessageWidth(columnWidths);
- const hasNonAsciiChar = messages.some((msg) => NON_ASCII_PATTERN.test(msg.text));
- output += table.table(cleanedMessages, {
- border: table.getBorderCharacters('void'),
- columns: {
- 0: { alignment: 'right', width: columnWidths[0], paddingRight: 0, paddingLeft: 2 },
- 1: { alignment: 'left', width: columnWidths[1] },
- 2: { alignment: 'center', width: columnWidths[2] },
- 3: {
- alignment: 'left',
- width: messageWidth,
- wrapWord: messageWidth > 1 && !hasNonAsciiChar,
- },
- 4: { alignment: 'left', width: columnWidths[4], paddingRight: 0 },
- },
- drawHorizontalLine: () => false,
- })
- .split('\n')
- .map((el) => el.replace(/(\d+)\s+(\d+)/, (_m, p1, p2) => dim(`${p1}:${p2}`)).trimEnd())
- .join('\n');
- return output;
- }
- /**
- * @type {import('stylelint').Formatter}
- */
- function stringFormatter(results, returnValue) {
- let output = invalidOptionsFormatter(results);
- output += deprecationsFormatter(results);
- const resultCounts = { error: 0, warning: 0 };
- const fixableCounts = { error: 0, warning: 0 };
- output = results.reduce((accum, result) => {
- preprocessWarnings(result);
- accum += formatter(
- result.warnings,
- result.source || '',
- (returnValue && returnValue.cwd) || process.cwd(),
- );
- for (const warning of result.warnings) {
- calcSeverityCounts(warning.severity, resultCounts);
- const fixable = returnValue.ruleMetadata?.[warning.rule]?.fixable;
- if (fixable === true) {
- calcSeverityCounts(warning.severity, fixableCounts);
- }
- }
- return accum;
- }, output);
- // Ensure consistent padding
- output = output.trim();
- if (output !== '') {
- output = `\n${output}\n`;
- const errorCount = resultCounts.error;
- const warningCount = resultCounts.warning;
- const total = errorCount + warningCount;
- if (total > 0) {
- const error = red(`${errorCount} ${pluralize('error', errorCount)}`);
- const warning = yellow(`${warningCount} ${pluralize('warning', warningCount)}`);
- const symbol = errorCount > 0 ? symbols.error : symbols.warning;
- output += `\n${symbol} ${total} ${pluralize('problem', total)} (${error}, ${warning})`;
- }
- const fixErrorCount = fixableCounts.error;
- const fixWarningCount = fixableCounts.warning;
- if (fixErrorCount > 0 || fixWarningCount > 0) {
- let fixErrorText;
- let fixWarningText;
- if (fixErrorCount > 0) {
- fixErrorText = `${fixErrorCount} ${pluralize('error', fixErrorCount)}`;
- }
- if (fixWarningCount > 0) {
- fixWarningText = `${fixWarningCount} ${pluralize('warning', fixWarningCount)}`;
- }
- const countText = [fixErrorText, fixWarningText].filter(Boolean).join(' and ');
- output += `\n ${countText} potentially fixable with the "--fix" option.`;
- }
- output += '\n\n';
- }
- return output;
- }
- module.exports = stringFormatter;
|