Restore green merge gate: pnpm settings, deps, unbound-method

pnpm 10.32 stopped reading the "pnpm" field from package.json, so the
undici/picomatch overrides and the three GHSA suppressions had silently
stopped applying — only the stale lockfile still held undici at 7.24.8.
Move the surviving picomatch override to pnpm-workspace.yaml.

With the config live again, two high advisories surfaced:
- postcss was stuck at 8.5.15 (GHSA-r28c-9q8g-f849, patched in 8.5.18);
  nothing pinned it, so refresh to 8.5.25 within vite's range.
- undici GHSA-4cwx-7wf7-3272 needed >=7.29.0, but our ~7.24.0 pin existed
  because jsdom 29 crashed on undici 7.28+. jsdom 30 moved to undici ^8.9,
  so bump jsdom and drop both the pin and all three suppressions.

15 vulnerabilities (5 high, 3 suppressed) down to 1 moderate (smol-toml
via knip, below the --audit-level=high gate).

Separately, ports.ts declared its members with method shorthand, which
TypeScript treats as this-dependent, so oxlint's unbound-method fired
wherever a port was passed by reference (use-bestiary.ts:236). The ports
are bags of plain module functions, so declare them as readonly function
properties instead of suppressing the one call site. This makes parameter
types contravariant rather than bivariant; typecheck passes unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-08-05 13:24:13 +02:00
co-authored by Claude Opus 5
parent 78079bf1b2
commit 90eb39b227
5 changed files with 122 additions and 122 deletions
+1 -1
View File
@@ -27,7 +27,7 @@
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^6.0.1",
"jsdom": "^29.1.1",
"jsdom": "^30.0.1",
"tailwindcss": "^4.2.2",
"vite": "^8.0.16"
}
+26 -23
View File
@@ -9,18 +9,18 @@ import type {
} from "@initiative/domain";
export interface EncounterPersistence {
load(): Encounter | null;
save(encounter: Encounter): void;
readonly load: () => Encounter | null;
readonly save: (encounter: Encounter) => void;
}
export interface UndoRedoPersistence {
load(): UndoRedoState;
save(state: UndoRedoState): void;
readonly load: () => UndoRedoState;
readonly save: (state: UndoRedoState) => void;
}
export interface PlayerCharacterPersistence {
load(): PlayerCharacter[];
save(characters: PlayerCharacter[]): void;
readonly load: () => PlayerCharacter[];
readonly save: (characters: PlayerCharacter[]) => void;
}
export interface CachedSourceInfo {
@@ -31,31 +31,34 @@ export interface CachedSourceInfo {
}
export interface BestiaryCachePort {
cacheSource(
readonly cacheSource: (
system: string,
sourceCode: string,
displayName: string,
creatures: AnyCreature[],
): Promise<void>;
isSourceCached(system: string, sourceCode: string): Promise<boolean>;
getCachedSources(system?: string): Promise<CachedSourceInfo[]>;
clearSource(system: string, sourceCode: string): Promise<void>;
clearAll(): Promise<void>;
loadAllCachedCreatures(): Promise<Map<CreatureId, AnyCreature>>;
) => Promise<void>;
readonly isSourceCached: (
system: string,
sourceCode: string,
) => Promise<boolean>;
readonly getCachedSources: (system?: string) => Promise<CachedSourceInfo[]>;
readonly clearSource: (system: string, sourceCode: string) => Promise<void>;
readonly clearAll: () => Promise<void>;
readonly loadAllCachedCreatures: () => Promise<Map<CreatureId, AnyCreature>>;
}
export interface BestiaryIndexPort {
loadIndex(): BestiaryIndex;
getAllSourceCodes(): string[];
getDefaultFetchUrl(sourceCode: string, baseUrl?: string): string;
getSourceDisplayName(sourceCode: string): string;
readonly loadIndex: () => BestiaryIndex;
readonly getAllSourceCodes: () => string[];
readonly getDefaultFetchUrl: (sourceCode: string, baseUrl?: string) => string;
readonly getSourceDisplayName: (sourceCode: string) => string;
}
export interface Pf2eBestiaryIndexPort {
loadIndex(): Pf2eBestiaryIndex;
getAllSourceCodes(): string[];
getDefaultFetchUrl(sourceCode: string, baseUrl?: string): string;
getSourceDisplayName(sourceCode: string): string;
getCreaturePathsForSource(sourceCode: string): string[];
getCreatureNamesByPaths(paths: string[]): Map<string, string>;
readonly loadIndex: () => Pf2eBestiaryIndex;
readonly getAllSourceCodes: () => string[];
readonly getDefaultFetchUrl: (sourceCode: string, baseUrl?: string) => string;
readonly getSourceDisplayName: (sourceCode: string) => string;
readonly getCreaturePathsForSource: (sourceCode: string) => string[];
readonly getCreatureNamesByPaths: (paths: string[]) => Map<string, string>;
}