diff --git a/packages/controller/controller.ts b/packages/controller/controller.ts index b7be8148..e0e72c0f 100644 --- a/packages/controller/controller.ts +++ b/packages/controller/controller.ts @@ -83,18 +83,16 @@ void new lib.Gauge( "clusterio_controller_websocket_active_connections", "How many WebSocket connections are currently open to the controller", { callback: function(gauge:lib.Gauge) { - gauge.set(controller.wsServer.activeConnectors.size); - } - } + gauge.set(controller.wsServer.activeConnectors.size); + }} ); void new lib.Gauge( "clusterio_controller_active_hosts", "How many hosts are currently connected to the controller", { callback: function(gauge:lib.Gauge) { - gauge.set(controller.wsServer.hostConnections.size); - } - } + gauge.set(controller.wsServer.hostConnections.size); + }} ); void new lib.Gauge( @@ -294,7 +292,7 @@ async function initialize(): Promise { logger.info(`Loading available plugins from ${args.pluginList}`); let pluginList = new Map(); try { - pluginList = new Map(JSON.parse(await fs.readFile(args.pluginList, { encoding: 'utf8' }))); + pluginList = new Map(JSON.parse(await fs.readFile(args.pluginList, { encoding: "utf8" }))); } catch (err: any) { if (err.code !== "ENOENT") { throw err; @@ -324,7 +322,7 @@ async function initialize(): Promise { logger.info(`Loading config from ${controllerConfigPath}`); const controllerConfig = new lib.ControllerConfig("controller"); try { - let fileData = await fs.readFile(controllerConfigPath, { encoding: 'utf8' }) + let fileData = await fs.readFile(controllerConfigPath, { encoding: "utf8" }); await controllerConfig.load(JSON.parse(fileData)); } catch (err: any) { @@ -363,7 +361,7 @@ async function initialize(): Promise { controllerConfigPath, controllerConfig, shouldRun, - } + }; } async function startup() { @@ -377,7 +375,7 @@ async function startup() { clusterLogger, pluginInfos, controllerConfigPath, - controllerConfig + controllerConfig, } = await initialize(); if (!shouldRun || !pluginInfos || !controllerConfigPath || !controllerConfig) { return; diff --git a/packages/controller/src/ControlConnection.ts b/packages/controller/src/ControlConnection.ts index 3ace64f8..58eb0fd1 100644 --- a/packages/controller/src/ControlConnection.ts +++ b/packages/controller/src/ControlConnection.ts @@ -254,7 +254,7 @@ export default class ControlConnection extends BaseConnection { assigned_host = undefined; } - let game_port: number|null|undefined = instance.game_port + let game_port: number|null|undefined = instance.game_port; if (game_port === null) { game_port = undefined; } @@ -275,8 +275,8 @@ export default class ControlConnection extends BaseConnection { if (assigned_host === null) { assigned_host = undefined; } - - let game_port: number|null|undefined = instance.game_port + + let game_port: number|null|undefined = instance.game_port; if (game_port === null) { game_port = undefined; } @@ -434,7 +434,7 @@ export default class ControlConnection extends BaseConnection { async handleModPackCreateRequest(request: lib.ModPackCreateRequest) { let modPack = request.modPack; if (modPack.id === undefined) { - throw new lib.RequestError(`Mod pack need an ID to be created`); + throw new lib.RequestError("Mod pack need an ID to be created"); } if (this._controller.modPacks!.has(modPack.id)) { throw new lib.RequestError(`Mod pack with ID ${modPack.id} already exist`); @@ -589,7 +589,7 @@ export default class ControlConnection extends BaseConnection { } async handleLogSetSubscriptionsRequest(request: lib.LogSetSubscriptionsRequest) { - this.logSubscriptions = { + this.logSubscriptions = { all: request.all || false, controller: request.controller || false, hostIds: request.hostIds || [], @@ -622,7 +622,7 @@ export default class ControlConnection extends BaseConnection { controller: request.controller, hostIds: request.hostIds, instanceIds: request.instanceIds, - } + }; let observeDuration = queryLogTime.startTimer(); let { all, controller, hostIds, instanceIds } = request; diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index 68dba094..900ebce5 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -77,7 +77,7 @@ export default class Controller { /** Event subscription controller */ subscriptions: lib.SubscriptionController; - + // Possible states are new, starting, running, stopping, stopped private _state: string = "new"; private _shouldStop: boolean = false; @@ -87,7 +87,7 @@ export default class Controller { _snoopedEvents = new Map(); devMiddleware: any | null = null; - + logDirectory: string = ""; clusterLogIndex: lib.LogIndex | null = null; clusterLogBuildInterval: ReturnType | null = null; @@ -157,7 +157,7 @@ export default class Controller { async _startInternal(args: ControllerArgs) { this.logDirectory = args.logDirectory; this.clusterLogIndex = await lib.LogIndex.load(path.join(this.logDirectory, "cluster")); - + this.clusterLogBuildInterval = setInterval(() => { if (this.clusterLogIndex) { this.clusterLogIndex.buildIndex().catch( @@ -239,7 +239,7 @@ export default class Controller { Controller.addAppRoutes(this.app, this.pluginInfos); if (!args.dev) { - let manifestPath = path.join(__dirname, "..", "..", "web", "manifest.json") + let manifestPath = path.join(__dirname, "..", "..", "web", "manifest.json"); let manifest = await Controller.loadJsonObject(manifestPath); if (!manifest["main.js"]) { @@ -365,7 +365,7 @@ export default class Controller { static async loadHosts(filePath: string): Promise> { let serialized: [number, HostInfo][]; try { - serialized = JSON.parse(await fs.readFile(filePath, { encoding: 'utf8' })); + serialized = JSON.parse(await fs.readFile(filePath, { encoding: "utf8" })); } catch (err: any) { if (err.code !== "ENOENT") { @@ -425,7 +425,7 @@ export default class Controller { static async loadModPacks(filePath: string): Promise> { let json; try { - json = JSON.parse(await fs.readFile(filePath, { encoding : "utf8" })); + json = JSON.parse(await fs.readFile(filePath, { encoding: "utf8" })); } catch (err: any) { if (err.code !== "ENOENT") { throw err; @@ -439,7 +439,7 @@ export default class Controller { await lib.safeOutputFile(filePath, JSON.stringify([...modPacks.values()], null, 4)); } - static async loadModInfos(modsDirectory: string): Promise> { + static async loadModInfos(modsDirectory: string): Promise> { let mods = new Map(); for (let entry of await fs.readdir(modsDirectory, { withFileTypes: true })) { if (entry.isDirectory()) { @@ -476,7 +476,7 @@ export default class Controller { static async loadJsonObject(filePath: string, throwOnMissing: boolean = false): Promise { let manifest = {}; try { - manifest = JSON.parse(await fs.readFile(filePath, { encoding: 'utf8' })); + manifest = JSON.parse(await fs.readFile(filePath, { encoding: "utf8" })); } catch (err: any) { if (!throwOnMissing && err.code !== "ENOENT") { throw err; @@ -543,7 +543,9 @@ export default class Controller { // Set folder to serve static content from (the website) const staticOptions = { immutable: true, maxAge: 1000 * 86400 * 365 }; - app.use("/static", express.static(path.join(__dirname, "..", "..", "..", "dist", "web", "static"), staticOptions)); + app.use("/static", + express.static(path.join(__dirname, "..", "..", "..", "dist", "web", "static"), staticOptions) + ); app.use("/static", express.static("static", staticOptions)); // Used for data export files // Add API routes @@ -595,9 +597,10 @@ export default class Controller { * Get instance by ID for a request * * @param instanceId - ID of instance to get. + * @returns Info for the given instance if it exists * @throws {module:lib.RequestError} if the instance does not exist. */ - getRequestInstance(instanceId:number):InstanceInfo { + getRequestInstance(instanceId:number): InstanceInfo { let instance = this.instances!.get(instanceId); if (!instance) { throw new lib.RequestError(`Instance with ID ${instanceId} does not exist`); @@ -773,7 +776,7 @@ export default class Controller { assigned_host = undefined; } - let game_port: number|null|undefined = instance.game_port + let game_port: number|null|undefined = instance.game_port; if (game_port === null) { game_port = undefined; } diff --git a/packages/controller/src/HostConnection.ts b/packages/controller/src/HostConnection.ts index be4c4413..61d2fb97 100644 --- a/packages/controller/src/HostConnection.ts +++ b/packages/controller/src/HostConnection.ts @@ -46,7 +46,7 @@ export default class HostConnection extends BaseConnection { this.plugins = new Map(Object.entries(registerData.plugins)); this._checkPluginVersions(); - let currentHostInfo = this._controller.hosts!.get(this._id) + let currentHostInfo = this._controller.hosts!.get(this._id); this._controller.hosts!.set(this._id, { agent: this._agent, @@ -223,7 +223,9 @@ export default class HostConnection extends BaseConnection { } instanceConfig.set("instance.assigned_host", this._id); - let newInstance = new InstanceInfo({ config: instanceConfig, status: instanceData.status as InstanceStatus }); + let newInstance = new InstanceInfo( + { config: instanceConfig, status: instanceData.status as InstanceStatus } + ); this._controller.instances!.set(instanceConfig.get("instance.id"), newInstance); this._controller.addInstanceHooks(newInstance); await this.send( diff --git a/packages/controller/src/HttpCloser.ts b/packages/controller/src/HttpCloser.ts index 4c52364e..2631930c 100644 --- a/packages/controller/src/HttpCloser.ts +++ b/packages/controller/src/HttpCloser.ts @@ -26,7 +26,8 @@ export default class HttpCloser { private _responses: Set; /** - * Server to attach this closer to. + * Create HttpCloser attached to a server. + * @param server - Node.js HTTP(S) server to attach to. */ constructor(server: http.Server | https.Server) { this._server = server; diff --git a/packages/controller/src/InstanceInfo.ts b/packages/controller/src/InstanceInfo.ts index 7af224cf..40c869cb 100644 --- a/packages/controller/src/InstanceInfo.ts +++ b/packages/controller/src/InstanceInfo.ts @@ -14,7 +14,7 @@ import type * as lib from "@clusterio/lib"; * - `exporting_data`: Instance is in the process of exporting game data. * - `deleted`: Instance has been deleted. */ -export type InstanceStatus = +export type InstanceStatus = "unknown" | "unassigned" | "stopped" | "starting" | "running" | "stopping" | "creating_save" | "exporting_data" | "deleted"; diff --git a/packages/controller/src/UserManager.ts b/packages/controller/src/UserManager.ts index bd2789c3..51254cb2 100644 --- a/packages/controller/src/UserManager.ts +++ b/packages/controller/src/UserManager.ts @@ -18,7 +18,7 @@ export default class UserManager { async load(filePath: string): Promise { try { - let content = JSON.parse(await fs.readFile(filePath, { encoding: 'utf8' })); + let content = JSON.parse(await fs.readFile(filePath, { encoding: "utf8" })); for (let serializedRole of content.roles) { let role = new lib.Role(serializedRole); this.roles.set(role.id, role); @@ -65,6 +65,7 @@ export default class UserManager { /** * Creates a new user and add it to the user database. * @param name - Name of the user to create. + * @returns The created user. */ createUser(name:string): lib.User { if (this.users.has(name)) { @@ -74,7 +75,7 @@ export default class UserManager { let roles = []; let defaultRoleId = this._config.get("controller.default_role_id"); if (defaultRoleId !== null) { - roles.push(defaultRoleId) + roles.push(defaultRoleId); } let user = new lib.User({ name, roles }, this.roles); diff --git a/packages/controller/src/WsServer.ts b/packages/controller/src/WsServer.ts index e52e267e..07886741 100644 --- a/packages/controller/src/WsServer.ts +++ b/packages/controller/src/WsServer.ts @@ -54,7 +54,9 @@ export default class WsServer { noServer: true, path: "/api/socket", }); - this.wss.on("connection", (socket: lib.WebSocketClusterio, req: IncomingMessage) => this.handleConnection(socket, req)); + this.wss.on("connection", + (socket: lib.WebSocketClusterio, req: IncomingMessage) => this.handleConnection(socket, req), + ); } async stop(): Promise { diff --git a/packages/controller/src/metrics.ts b/packages/controller/src/metrics.ts index d25d5690..ae0b7aca 100644 --- a/packages/controller/src/metrics.ts +++ b/packages/controller/src/metrics.ts @@ -12,4 +12,4 @@ endpointHitCounter.labels = util.deprecate( "incrementing endpointHitCounter is no longer needed and has no effect" ); -export default endpointHitCounter +export default endpointHitCounter; diff --git a/packages/controller/src/routes.ts b/packages/controller/src/routes.ts index 4e506313..4e5c14a1 100644 --- a/packages/controller/src/routes.ts +++ b/packages/controller/src/routes.ts @@ -34,7 +34,7 @@ function mergeSamples(destinationResult: any, sourceResult: any) { // Prometheus polling endpoint async function getMetrics(req: Request, res: Response, next: any) { - const controller: Controller = req.app.locals.controller + const controller: Controller = req.app.locals.controller; let results: any[] = []; let pluginResults: any[] = await lib.invokeHook(controller.plugins, "onMetrics"); @@ -93,7 +93,7 @@ async function getMetrics(req: Request, res: Response, next: any) { // lib.exposition expect AsyncIterable as parameter. // Should wrap results into a Generator functions ? - // @ts-ignore + // @ts-ignore let text = await lib.exposition(results); res.set("Content-Type", lib.exposition.contentType); res.send(text); @@ -426,28 +426,29 @@ async function uploadSave(req: Request, res: Response) { if (contentMime === "multipart/form-data") { await new Promise(resolve => { - let instanceId:number | undefined; - let parser = busboy({ headers: req.headers }); - parser.on("file", (name: string, stream: nodeStream.Readable, { filename, mimeType }: { filename: string, mimeType: string } ) => { + let instanceId: number | undefined; + function fileHandler( + name: string, + stream: nodeStream.Readable, + { filename, mimeType }: { filename: string, mimeType: string } + ) { if (instanceId === undefined) { requestErrors.push("instance_id must come before files uploaded"); } - if (!zipMimes.includes(mimeType)) { requestErrors.push("invalid file Content-Type"); } - if (!filename.endsWith(".zip")) { requestErrors.push("filename must end with .zip"); } - if (errors.length || requestErrors.length) { stream.resume(); return; } - tasks.push(handleFile(instanceId as number, stream, filename, mimeType)); - }); + } + let parser = busboy({ headers: req.headers }); + parser.on("file", fileHandler); parser.on("field", (name, value, info) => { if (name === "instance_id") { instanceId = Number.parseInt(value, 10); @@ -593,23 +594,26 @@ async function uploadMod(req: Request, res: Response) { if (contentMime === "multipart/form-data") { await new Promise(resolve => { - let parser = busboy({ headers: req.headers }); - parser.on("file", (name:string, stream: nodeStream.Readable, { filename, mimeType }: { filename: string, mimeType: string }) => { + function fileHandler( + name: string, + stream: nodeStream.Readable, + { filename, mimeType }: { filename: string, mimeType: string } + ) { if (!zipMimes.includes(mimeType)) { requestErrors.push("invalid file Content-Type"); } - if (!filename.endsWith(".zip")) { requestErrors.push("filename must end with .zip"); } - if (errors.length || requestErrors.length) { stream.resume(); return; } - tasks.push(handleFile(stream, filename)); - }); + } + + let parser = busboy({ headers: req.headers }); + parser.on("file", fileHandler); parser.on("close", resolve); parser.on("error", (err: any) => { logger.error(`Error parsing multipart request in upload-mod:\n${err.stack}`); diff --git a/packages/ctl/src/commands.ts b/packages/ctl/src/commands.ts index 1d8d5d9a..484490f1 100644 --- a/packages/ctl/src/commands.ts +++ b/packages/ctl/src/commands.ts @@ -466,7 +466,7 @@ instanceConfigCommands.add(new lib.Command({ }); await events.once(doneEmitter, "dot_on_done"); try { - await fs.unlink(tmpFile) + await fs.unlink(tmpFile); } catch (err) { print("err: temporary file", tmpFile, "could not be deleted."); print("This is not fatal, but they may build up over time if the issue persists."); diff --git a/packages/host/src/Host.ts b/packages/host/src/Host.ts index 835c39b7..7af872c0 100644 --- a/packages/host/src/Host.ts +++ b/packages/host/src/Host.ts @@ -1,4 +1,3 @@ -"use strict"; import fs from "fs-extra"; import path from "path"; import events from "events"; diff --git a/packages/host/src/Instance.ts b/packages/host/src/Instance.ts index 9c3e059f..0288ee1e 100644 --- a/packages/host/src/Instance.ts +++ b/packages/host/src/Instance.ts @@ -11,7 +11,7 @@ import * as lib from "@clusterio/lib"; import { FactorioServer } from "./server"; import { SaveModule, patch } from "./patch"; import { exportData } from "./export"; -import type Host from "./Host" +import type Host from "./Host"; const instanceRconCommandDuration = new lib.Histogram( @@ -99,7 +99,7 @@ export default class Instance extends lib.Link { /** * ID of this instance, equivalenet to `instance.config.get("instance.id")`. */ - readonly id: number + readonly id: number; plugins: Map; config: lib.InstanceConfig; logger: lib.Logger; diff --git a/packages/host/src/export.ts b/packages/host/src/export.ts index 76f13ebb..dcd2b01a 100644 --- a/packages/host/src/export.ts +++ b/packages/host/src/export.ts @@ -1,5 +1,4 @@ // Export of item icons and locale -"use strict"; import fs from "fs-extra"; import path from "path"; import Jimp from "jimp"; diff --git a/packages/host/src/patch.ts b/packages/host/src/patch.ts index 7e16bf92..035b824d 100644 --- a/packages/host/src/patch.ts +++ b/packages/host/src/patch.ts @@ -18,7 +18,7 @@ export class SaveModule { /** Module */ public info: lib.ModuleInfo, /** Files and their content that will be patched into the save */ - public files = new Map, + public files = new Map(), ) { } static moduleFilePath(filePath: string, moduleName: string) { @@ -47,7 +47,7 @@ export class SaveModule { if (entry.isFile()) { let savePath = SaveModule.moduleFilePath(relativePath, this.info.name); this.files.set(savePath, await fs.readFile(fsPath)); - if (relativePath == "module_exports.lua") { + if (relativePath === "module_exports.lua") { this.files.set( `modules/${this.info.name}.lua`, Buffer.from(`return require("modules/${this.info.name}/module_exports")`, "utf-8") @@ -96,7 +96,7 @@ export class SaveModule { version: plugin.info.version, dependencies: { "clusterio": "*" }, ...JSON.parse(await fs.readFile(moduleJsonPath, "utf8")), - } + }; } catch (err: any) { throw new Error(`Loading module/module.json in plugin ${plugin.info.name} failed: ${err.message}`); } @@ -173,7 +173,7 @@ export class PatchInfo { interface PatchInfoV0 { patch_number: number; scenario: ScenarioInfoV0; - modules: { name: string, files: { path: string, load: boolean, require: boolean }[], }[]; + modules: { name: string, files: { path: string, load: boolean, require: boolean }[], }[]; } const info = json as unknown as PatchInfoV0; @@ -394,7 +394,7 @@ export async function patch(savePath: string, modules: SaveModule[]) { } else { for (let module of patchInfo.modules) { for (let file of module.files.keys()) { - zip.remove(root.file(file)!.name) + zip.remove(root.file(file)!.name); } } patchInfo.modules = []; diff --git a/packages/host/src/server.ts b/packages/host/src/server.ts index 93a93364..a2404bb1 100644 --- a/packages/host/src/server.ts +++ b/packages/host/src/server.ts @@ -220,65 +220,61 @@ function parseOutput(line: string, source: "stdout" | "stderr"): lib.ParsedFacto level: secLogMatch[1], file: secLogMatch[2], message: secLogMatch[5], - } + }; + } // The other possibility is that the content is a generic message - } else { + return { + source, + format, + time, + type: "generic", + message: secContent, + }; + } + + // The second category of output starts with a date stamp of the format + // "yyyy-mm-dd hh:mm:ss message" + const dateRegex = /^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d) (.*)$/; + let dateMatch = dateRegex.exec(line); + if (dateMatch) { + const format = "date"; + const time = dateMatch[1]; + let dateContent = dateMatch[2]; + + // A date output has two general formats. The first is an action + // followed by a message and has a format of "[ACTION] message" + const dateActionRegex = /^\[(\w+)\] (.*)$/; + let dateActionMatch = dateActionRegex.exec(dateContent); + if (dateActionMatch) { return { source, format, time, - type: "generic", - message: secContent, - } + type: "action", + action: dateActionMatch[1], + message: dateActionMatch[2], + }; } - // The second category of output starts with a date stamp of the format - // "yyyy-mm-dd hh:mm:ss message" - } else { - const dateRegex = /^(\d{4}-\d\d-\d\d \d\d:\d\d:\d\d) (.*)$/; - let dateMatch = dateRegex.exec(line); - if (dateMatch) { - const format = "date"; - const time = dateMatch[1]; - let dateContent = dateMatch[2]; - - // A date output has two general formats. The first is an action - // followed by a message and has a format of "[ACTION] message" - const dateActionRegex = /^\[(\w+)\] (.*)$/; - let dateActionMatch = dateActionRegex.exec(dateContent); - if (dateActionMatch) { - return { - source, - format, - time, - type: "action", - action: dateActionMatch[1], - message: dateActionMatch[2], - } - - // The other format is a generic message - } else { - return { - source, - format, - time, - type: "generic", - message: dateContent, - } - } - - // The last category of output is simply a generic message with no - // formating. - } else { - return { - source, - format: "none", - type: "generic", - message: line, - } - } + // The other format is a generic message + return { + source, + format, + time, + type: "generic", + message: dateContent, + }; } + + // The last category of output is simply a generic message with no + // formating. + return { + source, + format: "none", + type: "generic", + message: line, + }; } // https://stackoverflow.com/a/49402091 @@ -465,7 +461,7 @@ export class FactorioServer extends events.EventEmitter { /** Enable Factorio.com based multiplayer bans **/ enableAuthserverBans: boolean; /** Enable verbose logging */ - verboseLogging: boolean + verboseLogging: boolean; /** Timeout in ms to wait for a response to a shutdown command */ hangTimeout = 5000; @@ -852,8 +848,8 @@ export class FactorioServer extends events.EventEmitter { "--config", this.writePath("config.ini"), "--create", this.writePath("saves", name), ...(seed !== undefined ? ["--map-gen-seed", String(seed)] : []), - ...(mapGenSettings !== undefined ? - ["--map-gen-settings", this.writePath("map-gen-settings.json")] : [] + ...(mapGenSettings !== undefined + ? ["--map-gen-settings", this.writePath("map-gen-settings.json")] : [] ), ...(mapSettings !== undefined ? ["--map-settings", this.writePath("map-settings.json")] : []), ...(this.verboseLogging ? ["--verbose"] : []), @@ -944,8 +940,8 @@ export class FactorioServer extends events.EventEmitter { "--config", this.writePath("config.ini"), "--start-server-load-scenario", scenario, ...(seed !== undefined ? ["--map-gen-seed", String(seed)] : []), - ...(mapGenSettings !== undefined ? - ["--map-gen-settings", this.writePath("map-gen-settings.json")] : [] + ...(mapGenSettings !== undefined + ? ["--map-gen-settings", this.writePath("map-gen-settings.json")] : [] ), ...(mapSettings !== undefined ? ["--map-settings", this.writePath("map-settings.json")] : []), "--port", String(this.gamePort), diff --git a/packages/lib/index.ts b/packages/lib/index.ts index 19583966..428086e3 100644 --- a/packages/lib/index.ts +++ b/packages/lib/index.ts @@ -25,7 +25,7 @@ export * from "./src/shared_commands"; export * from "./src/stream"; export * from "./src/users"; export * from "./src/zip_ops"; -export * from "./src/subscriptions" +export * from "./src/subscriptions"; export { default as ExponentialBackoff } from "./src/ExponentialBackoff"; export { default as PlayerStats } from "./src/PlayerStats"; diff --git a/packages/lib/src/config/classes.ts b/packages/lib/src/config/classes.ts index 88614815..4b40e4a9 100644 --- a/packages/lib/src/config/classes.ts +++ b/packages/lib/src/config/classes.ts @@ -3,7 +3,7 @@ import { Type, Static } from "@sinclair/typebox"; import events from "events"; import isDeepStrictEqual from "../is_deep_strict_equal"; -import { basicType } from"../helpers"; +import { basicType } from "../helpers"; export type ConfigLocation = "controller" | "host" | "instance" | "control"; diff --git a/packages/lib/src/config/definitions.ts b/packages/lib/src/config/definitions.ts index 72a5be05..9c878065 100644 --- a/packages/lib/src/config/definitions.ts +++ b/packages/lib/src/config/definitions.ts @@ -264,7 +264,7 @@ export class HostConfig extends classes.Config { get(name: "host.public_address"): string; get(name: "host.max_reconnect_delay"): number; get(name: string): unknown; - get(name: string) { + get(name: string) { return super.get(name); } } @@ -503,7 +503,10 @@ export class ControlConfig extends classes.Config { } ControlConfig.registerGroup(ControlGroup); -function validateGroup(pluginInfo: PluginNodeEnvInfo|PluginWebpackEnvInfo, groupName: "ControllerConfigGroup"|"InstanceConfigGroup") { +function validateGroup( + pluginInfo: PluginNodeEnvInfo | PluginWebpackEnvInfo, + groupName: "ControllerConfigGroup"|"InstanceConfigGroup", +) { if (!(pluginInfo[groupName]?.prototype instanceof classes.PluginConfigGroup)) { throw new Error( `Expected ${groupName} for ${pluginInfo.name} to be a subclass of PluginConfigGroup` diff --git a/packages/lib/src/data/ModPack.ts b/packages/lib/src/data/ModPack.ts index 95d1c31f..14fc7f29 100644 --- a/packages/lib/src/data/ModPack.ts +++ b/packages/lib/src/data/ModPack.ts @@ -1,4 +1,3 @@ -"use strict"; import zlib from "zlib"; import { Type, Static } from "@sinclair/typebox"; diff --git a/packages/lib/src/data/composites.ts b/packages/lib/src/data/composites.ts index 8566185f..c4f912ef 100644 --- a/packages/lib/src/data/composites.ts +++ b/packages/lib/src/data/composites.ts @@ -1,7 +1,7 @@ import { Type } from "@sinclair/typebox"; export function StringEnum(values: [...T]) { - return Type.Unsafe({ type: 'string', enum: values }) + return Type.Unsafe({ type: "string", enum: values }); } export interface JSONDeserialisable { diff --git a/packages/lib/src/data/message_validate.d.ts b/packages/lib/src/data/message_validate.d.ts index fdd40377..d9ec5838 100644 --- a/packages/lib/src/data/message_validate.d.ts +++ b/packages/lib/src/data/message_validate.d.ts @@ -1,4 +1,4 @@ import type { ValidateFunction } from "ajv"; import type { Message } from "./messages_core"; -var message_validate: ValidateFunction; +const message_validate: ValidateFunction; export default message_validate; diff --git a/packages/lib/src/data/messages_controller.ts b/packages/lib/src/data/messages_controller.ts index e39de057..5a0aefc8 100644 --- a/packages/lib/src/data/messages_controller.ts +++ b/packages/lib/src/data/messages_controller.ts @@ -166,6 +166,7 @@ export class LogQueryRequest { json.all, json.controller, json.hostIds, json.instanceIds, json.maxLevel, json.limit, json.order ); } + static Response = class Response { constructor( public log: object[], diff --git a/packages/lib/src/data/messages_host.ts b/packages/lib/src/data/messages_host.ts index 5389a7c2..4343e14b 100644 --- a/packages/lib/src/data/messages_host.ts +++ b/packages/lib/src/data/messages_host.ts @@ -23,7 +23,15 @@ export class HostDetails { }); static fromJSON(json: Static) { - return new this(json.agent, json.version, json.name, json.id, json.connected, json.publicAddress, json.tokenValidAfter); + return new this( + json.agent, + json.version, + json.name, + json.id, + json.connected, + json.publicAddress, + json.tokenValidAfter, + ); } } diff --git a/packages/lib/src/data/messages_user.ts b/packages/lib/src/data/messages_user.ts index be7c1c9d..c50a9339 100644 --- a/packages/lib/src/data/messages_user.ts +++ b/packages/lib/src/data/messages_user.ts @@ -211,7 +211,7 @@ export class RawUser { // TODO refactor into lib/user.User isDeleted: this.isDeleted, }; if (this.playerStats) { - json.playerStats = this.playerStats.toJSON() + json.playerStats = this.playerStats.toJSON(); } if (this.instanceStats) { json.instanceStats = [...this.instanceStats].map(([k, v]) => [k, v.toJSON()]); diff --git a/packages/lib/src/database.ts b/packages/lib/src/database.ts index 3f54c301..aaedd478 100644 --- a/packages/lib/src/database.ts +++ b/packages/lib/src/database.ts @@ -277,8 +277,9 @@ export class ItemDatabase { /** * Allow to iterate through the items. + * @returns array of items. */ getEntries(): IterableIterator<[string, number]> { - return this._items.entries() + return this._items.entries(); } } diff --git a/packages/lib/src/factorio/exchange_string.ts b/packages/lib/src/factorio/exchange_string.ts index 13a4ef6a..3ca83522 100644 --- a/packages/lib/src/factorio/exchange_string.ts +++ b/packages/lib/src/factorio/exchange_string.ts @@ -1,4 +1,3 @@ -"use strict"; import zlib from "zlib"; class MapReaderState { @@ -72,7 +71,7 @@ function readString(state: MapReaderState) { return data; } -function readOptional(state: MapReaderState, readValue: (state: MapReaderState) => T) { +function readOptional(state: MapReaderState, readValue: (s: MapReaderState) => T) { let load = readUInt8(state) !== 0; if (!load) { return null; @@ -80,7 +79,7 @@ function readOptional(state: MapReaderState, readValue: (state: MapReaderStat return readValue(state); } -function readArray(state: MapReaderState, readItem: (state: MapReaderState) => T) { +function readArray(state: MapReaderState, readItem: (s: MapReaderState) => T) { let size = readUInt32so(state); let array: T[] = []; @@ -94,8 +93,8 @@ function readArray(state: MapReaderState, readItem: (state: MapReaderState) = function readDict( state: MapReaderState, - readKey: (state: MapReaderState) => K, - readValue: (state: MapReaderState) => V + readKey: (s: MapReaderState) => K, + readValue: (s: MapReaderState) => V ) { let size = readUInt32so(state); diff --git a/packages/lib/src/is_deep_strict_equal.d.ts b/packages/lib/src/is_deep_strict_equal.d.ts index ec5e4c72..3ec0532c 100644 --- a/packages/lib/src/is_deep_strict_equal.d.ts +++ b/packages/lib/src/is_deep_strict_equal.d.ts @@ -1 +1 @@ -export default function isDeepStrictEqual(a: any, b: any): boolean +export default function isDeepStrictEqual(a: any, b: any): boolean; diff --git a/packages/lib/src/link/connectors.ts b/packages/lib/src/link/connectors.ts index 8345d975..2f22236d 100644 --- a/packages/lib/src/link/connectors.ts +++ b/packages/lib/src/link/connectors.ts @@ -1,13 +1,12 @@ // Connection adapters for Links -"use strict"; import { strict as assert } from "assert"; import events from "events"; import WebSocket from "./WebSocket"; import * as libData from "../data"; -import * as libErrors from "../errors"; -import { logger } from "../logging"; -import ExponentialBackoff from "../ExponentialBackoff"; +import * as libErrors from "../errors"; +import { logger } from "../logging"; +import ExponentialBackoff from "../ExponentialBackoff"; import type { Request, Event } from "./link"; diff --git a/packages/lib/src/link/index.ts b/packages/lib/src/link/index.ts index e13d1d8b..d48297e3 100644 --- a/packages/lib/src/link/index.ts +++ b/packages/lib/src/link/index.ts @@ -3,5 +3,5 @@ * @module lib/link * @author Hornwitser */ -export * from "./link" -export * from "./connectors" +export * from "./link"; +export * from "./connectors"; diff --git a/packages/lib/src/link/link.ts b/packages/lib/src/link/link.ts index 73bb633e..998e3a63 100644 --- a/packages/lib/src/link/link.ts +++ b/packages/lib/src/link/link.ts @@ -316,7 +316,7 @@ export class Link { if (!this.router) { let err = new libErrors.InvalidMessage( `Received message addressed to ${(message as libData.MessageRequest).dst} but this link `+ - `does not route messages` + "does not route messages" ); if (message.type === "request") { this.connector.sendResponseError( @@ -401,8 +401,8 @@ export class Link { this.connector.sendResponseError( new libData.ResponseError(err.message, err.code, err.stack), message.src, spoofedSrc ); - } catch (err: any) { - logger.error(`Unexpected error sending error response for ${message.name}:\n${err.stack}`); + } catch (subErr: any) { + logger.error(`Unexpected error sending error response for ${message.name}:\n${subErr.stack}`); } } ); @@ -527,7 +527,7 @@ export class Link { let requestId = this._nextRequestId; this._nextRequestId += 1; this._pendingRequests.set( - requestId, { request: entry, promise, resolve: resolve!, reject: reject!, dst, } + requestId, { request: entry, promise, resolve: resolve!, reject: reject!, dst } ); this.connector.sendRequest(request, requestId, dst); return promise; diff --git a/packages/lib/src/link/messages.ts b/packages/lib/src/link/messages.ts index 0f21bbd0..73868284 100644 --- a/packages/lib/src/link/messages.ts +++ b/packages/lib/src/link/messages.ts @@ -1,11 +1,10 @@ -"use strict"; import * as core from "../data/messages_core"; import * as controller from "../data/messages_controller"; import * as host from "../data/messages_host"; import * as instance from "../data/messages_instance"; import * as mod from "../data/messages_mod"; import * as user from "../data/messages_user"; -import * as subscriptions from "../subscriptions" +import * as subscriptions from "../subscriptions"; import type { RequestClass, EventClass } from "./link"; /** diff --git a/packages/lib/src/logging.ts b/packages/lib/src/logging.ts index 03b08870..0e6e6e97 100644 --- a/packages/lib/src/logging.ts +++ b/packages/lib/src/logging.ts @@ -1,4 +1,3 @@ -"use strict"; import winston from "winston"; import Transport from "winston-transport"; import { LEVEL, MESSAGE } from "triple-beam"; diff --git a/packages/lib/src/logging_utils.ts b/packages/lib/src/logging_utils.ts index 42f50045..592bae5e 100644 --- a/packages/lib/src/logging_utils.ts +++ b/packages/lib/src/logging_utils.ts @@ -4,7 +4,6 @@ * @author Hornwitser * @module lib/logging_utils */ -"use strict"; import fs from "fs-extra"; import path from "path"; import stream from "stream"; diff --git a/packages/lib/src/plugin.ts b/packages/lib/src/plugin.ts index 67623f35..de5c55c7 100644 --- a/packages/lib/src/plugin.ts +++ b/packages/lib/src/plugin.ts @@ -120,6 +120,7 @@ export class BaseInstancePlugin { message: string, expectEmpty: boolean, }[] = []; + private _sendingRconMessages = false; constructor( @@ -655,7 +656,6 @@ export class BaseControlPlugin { } - /** * Plugin supplied login form */ diff --git a/packages/lib/src/plugin_loader.ts b/packages/lib/src/plugin_loader.ts index 6a1a72bf..651a7b51 100644 --- a/packages/lib/src/plugin_loader.ts +++ b/packages/lib/src/plugin_loader.ts @@ -89,7 +89,7 @@ export async function loadControllerPluginClass( /** * Load instance plugin class of a plugin - + * * @param pluginInfo - * Plugin info object returned from {@link * loadPluginInfos} to load class from. diff --git a/packages/lib/src/prometheus.ts b/packages/lib/src/prometheus.ts index fd1ab626..5ef900e7 100644 --- a/packages/lib/src/prometheus.ts +++ b/packages/lib/src/prometheus.ts @@ -1188,7 +1188,7 @@ class HistogramChild { protected _bucketValues: Map; protected _sumValues: Map; protected _countValues: Map; - protected _key: string + protected _key: string; protected _bucketKeys: Map; constructor(collector: Histogram, key: string) { @@ -1438,6 +1438,7 @@ export class Histogram extends LabeledCollector { * Observe a given value and increment matching buckets * * Note: Only works if this is an unlabeled collector. + * @param value - number to count into histogram buckets. */ observe(value: number) { this._defaultChild!.observe(value); diff --git a/packages/lib/src/schema.ts b/packages/lib/src/schema.ts index d39416e9..de8032f4 100644 --- a/packages/lib/src/schema.ts +++ b/packages/lib/src/schema.ts @@ -22,13 +22,13 @@ export function compile(schema: JSONSchemaType) { } let doValidate: ValidateFunction; - const validate = >function (data) { + const validate = > function (data) { if (!doValidate) { doValidate = ajv.compile(schema); } let result = doValidate(data); validate.errors = doValidate.errors; return result; - } - return validate + }; + return validate; } diff --git a/packages/lib/src/shared_commands.ts b/packages/lib/src/shared_commands.ts index 7c959b93..cec55d47 100644 --- a/packages/lib/src/shared_commands.ts +++ b/packages/lib/src/shared_commands.ts @@ -2,7 +2,6 @@ * Implementation of commands shared between controller/host/ctl. * @module lib/shared_commands */ -"use strict"; import path from "path"; import * as libConfig from "./config"; diff --git a/packages/lib/src/stream.ts b/packages/lib/src/stream.ts index 5e2ab36c..315e6a13 100644 --- a/packages/lib/src/stream.ts +++ b/packages/lib/src/stream.ts @@ -1,4 +1,3 @@ -"use strict"; import assert from "assert"; import fs from "fs-extra"; import stream from "stream"; diff --git a/packages/lib/src/subscriptions.ts b/packages/lib/src/subscriptions.ts index ae346b65..1f6c149e 100644 --- a/packages/lib/src/subscriptions.ts +++ b/packages/lib/src/subscriptions.ts @@ -33,16 +33,15 @@ export class SubscriptionResponse { Type.String(), Type.Unknown(), ]), - Type.Null() - ]) + Type.Null(), + ]); toJSON() { if (this.eventReplay) { const entry = Link._eventsByClass.get(this.eventReplay.constructor)!; return [entry.name, this.eventReplay]; - } else { - return null; } + return null; } static fromJSON(json: Static): SubscriptionResponse { @@ -67,7 +66,7 @@ export class SubscriptionResponse { export class SubscriptionRequest { declare ["constructor"]: typeof SubscriptionRequest; static type = "request" as const; - static src = ["control", "instance"] as const; + static src = ["control", "instance"] as const; static dst = "controller" as const; static Response = SubscriptionResponse; static permission(user: User, message: MessageRequest) { @@ -100,7 +99,7 @@ export class SubscriptionRequest { Type.Boolean(), Type.Array(Type.Union([Type.String(), Type.Number()])), Type.Number(), - ]) + ]); toJSON() { return [this.eventName, this.allChannels, this.channels, this.lastRequestTime]; @@ -130,6 +129,9 @@ export class SubscriptionController { /** * Allow clients to subscribe to an event by telling the subscription controller to accept them * Has an optional subscription update handler which is called when any client updates their subscription + * @param Event - Event class which is sent out as updates. + * @param subscriptionUpdate - + * Optional handler called when a client updates its subscriptions. */ handle(Event: EventClass, subscriptionUpdate?: SubscriptionRequestHandler) { const entry = Link._eventsByClass.get(Event); @@ -147,6 +149,7 @@ export class SubscriptionController { /** * Broadcast an event to all subscribers of that event, will be filtered by channel if a ChannelEvent is provided + * @param event - Event to broadcast. */ broadcast(event: Event | ChannelEvent) { const entry = Link._eventsByClass.get(event.constructor); @@ -169,6 +172,11 @@ export class SubscriptionController { /** * Handle incoming event subscription requests + * @param event - incomming event. + * @param src - Source address of incomming request. + * @param dst - destination address of incomming request. + * @returns Response to subscription request. + * @internal */ async _handleRequest(event: SubscriptionRequest, src: Address, dst: Address) { if (!Link._eventsByName.has(event.eventName)) { @@ -192,7 +200,9 @@ export class SubscriptionController { onceClose = () => eventData.subscriptions.delete(link); link.connector.once("close", onceClose); } - eventData.subscriptions.set(link, { all: event.allChannels, channels: event.channels, onceClose: onceClose }); + eventData.subscriptions.set( + link, { all: event.allChannels, channels: event.channels, onceClose: onceClose }, + ); } return new SubscriptionResponse(eventReplay); } @@ -204,15 +214,15 @@ export class SubscriptionController { * Multiple handlers can be subscribed at the same time, on the same or different channels */ export class EventSubscriber { - _callbacks = new Array>() - _channelCallbacks = new Map>>() + _callbacks = new Array>(); + _channelCallbacks = new Map>>(); lastResponse: Event | null = null; lastResponseTime = 0; - control?: Link + control?: Link; constructor( private event: EventClass | ChannelEventClass, - private prehandler?: (event: T) => V, + private prehandler?: (e: T) => V, control?: Link ) { const entry = Link._eventsByClass.get(this.event); @@ -226,6 +236,8 @@ export class EventSubscriber { /** * Handle incoming events and distribute it to the correct callbacks + * @param response - event from subscribed resource + * @internal */ async _handle(response: Event | ChannelEvent) { this.lastResponse = response; @@ -246,10 +258,14 @@ export class EventSubscriber { } /** - * If a control link was not connected at creation, it can be connected here (normally during onControllerConnectionEvent) + * If a control link was not connected at creation, it can be connected + * here (normally during onControllerConnectionEvent) + * @param control - Control link to associate with. */ async connectControl(control: Link) { - if (this.control === control) return; + if (this.control === control) { + return; + } this.control = control; this.control.handle(this.event, this._handle.bind(this)); await this._updateSubscription(); @@ -257,6 +273,8 @@ export class EventSubscriber { /** * Subscribe to receive all event notifications + * @param handler - + * callback invoked whenever the subscribed resource changes. */ async subscribe(handler: EventSubscriberCallback) { this._callbacks.push(handler); @@ -265,6 +283,10 @@ export class EventSubscriber { /** * Subscribe to receive event notifications for the given channel + * @param channel - Channel to subscribe to. + * @param handler - + * callback invoked whenever the subscribed resource changes on the + * given channel. */ async subscribeToChannel(channel: string | number, handler: EventSubscriberCallback) { if (!this._channelCallbacks.get(channel)) { @@ -275,8 +297,14 @@ export class EventSubscriber { } /** - * Unsubscribe from receiving all event notifications, does not effect the subscriptions of other handlers - * Will throw an error if your handler is not subscribed to all channels, does not accept anonymous functions + * Unsubscribe from receiving all event notifications, does not effect + * the subscriptions of other handlers. + * + * @param handler - A callback previously passed to {@link subscribe} + * + * @throws {Error} + * If your handler is not subscribed to all channels, does not + * accept anonymous functions */ async unsubscribe(handler: EventSubscriberCallback) { let index = this._callbacks.lastIndexOf(handler); @@ -289,8 +317,15 @@ export class EventSubscriber { } /** - * Unsubscribe from receiving event notifications for a given channel, does not effect the subscriptions of other handlers - * Will throw an error if your handler is not subscribed to the channel, does not accept anonymous functions + * Unsubscribe from receiving event notifications for a given channel, + * does not effect the subscriptions of other handlers. + * + * @param channel - A channel previously passed to {@link subscribeToChannel} + * @param handler - A callback previously passed to {@link subscribeToChannel} + * + * @throws {Error} + * If your handler is not subscribed to the channel or does not + * accept anonymous functions */ async unsubscribeFromChannel(channel: string | number, handler: EventSubscriberCallback) { const channelCallbacks = this._channelCallbacks.get(channel); @@ -315,7 +350,9 @@ export class EventSubscriber { * Update the subscription with the controller based on current handler counts */ async _updateSubscription() { - if (!this.control || !(this.control.connector as WebSocketClientConnector).connected) return; + if (!this.control || !(this.control.connector as WebSocketClientConnector).connected) { + return; + } const entry = Link._eventsByClass.get(this.event)!; const response = await this.control.send(new SubscriptionRequest( diff --git a/packages/lib/src/users.ts b/packages/lib/src/users.ts index 5990db08..53bc91f7 100644 --- a/packages/lib/src/users.ts +++ b/packages/lib/src/users.ts @@ -6,7 +6,6 @@ * @author Hornwitser * @module lib/users */ -"use strict"; import * as libErrors from "./errors"; import PlayerStats from "./PlayerStats"; @@ -328,6 +327,7 @@ export class User { } return playerStats; } + /** * Set of users currently online in the cluster. */ diff --git a/packages/web_ui/global.d.ts b/packages/web_ui/global.d.ts index e1a04c39..2bb8472e 100644 --- a/packages/web_ui/global.d.ts +++ b/packages/web_ui/global.d.ts @@ -1,5 +1,5 @@ -declare module '*.png' { - const value: import('react-native').ImageSourcePropType; +declare module "*.png" { + const value: import("react-native").ImageSourcePropType; export default value; } diff --git a/packages/web_ui/src/components/BaseConfigTree.tsx b/packages/web_ui/src/components/BaseConfigTree.tsx index 99c8c69d..93aab9ea 100644 --- a/packages/web_ui/src/components/BaseConfigTree.tsx +++ b/packages/web_ui/src/components/BaseConfigTree.tsx @@ -103,7 +103,7 @@ export default function BaseConfigTree(props: BaseConfigTreeProps) { title="A restart is required for this setting to take effect" >; - + type ChildNode = { key: string; children: any[]; diff --git a/packages/web_ui/src/components/HostViewPage.tsx b/packages/web_ui/src/components/HostViewPage.tsx index 1d2524db..a620a9df 100644 --- a/packages/web_ui/src/components/HostViewPage.tsx +++ b/packages/web_ui/src/components/HostViewPage.tsx @@ -41,8 +41,8 @@ export default function HostViewPage() { } let hostButtons = { - account.hasPermission("core.host.revoke_access") && - { control.send(new lib.HostRevokeTokensRequest(host.id!)) .then(() => notify("Host tokens revoked")) - .catch(notifyErrorHandler(`Error revoking tokens for host id:${host.id}`)) + .catch(notifyErrorHandler(`Error revoking tokens for host id:${host.id}`)); }} > - } - + } + ; return {host["agent"]} {host["version"]} { - host.tokenValidAfter && - - {formatTimestamp(host.tokenValidAfter*1000)} + host.tokenValidAfter + && + {formatTimestamp(host.tokenValidAfter*1000)} } diff --git a/packages/web_ui/src/components/HostsPage.tsx b/packages/web_ui/src/components/HostsPage.tsx index c6123351..4816301b 100644 --- a/packages/web_ui/src/components/HostsPage.tsx +++ b/packages/web_ui/src/components/HostsPage.tsx @@ -37,7 +37,7 @@ function GenerateHostTokenButton() { }, []); async function generateToken() { - let id = undefined; + let id; let values = form.getFieldsValue(); if (values.hostId) { id = Number.parseInt(values.hostId, 10); @@ -114,12 +114,12 @@ function GenerateHostTokenButton() {

> mkdir clusterio

> cd clusterio

@@ -166,7 +166,7 @@ function CopyButton({ text, message }: { text:string, message:string }) { return result.state === "granted"; } catch (err: any) { - //If it fail because "clipboard-write" is not supported. + // If it fail because "clipboard-write" is not supported. return err.name === "TypeError"; } } @@ -229,7 +229,7 @@ export default function HostsPage() { {host.connected ? "Connected" : "Disconnected"} , sorter: (a, b) => Number(a.connected) - Number(b.connected), - } + }, ]} dataSource={hostList} rowKey={host => host.id} diff --git a/packages/web_ui/src/components/InstanceList.tsx b/packages/web_ui/src/components/InstanceList.tsx index 23e0af24..feec3335 100644 --- a/packages/web_ui/src/components/InstanceList.tsx +++ b/packages/web_ui/src/components/InstanceList.tsx @@ -99,7 +99,7 @@ export default function InstanceList(props: InstanceListProps) { responsive: ["sm"], align: "right", width: 100, - }) + }); } if (props.hideAssignedHost) { diff --git a/packages/web_ui/src/components/InstanceViewPage.tsx b/packages/web_ui/src/components/InstanceViewPage.tsx index c1ffad6c..e00fd6d4 100644 --- a/packages/web_ui/src/components/InstanceViewPage.tsx +++ b/packages/web_ui/src/components/InstanceViewPage.tsx @@ -1,7 +1,7 @@ import React, { useContext, useState } from "react"; import { useNavigate, useParams } from "react-router-dom"; import { Alert, Button, Descriptions, Dropdown, Menu, MenuProps, Modal, Space, Spin, Typography } from "antd"; -import type { ItemType } from 'antd/es/menu/hooks/useItems'; +import type { ItemType } from "antd/es/menu/hooks/useItems"; import DeleteOutlined from "@ant-design/icons/DeleteOutlined"; import DownOutlined from "@ant-design/icons/DownOutlined"; diff --git a/packages/web_ui/src/components/ModDetails.tsx b/packages/web_ui/src/components/ModDetails.tsx index 1506f15e..bb80b8e8 100644 --- a/packages/web_ui/src/components/ModDetails.tsx +++ b/packages/web_ui/src/components/ModDetails.tsx @@ -38,7 +38,7 @@ export default function ModDetails(props: ModDetailsProps) { {`https://mods.factorio.com/mod/${mod.name}`} - + { (mod instanceof lib.ModInfo) && <> {mod.contact && {mod.contact}} {mod.homepage && {mod.homepage}} diff --git a/packages/web_ui/src/components/ModPackViewPage.tsx b/packages/web_ui/src/components/ModPackViewPage.tsx index 25e8d57f..39ad5c06 100644 --- a/packages/web_ui/src/components/ModPackViewPage.tsx +++ b/packages/web_ui/src/components/ModPackViewPage.tsx @@ -70,7 +70,7 @@ function SearchModsTable(props: SearchModsTableProps) { const [modResultPage, setModResultPage] = useState(1); const [modResultPageSize, setModResultPageSize] = useState(10); const [modResultCount, setModResultCount] = useState(2); - const [modResultSelectedVersion, setModResultSelectedVersion] = useState>(new Map()); + const [modResultSelectedVersion, setModResultSelectedVersion] = useState>(new Map()); const factorioVersion = props.modPack.factorioVersion.split(".").slice(0, 2).join("."); @@ -216,7 +216,9 @@ function SearchModsTable(props: SearchModsTableProps) { title: "Action", key: "action", responsive: ["lg"], - render: (result:ModResult) => actions(result.versions[modResultSelectedVersion.get(result.name) || 0]), + render: (result:ModResult) => ( + actions(result.versions[modResultSelectedVersion.get(result.name) || 0]) + ), }, ]} expandable={{ @@ -294,11 +296,13 @@ function ModsTable(props: ModsTableProps) { >remove} {(deletedMods.has(mod.name) || changedMods.has(mod.name)) && { - props.onRevert && props.onRevert({ - type: deletedMods.has(mod.name) ? "mods.delete" : "mods.set", - name: mod.name, - value: mod, - }); + if (props.onRevert) { + props.onRevert({ + type: deletedMods.has(mod.name) ? "mods.delete" : "mods.set", + name: mod.name, + value: mod, + }); + } }} >revert} ; @@ -337,7 +341,9 @@ function ModsTable(props: ModsTableProps) { }); } } - const added = selectedRowKeys.filter(key => !props.modPack.mods.get(key as string)?.enabled) as string[]; + const added = selectedRowKeys.filter( + key => !props.modPack.mods.get(key as string)?.enabled + ) as string[]; const removed = [...props.modPack.mods.values()].filter( mod => mod.enabled && selectedRowKeys.indexOf(mod.name) === -1 ).map(mod => mod.name); diff --git a/packages/web_ui/src/components/RoleViewPage.tsx b/packages/web_ui/src/components/RoleViewPage.tsx index 3d4ae548..19137389 100644 --- a/packages/web_ui/src/components/RoleViewPage.tsx +++ b/packages/web_ui/src/components/RoleViewPage.tsx @@ -14,9 +14,9 @@ import { notifyErrorHandler } from "../util/notify"; export type RawRoleState = Partial & { - loading?: Boolean; - missing?: Boolean; - present?: Boolean; + loading?: boolean; + missing?: boolean; + present?: boolean; }; function useRole(id: number): [RawRoleState, () => void] { let control = useContext(ControlContext); diff --git a/packages/web_ui/src/components/SavesList.tsx b/packages/web_ui/src/components/SavesList.tsx index d69d1cb9..bc707dd3 100644 --- a/packages/web_ui/src/components/SavesList.tsx +++ b/packages/web_ui/src/components/SavesList.tsx @@ -17,7 +17,6 @@ import { useSaves } from "../model/saves"; import { notifyErrorHandler } from "../util/notify"; - type ModalProps = { disabled: boolean; save: lib.SaveDetails; @@ -150,7 +149,9 @@ function TransferModal(props: ModalProps) {