Update to ESLint 9's "flat" configuration file format.

This commit is contained in:
David Anson 2024-04-20 21:23:06 -07:00
parent 36844eefef
commit c6716f9bac
9 changed files with 155 additions and 191 deletions

View file

@ -1,140 +0,0 @@
{
"env": {
"node": true,
"es2021": true
},
"extends": [
"eslint:all",
"plugin:jsdoc/recommended",
"plugin:n/recommended",
"plugin:regexp/recommended",
"plugin:unicorn/all"
],
"ignorePatterns": [
"demo/markdown-it.min.js",
"demo/markdownlint-browser.js",
"demo/markdownlint-browser.min.js",
"demo/micromark-browser.js",
"demo/micromark-html-browser.js",
"example/typescript/type-check.js",
"micromark/micromark.cjs",
"micromark/micromark.dev.cjs",
"micromark/micromark-browser.js",
"micromark/micromark-browser.dev.js",
"test-repos/"
],
"overrides": [
{
"files": [
"demo/*.js"
],
"env": {
"browser": true
},
"rules": {
"jsdoc/require-jsdoc": "off",
"unicorn/prefer-query-selector": "off",
"unicorn/prefer-add-event-listener": "off",
"no-console": "off",
"no-invalid-this": "off",
"no-shadow": "off",
"no-var": "off"
}
},
{
"files": [
"example/*.js"
],
"rules": {
"n/no-extraneous-require": "off",
"n/no-missing-require": "off",
"no-console": "off",
"no-invalid-this": "off",
"no-shadow": "off",
"object-property-newline": "off"
}
},
{
"files": [
"test/rules/**/*.js"
],
"rules": {
"jsdoc/valid-types": "off"
}
},
{
"files": [
"**/*.mjs"
],
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module"
}
}
],
"parserOptions": {
"ecmaVersion": 2021,
"sourceType": "script"
},
"plugins": [
"jsdoc",
"n",
"regexp",
"unicorn"
],
"reportUnusedDisableDirectives": true,
"rules": {
"capitalized-comments": "off",
"complexity": "off",
"func-style": "off",
"id-length": "off",
"jsdoc/tag-lines": ["error", "never", {"startLines":1}],
"logical-assignment-operators": "off",
"max-depth": "off",
"max-lines-per-function": "off",
"max-lines": "off",
"max-params": "off",
"max-statements": "off",
"multiline-comment-style": ["error", "separate-lines"],
"no-empty-function": "off",
"no-implicit-coercion": "off",
"no-magic-numbers": "off",
"no-param-reassign": "off",
"no-plusplus": "off",
"no-ternary": "off",
"no-undefined": "off",
"object-shorthand": "off",
"one-var": "off",
"prefer-arrow-callback": "off",
"prefer-destructuring": "off",
"prefer-named-capture-group": "off",
"prefer-template": "off",
"regexp/no-super-linear-backtracking": "off",
"require-unicode-regexp": "off",
"sort-imports": "off",
"sort-keys": "off",
"unicorn/better-regex": "off",
"unicorn/consistent-function-scoping": "off",
"unicorn/filename-case": "off",
"unicorn/no-array-callback-reference": "off",
"unicorn/no-keyword-prefix": "off",
"unicorn/no-new-array": "off",
"unicorn/no-null": "off",
"unicorn/no-useless-undefined": "off",
"unicorn/prefer-at": "off",
"unicorn/prefer-module": "off",
"unicorn/prefer-string-replace-all": "off",
"unicorn/prefer-string-slice": "off",
"unicorn/prefer-switch": "off",
"unicorn/prevent-abbreviations": "off",
"unicorn/switch-case-braces": ["error", "avoid"],
"vars-on-top": "off"
},
"settings": {
"jsdoc": {
"preferredTypes": {
"object": "Object"
}
}
}
}

View file

