diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 89043c52..00000000 --- a/.eslintrc.json +++ /dev/null @@ -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" - } - } - } -} diff --git a/.npmignore b/.npmignore index 70c3a72e..0b1a6d4f 100644 --- a/.npmignore +++ b/.npmignore @@ -1,5 +1,4 @@ .eslintignore -.eslintrc.json .github .markdownlint.json .npmrc @@ -8,6 +7,7 @@ coverage demo/* !demo/markdownlint-browser.js doc-build +eslint.config.mjs example micromark npm-debug.log diff --git a/demo/default.js b/demo/default.js index aede8ed5..27c01c2c 100644 --- a/demo/default.js +++ b/demo/default.js @@ -267,8 +267,7 @@ if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) { markdown.value = decodedHash.substring(hashPrefix.length); } - /* eslint-disable-next-line unicorn/prefer-optional-catch-binding */ - } catch (error) { + } catch { // Invalid } } @@ -277,8 +276,7 @@ try { /* eslint-disable-next-line no-new */ new URL("https://example.com/"); - /* eslint-disable-next-line unicorn/prefer-optional-catch-binding */ - } catch (error) { + } catch { markdown.value = [ "# Sorry", "", diff --git a/demo/markdownlint-browser.js b/demo/markdownlint-browser.js index 703ca7f4..20771a1e 100644 --- a/demo/markdownlint-browser.js +++ b/demo/markdownlint-browser.js @@ -1723,7 +1723,7 @@ function validateRuleList(ruleList, synchronous) { const allIds = {}; for (const [ index, rule ] of ruleList.entries()) { 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) { return new Error( `Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`); diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..0b4a3bab --- /dev/null +++ b/eslint.config.mjs @@ -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" + } + } +]; diff --git a/lib/markdownlint.js b/lib/markdownlint.js index 7cdeed91..86919b8e 100644 --- a/lib/markdownlint.js +++ b/lib/markdownlint.js @@ -32,7 +32,7 @@ function validateRuleList(ruleList, synchronous) { const allIds = {}; for (const [ index, rule ] of ruleList.entries()) { 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) { return new Error( `Property '${property}' of custom rule at index ${customIndex} is incorrect: '${value}'.`); diff --git a/package.json b/package.json index 729fc86d..f4fe58cc 100644 --- a/package.json +++ b/package.json @@ -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-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", - "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", "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", @@ -69,6 +69,7 @@ "markdownlint-micromark": "0.1.10" }, "devDependencies": { + "@eslint/js": "9.1.1", "ajv": "8.12.0", "ava": "6.1.2", "c8": "9.1.0", diff --git a/test/markdownlint-test-custom-rules.js b/test/markdownlint-test-custom-rules.js index becfe621..a4a527eb 100644 --- a/test/markdownlint-test-custom-rules.js +++ b/test/markdownlint-test-custom-rules.js @@ -1598,22 +1598,12 @@ test("customRulesLintJavaScript", (t) => new Promise((resolve) => { t.falsy(err); const expected = { "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, "ruleNames": [ "lint-javascript" ], "ruleDescription": "Rule that lints JavaScript code", "ruleInformation": null, - "errorDetail": "Unexpected console statement.", + "errorDetail": "'console' is not defined.", "errorContext": "console.log(x);", "errorRange": null, "fixInfo": null diff --git a/test/rules/lint-javascript.js b/test/rules/lint-javascript.js index 88b054b2..c2d5380c 100644 --- a/test/rules/lint-javascript.js +++ b/test/rules/lint-javascript.js @@ -2,54 +2,31 @@ "use strict"; +const js = require("@eslint/js"); const { filterTokens } = require("../../helpers"); const eslint = require("eslint"); -const eslintInstance = new eslint.ESLint(); const linter = new eslint.Linter(); 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 */ module.exports = { "names": [ "lint-javascript" ], "description": "Rule that lints JavaScript code", "tags": [ "test", "lint", "javascript" ], "parser": "markdownit", - "asynchronous": true, "function": (params, onError) => { filterTokens(params, "fence", (fence) => { if (languageJavaScript.test(fence.info)) { - return eslintInstance.calculateConfigForFile(params.name) - .then((config) => { - config = cleanJsdocRulesFromEslintConfig(config); - const results = linter.verify(fence.content, config); - for (const result of results) { - // @ts-ignore - const lineNumber = fence.lineNumber + result.line; - onError({ - "lineNumber": lineNumber, - "detail": result.message, - "context": params.lines[lineNumber - 1] - }); - } + const results = linter.verify(fence.content, js.configs.recommended); + for (const result of results) { + const lineNumber = fence.lineNumber + result.line; + onError({ + "lineNumber": lineNumber, + "detail": result.message, + "context": params.lines[lineNumber - 1] }); + } } - return Promise.resolve(); }); // Unsupported: // filterTokens("code_block"), language unknown