import { I_END_POINT , WATCH_END_POINT } from "../constants" ; import { getQueryParameter , HTTP } from "../common" ; import { Playlist , Video , SearchResult , LiveVideo , Channel , MixPlaylist } from "." ; import { SearchResultType } from "./SearchResult" ; import { RequestOptions } from "https" ; export namespace Client { export type SearchType = "video" | "channel" | "playlist" | "all" ; export type SearchOptions = { /** Search type, can be `"video"`, `"channel"`, `"playlist"`, or `"all"` */ type : SearchType ; /** Raw search params to be passed on the request, ignores `type` value if this is provided */ params : string ; } ; export type ClientOptions = { cookie : string ; /** Optional options for http client */ requestOptions : Partial < RequestOptions > ; /** Optional options passed when sending a request to youtube (context.client) */ youtubeClientOptions : Record < string , unknown > ; /** Use Node `https` module, set false to use `http` */ https : boolean ; } ; } /** Youtube Client */ export default class Client { hidden http : HTTP ; constructor ( options = { } ) { const fullOptions = { cookie : "" , https : true , requestOptions : { } , ... options , youtubeClientOptions : { hl : "en" , gl : "US" , ... options . youtubeClientOptions , } , } ; this . http = new HTTP ( fullOptions ) ; } param query param searchOptions async search < T extends Client . SearchOptions > ( query , searchOptions ? ) { const options = { type : "all" , params : "" , ... searchOptions , } ; const result = new SearchResult ( ) . load ( this ) ; await result . init ( query , options ) ; return result ; } return Can be  VideoCompact |  PlaylistCompact |  Channel | `undefined`
      async findOne < T extends Client . SearchOptions > ( query , searchOptions ? ) { return ( await this . search ( query , searchOptions ) ) . shift ( ) ; } /** Get playlist information and its videos by playlist id or URL */ async getPlaylist < T extends Playlist | MixPlaylist | undefined > ( playlistIdOrUrl ) { const playlistId = getQueryParameter ( playlistIdOrUrl , "list" ) ; if ( playlistId . startsWith ( "RD" ) ) { const response = await this . http . post ( `${ I_END_POINT }/next` , { data : { playlistId } , } ) ; if ( response . data . error ) { return undefined as T ; } return new MixPlaylist ( { client : this } ) . load ( response . data ) as T ; } const response = await this . http . post ( `${ I_END_POINT }/browse` , { data : { browseId : `VL${ playlistId }` } , } ) ; if ( response . data . error || response . data . alerts ?. shift ( ) ?. alertRenderer ?. type === "ERROR" ) { return undefined as T ; } return new Playlist ( { client : this } ) . load ( response . data ) as T ; } /** Get video information by video id or URL */ async getVideo < T extends Video | LiveVideo | undefined > ( videoIdOrUrl ) { const videoId = getQueryParameter ( videoIdOrUrl , "v" ) ; const response = await this . http . get ( `${ WATCH_END_POINT }` , { params : { v : videoId , pbj : "1" } , } ) ; if ( ! response . data [ 3 ] . response . contents ) return undefined as T ; return ( ! response . data [ 2 ] . playerResponse . playabilityStatus . liveStreamability ? new Video ( { client : this } ) . load ( response . data ) : new LiveVideo ( { client : this } ) . load ( response . data ) ) as T ; } /** Get channel information by channel id+ */ async getChannel ( channelId ) { const response = await this . http . post ( `${ I_END_POINT }/browse` , { data : { browseId : channelId } , } ) ; if ( response . data . error || response . data . alerts ?. shift ( ) ?. alertRenderer ?. type === "ERROR" ) { return undefined ; } return new Channel ( { client : this } ) . load ( response . data ) ; } }