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/configs/typescript.js b/lib/configs/typescript.js index d5981b14..ee592186 100644 --- a/lib/configs/typescript.js +++ b/lib/configs/typescript.js @@ -5,6 +5,8 @@ module.exports = { rules: { camelcase: 'off', 'no-unused-vars': 'off', + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 'on', '@typescript-eslint/interface-name-prefix': 'off', '@typescript-eslint/array-type': ['error', {default: 'array-simple'}], '@typescript-eslint/no-use-before-define': '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..2244024d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "eslint-plugin-github", - "version": "4.1.3", + "version": "4.1.4", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "4.1.3", + "version": "4.1.4", "license": "MIT", "dependencies": { "@typescript-eslint/eslint-plugin": "^4.20.0", @@ -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", @@ -1392,9 +1405,9 @@ } }, "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, @@ -1489,9 +1502,9 @@ } }, "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, "node_modules/ignore": { "version": "5.1.4", @@ -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", @@ -4135,9 +4155,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } @@ -4199,9 +4219,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, "ignore": { "version": "5.1.4", diff --git a/package.json b/package.json index e6d60533..e771e81f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-github", - "version": "4.1.3", + "version": "4.1.4", "description": "An opinionated collection of ESLint shared configs and rules used by GitHub.", "main": "lib/index.js", "entries": [ @@ -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"' + ] } ] })