typescriptify it all

This commit is contained in:
Elijah R 2024-06-23 19:33:38 -04:00
parent c0e1f9c830
commit 8d5aaf4eeb
6 changed files with 261 additions and 100 deletions

2
.gitignore vendored
View file

@ -2,3 +2,5 @@ node_modules/
package-lock.json
yarn.lock
config.js
config.json
dist/

View file

@ -11,9 +11,14 @@
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
"scripts": {
"format": "prettier *.js -w"
"format": "prettier src/*.ts -w",
"build": "tsc",
"serve": "node dist/index.js"
},
"devDependencies": {
"prettier": "^3.3.2"
"@types/node": "^20.14.8",
"@types/ws": "^8.5.10",
"prettier": "^3.3.2",
"typescript": "^5.5.2"
}
}

View file

@ -2,9 +2,9 @@
import * as ws from "ws";
const guacutils = {
parse: (string) => {
parse: (string: string) => {
let pos = -1;
let sections = [];
let sections: string[] = [];
for (;;) {
let len = string.indexOf(".", pos + 1);
@ -29,7 +29,7 @@ const guacutils = {
return sections;
},
encode: (cypher) => {
encode: (cypher: string[]) => {
let command = "";
for (var i = 0; i < cypher.length; i++) {
@ -41,22 +41,22 @@ const guacutils = {
},
};
const ConnectionState = Object.freeze({
CLOSED: 0,
CONNECTING: 1,
CONNECTED: 2,
});
enum ConnectionState {
CLOSED = 0,
CONNECTING = 1,
CONNECTED = 2,
}
// System chat messages have a nil username.
function IsSystemChatInstruction(inst) {
function IsSystemChatInstruction(inst: string[]) {
return inst[1] == "";
}
class UserData {
#_name;
#_rank;
private _name: string;
private _rank: number;
constructor(name, rank) {
constructor(name: string, rank: number) {
this._name = name;
this._rank = rank;
}
@ -68,12 +68,25 @@ class UserData {
return this._rank;
}
UpdateRank(new_rank) {
UpdateRank(new_rank: number) {
this._rank = new_rank;
}
}
export default class CollabVMClient {
export default abstract class CollabVMClient {
abstract OnOpen(): void;
abstract OnClose(): void;
abstract OnChat(username: string, message: string): void;
abstract OnGuacamoleMessage(msg: string[]): void;
abstract OnAddUser_Bot(count: number): void;
abstract OnRemUser_Bot(count: number): void;
private _state: ConnectionState;
private _users: UserData[];
private _ws: ws.WebSocket | undefined;
private _username: string | undefined;
private _vm: string | undefined;
constructor() {
this._state = ConnectionState.CLOSED;
this._users = [];
@ -83,14 +96,16 @@ export default class CollabVMClient {
return this._state;
}
Connect(uri) {
Connect(uri: string) {
this._ws = new ws.WebSocket(uri, "guacamole", {
origin: "https://computernewb.com",
});
this._ws.onopen = this.OnWebSocketOpen.bind(this);
this._ws.onclose = this.OnWebSocketClose.bind(this);
this._ws.onerror = this.OnWebSocketError.bind(this);
this._ws.onmessage = this.OnWebSocketMessage.bind(this);
this._ws.on("open", () => this.OnWebSocketOpen());
this._ws.on("close", () => this.OnWebSocketClose());
this._ws.on("error", () => this.OnWebSocketError());
this._ws.on("message", (msg, isBinary) =>
this.OnWebSocketMessage(msg, isBinary),
);
this._state = ConnectionState.CONNECTING;
}
@ -101,25 +116,25 @@ export default class CollabVMClient {
OnWebSocketClose() {
this._state = ConnectionState.CLOSED;
this.OnClose(arguments);
this.OnClose();
}
OnWebSocketError() {
// fire the close handler
this._state = ConnectionState.CLOSED;
this.OnClose(arguments);
this.OnClose();
}
Close() {
this._state = ConnectionState.CLOSED;
this._ws.close();
this._ws?.close();
}
OnWebSocketMessage(ev) {
OnWebSocketMessage(msg: Buffer | ArrayBuffer | Buffer[], isBinary: boolean) {
// cvm server should never send binary data
if (typeof ev.data !== "string") return;
if (isBinary) return;
let message = guacutils.parse(ev.data);
let message = guacutils.parse(msg.toString("utf-8"));
if (message.length === 0) return;
// Hardcoded, we need to keep this to be alive
@ -165,11 +180,11 @@ export default class CollabVMClient {
this.OnGuacamoleMessage(message);
}
OnAddUser(users, count) {
OnAddUser(users: string[], count: number) {
//console.log(users);
for (var i = 0; i < count * 2; i += 2) {
let name = users[i];
let rank = users[i + 1];
let rank = parseInt(users[i + 1]);
//console.log(`[${this.GetVM()}] user ${name} rank ${rank}`)
@ -188,7 +203,7 @@ export default class CollabVMClient {
this.OnAddUser_Bot(this.GetUserCount());
}
OnRemUser(users, count) {
OnRemUser(users: string[], count: number) {
for (var i = 0; i < count; i++) {
let saveUserTemp = this.GetUser(users[i]);
this._users = this._users.filter((user) => user.GetName() != users[i]);
@ -212,7 +227,7 @@ export default class CollabVMClient {
// subtract known bots
for (var i = len - 1; i != 0; --i) {
// ?
if (this._users[i] === undefined) return;
if (this._users[i] === undefined) break;
var name = this._users[i].GetName();
if (KnownBots.find((elem) => name == elem) !== undefined) {
@ -232,7 +247,7 @@ export default class CollabVMClient {
this._users;
}
GetUser(username) {
GetUser(username: string) {
let existingUser = this._users.find((elem) => elem.GetName() == username);
// Apparently this can fail somehow..?
@ -245,7 +260,7 @@ export default class CollabVMClient {
return this._username;
}
Rename(name) {
Rename(name: string) {
this._username = name;
this.SendGuacamoleMessage("rename", name);
}
@ -254,14 +269,14 @@ export default class CollabVMClient {
return this._vm;
}
ConnectToVM(vm) {
ConnectToVM(vm: string) {
this._vm = vm;
this.SendGuacamoleMessage("connect", vm);
}
SendGuacamoleMessage() {
SendGuacamoleMessage(...args: string[]) {
if (this._state !== ConnectionState.CONNECTED) return;
this._ws.send(guacutils.encode(Array.prototype.slice.call(arguments)));
this._ws?.send(guacutils.encode(args));
}
}

14
src/config.ts Normal file
View file

@ -0,0 +1,14 @@
export default interface Config {
BANNED_ISO: RegExp[];
ISO_DIRECTORIES: { [key: string]: string };
INSTALLBOT_VMS: {
uri: string;
id: string;
usesIde2: boolean;
hasFloppy: boolean;
}[];
BOT_PREFIX: string;
ADMIN_TOKEN: string;
kGeneralLimitBaseSeconds: number;
kRebootLimitBaseSeconds: number;
}

View file

@ -1,28 +1,39 @@
import { readFileSync } from "fs";
import CollabVMClient from "./client.js";
import {
BANNED_ISO,
ISO_DIRECTORIES,
INSTALLBOT_VMS,
BOT_PREFIX,
ADMIN_TOKEN,
kGeneralLimitBaseSeconds,
kRebootLimitBaseSeconds,
} from "./config.js";
import Config from "./config.js";
function Log() {
let config: Config = JSON.parse(readFileSync("config.json", "utf-8"));
function Log(...args: string[]) {
// console.log(`[AnyOSBot] [${new Date()}]`, [...arguments].join(' '))
console.log("[AnyOSBot]", [...arguments].join(" "));
console.log("[AnyOSBot]", args.join(" "));
}
interface HelpCommand {
command: string;
help: string;
usesFloppy?: boolean | undefined;
}
// you people SUCK man (dynamic edition, with less bugs!)
// and it actually probably works without hanging or negative seconds this time.
class RateLimit {
constructor(time, factor, ident) {
private _ident: string;
private _timeBase: number;
private _factor: number;
private _msUntil: number;
private _n: number;
private _limited: boolean;
private _siHandle: NodeJS.Timeout | null;
constructor(time: number, factor: number, ident: string) {
this._ident = ident;
this._timeBase = time;
this._msUntil = 0;
this._n = 1;
this._factor = factor;
this._limited = false;
this._siHandle = null;
}
GetTime() {
@ -46,7 +57,7 @@ class RateLimit {
return ret;
}
SetUserCount(count) {
SetUserCount(count: number) {
if (count == 0) count = 1;
this._n = count;
@ -57,19 +68,18 @@ class RateLimit {
// TODO: this might work for the dyna ratelimit?
if (this._limited) return;
let self = this;
self._msUntil = this.GetMs();
this._msUntil = this.GetMs();
Log(
`Ratelimit \"${this._ident}\" started, will be done in ${self._msUntil} ms (${self._msUntil / 1000} seconds)`,
`Ratelimit \"${this._ident}\" started, will be done in ${this._msUntil} ms (${this._msUntil / 1000} seconds)`,
);
self._limited = true;
this._limited = true;
this._siHandle = setInterval(() => {
self._msUntil -= 1000;
if (self._msUntil <= 0) {
Log(`Ratelimit \"${self._ident}\" is done.`);
clearInterval(self._siHandle);
self._limited = false;
this._msUntil -= 1000;
if (this._msUntil <= 0) {
Log(`Ratelimit \"${this._ident}\" is done.`);
if (this._siHandle !== null) clearInterval(this._siHandle);
this._limited = false;
return;
}
}, 1000);
@ -86,7 +96,14 @@ class RateLimit {
}
class HelperBot extends CollabVMClient {
constructor(wsUri, vmId, ide2, floppy) {
private _wsUri: string;
private _vmId: string;
private _ide2: boolean;
private _hasFloppy: boolean;
private GeneralCmdLimit: RateLimit | undefined;
private RebootLimit: RateLimit | undefined;
constructor(wsUri: string, vmId: string, ide2: boolean, floppy: boolean) {
super();
this._wsUri = wsUri;
@ -109,17 +126,17 @@ class HelperBot extends CollabVMClient {
this.ConnectToVM(this._vmId);
}
OnClose(ev) {
OnClose() {
//console.log(arguments)
// reconnect lol
/* the right way doesnt work thanks to something
Log(`[${this._vmId}]`, `Connection closed, reconnecting in 5 seconds`);
let self = this;
let this = this;
setTimeout(() => {
Log(`[${this._vmId}]`, `Reconnecting now`);
self.DoConn();
this.DoConn();
}, 1000 * 5)
*/
@ -129,21 +146,21 @@ class HelperBot extends CollabVMClient {
// The bot should probably give up after some attempts
}
Chat(message) {
Chat(message: string) {
this.SendGuacamoleMessage("chat", message);
}
OnAddUser_Bot(count) {
this.GeneralCmdLimit.SetUserCount(count);
this.RebootLimit.SetUserCount(count);
OnAddUser_Bot(count: number) {
this.GeneralCmdLimit!.SetUserCount(count);
this.RebootLimit!.SetUserCount(count);
}
OnRemUser_Bot(count) {
this.GeneralCmdLimit.SetUserCount(count);
this.RebootLimit.SetUserCount(count);
OnRemUser_Bot(count: number) {
this.GeneralCmdLimit!.SetUserCount(count);
this.RebootLimit!.SetUserCount(count);
}
UserCanBypass(username) {
UserCanBypass(username: string) {
let existingUser = this.GetUser(username);
// Apparently this can fail somehow..?
@ -153,12 +170,12 @@ class HelperBot extends CollabVMClient {
return rank == 2 || rank == 3;
}
SendMonitorCommand(cmd) {
this.SendGuacamoleMessage("admin", "5", this.GetVM(), cmd);
SendMonitorCommand(cmd: string) {
this.SendGuacamoleMessage("admin", "5", this.GetVM()!, cmd);
}
ConcatPath(isodir, otherPath) {
let isopath = ISO_DIRECTORIES[isodir];
ConcatPath(isodir: string, otherPath: string) {
let isopath = config.ISO_DIRECTORIES[isodir];
if (isopath === undefined) {
// imo crashing and being restarted by systemd is better than not knowing why shit was coming out as undefined
// gotta love javascript
@ -169,11 +186,11 @@ class HelperBot extends CollabVMClient {
// QEMU Abstractions
QemuEjectDevice(devname) {
QemuEjectDevice(devname: string) {
this.SendMonitorCommand(`eject ${devname}`);
}
QemuChangeDevice(devname, source, opts) {
QemuChangeDevice(devname: string, source: string, opts: string) {
this.SendMonitorCommand(`change ${devname} "${source}" ${opts}`);
}
@ -186,27 +203,27 @@ class HelperBot extends CollabVMClient {
if (this._hasFloppy) this.QemuEjectDevice("vm.floppy");
}
QemuChangeCd(source, opts) {
QemuChangeCd(source: string, opts: string) {
if (this._ide2) this.QemuChangeDevice("ide2-cd0", source, opts);
else this.QemuChangeDevice("vm.cd", source, opts);
}
QemuChangeFloppy(source) {
QemuChangeFloppy(source: string) {
if (this._hasFloppy)
this.QemuChangeDevice("vm.floppy", source, "raw read-only");
}
OnChat(username, message) {
OnChat(username: string, message: string) {
//console.log(`${username}> ${message}`);
if (username == this.GetUsername()) return;
if (message[0] === BOT_PREFIX) {
if (message[0] === config.BOT_PREFIX) {
this.HandleCommands(username, message);
}
}
HandleCommands(username, message) {
HandleCommands(username: string, message: string) {
{
let user = this.GetUser(username);
if (user == null) {
@ -224,7 +241,7 @@ class HelperBot extends CollabVMClient {
// Little code fragment to make rate limiting
// more portable.
const DoLimit = (limit) => {
const DoLimit = (limit: RateLimit) => {
//console.log(`[AnyOSBot] [${this._vmId}] ${this.GetUserCount()} users online (${this.GetUserCountFull()} actual)`)
//if(this._vmId !== 'vm0b0t') {
@ -249,18 +266,18 @@ class HelperBot extends CollabVMClient {
};
// generate a help HTML string for the help
const generateHelp = (arr) => {
const generateHelp = (arr: HelpCommand[]) => {
let str = "<h4>AnyOSInstallBot Help:</h4><ul>";
for (var cmd of arr) {
// remove commands which depend on the floppy on a VM without floppy
if (cmd.usesFloppy && !this._hasFloppy) continue;
str += `<li><b>${BOT_PREFIX}${cmd.command}</b> - ${cmd.help}</li>`;
str += `<li><b>${config.BOT_PREFIX}${cmd.command}</b> - ${cmd.help}</li>`;
}
str += "</ul>";
return str;
};
const generateList = (title, arr) => {
const generateList = (title: string, arr: string[]) => {
let str = `<h4>${title}</h4><ul>`;
for (var cmd of arr) {
str += `<li>${cmd}</li>`;
@ -277,7 +294,7 @@ class HelperBot extends CollabVMClient {
switch (command) {
case "help":
if (!DoLimit(this.GeneralCmdLimit)) return;
if (!DoLimit(this.GeneralCmdLimit!)) return;
this.SendGuacamoleMessage(
"admin",
"21",
@ -331,7 +348,7 @@ class HelperBot extends CollabVMClient {
break;
case "network":
if (!DoLimit(this.GeneralCmdLimit)) return;
if (!DoLimit(this.GeneralCmdLimit!)) return;
switch (this._vmId) {
case "vm7":
@ -359,14 +376,14 @@ class HelperBot extends CollabVMClient {
);
break;
default:
this.chat("This VM should already have internet.");
this.Chat("This VM should already have internet.");
break;
}
break;
case "certerror":
if (!DoLimit(this.GeneralCmdLimit)) return;
if (!DoLimit(this.GeneralCmdLimit!)) return;
//if(this._vmId == 'vm0b0t') {
// this.SendGuacamoleMessage("admin", "21", "<h1>fuck off retard why are you trying to get collabnet on vm0</h1>");
@ -391,13 +408,13 @@ class HelperBot extends CollabVMClient {
case "httpcd":
case "httpflp":
{
if (!DoLimit(this.GeneralCmdLimit)) return;
if (!DoLimit(this.GeneralCmdLimit!)) return;
let arg = message.slice(message.indexOf(" ") + 1);
let ext = arg.slice(arg.lastIndexOf(".") + 1);
if (arg.indexOf("..") !== -1) return;
for (var ii = 0; ii < BANNED_ISO.length; ii++) {
if (BANNED_ISO[ii].test(arg)) {
for (var ii = 0; ii < config.BANNED_ISO.length; ii++) {
if (config.BANNED_ISO[ii].test(arg)) {
this.Chat("That ISO is currently blacklisted.");
return;
}
@ -541,7 +558,7 @@ class HelperBot extends CollabVMClient {
case "eject":
{
if (!DoLimit(this.GeneralCmdLimit)) return;
if (!DoLimit(this.GeneralCmdLimit!)) return;
let arg = message.slice(message.indexOf(" ") + 1);
@ -560,7 +577,7 @@ class HelperBot extends CollabVMClient {
break;
case "reboot":
if (!DoLimit(this.RebootLimit)) return;
if (!DoLimit(this.RebootLimit!)) return;
// this.Chat("hold on fellas");
// return;
@ -568,7 +585,7 @@ class HelperBot extends CollabVMClient {
break;
case "bootset":
if (!DoLimit(this.GeneralCmdLimit)) return;
if (!DoLimit(this.GeneralCmdLimit!)) return;
//this.Chat("sorry, severe autism not allowed right now");
//return;
@ -591,20 +608,20 @@ class HelperBot extends CollabVMClient {
// this.GeneralCmdLimit = new RateLimit(25 * 1000);
//else
this.GeneralCmdLimit = new RateLimit(
kGeneralLimitBaseSeconds * 1000,
config.kGeneralLimitBaseSeconds * 1000,
2,
`General commands/${this._vmId}`,
);
//this.EjectLimit = new RateLimit(30 * 1000);
this.RebootLimit = new RateLimit(
kRebootLimitBaseSeconds * 1000,
config.kRebootLimitBaseSeconds * 1000,
3,
`!reboot/${this._vmId}`,
);
}
OnGuacamoleMessage(message) {
OnGuacamoleMessage(message: string[]) {
if (message[0] == "connect") {
if (message[1] == "0") {
Log(`[${this._vmId}]`, `Failed to connect to VM`);
@ -616,7 +633,7 @@ class HelperBot extends CollabVMClient {
Log(`[${this._vmId}]`, `Connected to VM`);
// I'm fucking lazy
this.SendGuacamoleMessage("login", ADMIN_TOKEN);
this.SendGuacamoleMessage("login", config.ADMIN_TOKEN);
this.CreateRateLimits();
}
@ -636,7 +653,7 @@ class HelperBot extends CollabVMClient {
}
}
for (let vm of INSTALLBOT_VMS) {
for (let vm of config.INSTALLBOT_VMS) {
// initalize this bot instance
new HelperBot(vm.uri, vm.id, vm.usesIde2, vm.hasFloppy).DoConn();
}

108
tsconfig.json Normal file
View file

@ -0,0 +1,108 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ES2022", /* Specify what module code is generated. */
"rootDir": "./src", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}