diff --git a/package.json b/package.json index fffec43..160c880 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "lib/" ], "scripts": { - "test": "yarn build && cd test && node index.js", + "test": "cd test && ts-node index.ts", "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", "lint": "tslint -p tsconfig.json", @@ -71,6 +71,7 @@ "discord.js-docgen": "discordjs/docgen#ts-patch", "jsdoc-babel": "^0.5.0", "prettier": "^2.2.1", + "ts-node": "^10.0.0", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", "typescipt": "^1.0.0", diff --git a/src/Player.ts b/src/Player.ts index d10a9f7..cb0ff5c 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,202 +1 @@ -import { EventEmitter } from 'events'; -import { Client, Collection, Snowflake, Message, Collector } from 'discord.js'; -import Util from './utils/Util'; -import Queue from './Structures/Queue'; -import Track from './Structures/Track'; -import PlayerError from './utils/PlayerError'; -import { ExtractorModel } from './Structures/ExtractorModel'; -import ytdl from 'discord-ytdl-core'; -import { PlayerEvents, PlayerErrorEventCodes } from './utils/Constants'; - -export class Player extends EventEmitter { - public client: Client; - public queues = new Collection(); - public Extractors = new Collection(); - private _cooldownsTimeout = new Collection(); - private _resultsCollectors = new Collection>(); - - constructor(client: Client) { - super(); - - Object.defineProperty(this, 'client', { - value: client, - enumerable: false - }); - - Util.alertFFmpeg(); - } - - public createQueue(message: Message) { - return new Promise((resolve) => { - if (this.queues.has(message.guild.id)) return this.queues.get(message.guild.id); - const channel = message.member.voice?.channel; - if (!channel) - return void this.emit( - PlayerEvents.ERROR, - new PlayerError( - 'Voice connection is not available in this server!', - PlayerErrorEventCodes.NOT_CONNECTED, - message - ) - ); - - const queue = new Queue(this, message.guild); - void this.queues.set(message.guild.id, queue); - - channel - .join() - .then((connection) => { - this.emit(PlayerEvents.CONNECTION_CREATE, message, connection); - - queue.voiceConnection = connection; - if (queue.options.setSelfDeaf) connection.voice.setSelfDeaf(true); - this.emit(PlayerEvents.QUEUE_CREATE, message, queue); - resolve(queue); - }) - .catch((err) => { - this.queues.delete(message.guild.id); - this.emit( - PlayerEvents.ERROR, - new PlayerError(err.message ?? err, PlayerErrorEventCodes.UNABLE_TO_JOIN, message) - ); - }); - - return queue; - }); - } - - public getQueue(message: Message) { - return this.queues.get(message.guild.id) ?? null; - } - - async play(message: Message, query: string | Track, firstResult?: boolean): Promise { - if (!message) throw new PlayerError('Play function needs message'); - if (!query) throw new PlayerError('Play function needs search query as a string or Player.Track object'); - - if (this._cooldownsTimeout.has(`end_${message.guild.id}`)) { - clearTimeout(this._cooldownsTimeout.get(`end_${message.guild.id}`)); - this._cooldownsTimeout.delete(`end_${message.guild.id}`); - } - - if (typeof query === 'string') query = query.replace(/<(.+)>/g, '$1'); - let track; - - const queue = this.getQueue(message); - - if (query instanceof Track) track = query; - else { - if (ytdl.validateURL(query)) { - const info = await ytdl.getBasicInfo(query).catch(() => {}); - if (!info) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - if (info.videoDetails.isLiveContent && !queue.options.enableLive) - return void this.emit( - PlayerEvents.ERROR, - new PlayerError('Live video is not enabled!', PlayerErrorEventCodes.LIVE_VIDEO, message) - ); - const lastThumbnail = info.videoDetails.thumbnails[info.videoDetails.thumbnails.length - 1]; - - track = new Track(this, { - title: info.videoDetails.title, - description: info.videoDetails.description, - author: info.videoDetails.author.name, - url: info.videoDetails.video_url, - thumbnail: lastThumbnail.url, - duration: Util.buildTimeCode(Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)), - views: parseInt(info.videoDetails.viewCount), - requestedBy: message.author, - fromPlaylist: false, - source: 'youtube', - live: Boolean(info.videoDetails.isLiveContent) - }); - } else { - for (const [_, extractor] of this.Extractors) { - if (extractor.validate(query)) { - const data = await extractor.handle(query); - if (data) { - track = new Track(this, { - title: data.title, - description: data.description, - duration: Util.buildTimeCode(Util.parseMS(data.duration)), - thumbnail: data.thumbnail, - author: data.author, - views: data.views, - engine: data.engine, - source: 'arbitrary', - fromPlaylist: false, - requestedBy: message.author, - url: data.url - }); - - if (extractor.important) break; - } - } - } - - if (!track) track = await this.searchTracks(message, query, firstResult); - } - } - - if (track) { - if (queue) { - const q = queue.addTrack(track); - this.emit(PlayerEvents.TRACK_ADD, message, q, q.tracks[q.tracks.length - 1]); - } else { - const q = queue.addTrack(track); - if (q) this.emit(PlayerEvents.TRACK_START, message, q.tracks[0], q); - - // todo: start playing - } - } - } - - private searchTracks(message: Message, query: string, firstResult?: boolean): Promise { - return new Promise(async (resolve) => { - let tracks: Track[] = []; - const queryType = Util.getQueryType(query); - - switch (queryType) { - default: - tracks = await Util.ytSearch(query, { user: message.author, player: this }); - } - - if (tracks.length < 1) return void this.emit(PlayerEvents.NO_RESULTS, message, query); - if (firstResult || tracks.length === 1) return resolve(tracks[0]); - - const collectorString = `${message.author.id}-${message.channel.id}`; - const currentCollector = this._resultsCollectors.get(collectorString); - if (currentCollector) currentCollector.stop(); - - const collector = message.channel.createMessageCollector((m) => m.author.id === message.author.id, { - time: 60000 - }); - - this._resultsCollectors.set(collectorString, collector); - - this.emit(PlayerEvents.SEARCH_RESULTS, message, query, tracks, collector); - - collector.on('collect', ({ content }) => { - if (content === 'cancel') { - collector.stop(); - return void this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); - } - - if (!isNaN(content) && parseInt(content) >= 1 && parseInt(content) <= tracks.length) { - const index = parseInt(content, 10); - const track = tracks[index - 1]; - collector.stop(); - resolve(track); - } else { - this.emit(PlayerEvents.SEARCH_INVALID_RESPONSE, message, query, tracks, content, collector); - } - }); - - collector.on('end', (_, reason) => { - if (reason === 'time') { - this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); - } - }); - }); - } -} - -export default Player; +export {}; diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index 578470a..cb0ff5c 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -1,70 +1 @@ -import { ExtractorModelData } from '../types/types'; - -class ExtractorModel { - name: string; - private _raw: any; - - /** - * Model for raw Discord Player extractors - * @param {String} extractorName Name of the extractor - * @param {Object} data Extractor object - */ - constructor(extractorName: string, data: any) { - /** - * The extractor name - * @type {String} - */ - this.name = extractorName; - - Object.defineProperty(this, '_raw', { value: data, configurable: false, writable: false, enumerable: false }); - } - - /** - * Method to handle requests from `Player.play()` - * @param {String} query Query to handle - * @returns {Promise} - */ - async handle(query: string): Promise { - const data = await this._raw.getInfo(query); - if (!data) return null; - - return { - title: data.title, - duration: data.duration, - thumbnail: data.thumbnail, - engine: data.engine, - views: data.views, - author: data.author, - description: data.description, - url: data.url - }; - } - - /** - * Method used by Discord Player to validate query with this extractor - * @param {String} query The query to validate - * @returns {Boolean} - */ - validate(query: string): boolean { - return Boolean(this._raw.validate(query)); - } - - /** - * The extractor version - * @type {String} - */ - get version(): string { - return this._raw.version ?? '0.0.0'; - } - - /** - * If player should mark this extractor as important - * @type {Boolean} - */ - get important(): boolean { - return Boolean(this._raw.important); - } -} - -export default ExtractorModel; -export { ExtractorModel }; +export {}; diff --git a/src/Structures/Playlist.ts b/src/Structures/Playlist.ts index 804776c..cb0ff5c 100644 --- a/src/Structures/Playlist.ts +++ b/src/Structures/Playlist.ts @@ -1,11 +1 @@ -import Player from '../Player'; - -export class Playlist { - player: Player; - - constructor(player: Player, data: any) { - Object.defineProperty(this, 'player', { value: player }); - } -} - -export default Playlist; +export {}; diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 6ed849d..cb0ff5c 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -1,42 +1 @@ -import { Guild, Message, VoiceConnection } from 'discord.js'; -import { Player } from '../Player'; -import { PlayerOptions } from '../types/types'; -import Track from './Track'; -import { PlayerError } from '../utils/PlayerError'; - -export class Queue { - player: Player; - guild: Guild; - firstMessage: Message; - options: PlayerOptions = {}; - tracks: Track[] = []; - voiceConnection: VoiceConnection = null; - - constructor(player: Player, guild: Guild) { - Object.defineProperty(this, 'player', { value: player, enumerable: false }); - - this.guild = guild; - } - - get playing() { - return this.tracks[0]; - } - - async play(message: Message, query: string | Track, firstResult?: boolean) { - return await this.player.play(message, query, firstResult); - } - - addTrack(track: Track) { - if (!track || !(track instanceof Track)) throw new PlayerError('No track specified to add to the queue'); - this.tracks.push(track); - return this; - } - - addTracks(tracks: Track[]) { - this.tracks.push(...tracks); - - return this; - } -} - -export default Queue; +export {}; diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index ed146b5..cb0ff5c 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,13 +1 @@ -import { Message } from 'discord.js'; -import { Player } from '../Player'; - -export class Track { - readonly player: Player; - readonly message: Message; - - constructor(player: Player, data: any) { - Object.defineProperty(this, 'player', { value: player, enumerable: false }); - } -} - -export default Track; +export {}; diff --git a/src/VoiceNative/VoiceAdapter.ts b/src/VoiceNative/VoiceAdapter.ts deleted file mode 100644 index 7bab0a6..0000000 --- a/src/VoiceNative/VoiceAdapter.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { DiscordGatewayAdapterCreator, DiscordGatewayAdapterLibraryMethods } from '@discordjs/voice'; -import { - VoiceChannel, - Snowflake, - Client, - Constants, - WebSocketShard, - Guild, - StageChannel, - Collection -} from 'discord.js'; -import { GatewayVoiceServerUpdateDispatchData, GatewayVoiceStateUpdateDispatchData } from 'discord-api-types/v8'; - -class VoiceAdapter { - public client: Client; - public adapters = new Collection(); - public clients = new Set(); - public guilds = new Collection>(); - - constructor(client: Client) { - this.client = client; - - Object.defineProperty(this, 'client', { - enumerable: false, - writable: true, - configurable: true - }); - } - - trackVoiceState() { - if (this.clients.has(this.client)) return; - this.clients.add(this.client); - - this.client.ws.on('VOICE_STATE_UPDATE', (data: GatewayVoiceServerUpdateDispatchData) => { - this.adapters.get(data.guild_id)?.onVoiceServerUpdate(data); - }); - - this.client.ws.on(Constants.WSEvents.VOICE_STATE_UPDATE, (payload: GatewayVoiceStateUpdateDispatchData) => { - if (payload.guild_id && payload.session_id && payload.user_id === this.client.user?.id) { - this.adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload); - } - }); - } - - cleanupGuilds(shard: WebSocketShard) { - const guilds = this.guilds.get(shard); - if (guilds) { - for (const guildID of guilds.values()) { - this.adapters.get(guildID)?.destroy(); - } - } - } - - trackGuild(guild: Guild) { - let guilds = this.guilds.get(guild.shard); - if (!guilds) { - const cleanup = () => this.cleanupGuilds(guild.shard); - guild.shard.on('close', cleanup); - guild.shard.on('destroyed', cleanup); - guilds = new Set(); - this.guilds.set(guild.shard, guilds); - } - - guilds.add(guild.id); - } -} - -export default function createAdapter(channel: VoiceChannel | StageChannel): DiscordGatewayAdapterCreator { - return (methods) => { - const adapter = new VoiceAdapter(channel.client); - adapter.adapters.set(channel.guild.id, methods); - adapter.trackVoiceState(); - adapter.trackGuild(channel.guild); - - return { - sendPayload(data) { - if (channel.guild.shard.status === Constants.Status.READY) { - channel.guild.shard.send(data); - return true; - } - - return false; - }, - destroy() { - return adapter.adapters.delete(channel.guild.id); - } - }; - }; -} diff --git a/src/VoiceNative/VoiceSubscriptionManager.ts b/src/VoiceNative/VoiceSubscriptionManager.ts deleted file mode 100644 index d1e61ea..0000000 --- a/src/VoiceNative/VoiceSubscriptionManager.ts +++ /dev/null @@ -1 +0,0 @@ -class VoiceSubscriptionManager {} diff --git a/src/index.ts b/src/index.ts index 4dd3a82..cb0ff5c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1 @@ -export { AudioFilters } from './utils/AudioFilters'; -export * as Constants from './utils/Constants'; -export { ExtractorModel } from './Structures/ExtractorModel'; -export { Player } from './Player'; -export { Util } from './utils/Util'; -export { Track } from './Structures/Track'; -export { Queue } from './Structures/Queue'; -export * from './types/types'; -export { PlayerError } from './utils/PlayerError'; +export {}; diff --git a/src/types/types.ts b/src/types/types.ts index 546be00..cb0ff5c 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,158 +1 @@ -import { downloadOptions } from 'ytdl-core'; -import { User } from 'discord.js'; -import { Readable, Duplex } from 'stream'; - -export interface PlayerOptions { - leaveOnEnd?: boolean; - leaveOnEndCooldown?: number; - leaveOnStop?: boolean; - leaveOnEmpty?: boolean; - leaveOnEmptyCooldown?: number; - setSelfDeaf?: boolean; - enableLive?: boolean; - ytdlDownloadOptions?: downloadOptions; - useSafeSearch?: boolean; - disableAutoRegister?: boolean; -} - -export type FiltersName = keyof QueueFilters; - -export type TrackSource = 'soundcloud' | 'youtube' | 'arbitrary'; - -export interface TrackData { - title: string; - description: string; - author: string; - url: string; - thumbnail: string; - duration: string; - views: number; - requestedBy: User; - fromPlaylist: boolean; - source?: TrackSource; - engine?: any; - live?: boolean; -} - -export type QueueFilters = { - bassboost?: boolean; - '8D'?: boolean; - vaporwave?: boolean; - nightcore?: boolean; - phaser?: boolean; - tremolo?: boolean; - vibrato?: boolean; - reverse?: boolean; - treble?: boolean; - normalizer?: boolean; - surrounding?: boolean; - pulsator?: boolean; - subboost?: boolean; - karaoke?: boolean; - flanger?: boolean; - gate?: boolean; - haas?: boolean; - mcompand?: boolean; - mono?: boolean; - mstlr?: boolean; - mstrr?: boolean; - compressor?: boolean; - expander?: boolean; - softlimiter?: boolean; - chorus?: boolean; - chorus2d?: boolean; - chorus3d?: boolean; - fadein?: boolean; -}; - -export type QueryType = - | 'soundcloud_track' - | 'soundcloud_playlist' - | 'spotify_song' - | 'spotify_album' - | 'spotify_playlist' - | 'youtube_video' - | 'youtube_playlist' - | 'vimeo' - | 'facebook' - | 'reverbnation' - | 'attachment' - | 'youtube_search'; - -export interface ExtractorModelData { - title: string; - duration: number; - thumbnail: string; - engine: string | Readable | Duplex; - views: number; - author: string; - description: string; - url: string; - version?: string; - important?: boolean; -} - -export interface PlayerProgressbarOptions { - timecodes?: boolean; - queue?: boolean; - length?: number; - line?: string; - indicator?: string; -} - -export interface LyricsData { - title: string; - id: number; - thumbnail: string; - image: string; - url: string; - artist: { - name: string; - id: number; - url: string; - image: string; - }; - lyrics?: string; -} - -export interface PlayerStats { - uptime: number; - connections: number; - users: number; - queues: number; - extractors: number; - versions: { - ffmpeg: string; - node: string; - v8: string; - }; - system: { - arch: string; - platform: - | 'aix' - | 'android' - | 'darwin' - | 'freebsd' - | 'linux' - | 'openbsd' - | 'sunos' - | 'win32' - | 'cygwin' - | 'netbsd'; - cpu: number; - memory: { - total: string; - usage: string; - rss: string; - arrayBuffers: string; - }; - uptime: number; - }; -} - -export interface TimeData { - days: number; - hours: number; - minutes: number; - seconds: number; -} +export {}; diff --git a/yarn.lock b/yarn.lock index c927e0b..d81ad6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -994,6 +994,26 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.8.tgz#a883d62f049a64fea1e56a6bbe66828d11c6241b" + integrity sha512-LM6XwBhjZRls1qJGpiM/It09SntEwe9M0riXRfQ9s6XlJQG0JPGl92ET18LtGeYh/GuOtafIXqwZeqLOd0FNFQ== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1" + integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA== + "@types/node@*": version "15.12.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d" @@ -1150,6 +1170,11 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1349,6 +1374,11 @@ browserslist@^4.16.6: escalade "^3.1.1" node-releases "^1.1.71" +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1655,6 +1685,11 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-fetch@~3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" @@ -2964,6 +2999,11 @@ make-dir@^3.1.0: dependencies: semver "^6.0.0" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -3788,6 +3828,14 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@^0.5.17: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" @@ -3798,7 +3846,7 @@ source-map@^0.5.0, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -4085,6 +4133,22 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +ts-node@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be" + integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg== + dependencies: + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -4439,6 +4503,11 @@ yargs@^14.0.0: y18n "^4.0.0" yargs-parser "^15.0.1" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + youtube-sr@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/youtube-sr/-/youtube-sr-4.1.4.tgz#5ea646812264a951df7b1f6094f9f7406001dde6"