@ -1,5 +1,4 @@
.eslintignore .eslintignore
.eslintrc.json
.github .github
.markdownlint.json .markdownlint.json
.npmrc .npmrc
@ -8,6 +7,7 @@ coverage
demo/* demo/*
!demo/markdownlint-browser.js !demo/markdownlint-browser.js
doc-build doc-build
eslint.config.mjs
example example
micromark micromark
npm-debug.log npm-debug.log

View file

@ -267,8 +267,7 @@
if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) { if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) {
markdown.value = decodedHash.substring(hashPrefix.length); markdown.value = decodedHash.substring(hashPrefix.length);
} }
/* eslint-disable-next-line unicorn/prefer-optional-catch-binding */ } catch {
} catch (error) {
// Invalid // Invalid
} }
} }
@ -277,8 +276,7 @@
try { try {
/* eslint-disable-next-line no-new */ /* eslint-disable-next-line no-new */
new URL("https://example.com/"); new URL("https://example.com/");
/* eslint-disable-next-line unicorn/prefer-optional-catch-binding */ } catch {
} catch (error) {
markdown.value = [ markdown.value = [
"# Sorry", "# Sorry",
"", "",

View file

@ -1723,7 +1723,7 @@ function validateRuleList(ruleList, synchronous) {
const allIds = {}; const allIds = {};
for (const [ index, rule ] of ruleList.entries()) { for (const [ index, rule ] of ruleList.entries()) {
const customIndex = index - rules.length; const customIndex = index - rules.length;
// eslint-disable-next-line no-inner-declarations, jsdoc/require-jsdoc // eslint-disable-next-line jsdoc/require-jsdoc
function newError(property, value) { function newError(property, value) {
return new Error( return new Error(
`Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`); `Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`);

138
eslint.config.mjs Normal file
View file

@ -0,0 +1,138 @@
import js from "@eslint/js";
import eslintPluginJsdoc from "eslint-plugin-jsdoc";
import eslintPluginNode from "eslint-plugin-n";
import eslintPluginRegexp from "eslint-plugin-regexp"
import eslintPluginUnicorn from "eslint-plugin-unicorn";
export default [
js.configs.all,
eslintPluginJsdoc.configs['flat/recommended'],
eslintPluginNode.configs["flat/recommended"],
eslintPluginRegexp.configs["flat/recommended"],
eslintPluginUnicorn.configs["flat/all"],
{
"ignores": [
"demo/markdown-it.min.js",
"demo/markdownlint-browser.js",
"demo/markdownlint-browser.min.js",
"demo/micromark-browser.js",
"demo/micromark-html-browser.js",
"example/typescript/type-check.js",
"micromark/micromark.cjs",
"micromark/micromark.dev.cjs",
"micromark/micromark-browser.js",
"micromark/micromark-browser.dev.js",
"test-repos/**"
]
},
{
"languageOptions": {
"sourceType": "commonjs",
},
"linterOptions": {
"reportUnusedDisableDirectives": true
},
"rules": {
"capitalized-comments": "off",
"complexity": "off",
"func-style": "off",
"id-length": "off",
"jsdoc/tag-lines": [ "error", "never", { "startLines":1 } ],
"logical-assignment-operators": "off",
"max-depth": "off",
"max-lines-per-function": "off",
"max-lines": "off",
"max-params": "off",
"max-statements": "off",
"multiline-comment-style": [ "error", "separate-lines" ],
"no-empty-function": "off",
"no-implicit-coercion": "off",
"no-magic-numbers": "off",
"no-param-reassign": "off",
"no-plusplus": "off",
"no-ternary": "off",
"no-undefined": "off",
"no-useless-assignment": "off",
"object-shorthand": "off",
"one-var": "off",
"prefer-arrow-callback": "off",
"prefer-destructuring": "off",
"prefer-named-capture-group": "off",
"prefer-template": "off",
"regexp/no-super-linear-backtracking": "off",
"require-unicode-regexp": "off",
"sort-imports": "off",
"sort-keys": "off",
"unicorn/better-regex": "off",
"unicorn/consistent-function-scoping": "off",
"unicorn/filename-case": "off",
"unicorn/no-array-callback-reference": "off",
"unicorn/no-keyword-prefix": "off",
"unicorn/no-new-array": "off",
"unicorn/no-null": "off",
"unicorn/no-useless-undefined": "off",
"unicorn/prefer-at": "off",
"unicorn/prefer-module": "off",
"unicorn/prefer-string-replace-all": "off",
"unicorn/prefer-string-slice": "off",
"unicorn/prefer-switch": "off",
"unicorn/prevent-abbreviations": "off",
"unicorn/switch-case-braces": [ "error", "avoid" ],
"vars-on-top": "off"
},
"settings": {
"jsdoc": {
"preferredTypes": {
"object": "Object"
}
}
}
},
{
"files": [
"**/*.mjs"
],
"languageOptions": {
"sourceType": "module"
}
},
{
"files": [
"demo/*.js"
],
"languageOptions": {
"globals": {
"alert": "readonly",
"document": "readonly",
"navigator": "readonly",
"window": "readonly"
}
},
"rules": {
"jsdoc/require-jsdoc": "off",
"no-invalid-this": "off",
"no-shadow": "off",
"no-var": "off",
"unicorn/prefer-query-selector": "off"
}
},
{
"files": [
"example/*.js"
],
"rules": {
"n/no-missing-require": "off",
"no-console": "off",
"no-invalid-this": "off",
"no-shadow": "off"
}
},
{
"files": [
"test/rules/**/*.js"
],
"rules": {
"jsdoc/valid-types": "off"
}
}
];

View file

@ -32,7 +32,7 @@ function validateRuleList(ruleList, synchronous) {
const allIds = {}; const allIds = {};
for (const [ index, rule ] of ruleList.entries()) { for (const [ index, rule ] of ruleList.entries()) {
const customIndex = index - rules.length; const customIndex = index - rules.length;
// eslint-disable-next-line no-inner-declarations, jsdoc/require-jsdoc // eslint-disable-next-line jsdoc/require-jsdoc
function newError(property, value) { function newError(property, value) {
return new Error( return new Error(
`Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`); `Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`);

View file

@ -49,7 +49,7 @@
"docker-npm-install": "docker run --rm --tty --name npm-install --volume $PWD:/home/workdir --workdir /home/workdir --user node node:latest npm install", "docker-npm-install": "docker run --rm --tty --name npm-install --volume $PWD:/home/workdir --workdir /home/workdir --user node node:latest npm install",
"docker-npm-run-upgrade": "docker run --rm --tty --name npm-run-upgrade --volume $PWD:/home/workdir --workdir /home/workdir --user node node:latest npm run upgrade", "docker-npm-run-upgrade": "docker run --rm --tty --name npm-run-upgrade --volume $PWD:/home/workdir --workdir /home/workdir --user node node:latest npm run upgrade",
"install-micromark": "cd micromark && npm install", "install-micromark": "cd micromark && npm install",
"lint": "eslint --ext .js,.cjs,.mjs --max-warnings 0 .", "lint": "eslint --max-warnings 0",
"lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos-*.js", "lint-test-repos": "ava --timeout=10m test/markdownlint-test-repos-*.js",
"serial-config-docs": "npm run build-config && npm run build-docs", "serial-config-docs": "npm run build-config && npm run build-docs",
"serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration", "serial-declaration-demo": "npm run build-declaration && npm-run-all --continue-on-error --parallel build-demo test-declaration",
@ -69,6 +69,7 @@
"markdownlint-micromark": "0.1.10" "markdownlint-micromark": "0.1.10"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "9.1.1",
"ajv": "8.12.0", "ajv": "8.12.0",
"ava": "6.1.2", "ava": "6.1.2",
"c8": "9.1.0", "c8": "9.1.0",

View file

@ -1598,22 +1598,12 @@ test("customRulesLintJavaScript", (t) => new Promise((resolve) => {
t.falsy(err); t.falsy(err);
const expected = { const expected = {
"test/lint-javascript.md": [ "test/lint-javascript.md": [
{
"lineNumber": 10,
"ruleNames": [ "lint-javascript" ],
"ruleDescription": "Rule that lints JavaScript code",
"ruleInformation": null,
"errorDetail": "Unexpected var, use let or const instead.",
"errorContext": "var x = 0;",
"errorRange": null,
"fixInfo": null
},
{ {
"lineNumber": 12, "lineNumber": 12,
"ruleNames": [ "lint-javascript" ], "ruleNames": [ "lint-javascript" ],
"ruleDescription": "Rule that lints JavaScript code", "ruleDescription": "Rule that lints JavaScript code",
"ruleInformation": null, "ruleInformation": null,
"errorDetail": "Unexpected console statement.", "errorDetail": "'console' is not defined.",
"errorContext": "console.log(x);", "errorContext": "console.log(x);",
"errorRange": null, "errorRange": null,
"fixInfo": null "fixInfo": null

View file

@ -2,54 +2,31 @@
"use strict"; "use strict";
const js = require("@eslint/js");
const { filterTokens } = require("../../helpers"); const { filterTokens } = require("../../helpers");
const eslint = require("eslint"); const eslint = require("eslint");
const eslintInstance = new eslint.ESLint();
const linter = new eslint.Linter(); const linter = new eslint.Linter();
const languageJavaScript = /js|javascript/i; const languageJavaScript = /js|javascript/i;
/**
* Remove references to rules from eslint-plugin-jsdoc.
*
* @param {Object} config ESLint configuration object.
* @returns {Object} ESLint configuration object.
*/
function cleanJsdocRulesFromEslintConfig(config) {
const cleanedConfig = { ...config };
for (const rule in config.rules) {
if (/^(?:jsdoc|n|regexp|unicorn)\//.test(rule)) {
delete cleanedConfig.rules[rule];
}
}
return cleanedConfig;
}
/** @type import("../../lib/markdownlint").Rule */ /** @type import("../../lib/markdownlint").Rule */
module.exports = { module.exports = {
"names": [ "lint-javascript" ], "names": [ "lint-javascript" ],
"description": "Rule that lints JavaScript code", "description": "Rule that lints JavaScript code",
"tags": [ "test", "lint", "javascript" ], "tags": [ "test", "lint", "javascript" ],
"parser": "markdownit", "parser": "markdownit",
"asynchronous": true,
"function": (params, onError) => { "function": (params, onError) => {
filterTokens(params, "fence", (fence) => { filterTokens(params, "fence", (fence) => {
if (languageJavaScript.test(fence.info)) { if (languageJavaScript.test(fence.info)) {
return eslintInstance.calculateConfigForFile(params.name) const results = linter.verify(fence.content, js.configs.recommended);
.then((config) => { for (const result of results) {
config = cleanJsdocRulesFromEslintConfig(config); const lineNumber = fence.lineNumber + result.line;
const results = linter.verify(fence.content, config); onError({
for (const result of results) { "lineNumber": lineNumber,
// @ts-ignore "detail": result.message,
const lineNumber = fence.lineNumber + result.line; "context": params.lines[lineNumber - 1]
onError({
"lineNumber": lineNumber,
"detail": result.message,
"context": params.lines[lineNumber - 1]
});
}
}); });
}
} }
return Promise.resolve();
}); });
// Unsupported: // Unsupported:
// filterTokens("code_block"), language unknown // filterTokens("code_block"), language unknown