eslint-formatter-mo
Advanced tools
Comparing version
118
lib/index.js
@@ -1,5 +0,117 @@ | ||
import { createFormatter } from './formatter.js' | ||
/* eslint-disable no-magic-numbers */ | ||
const path = require( 'path' ) | ||
const chalk = require( 'chalk' ) | ||
const plur = require( 'plur' ) | ||
const stringWidth = require( 'string-width' ) | ||
const gradient = require( 'gradient-string' ) | ||
const link = require( 'terminal-link' ) | ||
const { locate } = require( './locator' ) | ||
const theme = process.env.MO_THEME ?? 'one-dark-pro' | ||
module.exports = function ( results ) { | ||
let totalErrorCount = 0 | ||
let totalWarningCount = 0 | ||
let autoFixableCount = 0 | ||
export default createFormatter(theme) | ||
const lines = [] | ||
results | ||
.forEach( result => { | ||
const { | ||
filePath, | ||
source, | ||
output, | ||
errorCount, | ||
warningCount, | ||
messages = [] | ||
} = result | ||
if ( errorCount + warningCount === 0 ) { | ||
return | ||
} | ||
totalErrorCount = totalErrorCount + errorCount | ||
totalWarningCount = totalWarningCount + warningCount | ||
const errorSummary = errorCount > 0 ? | ||
chalk.red.bold( errorCount + ' ' + plur( 'error', errorCount ) ) : | ||
'' | ||
const warningSummary = warningCount > 0 ? | ||
chalk.yellow.bold( | ||
`${ warningCount } ${ plur( 'warning', warningCount ) }` | ||
) : | ||
'' | ||
const relativePath = path.relative( '.', filePath ) | ||
const basename = path.basename( relativePath ) | ||
const dirname = path.dirname( relativePath ) + path.sep | ||
const formattedPath = chalk.dim( dirname ) + chalk.dim.bold( basename ) | ||
let header = '\n ' + link( formattedPath, `file://${ filePath }`, { | ||
fallback: () => formattedPath | ||
} ) + | ||
` 🔥${ errorCount > 0 ? ' ' : '' }` + | ||
[ errorSummary, warningSummary ].join( ' ' ) + | ||
`🔥\n` | ||
const divider = chalk.dim( '─'.repeat( stringWidth( header ) ) ) | ||
header = divider + header + divider | ||
lines.push( header ) | ||
const locations = messages.map( m => { | ||
let { message } = m | ||
message = message.replace( | ||
/\B`(.*?)`\B|\B'(.*?)'\B/g, | ||
( m, p1, p2 ) => chalk.bold( p1 || p2 ) | ||
) | ||
message = message.replace( /\s+$/, '' ) | ||
if ( m.fix ) { | ||
autoFixableCount = autoFixableCount + 1 | ||
} | ||
const severity = ( m.fatal || m.severity === 2 || m.severity === 'error' ) ? | ||
'error' : | ||
'warning' | ||
const line = Number( m.line || 0 ) | ||
const column = Number( m.column || 0 ) | ||
return { | ||
severity, | ||
message, | ||
line, | ||
column, | ||
fixable: Boolean( m.fix ), | ||
ruleId: m.ruleId, | ||
} | ||
} ) | ||
// Parsing error(e.g. using ts rules but missing tsconfig.json) | ||
if ( | ||
locations.length === 1 && | ||
locations[ 0 ].line === 0 && | ||
locations[ 0 ].column === 0 | ||
) { | ||
lines.push( `${ chalk.red( '✖' ) } ${ locations[ 0 ].message }` ) | ||
} else if ( source || output ) { | ||
try { | ||
const codeframe = locate( source || output, locations ) | ||
lines.push( codeframe ) | ||
} catch ( e ) { | ||
console.log( e ) | ||
} | ||
} | ||
} ) | ||
if ( totalErrorCount + totalWarningCount > 0 ) { | ||
const totalErrorMessage = chalk.redBright( ` ${ chalk.bold( totalErrorCount ) } ${ plur( 'error', totalErrorCount ) }` ) | ||
const totalWarningMessage = chalk.yellowBright( ` ${ chalk.bold( totalWarningCount ) } ${ plur( 'warning', totalWarningCount ) }` ) | ||
const totalFixableMessage = chalk.greenBright( ` ${ chalk.bold( autoFixableCount ) } ${ plur( 'auto-fixable', autoFixableCount ) } ( with the \`--fix\` flag )` ) | ||
const maxLen = stringWidth( totalFixableMessage ) + 1 | ||
return `\n${ lines.join( '\n' ) }\n` + | ||
`${ gradient.fruit( `─`.repeat( maxLen ) ) }\n` + | ||
`${ totalErrorMessage }\n${ totalWarningMessage }\n${ totalFixableMessage }\n` + | ||
`${ gradient.cristal( `─`.repeat( maxLen ) ) }\n` | ||
} | ||
return '' | ||
} |
@@ -1,4 +0,6 @@ | ||
import chalk from 'chalk' | ||
/* eslint-disable no-magic-numbers */ | ||
const chalk = require( 'chalk' ) | ||
const emphasize = require( 'emphasize' ) | ||
function locate( source, locations, highlight ) { | ||
function locate( source, locations ) { | ||
let lines = source.split( '\n' ) | ||
@@ -16,3 +18,12 @@ | ||
const formattedLines = highlight(source).split('\n') | ||
const formattedLines = emphasize.highlight( 'js', source, { | ||
keyword: chalk.magenta, | ||
built_in: chalk.cyan, // eslint-disable-line | ||
string: chalk.green, | ||
number: chalk.green, | ||
literal: chalk.green, | ||
'class': chalk.yellow, // eslint-disable-line | ||
'function': chalk.reset.white, // eslint-disable-line | ||
params: chalk.reset.white, | ||
} ).value.split( '\n' ) | ||
@@ -151,4 +162,2 @@ return lines | ||
export { | ||
locate | ||
} | ||
exports.locate = locate |
{ | ||
"name": "eslint-formatter-mo", | ||
"description": "Good-lookin' ESLint formatter for delightful readability", | ||
"version": "1.4.0", | ||
"type": "module", | ||
"exports": "./lib/index.js", | ||
"version": "1.4.1", | ||
"main": "lib/index.js", | ||
"files": [ | ||
@@ -11,6 +10,8 @@ "lib" | ||
"scripts": { | ||
"fixture": "eslint fixtures -f mo", | ||
"lint": "eslint lib -f mo", | ||
"lint:fix": "eslint lib -f mo --fix" | ||
"fixture": "eslint fixtures -f ./", | ||
"lint": "eslint lib -f ./" | ||
}, | ||
"eslintConfig": { | ||
"extends": "mo" | ||
}, | ||
"repository": { | ||
@@ -36,10 +37,8 @@ "type": "git", | ||
"dependencies": { | ||
"chalk": "^5.4.1", | ||
"gradient-string": "^3.0.0", | ||
"plur": "^5.1.0", | ||
"string-width": "^7.2.0", | ||
"terminal-link": "^3.0.0", | ||
"shiki": "^1.26.1", | ||
"@shikijs/themes": "^1.26.1", | ||
"@shikijs/langs": "^1.26.1" | ||
"chalk": "^3.0.0", | ||
"emphasize": "^4.2.0", | ||
"gradient-string": "^1.2.0", | ||
"plur": "^4.0.0", | ||
"string-width": "^4.2.0", | ||
"terminal-link": "^2.1.1" | ||
}, | ||
@@ -49,15 +48,7 @@ "devDependencies": { | ||
"@semantic-release/git": "^10.0.1", | ||
"eslint": "^9", | ||
"eslint": "^8.1.0", | ||
"eslint-config-mo": "^0.5.2", | ||
"semantic-release": "^19.0.3", | ||
"@eslint/js": "^9.17.0", | ||
"typescript-eslint": "^8.19.0", | ||
"eslint-plugin-import-x": "^4.6.1", | ||
"globals": "^15.14.0", | ||
"eslint-plugin-simple-import-sort": "^12.1.1" | ||
"semantic-release": "^19.0.3" | ||
}, | ||
"engines": { | ||
"node": ">=18" | ||
}, | ||
"packageManager": "pnpm@9.15.1" | ||
} |
@@ -14,7 +14,2 @@ # eslint-formatter-mo | ||
> [!NOTE] | ||
> This library was moved to ESM from v2. | ||
> | ||
> If ESM doesn't work well with your Node.js version, check the 1.x version for CJS compatibility. | ||
# Features | ||
@@ -29,7 +24,14 @@ | ||
- 📋 Total summary | ||
- 🥳 **Support 50+ VSCode Syntax themes (New feature from v2)** | ||
# Installation | ||
```shell | ||
```bash | ||
yarn add eslint-formatter-mo --dev | ||
``` | ||
or | ||
```bash | ||
npm i eslint-formatter-mo -D | ||
@@ -46,25 +48,4 @@ ``` | ||
See [ESLint Formatters](https://eslint.org/docs/latest/use/formatters/#eslint-formatters) for detail | ||
See [ESLint Formatters](https://eslint.org/docs/user-guide/formatters/#eslint-formatters) for detail | ||
# Themes | ||
Thanks to [shiki](https://github.com/shikijs/shiki), we now support 50+ VSCode syntax themes in v2. | ||
And you can choose your favorite theme by specifying `MO_THEME` environment variable. | ||
```shell | ||
MO_THEME=<theme_id> eslint [patterns] -f mo | ||
``` | ||
theme_id | preview | | ||
---------|---------- | ||
one-dark-pro | <img src="./media/themes/one-dark-pro.jpg" alt="one-dark-pro" width="360" /> | ||
dracula | <img src="./media/themes/dracula.jpg" alt="dracula" width="360" /> | ||
night-owl | <img src="./media/themes/night-owl.jpg" alt="night-owl" width="360" /> | ||
vitesse-dark | <img src="./media/themes/vitesse-dark.jpg" alt="vitesse-dark" width="360" /> | ||
nord | <img src="./media/themes/nord.jpg" alt="nord" width="360" /> | ||
... | ... | ||
[Here](https://shiki.style/themes) you can find all the 50+ themes. | ||
# More screenshots | ||
@@ -71,0 +52,0 @@ |
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
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
6
-25%5
-50%0
-100%0
-100%11748
-19.92%5
-37.5%232
-18.6%57
-25%No
NaN+ 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
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated