stylelint-formatter-pretty
Advanced tools
Comparing version
229
index.js
@@ -0,4 +1,231 @@ | ||
import path from 'node:path'; | ||
import process from 'node:process'; | ||
import pico from 'picocolors'; | ||
import logSymbols from 'log-symbols'; | ||
import plur from 'plur'; | ||
import stringWidth from 'string-width'; | ||
import ansiEscapes from 'ansi-escapes'; | ||
import {supportsHyperlink} from 'supports-hyperlinks'; | ||
/** | ||
* @param {string|undefined} rule Stylelint rule | ||
* @param {import('stylelint').LinterResult} linterResult Linter result | ||
* @returns {string|undefined} URL | ||
*/ | ||
function getRuleUrl(rule, linterResult) { | ||
let ruleUrl; | ||
try { | ||
ruleUrl = linterResult.ruleMetadata[rule].url; | ||
} catch {} | ||
return ruleUrl; | ||
} | ||
/** | ||
* @type {import('stylelint').Formatter} | ||
*/ | ||
export {default} from './index.cjs'; | ||
function formatter(results, returnValue) { | ||
if (Array.isArray(results) && results.length > 0) { | ||
const lines = []; | ||
let errorCount = 0; | ||
let warningsCount = 0; | ||
let deprecationsCount = 0; | ||
let invalidOptionWarningsCount = 0; | ||
let maxLineWidth = 0; | ||
let maxColumnWidth = 0; | ||
let maxMessageWidth = 0; | ||
let showLineNumbers = false; | ||
let deprecations = []; | ||
let invalidOptionWarnings = []; | ||
const cleanUpAdditionals = items => items | ||
.sort((a, b) => a.text === b.text) | ||
.filter((item, idx, array) => array.findIndex(d => d.text === item.text) === idx) | ||
.map(item => ({ | ||
text: item.text.replaceAll(/\B"(.*?)"\B|\B'(.*?)'\B/g, (m, p1, p2) => pico.bold(p1 || p2)), | ||
})); | ||
results | ||
.sort((a, b) => a.warnings.length - b.warnings.length) | ||
.forEach(result => { | ||
const {warnings} = result; | ||
for (const x of result.deprecations) { | ||
deprecations.push(x); | ||
} | ||
for (const x of result.invalidOptionWarnings) { | ||
invalidOptionWarnings.push(x); | ||
} | ||
if (Array.isArray(result.parseErrors)) { | ||
for (const x of result.parseErrors) { | ||
warnings.push(x); | ||
} | ||
} | ||
if (warnings.length === 0) { | ||
return; | ||
} | ||
if (lines.length > 0) { | ||
lines.push({type: 'separator'}); | ||
} | ||
const filePath = result.source; | ||
lines.push({ | ||
type: 'header', | ||
filePath, | ||
relativeFilePath: path.relative('.', filePath), | ||
firstLineCol: warnings[0].line + ':' + warnings[0].column, | ||
}); | ||
warnings | ||
.sort((a, b) => { | ||
if (a.severity === b.severity) { | ||
if (a.line === b.line) { | ||
return a.column < b.column ? -1 : 1; | ||
} | ||
return a.line < b.line ? -1 : 1; | ||
} | ||
if (a.severity === 2 && b.severity !== 2) { | ||
return 1; | ||
} | ||
return -1; | ||
}) | ||
.forEach(x => { | ||
let message = x.text; | ||
// Remove rule ID from message | ||
message = message.replaceAll(/\s\(.+\)$/g, ''); | ||
// Stylize inline code blocks | ||
message = message.replaceAll(/\B"(.*?)"\B|\B'(.*?)'\B/g, (m, p1, p2) => pico.bold(p1 || p2)); | ||
const line = String(x.line || 0); | ||
const column = String(x.column || 0); | ||
const lineWidth = stringWidth(line); | ||
const columnWidth = stringWidth(column); | ||
const messageWidth = stringWidth(message); | ||
let severity = 'warning'; | ||
if (x.severity === 2 || x.severity === 'error') { | ||
severity = 'error'; | ||
errorCount++; | ||
} else { | ||
warningsCount++; | ||
} | ||
maxLineWidth = Math.max(lineWidth, maxLineWidth); | ||
maxColumnWidth = Math.max(columnWidth, maxColumnWidth); | ||
maxMessageWidth = Math.max(messageWidth, maxMessageWidth); | ||
showLineNumbers = showLineNumbers || x.line || x.column; | ||
lines.push({ | ||
type: 'message', | ||
severity, | ||
line, | ||
lineWidth, | ||
column, | ||
columnWidth, | ||
message, | ||
messageWidth, | ||
ruleId: x.rule || '', | ||
ruleUrl: getRuleUrl(x.rule, returnValue), | ||
}); | ||
}); | ||
}); | ||
deprecations = cleanUpAdditionals(deprecations); | ||
deprecationsCount = deprecations.length; | ||
invalidOptionWarnings = cleanUpAdditionals(invalidOptionWarnings); | ||
invalidOptionWarningsCount = invalidOptionWarnings.length; | ||
let output = '\n'; | ||
if (process.stdout.isTTY && !process.env.CI) { | ||
// Make relative paths Cmd+click'able in iTerm | ||
output += ansiEscapes.iTerm.setCwd(); | ||
} | ||
output += lines.map(x => { | ||
if (x.type === 'header') { | ||
// Add the line number so it's Cmd+click'able in some terminals | ||
// Use dim & gray for terminals like iTerm that doesn't support `hidden` | ||
const position = showLineNumbers ? pico.hidden(pico.dim(pico.gray(`:${x.firstLineCol}`))) : ''; | ||
return ' ' + pico.underline(x.relativeFilePath + position); | ||
} | ||
if (x.type === 'message') { | ||
const rule = (x.ruleUrl && supportsHyperlink(process.stdout) ? ansiEscapes.link(x.ruleId, x.ruleUrl) : x.ruleId); | ||
const line = [ | ||
'', | ||
x.severity === 'warning' ? logSymbols.warning : logSymbols.error, | ||
' '.repeat(maxLineWidth - x.lineWidth) + pico.dim(x.line + pico.gray(':') + x.column), | ||
' '.repeat(maxColumnWidth - x.columnWidth) + x.message, | ||
' '.repeat(maxMessageWidth - x.messageWidth) + pico.dim(rule), | ||
]; | ||
if (!showLineNumbers) { | ||
line.splice(2, 1); | ||
} | ||
return line.join(' '); | ||
} | ||
return ''; | ||
}).join('\n'); | ||
if (warningsCount + errorCount > 0) { | ||
output += '\n\n'; | ||
} | ||
if (deprecationsCount + invalidOptionWarningsCount > 0) { | ||
output += ` ${pico.underline('Stylelint Configuration')}\n`; | ||
} | ||
output += deprecations.map(x => ' ' + logSymbols.info + ' ' + x.text).join('\n'); | ||
if (deprecationsCount > 0) { | ||
output += '\n'; | ||
} | ||
output += invalidOptionWarnings.map(x => ' ' + logSymbols.error + ' ' + x.text).join('\n'); | ||
if (invalidOptionWarningsCount > 0) { | ||
output += '\n'; | ||
} | ||
if (deprecationsCount + invalidOptionWarningsCount > 0) { | ||
output += '\n'; | ||
} | ||
if (warningsCount > 0) { | ||
output += ' ' + pico.yellow(`${warningsCount} ${plur('warning', warningsCount)}`) + '\n'; | ||
} | ||
if (errorCount > 0) { | ||
output += ' ' + pico.red(`${errorCount} ${plur('error', errorCount)}`) + '\n'; | ||
} | ||
if (deprecationsCount > 0) { | ||
output += ' ' + pico.blue(`${deprecationsCount} ${plur('deprecation', deprecationsCount)}`) + '\n'; | ||
} | ||
if (invalidOptionWarningsCount > 0) { | ||
output += ' ' + pico.red(`${invalidOptionWarningsCount} invalid ${plur('option', invalidOptionWarningsCount)}`) + '\n'; | ||
} | ||
return (errorCount + warningsCount + deprecationsCount + invalidOptionWarningsCount) > 0 ? output : ''; | ||
} | ||
return ''; | ||
} | ||
export default formatter; |
{ | ||
"name": "stylelint-formatter-pretty", | ||
"version": "3.2.1", | ||
"version": "4.0.0", | ||
"description": "A pretty Stylelint formatter.", | ||
@@ -23,13 +23,6 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">=14" | ||
"node": ">=18.12.0" | ||
}, | ||
"type": "module", | ||
"main": "index.cjs", | ||
"module": "index.js", | ||
"exports": { | ||
".": { | ||
"require": "./index.cjs", | ||
"default": "./index.js" | ||
} | ||
}, | ||
"exports": "./index.js", | ||
"scripts": { | ||
@@ -40,3 +33,2 @@ "test": "xo && c8 ava", | ||
"files": [ | ||
"index.cjs", | ||
"index.js" | ||
@@ -53,19 +45,22 @@ ], | ||
"dependencies": { | ||
"ansi-escapes": "~4.3.2", | ||
"log-symbols": "~4.1.0", | ||
"ansi-escapes": "^6.2.0", | ||
"log-symbols": "^6.0.0", | ||
"picocolors": "^1.0.0", | ||
"plur": "~4.0.0", | ||
"string-width": "~4.2.2", | ||
"plur": "^5.1.0", | ||
"string-width": "^7.0.0", | ||
"supports-hyperlinks": "^3.0.0" | ||
}, | ||
"devDependencies": { | ||
"ava": "^5.3.0", | ||
"ava": "^6.0.1", | ||
"c8": "^8.0.0", | ||
"husky": "^8.0.1", | ||
"lint-staged": "^13.2.2", | ||
"lint-staged": "^15.2.0", | ||
"strip-ansi": "^7.1.0", | ||
"xo": "^0.54.2" | ||
"xo": "^0.56.0" | ||
}, | ||
"peerDependencies": { | ||
"stylelint": ">=16.0.0" | ||
}, | ||
"lint-staged": { | ||
"*.?({c,m})js": "xo --fix" | ||
"*.js": "xo --fix" | ||
}, | ||
@@ -72,0 +67,0 @@ "xo": { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
11615
-1.7%7
16.67%4
-20%185
-2.12%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated