Enable no unused vars and add more types (#2005)
Some checks failed
Project CI / build (24.x) (push) Has been cancelled

This commit is contained in:
Carlos Fernandez 2026-06-14 16:10:49 -04:00 committed by GitHub
parent af49c1f4c8
commit 96f090bef5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 141 additions and 31 deletions

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"js/ts.preferGoToSourceDefinition": true
}

40
daggerheart.d.ts vendored
View file

@ -2,6 +2,7 @@ import '@client/global.mjs';
import '@common/global.mjs';
import '@common/primitives/global.mjs';
import Canvas from '@client/canvas/board.mjs';
import { ResourceUpdateMap } from './module/data/action/baseAction.mjs';
// Foundry's use of `Object.assign(globalThis) means many globally available objects are not read as such
// This declare global hopefully fixes that
@ -39,4 +40,43 @@ declare global {
const Collection: foundry.utils.Collection;
const FormDataExtended: foundry.applications.ux.FormDataExtended;
const TextEditor: foundry.applications.ux.TextEditor;
/**
* Data used to build rolls such as duality rolls. The definition is incomplete and likely incorrect.
* Objects will often accept a Partial<RollConfig> and spit out a non-partial. Those that are not guaranteed should be marked optional.
*/
interface RollConfig {
// unverified, check which ones are used and optional/not optional
event: Event;
title: string;
roll: {
modifier: number;
simple: boolean;
type: string;
difficulty: number;
};
hasDamage: boolean;
hasEffect: boolean;
hasRoll: boolean;
chatMessage: {
template: string;
mute: boolean;
};
targets: object;
costs: object;
// verified
source?: {
/** uuid of the actor this roll is coming from */
actor: string;
};
/** Roll data associated with the actor or item */
data: object;
resourceUpdates: ResourceUpdateMap;
hooks: string[];
dialog: {
configure: boolean;
};
damageOptions: object;
}
}

View file

@ -90,12 +90,26 @@ export default defineConfig([
},
rules: {
'no-undef': 'error',
// 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'no-unused-vars': [
'error',
{
args: 'none',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_[A-Z]',
ignoreRestSiblings: true
}
],
...stylisticRules
}
},
{
files: ['**/*.ts'],
extends: [js.configs.recommended, tseslint.configs.recommended]
extends: [js.configs.recommended, tseslint.configs.recommended],
plugins: {
'@stylistic': stylistic
},
rules: {
...stylisticRules
}
}
]);

View file

@ -8,7 +8,7 @@
}
},
"exclude": ["node_modules", "**/node_modules/*"],
"include": ["daggerheart.mjs", "foundry/client/client.mjs", "daggerheart.d.ts"],
"include": ["daggerheart.mjs", "foundry/client/client.mjs", "daggerheart.d.ts", "module/**/*.d.ts"],
"typeAcquisition": {
"include": ["jquery"]
}

View file

@ -176,7 +176,6 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
}
static updateData(event, _, formData) {
const form = foundry.utils.expandObject(formData.object);
this.render(true);
}

View file

@ -1,4 +1,3 @@
import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs';
import { getDeleteKeys, tagifyElement } from '../../helpers/utils.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;

View file

