From 09b411730665ed57dc0abceefc7717113d4a86ed Mon Sep 17 00:00:00 2001 From: Johannes Loher Date: Sun, 7 Feb 2021 13:51:20 +0100 Subject: [PATCH] Activate strict mode --- src/module/actor/sheets/actor-sheet.ts | 2 +- src/module/ds4.ts | 41 +++++++++++-------- src/module/item/item-sheet.ts | 4 +- src/module/migrations.ts | 10 ++--- src/module/migrations/001.ts | 4 +- src/module/rolls/check-factory.ts | 56 ++++++++++++++------------ src/module/rolls/check.ts | 12 +++--- src/module/rolls/roll-executor.ts | 10 ++--- tsconfig.json | 2 +- 9 files changed, 78 insertions(+), 63 deletions(-) diff --git a/src/module/actor/sheets/actor-sheet.ts b/src/module/actor/sheets/actor-sheet.ts index 8d373def..177fff4c 100644 --- a/src/module/actor/sheets/actor-sheet.ts +++ b/src/module/actor/sheets/actor-sheet.ts @@ -221,7 +221,7 @@ export class DS4ActorSheet extends ActorSheet { ): Promise> { const item = ((await Item.fromDropData(data)) as unknown) as DS4Item; if (item && !this.actor.canOwnItemType(item.data.type)) { - ui.notifications.warn( + ui.notifications?.warn( game.i18n.format("DS4.WarningActorCannotOwnItem", { actorName: this.actor.name, actorType: this.actor.data.type, diff --git a/src/module/ds4.ts b/src/module/ds4.ts index 2f825cfc..0a500414 100644 --- a/src/module/ds4.ts +++ b/src/module/ds4.ts @@ -9,7 +9,7 @@ import { createCheckRoll } from "./rolls/check-factory"; import { registerSystemSettings } from "./settings"; import { migration } from "./migrations"; -Hooks.once("init", async function () { +Hooks.once("init", async () => { console.log(`DS4 | Initializing the DS4 Game System\n${DS4.ASCII}`); game.ds4 = { @@ -68,23 +68,11 @@ async function registerHandlebarsPartials() { /** * This function runs after game data has been requested and loaded from the servers, so entities exist */ -Hooks.once("setup", function () { - const noSort = ["attributes", "traits", "combatValues", "creatureSizeCategories"]; - - // Localize and sort CONFIG objects - for (const o of Object.keys(DS4.i18n)) { - const localized = Object.entries(DS4.i18n[o]).map((e) => { - return [e[0], game.i18n.localize(e[1] as string)]; - }); - if (!noSort.includes(o)) localized.sort((a, b) => a[1].localeCompare(b[1])); - DS4.i18n[o] = localized.reduce((obj, e) => { - obj[e[0]] = e[1]; - return obj; - }, {}); - } +Hooks.once("setup", () => { + localizeAndSortConfigObjects(); }); -Hooks.once("ready", function () { +Hooks.once("ready", () => { migration.migrate(); }); @@ -105,3 +93,24 @@ Hooks.once("ready", function () { }); }); }); + +/** + * Localizes all objects in {@link DS4.i18n} and sorts them unless they are explicitly excluded. + */ +function localizeAndSortConfigObjects() { + const noSort = ["attributes", "traits", "combatValues", "creatureSizeCategories"]; + + const localizeObject = (obj: T, sort = true): T => { + const localized = Object.entries(obj).map(([key, value]) => { + return [key, game.i18n.localize(value)]; + }); + if (sort) localized.sort((a, b) => a[1].localeCompare(b[1])); + return Object.fromEntries(localized); + }; + + DS4.i18n = Object.fromEntries( + Object.entries(DS4.i18n).map(([key, value]) => { + return [key, localizeObject(value, !noSort.includes(key))]; + }), + ) as typeof DS4.i18n; +} diff --git a/src/module/item/item-sheet.ts b/src/module/item/item-sheet.ts index 5afc372d..f32b6029 100644 --- a/src/module/item/item-sheet.ts +++ b/src/module/item/item-sheet.ts @@ -83,7 +83,7 @@ export class DS4ItemSheet extends ItemSheet { event.preventDefault(); if (this.item.isOwned) { - return ui.notifications.warn(game.i18n.localize("DS4.WarningManageActiveEffectOnOwnedItem")); + return ui.notifications?.warn(game.i18n.localize("DS4.WarningManageActiveEffectOnOwnedItem")); } const a = event.currentTarget; const li = $(a).parents(".effect"); @@ -93,7 +93,7 @@ export class DS4ItemSheet extends ItemSheet { return this._createActiveEffect(); case "edit": const effect = this.item.effects.get(li.data("effectId")); - return effect.sheet.render(true); + return effect?.sheet.render(true); case "delete": { return this.item.deleteEmbeddedEntity("ActiveEffect", li.data("effectId")); } diff --git a/src/module/migrations.ts b/src/module/migrations.ts index ec48294a..345ad263 100644 --- a/src/module/migrations.ts +++ b/src/module/migrations.ts @@ -1,7 +1,7 @@ import { migrate as migrate001 } from "./migrations/001"; async function migrate(): Promise { - if (!game.user.isGM) { + if (!game.user?.isGM) { return; } @@ -18,14 +18,14 @@ async function migrate(): Promise { } async function migrateFromTo(oldMigrationVersion: number, targetMigrationVersion: number): Promise { - if (!game.user.isGM) { + if (!game.user?.isGM) { return; } const migrationsToExecute = migrations.slice(oldMigrationVersion, targetMigrationVersion); if (migrationsToExecute.length > 0) { - ui.notifications.info( + ui.notifications?.info( game.i18n.format("DS4.InfoSystemUpdateStart", { currentVersion: oldMigrationVersion, targetVersion: targetMigrationVersion, @@ -40,7 +40,7 @@ async function migrateFromTo(oldMigrationVersion: number, targetMigrationVersion await migration(); game.settings.set("ds4", "systemMigrationVersion", currentMigrationVersion); } catch (err) { - ui.notifications.error( + ui.notifications?.error( game.i18n.format("DS4.ErrorDuringMigration", { currentVersion: oldMigrationVersion, targetVersion: targetMigrationVersion, @@ -54,7 +54,7 @@ async function migrateFromTo(oldMigrationVersion: number, targetMigrationVersion } } - ui.notifications.info( + ui.notifications?.info( game.i18n.format("DS4.InfoSystemUpdateCompleted", { currentVersion: oldMigrationVersion, targetVersion: targetMigrationVersion, diff --git a/src/module/migrations/001.ts b/src/module/migrations/001.ts index efc3637e..943aecc9 100644 --- a/src/module/migrations/001.ts +++ b/src/module/migrations/001.ts @@ -1,5 +1,5 @@ export async function migrate(): Promise { - for (const a of game.actors.entities) { + for (const a of game.actors?.entities ?? []) { const updateData = getActorUpdateData(); console.log(`Migrating actor ${a.name}`); await a.update(updateData, { enforceTypes: false }); @@ -18,7 +18,7 @@ function getActorUpdateData(): Record { "rangedAttack", "spellcasting", "targetedSpellcasting", - ].reduce((acc, curr) => { + ].reduce((acc: Partial>, curr) => { acc[curr] = { "-=base": null }; return acc; }, {}), diff --git a/src/module/rolls/check-factory.ts b/src/module/rolls/check-factory.ts index 21291e57..b0f007ea 100644 --- a/src/module/rolls/check-factory.ts +++ b/src/module/rolls/check-factory.ts @@ -131,34 +131,40 @@ async function askGmModifier( const renderedHtml = await renderTemplate(usedTemplate, templateData); const dialogPromise = new Promise((resolve) => { - new Dialog({ - title: usedTitle, - content: renderedHtml, - buttons: { - ok: { - icon: '', - label: game.i18n.localize("DS4.RollDialogOkButton"), - callback: (html) => { - if (!("jquery" in html)) { - throw new Error( - game.i18n.format("DS4.ErrorUnexpectedHtmlType", { - exType: "JQuery", - realType: "HTMLElement", - }), - ); - } else { - const innerForm = html[0].querySelector("form"); - resolve(innerForm); - } + new Dialog( + { + title: usedTitle, + content: renderedHtml, + buttons: { + ok: { + icon: '', + label: game.i18n.localize("DS4.RollDialogOkButton"), + callback: (html) => { + if (!("jquery" in html)) { + throw new Error( + game.i18n.format("DS4.ErrorUnexpectedHtmlType", { + exType: "JQuery", + realType: "HTMLElement", + }), + ); + } else { + const innerForm = html[0].querySelector("form"); + if (!innerForm) { + throw new Error(); // TODO: localize + } + resolve(innerForm); + } + }, + }, + cancel: { + icon: '', + label: game.i18n.localize("DS4.RollDialogCancelButton"), }, }, - cancel: { - icon: '', - label: game.i18n.localize("DS4.RollDialogCancelButton"), - }, + default: "ok", }, - default: "ok", - }).render(true); + { jQuery: true }, + ).render(true); }); const dialogForm = await dialogPromise; return parseDialogFormData(dialogForm); diff --git a/src/module/rolls/check.ts b/src/module/rolls/check.ts index 0fd84be2..12216ae6 100644 --- a/src/module/rolls/check.ts +++ b/src/module/rolls/check.ts @@ -56,8 +56,8 @@ export class DS4Check extends DiceTerm { } } - success = null; - failure = null; + success: boolean | null = null; + failure: boolean | null = null; targetValue = DS4Check.DEFAULT_TARGET_VALUE; minCritFailure = DS4Check.DEFAULT_MIN_CRIT_FAILURE; maxCritSuccess = DS4Check.DEFAULT_MAX_CRIT_SUCCESS; @@ -94,15 +94,15 @@ export class DS4Check extends DiceTerm { } /** Term Modifiers */ - noop(): this { - return this; + noop(): void { + return; } // DS4 only allows recursive explosions - explode(modifier: string): this { + explode(modifier: string): void { const rgx = /[xX]/; const match = modifier.match(rgx); - if (!match) return this; + if (!match) return; this.results = (this.results as Array) .map((r) => { diff --git a/src/module/rolls/roll-executor.ts b/src/module/rolls/roll-executor.ts index 8801170d..ea84bac8 100644 --- a/src/module/rolls/roll-executor.ts +++ b/src/module/rolls/roll-executor.ts @@ -11,7 +11,7 @@ import { calculateRollResult, isDiceSwapNecessary, isSlayingDiceRepetition, sepa export function ds4roll( checkTargetValue: number, rollOptions: Partial = {}, - dice: Array = null, + dice: Array = [], ): RollResult { if (checkTargetValue <= 20) { return rollCheckSingleDie(checkTargetValue, rollOptions, dice); @@ -36,11 +36,11 @@ export function ds4roll( export function rollCheckSingleDie( checkTargetValue: number, rollOptions: Partial, - dice: Array = null, + dice: Array = [], ): RollResult { const usedOptions = new DefaultRollOptions().mergeWith(rollOptions); - if (dice?.length != 1) { + if (dice.length != 1) { dice = [new DS4RollProvider().getNextRoll()]; } const usedDice = dice; @@ -75,13 +75,13 @@ export function rollCheckSingleDie( export function rollCheckMultipleDice( targetValue: number, rollOptions: Partial, - dice: Array = null, + dice: Array = [], ): RollResult { const usedOptions = new DefaultRollOptions().mergeWith(rollOptions); const remainderTargetValue = targetValue % 20; const numberOfDice = Math.ceil(targetValue / 20); - if (!dice || dice.length != numberOfDice) { + if (dice.length != numberOfDice) { dice = new DS4RollProvider().getNextRolls(numberOfDice); } const usedDice = dice; diff --git a/tsconfig.json b/tsconfig.json index f0f1205b..de75b335 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "esModuleInterop": true, "moduleResolution": "node", "forceConsistentCasingInFileNames": true, - "strict": false + "strict": true }, "include": ["src"] }