mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 07:04:53 +09:00
Use strict type checking
This commit is contained in:
1 parent
2ca8e69025
commit
a66e930997
36 files changed
+714
-676
No files matched your search
@@ -38,6 +38,7 @@
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/node": "^20.4.5",
|
||||
"@types/triple-beam": "^1.3.2",
|
||||
"@types/ws": "^8.5.5",
|
||||
"typescript": "^5.1.6"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { Type, Static } from "@sinclair/typebox";
|
||||
|
||||
/**
|
||||
* Stastics collected about a player.
|
||||
*/
|
||||
@@ -27,18 +29,15 @@ export default class PlayerStats {
|
||||
*/
|
||||
lastLeaveReason?: string;
|
||||
|
||||
static jsonSchema = {
|
||||
type: "object",
|
||||
properties: {
|
||||
"join_count": { type: "integer" },
|
||||
"online_time_ms": { type: "number" },
|
||||
"last_join_at": { type: "number" },
|
||||
"last_leave_at": { type: "number" },
|
||||
"last_leave_reason": { type: "string" },
|
||||
},
|
||||
};
|
||||
static jsonSchema = Type.Object({
|
||||
"join_count": Type.Optional(Type.Integer()),
|
||||
"online_time_ms": Type.Optional(Type.Number()),
|
||||
"last_join_at": Type.Optional(Type.Number()),
|
||||
"last_leave_at": Type.Optional(Type.Number()),
|
||||
"last_leave_reason": Type.Optional(Type.String()),
|
||||
});
|
||||
|
||||
constructor(json = {}) {
|
||||
constructor(json: Static<typeof PlayerStats.jsonSchema> = {}) {
|
||||
if (json["join_count"]) {
|
||||
this.joinCount = json["join_count"];
|
||||
}
|
||||
@@ -54,12 +53,12 @@ export default class PlayerStats {
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON(json: any) {
|
||||
static fromJSON(json: Static<typeof PlayerStats.jsonSchema>) {
|
||||
return new this(json);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
let json = {};
|
||||
let json: Static<typeof PlayerStats.jsonSchema> = {};
|
||||
if (this.joinCount) {
|
||||
json["join_count"] = this.joinCount;
|
||||
}
|
||||
|
||||
@@ -27,11 +27,10 @@ export default class RateLimiter {
|
||||
/**
|
||||
* Callback invoked at most `maxRate` per second on activation.
|
||||
*/
|
||||
action: Function | null;
|
||||
action?: Function;
|
||||
|
||||
private _lastRun = 0;
|
||||
private _runTimeout = null;
|
||||
private lastProgressBroadcast = Date.now();
|
||||
private _runTimeout?: NodeJS.Timeout;
|
||||
|
||||
/**
|
||||
* Construct RateLimiter helper
|
||||
@@ -46,7 +45,7 @@ export default class RateLimiter {
|
||||
*/
|
||||
constructor(options: { maxRate?: number, action?: Function } = {}) {
|
||||
this.maxRate = options.maxRate || 1;
|
||||
this.action = options.action || null;
|
||||
this.action = options.action || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,11 +61,13 @@ export default class RateLimiter {
|
||||
activate() {
|
||||
let now = Date.now();
|
||||
if (now < this._lastRun + 1000 / this.maxRate) {
|
||||
if (!this._runTimeout && this.action !== null) {
|
||||
if (!this._runTimeout && this.action) {
|
||||
this._runTimeout = setTimeout(() => {
|
||||
this._runTimeout = null;
|
||||
this._runTimeout = undefined;
|
||||
this._lastRun = Date.now();
|
||||
this.action();
|
||||
if (this.action) {
|
||||
this.action();
|
||||
}
|
||||
}, this._lastRun + 1000 / this.maxRate - now);
|
||||
}
|
||||
return false;
|
||||
@@ -75,11 +76,11 @@ export default class RateLimiter {
|
||||
// We may end up activating before the timeout does.
|
||||
if (this._runTimeout) {
|
||||
clearTimeout(this._runTimeout);
|
||||
this._runTimeout = null;
|
||||
this._runTimeout = undefined;
|
||||
}
|
||||
|
||||
this._lastRun = now;
|
||||
if (this.action !== null) {
|
||||
if (this.action) {
|
||||
this.action();
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -157,12 +157,11 @@ export class CommandTree {
|
||||
* @returns host ID.
|
||||
*/
|
||||
export async function resolveHost(client: Link, hostName: string) {
|
||||
let hostId: number;
|
||||
let hostId: number | undefined;
|
||||
if (/^-?\d+$/.test(hostName)) {
|
||||
hostId = parseInt(hostName, 10);
|
||||
} else {
|
||||
let hosts = await client.sendTo("controller", new libData.HostListRequest());
|
||||
// @ts-ignore: TODO Remove when lib/data is migrated to ts
|
||||
for (let host of hosts) {
|
||||
if (host.name === hostName) {
|
||||
hostId = host.id;
|
||||
@@ -189,12 +188,11 @@ export async function resolveHost(client: Link, hostName: string) {
|
||||
* @returns instance ID.
|
||||
*/
|
||||
export async function resolveInstance(client: Link, instanceName: string) {
|
||||
let instanceId: number;
|
||||
let instanceId: number | undefined;
|
||||
if (/^-?\d+$/.test(instanceName)) {
|
||||
instanceId = parseInt(instanceName, 10);
|
||||
} else {
|
||||
let instances = await client.sendTo("controller", new libData.InstanceDetailsListRequest());
|
||||
// @ts-ignore: TODO Remove when lib/data is migrated to ts
|
||||
for (let instance of instances) {
|
||||
if (instance.name === instanceName) {
|
||||
instanceId = instance.id;
|
||||
@@ -222,12 +220,11 @@ export async function resolveInstance(client: Link, instanceName: string) {
|
||||
* @returns mod pack ID.
|
||||
*/
|
||||
export async function resolveModPack(client: Link, modPackName: string) {
|
||||
let modPackId: number;
|
||||
let modPackId: number | undefined;
|
||||
if (/^-?\d+/.test(modPackName)) {
|
||||
modPackId = parseInt(modPackName, 10);
|
||||
} else {
|
||||
let modPacks = await client.sendTo("controller", new libData.ModPackListRequest());
|
||||
// @ts-ignore: TODO Remove when lib/data is migrated to ts
|
||||
for (let modPack of modPacks) {
|
||||
if (modPack.name === modPackName) {
|
||||
modPackId = modPack.id;
|
||||
@@ -256,10 +253,9 @@ export async function resolveModPack(client: Link, modPackName: string) {
|
||||
export async function retrieveRole(client: Link, roleName: string) {
|
||||
let roles = await client.sendTo("controller", new libData.RoleListRequest());
|
||||
|
||||
let resolvedRole: libData.RawRole;
|
||||
let resolvedRole: libData.RawRole | undefined;
|
||||
if (/^-?\d+$/.test(roleName)) {
|
||||
let roleId = parseInt(roleName, 10);
|
||||
// @ts-ignore: TODO Remove when lib/data is migrated to ts
|
||||
for (let role of roles) {
|
||||
if (role.id === roleId) {
|
||||
resolvedRole = role;
|
||||
@@ -268,7 +264,6 @@ export async function retrieveRole(client: Link, roleName: string) {
|
||||
}
|
||||
|
||||
} else {
|
||||
// @ts-ignore: TODO Remove when lib/data is migrated to ts
|
||||
for (let role of roles) {
|
||||
if (role.name === roleName) {
|
||||
resolvedRole = role;
|
||||
|
||||
@@ -521,7 +521,7 @@ export class ConfigGroup {
|
||||
} else if (def.type === "object") {
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
throw new InvalidValue(`Error parsing value for ${name}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
@@ -567,7 +567,7 @@ export class ConfigGroup {
|
||||
throw new InvalidValue(`Cannot set property on non-object field '${name}'`);
|
||||
}
|
||||
|
||||
let prev = this._fields.get(name) as object;
|
||||
let prev = this._fields.get(name) as Record<string, unknown>;
|
||||
let updated = {...prev || {}};
|
||||
|
||||
if (value !== undefined) {
|
||||
@@ -648,9 +648,9 @@ export class ConfigGroup {
|
||||
* @returns JSON serializable representation of the group.
|
||||
*/
|
||||
serialize(location: ConfigLocation = this.config.location) {
|
||||
let fields = {};
|
||||
let fields: Record<string, unknown> = {};
|
||||
for (let [name, value] of this._fields) {
|
||||
let def = (this.constructor as typeof ConfigGroup)._definitions.get(name);
|
||||
let def = (this.constructor as typeof ConfigGroup)._definitions.get(name)!;
|
||||
if (!this._checkAccess(def, location, false)) {
|
||||
continue;
|
||||
}
|
||||
@@ -753,76 +753,77 @@ export class ConfigGroup {
|
||||
});
|
||||
|
||||
// Validate properties
|
||||
let validTypes = ["boolean", "string", "number", "object"];
|
||||
// eslint-disable-next-line complexity
|
||||
Object.keys(item).forEach(key => {
|
||||
let value = item[key];
|
||||
let valueType = basicType(value);
|
||||
switch (key) {
|
||||
case "type":
|
||||
if (!validTypes.includes(value)) {
|
||||
throw new Error(`${value} is not a valid type`);
|
||||
}
|
||||
break;
|
||||
{
|
||||
const {
|
||||
type, access, enum: enum_, name, title, description, restartRequired,
|
||||
restartRequiredProps, optional, initial_value, ...rest
|
||||
} = item;
|
||||
|
||||
case "access":
|
||||
if (valueType !== "array") {
|
||||
throw new Error("access must be an array");
|
||||
}
|
||||
break;
|
||||
|
||||
case "enum":
|
||||
if (valueType !== "array") {
|
||||
throw new Error("enum must be an array");
|
||||
}
|
||||
break;
|
||||
|
||||
case "name":
|
||||
if (valueType !== "string") {
|
||||
throw new Error("name must be a string");
|
||||
}
|
||||
break;
|
||||
|
||||
case "title":
|
||||
if (valueType !== "string") {
|
||||
throw new Error("title must be a string");
|
||||
}
|
||||
break;
|
||||
|
||||
case "description":
|
||||
if (valueType !== "string") {
|
||||
throw new Error("description must be a string");
|
||||
}
|
||||
break;
|
||||
|
||||
case "restartRequired":
|
||||
if (valueType !== "boolean") {
|
||||
throw new Error("restartRequired must be a boolean");
|
||||
}
|
||||
break;
|
||||
|
||||
case "restartRequiredProps":
|
||||
if (valueType !== "array") {
|
||||
throw new Error("restartRequiredProps must be a array");
|
||||
}
|
||||
break;
|
||||
|
||||
case "optional":
|
||||
if (valueType !== "boolean") {
|
||||
throw new Error("optional must be a boolean");
|
||||
}
|
||||
break;
|
||||
|
||||
case "initial_value":
|
||||
if (valueType !== item.type && valueType !== "function") {
|
||||
throw new Error("initial_value must match the type or be a function");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown property ${key}`);
|
||||
let validTypes = ["boolean", "string", "number", "object"];
|
||||
if (type !== undefined) {
|
||||
if (!validTypes.includes(type)) {
|
||||
throw new Error(`${type} is not a valid type`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (access !== undefined) {
|
||||
if (basicType(access) !== "array") {
|
||||
throw new Error("access must be an array");
|
||||
}
|
||||
}
|
||||
|
||||
if (enum_ !== undefined) {
|
||||
if (basicType(enum_) !== "array") {
|
||||
throw new Error("enum must be an array");
|
||||
}
|
||||
}
|
||||
|
||||
if (name !== undefined) {
|
||||
if (typeof name !== "string") {
|
||||
throw new Error("name must be a string");
|
||||
}
|
||||
}
|
||||
|
||||
if (title !== undefined) {
|
||||
if (typeof title !== "string") {
|
||||
throw new Error("title must be a string");
|
||||
}
|
||||
}
|
||||
|
||||
if (description !== undefined) {
|
||||
if (typeof description !== "string") {
|
||||
throw new Error("description must be a string");
|
||||
}
|
||||
}
|
||||
|
||||
if (restartRequired !== undefined) {
|
||||
if (typeof restartRequired !== "boolean") {
|
||||
throw new Error("restartRequired must be a boolean");
|
||||
}
|
||||
}
|
||||
|
||||
if (restartRequiredProps !== undefined) {
|
||||
if (basicType(restartRequiredProps) !== "array") {
|
||||
throw new Error("restartRequiredProps must be a array");
|
||||
}
|
||||
}
|
||||
|
||||
if (optional !== undefined) {
|
||||
if (typeof optional !== "boolean") {
|
||||
throw new Error("optional must be a boolean");
|
||||
}
|
||||
}
|
||||
|
||||
if (initial_value !== undefined) {
|
||||
if (basicType(initial_value) !== item.type && basicType(initial_value) !== "function") {
|
||||
throw new Error("initial_value must match the type or be a function");
|
||||
}
|
||||
}
|
||||
|
||||
for (let key of Object.keys(rest)) {
|
||||
throw new Error(`Unknown property ${key}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._definitions.has(item.name)) {
|
||||
throw new Error(`Config field ${item.name} has already been defined`);
|
||||
|
||||
@@ -101,7 +101,7 @@ export default class ModInfo {
|
||||
/**
|
||||
* SHA1 hash of this mod
|
||||
*/
|
||||
sha1: string;
|
||||
sha1?: string;
|
||||
|
||||
/**
|
||||
* True if this mod has been deleted
|
||||
@@ -174,13 +174,13 @@ export default class ModInfo {
|
||||
return json;
|
||||
}
|
||||
|
||||
static async fromModFile(modPath) {
|
||||
static async fromModFile(modPath: string) {
|
||||
let modInfo: Static<typeof ModInfo.jsonSchema>;
|
||||
{
|
||||
// XXX: JSZip needs the whole archive loaded in memory to work.
|
||||
// This is clearly untenable and will be replaced later.
|
||||
let zip = await JSZip.loadAsync(await fs.readFile(modPath));
|
||||
let root = zip.folder(findRoot(zip));
|
||||
let root = zip.folder(findRoot(zip))!;
|
||||
|
||||
let infoFile = root.file("info.json");
|
||||
if (!infoFile) {
|
||||
|
||||
@@ -57,7 +57,7 @@ export default class ModPack {
|
||||
/**
|
||||
* Id of this mod pack
|
||||
*/
|
||||
id: number;
|
||||
id?: number;
|
||||
|
||||
/**
|
||||
* Name of this mod pack.
|
||||
@@ -197,7 +197,7 @@ export default class ModPack {
|
||||
try {
|
||||
// eslint-disable-next-line node/no-sync
|
||||
buf = zlib.inflateSync(buf);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code.startsWith("Z_")) {
|
||||
throw new Error("Malformed mod pack string: zlib inflate failed");
|
||||
}
|
||||
@@ -206,7 +206,7 @@ export default class ModPack {
|
||||
let json: unknown;
|
||||
try {
|
||||
json = JSON.parse(buf.toString());
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
throw new Error(`Malformed mod pack string: ${err.message}`);
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ export default class ModPack {
|
||||
buf,
|
||||
]);
|
||||
}
|
||||
function immutableStringBytes(str: string) {
|
||||
function immutableStringBytes(str?: string) {
|
||||
if (str === undefined) {
|
||||
return uint8Byte(1); // empty
|
||||
}
|
||||
@@ -265,7 +265,7 @@ export default class ModPack {
|
||||
Buffer.alloc(1), // reserved byte
|
||||
]);
|
||||
}
|
||||
function propertyTreeListBytes(entries: [string, PropertyType][]) {
|
||||
function propertyTreeListBytes(entries: [string | undefined, PropertyType][]) {
|
||||
const sizeBytes = uint32Bytes(entries.length);
|
||||
const itemBytes = entries.flatMap(([key, item]) => [
|
||||
immutableStringBytes(key),
|
||||
@@ -295,7 +295,7 @@ export default class ModPack {
|
||||
} else if (element instanceof Array) {
|
||||
type = 4;
|
||||
dataBytes = propertyTreeListBytes(element.map(item => [undefined, item]));
|
||||
} else if (typeof element === "object") {
|
||||
} else if (typeof element === "object" && element !== null) {
|
||||
type = 5;
|
||||
dataBytes = propertyTreeListBytes(Object.entries(element));
|
||||
} else {
|
||||
@@ -332,19 +332,20 @@ export default class ModPack {
|
||||
;
|
||||
|
||||
for (let prototype of prototypes) {
|
||||
if (!["startup", "runtime-global", "runtime-per-user"].includes(prototype.setting_type)) {
|
||||
logger.warn(`Ignoring ${prototype.name} with unknown setting_type ${prototype.setting_type}`);
|
||||
const settingType = prototype.setting_type as keyof typeof this.settings;
|
||||
if (!["startup", "runtime-global", "runtime-per-user"].includes(settingType)) {
|
||||
logger.warn(`Ignoring ${prototype.name} with unknown setting_type ${settingType}`);
|
||||
continue;
|
||||
}
|
||||
if (prototype.default_value === undefined) {
|
||||
logger.warn(`Ignoring ${prototype.name} with missing default_value`);
|
||||
continue;
|
||||
}
|
||||
if (this.settings[prototype.setting_type].get(prototype.name)) {
|
||||
if (this.settings[settingType].get(prototype.name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this.settings[prototype.setting_type].set(prototype.name, { value: prototype.default_value });
|
||||
this.settings[settingType].set(prototype.name, { value: prototype.default_value });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,32 +14,3 @@ export * from "./messages_instance";
|
||||
export * from "./messages_mod";
|
||||
export * from "./messages_user";
|
||||
export * from "./version";
|
||||
|
||||
// TODO: Remove/migrate after lib/data is migrated to ts
|
||||
import type { User } from "../users";
|
||||
export interface Serialisable {
|
||||
jsonSchema: object,
|
||||
fromJSON(json: any): object,
|
||||
}
|
||||
import { AddressType } from "./messages_core";
|
||||
|
||||
export class Request {
|
||||
static type: "request";
|
||||
static src: AddressType | AddressType[];
|
||||
static dst: AddressType | AddressType[];
|
||||
static permission: null | "string" | ((user: User, message: Request) => void);
|
||||
static plugin?: string;
|
||||
static jsonSchema?: object;
|
||||
static fromJSON?: (json: any) => Request;
|
||||
static Response?: Serialisable;
|
||||
}
|
||||
|
||||
export class Event {
|
||||
static type: "event";
|
||||
static src: AddressType | AddressType[];
|
||||
static dst: AddressType | AddressType[];
|
||||
static permission: null | "string" | ((user: User, message: Event) => void);
|
||||
static plugin?: string;
|
||||
static jsonSchema?: object;
|
||||
static fromJSON?: (json: any) => Event;
|
||||
}
|
||||
@@ -19,19 +19,19 @@ export class RawConfig {
|
||||
|
||||
export class ControllerConfigGetRequest {
|
||||
declare ["constructor"]: typeof ControllerConfigGetRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.controller.get_config";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.controller.get_config" as const;
|
||||
static Response = RawConfig;
|
||||
}
|
||||
|
||||
export class ControllerConfigSetFieldRequest {
|
||||
declare ["constructor"]: typeof ControllerConfigSetFieldRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.controller.update_config";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.controller.update_config" as const;
|
||||
|
||||
constructor(
|
||||
public field: string,
|
||||
@@ -50,10 +50,10 @@ export class ControllerConfigSetFieldRequest {
|
||||
|
||||
export class ControllerConfigSetPropRequest {
|
||||
declare ["constructor"]: typeof ControllerConfigSetPropRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.controller.update_config";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.controller.update_config" as const;
|
||||
|
||||
constructor(
|
||||
public field: string,
|
||||
@@ -74,10 +74,10 @@ export class ControllerConfigSetPropRequest {
|
||||
|
||||
export class HostGenerateTokenRequest {
|
||||
declare ["constructor"]: typeof HostGenerateTokenRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.host.generate_token";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.host.generate_token" as const;
|
||||
|
||||
constructor(
|
||||
public hostId?: number,
|
||||
@@ -96,10 +96,10 @@ export class HostGenerateTokenRequest {
|
||||
|
||||
export class HostConfigCreateRequest {
|
||||
declare ["constructor"]: typeof HostConfigCreateRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.host.create_config";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.host.create_config" as const;
|
||||
|
||||
constructor(
|
||||
public id: number | undefined,
|
||||
@@ -122,10 +122,10 @@ export class HostConfigCreateRequest {
|
||||
|
||||
export class LogSetSubscriptionsRequest {
|
||||
declare ["constructor"]: typeof LogSetSubscriptionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.log.follow";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.log.follow" as const;
|
||||
|
||||
constructor(
|
||||
public all?: boolean,
|
||||
@@ -150,10 +150,10 @@ export class LogSetSubscriptionsRequest {
|
||||
|
||||
export class LogQueryRequest {
|
||||
declare ["constructor"]: typeof LogQueryRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.log.query";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.log.query" as const;
|
||||
|
||||
constructor(
|
||||
public all: boolean,
|
||||
@@ -197,9 +197,9 @@ export class LogQueryRequest {
|
||||
|
||||
export class LogMessageEvent {
|
||||
declare ["constructor"]: typeof LogMessageEvent;
|
||||
static type = "event";
|
||||
static src = ["host", "controller"];
|
||||
static dst = ["controller", "control"];
|
||||
static type = "event" as const;
|
||||
static src = ["host", "controller"] as const;
|
||||
static dst = ["controller", "control"] as const;
|
||||
|
||||
constructor(
|
||||
public info: object,
|
||||
@@ -219,17 +219,17 @@ export class LogMessageEvent {
|
||||
|
||||
export class DebugDumpWsRequest {
|
||||
declare ["constructor"]: typeof DebugDumpWsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.debug.dump_ws";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.debug.dump_ws" as const;
|
||||
}
|
||||
|
||||
export class DebugWsMessageEvent {
|
||||
declare ["constructor"]: typeof DebugWsMessageEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "control" as const;
|
||||
|
||||
constructor(
|
||||
public direction: string,
|
||||
|
||||
@@ -323,7 +323,7 @@ export class ReadyData {
|
||||
});
|
||||
|
||||
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
||||
let account: AccountDetails;
|
||||
let account: AccountDetails | undefined;
|
||||
if (json.account) { account = AccountDetails.fromJSON(json.account); }
|
||||
return new this(
|
||||
Address.fromJSON(json.src),
|
||||
@@ -622,8 +622,9 @@ Message.jsonSchema = Type.Union([
|
||||
]);
|
||||
|
||||
export class PingRequest {
|
||||
static type = "request";
|
||||
static src = ["controller", "host", "control"];
|
||||
static dst = ["controller", "host", "control"];
|
||||
declare ["constructor"]: typeof PingRequest;
|
||||
static type = "request" as const;
|
||||
static src = ["controller", "host", "control"] as const;
|
||||
static dst = ["controller", "host", "control"] as const;
|
||||
static permission = null;
|
||||
}
|
||||
@@ -28,19 +28,19 @@ export class HostDetails {
|
||||
|
||||
export class HostListRequest {
|
||||
declare ["constructor"]: typeof HostListRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.host.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.host.list" as const;
|
||||
static Response = jsonArray(HostDetails);
|
||||
}
|
||||
|
||||
export class HostSetSubscriptionsRequest {
|
||||
declare ["constructor"]: typeof HostSetSubscriptionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.host.subscribe";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.host.subscribe" as const;
|
||||
|
||||
constructor(
|
||||
public all: boolean,
|
||||
@@ -60,9 +60,9 @@ export class HostSetSubscriptionsRequest {
|
||||
|
||||
export class HostUpdateEvent {
|
||||
declare ["constructor"]: typeof HostUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "control" as const;
|
||||
|
||||
constructor(
|
||||
public update: HostDetails,
|
||||
@@ -79,9 +79,9 @@ export class HostUpdateEvent {
|
||||
|
||||
export class HostMetricsRequest {
|
||||
declare ["constructor"]: typeof HostMetricsRequest;
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
static type = "request" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "host" as const;
|
||||
static Response = class Response { // TODO: Use JSON class pattern in Prometheus
|
||||
constructor(
|
||||
public results: object[],
|
||||
@@ -99,9 +99,9 @@ export class HostMetricsRequest {
|
||||
|
||||
export class ControllerConnectionEvent {
|
||||
declare ["constructor"]: typeof ControllerConnectionEvent;
|
||||
static type = "event";
|
||||
static src = "host";
|
||||
static dst = "instance";
|
||||
static type = "event" as const;
|
||||
static src = "host" as const;
|
||||
static dst = "instance" as const;
|
||||
|
||||
constructor(
|
||||
public event: string,
|
||||
@@ -118,16 +118,16 @@ export class ControllerConnectionEvent {
|
||||
|
||||
export class PrepareControllerDisconnectRequest {
|
||||
declare ["constructor"]: typeof PrepareControllerDisconnectRequest;
|
||||
static type = "request";
|
||||
static src = "host";
|
||||
static dst = "instance";
|
||||
static type = "request" as const;
|
||||
static src = "host" as const;
|
||||
static dst = "instance" as const;
|
||||
}
|
||||
|
||||
export class SyncUserListsEvent {
|
||||
declare ["constructor"]: typeof SyncUserListsEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "host" as const;
|
||||
|
||||
constructor(
|
||||
public adminlist: Set<string>,
|
||||
|
||||
@@ -35,10 +35,10 @@ export class InstanceDetails {
|
||||
|
||||
export class InstanceDetailsGetRequest {
|
||||
declare ["constructor"]: typeof InstanceDetailsGetRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.get";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.get" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -57,19 +57,19 @@ export class InstanceDetailsGetRequest {
|
||||
|
||||
export class InstanceDetailsListRequest {
|
||||
declare ["constructor"]: typeof InstanceDetailsListRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.list" as const;
|
||||
static Response = jsonArray(InstanceDetails);
|
||||
};
|
||||
|
||||
export class InstanceDetailsSetSubscriptionsRequest {
|
||||
declare ["constructor"]: typeof InstanceDetailsSetSubscriptionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.subscribe";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.subscribe" as const;
|
||||
|
||||
constructor(
|
||||
public all: boolean = false,
|
||||
@@ -88,9 +88,9 @@ export class InstanceDetailsSetSubscriptionsRequest {
|
||||
|
||||
export class InstanceDetailsUpdateEvent {
|
||||
declare ["constructor"]: typeof InstanceDetailsUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "control" as const;
|
||||
|
||||
constructor(
|
||||
public details: InstanceDetails,
|
||||
@@ -109,10 +109,10 @@ export class InstanceDetailsUpdateEvent {
|
||||
|
||||
export class InstanceCreateRequest {
|
||||
declare ["constructor"]: typeof InstanceCreateRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.create";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.create" as const;
|
||||
|
||||
constructor(
|
||||
public config: object,
|
||||
@@ -130,10 +130,10 @@ export class InstanceCreateRequest {
|
||||
|
||||
export class InstanceConfigGetRequest {
|
||||
declare ["constructor"]: typeof InstanceConfigGetRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.get_config";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.get_config" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -165,10 +165,10 @@ export class InstanceConfigGetRequest {
|
||||
|
||||
export class InstanceConfigSetFieldRequest {
|
||||
declare ["constructor"]: typeof InstanceConfigSetFieldRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.update_config";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.update_config" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -189,10 +189,10 @@ export class InstanceConfigSetFieldRequest {
|
||||
|
||||
export class InstanceConfigSetPropRequest {
|
||||
declare ["constructor"]: typeof InstanceConfigSetPropRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.update_config";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.update_config" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -215,10 +215,10 @@ export class InstanceConfigSetPropRequest {
|
||||
|
||||
export class InstanceAssignRequest {
|
||||
declare ["constructor"]: typeof InstanceAssignRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.assign";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.assign" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -237,9 +237,9 @@ export class InstanceAssignRequest {
|
||||
|
||||
export class InstanceMetricsRequest {
|
||||
declare ["constructor"]: typeof InstanceMetricsRequest;
|
||||
static type = "request";
|
||||
static src = "host";
|
||||
static dst = "instance";
|
||||
static type = "request" as const;
|
||||
static src = "host" as const;
|
||||
static dst = "instance" as const;
|
||||
|
||||
static Response = class Response { // TODO: Use JSON class pattern in Prometheus
|
||||
constructor(
|
||||
@@ -258,10 +258,10 @@ export class InstanceMetricsRequest {
|
||||
|
||||
export class InstanceStartRequest {
|
||||
declare ["constructor"]: typeof InstanceStartRequest;
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.start";
|
||||
static type = "request" as const;
|
||||
static src = ["control", "controller"] as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.start" as const;
|
||||
|
||||
constructor(
|
||||
public save?: string,
|
||||
@@ -302,19 +302,19 @@ export class SaveDetails {
|
||||
|
||||
export class InstanceListSavesRequest {
|
||||
declare ["constructor"]: typeof InstanceListSavesRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.save.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.save.list" as const;
|
||||
static Response = jsonArray(SaveDetails);
|
||||
}
|
||||
|
||||
export class InstanceSetSaveListSubscriptionsRequest {
|
||||
declare ["constructor"]: typeof InstanceSetSaveListSubscriptionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.save.list_subscribe";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.save.list_subscribe" as const;
|
||||
|
||||
constructor(
|
||||
public all: boolean = false,
|
||||
@@ -333,9 +333,9 @@ export class InstanceSetSaveListSubscriptionsRequest {
|
||||
|
||||
export class InstanceSaveListUpdateEvent {
|
||||
declare ["constructor"]: typeof InstanceSaveListUpdateEvent;
|
||||
static type = "event";
|
||||
static src = ["instance", "host", "controller"];
|
||||
static dst = ["controller", "control"];
|
||||
static type = "event" as const;
|
||||
static src = ["instance", "host", "controller"] as const;
|
||||
static dst = ["controller", "control"] as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -354,10 +354,10 @@ export class InstanceSaveListUpdateEvent {
|
||||
|
||||
export class InstanceCreateSaveRequest {
|
||||
declare ["constructor"]: typeof InstanceCreateSaveRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.save.create";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.save.create" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -380,10 +380,10 @@ export class InstanceCreateSaveRequest {
|
||||
|
||||
export class InstanceRenameSaveRequest {
|
||||
declare ["constructor"]: typeof InstanceRenameSaveRequest;
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
static dst = ["controller", "host"];
|
||||
static permission = "core.instance.save.rename";
|
||||
static type = "request" as const;
|
||||
static src = ["control", "controller"] as const;
|
||||
static dst = ["controller", "host"] as const;
|
||||
static permission = "core.instance.save.rename" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -404,10 +404,10 @@ export class InstanceRenameSaveRequest {
|
||||
|
||||
export class InstanceCopySaveRequest {
|
||||
declare ["constructor"]: typeof InstanceCopySaveRequest;
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
static dst = ["controller", "host"];
|
||||
static permission = "core.instance.save.copy";
|
||||
static type = "request" as const;
|
||||
static src = ["control", "controller"] as const;
|
||||
static dst = ["controller", "host"] as const;
|
||||
static permission = "core.instance.save.copy" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -428,10 +428,10 @@ export class InstanceCopySaveRequest {
|
||||
|
||||
export class InstanceDeleteSaveRequest {
|
||||
declare ["constructor"]: typeof InstanceDeleteSaveRequest;
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
static dst = ["controller", "host"];
|
||||
static permission = "core.instance.save.delete";
|
||||
static type = "request" as const;
|
||||
static src = ["control", "controller"] as const;
|
||||
static dst = ["controller", "host"] as const;
|
||||
static permission = "core.instance.save.delete" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -450,10 +450,10 @@ export class InstanceDeleteSaveRequest {
|
||||
|
||||
export class InstanceDownloadSaveRequest {
|
||||
declare ["constructor"]: typeof InstanceDownloadSaveRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.save.download";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.save.download" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -474,9 +474,9 @@ export class InstanceDownloadSaveRequest {
|
||||
|
||||
export class InstanceTransferSaveRequest {
|
||||
declare ["constructor"]: typeof InstanceTransferSaveRequest;
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
static dst = ["controller", "host"];
|
||||
static type = "request" as const;
|
||||
static src = ["control", "controller"] as const;
|
||||
static dst = ["controller", "host"] as const;
|
||||
static permission(user: User, message: MessageRequest) {
|
||||
user.checkPermission("core.instance.save.transfer");
|
||||
if (typeof message.data === "object" && message.data !== null) {
|
||||
@@ -517,9 +517,9 @@ export class InstanceTransferSaveRequest {
|
||||
|
||||
export class InstancePullSaveRequest {
|
||||
declare ["constructor"]: typeof InstancePullSaveRequest;
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
static type = "request" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "host" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -542,9 +542,9 @@ export class InstancePullSaveRequest {
|
||||
|
||||
export class InstancePushSaveRequest {
|
||||
declare ["constructor"]: typeof InstancePushSaveRequest;
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
static type = "request" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "host" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -565,10 +565,10 @@ export class InstancePushSaveRequest {
|
||||
|
||||
export class InstanceLoadScenarioRequest {
|
||||
declare ["constructor"]: typeof InstanceLoadScenarioRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.load_scenario";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.load_scenario" as const;
|
||||
|
||||
constructor(
|
||||
public scenario: string,
|
||||
@@ -591,42 +591,42 @@ export class InstanceLoadScenarioRequest {
|
||||
|
||||
export class InstanceExportDataRequest {
|
||||
declare ["constructor"]: typeof InstanceExportDataRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.export_data";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.export_data" as const;
|
||||
}
|
||||
|
||||
export class InstanceExtractPlayersRequest {
|
||||
declare ["constructor"]: typeof InstanceExtractPlayersRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.extract_players";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.extract_players" as const;
|
||||
}
|
||||
|
||||
export class InstanceStopRequest {
|
||||
declare ["constructor"]: typeof InstanceStopRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.stop";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.stop" as const;
|
||||
}
|
||||
|
||||
export class InstanceKillRequest {
|
||||
declare ["constructor"]: typeof InstanceKillRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.kill";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.kill" as const;
|
||||
}
|
||||
|
||||
export class InstanceDeleteRequest {
|
||||
declare ["constructor"]: typeof InstanceDeleteRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.instance.delete";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.instance.delete" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -643,9 +643,9 @@ export class InstanceDeleteRequest {
|
||||
|
||||
export class InstanceDeleteInternalRequest {
|
||||
declare ["constructor"]: typeof InstanceDeleteInternalRequest;
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
static type = "request" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "host" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -662,10 +662,10 @@ export class InstanceDeleteInternalRequest {
|
||||
|
||||
export class InstanceSendRconRequest {
|
||||
declare ["constructor"]: typeof InstanceSendRconRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "instance";
|
||||
static permission = "core.instance.send_rcon";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "instance" as const;
|
||||
static permission = "core.instance.send_rcon" as const;
|
||||
|
||||
constructor(
|
||||
public command: string,
|
||||
@@ -704,9 +704,9 @@ export class RawInstanceInfo {
|
||||
|
||||
export class InstancesUpdateRequest {
|
||||
declare ["constructor"]: typeof InstancesUpdateRequest;
|
||||
static type = "request";
|
||||
static src = "host";
|
||||
static dst = "controller";
|
||||
static type = "request" as const;
|
||||
static src = "host" as const;
|
||||
static dst = "controller" as const;
|
||||
|
||||
constructor(
|
||||
public instances: RawInstanceInfo[],
|
||||
@@ -725,9 +725,9 @@ export class InstancesUpdateRequest {
|
||||
|
||||
export class InstanceAssignInternalRequest {
|
||||
declare ["constructor"]: typeof InstanceAssignInternalRequest;
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
static type = "request" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "host" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -747,9 +747,9 @@ export class InstanceAssignInternalRequest {
|
||||
|
||||
export class InstanceUnassignInternalRequest {
|
||||
declare ["constructor"]: typeof InstanceUnassignInternalRequest;
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
static type = "request" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "host" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -766,9 +766,9 @@ export class InstanceUnassignInternalRequest {
|
||||
|
||||
export class InstanceInitialisedEvent {
|
||||
declare ["constructor"]: typeof InstanceInitialisedEvent;
|
||||
static type = "event";
|
||||
static src = "instance";
|
||||
static dst = "host";
|
||||
static type = "event" as const;
|
||||
static src = "instance" as const;
|
||||
static dst = "host" as const;
|
||||
|
||||
constructor(
|
||||
public plugins: Record<string, string>,
|
||||
@@ -785,9 +785,9 @@ export class InstanceInitialisedEvent {
|
||||
|
||||
export class InstanceStatusChangedEvent {
|
||||
declare ["constructor"]: typeof InstanceStatusChangedEvent;
|
||||
static type = "event";
|
||||
static src = ["instance", "host"];
|
||||
static dst = "controller";
|
||||
static type = "event" as const;
|
||||
static src = ["instance", "host"] as const;
|
||||
static dst = "controller" as const;
|
||||
|
||||
constructor(
|
||||
public instanceId: number,
|
||||
@@ -810,9 +810,9 @@ export class InstanceStatusChangedEvent {
|
||||
|
||||
export class InstanceDetailsChangedEvent {
|
||||
declare ["constructor"]: typeof InstanceDetailsChangedEvent;
|
||||
static type = "event";
|
||||
static src = "instance";
|
||||
static dst = "controller";
|
||||
static type = "event" as const;
|
||||
static src = "instance" as const;
|
||||
static dst = "controller" as const;
|
||||
|
||||
constructor(
|
||||
public details: InstanceDetails,
|
||||
@@ -827,9 +827,9 @@ export class InstanceDetailsChangedEvent {
|
||||
|
||||
export class InstanceBanlistUpdateEvent {
|
||||
declare ["constructor"]: typeof InstanceBanlistUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "instance";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "instance" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -850,9 +850,9 @@ export class InstanceBanlistUpdateEvent {
|
||||
|
||||
export class InstanceAdminlistUpdateEvent {
|
||||
declare ["constructor"]: typeof InstanceAdminlistUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "instance";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "instance" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -871,9 +871,9 @@ export class InstanceAdminlistUpdateEvent {
|
||||
|
||||
export class InstanceWhitelistUpdateEvent {
|
||||
declare ["constructor"]: typeof InstanceWhitelistUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "instance";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "instance" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -892,9 +892,9 @@ export class InstanceWhitelistUpdateEvent {
|
||||
|
||||
export class InstancePlayerUpdateEvent {
|
||||
declare ["constructor"]: typeof InstancePlayerUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "instance";
|
||||
static dst = "controller";
|
||||
static type = "event" as const;
|
||||
static src = "instance" as const;
|
||||
static dst = "controller" as const;
|
||||
|
||||
constructor(
|
||||
public type: string,
|
||||
|
||||
@@ -6,10 +6,10 @@ import { JsonString, jsonArray } from "./composites";
|
||||
|
||||
export class ModPackGetRequest {
|
||||
declare ["constructor"]: typeof ModPackGetRequest;
|
||||
static type = "request";
|
||||
static src = ["instance", "control"];
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.get";
|
||||
static type = "request" as const;
|
||||
static src = ["instance", "control"] as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod_pack.get" as const;
|
||||
|
||||
constructor(
|
||||
public id: number,
|
||||
@@ -28,28 +28,28 @@ export class ModPackGetRequest {
|
||||
|
||||
export class ModPackGetDefaultRequest {
|
||||
declare ["constructor"]: typeof ModPackGetDefaultRequest;
|
||||
static type = "request";
|
||||
static src = ["instance", "control"];
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.get";
|
||||
static type = "request" as const;
|
||||
static src = ["instance", "control"] as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod_pack.get" as const;
|
||||
static Response = ModPack;
|
||||
}
|
||||
|
||||
export class ModPackListRequest {
|
||||
declare ["constructor"]: typeof ModPackListRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod_pack.list" as const;
|
||||
static Response = jsonArray(ModPack);
|
||||
}
|
||||
|
||||
export class ModPackCreateRequest {
|
||||
declare ["constructor"]: typeof ModPackCreateRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.create";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod_pack.create" as const;
|
||||
|
||||
constructor(
|
||||
public modPack: ModPack,
|
||||
@@ -66,10 +66,10 @@ export class ModPackCreateRequest {
|
||||
|
||||
export class ModPackUpdateRequest {
|
||||
declare ["constructor"]: typeof ModPackUpdateRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.update";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod_pack.update" as const;
|
||||
|
||||
constructor(
|
||||
public modPack: ModPack,
|
||||
@@ -86,10 +86,10 @@ export class ModPackUpdateRequest {
|
||||
|
||||
export class ModPackDeleteRequest {
|
||||
declare ["constructor"]: typeof ModPackDeleteRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.delete";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod_pack.delete" as const;
|
||||
|
||||
constructor(
|
||||
public id: number,
|
||||
@@ -106,10 +106,10 @@ export class ModPackDeleteRequest {
|
||||
|
||||
export class ModPackSetSubscriptionsRequest {
|
||||
declare ["constructor"]: typeof ModPackSetSubscriptionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.subscribe";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod_pack.subscribe" as const;
|
||||
|
||||
constructor(
|
||||
public all: boolean,
|
||||
@@ -128,10 +128,10 @@ export class ModPackSetSubscriptionsRequest {
|
||||
|
||||
export class ModGetRequest {
|
||||
declare ["constructor"]: typeof ModGetRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod.get";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod.get" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -152,19 +152,19 @@ export class ModGetRequest {
|
||||
|
||||
export class ModListRequest {
|
||||
declare ["constructor"]: typeof ModListRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod.list" as const;
|
||||
static Response = jsonArray(ModInfo);
|
||||
}
|
||||
|
||||
export class ModSearchRequest {
|
||||
declare ["constructor"]: typeof ModSearchRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod.search";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod.search" as const;
|
||||
|
||||
constructor(
|
||||
public query: string,
|
||||
@@ -178,8 +178,8 @@ export class ModSearchRequest {
|
||||
static jsonSchema = Type.Object({
|
||||
"query": Type.String(),
|
||||
"factorioVersion": Type.String(),
|
||||
"pageSize": Type.Integer(),
|
||||
"page": Type.Optional(Type.Integer()),
|
||||
"page": Type.Integer(),
|
||||
"pageSize": Type.Optional(Type.Integer()),
|
||||
"sort": Type.Optional(Type.String()),
|
||||
"sortOrder": Type.Optional(Type.String()),
|
||||
});
|
||||
@@ -219,10 +219,10 @@ export class ModSearchRequest {
|
||||
|
||||
export class ModSetSubscriptionsRequest {
|
||||
declare ["constructor"]: typeof ModSetSubscriptionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod.subscribe";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod.subscribe" as const;
|
||||
|
||||
constructor(
|
||||
public all: boolean,
|
||||
@@ -241,10 +241,10 @@ export class ModSetSubscriptionsRequest {
|
||||
|
||||
export class ModDownloadRequest {
|
||||
declare ["constructor"]: typeof ModDownloadRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod.download";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod.download" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -265,10 +265,10 @@ export class ModDownloadRequest {
|
||||
|
||||
export class ModDeleteRequest {
|
||||
declare ["constructor"]: typeof ModDeleteRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod.delete";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.mod.delete" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -287,9 +287,9 @@ export class ModDeleteRequest {
|
||||
|
||||
export class ModPackUpdateEvent {
|
||||
declare ["constructor"]: typeof ModPackUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "control" as const;
|
||||
|
||||
constructor(
|
||||
public modPack: ModPack,
|
||||
@@ -306,9 +306,9 @@ export class ModPackUpdateEvent {
|
||||
|
||||
export class ModUpdateEvent {
|
||||
declare ["constructor"]: typeof ModUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "control" as const;
|
||||
|
||||
constructor(
|
||||
public mod: ModInfo,
|
||||
|
||||
@@ -22,10 +22,10 @@ export class RawPermission { // TODO refactor into lib/user.Permission
|
||||
|
||||
export class PermissionListRequest {
|
||||
declare ["constructor"]: typeof PermissionListRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.permission.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.permission.list" as const;
|
||||
static Response = jsonArray(RawPermission);
|
||||
}
|
||||
|
||||
@@ -51,19 +51,19 @@ export class RawRole { // TODO refactor into lib/user.Role
|
||||
|
||||
export class RoleListRequest {
|
||||
declare ["constructor"]: typeof RoleListRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.role.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.role.list" as const;
|
||||
static Response = jsonArray(RawRole);
|
||||
}
|
||||
|
||||
export class RoleCreateRequest {
|
||||
declare ["constructor"]: typeof RoleCreateRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.role.create";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.role.create" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -86,10 +86,10 @@ export class RoleCreateRequest {
|
||||
|
||||
export class RoleUpdateRequest {
|
||||
declare ["constructor"]: typeof RoleUpdateRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.role.update";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.role.update" as const;
|
||||
|
||||
constructor(
|
||||
public id: number,
|
||||
@@ -112,10 +112,10 @@ export class RoleUpdateRequest {
|
||||
|
||||
export class RoleGrantDefaultPermissionsRequest {
|
||||
declare ["constructor"]: typeof RoleGrantDefaultPermissionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.role.update";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.role.update" as const;
|
||||
|
||||
constructor(
|
||||
public id: number,
|
||||
@@ -132,10 +132,10 @@ export class RoleGrantDefaultPermissionsRequest {
|
||||
|
||||
export class RoleDeleteRequest {
|
||||
declare ["constructor"]: typeof RoleDeleteRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.role.delete";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.role.delete" as const;
|
||||
|
||||
constructor(
|
||||
public id: number,
|
||||
@@ -173,20 +173,20 @@ export class RawUser { // TODO refactor into lib/user.User
|
||||
isWhitelisted: Type.Optional(Type.Boolean()),
|
||||
banReason: Type.Optional(Type.String()),
|
||||
isDeleted: Type.Optional(Type.Boolean()),
|
||||
playerStats: Type.Optional(Type.Unsafe<unknown>(PlayerStats.jsonSchema)),
|
||||
playerStats: Type.Optional(PlayerStats.jsonSchema),
|
||||
instanceStats: Type.Optional(
|
||||
Type.Array(
|
||||
Type.Tuple([Type.Integer(), Type.Unsafe<unknown>(PlayerStats.jsonSchema)]),
|
||||
Type.Tuple([Type.Integer(), PlayerStats.jsonSchema]),
|
||||
)
|
||||
),
|
||||
});
|
||||
|
||||
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
||||
let playerStats: PlayerStats;
|
||||
let playerStats: PlayerStats | undefined;
|
||||
if (json.playerStats) {
|
||||
playerStats = PlayerStats.fromJSON(json.playerStats);
|
||||
}
|
||||
let instanceStats: Map<number, PlayerStats>;
|
||||
let instanceStats: Map<number, PlayerStats> | undefined;
|
||||
if (json.instanceStats) {
|
||||
instanceStats = new Map(
|
||||
json.instanceStats.map(([id, stats]) => [id, PlayerStats.fromJSON(stats)])
|
||||
@@ -208,10 +208,12 @@ export class RawUser { // TODO refactor into lib/user.User
|
||||
isWhitelisted: this.isWhitelisted,
|
||||
banReason: this.banReason,
|
||||
isDeleted: this.isDeleted,
|
||||
playerStats: this.playerStats,
|
||||
};
|
||||
if (this.playerStats) {
|
||||
json.playerStats = this.playerStats.toJSON()
|
||||
}
|
||||
if (this.instanceStats) {
|
||||
json.instanceStats = [...this.instanceStats];
|
||||
json.instanceStats = [...this.instanceStats].map(([k, v]) => [k, v.toJSON()]);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
@@ -219,10 +221,10 @@ export class RawUser { // TODO refactor into lib/user.User
|
||||
|
||||
export class UserGetRequest {
|
||||
declare ["constructor"]: typeof UserGetRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.get";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.get" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -241,19 +243,19 @@ export class UserGetRequest {
|
||||
|
||||
export class UserListRequest {
|
||||
declare ["constructor"]: typeof UserListRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.list";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.list" as const;
|
||||
static Response = jsonArray(RawUser);
|
||||
}
|
||||
|
||||
export class UserSetSubscriptionsRequest {
|
||||
declare ["constructor"]: typeof UserSetSubscriptionsRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.subscribe";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.subscribe" as const;
|
||||
|
||||
constructor(
|
||||
public all: boolean,
|
||||
@@ -272,10 +274,10 @@ export class UserSetSubscriptionsRequest {
|
||||
|
||||
export class UserCreateRequest {
|
||||
declare ["constructor"]: typeof UserCreateRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.create";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.create" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -292,10 +294,10 @@ export class UserCreateRequest {
|
||||
|
||||
export class UserRevokeTokenRequest {
|
||||
declare ["constructor"]: typeof UserRevokeTokenRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.revoke_token";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.revoke_token" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -312,10 +314,10 @@ export class UserRevokeTokenRequest {
|
||||
|
||||
export class UserUpdateRolesRequest {
|
||||
declare ["constructor"]: typeof UserUpdateRolesRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.update_roles";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.update_roles" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -334,10 +336,10 @@ export class UserUpdateRolesRequest {
|
||||
|
||||
export class UserSetAdminRequest {
|
||||
declare ["constructor"]: typeof UserSetAdminRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.set_admin";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.set_admin" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -358,10 +360,10 @@ export class UserSetAdminRequest {
|
||||
|
||||
export class UserSetWhitelistedRequest {
|
||||
declare ["constructor"]: typeof UserSetWhitelistedRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.set_whitelisted";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.set_whitelisted" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -382,10 +384,10 @@ export class UserSetWhitelistedRequest {
|
||||
|
||||
export class UserSetBannedRequest {
|
||||
declare ["constructor"]: typeof UserSetBannedRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.set_banned";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.set_banned" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -408,10 +410,10 @@ export class UserSetBannedRequest {
|
||||
|
||||
export class UserDeleteRequest {
|
||||
declare ["constructor"]: typeof UserDeleteRequest;
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.user.delete";
|
||||
static type = "request" as const;
|
||||
static src = "control" as const;
|
||||
static dst = "controller" as const;
|
||||
static permission = "core.user.delete" as const;
|
||||
|
||||
constructor(
|
||||
public name: string,
|
||||
@@ -429,9 +431,9 @@ export class UserDeleteRequest {
|
||||
|
||||
export class AccountUpdateEvent {
|
||||
declare ["constructor"]: typeof AccountUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "control" as const;
|
||||
|
||||
constructor(
|
||||
public roles?: { name: string, id: number, permissions: string[] }[],
|
||||
@@ -454,9 +456,9 @@ export class AccountUpdateEvent {
|
||||
|
||||
export class UserUpdateEvent {
|
||||
declare ["constructor"]: typeof UserUpdateEvent;
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
static type = "event" as const;
|
||||
static src = "controller" as const;
|
||||
static dst = "control" as const;
|
||||
|
||||
constructor(
|
||||
public user: RawUser,
|
||||
|
||||
@@ -54,7 +54,7 @@ export async function loadJsonAsMap(filePath: string): Promise<Map<string, unkno
|
||||
|
||||
return new Map(Object.entries(parsed));
|
||||
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT") {
|
||||
// File does not exist, return empty map
|
||||
return new Map();
|
||||
@@ -115,7 +115,7 @@ export async function loadJsonArrayAsMap(filePath: string): Promise<Map<unknown,
|
||||
}
|
||||
return map;
|
||||
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT") {
|
||||
// File does not exist, return empty map
|
||||
return new Map();
|
||||
@@ -247,7 +247,7 @@ export class ItemDatabase {
|
||||
checkCount(count);
|
||||
|
||||
if (this._items.has(name)) {
|
||||
count += this._items.get(name);
|
||||
count += this._items.get(name)!;
|
||||
}
|
||||
|
||||
this._items.set(name, count);
|
||||
@@ -269,7 +269,7 @@ export class ItemDatabase {
|
||||
|
||||
count = -count;
|
||||
if (this._items.has(name)) {
|
||||
count += this._items.get(name);
|
||||
count += this._items.get(name)!;
|
||||
}
|
||||
|
||||
this._items.set(name, count);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Thrown by commands when they fail
|
||||
*/
|
||||
export class CommandError extends Error {
|
||||
code: "CommandError";
|
||||
code = "CommandError";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,10 +45,10 @@ export class PermissionError extends RequestError {
|
||||
* Signal for messages that fail validation
|
||||
*/
|
||||
export class InvalidMessage extends Error {
|
||||
code: "InvalidMessage";
|
||||
code = "InvalidMessage";
|
||||
constructor(
|
||||
message: string,
|
||||
public errors: object = null,
|
||||
public errors?: object | null,
|
||||
) {
|
||||
super(message);
|
||||
}
|
||||
@@ -58,35 +58,35 @@ export class InvalidMessage extends Error {
|
||||
* Thrown from requests when the session it was sent on was lost
|
||||
*/
|
||||
export class SessionLost extends Error {
|
||||
code: "SessionLost";
|
||||
code = "SessionLost";
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown when WebSocket authentication failed
|
||||
*/
|
||||
export class AuthenticationFailed extends Error {
|
||||
code: "AuthenticationFailed";
|
||||
code = "AuthenticationFailed";
|
||||
}
|
||||
|
||||
/**
|
||||
* Errror class for known errors occuring during startup
|
||||
*/
|
||||
export class StartupError extends Error {
|
||||
code: "StartupError";
|
||||
code = "StartupError";
|
||||
}
|
||||
|
||||
/**
|
||||
* Errors outside of our control
|
||||
*/
|
||||
export class EnvironmentError extends Error {
|
||||
code: "EnvironmentError";
|
||||
code = "EnvironmentError";
|
||||
}
|
||||
|
||||
/**
|
||||
* Errors caused by plugins
|
||||
*/
|
||||
export class PluginError extends Error {
|
||||
code: "PluginError";
|
||||
code = "PluginError";
|
||||
constructor(
|
||||
public pluginName: string,
|
||||
public original: Error
|
||||
|
||||
@@ -363,7 +363,7 @@ export function readMapExchangeString(exchangeString: string) {
|
||||
try {
|
||||
// eslint-disable-next-line node/no-sync
|
||||
buf = zlib.inflateSync(buf);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code.startsWith("Z_")) {
|
||||
throw new Error("Malformed map exchange string: zlib inflate failed");
|
||||
}
|
||||
@@ -380,7 +380,7 @@ export function readMapExchangeString(exchangeString: string) {
|
||||
map_settings: readMapSettings(state),
|
||||
checksum: readUInt32(state),
|
||||
};
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code === "ERR_OUT_OF_RANGE") {
|
||||
throw new Error("Malformed map exchange string: reached end before finishing parsing");
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export async function directorySize(directory: string) {
|
||||
let dirEntries: fs.Dirent[];
|
||||
try {
|
||||
dirEntries = await fs.readdir(directory, { withFileTypes: true });
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code === "ENOENT") {
|
||||
return 0;
|
||||
}
|
||||
@@ -92,7 +92,7 @@ export async function findUnusedName(directory: string, name: string, extension
|
||||
return `${name}${extension}`;
|
||||
}
|
||||
|
||||
let match = /^(.*?)(-(\d+))?$/.exec(name);
|
||||
let match = /^(.*?)(-(\d+))?$/.exec(name)!;
|
||||
if (!match[2]) {
|
||||
name = `${match[1]}-2`;
|
||||
} else {
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function wait(duration: number) {
|
||||
* @param {*=} timeoutResult - Value to return if the operation timed out.
|
||||
*/
|
||||
export async function timeout<T>(promise: Promise<T>, time: number, timeoutResult: T) {
|
||||
let timer: ReturnType<typeof setTimeout>;
|
||||
let timer: NodeJS.Timer | undefined;
|
||||
try {
|
||||
return await Promise.race([
|
||||
promise,
|
||||
@@ -157,10 +157,10 @@ function parseSearchTerm(
|
||||
input: string,
|
||||
attributes: Record<string, string>,
|
||||
issues: Array<string>
|
||||
): [number, ParsedTerm] {
|
||||
): [number, ParsedTerm | undefined] {
|
||||
// attribute = identifier, ':', word
|
||||
// term = word | attribute
|
||||
let term: ParsedTerm;
|
||||
let term: ParsedTerm | undefined;
|
||||
if (["-", '"'].includes(input.charAt(pos))) {
|
||||
([pos, term] = parseSearchWord(pos, input));
|
||||
} else {
|
||||
@@ -274,12 +274,12 @@ export function parseSearchString(
|
||||
// search = [ term, *( [ whitespace ], term ) ]
|
||||
input = input.trim();
|
||||
let parsed = {
|
||||
terms: [],
|
||||
issues: [],
|
||||
terms: [] as ParsedTerm[],
|
||||
issues: [] as string[],
|
||||
};
|
||||
let pos = 0;
|
||||
while (pos < input.length) {
|
||||
let term: ParsedTerm;
|
||||
let term: ParsedTerm | undefined;
|
||||
([pos, term] = parseSearchTerm(pos, input, attributes, parsed.issues));
|
||||
if (term) {
|
||||
parsed.terms.push(term);
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import ws = require("ws");
|
||||
export = ws;
|
||||
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
// eslint-disable-next-line node/no-process-env
|
||||
module.exports = process.env.APP_ENV === "browser" ? window.WebSocket : require("ws");
|
||||
@@ -2,14 +2,13 @@
|
||||
"use strict";
|
||||
import { strict as assert } from "assert";
|
||||
import events from "events";
|
||||
// eslint-disable-next-line node/no-process-env
|
||||
// @ts-ignore
|
||||
const WebSocket = process.env.APP_ENV === "browser" ? window.WebSocket : require("ws");
|
||||
import WebSocket from "./WebSocket";
|
||||
|
||||
import * as libData from "../data";
|
||||
import * as libErrors from "../errors";
|
||||
import { logger } from "../logging";
|
||||
import ExponentialBackoff from "../ExponentialBackoff";
|
||||
import type { Request, Event } from "./link";
|
||||
|
||||
|
||||
/**
|
||||
@@ -37,15 +36,15 @@ export abstract class BaseConnector extends events.EventEmitter {
|
||||
|
||||
abstract send(message: libData.Message): void;
|
||||
|
||||
sendRequest(
|
||||
request: libData.Request,
|
||||
sendRequest<Req, Res>(
|
||||
request: Request<Req, Res>,
|
||||
requestId: number,
|
||||
dst: libData.Address
|
||||
) {
|
||||
let seq = this._seq;
|
||||
this._seq += 1;
|
||||
let src = new libData.Address(this.src.type, this.src.id, requestId);
|
||||
let Request = request.constructor as typeof libData.Request;
|
||||
let Request = request.constructor;
|
||||
let name = Request.plugin ? `${Request.plugin}:${Request.name}` : Request.name;
|
||||
let hasData = Boolean(Request.jsonSchema);
|
||||
const message = new libData.MessageRequest(seq, src, dst, name, hasData ? request : undefined);
|
||||
@@ -69,10 +68,10 @@ export abstract class BaseConnector extends events.EventEmitter {
|
||||
return seq;
|
||||
}
|
||||
|
||||
sendEvent(event: libData.Event, dst: libData.Address) {
|
||||
sendEvent<T>(event: Event<T>, dst: libData.Address) {
|
||||
let seq = this._seq;
|
||||
this._seq += 1;
|
||||
let Event = event.constructor as typeof libData.Event;
|
||||
let Event = event.constructor;
|
||||
let name = Event.plugin ? `${Event.plugin}:${Event.name}` : Event.name;
|
||||
let hasData = Boolean(Event.jsonSchema);
|
||||
const message = new libData.MessageEvent(seq, this.src, dst, name, hasData ? event : undefined);
|
||||
@@ -82,6 +81,12 @@ export abstract class BaseConnector extends events.EventEmitter {
|
||||
}
|
||||
|
||||
type ConnectorState = "closed" | "connecting" | "connected" | "resuming";
|
||||
type ReliableMessages =
|
||||
| libData.MessageRequest
|
||||
| libData.MessageResponse
|
||||
| libData.MessageResponseError
|
||||
| libData.MessageEvent
|
||||
;
|
||||
|
||||
/**
|
||||
* Base connector for links
|
||||
@@ -92,12 +97,12 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
// One of closed, connecting (client only), connected and resuming.
|
||||
_state: ConnectorState = "closed";
|
||||
_closing = false;
|
||||
_socket = null;
|
||||
_lastHeartbeat = null;
|
||||
_heartbeatId: NodeJS.Timer = null;
|
||||
_socket: WebSocket | null = null;
|
||||
_lastHeartbeat: number | null = null;
|
||||
_heartbeatId: NodeJS.Timer | null = null;
|
||||
_heartbeatInterval: number | null = null;
|
||||
_lastReceivedSeq = undefined;
|
||||
_sendBuffer = [];
|
||||
_sendBuffer: (ReliableMessages)[] = [];
|
||||
|
||||
constructor(src: libData.Address, dst: libData.Address) {
|
||||
super(src, dst);
|
||||
@@ -194,13 +199,13 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
|
||||
_doHeartbeat() {
|
||||
this._check("connected");
|
||||
if (Date.now() - this._lastHeartbeat > 2000 * this._heartbeatInterval) {
|
||||
if (Date.now() - this._lastHeartbeat! > 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(4008, "Heartbeat timeout");
|
||||
this._socket!.close(4008, "Heartbeat timeout");
|
||||
} else {
|
||||
this._socket.terminate();
|
||||
this._socket!.terminate();
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -223,7 +228,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
this._lastHeartbeat = Date.now();
|
||||
this._heartbeatId = setInterval(() => {
|
||||
this._doHeartbeat();
|
||||
}, this._heartbeatInterval * 1000);
|
||||
}, this._heartbeatInterval! * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,7 +249,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
*
|
||||
* @param message - Message to send.
|
||||
*/
|
||||
send(message: libData.Message) {
|
||||
send(message: ReliableMessages) {
|
||||
if (!["connected", "resuming"].includes(this._state)) {
|
||||
throw new libErrors.SessionLost("No session");
|
||||
}
|
||||
@@ -256,7 +261,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
}
|
||||
|
||||
_sendInternal(message: libData.Message) {
|
||||
this._socket.send(JSON.stringify(message));
|
||||
this._socket!.send(JSON.stringify(message));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -280,9 +285,9 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
}
|
||||
|
||||
this.setClosing();
|
||||
this.send(new libData.MessageDisconnect("prepare"));
|
||||
this._sendInternal(new libData.MessageDisconnect("prepare"));
|
||||
|
||||
let timeout: NodeJS.Timeout;
|
||||
let timeout: NodeJS.Timeout | undefined;
|
||||
let waitTimeout = new Promise(resolve => { timeout = setTimeout(resolve, 10000); }); // Make Configurable?
|
||||
try {
|
||||
await Promise.race([
|
||||
@@ -326,7 +331,7 @@ export abstract class WebSocketBaseConnector extends BaseConnector {
|
||||
* @extends module:lib.WebSocketBaseConnector
|
||||
*/
|
||||
export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
_reconnectId: NodeJS.Timeout | null = null;
|
||||
_reconnectId?: NodeJS.Timeout;
|
||||
_sessionToken: string | null = null;
|
||||
_sessionTimeout: number | null = null;
|
||||
_startedResuming: number | null = null;
|
||||
@@ -337,7 +342,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
maxReconnectDelay: number,
|
||||
protected _tlsCa = null
|
||||
) {
|
||||
super(undefined, new libData.Address(libData.Address.controller, 0));
|
||||
super(undefined as any, new libData.Address(libData.Address.controller, 0));
|
||||
this._backoff = new ExponentialBackoff({ max: maxReconnectDelay });
|
||||
|
||||
// The following states are used in the client connector
|
||||
@@ -349,21 +354,21 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
|
||||
_reset() {
|
||||
clearTimeout(this._reconnectId);
|
||||
this._reconnectId = null;
|
||||
this._reconnectId = undefined;
|
||||
this._sessionToken = null;
|
||||
this._sessionTimeout = null;
|
||||
this._startedResuming = null;
|
||||
super._reset();
|
||||
this.src = undefined;
|
||||
this.src = undefined as any;
|
||||
}
|
||||
|
||||
_invalidate() {
|
||||
assert(this._reconnectId === null);
|
||||
assert(this._reconnectId === undefined);
|
||||
this._sessionToken = null;
|
||||
this._sessionTimeout = null;
|
||||
this._startedResuming = null;
|
||||
super._invalidate();
|
||||
this.src = undefined;
|
||||
this.src = undefined as any;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -394,7 +399,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
|
||||
this._closing = true;
|
||||
if (this._state === "connected" || this._socket) {
|
||||
this._socket.close(code, reason);
|
||||
this._socket!.close(code, reason);
|
||||
await events.once(this, "close");
|
||||
|
||||
} else {
|
||||
@@ -421,7 +426,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
}
|
||||
|
||||
if (this._socket) {
|
||||
this._socket.close(1000, "Connector closing");
|
||||
this._socket!.close(1000, "Connector closing");
|
||||
|
||||
} else {
|
||||
this._reset();
|
||||
@@ -471,14 +476,14 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
throw new Error("Cannot reconnect while socket is open");
|
||||
}
|
||||
|
||||
if (this._reconnectId !== null) {
|
||||
if (this._reconnectId !== undefined) {
|
||||
logger.error("Unexpected double call to reconnect");
|
||||
}
|
||||
|
||||
let delay = this._backoff.delay();
|
||||
if (
|
||||
this._state === "resuming"
|
||||
&& this._startedResuming + this._sessionTimeout * 1000 < Date.now() + delay
|
||||
&& this._startedResuming! + this._sessionTimeout! * 1000 < Date.now() + delay
|
||||
) {
|
||||
logger.error("Connector | Session timed out trying to resume");
|
||||
this._reset();
|
||||
@@ -494,14 +499,13 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
`Connector | waiting ${(Math.round(delay / 10) / 100)} seconds for reconnect`
|
||||
);
|
||||
this._reconnectId = setTimeout(() => {
|
||||
this._reconnectId = null;
|
||||
this._reconnectId = undefined;
|
||||
this._doConnect();
|
||||
}, delay);
|
||||
}
|
||||
|
||||
_attachSocketHandlers() {
|
||||
// TODO type event
|
||||
this._socket.onclose = (event: any) => {
|
||||
this._socket!.onclose = (event) => {
|
||||
const previousState = this._state;
|
||||
|
||||
// Authentication failed
|
||||
@@ -544,7 +548,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
}
|
||||
};
|
||||
|
||||
this._socket.onerror = (event: any) => {
|
||||
this._socket!.onerror = (event) => {
|
||||
// It's assumed that close is always called by ws
|
||||
let code = !event.error ? "" : `, code: ${event.error.code}`;
|
||||
let message = `Connector | Socket error: ${event.message || "unknown error"}${code}`;
|
||||
@@ -568,13 +572,13 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
}
|
||||
};
|
||||
|
||||
this._socket.onopen = () => {
|
||||
this._socket!.onopen = () => {
|
||||
logger.verbose("Connector | Open");
|
||||
};
|
||||
|
||||
// Handle messages
|
||||
this._socket.onmessage = (event: any) => {
|
||||
let message = this._parseMessage(event.data);
|
||||
this._socket!.onmessage = (event) => {
|
||||
let message = this._parseMessage(event.data as string);
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -7,13 +7,42 @@ import { dataClasses } from "./messages";
|
||||
import { BaseConnector, WebSocketBaseConnector } from "./connectors";
|
||||
import { strict as assert } from "assert";
|
||||
import type { PluginInfo } from "../plugin";
|
||||
import type { User } from "../users";
|
||||
import type { AddressType, JSONDeserialisable, Message, MessageRequest, MessageEvent } from "../data";
|
||||
|
||||
export interface Request<Req, Res> {
|
||||
constructor: Partial<JSONDeserialisable<Request<Req, Res>>> & {
|
||||
new (...args: any): Request<Req, Res>,
|
||||
name: string,
|
||||
type: "request";
|
||||
src: AddressType | readonly AddressType[];
|
||||
dst: AddressType | readonly AddressType[];
|
||||
permission?: null | string | ((user: User, message: MessageRequest) => void);
|
||||
plugin?: string;
|
||||
Response?: JSONDeserialisable<Res>,
|
||||
}
|
||||
}
|
||||
export type RequestClass<Req, Res> = Request<Req, Res>["constructor"];
|
||||
|
||||
export interface Event<T> {
|
||||
constructor: Partial<JSONDeserialisable<Event<T>>> & {
|
||||
new (...args: any): Event<T>,
|
||||
name: string,
|
||||
type: "event";
|
||||
src: AddressType | readonly AddressType[];
|
||||
dst: AddressType | readonly AddressType[];
|
||||
permission?: null | string | ((user: User, message: MessageEvent) => void);
|
||||
plugin?: string;
|
||||
}
|
||||
}
|
||||
export type EventClass<T> = Event<T>["constructor"];
|
||||
|
||||
interface RequestEntry {
|
||||
Request: typeof libData.Request;
|
||||
Request: RequestClass<unknown, unknown>;
|
||||
name: string,
|
||||
allowedSrcTypes: Set<number>;
|
||||
allowedDstTypes: Set<number>;
|
||||
requestFromJSON: (json: any) => libData.Request;
|
||||
requestFromJSON: (json: any) => Request<unknown, unknown>;
|
||||
Response?: any;
|
||||
responseFromJSON: (json: any) => any;
|
||||
}
|
||||
@@ -32,14 +61,18 @@ interface ForwardedRequest {
|
||||
}
|
||||
|
||||
interface EventEntry {
|
||||
Event: typeof libData.Event;
|
||||
Event: EventClass<unknown>;
|
||||
name: string,
|
||||
allowedSrcTypes: Set<number>;
|
||||
allowedDstTypes: Set<number>;
|
||||
eventFromJSON: (json: any) => libData.Event;
|
||||
eventFromJSON: (json: any) => Event<unknown>;
|
||||
}
|
||||
type RequestHandler<Req, Res> = (request: Request<Req, Res>, src: libData.Address, dst: libData.Address) => any;
|
||||
type EventHandler<T> = (event: Event<T>, src: libData.Address, dst: libData.Address) => any;
|
||||
|
||||
interface Router {
|
||||
forwardMessage(origin: Link, message: Message, fallback: boolean): boolean,
|
||||
}
|
||||
type RequestHandler = (request: libData.Request, src: libData.Address, dst: libData.Address) => any;
|
||||
type EventHandler = (request: libData.Event, src: libData.Address, dst: libData.Address) => any;
|
||||
|
||||
// Some definitions for the terminology used here:
|
||||
// link: Either side of a controller - client connection
|
||||
@@ -52,7 +85,7 @@ type EventHandler = (request: libData.Event, src: libData.Address, dst: libData.
|
||||
* Common interface for server and client connections
|
||||
*/
|
||||
export class Link {
|
||||
router = undefined;
|
||||
router?: Router = undefined;
|
||||
validateSent = true;
|
||||
|
||||
_requestHandlers = new Map();
|
||||
@@ -66,7 +99,6 @@ export class Link {
|
||||
constructor(
|
||||
public connector: BaseConnector
|
||||
) {
|
||||
// @ts-ignore: TODO Remove when lib/data is migrated to ts
|
||||
this.handle(libData.PingRequest, () => {});
|
||||
|
||||
// Process messages received by the connector
|
||||
@@ -207,7 +239,7 @@ export class Link {
|
||||
throw new libErrors.InvalidMessage("Message src may not be broadcast");
|
||||
}
|
||||
this.validateIngress(message);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (message.type === "request") {
|
||||
this.connector.sendResponseError(new libData.ResponseError(err.message, err.code), message.src);
|
||||
}
|
||||
@@ -314,7 +346,7 @@ export class Link {
|
||||
_processRequest(
|
||||
message: libData.MessageRequest,
|
||||
entry: RequestEntry,
|
||||
handler: RequestHandler,
|
||||
handler: RequestHandler<unknown, unknown>,
|
||||
spoofedSrc?: libData.Address
|
||||
) {
|
||||
if (!handler) {
|
||||
@@ -327,7 +359,7 @@ export class Link {
|
||||
let response: any;
|
||||
try {
|
||||
response = handler(entry.requestFromJSON(message.data), message.src, message.dst);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.errors) {
|
||||
logger.error(JSON.stringify(err.errors, null, 4));
|
||||
}
|
||||
@@ -366,7 +398,7 @@ export class Link {
|
||||
this.connector.sendResponseError(
|
||||
new libData.ResponseError(err.message, err.code, err.stack), message.src, spoofedSrc
|
||||
);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
logger.error(`Unexpected error sending error response for ${message.name}:\n${err.stack}`);
|
||||
}
|
||||
}
|
||||
@@ -374,7 +406,7 @@ export class Link {
|
||||
}
|
||||
|
||||
_processResponse(message: libData.MessageResponse) {
|
||||
let pending = this._pendingRequests.get(message.dst.requestId);
|
||||
let pending = this._pendingRequests.get(message.dst.requestId!);
|
||||
if (!pending) {
|
||||
throw new libErrors.InvalidMessage(
|
||||
`Received response ${message.dst.requestId} without a pending request`
|
||||
@@ -387,14 +419,14 @@ export class Link {
|
||||
|
||||
try {
|
||||
pending.resolve(pending.request.responseFromJSON(message.data));
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
// An invalid response object was likely received
|
||||
pending.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
_processResponseError(message: libData.MessageResponseError) {
|
||||
let pending = this._pendingRequests.get(message.dst.requestId);
|
||||
let pending = this._pendingRequests.get(message.dst.requestId!);
|
||||
if (!pending) {
|
||||
throw new libErrors.InvalidMessage(
|
||||
`Received error response ${message.dst.requestId} without a pending request`
|
||||
@@ -441,10 +473,10 @@ export class Link {
|
||||
* Promise that resolves to the response if a request was sent or
|
||||
* undefined if it was an event.
|
||||
*/
|
||||
send(requestOrEvent: libData.Request): Promise<unknown>;
|
||||
send(requestOrEvent: libData.Event): void;
|
||||
send(requestOrEvent: libData.Request | libData.Event): Promise<unknown> | void {
|
||||
return this.sendTo(this.connector.dst, requestOrEvent);
|
||||
send<Req, Res = void>(requestOrEvent: Request<Req, Res>): Promise<Res>;
|
||||
send<T>(requestOrEvent: Event<T>): void;
|
||||
send(requestOrEvent: Request<unknown, unknown> | Event<unknown>): Promise<unknown> | void {
|
||||
return this.sendTo(this.connector.dst, requestOrEvent as any);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -456,26 +488,26 @@ export class Link {
|
||||
* Promise that resolves to the response if a request was sent or
|
||||
* undefined if it was an event.
|
||||
*/
|
||||
sendTo(destination: libData.AddressShorthand, requestOrEvent: libData.Request): Promise<unknown>;
|
||||
sendTo(destination: libData.AddressShorthand, requestOrEvent: libData.Event): void;
|
||||
sendTo<Req, Res = void>(destination: libData.AddressShorthand, requestOrEvent: Request<Req, Res>): Promise<Res>;
|
||||
sendTo<T>(destination: libData.AddressShorthand, requestOrEvent: Event<T>): void;
|
||||
sendTo(
|
||||
destination: libData.AddressShorthand,
|
||||
requestOrEvent: libData.Request | libData.Event,
|
||||
requestOrEvent: Request<unknown, unknown> | Event<unknown>,
|
||||
): Promise<unknown> | void {
|
||||
let dst = libData.Address.fromShorthand(destination);
|
||||
|
||||
// TODO investigate if these types can be inferred
|
||||
if ((requestOrEvent.constructor as any).type === "request") {
|
||||
return this.sendRequest(requestOrEvent, dst);
|
||||
if (requestOrEvent.constructor.type === "request") {
|
||||
return this.sendRequest(requestOrEvent as Request<unknown, unknown>, dst);
|
||||
}
|
||||
if ((requestOrEvent.constructor as any).type === "event") {
|
||||
return this.sendEvent(requestOrEvent, dst);
|
||||
if (requestOrEvent.constructor.type === "event") {
|
||||
return this.sendEvent(requestOrEvent as Event<unknown>, dst);
|
||||
}
|
||||
throw Error(`Expected request or event but got type ${(requestOrEvent.constructor as any).type}`);
|
||||
}
|
||||
|
||||
sendRequest(request: libData.Request, dst: libData.Address) {
|
||||
let entry = Link._requestsByClass.get(request.constructor as typeof libData.Request);
|
||||
sendRequest<Req, Res>(request: Request<Req, Res>, dst: libData.Address) {
|
||||
let entry = Link._requestsByClass.get(request.constructor as RequestClass<unknown, unknown>);
|
||||
if (!entry) {
|
||||
throw new Error(`Attempt to send unregistered Request ${request.constructor.name}`);
|
||||
}
|
||||
@@ -492,7 +524,7 @@ export class Link {
|
||||
let requestId = this._nextRequestId;
|
||||
this._nextRequestId += 1;
|
||||
this._pendingRequests.set(
|
||||
requestId, { request: entry, promise, resolve, reject, dst, }
|
||||
requestId, { request: entry, promise, resolve: resolve!, reject: reject!, dst, }
|
||||
);
|
||||
this.connector.sendRequest(request, requestId, dst);
|
||||
return promise;
|
||||
@@ -508,8 +540,8 @@ export class Link {
|
||||
this.connector.send(message);
|
||||
}
|
||||
|
||||
sendEvent(event: libData.Event, dst: libData.Address) {
|
||||
let entry = Link._eventsByClass.get(event.constructor as typeof libData.Event);
|
||||
sendEvent<T>(event: Event<T>, dst: libData.Address) {
|
||||
let entry = Link._eventsByClass.get(event.constructor as EventClass<unknown>);
|
||||
if (!entry) {
|
||||
throw new Error(`Attempt to send unregistered Event ${event.constructor.name}`);
|
||||
}
|
||||
@@ -520,23 +552,23 @@ export class Link {
|
||||
this.connector.sendEvent(event, dst);
|
||||
}
|
||||
|
||||
handle(Class: typeof libData.Request, handler: RequestHandler): void;
|
||||
handle(Class: typeof libData.Event, handler: EventHandler): void;
|
||||
handle<Req, Res>(Class: RequestClass<Req, Res>, handler: RequestHandler<Req, Res>): void;
|
||||
handle<T>(Class: EventClass<T>, handler: EventHandler<T>): void;
|
||||
handle(
|
||||
Class: typeof libData.Request | typeof libData.Event,
|
||||
handler: RequestHandler | EventHandler,
|
||||
Class: RequestClass<unknown, unknown> | EventClass<unknown>,
|
||||
handler: RequestHandler<unknown, unknown> | EventHandler<unknown>,
|
||||
) {
|
||||
if (Class.type === "request") {
|
||||
this.handleRequest(Class, handler);
|
||||
this.handleRequest(Class, handler as RequestHandler<unknown, unknown>);
|
||||
} else if (Class.type === "event") {
|
||||
this.handleEvent(Class, handler);
|
||||
this.handleEvent(Class, handler as EventHandler<unknown>);
|
||||
} else {
|
||||
throw new Error(`Class ${(Class as any).name} has unrecognized type ${(Class as any).type}`);
|
||||
}
|
||||
}
|
||||
|
||||
handleRequest(Request: typeof libData.Request, handler: RequestHandler) {
|
||||
let entry = Link._requestsByClass.get(Request);
|
||||
handleRequest<Req, Res>(Request: RequestClass<Req, Res>, handler: RequestHandler<Req, Res>) {
|
||||
let entry = Link._requestsByClass.get(Request as RequestClass<unknown, unknown>);
|
||||
if (!entry) {
|
||||
throw new Error(`Unregistered Request class ${Request.name}`);
|
||||
}
|
||||
@@ -546,8 +578,8 @@ export class Link {
|
||||
this._requestHandlers.set(Request, handler);
|
||||
}
|
||||
|
||||
fallbackRequest(Request: typeof libData.Request, handler: RequestHandler) {
|
||||
let entry = Link._requestsByClass.get(Request);
|
||||
fallbackRequest<Req, Res>(Request: RequestClass<Req, Res>, handler: RequestHandler<Req, Res>) {
|
||||
let entry = Link._requestsByClass.get(Request as RequestClass<unknown, unknown>);
|
||||
if (!entry) {
|
||||
throw new Error(`Unregistered Request class ${Request.name}`);
|
||||
}
|
||||
@@ -557,8 +589,8 @@ export class Link {
|
||||
this._requestFallbacks.set(Request, handler);
|
||||
}
|
||||
|
||||
handleEvent(Event: typeof libData.Event, handler: EventHandler) {
|
||||
let entry = Link._eventsByClass.get(Event);
|
||||
handleEvent<T>(Event: EventClass<T>, handler: EventHandler<T>) {
|
||||
let entry = Link._eventsByClass.get(Event as EventClass<unknown>);
|
||||
if (!entry) {
|
||||
throw new Error(`Unregistered Event class ${Event.name}`);
|
||||
}
|
||||
@@ -568,8 +600,8 @@ export class Link {
|
||||
this._eventHandlers.set(Event, handler);
|
||||
}
|
||||
|
||||
snoopEvent(Event: typeof libData.Event, handler: EventHandler) {
|
||||
let entry = Link._eventsByClass.get(Event);
|
||||
snoopEvent<T>(Event: EventClass<T>, handler: EventHandler<T>) {
|
||||
let entry = Link._eventsByClass.get(Event as EventClass<unknown>);
|
||||
if (!entry) {
|
||||
throw new Error(`Unregistered Event class ${Event.name}`);
|
||||
}
|
||||
@@ -579,7 +611,9 @@ export class Link {
|
||||
this._eventSnoopers.set(Event, handler);
|
||||
}
|
||||
|
||||
static register(Class: typeof libData.Request | typeof libData.Event) {
|
||||
static register<Req, Res>(Class: RequestClass<Req, Res>): void;
|
||||
static register<T>(Class: EventClass<T>): void;
|
||||
static register(Class: RequestClass<unknown, unknown> | EventClass<unknown>) {
|
||||
if (Class.type === "request") {
|
||||
this.registerRequest(Class);
|
||||
} else if (Class.type === "event") {
|
||||
@@ -589,7 +623,7 @@ export class Link {
|
||||
}
|
||||
}
|
||||
|
||||
static requestFromJSON(Request: typeof libData.Request, name: string) {
|
||||
static requestFromJSON<Req, Res>(Request: RequestClass<Req, Res>, name: string): (json: any) => Request<Req, Res> {
|
||||
if (Request.fromJSON) {
|
||||
if (!Request.jsonSchema) {
|
||||
throw new Error(`Request ${name} has static fromJSON but is missing static jsonSchema`);
|
||||
@@ -599,7 +633,7 @@ export class Link {
|
||||
if (!validate(json)) {
|
||||
throw new libErrors.InvalidMessage(`Request ${name} failed validation`, validate.errors);
|
||||
}
|
||||
return Request.fromJSON(json);
|
||||
return Request.fromJSON!(json);
|
||||
};
|
||||
}
|
||||
if (Request.jsonSchema) {
|
||||
@@ -608,7 +642,7 @@ export class Link {
|
||||
return () => new Request();
|
||||
}
|
||||
|
||||
static responseFromJSON(Response: libData.Serialisable, name: string) {
|
||||
static responseFromJSON<T>(Response: JSONDeserialisable<T>, name: string) {
|
||||
if (!Response.jsonSchema) {
|
||||
throw new Error(`Response for Request ${name} is missing static jsonSchema`);
|
||||
}
|
||||
@@ -627,7 +661,11 @@ export class Link {
|
||||
};
|
||||
}
|
||||
|
||||
static allowedTypes(types: libData.AddressType | libData.AddressType[], name: string, side: "src" | "dst") {
|
||||
static allowedTypes(
|
||||
types: libData.AddressType | readonly libData.AddressType[],
|
||||
name: string,
|
||||
side: "src" | "dst"
|
||||
) {
|
||||
if (types === undefined) {
|
||||
throw new Error(`Missing ${side} specification in ${name}`);
|
||||
}
|
||||
@@ -651,9 +689,9 @@ export class Link {
|
||||
}
|
||||
|
||||
static _requestsByName = new Map<string, RequestEntry>();
|
||||
static _requestsByClass = new Map<typeof libData.Request, RequestEntry>();
|
||||
static _requestsByClass = new Map<RequestClass<unknown, unknown>, RequestEntry>();
|
||||
|
||||
static registerRequest(Request: typeof libData.Request) {
|
||||
static registerRequest(Request: RequestClass<unknown, unknown>) {
|
||||
const name = Request.plugin ? `${Request.plugin}:${Request.name}` : Request.name;
|
||||
if (this._requestsByName.has(name)) {
|
||||
throw new Error(`Request ${name} is already registered`);
|
||||
@@ -685,7 +723,7 @@ export class Link {
|
||||
this._requestsByClass.set(Request, entry);
|
||||
}
|
||||
|
||||
static eventFromJSON(Event: typeof libData.Event, name: string) {
|
||||
static eventFromJSON<T>(Event: EventClass<T>, name: string) {
|
||||
if (Event.fromJSON) {
|
||||
if (!Event.jsonSchema) {
|
||||
throw new Error(`Event ${name} has static fromJSON but is missing static jsonSchema`);
|
||||
@@ -695,7 +733,7 @@ export class Link {
|
||||
if (!validate(json)) {
|
||||
throw new libErrors.InvalidMessage(`Event ${name} failed validation`, validate.errors);
|
||||
}
|
||||
return Event.fromJSON(json);
|
||||
return Event.fromJSON!(json);
|
||||
};
|
||||
}
|
||||
if (Event.jsonSchema) {
|
||||
@@ -705,16 +743,16 @@ export class Link {
|
||||
}
|
||||
|
||||
static _eventsByName = new Map<string, EventEntry>();
|
||||
static _eventsByClass = new Map<typeof libData.Event, EventEntry>();
|
||||
static _eventsByClass = new Map<EventClass<unknown>, EventEntry>();
|
||||
|
||||
static registerEvent(Event: typeof libData.Event) {
|
||||
static registerEvent<T>(Event: EventClass<T>) {
|
||||
const name = Event.plugin ? `${Event.plugin}:${Event.name}` : Event.name;
|
||||
if (this._eventsByName.has(name)) {
|
||||
throw new Error(`Event ${name} is already registered`);
|
||||
}
|
||||
|
||||
let entry = {
|
||||
Event,
|
||||
let entry: EventEntry = {
|
||||
Event: Event as EventClass<unknown>,
|
||||
name,
|
||||
eventFromJSON: this.eventFromJSON(Event, name),
|
||||
allowedSrcTypes: this.allowedTypes(Event.src, name, "src"),
|
||||
@@ -729,13 +767,12 @@ export class Link {
|
||||
}
|
||||
|
||||
this._eventsByName.set(name, entry);
|
||||
this._eventsByClass.set(Event, entry);
|
||||
this._eventsByClass.set(Event as EventClass<unknown>, entry);
|
||||
}
|
||||
}
|
||||
|
||||
for (let Class of dataClasses) {
|
||||
// @ts-ignore: TODO Remove when lib/data is migrated to ts
|
||||
Link.register(Class);
|
||||
Link.register(Class as RequestClass<unknown, unknown>);
|
||||
}
|
||||
|
||||
export function registerPluginMessages(pluginInfos: PluginInfo[]) {
|
||||
|
||||
@@ -5,6 +5,7 @@ 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 type { RequestClass, EventClass } from "./link";
|
||||
|
||||
/**
|
||||
* Event and Request payloads registered with the Link class. Used to decode
|
||||
@@ -12,7 +13,7 @@ import * as user from "../data/messages_user";
|
||||
* their proper classes.
|
||||
* @internal
|
||||
*/
|
||||
export const dataClasses = [
|
||||
export const dataClasses: (RequestClass<unknown, unknown> | EventClass<unknown>)[] = [
|
||||
core.PingRequest,
|
||||
|
||||
controller.ControllerConfigGetRequest,
|
||||
|
||||
@@ -130,7 +130,7 @@ export interface LogFilter {
|
||||
export function logFilter({ all, controller, hostIds, instanceIds, maxLevel }: LogFilter) {
|
||||
return (info: any) => {
|
||||
// Note: reversed to filter out undefined levels
|
||||
if (maxLevel && !(levels[info.level] <= levels[maxLevel])) {
|
||||
if (maxLevel && !((levels as any)[info.level] <= levels[maxLevel])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -256,7 +256,12 @@ export class LogIndex {
|
||||
serialize() {
|
||||
let serialized = {
|
||||
version: logIndexVersion,
|
||||
files: {},
|
||||
files: {} as Record<string, {
|
||||
levels: string[],
|
||||
controller: boolean,
|
||||
hostIds: number[],
|
||||
instanceIds: number[],
|
||||
}>,
|
||||
};
|
||||
|
||||
for (let [file, entry] of this.index) {
|
||||
@@ -285,7 +290,7 @@ export class LogIndex {
|
||||
try {
|
||||
let content = await fs.readFile(path.join(logDirectory, "index.json"));
|
||||
return new LogIndex(logDirectory, JSON.parse(content.toString()));
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
if (err.code !== "ENOENT") {
|
||||
logger.warn(`Failed to load ${path.join(logDirectory, "index.json")}: ${err}`);
|
||||
}
|
||||
@@ -369,7 +374,7 @@ export class LogIndex {
|
||||
* true if the file may contain entries included by the filter.
|
||||
*/
|
||||
filterIncludesFile(file: string, { maxLevel, all, controller, instanceIds, hostIds }: LogFilter) {
|
||||
let entry = this.index.get(file);
|
||||
const entry = this.index.get(file);
|
||||
if (!entry) {
|
||||
return true;
|
||||
}
|
||||
@@ -412,7 +417,7 @@ export interface QueryLogFilter {
|
||||
* Return entries in ascending ("asc") date order or desceding ("desc")
|
||||
* date order. Defaults to "asc".
|
||||
*/
|
||||
order: "asc" | "desc";
|
||||
order?: "asc" | "desc";
|
||||
/**
|
||||
* Maximum log level to include. Higher levels are more verbose.
|
||||
*/
|
||||
@@ -461,7 +466,7 @@ export async function queryLog(logDirectory: string, filter: QueryLogFilter, ind
|
||||
}
|
||||
|
||||
const includeEntry = logFilter(filter);
|
||||
let log = [];
|
||||
let log: object[] = [];
|
||||
for (let file of files) {
|
||||
if (index && !index.filterIncludesFile(file, filter)) {
|
||||
continue;
|
||||
@@ -485,7 +490,7 @@ export async function queryLog(logDirectory: string, filter: QueryLogFilter, ind
|
||||
}
|
||||
if (includeEntry(info)) {
|
||||
log.push(info);
|
||||
if (log.length >= filter.limit) {
|
||||
if (log.length >= Number(filter.limit)) {
|
||||
lineStream.destroy();
|
||||
fileStream.destroy();
|
||||
}
|
||||
@@ -494,13 +499,13 @@ export async function queryLog(logDirectory: string, filter: QueryLogFilter, ind
|
||||
fileStream.pipe(lineStream);
|
||||
try {
|
||||
await finished(lineStream);
|
||||
} catch (err) {
|
||||
if (log.length < filter.limit || err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
|
||||
} catch (err: any) {
|
||||
if (log.length < Number(filter.limit) || err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
if (log.length >= filter.limit) {
|
||||
if (log.length >= Number(filter.limit)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,11 +297,11 @@ export class BaseInstancePlugin {
|
||||
async _sendPendingRconMessages() {
|
||||
this._sendingRconMessages = true;
|
||||
while (this._pendingRconMessages.length) {
|
||||
let task = this._pendingRconMessages.shift();
|
||||
let task = this._pendingRconMessages.shift()!;
|
||||
try {
|
||||
let result = await this.sendRcon(task.message, task.expectEmpty);
|
||||
task.resolve(result);
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
task.reject(err);
|
||||
}
|
||||
}
|
||||
@@ -820,7 +820,7 @@ export async function invokeHook(plugins: Map<string, BasePlugin>, hook: string,
|
||||
// Use an object to detect if the hook failed on timeout or tried to return a value looking like an error
|
||||
const timeout = {};
|
||||
let result = await libHelpers.timeout(
|
||||
plugin[hook](...args),
|
||||
(plugin as any)[hook](...args),
|
||||
15000,
|
||||
timeout
|
||||
);
|
||||
@@ -829,7 +829,7 @@ export async function invokeHook(plugins: Map<string, BasePlugin>, hook: string,
|
||||
} else if (result !== undefined) {
|
||||
results.push(result);
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
plugin.logger.error(`Ignoring error from plugin ${name} in ${hook}:\n${err.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export async function loadPluginInfos(pluginList: Map<string, string>) {
|
||||
pluginInfo = require(path.posix.join(pluginPath, "info"));
|
||||
pluginPackage = require(path.posix.join(pluginPath, "package.json"));
|
||||
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
throw new libErrors.PluginError(pluginName, err);
|
||||
}
|
||||
|
||||
|
||||
@@ -307,11 +307,11 @@ function removeMatchingLabels(mapping: Map<string, unknown>, labels: Record<stri
|
||||
* @extends Collector
|
||||
*/
|
||||
export class LabeledCollector<Child> extends Collector {
|
||||
callback: (collector: LabeledCollector<Child>) => void | Promise<void>;
|
||||
callback: ((collector: any) => (void | Promise<void>)) | undefined;
|
||||
metric: Metric;
|
||||
|
||||
private _children: Map<string, Child>;
|
||||
private _childClass: { new(collector: LabeledCollector<Child>, key: string): Child };
|
||||
private _childClass: { new(collector: any, key: string): Child };
|
||||
|
||||
/**
|
||||
* Create optionally labeled collector
|
||||
@@ -343,9 +343,9 @@ export class LabeledCollector<Child> extends Collector {
|
||||
labels?: string[],
|
||||
_reservedLabels?: string[],
|
||||
register?: boolean,
|
||||
callback?: (collector: LabeledCollector<Child>) => void | Promise<void>,
|
||||
callback?: (collector: any) => (void | Promise<void>),
|
||||
},
|
||||
childClass: { new(collector: LabeledCollector<Child>, key: string): Child }
|
||||
childClass: { new(collector: any, key: string): Child }
|
||||
) {
|
||||
const { labels = [], _reservedLabels = [], register = true, callback, ...rest } = options;
|
||||
|
||||
@@ -485,7 +485,7 @@ export class ValueCollector<Child extends { get(): number }> extends LabeledColl
|
||||
labels?: string[],
|
||||
_reservedLabels?: string[],
|
||||
register?: boolean,
|
||||
callback?: (collector: ValueCollector<Child>) => void | Promise<void>,
|
||||
callback?: (collector: any) => (void | Promise<void>),
|
||||
},
|
||||
childClass: { new(collector: ValueCollector<Child>, key: string): Child }
|
||||
) {
|
||||
@@ -507,12 +507,13 @@ export class ValueCollector<Child extends { get(): number }> extends LabeledColl
|
||||
* @returns value stored.
|
||||
*/
|
||||
get() {
|
||||
return this._defaultChild.get();
|
||||
return this._defaultChild!.get();
|
||||
}
|
||||
|
||||
remove(...labels: LabelValues) {
|
||||
let key = super.remove(...labels);
|
||||
this._values.delete(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
removeAll(labels: Record<string, string>) {
|
||||
@@ -546,7 +547,7 @@ class ValueCollectorChild {
|
||||
* @returns value stored.
|
||||
*/
|
||||
get() {
|
||||
return this._values.get(this._key);
|
||||
return this._values.get(this._key)!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +566,7 @@ class CounterChild extends ValueCollectorChild {
|
||||
throw new Error("Expected value to be a positive number");
|
||||
}
|
||||
|
||||
this._values.set(this._key, this._values.get(this._key) + value);
|
||||
this._values.set(this._key, this._values.get(this._key)! + value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,7 +674,7 @@ export class Counter extends ValueCollector<CounterChild> {
|
||||
options: {
|
||||
labels?: string[],
|
||||
register?: boolean,
|
||||
callback?: (collector: Counter) => void | Promise<void>,
|
||||
callback?: (collector: Collector) => (void | Promise<void>),
|
||||
} = {},
|
||||
) {
|
||||
super("counter", name, help, options, CounterChild);
|
||||
@@ -686,7 +687,7 @@ export class Counter extends ValueCollector<CounterChild> {
|
||||
* @param value - Positive number to increment by.
|
||||
*/
|
||||
inc(value = 1) {
|
||||
this._defaultChild.inc(value);
|
||||
this._defaultChild!.inc(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,7 +702,7 @@ class GaugeChild extends ValueCollectorChild {
|
||||
* @param value - number to increment by.
|
||||
*/
|
||||
inc(value = 1) {
|
||||
this._values.set(this._key, this._values.get(this._key) + value);
|
||||
this._values.set(this._key, this._values.get(this._key)! + value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -710,7 +711,7 @@ class GaugeChild extends ValueCollectorChild {
|
||||
* @param value - number to decrease by.
|
||||
*/
|
||||
dec(value = 1) {
|
||||
this._values.set(this._key, this._values.get(this._key) - value);
|
||||
this._values.set(this._key, this._values.get(this._key)! - value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -869,7 +870,7 @@ export class Gauge extends ValueCollector<GaugeChild> {
|
||||
options: {
|
||||
labels?: string[],
|
||||
register?: boolean,
|
||||
callback?: (collector: Gauge) => void | Promise<void>,
|
||||
callback?: (collector: Gauge) => (void | Promise<void>),
|
||||
} = {},
|
||||
) {
|
||||
super("gauge", name, help, options, GaugeChild);
|
||||
@@ -882,7 +883,7 @@ export class Gauge extends ValueCollector<GaugeChild> {
|
||||
* @param value - number to increment by.
|
||||
*/
|
||||
inc(value = 1) {
|
||||
this._defaultChild.inc(value);
|
||||
this._defaultChild!.inc(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -892,7 +893,7 @@ export class Gauge extends ValueCollector<GaugeChild> {
|
||||
* @param value - number to decrease by.
|
||||
*/
|
||||
dec(value = 1) {
|
||||
this._defaultChild.dec(value);
|
||||
this._defaultChild!.dec(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -902,7 +903,7 @@ export class Gauge extends ValueCollector<GaugeChild> {
|
||||
* @param value - number to set gauge to.
|
||||
*/
|
||||
set(value: number) {
|
||||
this._defaultChild.set(value);
|
||||
this._defaultChild!.set(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -911,7 +912,7 @@ export class Gauge extends ValueCollector<GaugeChild> {
|
||||
* Note: Only works if this is an unlabeled collector.
|
||||
*/
|
||||
setToCurrentTime() {
|
||||
this._defaultChild.setToCurrentTime();
|
||||
this._defaultChild!.setToCurrentTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -923,7 +924,7 @@ export class Gauge extends ValueCollector<GaugeChild> {
|
||||
* seconds from when the timer was started
|
||||
*/
|
||||
startTimer() {
|
||||
return this._defaultChild.startTimer();
|
||||
return this._defaultChild!.startTimer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,8 +965,8 @@ class SummaryChild {
|
||||
* @param value - number to count into summary.
|
||||
*/
|
||||
observe(value: number) {
|
||||
this._sumValues.set(this._key, this._sumValues.get(this._key) + value);
|
||||
this._countValues.set(this._key, this._countValues.get(this._key) + 1);
|
||||
this._sumValues.set(this._key, this._sumValues.get(this._key)! + value);
|
||||
this._countValues.set(this._key, this._countValues.get(this._key)! + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1083,7 +1084,7 @@ export class Summary extends LabeledCollector<SummaryChild> {
|
||||
options: {
|
||||
labels?: string[],
|
||||
register?: boolean,
|
||||
callback?: (collector: Summary) => void | Promise<void>,
|
||||
callback?: (collector: Summary) => (void | Promise<void>),
|
||||
} = {},
|
||||
) {
|
||||
super("summary", name, help, options, SummaryChild);
|
||||
@@ -1111,7 +1112,7 @@ export class Summary extends LabeledCollector<SummaryChild> {
|
||||
* @type {number}
|
||||
*/
|
||||
get sum() {
|
||||
return this._defaultChild.sum;
|
||||
return this._defaultChild!.sum;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1121,7 +1122,7 @@ export class Summary extends LabeledCollector<SummaryChild> {
|
||||
* @type {number}
|
||||
*/
|
||||
get count() {
|
||||
return this._defaultChild.count;
|
||||
return this._defaultChild!.count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1131,7 +1132,7 @@ export class Summary extends LabeledCollector<SummaryChild> {
|
||||
* @param value - number to count into histogram buckets.
|
||||
*/
|
||||
observe(value: number) {
|
||||
this._defaultChild.observe(value);
|
||||
this._defaultChild!.observe(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1143,13 +1144,14 @@ export class Summary extends LabeledCollector<SummaryChild> {
|
||||
* when the timer was started into the metric.
|
||||
*/
|
||||
startTimer() {
|
||||
return this._defaultChild.startTimer();
|
||||
return this._defaultChild!.startTimer();
|
||||
}
|
||||
|
||||
remove(...labels: LabelValues) {
|
||||
let key = super.remove(...labels);
|
||||
this._sumValues.delete(key);
|
||||
this._countValues.delete(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
removeAll(labels: Record<string, string>) {
|
||||
@@ -1240,12 +1242,12 @@ class HistogramChild {
|
||||
observe(value: number) {
|
||||
for (let [bound, key] of this._bucketKeys) {
|
||||
if (value <= bound) {
|
||||
this._bucketValues.set(key, this._bucketValues.get(key) + 1);
|
||||
this._bucketValues.set(key, this._bucketValues.get(key)! + 1);
|
||||
}
|
||||
}
|
||||
|
||||
this._sumValues.set(this._key, this._sumValues.get(this._key) + value);
|
||||
this._countValues.set(this._key, this._countValues.get(this._key) + 1);
|
||||
this._sumValues.set(this._key, this._sumValues.get(this._key)! + value);
|
||||
this._countValues.set(this._key, this._countValues.get(this._key)! + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1371,7 +1373,7 @@ export class Histogram extends LabeledCollector<HistogramChild> {
|
||||
buckets?: number[],
|
||||
labels?: string[],
|
||||
register?: boolean,
|
||||
callback?: (collector: Histogram) => void | Promise<void>,
|
||||
callback?: (collector: Histogram) => (void | Promise<void>),
|
||||
} = {},
|
||||
) {
|
||||
// These defaults are taken from the Python Prometheus client
|
||||
@@ -1411,7 +1413,7 @@ export class Histogram extends LabeledCollector<HistogramChild> {
|
||||
* Note: Only available if this is an unlabeled collector.
|
||||
*/
|
||||
get buckets() {
|
||||
return this._defaultChild.buckets;
|
||||
return this._defaultChild!.buckets;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1420,7 +1422,7 @@ export class Histogram extends LabeledCollector<HistogramChild> {
|
||||
* Note: Only available if this is an unlabeled collector.
|
||||
*/
|
||||
get sum() {
|
||||
return this._defaultChild.sum;
|
||||
return this._defaultChild!.sum;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1429,7 +1431,7 @@ export class Histogram extends LabeledCollector<HistogramChild> {
|
||||
* Note: Only available if this is an unlabeled collector.
|
||||
*/
|
||||
get count() {
|
||||
return this._defaultChild.count;
|
||||
return this._defaultChild!.count;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1438,7 +1440,7 @@ export class Histogram extends LabeledCollector<HistogramChild> {
|
||||
* Note: Only works if this is an unlabeled collector.
|
||||
*/
|
||||
observe(value: number) {
|
||||
this._defaultChild.observe(value);
|
||||
this._defaultChild!.observe(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1450,7 +1452,7 @@ export class Histogram extends LabeledCollector<HistogramChild> {
|
||||
* when the timer was started into the metric.
|
||||
*/
|
||||
startTimer() {
|
||||
return this._defaultChild.startTimer();
|
||||
return this._defaultChild!.startTimer();
|
||||
}
|
||||
|
||||
remove(...labels: LabelValues) {
|
||||
@@ -1461,6 +1463,7 @@ export class Histogram extends LabeledCollector<HistogramChild> {
|
||||
}
|
||||
this._sumValues.delete(key);
|
||||
this._countValues.delete(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
removeAll(labels: Record<string, string>) {
|
||||
|
||||
@@ -17,7 +17,7 @@ const ajv = new Ajv({
|
||||
* @returns Validator for the schema.
|
||||
*/
|
||||
export function compile<T>(schema: JSONSchemaType<T>) {
|
||||
if (typeof global !== "object" || !global.lazySchemaCompilation) {
|
||||
if (typeof global !== "object" || !(global as any).lazySchemaCompilation) {
|
||||
return ajv.compile<T>(schema);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export async function handlePluginCommand(
|
||||
pluginList: Map<string, string>,
|
||||
pluginListPath: string
|
||||
) {
|
||||
let command = args._[1];
|
||||
let command = (args._ as string[])[1];
|
||||
|
||||
if (command === "add") {
|
||||
let pluginPath = args.path as string;
|
||||
@@ -61,7 +61,7 @@ export async function handlePluginCommand(
|
||||
try {
|
||||
// eslint-disable-next-line node/global-require
|
||||
pluginInfo = require(path.posix.join(pluginPath, "info"));
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
logger.error(`Unable to import plugin info from ${args.path}:\n${err.stack}`);
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
@@ -132,7 +132,7 @@ export async function handleConfigCommand(
|
||||
instance: libConfig.Config,
|
||||
configPath: string
|
||||
) {
|
||||
let command = args._[1];
|
||||
let command = (args._ as string[])[1];
|
||||
|
||||
if (command === "list") {
|
||||
for (let GroupClass of (instance.constructor as typeof libConfig.Config).groups.values()) {
|
||||
|
||||
@@ -310,10 +310,16 @@ export class User {
|
||||
_calculatePlayerStats() {
|
||||
let playerStats = new PlayerStats();
|
||||
for (let instanceStats of this.instanceStats.values()) {
|
||||
if (!playerStats.lastJoinAt || instanceStats.lastJoinAt > playerStats.lastJoinAt) {
|
||||
if (
|
||||
instanceStats.lastJoinAt
|
||||
&& (!playerStats.lastJoinAt || instanceStats.lastJoinAt > playerStats.lastJoinAt)
|
||||
) {
|
||||
playerStats.lastJoinAt = instanceStats.lastJoinAt;
|
||||
}
|
||||
if (!playerStats.lastLeaveAt || instanceStats.lastLeaveAt > playerStats.lastLeaveAt) {
|
||||
if (
|
||||
instanceStats.lastLeaveAt
|
||||
&& (!playerStats.lastLeaveAt || instanceStats.lastLeaveAt > playerStats.lastLeaveAt)
|
||||
) {
|
||||
playerStats.lastLeaveAt = instanceStats.lastLeaveAt;
|
||||
playerStats.lastLeaveReason = instanceStats.lastLeaveReason;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import type JSZip from "jszip";
|
||||
* @returns name of the root folder.
|
||||
*/
|
||||
export function findRoot(zip: JSZip) {
|
||||
let root = null;
|
||||
let root: undefined | string;
|
||||
zip.forEach((relativePath, file) => {
|
||||
let index = relativePath.indexOf("/");
|
||||
if (index === -1) {
|
||||
@@ -18,14 +18,14 @@ export function findRoot(zip: JSZip) {
|
||||
}
|
||||
|
||||
let pathRoot = relativePath.slice(0, index);
|
||||
if (root === null) {
|
||||
if (root === undefined) {
|
||||
root = pathRoot;
|
||||
} else if (root !== pathRoot) {
|
||||
throw new Error("Zip contains multiple root folders");
|
||||
}
|
||||
});
|
||||
|
||||
if (root === null) {
|
||||
if (root === undefined) {
|
||||
throw new Error("Empty zip file");
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"rootDir": ".",
|
||||
"outDir": "dist",
|
||||
"composite": false,
|
||||
"strict": false,
|
||||
"strict": true,
|
||||
"alwaysStrict": true,
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
|
||||
@@ -44,7 +44,6 @@ class ControllerPlugin extends lib.BaseControllerPlugin {
|
||||
action: () => this.broadcastProgress(),
|
||||
});
|
||||
|
||||
this.lastProgressBroadcast = Date.now();
|
||||
this.progressBroadcastId = null;
|
||||
this.progressToBroadcast = new Set();
|
||||
|
||||
@@ -68,7 +67,6 @@ class ControllerPlugin extends lib.BaseControllerPlugin {
|
||||
}
|
||||
this.progressToBroadcast.clear();
|
||||
|
||||
this.lastProgressBroadcast = Date.now();
|
||||
if (techs.length) {
|
||||
this.controller.sendTo("allInstances", new ProgressEvent(techs));
|
||||
}
|
||||
|
||||
+12
-5
@@ -80,7 +80,7 @@ describe("lib/link/link", function() {
|
||||
testConnector._seq - 1,
|
||||
src,
|
||||
dst,
|
||||
new lib.ResponseError("Unrecognized request UnhandledRequest")
|
||||
new lib.ResponseError("Unrecognized request UnhandledRequest", "InvalidMessage")
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -114,7 +114,10 @@ describe("lib/link/link", function() {
|
||||
testConnector._seq - 1,
|
||||
src,
|
||||
dst,
|
||||
new lib.ResponseError("Source [Address controller:0] is not allowed for InvalidSrcRequest")
|
||||
new lib.ResponseError(
|
||||
"Source [Address controller:0] is not allowed for InvalidSrcRequest",
|
||||
"InvalidMessage"
|
||||
)
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -132,7 +135,8 @@ describe("lib/link/link", function() {
|
||||
src,
|
||||
dst,
|
||||
new lib.ResponseError(
|
||||
"Destination [Address control:1] is not allowed for InvalidDstRequest"
|
||||
"Destination [Address control:1] is not allowed for InvalidDstRequest",
|
||||
"InvalidMessage",
|
||||
)
|
||||
),
|
||||
]);
|
||||
@@ -144,7 +148,7 @@ describe("lib/link/link", function() {
|
||||
testConnector._seq - 1,
|
||||
src,
|
||||
addr("allControls"),
|
||||
new lib.ResponseError("Message src may not be broadcast")
|
||||
new lib.ResponseError("Message src may not be broadcast", "InvalidMessage")
|
||||
),
|
||||
]);
|
||||
});
|
||||
@@ -155,7 +159,10 @@ describe("lib/link/link", function() {
|
||||
testConnector._seq - 1,
|
||||
src,
|
||||
dst,
|
||||
new lib.ResponseError("Destination [Address 4:control] is not allowed for SimpleRequest")
|
||||
new lib.ResponseError(
|
||||
"Destination [Address 4:control] is not allowed for SimpleRequest",
|
||||
"InvalidMessage",
|
||||
)
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user