diff --git a/.github/discord.js b/.github/discord.js new file mode 100644 index 0000000..332c651 --- /dev/null +++ b/.github/discord.js @@ -0,0 +1,70 @@ +const bot_token = process.env['BOT_TOKEN'] +const { request } = require('https') + +let tag = undefined, body = undefined, channel = undefined; + +process.argv.forEach((arg) => { + const [ key, value ] = arg.split('=') + if(key === 'tag') tag = value + if(key === 'body') body = value + if(key === 'channel') channel = value +}) + +if(!tag || !body || !channel) { + console.log(`Some args are missing`) + process.exit(1) +} +else if(!bot_token) { + console.log('Bot Token is missing') + process.exit(1) +}; + +(async() => { + const body_args = body.replaceAll('\r', '').split('- [x]') + body_args.shift() + body_args.unshift('**Change Log :-**\n') + const description = body_args.join('\n') + const embed = { + title : tag, + url : `https://github.com/play-dl/play-dl/releases/tag/${tag}`, + description : description, + color : 0x00FF00 + } + + const payload = { + embeds : [embed] + } + + console.log(payload) + + const x = await https_getter(`https://discord.com/api/v9/channels/${channel}/messages`, { + headers : { + "Authorization" : `Bot ${bot_token}`, + "content-type" : "application/json" + }, + method : "POST", + body : JSON.stringify(payload) + }) + console.log(x.statusCode) + process.exit(0) +})() + +function https_getter(req_url, options = {}) { + return new Promise((resolve, reject) => { + const s = new URL(req_url); + options.method ??= 'GET'; + const req_options = { + host: s.hostname, + path: s.pathname + s.search, + headers: options.headers ?? {}, + method: options.method + }; + + const req = request(req_options, resolve); + req.on('error', (err) => { + reject(err); + }); + if (options.method === 'POST') req.write(options.body); + req.end(); + }); +} \ No newline at end of file diff --git a/.github/docs.js b/.github/docs.js new file mode 100644 index 0000000..4fc46cd --- /dev/null +++ b/.github/docs.js @@ -0,0 +1,12 @@ +const fs = require('fs') + +const path = "play-dl/index.ts" + +if(!fs.existsSync(path)) { + console.log('File Missing') + process.exit(1) +} + +const oldData = fs.readFileSync(path, 'utf-8') + +fs.writeFileSync(path, oldData.split('// Export Default ')[0]) \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1cb45b4..9e049b8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,6 +42,9 @@ jobs: - name: Install Dependencies run: npm install + - name: Deleting default exports for ESM. + run: node .github/docs.js + - name: TypeDoc run: npx typedoc @@ -53,3 +56,17 @@ jobs: git add * git commit -m "Automated Docs" git push + + publish_discord: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: 16 + registry-url: 'https://registry.npmjs.org' + + - name: Publish on discord + run: node .github/discord.js channel="888999793458835466" body="${{ github.event.release.body }}" tag="${{ github.event.release.tag_name }}" + env: + BOT_TOKEN: ${{ secrets.BOT_TOKEN }} \ No newline at end of file diff --git a/play-dl/YouTube/utils/extractor.ts b/play-dl/YouTube/utils/extractor.ts index b7b7004..405a7c8 100644 --- a/play-dl/YouTube/utils/extractor.ts +++ b/play-dl/YouTube/utils/extractor.ts @@ -16,7 +16,7 @@ const video_id_pattern = /^[a-zA-Z\d_-]{11,12}$/; const playlist_id_pattern = /^(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}$/; const DEFAULT_API_KEY = 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8'; const video_pattern = - /^((?:https?:)?\/\/)?(?:(?:www|m)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|shorts\/|embed\/|v\/)?)([\w\-]+)(\S+)?$/; + /^((?:https?:)?\/\/)?(?:(?:www|m|music)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|shorts\/|embed\/|v\/)?)([\w\-]+)(\S+)?$/; const playlist_pattern = /^((?:https?:)?\/\/)?(?:(?:www|m)\.)?(youtube\.com)\/(?:(playlist|watch))(.*)?((\?|\&)list=)(PL|UU|LL|RD|OL)[a-zA-Z\d_-]{10,}(.*)?$/; /** diff --git a/play-dl/index.ts b/play-dl/index.ts index 1700139..3fe6c69 100644 --- a/play-dl/index.ts +++ b/play-dl/index.ts @@ -1,4 +1,4 @@ -export { +import { playlist_info, video_basic_info, video_info, @@ -11,7 +11,7 @@ export { YouTubePlayList, YouTubeVideo } from './YouTube'; -export { +import { spotify, sp_validate, refreshToken, @@ -19,27 +19,34 @@ export { SpotifyAlbum, SpotifyPlaylist, SpotifyTrack, - Spotify + Spotify, + SpotifyAuthorize, + sp_search } from './Spotify'; -export { +import { soundcloud, so_validate, SoundCloud, SoundCloudStream, getFreeClientID, SoundCloudPlaylist, - SoundCloudTrack + SoundCloudTrack, + check_id, + so_search, + stream as so_stream, + stream_from_info as so_stream_info } from './SoundCloud'; -export { +import { deezer, dz_validate, dz_advanced_track_search, Deezer, DeezerTrack, DeezerPlaylist, - DeezerAlbum + DeezerAlbum, + dz_search } from './Deezer'; -export { setToken } from './token'; +import { setToken } from './token'; enum AudioPlayerStatus { Idle = 'idle', @@ -62,35 +69,16 @@ interface SearchOptions { import { createInterface } from 'node:readline'; import { existsSync, mkdirSync, writeFileSync } from 'node:fs'; -import { - sp_validate, - yt_validate, - so_validate, - YouTubeStream, - SoundCloudStream, - YouTube, - SoundCloud, - Spotify -} from '.'; -import { SpotifyAuthorize, sp_search } from './Spotify'; -import { check_id, so_search, stream as so_stream, stream_from_info as so_stream_info } from './SoundCloud'; import { stream as yt_stream, StreamOptions, stream_from_info as yt_stream_info } from './YouTube/stream'; -import { SoundCloudPlaylist, SoundCloudTrack } from './SoundCloud/classes'; import { yt_search } from './YouTube/search'; import { EventEmitter } from 'stream'; -import { Deezer, dz_search, dz_validate } from './Deezer'; import { InfoData } from './YouTube/utils/constants'; -import { YouTubeVideo } from './YouTube/classes/Video'; -import { YouTubePlayList } from './YouTube/classes/Playlist'; -import { YouTubeChannel } from './YouTube/classes/Channel'; -import { SpotifyAlbum, SpotifyPlaylist, SpotifyTrack } from './Spotify/classes'; -import { DeezerAlbum, DeezerPlaylist, DeezerTrack } from './Deezer/classes'; -export async function stream( +async function stream( url: string, options: { seek?: number; seekMode?: 'precise' | 'granular' } & StreamOptions ): Promise; -export async function stream(url: string, options?: StreamOptions): Promise; +async function stream(url: string, options?: StreamOptions): Promise; /** * Creates a Stream [ YouTube or SoundCloud ] class from a url for playing. * @@ -118,7 +106,7 @@ export async function stream(url: string, options?: StreamOptions): Promise { +async function stream(url: string, options: StreamOptions = {}): Promise { if (url.length === 0) throw new Error('Stream URL has a length of 0. Check your url again.'); if (options.htmldata) return await yt_stream(url, options); if (url.indexOf('spotify') !== -1) { @@ -135,56 +123,56 @@ export async function stream(url: string, options: StreamOptions = {}): Promise< else return await yt_stream(url, options); } -export async function search( +async function search( query: string, options: { source: { deezer: 'album' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { deezer: 'playlist' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { deezer: 'track' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { soundcloud: 'albums' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { soundcloud: 'playlists' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { soundcloud: 'tracks' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { spotify: 'album' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { spotify: 'playlist' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { spotify: 'track' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { youtube: 'channel' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { youtube: 'playlist' } } & SearchOptions ): Promise; -export async function search( +async function search( query: string, options: { source: { youtube: 'video' } } & SearchOptions ): Promise; -export async function search(query: string, options: { limit: number } & SearchOptions): Promise; -export async function search(query: string, options?: SearchOptions): Promise; +async function search(query: string, options: { limit: number } & SearchOptions): Promise; +async function search(query: string, options?: SearchOptions): Promise; /** * Searches through a particular source and gives respective info. * @@ -214,7 +202,7 @@ export async function search(query: string, options?: SearchOptions): Promise { @@ -228,8 +216,8 @@ export async function search( else throw new Error('Not possible to reach Here LOL. Easter Egg of play-dl if someone get this.'); } -export async function stream_from_info(info: SoundCloudTrack, options?: StreamOptions): Promise; -export async function stream_from_info(info: InfoData, options?: StreamOptions): Promise; +async function stream_from_info(info: SoundCloudTrack, options?: StreamOptions): Promise; +async function stream_from_info(info: InfoData, options?: StreamOptions): Promise; /** * Creates a Stream [ YouTube or SoundCloud ] class from video or track info for playing. * @@ -260,7 +248,7 @@ export async function stream_from_info(info: InfoData, options?: StreamOptions): * - `boolean` htmldata : given data is html data or not * @returns A {@link YouTubeStream} or {@link SoundCloudStream} Stream to play */ -export async function stream_from_info( +async function stream_from_info( info: InfoData | SoundCloudTrack, options: StreamOptions = {} ): Promise { @@ -280,7 +268,7 @@ export async function stream_from_info( * 'so_playlist' / 'so_track' | 'sp_track' | 'sp_album' | 'sp_playlist' | 'dz_track' | 'dz_playlist' | 'dz_album' | 'yt_video' | 'yt_playlist' | 'search' | false * ``` */ -export async function validate( +async function validate( url: string ): Promise< | 'so_playlist' @@ -325,7 +313,7 @@ export async function validate( * * Just run the above command and you will get a interface asking some questions. */ -export function authorization(): void { +function authorization(): void { const ask = createInterface({ input: process.stdin, output: process.stdout @@ -444,7 +432,7 @@ export function authorization(): void { * @param player discordjs voice AudioPlayer * @param resource A {@link YouTubeStream} or {@link SoundCloudStream} */ -export function attachListeners(player: EventEmitter, resource: YouTubeStream | SoundCloudStream) { +function attachListeners(player: EventEmitter, resource: YouTubeStream | SoundCloudStream) { // cleanup existing listeners if they are still registered type listenerType = (...args: any[]) => void; @@ -472,22 +460,49 @@ export function attachListeners(player: EventEmitter, resource: YouTubeStream | player.once(AudioPlayerStatus.Idle, idleListener); } -import { +// Export Main Commands +export { + DeezerAlbum, + DeezerPlaylist, + DeezerTrack, + SoundCloudPlaylist, + SoundCloudStream, + SoundCloudTrack, + SpotifyAlbum, + SpotifyPlaylist, + SpotifyTrack, + YouTubeChannel, + YouTubePlayList, + YouTubeVideo, + attachListeners, + authorization, decipher_info, deezer, dz_advanced_track_search, + dz_validate, extractID, getFreeClientID, is_expired, playlist_info, refreshToken, + search, setToken, + so_validate, soundcloud, spotify, + sp_validate, + stream, + stream_from_info, + validate, video_basic_info, - video_info -} from '.'; + video_info, + yt_validate +} +// Export Types +export { Deezer, YouTube, SoundCloud, Spotify } + +// Export Default export default { DeezerAlbum, DeezerPlaylist,