diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 317dd08..0cdd562 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - eslint: [7] + eslint: [8] node: [16] include: # On other platforms @@ -26,10 +26,8 @@ jobs: os: ubuntu-latest - node: 12 os: ubuntu-latest - - node: 10 - os: ubuntu-latest # On the minimum supported ESLint/Node.js version - - node: 10.12.0 + - node: 12.22.0 os: ubuntu-latest runs-on: ${{ matrix.os }} diff --git a/README.md b/README.md index 0f80663..8166746 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ npm install --save-dev eslint @mysticatea/eslint-plugin ### Requirements -- Node.js `^10.12.0 || >=12.0.0` or newer versions. -- ESLint `^7.0.0` or newer versions. +- Node.js `^12.22.0 || ^14.17.0 || >=16.0.0` or newer versions. +- ESLint `^8.0.0` or newer versions. ## 📖 Usage diff --git a/lib/configs/_override-vue.js b/lib/configs/_override-vue.js index 1b4ec25..d53a912 100644 --- a/lib/configs/_override-vue.js +++ b/lib/configs/_override-vue.js @@ -77,10 +77,7 @@ module.exports = { "error", { singleline: 3, - multiline: { - max: 1, - allowFirstLine: false, - }, + multiline: 1, }, ], "@mysticatea/vue/max-len": ["error", { tabWidth: 4 }], diff --git a/lib/processors/vue.js b/lib/processors/vue.js index b6aa629..be211ea 100644 --- a/lib/processors/vue.js +++ b/lib/processors/vue.js @@ -22,7 +22,7 @@ module.exports = { } // Filter messages which are in disabled area. - return messages[0].filter(message => { + return messages[0].filter((message) => { if (message.ruleId === "@mysticatea/vue/comment-directive") { const rules = message.message.split(" ") const type = rules.shift() diff --git a/lib/rules/arrow-parens.js b/lib/rules/arrow-parens.js index 3736763..45bf21e 100644 --- a/lib/rules/arrow-parens.js +++ b/lib/rules/arrow-parens.js @@ -30,8 +30,7 @@ module.exports = { description: "enforce the parentheses style of arrow functions.", category: "Stylistic Issues", recommended: false, - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/arrow-parens.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/arrow-parens.md", }, fixable: "code", schema: [], diff --git a/lib/rules/block-scoped-var.js b/lib/rules/block-scoped-var.js index b212809..7d774ca 100644 --- a/lib/rules/block-scoped-var.js +++ b/lib/rules/block-scoped-var.js @@ -9,8 +9,10 @@ // Helpers //------------------------------------------------------------------------------ -const scopeNodeType = /^(?:(?:Block|Switch|For(?:In|Of)?)Statement|CatchClause|Program)$/u -const containerNodeType = /^(?:For(?:In|Of)?Statement|(?:Arrow)?Function(?:Declaration|Expression))$/u +const scopeNodeType = + /^(?:(?:Block|Switch|For(?:In|Of)?)Statement|CatchClause|Program)$/u +const containerNodeType = + /^(?:For(?:In|Of)?Statement|(?:Arrow)?Function(?:Declaration|Expression))$/u /** * Checks whether or not a given definition should be skipped. @@ -196,8 +198,7 @@ module.exports = { description: "disallow illegal usage of variables as block-scoped.", category: "Possible Errors", recommended: false, - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/block-scoped-var.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/block-scoped-var.md", }, fixable: null, schema: [], diff --git a/lib/rules/no-instanceof-array.js b/lib/rules/no-instanceof-array.js index 5cc1e54..2cb8734 100644 --- a/lib/rules/no-instanceof-array.js +++ b/lib/rules/no-instanceof-array.js @@ -14,8 +14,7 @@ module.exports = { docs: { description: "disallow 'instanceof' for Array", category: "Best Practices", - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-instanceof-array.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-instanceof-array.md", }, fixable: "code", schema: [], @@ -64,7 +63,7 @@ module.exports = { loc: node.loc, message: "Unexpected 'instanceof' operator. Use 'Array.isArray' instead.", - fix: fixer => + fix: (fixer) => fixer.replaceText( node, `Array.isArray(${sourceCode.getText( diff --git a/lib/rules/no-instanceof-wrapper.js b/lib/rules/no-instanceof-wrapper.js index c30ee6b..f35bf2e 100644 --- a/lib/rules/no-instanceof-wrapper.js +++ b/lib/rules/no-instanceof-wrapper.js @@ -14,8 +14,7 @@ module.exports = { docs: { description: "disallow 'instanceof' for wrapper objects", category: "Best Practices", - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-instanceof-wrapper.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-instanceof-wrapper.md", }, fixable: "code", schema: [], @@ -76,7 +75,7 @@ module.exports = { message: "Unexpected 'instanceof' operator. Use 'typeof x === \"{{typeName}}\"' instead.", data: { typeName }, - fix: fixer => + fix: (fixer) => fixer.replaceText( node, `typeof ${sourceCode.getText( diff --git a/lib/rules/no-literal-call.js b/lib/rules/no-literal-call.js index a6973dd..6733c5e 100644 --- a/lib/rules/no-literal-call.js +++ b/lib/rules/no-literal-call.js @@ -9,7 +9,8 @@ //------------------------------------------------------------------------------ const LITERAL_TYPE = /^(?:(?:Array|Object)Expression|(?:Template)?Literal)$/u -const LITERAL_AND_CLASS_TYPE = /^(?:(?:Array|Class|Object)Expression|(?:Template)?Literal)$/u +const LITERAL_AND_CLASS_TYPE = + /^(?:(?:Array|Class|Object)Expression|(?:Template)?Literal)$/u //------------------------------------------------------------------------------ // Rule Definition @@ -21,8 +22,7 @@ module.exports = { description: "disallow a call of a literal.", category: "Possible Errors", recommended: false, - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-literal-call.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-literal-call.md", }, fixable: null, schema: [], diff --git a/lib/rules/no-this-in-static.js b/lib/rules/no-this-in-static.js index 0f6f5cf..d065d21 100644 --- a/lib/rules/no-this-in-static.js +++ b/lib/rules/no-this-in-static.js @@ -14,8 +14,7 @@ module.exports = { docs: { description: "disallow `this`/`super` in static methods", category: "Best Practices", - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-this-in-static.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-this-in-static.md", }, fixable: null, schema: [], diff --git a/lib/rules/no-use-ignored-vars.js b/lib/rules/no-use-ignored-vars.js index e69e24b..ec9cd12 100644 --- a/lib/rules/no-use-ignored-vars.js +++ b/lib/rules/no-use-ignored-vars.js @@ -20,8 +20,7 @@ module.exports = { description: "disallow a use of ignored variables.", category: "Stylistic Issues", recommended: false, - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-use-ignored-vars.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-use-ignored-vars.md", }, fixable: null, schema: [{ type: "string" }], diff --git a/lib/rules/no-useless-rest-spread.js b/lib/rules/no-useless-rest-spread.js index 64b907d..7898348 100644 --- a/lib/rules/no-useless-rest-spread.js +++ b/lib/rules/no-useless-rest-spread.js @@ -8,7 +8,8 @@ // Helpers //------------------------------------------------------------------------------ -const FUNC_TYPE = /^(?:FunctionDeclaration|(?:New|Call|(?:Arrow)?Function)Expression)$/u +const FUNC_TYPE = + /^(?:FunctionDeclaration|(?:New|Call|(?:Arrow)?Function)Expression)$/u const PROPERTY_PATTERN = /^(?:Experimental)?(Rest|Spread)Property$/u /** @@ -56,7 +57,7 @@ function getLastElementToken(sourceCode, node) { * @returns {function} A fixer function. */ function defineFixer(sourceCode, node) { - return fixer => { + return (fixer) => { const child = node.argument // If the inner array includes holes, do nothing. @@ -97,8 +98,7 @@ module.exports = { description: "disallow unnecessary spread operators.", category: "Best Practices", recommended: false, - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-useless-rest-spread.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/no-useless-rest-spread.md", }, fixable: "code", schema: [], @@ -116,7 +116,7 @@ module.exports = { function verify(node) { const nodeType = node.type.replace( PROPERTY_PATTERN, - t => `${t}Element` + (t) => `${t}Element` ) const parentType = node.parent.type const argumentType = node.argument.type diff --git a/lib/rules/prefer-for-of.js b/lib/rules/prefer-for-of.js index 504badc..b561870 100644 --- a/lib/rules/prefer-for-of.js +++ b/lib/rules/prefer-for-of.js @@ -243,7 +243,7 @@ function isIndexVarOnlyUsedToGetArrayElements(context, node) { const arrayText = getArrayTextOfForStatement(sourceCode, node) const indexVar = context.getDeclaredVariables(node.init)[0] - return indexVar.references.every(reference => { + return indexVar.references.every((reference) => { const id = reference.identifier return ( @@ -273,7 +273,8 @@ function isLengthVarOnlyUsedToTest(context, node) { const lengthVar = context.getDeclaredVariables(node.init.declarations[1])[0] return lengthVar.references.every( - reference => reference.init || contains(node.test, reference.identifier) + (reference) => + reference.init || contains(node.test, reference.identifier) ) } @@ -497,8 +498,7 @@ module.exports = { description: "requires for-of statements instead of Array#forEach", category: "Best Practices", recommended: false, - url: - "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/prefer-for-of.md", + url: "https://github.com/mysticatea/eslint-plugin/blob/v13.0.0/docs/rules/prefer-for-of.md", }, fixable: "code", schema: [], @@ -580,7 +580,7 @@ module.exports = { if ( thisFuncInfo != null && thisFuncInfo.isTarget && - !thisFuncInfo.returnNodes.some(returnNode => + !thisFuncInfo.returnNodes.some((returnNode) => contains(returnNode, node) ) ) { diff --git a/package.json b/package.json index bb04713..e43c381 100644 --- a/package.json +++ b/package.json @@ -3,31 +3,31 @@ "version": "13.0.0", "description": "Additional ESLint rules.", "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "main": "index.js", "files": [ "lib" ], "peerDependencies": { - "eslint": "^7.0.0" + "eslint": "^8.0.0" }, "dependencies": { - "@eslint/eslintrc": "^0.4.3", - "@typescript-eslint/eslint-plugin": "^4.33.0", - "@typescript-eslint/parser": "^4.33.0", + "@eslint/eslintrc": "^1.0.3", + "@typescript-eslint/eslint-plugin": "^5.2.0", + "@typescript-eslint/parser": "^5.2.0", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-eslint-plugin": "^3.6.1", + "eslint-plugin-eslint-plugin": "^4.0.2", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^3.4.1", - "eslint-plugin-vue": "^7.19.1", - "prettier": "^1.19.1", - "vue-eslint-parser": "^7.11.0" + "eslint-plugin-prettier": "^4.0.0", + "eslint-plugin-vue": "^8.0.3", + "prettier": "^2.4.1", + "vue-eslint-parser": "^8.0.1" }, "devDependencies": { "@mysticatea/eslint-plugin": "file:.", "codecov": "^3.6.1", - "eslint": "^7.32.0", + "eslint": "^8.1.0", "fs-extra": "^8.1.0", "globals": "^12.1.1", "mocha": "^6.2.2", diff --git a/scripts/generate-browser-globals.js b/scripts/generate-browser-globals.js index 7b3bcfe..290aa46 100644 --- a/scripts/generate-browser-globals.js +++ b/scripts/generate-browser-globals.js @@ -6,7 +6,7 @@ const fs = require("fs") const path = require("path") -const { CLIEngine } = require("eslint") +const { ESLint } = require("eslint") const { browser: originalGlobals } = require("globals") const targetFile = path.resolve(__dirname, "../lib/configs/_browser-globals.js") @@ -33,7 +33,7 @@ for (const key of Object.keys(originalGlobals).sort()) { } } -const linter = new CLIEngine({ fix: true }) +const linter = new ESLint({ fix: true }) const rawCode = `/** * DON'T EDIT THIS FILE WHICH WAS GENERATED BY './scripts/generate-browser-globals.js'. */ @@ -42,7 +42,6 @@ const rawCode = `/** module.exports = ${JSON.stringify(globals, null, 4)} ` const code = - linter.executeOnText(rawCode, "_browser-globals.js").results[0].output || - rawCode + linter.lintText(rawCode, "_browser-globals.js").results[0].output || rawCode fs.writeFileSync(targetFile, code) diff --git a/scripts/generate-configs.js b/scripts/generate-configs.js index a0587d1..d6ed195 100644 --- a/scripts/generate-configs.js +++ b/scripts/generate-configs.js @@ -6,7 +6,7 @@ const fs = require("fs") const path = require("path") -const { CLIEngine } = require("eslint") +const { ESLint } = require("eslint") const targetFile = path.resolve(__dirname, "../lib/configs.js") @@ -20,14 +20,14 @@ fs.writeFileSync( module.exports = { ${fs .readdirSync(path.resolve(__dirname, "../lib/configs")) - .map(fileName => path.basename(fileName, ".js")) - .filter(id => !id.startsWith("_")) - .map(id => ` "${id}": require("./configs/${id}"),`) + .map((fileName) => path.basename(fileName, ".js")) + .filter((id) => !id.startsWith("_")) + .map((id) => ` "${id}": require("./configs/${id}"),`) .join("\n")} } ` ) -const linter = new CLIEngine({ fix: true }) -const result = linter.executeOnFiles([targetFile]) -CLIEngine.outputFixes(result) +const linter = new ESLint({ fix: true }) +const result = linter.lintFiles([targetFile]) +ESLint.outputFixes(result) diff --git a/scripts/generate-rules.js b/scripts/generate-rules.js index 141e876..31d67ba 100644 --- a/scripts/generate-rules.js +++ b/scripts/generate-rules.js @@ -6,7 +6,7 @@ const fs = require("fs") const path = require("path") -const { CLIEngine } = require("eslint") +const { ESLint } = require("eslint") const targetFile = path.resolve(__dirname, "../lib/rules.js") @@ -20,20 +20,20 @@ fs.writeFileSync( module.exports = Object.assign( ${fs .readdirSync(path.resolve(__dirname, "../lib/foreign-rules")) - .map(fileName => path.basename(fileName, ".js")) - .map(id => ` require("./foreign-rules/${id}"),`) + .map((fileName) => path.basename(fileName, ".js")) + .map((id) => ` require("./foreign-rules/${id}"),`) .join("\n")} { ${fs .readdirSync(path.resolve(__dirname, "../lib/rules")) - .map(fileName => path.basename(fileName, ".js")) - .map(id => ` "${id}": require("./rules/${id}"),`) + .map((fileName) => path.basename(fileName, ".js")) + .map((id) => ` "${id}": require("./rules/${id}"),`) .join("\n")} } ) ` ) -const linter = new CLIEngine({ fix: true }) -const result = linter.executeOnFiles([targetFile]) -CLIEngine.outputFixes(result) +const linter = new ESLint({ fix: true }) +const result = linter.lintFiles([targetFile]) +ESLint.outputFixes(result) diff --git a/tests/lib/configs/_rules.js b/tests/lib/configs/_rules.js index b46dcde..7937a4c 100644 --- a/tests/lib/configs/_rules.js +++ b/tests/lib/configs/_rules.js @@ -7,14 +7,14 @@ const { Linter } = require("eslint") const { ConfigArrayFactory, -} = require("@eslint/eslintrc/lib/config-array-factory") -const Validator = require("eslint/lib/shared/config-validator") + Legacy: { ConfigValidator }, +} = require("@eslint/eslintrc") const { rules: PluginRulesIndex } = require("@mysticatea/eslint-plugin") const { rules: removedRules } = require("eslint/conf/replacements.json") const coreRules = new Linter().getRules() const pluginRules = new Map( - Object.keys(PluginRulesIndex).map(key => [ + Object.keys(PluginRulesIndex).map((key) => [ `@mysticatea/${key}`, PluginRulesIndex[key], ]) @@ -38,12 +38,14 @@ module.exports = { * @returns {void} */ validateConfig(config, source) { - Validator.validate(config, source, ruleId => allRules.get(ruleId)) + ConfigValidator.validate(config, source, (ruleId) => + allRules.get(ruleId) + ) /* istanbul ignore next */ for (const ruleId of [].concat( Object.keys(config.rules || {}), - ...(config.overrides || []).map(c => Object.keys(c.rules || {})) + ...(config.overrides || []).map((c) => Object.keys(c.rules || {})) )) { const rule = allRules.get(ruleId) if (rule == null) { @@ -73,7 +75,7 @@ module.exports = { */ getCoreRuleNames() { return Array.from(coreRules.keys()).filter( - ruleId => + (ruleId) => !deprecatedRuleNames.has(ruleId) && !removedRuleNames.has(ruleId) ) @@ -86,14 +88,14 @@ module.exports = { */ getPluginRuleNames(pluginName) { return Object.keys(PluginRulesIndex) - .filter(ruleId => + .filter((ruleId) => pluginName === "mysticatea" ? !ruleId.includes("/") : ruleId.startsWith(`${pluginName}/`) ) - .map(ruleId => `@mysticatea/${ruleId}`) + .map((ruleId) => `@mysticatea/${ruleId}`) .filter( - ruleId => + (ruleId) => !deprecatedRuleNames.has(ruleId) && !removedRuleNames.has(ruleId) ) diff --git a/tests/lib/rules/block-scoped-var.js b/tests/lib/rules/block-scoped-var.js index c5385e5..8cb8b03 100644 --- a/tests/lib/rules/block-scoped-var.js +++ b/tests/lib/rules/block-scoped-var.js @@ -14,8 +14,7 @@ new RuleTester().run("block-scoped-var", rule, { "if (true) { var a; a; } else if (true) { var a; a; } else { var a; a; }", "while (true) { var a; a; } do { var a; a; } while (true);", { - code: - "for (var a = 0; a; a) { a; var b; b; } for (var a in []) { a; var b; b; } for (var a of []) { a; var b; b; }", + code: "for (var a = 0; a; a) { a; var b; b; } for (var a in []) { a; var b; b; } for (var a of []) { a; var b; b; }", env: { es6: true }, }, "switch (0) { case 0: var a; a; case 1: a; default: a; } { var a; a; }", @@ -85,8 +84,7 @@ new RuleTester().run("block-scoped-var", rule, { ], }, { - code: - "{ var {x: [a = 0]} = {x: [1]}; a; } { var a; ({x: [a = 0]} = {x: [1]}); }", + code: "{ var {x: [a = 0]} = {x: [1]}; a; } { var a; ({x: [a = 0]} = {x: [1]}); }", env: { es6: true }, errors: [ { diff --git a/tests/lib/rules/prefer-for-of.js b/tests/lib/rules/prefer-for-of.js index 7583264..e7feefd 100644 --- a/tests/lib/rules/prefer-for-of.js +++ b/tests/lib/rules/prefer-for-of.js @@ -37,10 +37,8 @@ tester.run("prefer-for-of", rule, { ], invalid: [ { - code: - "list.forEach(function(value) { return; function foo() { return } });", - output: - "for (let value of list) { continue; function foo() { return } }", + code: "list.forEach(function(value) { return; function foo() { return } });", + output: "for (let value of list) { continue; function foo() { return } }", errors: ["Expected for-of statement."], }, { @@ -62,8 +60,7 @@ tester.run("prefer-for-of", rule, { errors: ["Expected for-of statement."], }, { - code: - "list.forEach(function(value) { return; let obj; this.a }, obj);", + code: "list.forEach(function(value) { return; let obj; this.a }, obj);", output: null, globals: { list: false, obj: false }, errors: ["Expected for-of statement."], @@ -87,8 +84,7 @@ tester.run("prefer-for-of", rule, { errors: ["Expected for-of statement."], }, { - code: - "list.forEach(function(value) { return; foo(a => this[a]) });", + code: "list.forEach(function(value) { return; foo(a => this[a]) });", output: "for (let value of list) { continue; foo(a => list[a]) }", globals: { list: false, obj: false }, errors: ["Expected for-of statement."], @@ -126,8 +122,7 @@ tester.run("prefer-for-of", rule, { errors: ["Expected for-of statement."], }, { - code: - "list.filter(p)\n .map(t)\n .forEach(value => { return });", + code: "list.filter(p)\n .map(t)\n .forEach(value => { return });", output: null, errors: ["Expected for-of statement."], }, @@ -137,38 +132,32 @@ tester.run("prefer-for-of", rule, { errors: ["Expected for-of statement."], }, { - code: - "function wrap() { for (let i = 0; i < list.length; ++i) { return } }", + code: "function wrap() { for (let i = 0; i < list.length; ++i) { return } }", output: null, errors: ["Expected for-of statement."], }, { - code: - "function wrap() { for (let i = 0; i < list.length; ++i) { const value = list[i]; return } }", + code: "function wrap() { for (let i = 0; i < list.length; ++i) { const value = list[i]; return } }", output: "function wrap() { for (let value of list) { return } }", errors: ["Expected for-of statement."], }, { - code: - "function wrap() { for (let i = 0; i < list.length; i++) { const value = list[i]; return } }", + code: "function wrap() { for (let i = 0; i < list.length; i++) { const value = list[i]; return } }", output: "function wrap() { for (let value of list) { return } }", errors: ["Expected for-of statement."], }, { - code: - "function wrap() { for (let i = 0; i < list.length; i += 1) { const value = list[i]; return } }", + code: "function wrap() { for (let i = 0; i < list.length; i += 1) { const value = list[i]; return } }", output: "function wrap() { for (let value of list) { return } }", errors: ["Expected for-of statement."], }, { - code: - "for (let i = 0, end = list.length; i < end;i = 1 + i) { const value = list[i]; }", + code: "for (let i = 0, end = list.length; i < end;i = 1 + i) { const value = list[i]; }", output: "for (let value of list) { }", errors: ["Expected for-of statement."], }, { - code: - "for (let i = 0, length = list.length; i < length; i = i + 1) { const value = list[i]; }", + code: "for (let i = 0, length = list.length; i < length; i = i + 1) { const value = list[i]; }", output: "for (let value of list) { }", errors: ["Expected for-of statement."], },