Merge pull request #785 from clusterio/dependency-updates

Update dependencies
This commit is contained in:
Daniel authored and GitHub committed 2025-08-04 19:03:49 +02:00
commit e1d9c1e414
39 files changed
+390 -289

No files matched your search

-1
View File
@@ -1 +0,0 @@
dist/
+274 -186
View File
@@ -1,118 +1,47 @@
"use strict";
module.exports = {
"plugins": [
"@typescript-eslint",
"node",
],
"root": true,
"env": {
"node": true,
"commonjs": true,
"es2022": true,
import {
defineConfig,
globalIgnores,
} from "eslint/config";
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import node from "eslint-plugin-node";
import globals from "globals";
import tsParser from "@typescript-eslint/parser";
import js from "@eslint/js";
import stylistic from "@stylistic/eslint-plugin";
import {
FlatCompat,
} from "@eslint/eslintrc";
const compat = new FlatCompat({
baseDirectory: import.meta.dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
export default defineConfig([{
plugins: {
"@typescript-eslint": typescriptEslint,
"@stylistic": stylistic,
node,
},
"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",
"@typescript-eslint/triple-slash-reference": "off",
"@typescript-eslint/no-shadow": ["error", { "allow": ["Event", "Request", "yargs"] }],
"prefer-const": "off",
"no-shadow": "off",
},
languageOptions: {
globals: {
...globals.node,
...globals.commonjs,
},
{
"files": ["test/**/*.js", "plugins/*/test/**/*.js"],
"env": {
"mocha": "true",
},
"parserOptions": { sourceType: "commonjs" },
"rules": {
"prefer-arrow-callback": "off",
"no-invalid-this": "off",
"valid-jsdoc": "off",
"node/no-unpublished-import": "off",
"node/no-unpublished-require": "off",
},
},
{
"files": [
"packages/web_ui/src/**/*.ts?(x)",
"packages/lib/browser.ts",
"packages/create/templates/*/web/**/*.{t,j}s?(x)",
"{packages,plugins}/*/web/**/*.ts?(x)",
],
"env": {
"browser": true,
},
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,
},
},
"rules": {
"node/callback-return": "off",
"node/exports-style": "off",
"node/file-extension-in-import": "off",
"node/global-require": "off",
"node/handle-callback-err": "off",
"node/no-callback-literal": "off",
"node/no-deprecated-api": "off",
"node/no-exports-assign": "off",
"node/no-extraneous-import": "off",
"node/no-extraneous-require": "off",
"node/no-missing-import": "off",
"node/no-missing-require": "off",
"node/no-mixed-requires": "off",
"node/no-new-require": "off",
"node/no-path-concat": "off",
"node/no-process-env": "off",
"node/no-process-exit": "off",
"node/no-restricted-require": "off",
"node/no-sync": "off",
"node/no-unpublished-bin": "off",
"node/no-unpublished-import": "off",
"node/no-unpublished-require": "off",
"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": "off",
"node/prefer-global/console": "off",
"node/prefer-global/process": "off",
"node/prefer-global/text-decoder": "off",
"node/prefer-global/text-encoder": "off",
"node/prefer-global/url-search-params": "off",
"node/prefer-global/url": "off",
"node/prefer-promises/dns": "off",
"node/prefer-promises/fs": "off",
"node/process-exit-as-throw": "off",
"node/shebang": "off",
},
},
{
"files": [
"packages/create/templates/**/*.{t,j}s?(x)",
],
"rules": {
"node/no-missing-require": "off",
"node/no-missing-import": "off",
"spaced-comment": "off",
"comma-spacing": "off",
"max-len": "off",
"indent": "off",
},
},
],
},
"rules": {
"@stylistic/indent": ["error", "tab", {
"ignoredNodes": [
"JSXFragment", // TODO: Linter crashes if this is removed
],
"ignoreComments": true,
"SwitchCase": 1, // Indent case statements one level from switch
}],
"accessor-pairs": "error",
"array-bracket-newline": "off",
"array-bracket-spacing": ["error", "never"],
@@ -120,26 +49,34 @@ module.exports = {
"array-element-newline": "off",
"arrow-body-style": "error",
"arrow-parens": "off",
"arrow-spacing": ["error", { "after": true, "before": true }],
"arrow-spacing": ["error", {
"after": true,
"before": true,
}],
"block-scoped-var": "error",
"block-spacing": "error",
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"brace-style": ["error", "1tbs", {
"allowSingleLine": true,
}],
"camelcase": "off",
"capitalized-comments": "off",
"class-methods-use-this": "off",
"comma-dangle": [
"error",
{
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "only-multiline",
},
],
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "only-multiline",
}],
"comma-spacing": "error",
"comma-style": ["error", "last"],
"complexity": "error",
"complexity": ["error", { "max": 25 }],
"computed-property-spacing": ["error", "never"],
"consistent-return": "error",
"consistent-this": "error",
@@ -148,27 +85,36 @@ module.exports = {
"default-case-last": "error",
"default-param-last": "off",
"dot-location": ["error", "property"],
"dot-notation": ["error", { "allowPattern": "^[a-z]+(_[a-z]+)*$" }],
"dot-notation": ["error", {
"allowPattern": "^[a-z]+(_[a-z]+)*$",
}],
"eol-last": "error",
"eqeqeq": "error",
"func-call-spacing": "error",
"func-name-matching": "error",
"func-names": "off",
"func-style": ["error", "declaration", {
// Allow arrow functions as it better expresses referencing this
// of the containing scope, which is unweilding in plain functions.
"allowArrowFunctions": true,
}],
"function-call-argument-newline": "off",
"function-paren-newline": "off",
"generator-star-spacing": ["error", { "before": false, "after": true }],
"generator-star-spacing": ["error", {
"before": false,
"after": true,
}],
"grouped-accessor-pairs": "error",
"guard-for-in": "error",
"id-blacklist": "error",
"id-length": "off",
"id-match": "error",
"implicit-arrow-linebreak": "error",
"indent": ["error", "tab", { "SwitchCase": 1 }],
"indent-legacy": "off",
"init-declarations": "off",
"jsx-quotes": "error",
@@ -178,10 +124,18 @@ module.exports = {
"linebreak-style": ["error", "unix"],
"lines-around-comment": "off",
"lines-around-directive": "off",
"lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }],
"lines-between-class-members": ["error", "always", {
"exceptAfterSingleLine": true,
}],
"max-classes-per-file": "off",
"max-depth": "error",
"max-len": ["error", { "code": 120 }],
"max-len": ["error", {
"code": 120,
}],
"max-lines": "off",
"max-lines-per-function": "off",
"max-nested-callbacks": "error",
@@ -190,10 +144,12 @@ module.exports = {
"max-statements-per-line": "off",
"multiline-comment-style": ["error", "separate-lines"],
"multiline-ternary": "off",
"new-cap": ["error", {
"capIsNewExceptions": ["StringEnum", "StringKey"],
"capIsNewExceptionPattern": "^Type\\.",
}],
"new-parens": "error",
"newline-after-var": "off",
"newline-before-return": "off",
@@ -207,7 +163,11 @@ module.exports = {
"no-catch-shadow": "off",
"no-confusing-arrow": "error",
"no-console": "error",
"no-constant-condition": ["error", { "checkLoops": false }],
"no-constant-condition": ["error", {
"checkLoops": false,
}],
"no-constructor-return": "error",
"no-continue": "off",
"no-div-regex": "error",
@@ -232,16 +192,15 @@ module.exports = {
"no-lonely-if": "error",
"no-loop-func": "error",
"no-magic-numbers": "off",
"no-mixed-operators": [
"error",
{
"groups": [
["&", "|", "^", "~", "<<", ">>", ">>>"],
["==", "!=", "===", "!==", ">", ">=", "<", "<="],
["in", "instanceof"],
],
},
],
"no-mixed-operators": ["error", {
"groups": [
["&", "|", "^", "~", "<<", ">>", ">>>"],
["==", "!=", "===", "!==", ">", ">=", "<", "<="],
["in", "instanceof"],
],
}],
"no-multi-assign": "error",
"no-multi-spaces": "error",
"no-multi-str": "error",
@@ -256,7 +215,11 @@ module.exports = {
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-param-reassign": "off",
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
"no-plusplus": ["error", {
"allowForLoopAfterthoughts": true,
}],
"no-proto": "error",
"no-restricted-exports": "error",
"no-restricted-globals": "error",
@@ -268,9 +231,15 @@ module.exports = {
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow": ["error", { "allow": ["Event", "Request", "yargs"] }],
"no-shadow": ["error", {
"allow": ["Event", "Request", "yargs"],
}],
"no-spaced-func": "error",
"no-tabs": ["error", { "allowIndentationTabs": true }],
"no-tabs": "off",
"no-template-curly-in-string": "error",
"no-ternary": "off",
"no-throw-literal": "error",
@@ -289,7 +258,11 @@ module.exports = {
"no-useless-rename": "error",
"no-useless-return": "error",
"no-var": "error",
"no-void": ["error", { "allowAsStatement": true }],
"no-void": ["error", {
"allowAsStatement": true,
}],
"no-warning-comments": "off",
"no-whitespace-before-property": "error",
"nonblock-statement-body-position": "error",
@@ -299,6 +272,7 @@ module.exports = {
"one-var": "off",
"one-var-declaration-per-line": "error",
"operator-assignment": "off",
"operator-linebreak": ["error", "after", {
"overrides": {
"?": "before",
@@ -308,6 +282,7 @@ module.exports = {
"??": "before",
},
}],
"padded-blocks": "off",
"padding-line-between-statements": "error",
"prefer-arrow-callback": "error",
@@ -324,9 +299,13 @@ module.exports = {
"prefer-spread": "error",
"prefer-template": "error",
"quote-props": "off",
"quotes": ["error", "double", { "avoidEscape": true }],
"quotes": ["error", "double", {
"avoidEscape": true,
}],
"radix": ["error", "always"],
"require-atomic-updates": "off", // XXX Not sure why this triggers on process.title = ...
"require-atomic-updates": "off",
"require-await": "off",
"require-jsdoc": "off",
"require-unicode-regexp": "off",
@@ -342,73 +321,182 @@ module.exports = {
"space-in-parens": ["error", "never"],
"space-infix-ops": "off",
"space-unary-ops": "error",
"spaced-comment": ["error", "always", {
"line": {
"markers": ["/"],
},
}],
"strict": "error",
"switch-colon-spacing": "error",
"symbol-description": "error",
"template-curly-spacing": ["error", "never"],
"template-tag-spacing": "error",
"unicode-bom": ["error", "never"],
"valid-jsdoc": ["error", {
"requireReturn": false,
"requireReturnType": false,
"requireParamType": false,
}],
"vars-on-top": "error",
"wrap-iife": "error",
"wrap-regex": "off",
"yield-star-spacing": "error",
"yoda": ["error", "never", { "exceptRange": true }],
"yoda": ["error", "never", {
"exceptRange": true,
}],
"node/callback-return": "off",
"node/exports-style": "off",
"node/file-extension-in-import": "off",
"node/global-require": "off",
// Node.js callback passing style of (err, value) is not used in this project
"node/handle-callback-err": "off",
"node/no-callback-literal": "off",
"node/no-deprecated-api": "error",
"node/no-exports-assign": "error",
"node/no-deprecated-api": "off",
"node/no-exports-assign": "off",
"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",
"node/no-path-concat": "error",
"node/no-process-env": "error",
"node/no-process-exit": "error",
"node/no-missing-import": "off",
"node/no-missing-require": "off",
"node/no-mixed-requires": "off",
"node/no-new-require": "off",
"node/no-path-concat": "off",
"node/no-process-env": "off",
"node/no-process-exit": "off",
"node/no-restricted-require": "off",
"node/no-sync": "error",
"node/no-unpublished-bin": "error",
"node/no-unpublished-import": "error",
"node/no-unpublished-require": [
"error",
{ "allowModules": ["webpack", "webpack-merge", "webpack-dev-middleware"] },
],
"node/no-unpublished-bin": "off",
"node/no-unpublished-import": "off",
"node/no-unpublished-require": "off",
"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",
"node/prefer-global/text-decoder": "error",
"node/prefer-global/text-encoder": "error",
"node/prefer-global/url-search-params": "error",
"node/prefer-global/url": "error",
"node/prefer-global/buffer": "off",
"node/prefer-global/console": "off",
"node/prefer-global/process": "off",
"node/prefer-global/text-decoder": "off",
"node/prefer-global/text-encoder": "off",
"node/prefer-global/url-search-params": "off",
"node/prefer-global/url": "off",
"node/prefer-promises/dns": "off",
"node/prefer-promises/fs": "off",
"node/process-exit-as-throw": "error",
"node/shebang": ["error", {
"convertPath": {
"*.ts": ["^(.+)\\.ts$", "dist/node/$1.js"],
},
}],
"node/process-exit-as-throw": "off",
"node/shebang": "off",
},
};
}, {
files: ["{packages,plugins}/**/*.ts?(x)"],
languageOptions: {
parser: tsParser,
},
extends: compat.extends("plugin:@typescript-eslint/recommended"),
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-useless-constructor": "error",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/triple-slash-reference": "off",
"@typescript-eslint/no-shadow": ["error", {
"allow": ["Event", "Request", "yargs"],
}],
// Allow require imports where necessary (dynamic loading, webpack configs, etc.)
"@typescript-eslint/no-require-imports": "off",
"prefer-const": "off",
"no-shadow": "off",
},
}, {
files: ["test/**/*.js", "plugins/*/test/**/*.js"],
languageOptions: {
globals: {
...globals.mocha,
},
sourceType: "commonjs",
parserOptions: {},
},
"rules": {
"prefer-arrow-callback": "off",
"no-invalid-this": "off",
"node/no-unpublished-import": "off",
"node/no-unpublished-require": "off",
},
}, {
files: [
"packages/web_ui/src/**/*.ts?(x)",
"packages/lib/browser.ts",
"packages/create/templates/*/web/**/*.{t,j}s?(x)",
"{packages,plugins}/*/web/**/*.ts?(x)",
],
languageOptions: {
globals: {
...globals.browser,
},
"sourceType": "module",
parserOptions: {
"ecmaFeatures": {
"jsx": true,
},
},
},
"rules": {
"node/callback-return": "off",
"node/exports-style": "off",
"node/file-extension-in-import": "off",
"node/global-require": "off",
"node/handle-callback-err": "off",
"node/no-callback-literal": "off",
"node/no-deprecated-api": "off",
"node/no-exports-assign": "off",
"node/no-extraneous-import": "off",
"node/no-extraneous-require": "off",
"node/no-missing-import": "off",
"node/no-missing-require": "off",
"node/no-mixed-requires": "off",
"node/no-new-require": "off",
"node/no-path-concat": "off",
"node/no-process-env": "off",
"node/no-process-exit": "off",
"node/no-restricted-require": "off",
"node/no-sync": "error",
"node/no-unpublished-bin": "off",
"node/no-unpublished-import": "off",
"node/no-unpublished-require": "off",
"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": "off",
"node/prefer-global/console": "off",
"node/prefer-global/process": "off",
"node/prefer-global/text-decoder": "off",
"node/prefer-global/text-encoder": "off",
"node/prefer-global/url-search-params": "off",
"node/prefer-global/url": "off",
"node/prefer-promises/dns": "off",
"node/prefer-promises/fs": "off",
"node/process-exit-as-throw": "off",
"node/shebang": "off",
},
}, {
files: ["packages/create/templates/**/*.{t,j}s?(x)"],
"rules": {
"node/no-missing-require": "off",
"node/no-missing-import": "off",
"spaced-comment": "off",
"comma-spacing": "off",
"max-len": "off",
"indent": "off",
},
}, globalIgnores(["**/dist/", "dist/"])]);
+18 -14
View File
@@ -41,21 +41,25 @@
"@clusterio/host": "workspace:*",
"@clusterio/lib": "workspace:*",
"@clusterio/web_ui": "workspace:*",
"@swc/core": "^1.11.1",
"@typescript-eslint/eslint-plugin": "^6.4.1",
"@typescript-eslint/parser": "^6.4.1",
"eslint": "^8.57.1",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.32.0",
"@stylistic/eslint-plugin": "^5.2.2",
"@swc/core": "^1.13.3",
"@typescript-eslint/eslint-plugin": "^8.38.0",
"@typescript-eslint/parser": "^8.38.0",
"eslint": "^9.32.0",
"eslint-plugin-node": "^11.1.0",
"express": "^4.21.2",
"form-data": "^4.0.2",
"express": "^5.1.0",
"form-data": "^4.0.4",
"fs-extra": "^11.3.0",
"jsonwebtoken": "^9.0.1",
"jszip": "^3.10.0",
"mocha": "^10.8.2",
"nyc": "^15.1.0",
"phin": "^3.7.0",
"typedoc": "^0.26.11",
"typescript": "^5.7.3",
"yargs": "^17.7.2"
"globals": "^16.3.0",
"jsonwebtoken": "^9.0.2",
"jszip": "^3.10.1",
"mocha": "^11.7.1",
"nyc": "^17.1.0",
"phin": "^3.7.1",
"typedoc": "^0.28.9",
"typescript": "^5.9.2",
"yargs": "^18.0.0"
}
}
+2 -2
View File
@@ -422,7 +422,7 @@ async function startup() {
if (secondSigint) {
setBlocking(true);
logger.fatal("Caught second interrupt, terminating immediately");
// eslint-disable-next-line node/no-process-exit
process.exit(1);
}
@@ -435,7 +435,7 @@ async function startup() {
if (secondSigterm) {
setBlocking(true);
logger.fatal("Caught second termination, terminating immediately");
// eslint-disable-next-line node/no-process-exit
process.exit(1);
}
+1 -1
View File
@@ -16,7 +16,7 @@ import * as routes from "./routes";
* @alias module:controller/src/BaseConnection
*/
export default class BaseConnection extends lib.Link {
declare ["connector"]: WsServerConnector;
declare "connector": WsServerConnector;
constructor(
connector: lib.WebSocketBaseConnector,
+1 -1
View File
@@ -901,7 +901,7 @@ export default class ControlConnection extends BaseConnection {
}
// A large number of small if statements are unavoidable when reducing the number of updates sent
// eslint-disable-next-line complexity
async handleUserBulkImportRequest(request: lib.UserBulkImportRequest) {
let backup: undefined | Awaited<ReturnType<ControlConnection["handleUserBulkExportRequest"]>>;
const updated = new Map<ControllerUser["id"], ControllerUser>();
+3 -3
View File
@@ -399,13 +399,13 @@ export default class Controller {
async _startDevServer(args: ControllerArgs) {
logger.warn("Webpack development mode enabled");
/* eslint-disable @typescript-eslint/no-var-requires, node/no-unpublished-require */
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpackConfigs = [];
if (args.dev) {
// eslint-disable-next-line node/no-missing-require
webpackConfigs.push(require("../../../webpack.config")({})); // Path outside of build
}
if (args.devPlugin) {
@@ -421,7 +421,7 @@ export default class Controller {
}
this.app.locals.devPlugins = devPlugins;
}
/* eslint-enable @typescript-eslint/no-var-requires, node/no-unpublished-require */
const compiler = webpack(webpackConfigs);
this.devMiddleware = webpackDevMiddleware(compiler, { serverSideRender: true });
+1 -1
View File
@@ -47,7 +47,7 @@ export default class HostConnection extends BaseConnection {
this._checkPluginVersions();
for (let event of ["connect", "drop", "resume", "close"] as const) {
// eslint-disable-next-line no-loop-func
this.connector.on(event, () => {
for (let plugin of this._controller.plugins.values()) {
plugin.onHostConnectionEvent(this, event);
+2 -2
View File
@@ -114,7 +114,7 @@ async function execFile(cmd, args) {
escaped,
{
shell: true,
// eslint-disable-next-line node/no-process-env
env: process.platform === "win32" ? { ...process.env, pct: "%" } : undefined,
},
(err, stdout, stderr) => {
@@ -396,7 +396,7 @@ async function installClusterio(mode, plugins) {
}
for (let plugin of plugins) {
if (!pluginList.has(plugin)) {
// eslint-disable-next-line node/global-require
let pluginInfo = require(require.resolve(plugin, { paths: [process.cwd()] })).plugin;
pluginList.set(pluginInfo.name, plugin);
}
+1 -1
View File
@@ -50,7 +50,7 @@ function escapeArg(arg) {
// For all other platforms the command is /bin/sh -c <command arg arg ...>
// The command and its arguments are passed as a single argument to the shell.
// See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
// eslint-disable-next-line no-lonely-if
if (!/[|&;<>()$`\\"' \t*?\[#~=%]/.test(arg)) {
return arg;
}
+1 -1
View File
@@ -40,7 +40,7 @@ const plugin = {
//%endif
//%if controller
controllerEntrypoint: "./dist/node/controller",
controllerEntrypoint: "./dist/node/controller",
//%endif
//%if controller & config
controllerConfigFields: {
@@ -35,9 +35,9 @@ function MyTemplatePage() {
return <PageLayout nav={[{ name: "__plugin_name__" }]}>
<PageHeader title="__plugin_name__" />
//%if controller // Subscribing requires web content and the controller
//%if controller // Subscribing requires web content and the controller
Synced: {String(synced)} Data: {JSON.stringify([...subscribableData.values()])}
//%endif
//%endif
</PageLayout>;
}
@@ -35,9 +35,9 @@ function MyTemplatePage() {
return <PageLayout nav={[{ name: "__plugin_name__" }]}>
<PageHeader title="__plugin_name__" />
//%if controller // Subscribing requires web content and the controller
//%if controller // Subscribing requires web content and the controller
Synced: {String(synced)} Data: {JSON.stringify([...subscribableData.values()])}
//%endif
//%endif
</PageLayout>;
}
+19 -9
View File
@@ -5,7 +5,7 @@
* @module ctl/ctl
*/
import fs from "fs-extra";
import yargs from "yargs";
import yargs, { type Argv } from "yargs";
import path from "path";
import { version } from "./package.json";
import setBlocking from "set-blocking";
@@ -156,7 +156,17 @@ export async function initialize(
ctlPlugins?: Map<string, BaseCtlPlugin>,
noLoggerTransport?: boolean,
): Promise<InitializeParameters> {
yargs
// Build a fresh, isolated yargs parser each time this function is called.
// If the currently loaded yargs object supports .reset() we use that (older versions),
// otherwise we fall back to creating a brand-new parser instance by invoking the
// yargs factory function directly with an empty argv array. This avoids Mocha’s
// own CLI flags (or anything else that touched yargs earlier in the same process)
// from leaking into subsequent parses inside the test runner.
const parser: Argv = typeof (yargs as any).reset === "function"
? (yargs as any).reset()
: (yargs as any)([]);
parser
.scriptName("clusterioctl")
.usage("$0 <command> [options]")
.option("log-level", {
@@ -181,13 +191,13 @@ export async function initialize(
})
.command("plugin", "Manage available plugins", lib.pluginCommand)
.command("control-config", "Manage Control config", lib.configCommand)
.wrap(yargs.terminalWidth())
.wrap(parser.terminalWidth())
.help(false) // Disable help to avoid triggering it on the first parse.
;
// Parse the args first to get the configured plugin list.
// eslint-disable-next-line node/no-sync
let args = yargs.parseSync(argv) as CtlArguments;
let args = parser.parseSync(argv) as CtlArguments;
// Log stream for the ctl session. Skipped in testing.
if (!noLoggerTransport) {
@@ -217,8 +227,8 @@ export async function initialize(
}
// Add all commands including from plugins and reparse with help and strict checking.
const rootCommands = await commands.registerCommands(ctlPlugins, yargs);
args = yargs
const rootCommands = await commands.registerCommands(ctlPlugins, parser);
args = parser
.help()
.strict()
.parse(argv) as CtlArguments
@@ -241,8 +251,8 @@ export async function initialize(
}
if (args._.length === 0) {
yargs.showHelp();
yargs.exit(1, undefined as unknown as Error); // Type definition file is wrong.
parser.showHelp();
parser.exit(1, undefined as unknown as Error); // Type definition file is wrong.
}
// Handle the control-config command before trying to connect.
@@ -310,7 +320,7 @@ async function startControl() {
control.shutdown().catch(err => {
setBlocking(true);
logger.error(err.stack);
// eslint-disable-next-line node/no-process-exit
process.exit(1);
});
});
+1 -1
View File
@@ -2062,7 +2062,7 @@ userCommands.add(new lib.Command({
exportType = "whitelist";
}
fs.writeJSON(args.filepath, await control.send(
await fs.writeJSON(args.filepath, await control.send(
new lib.UserBulkExportRequest(exportType)
), { spaces: 2 });
print(`Exported ${exportType} to ${args.filepath}`);
+2 -2
View File
@@ -243,7 +243,7 @@ async function startHost() {
if (secondSigint) {
setBlocking(true);
logger.fatal("Caught second interrupt, terminating immediately");
// eslint-disable-next-line node/no-process-exit
process.exit(1);
}
@@ -256,7 +256,7 @@ async function startHost() {
if (secondSigterm) {
setBlocking(true);
logger.fatal("Caught second termination, terminating immediately");
// eslint-disable-next-line node/no-process-exit
process.exit(1);
}
+2 -2
View File
@@ -250,7 +250,7 @@ export class HostRouter {
* Connects to the controller over the WebSocket and manages intsances.
*/
export default class Host extends lib.Link {
declare ["connector"]: HostConnector;
declare "connector": HostConnector;
router = new HostRouter(this);
/**
@@ -1201,7 +1201,7 @@ export default class Host extends lib.Link {
+------------------------------------------------------------+
${err.stack}`
);
// eslint-disable-next-line node/no-process-exit
process.exit(1);
}
}
+1 -1
View File
@@ -221,7 +221,7 @@ async function loadLayeredIcon(
iconLayer.scale(realScale);
}
// eslint-disable-next-line no-loop-func
iconLayer.scan(0, 0, iconLayer.bitmap.width, iconLayer.bitmap.height, (x, y, sidx) => {
x += xs;
y += ys;
+1 -1
View File
@@ -747,7 +747,7 @@ export class FactorioServer extends events.EventEmitter<FactorioServerEvents> {
this._rconClient.on("authenticated", () => {
this._rconReady = true;
this.emit("rcon-ready");
});
});
this._rconClient.on("end", () => {
this._rconClient = null;
if (!this._rconReady) {
+7 -7
View File
@@ -1,10 +1,10 @@
export interface BuildArgs {
factorioVersion?: string;
dependencies?: Record<string, string>;
clean?: boolean;
pack?: boolean;
build?: boolean;
outputDir: string;
sourceDir: string;
factorioVersion?: string;
dependencies?: Record<string, string>;
clean?: boolean;
pack?: boolean;
build?: boolean;
outputDir: string;
sourceDir: string;
};
export function build(args: BuildArgs): Promise<void>;
+2 -2
View File
@@ -218,7 +218,7 @@ export default class ModPack {
let buf = Buffer.from(modPackString, "base64");
try {
// eslint-disable-next-line node/no-sync
buf = zlib.inflateSync(buf);
buf = Buffer.from(zlib.inflateSync(buf));
} catch (err: any) {
if (err.code.startsWith("Z_")) {
throw new Error("Malformed mod pack string: zlib inflate failed");
@@ -291,7 +291,7 @@ export default class ModPack {
const sizeBytes = uint32Bytes(entries.length);
const itemBytes = entries.flatMap(([key, item]) => [
immutableStringBytes(key),
// eslint-disable-next-line no-use-before-define
propertyTreeBytes(item),
]);
return Buffer.concat([
+3 -3
View File
@@ -1,6 +1,6 @@
// Note: Run compile_validator script after making changes to this file.
import { TSchema, Type, Static } from "@sinclair/typebox";
// eslint-disable-next-line node/no-missing-import
import messageValidate from "./message_validate"; // generated file
import { StringEnum } from "./composites";
@@ -154,7 +154,7 @@ export class Message {
static validate = messageValidate;
static fromJSON(json: any) {
/* eslint-disable no-use-before-define */
if (json.type === "hello") { return MessageHello.fromJSON(json); }
if (json.type === "registerHost") { return MessageRegisterHost.fromJSON(json); }
if (json.type === "registerControl") { return MessageRegisterControl.fromJSON(json); }
@@ -168,7 +168,7 @@ export class Message {
if (json.type === "responseError") { return MessageResponseError.fromJSON(json); }
if (json.type === "event") { return MessageEvent.fromJSON(json); }
if (json.type === "disconnect") { return MessageDisconnect.fromJSON(json); }
/* eslint-enable no-use-before-define */
throw new Error(`Unrecognized message type ${json.type}`);
}
}
+2 -2
View File
@@ -137,8 +137,8 @@ export abstract class Datastore<
V extends DatastoreValue,
U = V,
> extends EventEmitter<{
"update": [ updates: U[] ],
}> {
"update": [ updates: U[] ],
}> {
private dirty = false;
constructor(
+1 -1
View File
@@ -414,7 +414,7 @@ export function readMapExchangeString(exchangeString: string) {
let buf = Buffer.from(exchangeString.slice(3, -3), "base64");
try {
// eslint-disable-next-line node/no-sync
buf = zlib.inflateSync(buf);
buf = Buffer.from(zlib.inflateSync(buf));
} catch (err: any) {
if (err.code.startsWith("Z_")) {
throw new Error("Malformed map exchange string: zlib inflate failed");
+3 -3
View File
@@ -1,8 +1,8 @@
/* eslint-disable node/global-require */
"use strict";
// eslint-disable-next-line node/no-process-env
if (process.env.APP_ENV === "browser") {
// eslint-disable-next-line node/no-extraneous-require
module.exports = require("fast-deep-equal/es6");
} else {
module.exports = require("util").isDeepStrictEqual;
+1 -1
View File
@@ -1,3 +1,3 @@
"use strict";
// eslint-disable-next-line node/no-process-env
module.exports = process.env.APP_ENV === "browser" ? window.WebSocket : require("ws");
+2 -2
View File
@@ -271,7 +271,7 @@ export abstract class WebSocketBaseConnector<
this._check("connected");
if (Date.now() - this._lastHeartbeatMs! > 2000 * this._heartbeatInterval!) {
logger.verbose("Connector | closing after heartbeat timed out");
// eslint-disable-next-line node/no-process-env
if (process.env.APP_ENV === "browser") {
this._socket!.close(ConnectionClosed.Timeout, "Heartbeat timeout");
} else {
@@ -544,7 +544,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector<We
// Open WebSocket to controller
logger.verbose(`Connector | connecting to ${url}`);
// eslint-disable-next-line node/no-process-env
if (process.env.APP_ENV === "browser") {
this._socket = new WebSocket(url) as WebSocketClusterio;
+2 -2
View File
@@ -519,7 +519,7 @@ export async function queryLog(logDirectory: string, filter: QueryLogFilter, ind
}
export function handleUnhandledErrors() {
/* eslint-disable node/no-process-exit */
process.on("uncaughtException", err => {
logger.fatal(`Uncaught exception:\n${err.stack}`);
process.exit(1);
@@ -528,7 +528,7 @@ export function handleUnhandledErrors() {
logger.fatal(`Unhandled rejection:\n${reason.stack ? reason.stack : reason}`);
process.exit(1);
});
/* eslint-enable node/no-process-exit */
}
// for testing only
+1 -1
View File
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/**
* Helpers for loading plugins in Node.js
* @module lib/plugin_loader
+1 -1
View File
@@ -58,7 +58,7 @@ export async function handlePluginCommand(
let pluginInfo: { name: string };
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
pluginInfo = require(pluginPath).plugin;
} catch (err: any) {
logger.error(`Unable to import plugin info from ${args.path}:\n${err.stack}`);
@@ -226,7 +226,7 @@ export default function BaseConfigTree(props: BaseConfigTreeProps) {
</>;
}
// eslint-disable-next-line complexity
function computeTreeData(
control: Control,
form: FormInstance<any>,
+1 -1
View File
@@ -4,7 +4,7 @@ import { Static } from "@sinclair/typebox";
import {
Button, Form, FormInstance, Input, Modal,
Radio, Upload, UploadProps,
Radio, Space, Upload, UploadProps,
} from "antd";
import { InboxOutlined } from "@ant-design/icons";
+7 -7
View File
@@ -61,13 +61,13 @@ export function dose(
let inp1 = [numreq, instore_adj, store_last_tick / numreq, dole, carry]; // 0..4
let inp2 = [
prev_req / numreq,
numreq / numreq_total_adj,
store_last_tick / numreq_total_adj,
prev_req/instore_adj,
b,
numreq_total_adj,
store_last_tick,
debt,
numreq / numreq_total_adj,
store_last_tick / numreq_total_adj,
prev_req/instore_adj,
b,
numreq_total_adj,
store_last_tick,
debt,
]; // 5..12
let inputs = inp1.concat(inp2);
let outputs = [0, 0, 0, 0];
+1 -1
View File
@@ -11,7 +11,7 @@ async function exec(file, args) {
const { stdout, stderr } = await execFile(
file,
args.map(escapeArg),
// eslint-disable-next-line node/no-process-env
{ shell: true, cwd: __dirname, env: { ...process.env, pct: "%"} }
);
return { stdout: JSON.parse(stdout), stderr };
+11 -10
View File
@@ -1055,13 +1055,13 @@ describe("Integration of Clusterio", function() {
describe("instance save transfer", function() {
before(async function() {
slowTest(this);
await execCtl("instance create spam --id 66");
await execCtl("instance assign spam 4");
await execCtl("instance create unassign --id 77");
await execCtlProcess("instance create spam --id 66");
await execCtlProcess("instance assign spam 4");
await execCtlProcess("instance create unassign --id 77");
});
after(async function() {
try {
await execCtl("instance delete spam");
await execCtlProcess("instance delete spam");
} catch (err) {
// Ignore
}
@@ -1075,14 +1075,15 @@ describe("Integration of Clusterio", function() {
: path.join("temp", "test", "instances", "spam", "saves")
;
describe(remote ? "remote" : "local", function() {
this.timeout(10000);
if (remote) {
let hostProcess;
before(async function() {
slowTest(this);
hostProcess = await startAltHost();
await execCtl("instance create save-test --id 88");
await execCtl("instance assign save-test 5");
await execCtlProcess("instance create save-test --id 88");
await execCtlProcess("instance assign save-test 5");
});
after(async function() {
await stopAltHost(hostProcess);
@@ -1090,14 +1091,14 @@ describe("Integration of Clusterio", function() {
}
it("should transfers a save", async function() {
await uploadSave(pri, "transfer.zip", "transfer.zip");
await execCtl(`instance save transfer ${pri} transfer.zip ${sec}`);
await execCtlProcess(`instance save transfer ${pri} transfer.zip ${sec}`);
assert(!await fs.pathExists(path.join(priSaves, "transfer.zip")), "save still at pri");
assert(await fs.pathExists(path.join(secSaves, "transfer.zip")), "save not at sec");
await deleteSave(sec, "transfer.zip");
});
it("should support rename", async function() {
await uploadSave(pri, "transfer.zip", "transfer.zip");
await execCtl(`instance save transfer ${pri} transfer.zip ${sec} rename.zip`);
await execCtlProcess(`instance save transfer ${pri} transfer.zip ${sec} rename.zip`);
assert(!await fs.pathExists(path.join(priSaves, "transfer.zip")), "save still at pri");
assert(await fs.pathExists(path.join(secSaves, "rename.zip")), "save not at sec");
await deleteSave(sec, "rename.zip");
@@ -1105,7 +1106,7 @@ describe("Integration of Clusterio", function() {
it("should auto-rename if target exists", async function() {
await uploadSave(pri, "transfer.zip", "transfer.zip");
await uploadSave(sec, "transfer.zip", "transfer.zip");
await execCtl(`instance save transfer ${pri} transfer.zip ${sec}`);
await execCtlProcess(`instance save transfer ${pri} transfer.zip ${sec}`);
assert(!await fs.pathExists(path.join(priSaves, "transfer.zip")), "save still at pri");
assert(await fs.pathExists(path.join(secSaves, "transfer-2.zip")), "save not at sec");
await deleteSave(sec, "transfer.zip");
@@ -1113,7 +1114,7 @@ describe("Integration of Clusterio", function() {
});
it("should copy when using --copy", async function() {
await uploadSave(pri, "transfer.zip", "transfer.zip");
await execCtl(`instance save transfer ${pri} transfer.zip ${sec} --copy`);
await execCtlProcess(`instance save transfer ${pri} transfer.zip ${sec} --copy`);
assert(await fs.pathExists(path.join(priSaves, "transfer.zip")), "save not at pri");
assert(await fs.pathExists(path.join(secSaves, "transfer.zip")), "save not at sec");
await deleteSave(pri, "transfer.zip");
+4 -4
View File
@@ -120,7 +120,7 @@ class TestHostConnector extends lib.WebSocketClientConnector {
// Mark that this test takes a lot of time, or depeneds on a test
// that takes a lot of time.
function slowTest(test) {
// eslint-disable-next-line node/no-process-env
if (process.env.FAST_TEST) {
test.skip();
}
@@ -221,7 +221,7 @@ function getControl() {
}
function spawn(name, cmd, waitFor) {
// eslint-disable-next-line node/no-process-env
const silent = process.env.SILENT_TEST;
const bootstrap = !controllerProcess || !hostProcess;
function log(...args) {
@@ -264,7 +264,7 @@ async function spawnNode(name, cmd, waitFor) {
before(async function() {
this.timeout(40000);
// eslint-disable-next-line node/no-process-env
const silent = process.env.SILENT_TEST;
if (silent) {
console.log("SILENT_TEST is present in env, loggers after bootstrap will be muted.");
@@ -278,7 +278,7 @@ before(async function() {
}));
// If fast test is enabled then output that it is
// eslint-disable-next-line node/no-process-env
if (process.env.FAST_TEST) {
console.log("FAST_TEST is present in env, slow tests will be skipped.");
}
+4 -4
View File
@@ -816,24 +816,24 @@ describe("lib/ModStore", function () {
assert.equal(
typeof firstMod.latest_release.version,
"string",
"latest_release version should be string" // eslint-disable-line max-len
"latest_release version should be string"
);
assert.equal(
typeof firstMod.latest_release.sha1,
"string",
"latest_release should have a sha1 string" // eslint-disable-line max-len
"latest_release should have a sha1 string"
);
assert.ok(firstMod.latest_release.info_json, "latest_release should have info_json");
assert.equal(
typeof firstMod.latest_release.info_json.factorio_version,
"string",
"info_json should have factorio_version string" // eslint-disable-line max-len
"info_json should have factorio_version string"
);
// Check for an expected field from the user example
assert.equal(
typeof firstMod.downloads_count,
"number",
"First mod should have downloads_count number" // eslint-disable-line max-len
"First mod should have downloads_count number"
);
} else {
// This should not happen for v1.1 but handles edge cases
+1 -2
View File
@@ -303,7 +303,7 @@ describe("lib/data/ModPack", function() {
Buffer.from(str),
];
}
/* eslint-disable indent */
/* eslint-disable @stylistic/indent */
assert.deepEqual(
pack.toModSettingsDat(),
Buffer.concat([
@@ -373,7 +373,6 @@ describe("lib/data/ModPack", function() {
new Uint8Array(Float64Array.from([1]).buffer),
])
);
/* eslint-enable indent */
});
});
describe("defaultModPacks", function() {
+1 -1
View File
@@ -46,7 +46,7 @@ describe("lib/plugin_loader", function() {
it("should reject on broken plugin", async function() {
let brokenMessage;
try {
// eslint-disable-next-line node/global-require
require(path.resolve(brokenPlugin));
} catch (err) {
brokenMessage = err.message;