mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 23:14:53 +09:00
Fix bad typings left over from the migration
This commit is contained in:
1 parent
7314dc99c8
commit
80e1904175
22 files changed
+93
-117
No files matched your search
@@ -32,7 +32,7 @@ const { ConsoleTransport, levels, logger } = lib;
|
||||
|
||||
import Controller from "./src/Controller";
|
||||
import UserManager from "./src/UserManager";
|
||||
const version = require("./package.json").version;
|
||||
import { version } from "./package.json";
|
||||
|
||||
// globals
|
||||
let controller: Controller;
|
||||
|
||||
@@ -29,17 +29,13 @@ export default class ControlConnection extends BaseConnection {
|
||||
private _agent: string;
|
||||
private _version: string;
|
||||
logTransport: lib.LinkTransport | null = null;
|
||||
logSubscriptions: {
|
||||
all: boolean,
|
||||
controller: boolean,
|
||||
hostIds: number[],
|
||||
instanceIds: number[],
|
||||
} = {
|
||||
logSubscriptions = {
|
||||
all: false,
|
||||
controller: false,
|
||||
hostIds: [],
|
||||
instanceIds: [],
|
||||
hostIds: [] as number[],
|
||||
instanceIds: [] as number[],
|
||||
};
|
||||
|
||||
ws_dumper: ((...args: any[]) => void) | null = null;
|
||||
declare connector: WsServerConnector;
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import type winston from "winston";
|
||||
import type { AddressInfo } from "net";
|
||||
import type { ControllerArgs } from "../controller";
|
||||
import type { HostInfo } from "./HostConnection";
|
||||
import type { Request, Response, Application } from "express";
|
||||
|
||||
import express, { type Request, type Response, type NextFunction, type Application } from "express";
|
||||
|
||||
import compression from "compression";
|
||||
import events, { EventEmitter } from "events";
|
||||
import express from "express";
|
||||
import fs from "fs-extra";
|
||||
import http from "http";
|
||||
import https from "https";
|
||||
@@ -20,12 +17,11 @@ const { logger, Summary, Gauge } = lib;
|
||||
|
||||
import HttpCloser from "./HttpCloser";
|
||||
import InstanceInfo, { InstanceStatus } from "./InstanceInfo";
|
||||
import metrics from "./metrics";
|
||||
import * as metrics from "./metrics";
|
||||
import * as routes from "./routes";
|
||||
import UserManager from "./UserManager";
|
||||
import WsServer from "./WsServer";
|
||||
import yargs from "yargs";
|
||||
import HostConnection from "./HostConnection";
|
||||
import HostConnection, { type HostInfo } from "./HostConnection";
|
||||
|
||||
const endpointDurationSummary = new Summary(
|
||||
"clusterio_controller_http_endpoint_duration_seconds",
|
||||
@@ -176,7 +172,8 @@ export default class Controller {
|
||||
const webpackConfigs = [];
|
||||
|
||||
if (args.dev) {
|
||||
webpackConfigs.push(require("../../../webpack.config")({}));
|
||||
// eslint-disable-next-line node/no-missing-require
|
||||
webpackConfigs.push(require("../../../webpack.config")({})); // Path outside of build
|
||||
}
|
||||
if (args.devPlugin) {
|
||||
let devPlugins = new Map();
|
||||
@@ -882,8 +879,7 @@ export default class Controller {
|
||||
ControllerPluginClass = await lib.loadControllerPluginClass(pluginInfo);
|
||||
}
|
||||
|
||||
//@ts-ignore //TODO::: metrics is lib.Counter but ControllerPluginClass expect any[], can't figure out how the metrics is used.
|
||||
let controllerPlugin = new ControllerPluginClass(pluginInfo, this, metrics, logger);
|
||||
let controllerPlugin = new ControllerPluginClass(pluginInfo, this, metrics as any, logger);
|
||||
await controllerPlugin.init();
|
||||
this.plugins.set(pluginInfo.name, controllerPlugin);
|
||||
|
||||
@@ -950,8 +946,8 @@ export default class Controller {
|
||||
/**
|
||||
* Servers the web interface with the root path set apropriately
|
||||
*
|
||||
* @param {string} route - route the interface is served under.
|
||||
* @returns {function} Experess.js route handler.
|
||||
* @param route - route the interface is served under.
|
||||
* @returns Experess.js route handler.
|
||||
*/
|
||||
static serveWeb(route: string) {
|
||||
// The depth is is the number of slashes in the route minus one, but due
|
||||
@@ -959,7 +955,7 @@ export default class Controller {
|
||||
// compensate if the request path contains a slash but not the route,
|
||||
// and vice versa.
|
||||
let routeDepth = (route.match(/\//g) || []).length - 1 - Number(route.slice(-1) === "/");
|
||||
return function(req: Request, res: Response, next: Function) {
|
||||
return function(req: Request, res: Response, next: NextFunction) {
|
||||
let depth = routeDepth + Number(req.path.slice(-1) === "/");
|
||||
let webRoot = "../".repeat(depth) || "./";
|
||||
let staticRoot = webRoot;
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface HostInfo {
|
||||
id: number;
|
||||
name: string;
|
||||
version: string;
|
||||
plugins: [number, any][];
|
||||
plugins: Record<string, string>;
|
||||
public_address: string | undefined;
|
||||
token_valid_after?: number;
|
||||
}
|
||||
@@ -30,10 +30,10 @@ export default class HostConnection extends BaseConnection {
|
||||
private _id: any;
|
||||
private _name: any;
|
||||
private _version: any;
|
||||
plugins: Map<string, Object>;
|
||||
plugins: Map<string, string>;
|
||||
|
||||
constructor(
|
||||
registerData: any,
|
||||
registerData: lib.RegisterHostData,
|
||||
connector: WsServerConnector,
|
||||
controller: Controller,
|
||||
) {
|
||||
|
||||
@@ -36,7 +36,7 @@ export default class InstanceInfo {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
toJSON(): Object {
|
||||
toJSON() {
|
||||
return {
|
||||
config: this.config.serialize(),
|
||||
status: this.status,
|
||||
|
||||
@@ -12,7 +12,7 @@ import ControlConnection from "./ControlConnection";
|
||||
import HostConnection, { HostInfo } from "./HostConnection";
|
||||
import WsServerConnector from "./WsServerConnector";
|
||||
|
||||
const packageVersion = require("../package.json").version;
|
||||
import { version as packageVersion } from "../package.json";
|
||||
|
||||
const wsMessageCounter = new lib.Counter(
|
||||
"clusterio_controller_websocket_message_total",
|
||||
@@ -111,12 +111,11 @@ export default class WsServer {
|
||||
}
|
||||
});
|
||||
let originalSend = socket.send;
|
||||
socket.send = (...args: any[]) => {
|
||||
socket.send = (...args: [string, any]) => {
|
||||
wsMessageCounter.labels("out").inc();
|
||||
if (typeof args[0] === "string" && !socket.clusterio_ignore_dump) {
|
||||
this.controller.debugEvents.emit("message", { direction: "out", content: args[0] });
|
||||
}
|
||||
// @ts-ignore TODO::: Issue with originalSend having multiple signatures ?
|
||||
return originalSend.call(socket, ...args);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as lib from "@clusterio/lib";
|
||||
import util from "util";
|
||||
|
||||
const endpointHitCounter = new lib.Counter(
|
||||
export const endpointHitCounter = new lib.Counter(
|
||||
"clusterio_controller_http_endpoint_hits_total",
|
||||
"How many requests a particular HTTP endpoint has gotten",
|
||||
{ labels: ["route"], register: false }
|
||||
@@ -11,5 +11,3 @@ endpointHitCounter.labels = util.deprecate(
|
||||
endpointHitCounter.labels,
|
||||
"incrementing endpointHitCounter is no longer needed and has no effect"
|
||||
);
|
||||
|
||||
export default endpointHitCounter;
|
||||
@@ -61,7 +61,7 @@ async function getMetrics(req: Request, res: Response, next: any) {
|
||||
));
|
||||
}
|
||||
|
||||
for await (let result of await lib.defaultRegistry.collect()) {
|
||||
for await (let result of lib.defaultRegistry.collect()) {
|
||||
results.push(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ const controllerConfigCommands = new lib.CommandTree({
|
||||
|
||||
controllerConfigCommands.add(new lib.Command({
|
||||
definition: ["list", "List controller configuration"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
let response = await control.send(new lib.ControllerConfigGetRequest());
|
||||
|
||||
for (let group of (response.serializedConfig as any).groups) {
|
||||
@@ -212,13 +212,13 @@ const controllerPluginCommands = new lib.CommandTree({
|
||||
});
|
||||
controllerPluginCommands.add(new lib.Command({
|
||||
definition: ["list", "List plugins on controller"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
let url = new URL(control.config.get("control.controller_url") as string);
|
||||
url.pathname += "api/plugins";
|
||||
let response = await phin<[]>({
|
||||
url,
|
||||
parse: "json",
|
||||
core: { ca: control.tlsCa } as {},
|
||||
core: { ca: control.tlsCa } as object,
|
||||
});
|
||||
print(asTable(response.body));
|
||||
},
|
||||
@@ -229,7 +229,7 @@ controllerCommands.add(controllerPluginCommands);
|
||||
const hostCommands = new lib.CommandTree({ name: "host", description: "Host management" });
|
||||
hostCommands.add(new lib.Command({
|
||||
definition: [["list", "l"], "List hosts connected to the controller"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
let hosts = await control.send(new lib.HostListRequest());
|
||||
print(asTable(hosts));
|
||||
},
|
||||
@@ -288,7 +288,7 @@ const instanceCommands = new lib.CommandTree({
|
||||
});
|
||||
instanceCommands.add(new lib.Command({
|
||||
definition: [["list", "l"], "List instances known to the controller"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
let list = await control.send(new lib.InstanceDetailsListRequest());
|
||||
print(asTable(list));
|
||||
},
|
||||
@@ -612,7 +612,7 @@ instanceSaveCommands.add(new lib.Command({
|
||||
"X-Access-Token": control.config.get("control.controller_token"),
|
||||
"Content-Type": "application/zip",
|
||||
},
|
||||
core: { ca: control.tlsCa } as {},
|
||||
core: { ca: control.tlsCa } as object,
|
||||
data: content,
|
||||
parse: "json",
|
||||
});
|
||||
@@ -687,7 +687,7 @@ instanceSaveCommands.add(new lib.Command({
|
||||
url.pathname += `api/stream/${streamId}`;
|
||||
let response = await phin({
|
||||
url, method: "GET",
|
||||
core: { ca: control.tlsCa } as {},
|
||||
core: { ca: control.tlsCa } as object,
|
||||
stream: true,
|
||||
});
|
||||
|
||||
@@ -898,13 +898,13 @@ modPackCommands.add(new lib.Command({
|
||||
|
||||
modPackCommands.add(new lib.Command({
|
||||
definition: [["list", "l"], "List mod packs in the cluster"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
let modPacks = await control.send(new lib.ModPackListRequest());
|
||||
let fields = ["id", "name", "factorioVersion"];
|
||||
for (let entry of modPacks) {
|
||||
for (let field of Object.keys(entry)) {
|
||||
if (!fields.includes(field)) {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error terrible hack
|
||||
delete entry[field];
|
||||
}
|
||||
}
|
||||
@@ -1176,7 +1176,7 @@ modCommands.add(new lib.Command({
|
||||
for (let entry of mods) {
|
||||
for (let field of Object.keys(entry)) {
|
||||
if (!args.fields.includes(field)) {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error terrible hack
|
||||
delete entry[field];
|
||||
}
|
||||
}
|
||||
@@ -1243,7 +1243,7 @@ modCommands.add(new lib.Command({
|
||||
for (let entry of results) {
|
||||
for (let field of Object.keys(entry)) {
|
||||
if (!args.fields.includes(field)) {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error terrible hack
|
||||
delete entry[field];
|
||||
}
|
||||
}
|
||||
@@ -1281,7 +1281,7 @@ modCommands.add(new lib.Command({
|
||||
"X-Access-Token": control.config.get("control.controller_token"),
|
||||
"Content-Type": "application/zip",
|
||||
},
|
||||
core: { ca: control.tlsCa } as {},
|
||||
core: { ca: control.tlsCa } as object,
|
||||
data: content,
|
||||
parse: "json",
|
||||
});
|
||||
@@ -1317,7 +1317,7 @@ modCommands.add(new lib.Command({
|
||||
url.pathname += `api/stream/${streamId}`;
|
||||
let response = await phin({
|
||||
url, method: "GET",
|
||||
core: { ca: control.tlsCa } as {},
|
||||
core: { ca: control.tlsCa } as object,
|
||||
stream: true,
|
||||
});
|
||||
|
||||
@@ -1358,7 +1358,7 @@ modCommands.add(new lib.Command({
|
||||
const permissionCommands = new lib.CommandTree({ name: "permission", description: "Permission inspection" });
|
||||
permissionCommands.add(new lib.Command({
|
||||
definition: [["list", "l"], "List permissions in the cluster"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
let permissions = await control.send(new lib.PermissionListRequest());
|
||||
print(asTable(permissions));
|
||||
},
|
||||
@@ -1368,7 +1368,7 @@ permissionCommands.add(new lib.Command({
|
||||
const roleCommands = new lib.CommandTree({ name: "role", description: "Role management" });
|
||||
roleCommands.add(new lib.Command({
|
||||
definition: [["list", "l"], "List roles in the cluster"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
let roles = await control.send(new lib.RoleListRequest());
|
||||
print(asTable(roles));
|
||||
},
|
||||
@@ -1716,7 +1716,7 @@ logCommands.add(new lib.Command({
|
||||
const debugCommands = new lib.CommandTree({ name: "debug", description: "Debugging utilities" });
|
||||
debugCommands.add(new lib.Command({
|
||||
definition: ["dump-ws", "Dump WebSocket messages sent and received by controller"],
|
||||
handler: async function(args: {}, control: Control) {
|
||||
handler: async function(args: object, control: Control) {
|
||||
await control.send(new lib.DebugDumpWsRequest());
|
||||
control.keepOpen = true;
|
||||
},
|
||||
|
||||
@@ -688,7 +688,7 @@ export default class Host extends lib.Link {
|
||||
url.pathname += `api/stream/${streamId}`;
|
||||
let response = await phin({
|
||||
url, method: "GET",
|
||||
core: { ca: this.tlsCa } as {},
|
||||
core: { ca: this.tlsCa } as object,
|
||||
stream: true,
|
||||
});
|
||||
|
||||
@@ -743,7 +743,7 @@ export default class Host extends lib.Link {
|
||||
url.pathname += `api/stream/${streamId}`;
|
||||
phin({
|
||||
url, method: "PUT",
|
||||
core: { ca: this.tlsCa } as {},
|
||||
core: { ca: this.tlsCa } as object,
|
||||
data: content,
|
||||
}).catch(err => {
|
||||
logger.error(`Error pushing save to controller:\n${err.stack}`, this.instanceLogMeta(instanceId));
|
||||
|
||||
@@ -1067,7 +1067,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
let response = await phin({
|
||||
url, method: "PUT",
|
||||
data: content,
|
||||
core: { ca: this._host.tlsCa } as {},
|
||||
core: { ca: this._host.tlsCa } as object,
|
||||
headers: {
|
||||
"Content-Type": "application/zip",
|
||||
"x-access-token": this._host.config.get("host.controller_token"),
|
||||
|
||||
@@ -692,9 +692,9 @@ export class FactorioServer extends events.EventEmitter {
|
||||
this._maxConcurrentCommands = value;
|
||||
this.setMaxListeners(value + 5);
|
||||
if (this._rconClient) {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error sendQueue is private
|
||||
if (this._rconClient.sendQueue) {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error sendQueue is private
|
||||
this._rconClient.sendQueue.maxConcurrent = value;
|
||||
}
|
||||
// XXX: Workaround to suppress bogus event listener warning
|
||||
|
||||
@@ -27,7 +27,7 @@ export default class RateLimiter {
|
||||
/**
|
||||
* Callback invoked at most `maxRate` per second on activation.
|
||||
*/
|
||||
action?: Function;
|
||||
action?: () => void;
|
||||
|
||||
private _lastRun = 0;
|
||||
private _runTimeout?: ReturnType<typeof setTimeout>;
|
||||
@@ -43,7 +43,7 @@ export default class RateLimiter {
|
||||
* @param options.action -
|
||||
* Callback invoked at maste `maxRate` per second on activation.
|
||||
*/
|
||||
constructor(options: { maxRate?: number, action?: Function } = {}) {
|
||||
constructor(options: { maxRate?: number, action?: () => void } = {}) {
|
||||
this.maxRate = options.maxRate || 1;
|
||||
this.action = options.action || undefined;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export async function timeout<T>(promise: Promise<T>, time: number, timeoutResul
|
||||
try {
|
||||
return await Promise.race([
|
||||
promise,
|
||||
new Promise(resolve => {
|
||||
new Promise<T>(resolve => {
|
||||
timer = setTimeout(() => resolve(timeoutResult), time);
|
||||
}),
|
||||
]);
|
||||
|
||||
@@ -101,10 +101,6 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
_lastReceivedSeq = undefined;
|
||||
_sendBuffer: (libData.MessageRoutable)[] = [];
|
||||
|
||||
constructor(src: libData.Address, dst: libData.Address) {
|
||||
super(src, dst);
|
||||
}
|
||||
|
||||
_reset() {
|
||||
this._state = "closed";
|
||||
this._closing = false;
|
||||
|
||||
@@ -44,7 +44,7 @@ export class ConsoleTransport extends Transport {
|
||||
this.filter = options.filter || (() => true);
|
||||
}
|
||||
|
||||
log(info: any, callback: Function) {
|
||||
log(info: any, callback: () => void) {
|
||||
if (!this.filter(info)) {
|
||||
return callback();
|
||||
}
|
||||
@@ -70,7 +70,7 @@ export class WebConsoleFormat {
|
||||
public options = {}
|
||||
) { }
|
||||
|
||||
transform(info: any, _options: {}) {
|
||||
transform(info: any, _options: object) {
|
||||
let src = " ";
|
||||
if (info.host_id !== undefined) {
|
||||
src += `s:${info.host_name} - `;
|
||||
@@ -174,5 +174,5 @@ export type Logger = Omit<winston.Logger,
|
||||
info: winston.LeveledLogMethod,
|
||||
server: winston.LeveledLogMethod,
|
||||
verbose: winston.LeveledLogMethod,
|
||||
child(options: Object): Logger,
|
||||
child(options: object): Logger,
|
||||
};
|
||||
@@ -201,7 +201,7 @@ export class LinkTransport extends Transport {
|
||||
this.filter = options.filter;
|
||||
}
|
||||
|
||||
log(info: any, callback: Function) {
|
||||
log(info: any, callback: () => void) {
|
||||
if (this.filter && !this.filter(info)) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
@@ -4,15 +4,12 @@
|
||||
*/
|
||||
import * as libHelpers from "./helpers";
|
||||
import type { Logger } from "./logging";
|
||||
import type { ConfigGroup } from "./config";
|
||||
import type { ConfigGroup, PluginConfigGroup } from "./config";
|
||||
import type { CollectorResult } from "./prometheus";
|
||||
import type { ParsedFactorioOutput } from "./logging_utils";
|
||||
import type { ModPack, ModInfo } from "./data";
|
||||
import type { Link } from "./link";
|
||||
import type { CommandTree } from "./command";
|
||||
import type { User } from "./users";
|
||||
import type { MessageRequest, MessageEvent } from "./data";
|
||||
import type { PluginConfigGroup } from "./config";
|
||||
|
||||
/**
|
||||
* Conceptual base for controller and instance plugins.
|
||||
@@ -365,7 +362,7 @@ export class BaseControllerPlugin {
|
||||
constructor(
|
||||
public info: PluginNodeEnvInfo,
|
||||
public controller: Controller,
|
||||
public metrics: any[],
|
||||
public metrics: any,
|
||||
logger: Logger
|
||||
) {
|
||||
this.logger = logger.child({ plugin: this.info.name }) as unknown as Logger;
|
||||
|
||||
@@ -61,8 +61,7 @@ function GenerateHostTokenButton() {
|
||||
}, [open]);
|
||||
|
||||
// Only install plugins that aren't filesystem paths. Npm modules have max 1 forward slash in their name.
|
||||
//@ts-ignore TODO::: this doesn't filter anything, `x.split("/") <= 1` is always = true. repair or shouldn't filter ?
|
||||
const pluginString = pluginList.map(p => `"${p.requirePath}"`).filter(x => x.split("/") <= 1).join(" ");
|
||||
const pluginString = pluginList.map(p => `"${p.requirePath}"`).filter(x => x.split("/").length <= 1).join(" ");
|
||||
return <>
|
||||
<Button
|
||||
onClick={() => { setOpen(true); }}
|
||||
@@ -141,12 +140,11 @@ npm init "@clusterio" -- --controller-token ${token} --mode "host" --download-he
|
||||
}
|
||||
|
||||
function CopyButton({ text, message }: { text:string, message:string }) {
|
||||
let [clipboardPermision, setClipboardPermission] = useState("granted");
|
||||
let [clipboardPermision, setClipboardPermission] = useState<PermissionState>("granted");
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
//@ts-ignore https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write
|
||||
// @ts-expect-error missing API https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write
|
||||
let result = await navigator.permissions.query({ name: "clipboard-write" });
|
||||
// result.state is "granted", "denied" or "prompt"
|
||||
setClipboardPermission(result.state);
|
||||
result.onchange = function () {
|
||||
setClipboardPermission(result.state);
|
||||
@@ -156,9 +154,8 @@ function CopyButton({ text, message }: { text:string, message:string }) {
|
||||
|
||||
async function checkClipboardPermission() {
|
||||
try {
|
||||
//@ts-ignore https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write
|
||||
// @ts-expect-error missing API https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/write
|
||||
let result = await navigator.permissions.query({ name: "clipboard-write" });
|
||||
// result.state is "granted", "denied" or "prompt"
|
||||
setClipboardPermission(result.state);
|
||||
result.onchange = function () {
|
||||
setClipboardPermission(result.state);
|
||||
|
||||
@@ -6,16 +6,19 @@ import * as lib from "@clusterio/lib";
|
||||
|
||||
const { useBreakpoint } = Grid;
|
||||
|
||||
type ModDetailsProps = {
|
||||
mod: lib.ModInfo|lib.ModRecord;
|
||||
actions: (mod: lib.ModInfo|lib.ModRecord) => React.JSX.Element;
|
||||
type ModDetailsProps<T> = {
|
||||
mod: T;
|
||||
actions: (mod: T) => React.JSX.Element;
|
||||
};
|
||||
export default function ModDetails(props: ModDetailsProps) {
|
||||
export default function ModDetails<T extends lib.ModInfo | lib.ModRecord>(props: ModDetailsProps<T>) {
|
||||
let screens = useBreakpoint();
|
||||
const mod = props.mod;
|
||||
const mod: Partial<lib.ModInfo> & Partial<lib.ModRecord> = props.mod;
|
||||
|
||||
return <Descriptions className="borderless" bordered size="small" column={{ xs: 1, sm: 1, md: 1, lg: 2 }}>
|
||||
{!(mod instanceof lib.ModInfo) && mod.error && <Descriptions.Item label={<><ExclamationCircleOutlined/> Error</>} span={2}>
|
||||
{mod.error && <Descriptions.Item
|
||||
label={<><ExclamationCircleOutlined/> Error</>}
|
||||
span={2}
|
||||
>
|
||||
{mod.error === "missing" && "The given version of this mod is missing from the controller storage."}
|
||||
{mod.error === "bad_checksum"
|
||||
&& "Checksum of the mod in the controller storage does not match the checksum provided " +
|
||||
@@ -23,15 +26,13 @@ export default function ModDetails(props: ModDetailsProps) {
|
||||
}
|
||||
</Descriptions.Item>}
|
||||
{props.actions && !screens.lg
|
||||
&& <Descriptions.Item label="Action">{props.actions(mod)}</Descriptions.Item>
|
||||
&& <Descriptions.Item label="Action">{props.actions(props.mod)}</Descriptions.Item>
|
||||
}
|
||||
|
||||
{ (mod instanceof lib.ModInfo) && <>
|
||||
{mod.title && <Descriptions.Item label="Title">{mod.title}</Descriptions.Item>}
|
||||
{mod.version && <Descriptions.Item label="Version" span={mod.title ? 1 : 2}>{mod.version}</Descriptions.Item>}
|
||||
{mod.description && <Descriptions.Item label="Description" span={2}>{mod.description}</Descriptions.Item> }
|
||||
{mod.author && <Descriptions.Item label="Author" span={2}>{mod.author}</Descriptions.Item>}
|
||||
</>}
|
||||
{mod.title && <Descriptions.Item label="Title">{mod.title}</Descriptions.Item>}
|
||||
{mod.version && <Descriptions.Item label="Version" span={mod.title ? 1 : 2}>{mod.version}</Descriptions.Item>}
|
||||
{mod.description && <Descriptions.Item label="Description" span={2}>{mod.description}</Descriptions.Item> }
|
||||
{mod.author && <Descriptions.Item label="Author" span={2}>{mod.author}</Descriptions.Item>}
|
||||
|
||||
<Descriptions.Item label="Mod Portal" span={2}>
|
||||
<Typography.Link href={`https://mods.factorio.com/mod/${mod.name}`}>
|
||||
@@ -39,26 +40,24 @@ export default function ModDetails(props: ModDetailsProps) {
|
||||
</Typography.Link>
|
||||
</Descriptions.Item>
|
||||
|
||||
{ (mod instanceof lib.ModInfo) && <>
|
||||
{mod.contact && <Descriptions.Item label="Contact" span={2}>{mod.contact}</Descriptions.Item>}
|
||||
{mod.homepage && <Descriptions.Item label="Homepage" span={2}>{mod.homepage}</Descriptions.Item>}
|
||||
<Descriptions.Item label="Internal Name" span={mod.factorioVersion ? 1 : 2}>{mod.name}</Descriptions.Item>
|
||||
{mod.factorioVersion
|
||||
&& <Descriptions.Item label="Factorio Version">{mod.factorioVersion}</Descriptions.Item>
|
||||
}
|
||||
{mod.filename && <Descriptions.Item label="Filename">{mod.filename}</Descriptions.Item>}
|
||||
{mod.size !== undefined
|
||||
&& <Descriptions.Item label="Size">{lib.formatBytes(mod.size)}</Descriptions.Item>
|
||||
}
|
||||
{mod.sha1 && <Descriptions.Item label="SHA1" span={2}>{mod.sha1}</Descriptions.Item>}
|
||||
{mod.dependencies && mod.dependencies.length
|
||||
&& <Descriptions.Item label="Dependencies" span={2}>
|
||||
{mod.dependencies
|
||||
.filter(e => !e.startsWith("(?)"))
|
||||
.map((e, i) => <Fragment key={i}>{e}<br/></Fragment>)
|
||||
}
|
||||
</Descriptions.Item>
|
||||
}
|
||||
</>}
|
||||
{mod.contact && <Descriptions.Item label="Contact" span={2}>{mod.contact}</Descriptions.Item>}
|
||||
{mod.homepage && <Descriptions.Item label="Homepage" span={2}>{mod.homepage}</Descriptions.Item>}
|
||||
<Descriptions.Item label="Internal Name" span={mod.factorioVersion ? 1 : 2}>{mod.name}</Descriptions.Item>
|
||||
{mod.factorioVersion
|
||||
&& <Descriptions.Item label="Factorio Version">{mod.factorioVersion}</Descriptions.Item>
|
||||
}
|
||||
{mod.filename && <Descriptions.Item label="Filename">{mod.filename}</Descriptions.Item>}
|
||||
{mod.size !== undefined
|
||||
&& <Descriptions.Item label="Size">{lib.formatBytes(mod.size)}</Descriptions.Item>
|
||||
}
|
||||
{mod.sha1 && <Descriptions.Item label="SHA1" span={2}>{mod.sha1}</Descriptions.Item>}
|
||||
{mod.dependencies && mod.dependencies.length
|
||||
&& <Descriptions.Item label="Dependencies" span={2}>
|
||||
{mod.dependencies
|
||||
.filter(e => !e.startsWith("(?)"))
|
||||
.map((e, i) => <Fragment key={i}>{e}<br/></Fragment>)
|
||||
}
|
||||
</Descriptions.Item>
|
||||
}
|
||||
</Descriptions>;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ export class Control extends lib.Link {
|
||||
accountRoles: lib.AccountRole[] | null = null;
|
||||
|
||||
/** Updates not handled by the subscription service */
|
||||
accountUpdateHandlers: Function[] = [];
|
||||
accountUpdateHandlers: accountHandler[] = [];
|
||||
logHandlers: Map<lib.LogFilter, logHandler[]> = new Map();
|
||||
|
||||
/** Updates handled by the subscription service */
|
||||
@@ -146,8 +146,8 @@ export class Control extends lib.Link {
|
||||
emitAccountUpdate() {
|
||||
for (let handler of this.accountUpdateHandlers) {
|
||||
handler({
|
||||
name: this.accountName,
|
||||
roles: this.accountRoles,
|
||||
name: this.accountName!,
|
||||
roles: this.accountRoles!,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import type { Request, Response } from "express";
|
||||
|
||||
import crypto from "crypto";
|
||||
import express from "express";
|
||||
import express, { type Request, type Response } from "express";
|
||||
import util from "util";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
|
||||
Reference in new issue
Block a user