Fix TypeScript errors under exactOptionalPropertyTypes

Use a local PdfJsXmpMetadata interface instead of the non-exported pdfjs
Metadata type, omit undefined optional fields in reconcileFingerprint, and
type discovery hook mocks with explicit DiscoveryCandidate return types.
This commit is contained in:
tegwick 2026-07-09 01:56:10 +02:00
parent 2b613f3f99
commit 1e549dd8ff
3 changed files with 20 additions and 10 deletions

View file

@ -6,7 +6,10 @@
*/ */
import { getDocument } from "pdfjs-dist"; import { getDocument } from "pdfjs-dist";
import type { Metadata } from "pdfjs-dist";
interface PdfJsXmpMetadata {
getAll(): Record<string, unknown>;
}
export interface PdfIntrinsicMetadata { export interface PdfIntrinsicMetadata {
readonly title?: string; readonly title?: string;
@ -72,7 +75,7 @@ export function mergeDocumentFields(
function normalizePdfMetadata( function normalizePdfMetadata(
info: Record<string, unknown>, info: Record<string, unknown>,
metadata: Metadata | null, metadata: PdfJsXmpMetadata | null,
): PdfIntrinsicMetadata { ): PdfIntrinsicMetadata {
const result: { const result: {
title?: string; title?: string;
@ -172,7 +175,9 @@ function pdfDateField(value: unknown): string | undefined {
return Number.isNaN(parsed.getTime()) ? trimmed : parsed.toISOString(); return Number.isNaN(parsed.getTime()) ? trimmed : parsed.toISOString();
} }
function xmpFields(metadata: Metadata | null): Record<string, string> | undefined { function xmpFields(
metadata: PdfJsXmpMetadata | null,
): Record<string, string> | undefined {
if (metadata === null) return undefined; if (metadata === null) return undefined;
const all = metadata.getAll() as Record<string, unknown>; const all = metadata.getAll() as Record<string, unknown>;
const xmp: Record<string, string> = {}; const xmp: Record<string, string> = {};

View file

@ -20,7 +20,7 @@ export function reconcileFingerprint(
return { return {
unchanged, unchanged,
previousFingerprint, ...(previousFingerprint !== undefined ? { previousFingerprint } : {}),
currentFingerprint, currentFingerprint,
requiresReanchor: !unchanged, requiresReanchor: !unchanged,
}; };

View file

@ -10,6 +10,7 @@ import {
reIngestAndCompare, reIngestAndCompare,
recoveryStateAfterLocalSearch, recoveryStateAfterLocalSearch,
searchCanonicalQuote, searchCanonicalQuote,
type DiscoveryCandidate,
} from "./index"; } from "./index";
describe("reconcileFingerprint", () => { describe("reconcileFingerprint", () => {
@ -77,15 +78,19 @@ describe("createSourceDiscoveryRegistry", () => {
const registry = createSourceDiscoveryRegistry(); const registry = createSourceDiscoveryRegistry();
registry.register({ registry.register({
name: "low", name: "low",
discover: vi.fn(async () => [ discover: vi.fn(
{ uri: "file:///a", confidence: 0.2, source: "local" }, async (): Promise<readonly DiscoveryCandidate[]> => [
]), { uri: "file:///a", confidence: 0.2, source: "local" },
],
),
}); });
registry.register({ registry.register({
name: "high", name: "high",
discover: vi.fn(async () => [ discover: vi.fn(
{ uri: "https://example.com/doc", confidence: 0.9, source: "external" }, async (): Promise<readonly DiscoveryCandidate[]> => [
]), { uri: "https://example.com/doc", confidence: 0.9, source: "external" },
],
),
}); });
const candidates = await registry.discover({ title: "Example" }); const candidates = await registry.discover({ title: "Example" });