From af9ed19af0e9a021c31979c885a861deffae7be0 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sun, 19 Nov 2023 04:25:58 +0100 Subject: [PATCH] Setup typescript-eslint Configure eslint to work with TypeScript via the typescript-eslint plugin. --- .eslintrc.js | 61 +++++++++++++++++++------- package.json | 2 + packages/controller/src/Controller.ts | 4 +- packages/ctl/ctl.ts | 1 + packages/host/host.ts | 1 + packages/lib/src/data/messages_core.ts | 3 +- packages/lib/src/plugin_loader.ts | 2 +- packages/lib/src/shared_commands.ts | 2 +- 8 files changed, 55 insertions(+), 21 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 76d4a5b5..084deb91 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,8 +1,10 @@ "use strict"; module.exports = { "plugins": [ + "@typescript-eslint", "node", ], + "root": true, "env": { "node": true, "commonjs": true, @@ -10,11 +12,25 @@ module.exports = { }, "overrides": [ + { + "files": ["{packages,plugins}/**/*.ts?(x)"], + "parser": "@typescript-eslint/parser", + "extends": [ + "plugin:@typescript-eslint/recommended", + ], + "rules": { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/no-unused-vars": "off", + "prefer-const": "off", + }, + }, { "files": ["test/**/*.js", "plugins/*/test/**/*.js"], "env": { "mocha": "true", }, + "parserOptions": { sourceType: "commonjs" }, "rules": { "prefer-arrow-callback": "off", "no-invalid-this": "off", @@ -23,7 +39,7 @@ module.exports = { }, }, { - "files": ["packages/web_ui/src/**/*.jsx", "packages/lib/browser.js", "plugins/*/web/**/*.jsx"], + "files": ["packages/web_ui/src/**/*.ts?(x)", "packages/lib/browser.js", "plugins/*/web/**/*.ts?(x)"], "env": { "browser": true, }, @@ -108,7 +124,7 @@ module.exports = { "curly": "error", "default-case": "error", "default-case-last": "error", - "default-param-last": "error", + "default-param-last": "off", "dot-location": ["error", "property"], "dot-notation": ["error", { "allowPattern": "^[a-z]+(_[a-z]+)*$" }], "eol-last": "error", @@ -148,7 +164,10 @@ module.exports = { "max-statements-per-line": "off", "multiline-comment-style": ["error", "separate-lines"], "multiline-ternary": "off", - "new-cap": "error", + "new-cap": ["error", { + "capIsNewExceptions": ["StringEnum"], + "capIsNewExceptionPattern": "^Type\\.", + }], "new-parens": "error", "newline-after-var": "off", "newline-before-return": "off", @@ -159,7 +178,7 @@ module.exports = { "no-bitwise": "off", "no-buffer-constructor": "error", "no-caller": "error", - "no-catch-shadow": "error", + "no-catch-shadow": "off", "no-confusing-arrow": "error", "no-console": "error", "no-constant-condition": ["error", { "checkLoops": false }], @@ -223,7 +242,7 @@ module.exports = { "no-script-url": "error", "no-self-compare": "error", "no-sequences": "error", - "no-shadow": ["error", { "allow": ["yargs"] }], + "no-shadow": ["error", { "allow": ["Event", "Request", "yargs"] }], "no-spaced-func": "error", "no-tabs": ["error", { "allowIndentationTabs": true }], "no-template-curly-in-string": "error", @@ -235,12 +254,12 @@ module.exports = { "no-unmodified-loop-condition": "error", "no-unneeded-ternary": "error", "no-unused-expressions": "error", - "no-use-before-define": "error", + "no-use-before-define": "off", "no-useless-backreference": "error", "no-useless-call": "error", "no-useless-computed-key": "error", "no-useless-concat": "error", - "no-useless-constructor": "error", + "no-useless-constructor": "off", "no-useless-rename": "error", "no-useless-return": "error", "no-var": "error", @@ -303,7 +322,11 @@ module.exports = { "template-curly-spacing": ["error", "never"], "template-tag-spacing": "error", "unicode-bom": ["error", "never"], - "valid-jsdoc": ["error", { "requireReturn": false }], + "valid-jsdoc": ["error", { + "requireReturn": false, + "requireReturnType": false, + "requireParamType": false, + }], "vars-on-top": "error", "wrap-iife": "error", "wrap-regex": "off", @@ -313,14 +336,16 @@ module.exports = { "node/callback-return": "off", "node/exports-style": "off", "node/file-extension-in-import": "off", - "node/global-require": "error", + "node/global-require": "off", "node/handle-callback-err": "error", "node/no-callback-literal": "error", "node/no-deprecated-api": "error", "node/no-exports-assign": "error", - "node/no-extraneous-import": "error", - "node/no-extraneous-require": "error", - "node/no-missing-import": "error", + "node/no-extraneous-import": "off", + "node/no-extraneous-require": "off", + "node/no-missing-import": ["error", { + "tryExtensions": [".js", ".ts"], + }], "node/no-missing-require": "error", "node/no-mixed-requires": "error", "node/no-new-require": "error", @@ -335,9 +360,9 @@ module.exports = { "error", { "allowModules": ["webpack", "webpack-merge", "webpack-dev-middleware"] }, ], - "node/no-unsupported-features/es-builtins": "error", - "node/no-unsupported-features/es-syntax": "error", - "node/no-unsupported-features/node-builtins": "error", + "node/no-unsupported-features/es-builtins": "off", + "node/no-unsupported-features/es-syntax": "off", + "node/no-unsupported-features/node-builtins": "off", "node/prefer-global/buffer": "error", "node/prefer-global/console": "error", "node/prefer-global/process": "error", @@ -348,6 +373,10 @@ module.exports = { "node/prefer-promises/dns": "off", "node/prefer-promises/fs": "off", "node/process-exit-as-throw": "error", - "node/shebang": "error", + "node/shebang": ["error", { + "convertPath": { + "*.ts": ["^(.+)\\.ts$", "dist/$1.js"], + }, + }], }, }; diff --git a/package.json b/package.json index dc107cc8..9f2eeae8 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ "@clusterio/ctl": "workspace:*", "@clusterio/host": "workspace:*", "@clusterio/lib": "workspace:*", + "@typescript-eslint/eslint-plugin": "^6.4.1", + "@typescript-eslint/parser": "^6.4.1", "eslint": "^8.45.0", "eslint-plugin-node": "^11.1.0", "express": "^4.18.2", diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index 9951fb9b..1ea56812 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -166,7 +166,7 @@ export default class Controller { // Start webpack development server if enabled if (args.dev || args.devPlugin) { logger.warn("Webpack development mode enabled"); - /* eslint-disable node/global-require, node/no-unpublished-require */ + /* eslint-disable @typescript-eslint/no-var-requires, node/no-unpublished-require */ const webpack = require("webpack"); const webpackDevMiddleware = require("webpack-dev-middleware"); const webpackConfigs = []; @@ -188,7 +188,7 @@ export default class Controller { } this.app.locals.devPlugins = devPlugins; } - /* eslint-enable node/global-require, node/no-unpublished-require */ + /* eslint-enable @typescript-eslint/no-var-requires, node/no-unpublished-require */ const compiler = webpack(webpackConfigs); this.devMiddleware = webpackDevMiddleware(compiler, { serverSideRender: true }); diff --git a/packages/ctl/ctl.ts b/packages/ctl/ctl.ts index 61ecf9c2..afa9e8d1 100755 --- a/packages/ctl/ctl.ts +++ b/packages/ctl/ctl.ts @@ -169,6 +169,7 @@ async function startControl() { ; // Parse the args first to get the configured plugin list. + // eslint-disable-next-line node/no-sync let args = yargs.parseSync() as CtlArguments; // Log stream for the ctl session. diff --git a/packages/host/host.ts b/packages/host/host.ts index 88c2d900..8c96106c 100755 --- a/packages/host/host.ts +++ b/packages/host/host.ts @@ -66,6 +66,7 @@ export class HostConnector extends lib.WebSocketClientConnector { async function startHost() { // argument parsing + // eslint-disable-next-line node/no-sync const args = yargs .scriptName("host") .usage("$0 [options]") diff --git a/packages/lib/src/data/messages_core.ts b/packages/lib/src/data/messages_core.ts index 7704bc17..a2cab960 100644 --- a/packages/lib/src/data/messages_core.ts +++ b/packages/lib/src/data/messages_core.ts @@ -1,6 +1,7 @@ // Note: Run compile_validator script after making changes to this file. import { TSchema, Type, Static } from "@sinclair/typebox"; -import messageValidate from "./message_validate"; +// eslint-disable-next-line node/no-missing-import +import messageValidate from "./message_validate"; // generated file import { StringEnum } from "./composites"; import { AccountRole } from "../plugin"; diff --git a/packages/lib/src/plugin_loader.ts b/packages/lib/src/plugin_loader.ts index 651a7b51..bb6c3573 100644 --- a/packages/lib/src/plugin_loader.ts +++ b/packages/lib/src/plugin_loader.ts @@ -1,4 +1,4 @@ -/* eslint-disable node/global-require */ +/* eslint-disable @typescript-eslint/no-var-requires */ /** * Helpers for loading plugins in Node.js * @module lib/plugin_loader diff --git a/packages/lib/src/shared_commands.ts b/packages/lib/src/shared_commands.ts index cec55d47..a85fd1f5 100644 --- a/packages/lib/src/shared_commands.ts +++ b/packages/lib/src/shared_commands.ts @@ -58,7 +58,7 @@ export async function handlePluginCommand( let pluginInfo: { name: string }; try { - // eslint-disable-next-line node/global-require + // eslint-disable-next-line @typescript-eslint/no-var-requires pluginInfo = require(pluginPath).default; } catch (err: any) { logger.error(`Unable to import plugin info from ${args.path}:\n${err.stack}`);