mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 07:40:43 +00:00
Fix various ESLint violations (#402)
## Description: Fixes a number of ESLint violations. Although I have tested these changes through the local dev server, I don't have a high confidence that the testing is sufficient, as I am new to this codebase. This change would benefit from heightened scrutiny. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: fake.neo --------- Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
This commit is contained in:
@@ -21,16 +21,13 @@ export default [
|
||||
{
|
||||
rules: {
|
||||
// Disable rules that would fail. The failures should be fixed, and the entries here removed.
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-namespace": "off",
|
||||
"@typescript-eslint/no-require-imports": "off",
|
||||
"@typescript-eslint/no-unused-expressions": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"no-case-declarations": "off",
|
||||
"no-useless-escape": "off",
|
||||
"prefer-const": "off",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"main": {
|
||||
"title": "OpenFront (ALPHA)",
|
||||
"join_discord": "Join the Discord!",
|
||||
"create_lobby": "Create Lobby",
|
||||
"join_lobby": "Join Lobby",
|
||||
|
||||
@@ -25,7 +25,7 @@ import { loadTerrainMap } from "../core/game/TerrainMapLoader";
|
||||
import { UserSettings } from "../core/game/UserSettings";
|
||||
import { WorkerClient } from "../core/worker/WorkerClient";
|
||||
import { InputHandler, MouseMoveEvent, MouseUpEvent } from "./InputHandler";
|
||||
import { LocalPersistantStats } from "./LocalPersistantStats";
|
||||
import { endGame, startGame, startTime } from "./LocalPersistantStats";
|
||||
import { getPersistentIDFromCookie } from "./Main";
|
||||
import {
|
||||
SendAttackIntentEvent,
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
import { createCanvas } from "./Utils";
|
||||
import { createRenderer, GameRenderer } from "./graphics/GameRenderer";
|
||||
|
||||
export // Is this function needed?
|
||||
function distSortUnitWorld(tile: TileRef, game: GameView) {
|
||||
return (a: Unit | UnitView, b: Unit | UnitView) => {
|
||||
return (
|
||||
@@ -69,10 +70,7 @@ export function joinLobby(
|
||||
);
|
||||
|
||||
const userSettings: UserSettings = new UserSettings();
|
||||
LocalPersistantStats.startGame(
|
||||
lobbyConfig.gameID,
|
||||
lobbyConfig.gameStartInfo?.config,
|
||||
);
|
||||
startGame(lobbyConfig.gameID, lobbyConfig.gameStartInfo?.config);
|
||||
|
||||
const transport = new Transport(lobbyConfig, eventBus);
|
||||
|
||||
@@ -198,13 +196,13 @@ export class ClientGameRunner {
|
||||
players,
|
||||
// Not saving turns locally
|
||||
[],
|
||||
LocalPersistantStats.startTime(),
|
||||
startTime(),
|
||||
Date.now(),
|
||||
winner,
|
||||
update.winnerType,
|
||||
update.allPlayersStats,
|
||||
);
|
||||
LocalPersistantStats.endGame(record);
|
||||
endGame(record);
|
||||
}
|
||||
|
||||
public start() {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
adsbygoogle: any[];
|
||||
adsbygoogle: unknown[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ const isElectron = () => {
|
||||
if (
|
||||
typeof window !== "undefined" &&
|
||||
typeof window.process === "object" &&
|
||||
// @ts-ignore
|
||||
// @ts-expect-error hidden
|
||||
window.process.type === "renderer"
|
||||
) {
|
||||
return true;
|
||||
|
||||
@@ -432,6 +432,7 @@ export class HostLobbyModal extends LitElement {
|
||||
} as GameConfig),
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
private getRandomMap(): GameMapType {
|
||||
@@ -460,6 +461,7 @@ export class HostLobbyModal extends LitElement {
|
||||
},
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
private async copyToClipboard() {
|
||||
|
||||
@@ -93,7 +93,7 @@ export class InputHandler {
|
||||
|
||||
private alternateView = false;
|
||||
|
||||
private moveInterval: any = null;
|
||||
private moveInterval: NodeJS.Timeout = null;
|
||||
private activeKeys = new Set<string>();
|
||||
|
||||
private readonly PAN_SPEED = 5;
|
||||
|
||||
+35
-33
@@ -20,10 +20,12 @@ const translations = {
|
||||
es: esTranslations,
|
||||
};
|
||||
|
||||
type Translation = Partial<(typeof translations)[keyof typeof translations]>;
|
||||
|
||||
@customElement("lang-selector")
|
||||
export class LangSelector extends LitElement {
|
||||
@state() public translations: any = {};
|
||||
@state() private defaultTranslations: any = {};
|
||||
@state() public translations: Translation = {};
|
||||
@state() private defaultTranslations = {};
|
||||
@state() private currentLang: string = "en";
|
||||
|
||||
createRenderRoot() {
|
||||
@@ -44,10 +46,10 @@ export class LangSelector extends LitElement {
|
||||
this.translations = await this.loadLanguage(userLang);
|
||||
this.currentLang = userLang;
|
||||
|
||||
this.applyTranslation(this.translations);
|
||||
this.applyTranslation();
|
||||
}
|
||||
|
||||
private async loadLanguage(lang: string): Promise<any> {
|
||||
private async loadLanguage(lang: string): Promise<Translation> {
|
||||
try {
|
||||
const translation = translations[lang as keyof typeof translations];
|
||||
if (!translation) throw new Error(`Language file not found: ${lang}`);
|
||||
@@ -58,7 +60,7 @@ export class LangSelector extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private applyTranslation(translations: any) {
|
||||
private applyTranslation() {
|
||||
const components = [
|
||||
"single-player-modal",
|
||||
"host-lobby-modal",
|
||||
@@ -75,24 +77,14 @@ export class LangSelector extends LitElement {
|
||||
"public-lobby",
|
||||
];
|
||||
|
||||
document.title = translations.main?.title || document.title;
|
||||
const main = this.translations.main;
|
||||
if (main && "title" in main) {
|
||||
document.title = main.title;
|
||||
}
|
||||
|
||||
document.querySelectorAll("[data-i18n]").forEach((element) => {
|
||||
const key = element.getAttribute("data-i18n");
|
||||
const keys = key.split(".");
|
||||
let text = translations;
|
||||
for (const k of keys) {
|
||||
text = text?.[k];
|
||||
if (!text) break;
|
||||
}
|
||||
if (!text && this.defaultTranslations) {
|
||||
let fallback = this.defaultTranslations;
|
||||
for (const k of keys) {
|
||||
fallback = fallback?.[k];
|
||||
if (!fallback) break;
|
||||
}
|
||||
text = fallback;
|
||||
}
|
||||
const text = this.translateText(key);
|
||||
if (text) {
|
||||
element.innerHTML = text;
|
||||
} else {
|
||||
@@ -101,7 +93,7 @@ export class LangSelector extends LitElement {
|
||||
});
|
||||
|
||||
components.forEach((tagName) => {
|
||||
const el = document.querySelector(tagName) as any;
|
||||
const el = document.querySelector(tagName) as LitElement;
|
||||
if (el && typeof el.requestUpdate === "function") {
|
||||
el.requestUpdate();
|
||||
} else {
|
||||
@@ -117,19 +109,13 @@ export class LangSelector extends LitElement {
|
||||
params: Record<string, string | number> = {},
|
||||
): string {
|
||||
const keys = key.split(".");
|
||||
let text: any = this.translations;
|
||||
|
||||
for (const k of keys) {
|
||||
text = text?.[k];
|
||||
if (!text) break;
|
||||
let text = findTranslation(keys, this.translations);
|
||||
if (!text && this.defaultTranslations) {
|
||||
text = findTranslation(keys, this.defaultTranslations);
|
||||
}
|
||||
|
||||
if (!text && this.defaultTranslations) {
|
||||
text = this.defaultTranslations;
|
||||
for (const k of keys) {
|
||||
text = text?.[k];
|
||||
if (!text) return key;
|
||||
}
|
||||
if (text == null || typeof text !== "string") {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (const [param, value] of Object.entries(params)) {
|
||||
@@ -143,7 +129,7 @@ export class LangSelector extends LitElement {
|
||||
localStorage.setItem("lang", lang);
|
||||
this.translations = await this.loadLanguage(lang);
|
||||
this.currentLang = lang;
|
||||
this.applyTranslation(this.translations);
|
||||
this.applyTranslation();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -178,3 +164,19 @@ export class LangSelector extends LitElement {
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
function findTranslation(
|
||||
keys: string[],
|
||||
translations: Translation,
|
||||
): string | null {
|
||||
let ptr: unknown = translations;
|
||||
for (const k of keys) {
|
||||
ptr = ptr?.[k];
|
||||
if (!ptr) break;
|
||||
}
|
||||
if (ptr && typeof ptr === "string") {
|
||||
return ptr;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,53 +9,51 @@ export interface LocalStatsData {
|
||||
};
|
||||
}
|
||||
|
||||
export namespace LocalPersistantStats {
|
||||
let _startTime: number;
|
||||
let _startTime: number;
|
||||
|
||||
function getStats(): LocalStatsData {
|
||||
const statsStr = localStorage.getItem("game-records");
|
||||
return statsStr ? JSON.parse(statsStr) : {};
|
||||
}
|
||||
|
||||
function save(stats: LocalStatsData) {
|
||||
// To execute asynchronously
|
||||
setTimeout(
|
||||
() => localStorage.setItem("game-records", JSON.stringify(stats)),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
// The user can quit the game anytime so better save the lobby as soon as the
|
||||
// game starts.
|
||||
export function startGame(id: GameID, lobby: GameConfig) {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
_startTime = Date.now();
|
||||
const stats = getStats();
|
||||
stats[id] = { lobby };
|
||||
save(stats);
|
||||
}
|
||||
|
||||
export function startTime() {
|
||||
return _startTime;
|
||||
}
|
||||
|
||||
export function endGame(gameRecord: GameRecord) {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const stats = getStats();
|
||||
const gameStat = stats[gameRecord.id];
|
||||
|
||||
if (!gameStat) {
|
||||
consolex.log("LocalPersistantStats: game not found");
|
||||
return;
|
||||
}
|
||||
|
||||
gameStat.gameRecord = gameRecord;
|
||||
save(stats);
|
||||
}
|
||||
function getStats(): LocalStatsData {
|
||||
const statsStr = localStorage.getItem("game-records");
|
||||
return statsStr ? JSON.parse(statsStr) : {};
|
||||
}
|
||||
|
||||
function save(stats: LocalStatsData) {
|
||||
// To execute asynchronously
|
||||
setTimeout(
|
||||
() => localStorage.setItem("game-records", JSON.stringify(stats)),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
// The user can quit the game anytime so better save the lobby as soon as the
|
||||
// game starts.
|
||||
export function startGame(id: GameID, lobby: GameConfig) {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
_startTime = Date.now();
|
||||
const stats = getStats();
|
||||
stats[id] = { lobby };
|
||||
save(stats);
|
||||
}
|
||||
|
||||
export function startTime() {
|
||||
return _startTime;
|
||||
}
|
||||
|
||||
export function endGame(gameRecord: GameRecord) {
|
||||
if (typeof localStorage === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const stats = getStats();
|
||||
const gameStat = stats[gameRecord.id];
|
||||
|
||||
if (!gameStat) {
|
||||
consolex.log("LocalPersistantStats: game not found");
|
||||
return;
|
||||
}
|
||||
|
||||
gameStat.gameRecord = gameRecord;
|
||||
save(stats);
|
||||
}
|
||||
|
||||
+2
-2
@@ -84,7 +84,7 @@ class Client {
|
||||
"google-ad",
|
||||
) as NodeListOf<GoogleAdElement>;
|
||||
|
||||
window.addEventListener("beforeunload", (event) => {
|
||||
window.addEventListener("beforeunload", () => {
|
||||
consolex.log("Browser is closing");
|
||||
if (this.gameStop != null) {
|
||||
this.gameStop();
|
||||
@@ -213,7 +213,7 @@ class Client {
|
||||
);
|
||||
}
|
||||
|
||||
private async handleLeaveLobby(event: CustomEvent) {
|
||||
private async handleLeaveLobby(/* event: CustomEvent */) {
|
||||
if (this.gameStop == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ export function createRenderer(
|
||||
const startingModal = document.querySelector(
|
||||
"game-starting-modal",
|
||||
) as GameStartingModal;
|
||||
startingModal instanceof GameStartingModal;
|
||||
startingModal.hide();
|
||||
|
||||
// TODO maybe append this to dcoument instead of querying for them?
|
||||
|
||||
@@ -216,7 +216,7 @@ export class StructureLayer implements Layer {
|
||||
|
||||
private handleUnitRendering(unit: UnitView) {
|
||||
const unitType = unit.constructionType() ?? unit.type();
|
||||
let iconType = unitType;
|
||||
const iconType = unitType;
|
||||
if (!this.isUnitTypeSupported(unitType)) return;
|
||||
|
||||
const config = this.unitConfigs[unitType];
|
||||
|
||||
@@ -12,11 +12,12 @@ import { Layer } from "./Layer";
|
||||
// Add this at the top of your file
|
||||
declare global {
|
||||
interface Window {
|
||||
adsbygoogle: any[];
|
||||
adsbygoogle: unknown[];
|
||||
}
|
||||
}
|
||||
|
||||
// Add this at the top of your file
|
||||
declare let adsbygoogle: any[];
|
||||
declare let adsbygoogle: unknown[];
|
||||
|
||||
@customElement("win-modal")
|
||||
export class WinModal extends LitElement implements Layer {
|
||||
@@ -257,7 +258,7 @@ export class WinModal extends LitElement implements Layer {
|
||||
});
|
||||
}
|
||||
|
||||
renderLayer(context: CanvasRenderingContext2D) {}
|
||||
renderLayer(/* context: CanvasRenderingContext2D */) {}
|
||||
|
||||
shouldTransform(): boolean {
|
||||
return false;
|
||||
|
||||
@@ -137,8 +137,8 @@ export class Cell {
|
||||
private strRepr: string;
|
||||
|
||||
constructor(
|
||||
public readonly x,
|
||||
public readonly y,
|
||||
public readonly x: number,
|
||||
public readonly y: number,
|
||||
) {
|
||||
this.strRepr = `Cell[${this.x},${this.y}]`;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ export class GameImpl implements Game {
|
||||
}
|
||||
|
||||
addUpdate(update: GameUpdate) {
|
||||
(this.updates[update.type] as any[]).push(update);
|
||||
(this.updates[update.type] as GameUpdate[]).push(update);
|
||||
}
|
||||
|
||||
nextUnitID(): number {
|
||||
@@ -383,7 +383,7 @@ export class GameImpl implements Game {
|
||||
}
|
||||
|
||||
playerByClientID(id: ClientID): Player | null {
|
||||
for (const [pID, player] of this._players) {
|
||||
for (const [, player] of this._players) {
|
||||
if (player.clientID() == id) {
|
||||
return player;
|
||||
}
|
||||
|
||||
@@ -1004,7 +1004,7 @@ export class PlayerImpl implements Player {
|
||||
// It's a probability list, so if an element appears twice it's because it's
|
||||
// twice more likely to be picked later.
|
||||
tradingPorts(port: Unit): Unit[] {
|
||||
let ports = this.mg
|
||||
const ports = this.mg
|
||||
.players()
|
||||
.filter((p) => p != port.owner() && p.canTrade(port.owner()))
|
||||
.flatMap((p) => p.units(UnitType.Port))
|
||||
|
||||
Vendored
-4
@@ -32,7 +32,3 @@ declare module "*.html" {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
declare module "*.json" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ export class GameServer {
|
||||
|
||||
const lastHashTurn = this.turns.length - 10;
|
||||
|
||||
let { mostCommonHash, outOfSyncClients } =
|
||||
const { mostCommonHash, outOfSyncClients } =
|
||||
this.findOutOfSyncClients(lastHashTurn);
|
||||
|
||||
if (outOfSyncClients.length == 0) {
|
||||
@@ -464,11 +464,6 @@ export class GameServer {
|
||||
return;
|
||||
}
|
||||
|
||||
if (outOfSyncClients.length >= Math.floor(this.activeClients.length / 2)) {
|
||||
// If half clients out of sync assume all are out of sync.
|
||||
outOfSyncClients = this.activeClients;
|
||||
}
|
||||
|
||||
const serverDesync = ServerDesyncSchema.safeParse({
|
||||
type: "desync",
|
||||
turn: lastHashTurn,
|
||||
@@ -519,7 +514,7 @@ export class GameServer {
|
||||
}
|
||||
|
||||
// Create a list of clients whose hash doesn't match the most common one
|
||||
const outOfSyncClients: Client[] = [];
|
||||
let outOfSyncClients: Client[] = [];
|
||||
|
||||
for (const client of this.activeClients) {
|
||||
if (client.hashes.has(turnNumber)) {
|
||||
@@ -530,6 +525,11 @@ export class GameServer {
|
||||
}
|
||||
}
|
||||
|
||||
// If half clients out of sync assume all are out of sync.
|
||||
if (outOfSyncClients.length >= Math.floor(this.activeClients.length / 2)) {
|
||||
outOfSyncClients = this.activeClients;
|
||||
}
|
||||
|
||||
return {
|
||||
mostCommonHash,
|
||||
outOfSyncClients,
|
||||
|
||||
@@ -16,7 +16,7 @@ export interface Gatekeeper {
|
||||
// The wrapper for request handlers with optional rate limiting
|
||||
httpHandler: (
|
||||
limiterType: LimiterType,
|
||||
fn: (req: Request, res: Response, next: NextFunction) => Promise<any>,
|
||||
fn: (req: Request, res: Response, next: NextFunction) => Promise<unknown>,
|
||||
) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
||||
|
||||
// The wrapper for WebSocket message handlers with rate limiting
|
||||
@@ -67,8 +67,8 @@ async function getGatekeeper(): Promise<Gatekeeper> {
|
||||
// Use dynamic import for ES modules
|
||||
// Using a type assertion to avoid TypeScript errors for optional modules
|
||||
const module = await import(
|
||||
"./gatekeeper/RealGatekeeper.js" as any
|
||||
).catch(() => import("./gatekeeper/RealGatekeeper.js" as any));
|
||||
"./gatekeeper/RealGatekeeper.js" as string
|
||||
).catch(() => import("./gatekeeper/RealGatekeeper.js" as string));
|
||||
|
||||
if (!module || !module.RealGatekeeper) {
|
||||
console.log(
|
||||
@@ -95,7 +95,7 @@ export class GatekeeperWrapper implements Gatekeeper {
|
||||
|
||||
httpHandler(
|
||||
limiterType: LimiterType,
|
||||
fn: (req: Request, res: Response, next: NextFunction) => Promise<any>,
|
||||
fn: (req: Request, res: Response, next: NextFunction) => Promise<unknown>,
|
||||
) {
|
||||
return async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
@@ -129,7 +129,7 @@ export class NoOpGatekeeper implements Gatekeeper {
|
||||
// Simple pass-through with no rate limiting
|
||||
httpHandler(
|
||||
limiterType: LimiterType,
|
||||
fn: (req: Request, res: Response, next: NextFunction) => Promise<any>,
|
||||
fn: (req: Request, res: Response, next: NextFunction) => Promise<unknown>,
|
||||
) {
|
||||
return async (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
|
||||
@@ -50,7 +50,7 @@ export function setupMetricsServer() {
|
||||
} else if (line.trim() && !line.startsWith("#")) {
|
||||
// Add worker label to each metric line and collect for later
|
||||
const processedLine = line.replace(
|
||||
/^([a-z][a-z0-9_]*)(?:{([^}]*)})?(\s+[0-9\.e+-]+.*)/,
|
||||
/^([a-z][a-z0-9_]*)(?:{([^}]*)})?(\s+[0-9.e+-]+.*)/,
|
||||
(match, metricName, existingLabels, valueAndRest) => {
|
||||
if (existingLabels) {
|
||||
return `${metricName}{${existingLabels},worker="master"}${valueAndRest}`;
|
||||
@@ -108,7 +108,7 @@ export function setupMetricsServer() {
|
||||
// Process and collect actual metric values
|
||||
try {
|
||||
const processedLine = line.replace(
|
||||
/^([a-z][a-z0-9_]*)(?:{([^}]*)})?(\s+[0-9\.e+-]+.*)/,
|
||||
/^([a-z][a-z0-9_]*)(?:{([^}]*)})?(\s+[0-9.e+-]+.*)/,
|
||||
(match, metricName, existingLabels, valueAndRest) => {
|
||||
if (existingLabels) {
|
||||
return `${metricName}{${existingLabels},worker="worker-${i}"}${valueAndRest}`;
|
||||
@@ -122,7 +122,7 @@ export function setupMetricsServer() {
|
||||
if (processedLine !== line) {
|
||||
allMetricValues.push(processedLine);
|
||||
} else if (
|
||||
line.match(/^[a-z][a-z0-9_]*(?:{[^}]*})?\s+[0-9\.e+-]+.*/)
|
||||
line.match(/^[a-z][a-z0-9_]*(?:{[^}]*})?\s+[0-9.e+-]+.*/)
|
||||
) {
|
||||
// This looks like a metric line but didn't match our regex, try a more general approach
|
||||
const parts = line.split(/({|\s+)/);
|
||||
|
||||
@@ -3,7 +3,13 @@ import { ClientID, GameID, LogSeverity } from "../core/Schemas";
|
||||
export interface slogMsg {
|
||||
logKey: string;
|
||||
msg: string;
|
||||
data?: any;
|
||||
data?: {
|
||||
stack?: unknown;
|
||||
clientID?: unknown;
|
||||
clientIP?: unknown;
|
||||
gameID?: unknown;
|
||||
isRejoin?: unknown;
|
||||
};
|
||||
severity?: LogSeverity;
|
||||
gameID?: GameID;
|
||||
clientID?: ClientID;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"resolveJsonModule": true,
|
||||
"useDefineForClassFields": false
|
||||
},
|
||||
"include": [
|
||||
|
||||
Reference in New Issue
Block a user