// JS deobfuscator subsystem — mirrors NPE's player.js / sig / nsig pipeline. // // Production callers go through `player_manager` (mirrors NPE's // YoutubeJavaScriptPlayerManager): // * signature_timestamp(video_id) // * deobfuscate_signature(video_id, obfuscated) // * url_with_throttling_parameter_deobfuscated(video_id, url) // * throttling_parameter_cache_size() // * clear_all_caches() // * clear_throttling_parameters_cache() // // The other submodules (runtime / lexer / extractor / signature / nsig) are // kept `pub` because `tests/js_phase2_offline.rs` exercises them directly // from outside the crate. If the integration test gets folded into the // inline `#[cfg(test)]` blocks, these can drop to `pub(crate)`. pub mod extractor; pub mod lexer; pub mod nsig; pub mod player_manager; pub mod runtime; pub mod signature; use thiserror::Error; // Clone: PlayerManager's failure memo replays the original extraction // error on calls suppressed by the cooldown (mirrors NPE's cached // ParsingException fields). #[derive(Debug, Clone, Error)] pub enum DeobfError { #[error("could not fetch iframe_api: {0}")] FetchIframe(String), #[error("could not fetch embed page: {0}")] FetchEmbed(String), #[error("could not extract player.js URL")] PlayerUrlMissing, #[error("could not fetch player.js: {0}")] FetchPlayerCode(String), #[error("invalid player.js URL: {0}")] InvalidPlayerUrl(String), #[error("could not find sig deobf function via any pattern")] SigFuncNotFound, #[error("could not parse sig deobf function body: {0}")] SigBodyParseFailed(String), #[error("could not find sig helper object")] SigHelperMissing, #[error("could not find sig global array")] SigGlobalArrayMissing, #[error("could not extract signature timestamp")] SigTimestampMissing, #[error("could not find nsig deobf function via any pattern")] NsigFuncNotFound, #[error("could not parse nsig deobf function body: {0}")] NsigBodyParseFailed(String), #[error("nsig array indirection failed: {0}")] NsigArrayLookupFailed(String), #[error("js compile failed: {0}")] JsCompileFailed(String), #[error("js runtime failed: {0}")] JsRuntimeFailed(String), #[error("nsig output was empty (function neutered?)")] NsigEmpty, #[error("nsig output equalled its input (identity — deobfuscator neutered?)")] NsigIdentity, #[error("downloader not initialized")] DownloaderMissing, } pub use player_manager::PlayerManager;