import { AUDIO_FORMATS, VIDEO_CONTAINERS, VIDEO_CODECS, SPONSORBLOCK_CATEGORIES, DEFAULT_DOWNLOAD_OPTIONS, type DownloadOptions, type SponsorBlockCategory, type AudioFormat, type VideoContainer, type VideoCodecPref } from '@shared/ipc' // Coerce an untrusted partial into a valid DownloadOptions, falling back to the // defaults for any missing/invalid field. Used both to migrate older settings // files (which predate downloadOptions) and to validate renderer writes. Lives // in its own module (not settings.ts) so the settings field schemas (CC9) can // reuse it without an import cycle. export function sanitizeOptions(input: unknown): DownloadOptions { const o = (input && typeof input === 'object' ? input : {}) as Partial const d = DEFAULT_DOWNLOAD_OPTIONS const bool = (v: unknown, fallback: boolean): boolean => (typeof v === 'boolean' ? v : fallback) const cats = Array.isArray(o.sponsorBlockCategories) ? (o.sponsorBlockCategories.filter((c) => (SPONSORBLOCK_CATEGORIES as readonly string[]).includes(c) ) as SponsorBlockCategory[]) : d.sponsorBlockCategories return { audioFormat: (AUDIO_FORMATS as readonly string[]).includes(o.audioFormat as string) ? (o.audioFormat as AudioFormat) : d.audioFormat, videoContainer: (VIDEO_CONTAINERS as readonly string[]).includes(o.videoContainer as string) ? (o.videoContainer as VideoContainer) : d.videoContainer, preferredVideoCodec: (VIDEO_CODECS as readonly string[]).includes( o.preferredVideoCodec as string ) ? (o.preferredVideoCodec as VideoCodecPref) : d.preferredVideoCodec, formatSort: typeof o.formatSort === 'string' ? o.formatSort.trim() : d.formatSort, embedSubtitles: bool(o.embedSubtitles, d.embedSubtitles), subtitleLanguages: typeof o.subtitleLanguages === 'string' && o.subtitleLanguages.trim() ? o.subtitleLanguages.trim() : d.subtitleLanguages, autoSubtitles: bool(o.autoSubtitles, d.autoSubtitles), sponsorBlock: bool(o.sponsorBlock, d.sponsorBlock), sponsorBlockMode: o.sponsorBlockMode === 'mark' ? 'mark' : 'remove', sponsorBlockCategories: cats, embedChapters: bool(o.embedChapters, d.embedChapters), splitChapters: bool(o.splitChapters, d.splitChapters), embedMetadata: bool(o.embedMetadata, d.embedMetadata), metadataTitle: typeof o.metadataTitle === 'string' ? o.metadataTitle : undefined, metadataArtist: typeof o.metadataArtist === 'string' ? o.metadataArtist : undefined, metadataAlbum: typeof o.metadataAlbum === 'string' ? o.metadataAlbum : undefined, embedThumbnail: bool(o.embedThumbnail, d.embedThumbnail), cropThumbnail: bool(o.cropThumbnail, d.cropThumbnail), writeInfoJson: bool(o.writeInfoJson, d.writeInfoJson), writeThumbnailFile: bool(o.writeThumbnailFile, d.writeThumbnailFile), writeDescription: bool(o.writeDescription, d.writeDescription) } }