Skip to content

[Tech] Let's be even more strict when writing TS code #1761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions public/locales/fa/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"launchAborted": "Launch aborted",
"title": "خطا",
"uncaught-exception": {
"message": "یک خطای نامشخص رخ داد:{{newLine}}{{error}}{{newLine}}{{newLine}}Heroic بسته خواهد شد! خطا را در ریپوزیتوری گیت‌هاب ما گزارش دهید.",
"message": "یک خطای نامشخص رخ داد:{{newLine}}{{error}}{{newLine}}{{newLine}}Heroic بسته خواهد شد! خطا را در ریپوزیتوری گیت\u200cهاب ما گزارش دهید.",
"title": "خطای نامشخص رخ داد!"
},
"update": {
Expand Down Expand Up @@ -477,7 +477,7 @@
},
"gameMode": {
"eacRuntimeEnabled": {
"message": "ران تایم EAC که بدون GameMode به درستی کار نمی کند، فعال شده است. آیا می خواهید ران تایم EAC و GameMode را غیرفعال کنید؟",
"message": "ران تایم EAC که بدون GameMode به درستی کار نمی کند،\u200c فعال شده است. آیا می خواهید ران تایم EAC و GameMode را غیرفعال کنید؟",
"title": "ران تایم EAC فعال شد"
}
},
Expand Down
2 changes: 1 addition & 1 deletion public/locales/fr/gamepage.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"uninstall": {
"checkbox": "Voulez-vous également retirer le préfixe ? Ceci ne peut pas être annulé.",
"checkbox_prefix": "Préfixe",
"message": "Voulez-vous désinstaller ce jeu?",
"message": "Voulez-vous désinstaller ce jeu\u202f?",
"title": "Désinstaller"
},
"update": {
Expand Down
8 changes: 6 additions & 2 deletions src/backend/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,14 @@ abstract class GlobalConfig {
return execAsync(`which wine`)
.then(async ({ stdout }) => {
const wineBin = stdout.split('\n')[0]
defaultWine.bin = wineBin

const { stdout: out } = await execAsync(`wine --version`)
const version = out.split('\n')[0]

if (!wineBin || !version) {
return defaultWine
}

defaultWine.bin = wineBin
defaultWine.name = `Wine Default - ${version}`

return {
Expand Down
85 changes: 49 additions & 36 deletions src/backend/gog/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
isLinux
} from '../constants'
import { installedGamesStore, syncStore } from '../gog/electronStores'
import { logError, logInfo, LogPrefix } from '../logger/logger'
import { logDebug, logError, logInfo, LogPrefix } from '../logger/logger'
import { errorHandler, execAsync, getFileSize, getGOGdlBin } from '../utils'
import { GOGUser } from './user'
import {
Expand All @@ -48,7 +48,7 @@ import { t } from 'i18next'

class GOGGame extends Game {
public appName: string
public window = BrowserWindow.getAllWindows()[0]
public window = BrowserWindow.getAllWindows()[0]!
private static instances = new Map<string, GOGGame>()
private constructor(appName: string) {
super()
Expand Down Expand Up @@ -159,7 +159,14 @@ class GOGGame extends Game {
const etaMatch = data.match(/ETA: (\d\d:\d\d:\d\d)/m)
const bytesMatch = data.match(/Downloaded: (\S+) MiB/m)
const progressMatch = data.match(/Progress: (\d+\.\d+) /m)
if (etaMatch && bytesMatch && progressMatch) {
if (
etaMatch &&
etaMatch[1] &&
bytesMatch &&
bytesMatch[1] &&
progressMatch &&
progressMatch[1]
) {
const eta = etaMatch[1]
const bytes = bytesMatch[1]
let percent = parseFloat(progressMatch[1])
Expand Down Expand Up @@ -587,51 +594,54 @@ class GOGGame extends Game {
}
}
public async uninstall(): Promise<ExecResult> {
const array: Array<InstalledInfo> =
const allInstallledInfo: InstalledInfo[] =
(installedGamesStore.get('installed') as Array<InstalledInfo>) || []
const index = array.findIndex((game) => game.appName === this.appName)
if (index === -1) {
const installedInfo = allInstallledInfo.find(
(game) => game.appName === this.appName
)
if (!installedInfo) {
throw Error("Game isn't installed")
}
const newInstalledInfoArray = allInstallledInfo.filter(
(game) => game !== installedInfo
)
const { install_path } = installedInfo

const [object] = array.splice(index, 1)
logInfo(['Removing', object.install_path], LogPrefix.Gog)
logInfo(['Removing', install_path], LogPrefix.Gog)
// TODO: Run unins000.exe /verysilent /dir=Z:/path/to/game
const uninstallerPath = join(object.install_path, 'unins000.exe')
const uninstallerPath = join(install_path, 'unins000.exe')

const res: ExecResult = { stdout: '', stderr: '' }
if (existsSync(uninstallerPath)) {
const {
winePrefix,
wineVersion: { bin, name },
wineCrossoverBottle
} = GameConfig.get(this.appName).config
let commandPrefix = `WINEPREFIX="${winePrefix}" ${bin}`
if (name.includes('CrossOver')) {
commandPrefix = `CX_BOTTLE=${wineCrossoverBottle} ${bin}`
}
const command = `${
isWindows ? '' : commandPrefix
} "${uninstallerPath}" /verysilent /dir="${isWindows ? '' : 'Z:'}${
object.install_path
}"`
logInfo(['Executing uninstall command', command], LogPrefix.Gog)
execAsync(command)
.then(({ stdout, stderr }) => {
if (!this.isNative()) {
const { stdout: wineGamePath } = await this.runWineCommand(
`winepath -w ${install_path}`
)
logDebug(['Game path from within Wine:', wineGamePath], LogPrefix.Gog)
this.runWineCommand(
`${uninstallerPath} /verysilent /dir=${wineGamePath}`
).then(({ stdout, stderr }) => {
res.stdout = stdout
res.stderr = stderr
})
.catch((error) => {
res.error = `${error}`
})
} else {
execAsync(`${uninstallerPath} /verysilent /dir=${install_path}`)
.then(({ stdout, stderr }) => {
res.stdout = stdout
res.stderr = stderr
})
.catch((error) => {
res.error = `${error}`
})
}
} else {
rmSync(object.install_path, { recursive: true })
rmSync(install_path, { recursive: true })
}
installedGamesStore.set('installed', array)
installedGamesStore.set('installed', newInstalledInfoArray)
GOGLibrary.get().refreshInstalled()
await removeShortcuts(this.appName, 'gog')
syncStore.delete(this.appName)
const gameInfo = await this.getGameInfo()
const gameInfo = this.getGameInfo()
const { defaultSteamPath } = await GlobalConfig.get().getSettings()
const steamUserdataDir = join(
defaultSteamPath.replaceAll("'", ''),
Expand Down Expand Up @@ -693,13 +703,18 @@ class GOGGame extends Game {
}

const installedArray = installedGamesStore.get(
'installed'
'installed',
[]
) as InstalledInfo[]
const gameIndex = installedArray.findIndex(
(value) => this.appName === value.appName
)
const gameObject = installedArray[gameIndex]

if (!gameObject) {
return { status: 'error' }
}

if (gameData.install.platform !== 'linux') {
const installInfo = await this.getInstallInfo()
gameObject.buildId = installInfo.game.buildId
Expand Down Expand Up @@ -768,9 +783,7 @@ class GOGGame extends Game {
) as Array<InstalledInfo>
const newInstalled = installed.filter((g) => g.appName !== this.appName)
installedGamesStore.set('installed', newInstalled)
const mainWindow =
BrowserWindow.getFocusedWindow() ?? BrowserWindow.getAllWindows()[0]
mainWindow.webContents.send('refreshLibrary', 'gog')
this.window.webContents.send('refreshLibrary', 'gog')
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/backend/gog/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ export class GOGLibrary {
(value) => value.app_name === appName
)
if (
!libraryArray[gameObjectIndex].gog_save_location &&
!libraryArray[gameObjectIndex]!.gog_save_location &&
this.installedGames.get(appName) &&
this.installedGames.get(appName)?.platform !== 'linux'
) {
Expand All @@ -360,8 +360,9 @@ export class GOGLibrary {
this.installedGames.get(appName)!
)
}
libraryArray[gameObjectIndex].folder_name = gogInfo.folder_name
libraryArray[gameObjectIndex].gog_save_location = gameData.gog_save_location
libraryArray[gameObjectIndex]!.folder_name = gogInfo.folder_name
libraryArray[gameObjectIndex]!.gog_save_location =
gameData.gog_save_location
gameData.folder_name = gogInfo.folder_name
libraryStore.set('games', libraryArray)
this.library.set(appName, gameData)
Expand Down Expand Up @@ -418,7 +419,7 @@ export class GOGLibrary {
(value) => value.appName === appName
)

installedArray[gameIndex].install_path = newInstallPath
installedArray[gameIndex]!.install_path = newInstallPath
cachedGameData.install.install_path = newInstallPath
installedGamesStore.set('installed', installedArray)
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend/legendary/eos_overlay/eos_overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ async function install() {
logMessagePrefix: 'Getting EOS Overlay install size',
onOutput: (output: string, child: ChildProcess) => {
const downloadMatch = output.match(/Download size: ([\d.]+) MiB/)
if (downloadMatch) {
if (downloadMatch && downloadMatch[1]) {
downloadSize = parseFloat(downloadMatch[1])
// Output is in MiB, we want it in bytes
downloadSize = downloadSize * 1024 ** 2
Expand Down
14 changes: 6 additions & 8 deletions src/backend/legendary/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { t } from 'i18next'

class LegendaryGame extends Game {
public appName: string
public window = BrowserWindow.getAllWindows()[0]
public window = BrowserWindow.getAllWindows()[0]!
private static instances: Map<string, LegendaryGame> = new Map()

private constructor(appName: string) {
Expand Down Expand Up @@ -266,14 +266,14 @@ class LegendaryGame extends Game {

// store the download size, needed for correct calculation
// when cancel/resume downloads
if (downloadSizeMatch) {
if (downloadSizeMatch && downloadSizeMatch[1]) {
this.currentDownloadSize = parseFloat(downloadSizeMatch[1])
}

// parse log for game download progress
const etaMatch = data.match(/ETA: (\d\d:\d\d:\d\d)/m)
const bytesMatch = data.match(/Downloaded: (\S+.) MiB/m)
if (!etaMatch || !bytesMatch) {
if (!etaMatch || !etaMatch[1] || !bytesMatch || !bytesMatch[1]) {
return
}

Expand Down Expand Up @@ -334,7 +334,7 @@ class LegendaryGame extends Game {

const onOutput = (data: string) => {
this.onInstallOrUpdateOutput(
'installing',
'updating',
info.manifest.download_size,
data
)
Expand Down Expand Up @@ -428,7 +428,7 @@ class LegendaryGame extends Game {

const onOutput = (data: string) => {
this.onInstallOrUpdateOutput(
'updating',
'installing',
info.manifest.download_size,
data
)
Expand Down Expand Up @@ -743,9 +743,7 @@ class LegendaryGame extends Game {
'-y',
'--keep-files'
])
const mainWindow =
BrowserWindow.getFocusedWindow() ?? BrowserWindow.getAllWindows()[0]
mainWindow.webContents.send('refreshLibrary', 'legendary')
this.window.webContents.send('refreshLibrary', 'legendary')
} catch (error) {
logError(
`Error reading ${installed}, could not complete operation`,
Expand Down
6 changes: 4 additions & 2 deletions src/backend/legendary/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export class LegendaryLibrary {
return
}
const latestVersion = currentAsset.build_version
if (currentVersion !== latestVersion) {
if (latestVersion && currentVersion !== latestVersion) {
logDebug(
[
'Update is available for',
Expand Down Expand Up @@ -502,7 +502,9 @@ export class LegendaryLibrary {
namespace,
is_mac_native: info
? platform === 'Mac'
: releaseInfo[0].platform.includes('Mac'),
: releaseInfo[0]
? releaseInfo[0].platform.includes('Mac')
: false,
save_folder: saveFolder,
title,
canRunOffline,
Expand Down
Loading