@ -1,12 +1,13 @@
import DhAppearance from '../../data/settings/Appearance.mjs';
import { getDiceSoNicePreset } from '../../config/generalConfig.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
/**
* @import DhAppearance from '../../data/settings/Appearance.mjs';
* @import {ApplicationClickAction} from "@client/applications/_types.mjs"
*/
/** Settings menu for appearance settings */
export default class DHAppearanceSettings extends HandlebarsApplicationMixin(ApplicationV2) {
/**@inheritdoc */
static DEFAULT_OPTIONS = {

View file

@ -0,0 +1,8 @@
import DhCompanion from '../../../data/actor/companion.mjs';
import DhpActor from '../../../documents/actor.mjs';
declare module './companion.mjs' {
export default interface DhCompanionSheet {
actor: DhpActor<DhCompanion>;
}
}

View file

@ -1,10 +1,12 @@
import { getDocFromElement, itemIsIdentical } from '../../../helpers/utils.mjs';
import DHBaseActorSettings from './actor-setting.mjs';
import DHApplicationMixin from './application-mixin.mjs';
const { ActorSheetV2 } = foundry.applications.sheets;
/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
/**
* @import DHBaseActorSettings from './actor-setting.mjs';
* @typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction
*/
/**
* A base actor sheet extending {@link ActorSheetV2} via {@link DHApplicationMixin}

14
module/data/actor/_types.d.ts vendored Normal file
View file

@ -0,0 +1,14 @@
import DhpActor from '../../documents/actor.mjs'
import DhCharacter from './character.mjs';
declare module './base.mjs' {
export default interface BaseDataActor {
parent: DhpActor<this>;
}
}
declare module './companion.mjs' {
export default interface DhCompanion {
partner: DhpActor<DhCharacter>;
}
}

View file

@ -1,9 +1,13 @@
import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs';
import DHItem from '../../documents/item.mjs';
import { createShallowProxy, getScrollTextData } from '../../helpers/utils.mjs';
const fields = foundry.data.fields;
/**
* @import DHItem from '../../documents/item.mjs';
* @import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs';
*/
/** Function to generate resistance fields for damage types */
const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) =>
new fields.SchemaField({
resistance: new fields.BooleanField({
@ -96,6 +100,8 @@ export const commonActorRules = (extendedData = { damageReduction: {}, attack: {
* @property {Boolean} isNPC - This data model represents a NPC?
* @property {typeof DHBaseActorSettings} settingSheet - The sheet class used to render the settings UI for this actor type.
*/
/** Base actor type data model for all actors in Daggerheart */
export default class BaseDataActor extends foundry.abstract.TypeDataModel {
/** @returns {ActorDataModelMetadata}*/
static get metadata() {

View file

@ -39,7 +39,7 @@ export default class FormulaField extends foundry.data.fields.StringField {
let roll = null;
try {
roll = new Roll(value.replace(/@([a-z.0-9_-]+)/gi, '1'));
} catch (_) {
} catch {
roll = new Roll(value.replace(/@([a-z.0-9_-]+)/gi, 'd6'));
}
roll.evaluateSync({ strict: false });

8
module/data/item/_types.d.ts vendored Normal file
View file

@ -0,0 +1,8 @@
import DHItem from '../../documents/item.mjs';
declare module './base.mjs' {
export default interface BaseDataItem {
parent: DHItem<this>;
actor: DhpActor;
}
}

View file

@ -149,7 +149,7 @@ export default class RegisteredTriggers extends Map {
const result = await command(...args);
if (result?.updates?.length) updates.push(...result.updates);
} catch (_) {
} catch {
const triggerName = game.i18n.localize(triggerData.label);
ui.notifications.error(
game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', {

View file

@ -23,6 +23,10 @@ export default class DHRoll extends Roll {
static DefaultDialog = D20RollDialog;
/**
* @param {Partial<RollConfig>} config
* @returns {Promise<RollConfig>}
*/
static async build(config = {}, message = {}) {
const roll = await this.buildConfigure(config, message);
if (!roll) return;
@ -34,6 +38,10 @@ export default class DHRoll extends Roll {
return config;
}
/**
* @param {Partial<RollConfig>} config
* @returns {Promise<RollConfig>}
*/
static async buildConfigure(config = {}, message = {}) {
config.hooks = [...this.getHooks(), ''];
config.dialog ??= {};

22
module/documents/_types.d.ts vendored Normal file
View file

@ -0,0 +1,22 @@
import BaseDataActor from '../data/actor/base.mjs'
import DHItem from './item.mjs';
import BaseDataItem from '../data/item/base.mjs';
import DhActiveEffect from './activeEffect.mjs';
import EmbeddedCollection from '@common/abstract/embedded-collection.mjs';
declare module './actor.mjs' {
export default interface DhpActor<T extends BaseDataActor = BaseDataActor> {
system: T;
items: EmbeddedCollection<DHItem>;
effects: EmbeddedCollection<DhActiveEffect>;
}
}
declare module './item.mjs' {
export default interface DHItem<T extends BaseDataItem = BaseDataItem> {
parent: DhpActor;
actor: DhpActor;
system: T;
effects: EmbeddedCollection<DhActiveEffect>;
}
}

View file

@ -212,7 +212,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
try {
const evl = new Function('sandbox', `with (sandbox) { return ${expression}}`);
result = evl(Roll.MATH_PROXY);
} catch (err) {
} catch {
return expression;
}

View file

@ -531,21 +531,7 @@ export default class DhpActor extends Actor {
}
/**
* @param {object} config
* @param {Event} config.event
* @param {string} config.title
* @param {object} config.roll
* @param {number} config.roll.modifier
* @param {boolean} [config.roll.simple=false]
* @param {string} [config.roll.type]
* @param {number} [config.roll.difficulty]
* @param {boolean} [config.hasDamage]
* @param {boolean} [config.hasEffect]
* @param {object} [config.chatMessage]
* @param {string} config.chatMessage.template
* @param {boolean} [config.chatMessage.mute]
* @param {object} [config.targets]
* @param {object} [config.costs]
* @param {Partial<RollConfig>} config
*/
async diceRoll(config) {
config.source = { ...(config.source ?? {}), actor: this.uuid };

View file

@ -49,7 +49,7 @@ export const renderFateButton = async event => {
const fateTypeData = getFateTypeData(button.dataset?.fatetype);
if (!fateTypeData) ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
const { value: fateType, label: fateTypeLabel } = fateTypeData;
const { value: fateType } = fateTypeData;
await enrichedFateRoll(
{

View file

@ -318,7 +318,7 @@ export function getDocFromElementSync(element) {
const target = element.closest('[data-item-uuid]');
try {
return foundry.utils.fromUuidSync(target.dataset.itemUuid) ?? null;
} catch (_) {
} catch {
return null;
}
}
@ -377,7 +377,7 @@ export const itemAbleRollParse = (value, actor, item) => {
try {
return Roll.replaceFormulaData(slicedValue, rollData);
} catch (_) {
} catch {
return '';
}
};