export interface AppConfig { server: { port: number; }; selenium: { remoteUrl: string; browser: string; }; cache: { basePath: string; }; addons: { directory: string; }; } export interface TocSelector { scope: string; linkPattern: string; } export interface ContentSelector { scope: string; } export type StealthStep = | { type: 'waitMs'; ms: number } | { type: 'waitForElement'; selector: string; timeoutMs?: number } | { type: 'click'; selector: string } | { type: 'scrollToBottom' }; export interface StealthConfig { enabled: boolean; /** @deprecated Use `steps` instead. Kept for backward compatibility. */ waitMs?: number; addons: string[]; steps?: StealthStep[]; } export interface DownloadConfig { parallelism: number; minContentBytes: number; } export interface NovelDefinition { slug: string; type: 'epub' | 'web-scraped'; source: { url?: string; // web-scraped TOC strategy: the table-of-contents page URL urls?: string[]; // epub: download URL(s) urlTemplate?: string; // web-scraped increment strategy: template with {n} placeholder, e.g. "https://example.com/chapter-{n}" startIndex?: number; // increment: chapter number of the first {n} value (default 1) }; selectors?: { toc?: TocSelector; content?: ContentSelector; }; stealth?: StealthConfig; download?: DownloadConfig; } export interface NovelsConfig { novels: NovelDefinition[]; }