diff --git a/.eslintrc.js b/.eslintrc.js index 685ceff2..744c5e61 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,5 +7,11 @@ module.exports = { es6: true, node: true }, - extends: [require.resolve('./lib/configs/recommended')] + extends: [require.resolve('./lib/configs/recommended'), 'plugin:eslint-plugin/all'], + plugins: ['eslint-plugin'], + rules: { + 'eslint-plugin/prefer-placeholders': 'off', + 'eslint-plugin/test-case-shorthand-strings': 'off', + 'eslint-plugin/require-meta-docs-url': 'off' + } } diff --git a/lib/formatters/stylish-fixes.js b/lib/formatters/stylish-fixes.js index 3cde74c8..4b977175 100644 --- a/lib/formatters/stylish-fixes.js +++ b/lib/formatters/stylish-fixes.js @@ -12,6 +12,7 @@ try { } const getRuleURI = require('eslint-rule-documentation') +// eslint-disable-next-line eslint-plugin/prefer-object-rule module.exports = function (results) { let output = '\n' let errors = 0 diff --git a/lib/rules/array-foreach.js b/lib/rules/array-foreach.js index f7e7a55f..279e9687 100644 --- a/lib/rules/array-foreach.js +++ b/lib/rules/array-foreach.js @@ -12,7 +12,7 @@ module.exports = { return { CallExpression(node) { if (node.callee.property && node.callee.property.name === 'forEach') { - context.report(node, 'Prefer for...of instead of Array.forEach') + context.report({node, message: 'Prefer for...of instead of Array.forEach'}) } } } diff --git a/lib/rules/async-currenttarget.js b/lib/rules/async-currenttarget.js index 40c4f98f..d96c43ba 100644 --- a/lib/rules/async-currenttarget.js +++ b/lib/rules/async-currenttarget.js @@ -19,7 +19,7 @@ module.exports = { if (node.property && node.property.name === 'currentTarget') { const scope = context.getScope() if (scope.block.async && scopeDidWait.has(scope)) { - context.report(node, 'event.currentTarget inside an async function is error prone') + context.report({node, message: 'event.currentTarget inside an async function is error prone'}) } } } diff --git a/lib/rules/async-preventdefault.js b/lib/rules/async-preventdefault.js index fa05ccd9..208d99a6 100644 --- a/lib/rules/async-preventdefault.js +++ b/lib/rules/async-preventdefault.js @@ -19,7 +19,7 @@ module.exports = { if (node.callee.property && node.callee.property.name === 'preventDefault') { const scope = context.getScope() if (scope.block.async && scopeDidWait.has(scope)) { - context.report(node, 'event.preventDefault() inside an async function is error prone') + context.report({node, message: 'event.preventDefault() inside an async function is error prone'}) } } } diff --git a/lib/rules/authenticity-token.js b/lib/rules/authenticity-token.js index 43a0da44..cccd881a 100644 --- a/lib/rules/authenticity-token.js +++ b/lib/rules/authenticity-token.js @@ -11,10 +11,11 @@ module.exports = { create(context) { function checkAuthenticityTokenUsage(node, str) { if (str.includes('authenticity_token')) { - context.report( + context.report({ node, - 'Form CSRF tokens (authenticity tokens) should not be created in JavaScript and their values should not be used directly for XHR requests.' - ) + message: + 'Form CSRF tokens (authenticity tokens) should not be created in JavaScript and their values should not be used directly for XHR requests.' + }) } } diff --git a/lib/rules/js-class-name.js b/lib/rules/js-class-name.js index 78a3b273..f4fe8580 100644 --- a/lib/rules/js-class-name.js +++ b/lib/rules/js-class-name.js @@ -17,14 +17,14 @@ module.exports = { const matches = str.match(allJsClassNameRegexp) || [] for (const match of matches) { if (!match.match(validJsClassNameRegexp)) { - context.report(node, 'js- class names should be lowercase and only contain dashes.') + context.report({node, message: 'js- class names should be lowercase and only contain dashes.'}) } } } function checkStringEndsWithJSClassName(node, str) { if (str.match(endWithJsClassNameRegexp)) { - context.report(node, 'js- class names should be statically defined.') + context.report({node, message: 'js- class names should be statically defined.'}) } } diff --git a/lib/rules/no-blur.js b/lib/rules/no-blur.js index 796cb3ff..1d979d4c 100644 --- a/lib/rules/no-blur.js +++ b/lib/rules/no-blur.js @@ -1,16 +1,18 @@ -module.exports = function (context) { - return { - meta: { - type: 'problem', - docs: { - description: 'disallow usage of `Element.prototype.blur()`', - url: require('../url')(module) - }, - schema: [] +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'disallow usage of `Element.prototype.blur()`', + url: require('../url')(module) }, - CallExpression(node) { - if (node.callee.property && node.callee.property.name === 'blur') { - context.report(node, 'Do not use element.blur(), instead restore the focus of a previous element.') + schema: [] + }, + create(context) { + return { + CallExpression(node) { + if (node.callee.property && node.callee.property.name === 'blur') { + context.report({node, message: 'Do not use element.blur(), instead restore the focus of a previous element.'}) + } } } } diff --git a/lib/rules/no-dataset.js b/lib/rules/no-dataset.js index 5f7b5ede..e3c0ab4b 100644 --- a/lib/rules/no-dataset.js +++ b/lib/rules/no-dataset.js @@ -12,7 +12,7 @@ module.exports = { return { MemberExpression(node) { if (node.property && node.property.name === 'dataset') { - context.report(node, "Use getAttribute('data-your-attribute') instead of dataset.") + context.report({node, message: "Use getAttribute('data-your-attribute') instead of dataset."}) } } } diff --git a/lib/rules/no-implicit-buggy-globals.js b/lib/rules/no-implicit-buggy-globals.js index 39992213..4a3af069 100644 --- a/lib/rules/no-implicit-buggy-globals.js +++ b/lib/rules/no-implicit-buggy-globals.js @@ -25,7 +25,7 @@ module.exports = { (def.type === 'Variable' && def.parent.kind === 'const') || (def.type === 'Variable' && def.parent.kind === 'let') ) { - context.report(def.node, 'Implicit global variable, assign as global property instead.') + context.report({node: def.node, message: 'Implicit global variable, assign as global property instead.'}) } } } diff --git a/lib/rules/no-then.js b/lib/rules/no-then.js index f53517f4..76656245 100644 --- a/lib/rules/no-then.js +++ b/lib/rules/no-then.js @@ -12,9 +12,9 @@ module.exports = { return { MemberExpression(node) { if (node.property && node.property.name === 'then') { - context.report(node.property, 'Prefer async/await to Promise.then()') + context.report({node: node.property, message: 'Prefer async/await to Promise.then()'}) } else if (node.property && node.property.name === 'catch') { - context.report(node.property, 'Prefer async/await to Promise.catch()') + context.report({node: node.property, message: 'Prefer async/await to Promise.catch()'}) } } } diff --git a/lib/rules/require-passive-events.js b/lib/rules/require-passive-events.js index 8af46a59..bce8787b 100644 --- a/lib/rules/require-passive-events.js +++ b/lib/rules/require-passive-events.js @@ -20,7 +20,7 @@ module.exports = { if (name.type !== 'Literal') return if (!passiveEventListenerNames.has(name.value)) return if (options && options.type === 'ObjectExpression' && options.properties.some(propIsPassiveTrue)) return - context.report(node, `High Frequency Events like "${name.value}" should be \`passive: true\``) + context.report({node, message: `High Frequency Events like "${name.value}" should be \`passive: true\``}) } } } diff --git a/lib/url.js b/lib/url.js index 30e162e1..2af0e08c 100644 --- a/lib/url.js +++ b/lib/url.js @@ -1,5 +1,6 @@ const {homepage, version} = require('../package.json') const path = require('path') +// eslint-disable-next-line eslint-plugin/prefer-object-rule module.exports = ({id}) => { const url = new URL(homepage) const rule = path.basename(id, '.js') diff --git a/package-lock.json b/package-lock.json index ce2686a3..81a09441 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "eslint-plugin-prettier": "^3.3.1", "eslint-rule-documentation": ">=1.0.0", "prettier": "^2.2.1", - "svg-element-attributes": ">=1.3.1" + "svg-element-attributes": "^1.3.1" }, "bin": { "eslint-ignore-errors": "bin/eslint-ignore-errors.js" @@ -24,6 +24,7 @@ "devDependencies": { "@github/prettier-config": "0.0.4", "eslint": "7.23.0", + "eslint-plugin-eslint-plugin": "^2.3.0", "eslint-visitor-keys": "^2.0.0", "globals": "^13.7.0", "mocha": "^8.3.2" @@ -962,6 +963,18 @@ "eslint": ">=4.19.1" } }, + "node_modules/eslint-plugin-eslint-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.3.0.tgz", + "integrity": "sha512-xER9XjfTLrAgoUzPguPKoreDGtXt2vUnwqAqdElNrkcSbl5K1rGtSOmhgbiqCb7UN4spnjNhIZplHMNWY6Kz/w==", + "dev": true, + "engines": { + "node": "^6.14.0 || ^8.10.0 || >=9.10.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, "node_modules/eslint-plugin-import": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", @@ -3850,6 +3863,13 @@ "ignore": "^5.0.5" } }, + "eslint-plugin-eslint-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.3.0.tgz", + "integrity": "sha512-xER9XjfTLrAgoUzPguPKoreDGtXt2vUnwqAqdElNrkcSbl5K1rGtSOmhgbiqCb7UN4spnjNhIZplHMNWY6Kz/w==", + "dev": true, + "requires": {} + }, "eslint-plugin-import": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", diff --git a/package.json b/package.json index e6d60533..a46edc2d 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "devDependencies": { "@github/prettier-config": "0.0.4", "eslint": "7.23.0", + "eslint-plugin-eslint-plugin": "^2.3.0", "eslint-visitor-keys": "^2.0.0", "globals": "^13.7.0", "mocha": "^8.3.2" diff --git a/tests/get-attribute.js b/tests/get-attribute.js index 440aa5bc..2d29312e 100644 --- a/tests/get-attribute.js +++ b/tests/get-attribute.js @@ -21,36 +21,37 @@ ruleTester.run('get-attribute', rule, { invalid: [ { code: "el.getAttribute('SRC')", + output: "el.getAttribute('src')", errors: [ { message: 'Attributes should be lowercase and hyphen separated, or part of the SVG whitelist.', type: 'Literal' } - ], - output: "el.getAttribute('src')" + ] }, { code: "el.hasAttribute('SRC')", + output: "el.hasAttribute('src')", errors: [ { message: 'Attributes should be lowercase and hyphen separated, or part of the SVG whitelist.', type: 'Literal' } - ], - output: "el.hasAttribute('src')" + ] }, { code: "el.getAttribute('onClick')", + output: "el.getAttribute('onclick')", errors: [ { message: 'Attributes should be lowercase and hyphen separated, or part of the SVG whitelist.', type: 'Literal' } - ], - output: "el.getAttribute('onclick')" + ] }, { code: "el.getAttribute('viewbox')", + output: null, errors: [ { message: 'Attributes should be lowercase and hyphen separated, or part of the SVG whitelist.', @@ -60,6 +61,7 @@ ruleTester.run('get-attribute', rule, { }, { code: "el.getAttribute('preserveaspectratio')", + output: null, errors: [ { message: 'Attributes should be lowercase and hyphen separated, or part of the SVG whitelist.', diff --git a/tests/no-innerText.js b/tests/no-innerText.js index 89832df4..3da2cb94 100644 --- a/tests/no-innerText.js +++ b/tests/no-innerText.js @@ -15,23 +15,23 @@ ruleTester.run('no-innerText', rule, { invalid: [ { code: 'document.createElement("js-flash-text").innerText = "foo"', + output: 'document.createElement("js-flash-text").textContent = "foo"', errors: [ { message: 'Prefer textContent to innerText', type: 'Identifier' } - ], - output: 'document.createElement("js-flash-text").textContent = "foo"' + ] }, { code: 'document.querySelector("js-flash-text").innerText = "bar"', + output: 'document.querySelector("js-flash-text").textContent = "bar"', errors: [ { message: 'Prefer textContent to innerText', type: 'Identifier' } - ], - output: 'document.querySelector("js-flash-text").textContent = "bar"' + ] } ] })