From 16fc2cbfec064e05fd8fe1ba8cd5cee7dac3f62d Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 22:08:35 +0545 Subject: [PATCH 001/131] init --- .gitignore | 5 + package.json | 38 ++++ yarn.lock | 537 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 580 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7009560 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Modules +node_modules/ + +# Test dir +test/ \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..4e3f02a --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "discord-player", + "version": "4.0.0-dev", + "description": "Complete framework to facilitate music commands using discord.js", + "main": "dist/index.js", + "scripts": { + "test": "cd test && node index.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Androz2091/discord-player.git" + }, + "keywords": [ + "music", + "player", + "bot", + "framework", + "discord", + "volume", + "queue", + "youtube" + ], + "author": "Androz2091", + "license": "MIT", + "bugs": { + "url": "https://github.com/Androz2091/discord-player/issues" + }, + "homepage": "https://github.com/Androz2091/discord-player#readme", + "dependencies": { + "discord-ytdl-core": "^5.0.2", + "youtube-sr": "^4.0.3" + }, + "devDependencies": { + "@discordjs/opus": "^0.5.0", + "@types/node": "^14.14.37", + "discord.js": "discordjs/discord.js" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..b293134 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,537 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@discordjs/collection@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c" + integrity sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ== + +"@discordjs/form-data@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@discordjs/form-data/-/form-data-3.0.1.tgz#5c9e6be992e2e57d0dfa0e39979a850225fb4697" + integrity sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +"@discordjs/node-pre-gyp@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@discordjs/node-pre-gyp/-/node-pre-gyp-0.3.2.tgz#e882e803b2be444fb557c3b46d9bbe75a053bc9c" + integrity sha512-NqRvPz0X+/3h+6ClElrSfvsD5XEG9ljYzXhzyo81DslVkVKzmmxX9FLs3MUr9qI7p53DG1eYru633qosrOqMyA== + dependencies: + detect-libc "^1.0.3" + http-proxy-agent "^4.0.1" + make-dir "^3.1.0" + node-fetch "^2.6.1" + nopt "^5.0.0" + npmlog "^4.1.2" + rimraf "^3.0.2" + semver "^7.3.4" + tar "^6.1.0" + +"@discordjs/opus@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@discordjs/opus/-/opus-0.5.0.tgz#26ae9f30d52c03ce1671b1db8eec957206fdf92b" + integrity sha512-s3XUJ7dYV+UvYUiqkgs7sq8JKWMhQrHcwDECP2SKdxtL9h9qGa4mr0IR6XnZw+G/Sogx8c+HRS7+wEspkqk3zA== + dependencies: + "@discordjs/node-pre-gyp" "^0.3.2" + node-addon-api "^3.1.0" + +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + +"@types/node@^14.14.37": + version "14.14.37" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" + integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +debug@4: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +discord-ytdl-core@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/discord-ytdl-core/-/discord-ytdl-core-5.0.2.tgz#28fb8712af8b5fda34f20800d2226b556e700422" + integrity sha512-tuu+skr0cA89Li7sCH+L1p3TwdfSOunmC9BFzSa0Jj567B1F2leVVbjKQ5ZKpsW1cXKv0fh0PdQA2/Fnu6WcQA== + dependencies: + prism-media "^1.2.7" + +discord.js@discordjs/discord.js: + version "12.5.0" + resolved "https://codeload.github.com/discordjs/discord.js/tar.gz/e848d25c86fcd4a11a7879f7dcd55d0bc93faa6d" + dependencies: + "@discordjs/collection" "^0.1.6" + "@discordjs/form-data" "^3.0.1" + abort-controller "^3.0.0" + node-fetch "^2.6.1" + prism-media "^1.2.2" + tweetnacl "^1.0.3" + ws "^7.3.1" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +iso8601-duration@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/iso8601-duration/-/iso8601-duration-1.3.0.tgz#29d7b69e0574e4acdee50c5e5e09adab4137ba5a" + integrity sha512-K4CiUBzo3YeWk76FuET/dQPH03WE04R94feo5TSKQCXpoXQt9E4yx2CnY737QZnSAI3PI4WlKo/zfqizGx52QQ== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +mime-db@1.47.0: + version "1.47.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" + integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== + +mime-types@^2.1.12: + version "2.1.30" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" + integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== + dependencies: + mime-db "1.47.0" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minipass@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +node-addon-api@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" + integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== + +node-fetch@^2.6.0, node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + +npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +prism-media@^1.2.2, prism-media@^1.2.7: + version "1.2.9" + resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.2.9.tgz#8d4f97b36efdfc82483eb8d3db64020767866f36" + integrity sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +readable-stream@^2.0.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +semver@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.4: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +signal-exit@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +simple-youtube-api@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/simple-youtube-api/-/simple-youtube-api-5.2.1.tgz#d1f6efb941ce404f50ce56e0c5e6bff249fcac6a" + integrity sha512-vmndP9Bkh35tifn2OwY+th2imSsfYtmDqczgdOW5yEARFzvSoR8VSQFsivJnctfV5QHQUL6VrOpNdbmDRLh9Bg== + dependencies: + iso8601-duration "^1.2.0" + node-fetch "^2.6.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +tar@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^7.3.1: + version "7.4.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" + integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +youtube-sr@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/youtube-sr/-/youtube-sr-4.0.3.tgz#f9ac3dc0f730770d52f9d14efbd645db8413043a" + integrity sha512-BijdoA3ahTfqpl8IYszjFYZA+oRNJekt/5qs8g7bJ5N36hv5viA4iyMX2PolOorh+K5Wqra1/ReqEp1WuGjkQQ== + dependencies: + node-fetch "^2.6.1" + simple-youtube-api "^5.2.1" From b1bd61b30ab5429a7359decc21150ce45cba0059 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 22:09:33 +0545 Subject: [PATCH 002/131] funding --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 4e3f02a..9654fbc 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "test": "cd test && node index.js" }, + "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "repository": { "type": "git", "url": "git+https://github.com/Androz2091/discord-player.git" From 73842d07d5deaef9f1bf0b007ec834bfe45bae80 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 22:10:16 +0545 Subject: [PATCH 003/131] LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1e22ec2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-present Androz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 51bdb99b8677003816fd7a48d7370e55595cec0c Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 22:19:41 +0545 Subject: [PATCH 004/131] maybe some README --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d39934d --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Discord Player +Complete framework to facilitate music commands using **[discord.js](https://discord.js.org)**. + +[![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) +[![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) + +> WIP + +## Installation + +### Install **[discord-player](https://npmjs.com/package/discord-player)** + +```sh +$ npm install --save discord-player +``` + +### Install **[@discordjs/opus](https://npmjs.com/package/@discordjs/opus)** + +```sh +$ npm install --save @discordjs/opus +``` + +### Install FFmpeg or Avconv +- Official FFMPEG Website: **[https://www.ffmpeg.org/download.html](https://www.ffmpeg.org/download.html)** + +- Node Module (FFMPEG): **[https://npmjs.com/package/ffmpeg-static](https://npmjs.com/package/ffmpeg-static)** + +- Avconv: **[https://libav.org/download](https://libav.org/download)** + +# Features +- Simple & easy to use 🤘 +- Beginner friendly 😱 +- Audio filters 🎸 +- Lightweight 🛬 + +# License +MIT License + +Copyright (c) 2020-present Androz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From a5542021a1834e2d71043611300f42819ca2cbe5 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 22:20:27 +0545 Subject: [PATCH 005/131] tsconfig --- package.json | 2 +- tsconfig.json | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tsconfig.json diff --git a/package.json b/package.json index 9654fbc..ea057e6 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "discord-player", "version": "4.0.0-dev", "description": "Complete framework to facilitate music commands using discord.js", - "main": "dist/index.js", + "main": "lib/index.js", "scripts": { "test": "cd test && node index.js" }, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..eca55b0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "declaration": true, + "outDir": "./lib", + "strict": true, + "strictNullChecks": false, + "resolveJsonModule": true + }, + "include": [ + "src/**/*" + ] +} \ No newline at end of file From 8e1e073097a8faa90cffe0abae4a9e4ae8a187a0 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 22:22:07 +0545 Subject: [PATCH 006/131] base --- src/index.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/index.ts diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..4cde362 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,5 @@ +import { version } from "../package.json" + +export { + version +} \ No newline at end of file From f72c91849c65ac22aa5f61d5b0928e8fba29aec8 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 22:28:54 +0545 Subject: [PATCH 007/131] I tried --- src/Structures/Track.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/Structures/Track.ts diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts new file mode 100644 index 0000000..515cb98 --- /dev/null +++ b/src/Structures/Track.ts @@ -0,0 +1 @@ +export default class Track {} \ No newline at end of file From 36567e346f11b77f6db57bbc178543da642e29ed Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 23:21:40 +0545 Subject: [PATCH 008/131] todo --- package.json | 3 ++- src/AudioFilters.ts | 47 +++++++++++++++++++++++++++++++++++++++++ src/Player.ts | 30 ++++++++++++++++++++++++++ src/Structures/Queue.ts | 13 ++++++++++++ src/Structures/Track.ts | 39 +++++++++++++++++++++++++++++++++- src/Util.ts | 38 +++++++++++++++++++++++++++++++++ src/index.ts | 12 ++++++----- src/types/Player.ts | 12 +++++++++++ yarn.lock | 27 +++++++++++++++++++++++ 9 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 src/AudioFilters.ts create mode 100644 src/Player.ts create mode 100644 src/Structures/Queue.ts create mode 100644 src/Util.ts create mode 100644 src/types/Player.ts diff --git a/package.json b/package.json index ea057e6..8622c77 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { "discord-ytdl-core": "^5.0.2", - "youtube-sr": "^4.0.3" + "youtube-sr": "^4.0.3", + "ytdl-core": "^4.5.0" }, "devDependencies": { "@discordjs/opus": "^0.5.0", diff --git a/src/AudioFilters.ts b/src/AudioFilters.ts new file mode 100644 index 0000000..047fa4f --- /dev/null +++ b/src/AudioFilters.ts @@ -0,0 +1,47 @@ +export default { + bassboost: "bass=g=20", + "8D": "apulsator=hz=0.09", + vaporwave: "aresample=48000,asetrate=48000*0.8", + nightcore: "aresample=48000,asetrate=48000*1.25", + phaser: "aphaser=in_gain=0.4", + tremolo: "tremolo", + vibrato: "vibrato=f=6.5", + reverse: "areverse", + treble: "treble=g=5", + normalizer: "dynaudnorm=g=101", + surrounding: "surround", + pulsator: "apulsator=hz=1", + subboost: "asubboost", + karaoke: "stereotools=mlev=0.03", + flanger: "flanger", + gate: "agate", + haas: "haas", + mcompand: "mcompand", + mono: "pan=mono|c0=.5*c0+.5*c1", + mstlr: "stereotools=mode=ms>lr", + mstrr: "stereotools=mode=ms>rr", + compressor: "compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6", + expander: "compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3", + softlimiter: "compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8", + chorus: "chorus=0.7:0.9:55:0.4:0.25:2", + chorus2d: "chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3", + chorus3d: "chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3", + fadein: "afade=t=in:ss=0:d=10", + + *[Symbol.iterator](): IterableIterator<{ name: string, value: string }> { + for (const [k, v] of Object.entries(this)) { + + // @ts-ignore + yield { name: k, value: v }; + } + }, + get names() { + return Object.keys(this); + }, + get length() { + return Object.keys(this).length; + }, + toString() { + return `"${Object.values(this).join(",")}"` + } +}; \ No newline at end of file diff --git a/src/Player.ts b/src/Player.ts new file mode 100644 index 0000000..e7f202a --- /dev/null +++ b/src/Player.ts @@ -0,0 +1,30 @@ +import { EventEmitter } from "events"; +import { Client } from "discord.js"; +import { PlayerOptions } from "./types/Player"; +import Util from "./Util"; + +export default class Player extends EventEmitter { + public client!: Client; + public options: PlayerOptions; + + constructor(client: Client, options?: PlayerOptions) { + super(); + + /** + * The discord client that instantiated this player + */ + Object.defineProperty(this, "client", { + value: client, + enumerable: false + }); + + /** + * The player options + */ + this.options = Object.assign({}, Util.DefaultPlayerOptions, options ?? {}); + + // check FFmpeg + void Util.alertFFmpeg(); + } + +} \ No newline at end of file diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts new file mode 100644 index 0000000..88020a9 --- /dev/null +++ b/src/Structures/Queue.ts @@ -0,0 +1,13 @@ +import Player from "../Player"; + +export default class Queue { + public player!: Player; + + constructor(player: Player) { + + /** + * The player that instantiated this Queue + */ + Object.defineProperty(this, "player", { value: player, enumerable: false }); + } +} \ No newline at end of file diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 515cb98..287e3c1 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1 +1,38 @@ -export default class Track {} \ No newline at end of file +import Player from "../Player"; +import { User } from "discord.js"; + +export default class Track { + public player!: Player; + public title!: string; + public description!: string; + public author!: string; + public url!: string; + public thumbnail!: string; + public duration!: string; + public views!: number; + public requestedBy!: User; + public fromPlaylist!: boolean; + + constructor(player: Player, data: any) { + + /** + * The player that instantiated this Track + */ + Object.defineProperty(this, "player", { value: player, enumerable: false }); + + void this._patch(data); + } + + private _patch(data: any) { + this.title = data.title ?? ""; + this.description = data.description ?? ""; + this.author = data.author ?? ""; + this.url = data.url ?? ""; + this.thumbnail = typeof data.thumbnail === "object" ? data.thumbnail.url : data.thumbnail; + this.duration = data.duration ?? ""; + this.views = data.views ?? 0; + this.requestedBy = data.requestedBy; + this.fromPlaylist = Boolean(data.fromPlaylist); + } + +} \ No newline at end of file diff --git a/src/Util.ts b/src/Util.ts new file mode 100644 index 0000000..4c118e6 --- /dev/null +++ b/src/Util.ts @@ -0,0 +1,38 @@ +import { PlayerOptions } from "./types/Player"; +import { FFmpeg } from "prism-media"; + +export default class Util { + + constructor() { + throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); + } + + static get DefaultPlayerOptions() { + return { + leaveOnEnd: true, + leaveOnStop: true, + leaveOnEmpty: true, + leaveOnEmptyCooldown: 0, + autoSelfDeaf: true, + enableLive: false, + ytdlDownloadOptions: {} + } as PlayerOptions; + } + + static checkFFmpeg(force?: boolean) { + try { + FFmpeg.getInfo(Boolean(force)); + + return true; + } catch { + return false; + } + } + + static alertFFmpeg() { + const hasFFmpeg = Util.checkFFmpeg(); + + if (!hasFFmpeg) console.warn("[Discord Player] FFmpeg/Avconv not found! Install via \"npm install ffmpeg-static\" or download from https://ffmpeg.org/download.html"); + } + +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4cde362..a323cbc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ -import { version } from "../package.json" - -export { - version -} \ No newline at end of file +export * as AudioFilters from "./AudioFilters"; +export * as Player from "./Player"; +export * as Util from "./Util"; +export * as Track from "./Structures/Track"; +export * as Queue from "./Structures/Queue"; +export * from "./types/Player"; +export { version } from "../package.json"; \ No newline at end of file diff --git a/src/types/Player.ts b/src/types/Player.ts new file mode 100644 index 0000000..cb91fba --- /dev/null +++ b/src/types/Player.ts @@ -0,0 +1,12 @@ +import { downloadOptions } from "ytdl-core"; + +export interface PlayerOptions { + leaveOnEnd?: boolean; + leaveOnEndCooldown?: number; + leaveOnStop?: boolean; + leaveOnEmpty?: boolean; + leaveOnEmptyCooldown?: number; + autoSelfDeaf?: boolean; + enableLive?: boolean; + ytdlDownloadOptions?: downloadOptions; +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b293134..a224a27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -281,6 +281,14 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +m3u8stream@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/m3u8stream/-/m3u8stream-0.8.3.tgz#c4624e92b4240eb356d040c4a5e155586cf58108" + integrity sha512-0nAcdrF8YJKUkb6PzWdvGftTPyCVWgoiot1AkNVbPKTeIGsWs6DrOjifrJ0Zi8WQfQmD2SuVCjkYIOip12igng== + dependencies: + miniget "^4.0.0" + sax "^1.2.4" + make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -300,6 +308,11 @@ mime-types@^2.1.12: dependencies: mime-db "1.47.0" +miniget@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/miniget/-/miniget-4.2.0.tgz#0004e95536b192d95a7d09f4435d67b9285481d0" + integrity sha512-IzTOaNgBw/qEpzkPTE7X2cUVXQfSKbG8w52Emi93zb+Zya2ZFrbmavpixzebuDJD9Ku4ecbaFlC7Y1cEESzQtQ== + minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -416,6 +429,11 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +sax@^1.1.3, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + semver@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -535,3 +553,12 @@ youtube-sr@^4.0.3: dependencies: node-fetch "^2.6.1" simple-youtube-api "^5.2.1" + +ytdl-core@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/ytdl-core/-/ytdl-core-4.5.0.tgz#f07733387c548e5c3a5614c93ef55bde666eeaf4" + integrity sha512-e8r6skrakWNixsVlNPBMoRM1HrdW1swE97If9nenDUjF65uogYk4DvxIuqlmqRfBWKe+6aIZwqedNxUU9XLYJA== + dependencies: + m3u8stream "^0.8.3" + miniget "^4.0.0" + sax "^1.1.3" From 390d80a3d20e6085ee93d6bdd56f8a7361f59398 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 23:29:45 +0545 Subject: [PATCH 009/131] format --- .github/FUNDING.yml | 2 + .gitignore | 5 +- .npmignore | 5 + .prettierrc | 6 ++ package.json | 15 ++- src/AudioFilters.ts | 63 ++++++------ src/Player.ts | 13 ++- src/Structures/Queue.ts | 7 +- src/Structures/Track.ts | 22 ++-- src/Util.ts | 13 +-- src/index.ts | 14 +-- src/types/Player.ts | 4 +- tsconfig.json | 2 +- tslint.json | 14 +++ yarn.lock | 217 +++++++++++++++++++++++++++++++++++++++- 15 files changed, 326 insertions(+), 76 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 .npmignore create mode 100644 .prettierrc create mode 100644 tslint.json diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..b031aef --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +patreon: androz2091 +github: Androz2091 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7009560..c4e1f82 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ node_modules/ # Test dir -test/ \ No newline at end of file +test/ + +# Compiled +lib/ \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..90bfa96 --- /dev/null +++ b/.npmignore @@ -0,0 +1,5 @@ +src/ +tsconfig.json +tslint.json +.prettierrc +test/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ab07ced --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "printWidth": 120, + "trailingComma": "none", + "singleQuote": true, + "tabWidth": 4 +} \ No newline at end of file diff --git a/package.json b/package.json index 8622c77..c41b42f 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,14 @@ "version": "4.0.0-dev", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/index.js", + "files": [ + "lib/**/*" + ], "scripts": { - "test": "cd test && node index.js" + "test": "cd test && node index.js", + "build": "tsc", + "format": "prettier --write \"src/**/*.ts\"", + "lint": "tslint -p tsconfig.json" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "repository": { @@ -35,6 +41,11 @@ "devDependencies": { "@discordjs/opus": "^0.5.0", "@types/node": "^14.14.37", - "discord.js": "discordjs/discord.js" + "@types/ws": "^7.4.1", + "discord.js": "discordjs/discord.js", + "prettier": "^2.2.1", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^4.2.3" } } diff --git a/src/AudioFilters.ts b/src/AudioFilters.ts index 047fa4f..3274d5b 100644 --- a/src/AudioFilters.ts +++ b/src/AudioFilters.ts @@ -1,36 +1,35 @@ export default { - bassboost: "bass=g=20", - "8D": "apulsator=hz=0.09", - vaporwave: "aresample=48000,asetrate=48000*0.8", - nightcore: "aresample=48000,asetrate=48000*1.25", - phaser: "aphaser=in_gain=0.4", - tremolo: "tremolo", - vibrato: "vibrato=f=6.5", - reverse: "areverse", - treble: "treble=g=5", - normalizer: "dynaudnorm=g=101", - surrounding: "surround", - pulsator: "apulsator=hz=1", - subboost: "asubboost", - karaoke: "stereotools=mlev=0.03", - flanger: "flanger", - gate: "agate", - haas: "haas", - mcompand: "mcompand", - mono: "pan=mono|c0=.5*c0+.5*c1", - mstlr: "stereotools=mode=ms>lr", - mstrr: "stereotools=mode=ms>rr", - compressor: "compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6", - expander: "compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3", - softlimiter: "compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8", - chorus: "chorus=0.7:0.9:55:0.4:0.25:2", - chorus2d: "chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3", - chorus3d: "chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3", - fadein: "afade=t=in:ss=0:d=10", + bassboost: 'bass=g=20', + '8D': 'apulsator=hz=0.09', + vaporwave: 'aresample=48000,asetrate=48000*0.8', + nightcore: 'aresample=48000,asetrate=48000*1.25', + phaser: 'aphaser=in_gain=0.4', + tremolo: 'tremolo', + vibrato: 'vibrato=f=6.5', + reverse: 'areverse', + treble: 'treble=g=5', + normalizer: 'dynaudnorm=g=101', + surrounding: 'surround', + pulsator: 'apulsator=hz=1', + subboost: 'asubboost', + karaoke: 'stereotools=mlev=0.03', + flanger: 'flanger', + gate: 'agate', + haas: 'haas', + mcompand: 'mcompand', + mono: 'pan=mono|c0=.5*c0+.5*c1', + mstlr: 'stereotools=mode=ms>lr', + mstrr: 'stereotools=mode=ms>rr', + compressor: 'compand=points=-80/-105|-62/-80|-15.4/-15.4|0/-12|20/-7.6', + expander: 'compand=attacks=0:points=-80/-169|-54/-80|-49.5/-64.6|-41.1/-41.1|-25.8/-15|-10.8/-4.5|0/0|20/8.3', + softlimiter: 'compand=attacks=0:points=-80/-80|-12.4/-12.4|-6/-8|0/-6.8|20/-2.8', + chorus: 'chorus=0.7:0.9:55:0.4:0.25:2', + chorus2d: 'chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3', + chorus3d: 'chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3', + fadein: 'afade=t=in:ss=0:d=10', - *[Symbol.iterator](): IterableIterator<{ name: string, value: string }> { + *[Symbol.iterator](): IterableIterator<{ name: string; value: string }> { for (const [k, v] of Object.entries(this)) { - // @ts-ignore yield { name: k, value: v }; } @@ -42,6 +41,6 @@ export default { return Object.keys(this).length; }, toString() { - return `"${Object.values(this).join(",")}"` + return `"${Object.values(this).join(',')}"`; } -}; \ No newline at end of file +}; diff --git a/src/Player.ts b/src/Player.ts index e7f202a..9abfd97 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,7 +1,7 @@ -import { EventEmitter } from "events"; -import { Client } from "discord.js"; -import { PlayerOptions } from "./types/Player"; -import Util from "./Util"; +import { EventEmitter } from 'events'; +import { Client } from 'discord.js'; +import { PlayerOptions } from './types/Player'; +import Util from './Util'; export default class Player extends EventEmitter { public client!: Client; @@ -13,7 +13,7 @@ export default class Player extends EventEmitter { /** * The discord client that instantiated this player */ - Object.defineProperty(this, "client", { + Object.defineProperty(this, 'client', { value: client, enumerable: false }); @@ -26,5 +26,4 @@ export default class Player extends EventEmitter { // check FFmpeg void Util.alertFFmpeg(); } - -} \ No newline at end of file +} diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 88020a9..c2880ce 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -1,13 +1,12 @@ -import Player from "../Player"; +import Player from '../Player'; export default class Queue { public player!: Player; constructor(player: Player) { - /** * The player that instantiated this Queue */ - Object.defineProperty(this, "player", { value: player, enumerable: false }); + Object.defineProperty(this, 'player', { value: player, enumerable: false }); } -} \ No newline at end of file +} diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 287e3c1..517ec8b 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,5 +1,5 @@ -import Player from "../Player"; -import { User } from "discord.js"; +import Player from '../Player'; +import { User } from 'discord.js'; export default class Track { public player!: Player; @@ -14,25 +14,23 @@ export default class Track { public fromPlaylist!: boolean; constructor(player: Player, data: any) { - /** * The player that instantiated this Track */ - Object.defineProperty(this, "player", { value: player, enumerable: false }); + Object.defineProperty(this, 'player', { value: player, enumerable: false }); void this._patch(data); } private _patch(data: any) { - this.title = data.title ?? ""; - this.description = data.description ?? ""; - this.author = data.author ?? ""; - this.url = data.url ?? ""; - this.thumbnail = typeof data.thumbnail === "object" ? data.thumbnail.url : data.thumbnail; - this.duration = data.duration ?? ""; + this.title = data.title ?? ''; + this.description = data.description ?? ''; + this.author = data.author ?? ''; + this.url = data.url ?? ''; + this.thumbnail = typeof data.thumbnail === 'object' ? data.thumbnail.url : data.thumbnail; + this.duration = data.duration ?? ''; this.views = data.views ?? 0; this.requestedBy = data.requestedBy; this.fromPlaylist = Boolean(data.fromPlaylist); } - -} \ No newline at end of file +} diff --git a/src/Util.ts b/src/Util.ts index 4c118e6..8890517 100644 --- a/src/Util.ts +++ b/src/Util.ts @@ -1,8 +1,7 @@ -import { PlayerOptions } from "./types/Player"; -import { FFmpeg } from "prism-media"; +import { PlayerOptions } from './types/Player'; +import { FFmpeg } from 'prism-media'; export default class Util { - constructor() { throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); } @@ -32,7 +31,9 @@ export default class Util { static alertFFmpeg() { const hasFFmpeg = Util.checkFFmpeg(); - if (!hasFFmpeg) console.warn("[Discord Player] FFmpeg/Avconv not found! Install via \"npm install ffmpeg-static\" or download from https://ffmpeg.org/download.html"); + if (!hasFFmpeg) + console.warn( + '[Discord Player] FFmpeg/Avconv not found! Install via "npm install ffmpeg-static" or download from https://ffmpeg.org/download.html' + ); } - -} \ No newline at end of file +} diff --git a/src/index.ts b/src/index.ts index a323cbc..d1fc979 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -export * as AudioFilters from "./AudioFilters"; -export * as Player from "./Player"; -export * as Util from "./Util"; -export * as Track from "./Structures/Track"; -export * as Queue from "./Structures/Queue"; -export * from "./types/Player"; -export { version } from "../package.json"; \ No newline at end of file +export * as AudioFilters from './AudioFilters'; +export * as Player from './Player'; +export * as Util from './Util'; +export * as Track from './Structures/Track'; +export * as Queue from './Structures/Queue'; +export * from './types/Player'; +export { version } from '../package.json'; diff --git a/src/types/Player.ts b/src/types/Player.ts index cb91fba..427f552 100644 --- a/src/types/Player.ts +++ b/src/types/Player.ts @@ -1,4 +1,4 @@ -import { downloadOptions } from "ytdl-core"; +import { downloadOptions } from 'ytdl-core'; export interface PlayerOptions { leaveOnEnd?: boolean; @@ -9,4 +9,4 @@ export interface PlayerOptions { autoSelfDeaf?: boolean; enableLive?: boolean; ytdlDownloadOptions?: downloadOptions; -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json index eca55b0..441108e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es6", + "target": "ES6", "module": "commonjs", "declaration": true, "outDir": "./lib", diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..5d61f36 --- /dev/null +++ b/tslint.json @@ -0,0 +1,14 @@ +{ + "defaultSeverity": "error", + "extends": ["tslint:recommended", "tslint-config-prettier"], + "jsRules": { + "no-unused-expression": true + }, + "rules": { + "object-literal-sort-keys": false, + "interface-name": false, + "no-empty": false, + "no-console": false + }, + "rulesDirectory": [] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a224a27..2a9d968 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,27 @@ # yarn lockfile v1 +"@babel/code-frame@^7.0.0": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/highlight@^7.12.13": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" + integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@discordjs/collection@^0.1.6": version "0.1.6" resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c" @@ -44,11 +65,18 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@types/node@^14.14.37": +"@types/node@*", "@types/node@^14.14.37": version "14.14.37" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== +"@types/ws@^7.4.1": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.1.tgz#49eacb15a0534663d53a36fbf5b4d98f5ae9a73a" + integrity sha512-ISCK1iFnR+jYv7+jLNX0wDqesZ/5RAeY3wUx6QaphmocphU61h+b+PHjS18TF4WIPTu/MMzxIq2PHr32o2TS5Q== + dependencies: + "@types/node" "*" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -78,6 +106,13 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -91,6 +126,13 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -109,6 +151,20 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +chalk@^2.0.0, chalk@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -119,6 +175,18 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -126,6 +194,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^2.12.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -163,6 +236,11 @@ detect-libc@^1.0.3: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + discord-ytdl-core@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/discord-ytdl-core/-/discord-ytdl-core-5.0.2.tgz#28fb8712af8b5fda34f20800d2226b556e700422" @@ -182,6 +260,16 @@ discord.js@discordjs/discord.js: tweetnacl "^1.0.3" ws "^7.3.1" +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -199,6 +287,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -213,7 +306,7 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -glob@^7.1.3: +glob@^7.1.1, glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -225,11 +318,23 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -252,6 +357,13 @@ inherits@2, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-core-module@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -274,6 +386,19 @@ iso8601-duration@^1.2.0: resolved "https://registry.yarnpkg.com/iso8601-duration/-/iso8601-duration-1.3.0.tgz#29d7b69e0574e4acdee50c5e5e09adab4137ba5a" integrity sha512-K4CiUBzo3YeWk76FuET/dQPH03WE04R94feo5TSKQCXpoXQt9E4yx2CnY737QZnSAI3PI4WlKo/zfqizGx52QQ== +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -320,6 +445,11 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + minipass@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" @@ -335,6 +465,13 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" +mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" @@ -394,6 +531,16 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +prettier@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + prism-media@^1.2.2, prism-media@^1.2.7: version "1.2.9" resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.2.9.tgz#8d4f97b36efdfc82483eb8d3db64020767866f36" @@ -417,6 +564,14 @@ readable-stream@^2.0.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +resolve@^1.3.2: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -434,6 +589,11 @@ sax@^1.1.3, sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +semver@^5.3.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@^6.0.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -464,6 +624,11 @@ simple-youtube-api@^5.2.1: iso8601-duration "^1.2.0" node-fetch "^2.6.0" +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -502,6 +667,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" @@ -514,11 +686,52 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" +tslib@^1.13.0, tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslint-config-prettier@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" + integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== + +tslint@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" + integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.3" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.13.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== +typescript@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" + integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" From b52e86f160d5b78bded8087938c46bfdf283b854 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 4 Apr 2021 23:32:40 +0545 Subject: [PATCH 010/131] contributors --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index c41b42f..5023efc 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,9 @@ "lint": "tslint -p tsconfig.json" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", + "contributors": [ + "Snowflake107" + ], "repository": { "type": "git", "url": "git+https://github.com/Androz2091/discord-player.git" From 1be07e47035795f56e95421be664138c7fae47c0 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 5 Apr 2021 12:30:55 +0545 Subject: [PATCH 011/131] track data --- src/Structures/Track.ts | 11 ++++++++--- src/types/Track.ts | 13 +++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/types/Track.ts diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 517ec8b..1df7e2d 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,5 +1,6 @@ import Player from '../Player'; import { User } from 'discord.js'; +import { TrackData } from "../types/Track"; export default class Track { public player!: Player; @@ -12,8 +13,9 @@ export default class Track { public views!: number; public requestedBy!: User; public fromPlaylist!: boolean; + public raw!: TrackData; - constructor(player: Player, data: any) { + constructor(player: Player, data: TrackData) { /** * The player that instantiated this Track */ @@ -22,15 +24,18 @@ export default class Track { void this._patch(data); } - private _patch(data: any) { + private _patch(data: TrackData) { this.title = data.title ?? ''; this.description = data.description ?? ''; this.author = data.author ?? ''; this.url = data.url ?? ''; - this.thumbnail = typeof data.thumbnail === 'object' ? data.thumbnail.url : data.thumbnail; + this.thumbnail = data.thumbnail ?? ''; this.duration = data.duration ?? ''; this.views = data.views ?? 0; this.requestedBy = data.requestedBy; this.fromPlaylist = Boolean(data.fromPlaylist); + + // raw + Object.defineProperty(this, "raw", { get: () => data, enumerable: false }); } } diff --git a/src/types/Track.ts b/src/types/Track.ts new file mode 100644 index 0000000..e574813 --- /dev/null +++ b/src/types/Track.ts @@ -0,0 +1,13 @@ +import { User } from "discord.js"; + +export interface TrackData { + title: string; + description: string; + author: string; + url: string; + thumbnail: string; + duration: string; + views: number; + requestedBy: User; + fromPlaylist: boolean; +} \ No newline at end of file From b40c070b2eefdcdb73057317edc44639fd2c1527 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 18:40:29 +0545 Subject: [PATCH 012/131] update --- .gitignore | 5 +- package.json | 2 + src/Player.ts | 120 +++++++++++++++++++++++-- src/Structures/Queue.ts | 125 +++++++++++++++++++++++++- src/Structures/Track.ts | 44 ++++++--- src/Util.ts | 39 -------- src/index.ts | 14 +-- src/types/Player.ts | 12 --- src/types/Track.ts | 13 --- src/types/types.ts | 105 ++++++++++++++++++++++ src/{ => utils}/AudioFilters.ts | 12 ++- src/utils/Constants.ts | 16 ++++ src/utils/Util.ts | 116 ++++++++++++++++++++++++ yarn.lock | 153 +++++++++++++++++++++++++++++++- 14 files changed, 681 insertions(+), 95 deletions(-) delete mode 100644 src/Util.ts delete mode 100644 src/types/Player.ts delete mode 100644 src/types/Track.ts create mode 100644 src/types/types.ts rename src/{ => utils}/AudioFilters.ts (80%) create mode 100644 src/utils/Constants.ts create mode 100644 src/utils/Util.ts diff --git a/.gitignore b/.gitignore index c4e1f82..d02ad80 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,7 @@ node_modules/ test/ # Compiled -lib/ \ No newline at end of file +lib/ + +# error logs +yarn-error.log \ No newline at end of file diff --git a/package.json b/package.json index 5023efc..d8ccef4 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,8 @@ "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { "discord-ytdl-core": "^5.0.2", + "soundcloud-scraper": "^4.0.3", + "spotify-url-info": "^2.2.0", "youtube-sr": "^4.0.3", "ytdl-core": "^4.5.0" }, diff --git a/src/Player.ts b/src/Player.ts index 9abfd97..414d691 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,11 +1,27 @@ -import { EventEmitter } from 'events'; -import { Client } from 'discord.js'; -import { PlayerOptions } from './types/Player'; -import Util from './Util'; +import YouTube from "youtube-sr"; +import { EventEmitter } from "events"; +import { Client, Collection, Snowflake, Collector, Message } from "discord.js"; +import { PlayerOptions } from "./types/types"; +import Util from "./utils/Util"; +import AudioFilters from "./utils/AudioFilters"; +import Queue from "./Structures/Queue"; +import Track from "./Structures/Track"; +import { PlayerEvents } from "./utils/Constants"; + +// @ts-ignore +import spotify from "spotify-url-info"; +// @ts-ignore +import { Client as SoundCloudClient } from "soundcloud-scraper"; + +const SoundCloud = new SoundCloudClient; export default class Player extends EventEmitter { public client!: Client; public options: PlayerOptions; + public filters: typeof AudioFilters; + public queues: Collection; + private _resultsCollectors: Collection>; + private _cooldownsTimeout: Collection; constructor(client: Client, options?: PlayerOptions) { super(); @@ -13,7 +29,7 @@ export default class Player extends EventEmitter { /** * The discord client that instantiated this player */ - Object.defineProperty(this, 'client', { + Object.defineProperty(this, "client", { value: client, enumerable: false }); @@ -25,5 +41,99 @@ export default class Player extends EventEmitter { // check FFmpeg void Util.alertFFmpeg(); + + /** + * The audio filters + */ + this.filters = AudioFilters; + + /** + * Player queues + */ + this.queues = new Collection(); + } + + static get AudioFilters() { + return AudioFilters; + } + + private _searchTracks(message: Message, query: string, firstResult?: boolean, isAttachment?: boolean): Promise { + return new Promise(async (resolve) => { + let tracks: Track[] = []; + let queryType = Util.getQueryType(query); + + switch(queryType) { + case "soundcloud_track": { + const data = await SoundCloud.getSongInfo(query).catch(() => { }) + if (data) { + const track = new Track(this, { + title: data.title, + url: data.url, + duration: Util.durationString(Util.parseMS(data.duration / 1000)), + description: data.description, + thumbnail: data.thumbnail, + views: data.playCount, + author: data.author, + requestedBy: message.author, + fromPlaylist: false, + source: "soundcloud", + engine: data + }); + + tracks.push(track) + } + } + break; + case "spotify_song": { + const matchSpotifyURL = query.match(/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/) + if (matchSpotifyURL) { + const spotifyData = await spotify.getPreview(query).catch(() => { }) + if (spotifyData) { + tracks = await Util.ytSearch(`${spotifyData.artist} - ${spotifyData.title}`, { user: message.author, player: this }); + } + } + } + break; + default: + tracks = await Util.ytSearch(query, { user: message.author, player: this }); + } + + if (tracks.length < 1) return this.emit(PlayerEvents.NO_RESULTS, message, query); + if (firstResult) 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 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", (collected, reason) => { + if (reason === "time") { + this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); + } + }); + }); } } diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index c2880ce..c853b5c 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -1,12 +1,129 @@ -import Player from '../Player'; +import { Message, Snowflake, VoiceConnection } from "discord.js"; +import AudioFilters from "../utils/AudioFilters"; +import Player from "../Player"; +import { EventEmitter } from "events"; +import Track from "./Track"; +import { QueueFilters } from "../types/types"; -export default class Queue { +export default class Queue extends EventEmitter { public player!: Player; + public guildID: Snowflake; + public voiceConnection?: VoiceConnection; + public stream?: any; + public tracks: Track[]; + public previousTracks: Track[]; + public stopped: boolean; + public lastSkipped: boolean; + public volume: number; + public paused: boolean; + public repeatMode: boolean; + public loopMode: boolean; + public filters: QueueFilters; + public additionalStreamTime: number; + public firstMessage: Message; + + constructor(player: Player, message: Message, filters: typeof AudioFilters) { + super(); - constructor(player: Player) { /** * The player that instantiated this Queue */ - Object.defineProperty(this, 'player', { value: player, enumerable: false }); + Object.defineProperty(this, "player", { value: player, enumerable: false }); + + /** + * ID of the guild assigned to this queue + */ + this.guildID = message.guild.id; + + /** + * The voice connection of this queue + */ + this.voiceConnection = null; + + /** + * Tracks of this queue + */ + this.tracks = []; + + /** + * Previous tracks of this queue + */ + this.previousTracks = []; + + /** + * If the player of this queue is stopped + */ + this.stopped = false; + + /** + * If last track was skipped + */ + this.lastSkipped = false; + + /** + * Queue volume + */ + this.volume = 100; + + /** + * If the player of this queue is paused + */ + this.paused = Boolean(this.voiceConnection?.dispatcher?.paused); + + /** + * If repeat mode is enabled in this queue + */ + this.repeatMode = false; + + /** + * If loop mode is enabled in this queue + */ + this.loopMode = false; + + /** + * The additional calculated stream time + */ + this.additionalStreamTime = 0; + + /** + * The initial message object + */ + this.firstMessage = message; + + // @ts-ignore + this.filters = {}; + + Object.keys(AudioFilters).forEach(fn => { + // @ts-ignore + this.filters[fn] = false; + }); + } + + /** + * Currently playing track + */ + get playing() { + return this.tracks[0]; + } + + /** + * Calculated volume of this queue + */ + get calculatedVolume() { + return this.filters.bassboost ? this.volume + 50 : this.volume; + } + + /** + * Total duration + */ + get totalTime() { + return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0; + } + + /** + * Current stream time + */ + get currentStreamTime() { + return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; } } diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 1df7e2d..970aeb4 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,6 +1,6 @@ -import Player from '../Player'; -import { User } from 'discord.js'; -import { TrackData } from "../types/Track"; +import Player from "../Player"; +import { User } from "discord.js"; +import { TrackData } from "../types/types"; export default class Track { public player!: Player; @@ -19,18 +19,18 @@ export default class Track { /** * The player that instantiated this Track */ - Object.defineProperty(this, 'player', { value: player, enumerable: false }); + Object.defineProperty(this, "player", { value: player, enumerable: false }); void this._patch(data); } private _patch(data: TrackData) { - this.title = data.title ?? ''; - this.description = data.description ?? ''; - this.author = data.author ?? ''; - this.url = data.url ?? ''; - this.thumbnail = data.thumbnail ?? ''; - this.duration = data.duration ?? ''; + this.title = data.title ?? ""; + this.description = data.description ?? ""; + this.author = data.author ?? ""; + this.url = data.url ?? ""; + this.thumbnail = data.thumbnail ?? ""; + this.duration = data.duration ?? ""; this.views = data.views ?? 0; this.requestedBy = data.requestedBy; this.fromPlaylist = Boolean(data.fromPlaylist); @@ -38,4 +38,28 @@ export default class Track { // raw Object.defineProperty(this, "raw", { get: () => data, enumerable: false }); } + + /** + * The queue in which this track is located + */ + get queue() { + return this.player.queues.find(q => q.tracks.includes(this)); + } + + /** + * The track duration in millisecond + */ + get durationMS() { + const times = (n: number, t: number) => { + let tn = 1; + for (let i = 0; i < t; i++) tn *= n; + return t <= 0 ? 1000 : tn * 1000; + }; + + return this.duration.split(":").reverse().map((m, i) => parseInt(m) * times(60, i)).reduce((a, c) => a + c, 0); + } + + toString() { + return `${this.title} by ${this.author}`; + } } diff --git a/src/Util.ts b/src/Util.ts deleted file mode 100644 index 8890517..0000000 --- a/src/Util.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { PlayerOptions } from './types/Player'; -import { FFmpeg } from 'prism-media'; - -export default class Util { - constructor() { - throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); - } - - static get DefaultPlayerOptions() { - return { - leaveOnEnd: true, - leaveOnStop: true, - leaveOnEmpty: true, - leaveOnEmptyCooldown: 0, - autoSelfDeaf: true, - enableLive: false, - ytdlDownloadOptions: {} - } as PlayerOptions; - } - - static checkFFmpeg(force?: boolean) { - try { - FFmpeg.getInfo(Boolean(force)); - - return true; - } catch { - return false; - } - } - - static alertFFmpeg() { - const hasFFmpeg = Util.checkFFmpeg(); - - if (!hasFFmpeg) - console.warn( - '[Discord Player] FFmpeg/Avconv not found! Install via "npm install ffmpeg-static" or download from https://ffmpeg.org/download.html' - ); - } -} diff --git a/src/index.ts b/src/index.ts index d1fc979..f54dbd7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -export * as AudioFilters from './AudioFilters'; -export * as Player from './Player'; -export * as Util from './Util'; -export * as Track from './Structures/Track'; -export * as Queue from './Structures/Queue'; -export * from './types/Player'; -export { version } from '../package.json'; +export * as AudioFilters from "./utils/AudioFilters"; +export * as Player from "./Player"; +export * as Util from "./utils/Util"; +export * as Track from "./Structures/Track"; +export * as Queue from "./Structures/Queue"; +export * from "./types/types"; +export { version } from "../package.json"; diff --git a/src/types/Player.ts b/src/types/Player.ts deleted file mode 100644 index 427f552..0000000 --- a/src/types/Player.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { downloadOptions } from 'ytdl-core'; - -export interface PlayerOptions { - leaveOnEnd?: boolean; - leaveOnEndCooldown?: number; - leaveOnStop?: boolean; - leaveOnEmpty?: boolean; - leaveOnEmptyCooldown?: number; - autoSelfDeaf?: boolean; - enableLive?: boolean; - ytdlDownloadOptions?: downloadOptions; -} diff --git a/src/types/Track.ts b/src/types/Track.ts deleted file mode 100644 index e574813..0000000 --- a/src/types/Track.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { User } from "discord.js"; - -export interface TrackData { - title: string; - description: string; - author: string; - url: string; - thumbnail: string; - duration: string; - views: number; - requestedBy: User; - fromPlaylist: boolean; -} \ No newline at end of file diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 0000000..56762fe --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1,105 @@ +import { downloadOptions } from "ytdl-core"; +import { User } from "discord.js"; + +export interface PlayerOptions { + leaveOnEnd?: boolean; + leaveOnEndCooldown?: number; + leaveOnStop?: boolean; + leaveOnEmpty?: boolean; + leaveOnEmptyCooldown?: number; + autoSelfDeaf?: boolean; + enableLive?: boolean; + ytdlDownloadOptions?: downloadOptions; + useSafeSearch?: boolean; +} + +export type FiltersName = + | "bassboost" + | "8D" + | "vaporwave" + | "nightcore" + | "phaser" + | "tremolo" + | "vibrato" + | "reverse" + | "treble" + | "normalizer" + | "surrounding" + | "pulsator" + | "subboost" + | "karaoke" + | "flanger" + | "gate" + | "haas" + | "mcompand" + | "mono" + | "mstlr" + | "mstrr" + | "compressor" + | "expander" + | "softlimiter" + | "chorus" + | "chorus2d" + | "chorus3d" + | "fadein"; + +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; +} + +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"; \ No newline at end of file diff --git a/src/AudioFilters.ts b/src/utils/AudioFilters.ts similarity index 80% rename from src/AudioFilters.ts rename to src/utils/AudioFilters.ts index 3274d5b..e8de4f8 100644 --- a/src/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -1,4 +1,6 @@ -export default { +import { FiltersName } from "../types/types"; + +const FilterList = { bassboost: 'bass=g=20', '8D': 'apulsator=hz=0.09', vaporwave: 'aresample=48000,asetrate=48000*0.8', @@ -41,6 +43,12 @@ export default { return Object.keys(this).length; }, toString() { - return `"${Object.values(this).join(',')}"`; + return `${Object.values(this).join(',')}`; + }, + create(filter?: FiltersName[]) { + if (!filter || !Array.isArray(filter)) return this.toString(); + return filter.filter(predicate => typeof predicate === "string").map(m => this[m]).join(","); } }; + +export default FilterList; \ No newline at end of file diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts new file mode 100644 index 0000000..e4f21a7 --- /dev/null +++ b/src/utils/Constants.ts @@ -0,0 +1,16 @@ +export const PlayerEvents = { + BOT_DISCONNECT: "botDisconnect", + CHANNEL_EMPTY: "channelEmpty", + ERROR: "error", + NO_RESULTS: "noResults", + PLAYLIST_ADD: "playlistAdd", + PLAYLIST_PARSE_END: "playlistParseEnd", + PLAYLIST_PARSE_START: "playlistParseStart", + QUEUE_CREATE: "queueCreate", + QUEUE_END: "queueEnd", + SEARCH_CANCEL: "searchCancel", + SEARCH_INVALID_RESPONSE: "searchInvalidResponse", + SEARCH_RESULTS: "searchResults", + TRACK_ADD: "trackAdd", + TRACK_START: "trackStart", +}; \ No newline at end of file diff --git a/src/utils/Util.ts b/src/utils/Util.ts new file mode 100644 index 0000000..fa4aeb4 --- /dev/null +++ b/src/utils/Util.ts @@ -0,0 +1,116 @@ +import { PlayerOptions, QueryType } from "../types/types"; +import { FFmpeg } from "prism-media"; +import YouTube from "youtube-sr"; +import Track from "../Structures/Track"; +// @ts-ignore +import { validateURL as SoundcloudValidateURL } from "soundcloud-scraper"; + +const spotifySongRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/); +const spotifyPlaylistRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/); +const spotifyAlbumRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/); +const vimeoRegex = (/(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/); +const facebookRegex = (/(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/); +const reverbnationRegex = (/https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/); + +export default class Util { + constructor() { + throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); + } + + static get DefaultPlayerOptions() { + return { + leaveOnEnd: true, + leaveOnStop: true, + leaveOnEmpty: true, + leaveOnEmptyCooldown: 0, + autoSelfDeaf: true, + enableLive: false, + ytdlDownloadOptions: {} + } as PlayerOptions; + } + + static checkFFmpeg(force?: boolean) { + try { + FFmpeg.getInfo(Boolean(force)); + + return true; + } catch { + return false; + } + } + + static alertFFmpeg() { + const hasFFmpeg = Util.checkFFmpeg(); + + if (!hasFFmpeg) + console.warn( + "[Discord Player] FFmpeg/Avconv not found! Install via \"npm install ffmpeg-static\" or download from https://ffmpeg.org/download.html" + ); + } + + static getQueryType(query: string): QueryType { + if (SoundcloudValidateURL(query) && !query.includes("/sets/")) return "soundcloud_track"; + if (SoundcloudValidateURL(query) && query.includes("/sets/")) return "soundcloud_playlist"; + if (spotifySongRegex.test(query)) return "spotify_song"; + if (spotifyAlbumRegex.test(query)) return "spotify_album"; + if (spotifyPlaylistRegex.test(query)) return "spotify_playlist"; + if (YouTube.validate(query, "VIDEO")) return "youtube_video"; + if (YouTube.validate(query, "PLAYLIST")) return "youtube_playlist"; + if (vimeoRegex.test(query)) return "vimeo"; + if (facebookRegex.test(query)) return "facebook"; + if (reverbnationRegex.test(query)) return "reverbnation"; + if (Util.isURL(query)) return "attachment"; + + return "youtube_search"; + } + + static isURL(str: string) { + const urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$'; + const url = new RegExp(urlRegex, 'i'); + return str.length < 2083 && url.test(str); + } + + static getVimeoID(query: string) { + return Util.getQueryType(query) === "vimeo" ? query.split("/").filter(x => !!x).pop() : null + } + + static parseMS(milliseconds: number) { + // taken from ms package :: https://github.com/sindresorhus/parse-ms/blob/main/index.js + const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; + + return { + days: roundTowardsZero(milliseconds / 86400000), + hours: roundTowardsZero(milliseconds / 3600000) % 24, + minutes: roundTowardsZero(milliseconds / 60000) % 60, + seconds: roundTowardsZero(milliseconds / 1000) % 60 + }; + } + + static durationString(durObj: object) { + return Object.values(durObj).map(m => isNaN(m) ? 0 : m ).join(":"); + } + + static ytSearch(query: string, options?: any): Promise { + return new Promise(async (resolve) => { + await YouTube.search(query, { + type: "video", + safeSearch: Boolean(options?.player.options.useSafeSearch) + }) + .then(results => { + resolve(results.map((r) => new Track(options?.player, { + title: r.title, + description: r.description, + author: r.channel.name, + url: r.url, + thumbnail: r.thumbnail.displayThumbnailURL(), + duration: r.durationFormatted, + views: r.views, + requestedBy: options?.user, + fromPlaylist: false, + source: "youtube" + }))); + }) + .catch(() => resolve([])); + }); + } +} diff --git a/yarn.lock b/yarn.lock index 2a9d968..ab51860 100644 --- a/yarn.lock +++ b/yarn.lock @@ -143,6 +143,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -165,6 +170,30 @@ chalk@^2.0.0, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +cheerio-select-tmp@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646" + integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ== + dependencies: + css-select "^3.1.2" + css-what "^4.0.0" + domelementtype "^2.1.0" + domhandler "^4.0.0" + domutils "^2.4.4" + +cheerio@^1.0.0-rc.3: + version "1.0.0-rc.5" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f" + integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw== + dependencies: + cheerio-select-tmp "^0.1.0" + dom-serializer "~1.2.0" + domhandler "^4.0.0" + entities "~2.1.0" + htmlparser2 "^6.0.0" + parse5 "^6.0.0" + parse5-htmlparser2-tree-adapter "^6.0.0" + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -214,6 +243,29 @@ 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= +cross-fetch@^3.0.5: + version "3.1.4" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" + integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== + dependencies: + node-fetch "2.6.1" + +css-select@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" + integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== + dependencies: + boolbase "^1.0.0" + css-what "^4.0.0" + domhandler "^4.0.0" + domutils "^2.4.3" + nth-check "^2.0.0" + +css-what@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" + integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== + debug@4: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" @@ -260,6 +312,46 @@ discord.js@discordjs/discord.js: tweetnacl "^1.0.3" ws "^7.3.1" +dom-serializer@^1.0.1, dom-serializer@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1" + integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.1.0, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^4.0.0, domhandler@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43" + integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.4.3, domutils@^2.4.4: + version "2.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.1.tgz#9b8e84b5d9f788499ae77506ea832e9b4f9aa1c0" + integrity sha512-hO1XwHMGAthA/1KL7c83oip/6UWo3FlUNIuWiWKltoiQ5oCOiqths8KknvY2jpOohUoUgnwa/+Rm7UpwpSbY/Q== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.1.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -335,6 +427,21 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +himalaya@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a" + integrity sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw== + +htmlparser2@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.1.tgz#422521231ef6d42e56bd411da8ba40aa36e91446" + integrity sha512-GDKPd+vk4jvSuvCbyuzx/unmXkk090Azec7LovXP8as1Hn8q9p3hbjmDGbUqqhknw0ajwit6LiiWqfiTUPMK7w== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.4.4" + entities "^2.0.0" + http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -406,7 +513,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -m3u8stream@^0.8.3: +m3u8stream@^0.8.0, m3u8stream@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/m3u8stream/-/m3u8stream-0.8.3.tgz#c4624e92b4240eb356d040c4a5e155586cf58108" integrity sha512-0nAcdrF8YJKUkb6PzWdvGftTPyCVWgoiot1AkNVbPKTeIGsWs6DrOjifrJ0Zi8WQfQmD2SuVCjkYIOip12igng== @@ -487,7 +594,7 @@ node-addon-api@^3.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== -node-fetch@^2.6.0, node-fetch@^2.6.1: +node-fetch@2.6.1, node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== @@ -509,6 +616,13 @@ npmlog@^4.1.2: gauge "~2.7.3" set-blocking "~2.0.0" +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== + dependencies: + boolbase "^1.0.0" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -526,6 +640,18 @@ once@^1.3.0: dependencies: wrappy "1" +parse5-htmlparser2-tree-adapter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5@^6.0.0, parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -624,6 +750,29 @@ simple-youtube-api@^5.2.1: iso8601-duration "^1.2.0" node-fetch "^2.6.0" +soundcloud-scraper@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/soundcloud-scraper/-/soundcloud-scraper-4.0.3.tgz#cd7ed1d7b6ed1d7729fd7580c011281f652b920f" + integrity sha512-A0a6sVJ2wkkWIX8Ft3L63sfHBlFDRAaPFif+SWi07KCNLh8YTcylw45pts76pndxlupKwV2NgOTIYeF/F9tg8w== + dependencies: + cheerio "^1.0.0-rc.3" + m3u8stream "^0.8.0" + node-fetch "^2.6.1" + +spotify-uri@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spotify-uri/-/spotify-uri-2.2.0.tgz#8db641615cf6e122284874287fe39e89595922df" + integrity sha512-uUybj02bfyfCoZ0MJ80MkqbKxtIVRJfbRGk05KJFq1li3zb7yNfN1f+TAw4wcXgp7jLWExeiw2wyPQXZ8PHtfg== + +spotify-url-info@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spotify-url-info/-/spotify-url-info-2.2.0.tgz#7d14adbae65b54b918c46e2dcfdf02b1146f85c8" + integrity sha512-GEMoMf2RF+CSPsSGstY/9c7dgViKOKJ09bFZTwrU4KzQ+JpLq+0Ho4eMCeeGmES94yjBz+GHMtBfTcp+4DxEbA== + dependencies: + cross-fetch "^3.0.5" + himalaya "^1.1.0" + spotify-uri "^2.1.0" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" From 073d94e7a9e6748a2e2fb820819e60d9308a3317 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 18:43:46 +0545 Subject: [PATCH 013/131] format --- src/Player.ts | 112 ++++++++++++++++------------- src/Structures/Queue.ts | 16 ++--- src/Structures/Track.ts | 30 ++++---- src/index.ts | 14 ++-- src/types/types.ts | 146 +++++++++++++++++++------------------- src/utils/AudioFilters.ts | 9 ++- src/utils/Constants.ts | 30 ++++---- src/utils/Util.ts | 95 ++++++++++++++----------- tslint.json | 3 +- 9 files changed, 244 insertions(+), 211 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 414d691..261ecb8 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,19 +1,19 @@ -import YouTube from "youtube-sr"; -import { EventEmitter } from "events"; -import { Client, Collection, Snowflake, Collector, Message } from "discord.js"; -import { PlayerOptions } from "./types/types"; -import Util from "./utils/Util"; -import AudioFilters from "./utils/AudioFilters"; -import Queue from "./Structures/Queue"; -import Track from "./Structures/Track"; -import { PlayerEvents } from "./utils/Constants"; +import YouTube from 'youtube-sr'; +import { EventEmitter } from 'events'; +import { Client, Collection, Snowflake, Collector, Message } from 'discord.js'; +import { PlayerOptions } from './types/types'; +import Util from './utils/Util'; +import AudioFilters from './utils/AudioFilters'; +import Queue from './Structures/Queue'; +import Track from './Structures/Track'; +import { PlayerEvents } from './utils/Constants'; // @ts-ignore -import spotify from "spotify-url-info"; +import spotify from 'spotify-url-info'; // @ts-ignore -import { Client as SoundCloudClient } from "soundcloud-scraper"; +import { Client as SoundCloudClient } from 'soundcloud-scraper'; -const SoundCloud = new SoundCloudClient; +const SoundCloud = new SoundCloudClient(); export default class Player extends EventEmitter { public client!: Client; @@ -29,7 +29,7 @@ export default class Player extends EventEmitter { /** * The discord client that instantiated this player */ - Object.defineProperty(this, "client", { + Object.defineProperty(this, 'client', { value: client, enumerable: false }); @@ -57,43 +57,55 @@ export default class Player extends EventEmitter { return AudioFilters; } - private _searchTracks(message: Message, query: string, firstResult?: boolean, isAttachment?: boolean): Promise { + private _searchTracks( + message: Message, + query: string, + firstResult?: boolean, + isAttachment?: boolean + ): Promise { return new Promise(async (resolve) => { let tracks: Track[] = []; - let queryType = Util.getQueryType(query); + const queryType = Util.getQueryType(query); - switch(queryType) { - case "soundcloud_track": { - const data = await SoundCloud.getSongInfo(query).catch(() => { }) - if (data) { - const track = new Track(this, { - title: data.title, - url: data.url, - duration: Util.durationString(Util.parseMS(data.duration / 1000)), - description: data.description, - thumbnail: data.thumbnail, - views: data.playCount, - author: data.author, - requestedBy: message.author, - fromPlaylist: false, - source: "soundcloud", - engine: data - }); + switch (queryType) { + case 'soundcloud_track': + { + const data = await SoundCloud.getSongInfo(query).catch(() => {}); + if (data) { + const track = new Track(this, { + title: data.title, + url: data.url, + duration: Util.durationString(Util.parseMS(data.duration / 1000)), + description: data.description, + thumbnail: data.thumbnail, + views: data.playCount, + author: data.author, + requestedBy: message.author, + fromPlaylist: false, + source: 'soundcloud', + engine: data + }); - tracks.push(track) - } - } - break; - case "spotify_song": { - const matchSpotifyURL = query.match(/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/) - if (matchSpotifyURL) { - const spotifyData = await spotify.getPreview(query).catch(() => { }) - if (spotifyData) { - tracks = await Util.ytSearch(`${spotifyData.artist} - ${spotifyData.title}`, { user: message.author, player: this }); + tracks.push(track); } } - } - break; + break; + case 'spotify_song': + { + const matchSpotifyURL = query.match( + /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/ + ); + if (matchSpotifyURL) { + const spotifyData = await spotify.getPreview(query).catch(() => {}); + if (spotifyData) { + tracks = await Util.ytSearch(`${spotifyData.artist} - ${spotifyData.title}`, { + user: message.author, + player: this + }); + } + } + } + break; default: tracks = await Util.ytSearch(query, { user: message.author, player: this }); } @@ -103,7 +115,7 @@ export default class Player extends EventEmitter { const collectorString = `${message.author.id}-${message.channel.id}`; const currentCollector = this._resultsCollectors.get(collectorString); - if (currentCollector) currentCollector.stop() + if (currentCollector) currentCollector.stop(); const collector = message.channel.createMessageCollector((m) => m.author.id === message.author.id, { time: 60000 @@ -113,8 +125,8 @@ export default class Player extends EventEmitter { this.emit(PlayerEvents.SEARCH_RESULTS, message, query, tracks, collector); - collector.on("collect", ({ content }) => { - if (content === "cancel") { + collector.on('collect', ({ content }) => { + if (content === 'cancel') { collector.stop(); return this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); } @@ -127,10 +139,10 @@ export default class Player extends EventEmitter { } else { this.emit(PlayerEvents.SEARCH_INVALID_RESPONSE, message, query, tracks, content, collector); } - }) + }); - collector.on("end", (collected, reason) => { - if (reason === "time") { + collector.on('end', (collected, reason) => { + if (reason === 'time') { this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); } }); diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index c853b5c..41a48ab 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -1,9 +1,9 @@ -import { Message, Snowflake, VoiceConnection } from "discord.js"; -import AudioFilters from "../utils/AudioFilters"; -import Player from "../Player"; -import { EventEmitter } from "events"; -import Track from "./Track"; -import { QueueFilters } from "../types/types"; +import { Message, Snowflake, VoiceConnection } from 'discord.js'; +import AudioFilters from '../utils/AudioFilters'; +import Player from '../Player'; +import { EventEmitter } from 'events'; +import Track from './Track'; +import { QueueFilters } from '../types/types'; export default class Queue extends EventEmitter { public player!: Player; @@ -28,7 +28,7 @@ export default class Queue extends EventEmitter { /** * The player that instantiated this Queue */ - Object.defineProperty(this, "player", { value: player, enumerable: false }); + Object.defineProperty(this, 'player', { value: player, enumerable: false }); /** * ID of the guild assigned to this queue @@ -93,7 +93,7 @@ export default class Queue extends EventEmitter { // @ts-ignore this.filters = {}; - Object.keys(AudioFilters).forEach(fn => { + Object.keys(AudioFilters).forEach((fn) => { // @ts-ignore this.filters[fn] = false; }); diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 970aeb4..b74bef0 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,6 +1,6 @@ -import Player from "../Player"; -import { User } from "discord.js"; -import { TrackData } from "../types/types"; +import Player from '../Player'; +import { User } from 'discord.js'; +import { TrackData } from '../types/types'; export default class Track { public player!: Player; @@ -19,31 +19,31 @@ export default class Track { /** * The player that instantiated this Track */ - Object.defineProperty(this, "player", { value: player, enumerable: false }); + Object.defineProperty(this, 'player', { value: player, enumerable: false }); void this._patch(data); } private _patch(data: TrackData) { - this.title = data.title ?? ""; - this.description = data.description ?? ""; - this.author = data.author ?? ""; - this.url = data.url ?? ""; - this.thumbnail = data.thumbnail ?? ""; - this.duration = data.duration ?? ""; + this.title = data.title ?? ''; + this.description = data.description ?? ''; + this.author = data.author ?? ''; + this.url = data.url ?? ''; + this.thumbnail = data.thumbnail ?? ''; + this.duration = data.duration ?? ''; this.views = data.views ?? 0; this.requestedBy = data.requestedBy; this.fromPlaylist = Boolean(data.fromPlaylist); // raw - Object.defineProperty(this, "raw", { get: () => data, enumerable: false }); + Object.defineProperty(this, 'raw', { get: () => data, enumerable: false }); } /** * The queue in which this track is located */ get queue() { - return this.player.queues.find(q => q.tracks.includes(this)); + return this.player.queues.find((q) => q.tracks.includes(this)); } /** @@ -56,7 +56,11 @@ export default class Track { return t <= 0 ? 1000 : tn * 1000; }; - return this.duration.split(":").reverse().map((m, i) => parseInt(m) * times(60, i)).reduce((a, c) => a + c, 0); + return this.duration + .split(':') + .reverse() + .map((m, i) => parseInt(m) * times(60, i)) + .reduce((a, c) => a + c, 0); } toString() { diff --git a/src/index.ts b/src/index.ts index f54dbd7..9cce00d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -export * as AudioFilters from "./utils/AudioFilters"; -export * as Player from "./Player"; -export * as Util from "./utils/Util"; -export * as Track from "./Structures/Track"; -export * as Queue from "./Structures/Queue"; -export * from "./types/types"; -export { version } from "../package.json"; +export * as AudioFilters from './utils/AudioFilters'; +export * as Player from './Player'; +export * as Util from './utils/Util'; +export * as Track from './Structures/Track'; +export * as Queue from './Structures/Queue'; +export * from './types/types'; +export { version } from '../package.json'; diff --git a/src/types/types.ts b/src/types/types.ts index 56762fe..69c5214 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,5 +1,5 @@ -import { downloadOptions } from "ytdl-core"; -import { User } from "discord.js"; +import { downloadOptions } from 'ytdl-core'; +import { User } from 'discord.js'; export interface PlayerOptions { leaveOnEnd?: boolean; @@ -14,36 +14,36 @@ export interface PlayerOptions { } export type FiltersName = - | "bassboost" - | "8D" - | "vaporwave" - | "nightcore" - | "phaser" - | "tremolo" - | "vibrato" - | "reverse" - | "treble" - | "normalizer" - | "surrounding" - | "pulsator" - | "subboost" - | "karaoke" - | "flanger" - | "gate" - | "haas" - | "mcompand" - | "mono" - | "mstlr" - | "mstrr" - | "compressor" - | "expander" - | "softlimiter" - | "chorus" - | "chorus2d" - | "chorus3d" - | "fadein"; + | 'bassboost' + | '8D' + | 'vaporwave' + | 'nightcore' + | 'phaser' + | 'tremolo' + | 'vibrato' + | 'reverse' + | 'treble' + | 'normalizer' + | 'surrounding' + | 'pulsator' + | 'subboost' + | 'karaoke' + | 'flanger' + | 'gate' + | 'haas' + | 'mcompand' + | 'mono' + | 'mstlr' + | 'mstrr' + | 'compressor' + | 'expander' + | 'softlimiter' + | 'chorus' + | 'chorus2d' + | 'chorus3d' + | 'fadein'; -export type TrackSource = "soundcloud" | "youtube" | "arbitrary"; +export type TrackSource = 'soundcloud' | 'youtube' | 'arbitrary'; export interface TrackData { title: string; @@ -60,46 +60,46 @@ export interface TrackData { } 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; -} + 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"; \ No newline at end of file +export type QueryType = + | 'soundcloud_track' + | 'soundcloud_playlist' + | 'spotify_song' + | 'spotify_album' + | 'spotify_playlist' + | 'youtube_video' + | 'youtube_playlist' + | 'vimeo' + | 'facebook' + | 'reverbnation' + | 'attachment' + | 'youtube_search'; diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index e8de4f8..736e300 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -1,4 +1,4 @@ -import { FiltersName } from "../types/types"; +import { FiltersName } from '../types/types'; const FilterList = { bassboost: 'bass=g=20', @@ -47,8 +47,11 @@ const FilterList = { }, create(filter?: FiltersName[]) { if (!filter || !Array.isArray(filter)) return this.toString(); - return filter.filter(predicate => typeof predicate === "string").map(m => this[m]).join(","); + return filter + .filter((predicate) => typeof predicate === 'string') + .map((m) => this[m]) + .join(','); } }; -export default FilterList; \ No newline at end of file +export default FilterList; diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index e4f21a7..1b501e7 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -1,16 +1,16 @@ export const PlayerEvents = { - BOT_DISCONNECT: "botDisconnect", - CHANNEL_EMPTY: "channelEmpty", - ERROR: "error", - NO_RESULTS: "noResults", - PLAYLIST_ADD: "playlistAdd", - PLAYLIST_PARSE_END: "playlistParseEnd", - PLAYLIST_PARSE_START: "playlistParseStart", - QUEUE_CREATE: "queueCreate", - QUEUE_END: "queueEnd", - SEARCH_CANCEL: "searchCancel", - SEARCH_INVALID_RESPONSE: "searchInvalidResponse", - SEARCH_RESULTS: "searchResults", - TRACK_ADD: "trackAdd", - TRACK_START: "trackStart", -}; \ No newline at end of file + BOT_DISCONNECT: 'botDisconnect', + CHANNEL_EMPTY: 'channelEmpty', + ERROR: 'error', + NO_RESULTS: 'noResults', + PLAYLIST_ADD: 'playlistAdd', + PLAYLIST_PARSE_END: 'playlistParseEnd', + PLAYLIST_PARSE_START: 'playlistParseStart', + QUEUE_CREATE: 'queueCreate', + QUEUE_END: 'queueEnd', + SEARCH_CANCEL: 'searchCancel', + SEARCH_INVALID_RESPONSE: 'searchInvalidResponse', + SEARCH_RESULTS: 'searchResults', + TRACK_ADD: 'trackAdd', + TRACK_START: 'trackStart' +}; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index fa4aeb4..3e7bb19 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -1,16 +1,16 @@ -import { PlayerOptions, QueryType } from "../types/types"; -import { FFmpeg } from "prism-media"; -import YouTube from "youtube-sr"; -import Track from "../Structures/Track"; +import { PlayerOptions, QueryType } from '../types/types'; +import { FFmpeg } from 'prism-media'; +import YouTube from 'youtube-sr'; +import Track from '../Structures/Track'; // @ts-ignore -import { validateURL as SoundcloudValidateURL } from "soundcloud-scraper"; +import { validateURL as SoundcloudValidateURL } from 'soundcloud-scraper'; -const spotifySongRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/); -const spotifyPlaylistRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/); -const spotifyAlbumRegex = (/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/); -const vimeoRegex = (/(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/); -const facebookRegex = (/(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/); -const reverbnationRegex = (/https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/); +const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/; +const spotifyPlaylistRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/; +const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/; +const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/; +const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/; +const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/; export default class Util { constructor() { @@ -44,34 +44,40 @@ export default class Util { if (!hasFFmpeg) console.warn( - "[Discord Player] FFmpeg/Avconv not found! Install via \"npm install ffmpeg-static\" or download from https://ffmpeg.org/download.html" + '[Discord Player] FFmpeg/Avconv not found! Install via "npm install ffmpeg-static" or download from https://ffmpeg.org/download.html' ); } static getQueryType(query: string): QueryType { - if (SoundcloudValidateURL(query) && !query.includes("/sets/")) return "soundcloud_track"; - if (SoundcloudValidateURL(query) && query.includes("/sets/")) return "soundcloud_playlist"; - if (spotifySongRegex.test(query)) return "spotify_song"; - if (spotifyAlbumRegex.test(query)) return "spotify_album"; - if (spotifyPlaylistRegex.test(query)) return "spotify_playlist"; - if (YouTube.validate(query, "VIDEO")) return "youtube_video"; - if (YouTube.validate(query, "PLAYLIST")) return "youtube_playlist"; - if (vimeoRegex.test(query)) return "vimeo"; - if (facebookRegex.test(query)) return "facebook"; - if (reverbnationRegex.test(query)) return "reverbnation"; - if (Util.isURL(query)) return "attachment"; + if (SoundcloudValidateURL(query) && !query.includes('/sets/')) return 'soundcloud_track'; + if (SoundcloudValidateURL(query) && query.includes('/sets/')) return 'soundcloud_playlist'; + if (spotifySongRegex.test(query)) return 'spotify_song'; + if (spotifyAlbumRegex.test(query)) return 'spotify_album'; + if (spotifyPlaylistRegex.test(query)) return 'spotify_playlist'; + if (YouTube.validate(query, 'VIDEO')) return 'youtube_video'; + if (YouTube.validate(query, 'PLAYLIST')) return 'youtube_playlist'; + if (vimeoRegex.test(query)) return 'vimeo'; + if (facebookRegex.test(query)) return 'facebook'; + if (reverbnationRegex.test(query)) return 'reverbnation'; + if (Util.isURL(query)) return 'attachment'; - return "youtube_search"; + return 'youtube_search'; } static isURL(str: string) { - const urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$'; + const urlRegex = + '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$'; const url = new RegExp(urlRegex, 'i'); return str.length < 2083 && url.test(str); } static getVimeoID(query: string) { - return Util.getQueryType(query) === "vimeo" ? query.split("/").filter(x => !!x).pop() : null + return Util.getQueryType(query) === 'vimeo' + ? query + .split('/') + .filter((x) => !!x) + .pop() + : null; } static parseMS(milliseconds: number) { @@ -87,28 +93,35 @@ export default class Util { } static durationString(durObj: object) { - return Object.values(durObj).map(m => isNaN(m) ? 0 : m ).join(":"); + return Object.values(durObj) + .map((m) => (isNaN(m) ? 0 : m)) + .join(':'); } static ytSearch(query: string, options?: any): Promise { return new Promise(async (resolve) => { await YouTube.search(query, { - type: "video", + type: 'video', safeSearch: Boolean(options?.player.options.useSafeSearch) }) - .then(results => { - resolve(results.map((r) => new Track(options?.player, { - title: r.title, - description: r.description, - author: r.channel.name, - url: r.url, - thumbnail: r.thumbnail.displayThumbnailURL(), - duration: r.durationFormatted, - views: r.views, - requestedBy: options?.user, - fromPlaylist: false, - source: "youtube" - }))); + .then((results) => { + resolve( + results.map( + (r) => + new Track(options?.player, { + title: r.title, + description: r.description, + author: r.channel.name, + url: r.url, + thumbnail: r.thumbnail.displayThumbnailURL(), + duration: r.durationFormatted, + views: r.views, + requestedBy: options?.user, + fromPlaylist: false, + source: 'youtube' + }) + ) + ); }) .catch(() => resolve([])); }); diff --git a/tslint.json b/tslint.json index 5d61f36..4e5571c 100644 --- a/tslint.json +++ b/tslint.json @@ -8,7 +8,8 @@ "object-literal-sort-keys": false, "interface-name": false, "no-empty": false, - "no-console": false + "no-console": false, + "radix": false }, "rulesDirectory": [] } \ No newline at end of file From 474d094ff2af241e6ea2f7cf7499d3f79ec07de2 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 18:44:07 +0545 Subject: [PATCH 014/131] param --- src/Player.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 261ecb8..01228e7 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -60,8 +60,7 @@ export default class Player extends EventEmitter { private _searchTracks( message: Message, query: string, - firstResult?: boolean, - isAttachment?: boolean + firstResult?: boolean ): Promise { return new Promise(async (resolve) => { let tracks: Track[] = []; From c7e6962219dac8d8dbb071bc310496cdc472c1d0 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 19:51:18 +0545 Subject: [PATCH 015/131] base --- src/Player.ts | 202 ++++++++++++++++++++++++++++++++++++++- src/utils/Constants.ts | 13 ++- src/utils/PlayerError.ts | 8 ++ tsconfig.json | 3 +- 4 files changed, 223 insertions(+), 3 deletions(-) create mode 100644 src/utils/PlayerError.ts diff --git a/src/Player.ts b/src/Player.ts index 01228e7..f4f69df 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -6,7 +6,9 @@ import Util from './utils/Util'; import AudioFilters from './utils/AudioFilters'; import Queue from './Structures/Queue'; import Track from './Structures/Track'; -import { PlayerEvents } from './utils/Constants'; +import { PlayerErrorEventCodes, PlayerEvents } from './utils/Constants'; +import PlayerError from "./utils/PlayerError"; +import ytdl from "discord-ytdl-core"; // @ts-ignore import spotify from 'spotify-url-info'; @@ -147,4 +149,202 @@ export default class Player extends EventEmitter { }); }); } + + async play(message: Message, query: string | Track, firstResult?: boolean) { + 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; + + if (query instanceof Track) track = query; + else { + if (ytdl.validateURL(query)) { + const info = await ytdl.getBasicInfo(query).catch(() => {}); + if (!info) return this.emit(PlayerEvents.NO_RESULTS, message, query); + if (info.videoDetails.isLiveContent && !this.options.enableLive) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.LIVE_VIDEO, message, new PlayerError("Live video is not enabled!")); + 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.durationString(Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)), + views: parseInt(info.videoDetails.viewCount), + requestedBy: message.author, + fromPlaylist: false, + source: "youtube" + }); + } else { + track = await this._searchTracks(message, query, firstResult); + } + } + + if (track) { + if (this.isPlaying(message)) { + const queue = this._addTrackToQueue(message, track); + this.emit(PlayerEvents.TRACK_ADD, message, queue, queue.tracks[queue.tracks.length - 1]); + } else { + const queue = await this._createQueue(message, track); + if (queue) this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); + } + } + } + + isPlaying(message: Message) { + return this.queues.some(g => g.guildID === message.guild.id); + } + + getQueue(message: Message) { + return this.queues.find(g => g.guildID === message.guild.id); + } + + private _addTrackToQueue(message: Message, track: Track) { + const queue = this.getQueue(message); + if (!queue) this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message, new PlayerError("Player is not available in this server")); + if (!track || !(track instanceof Track)) throw new PlayerError('No track specified to add to the queue'); + queue.tracks.push(track); + return queue; + } + + private _createQueue(message: Message, track: Track): Promise { + return new Promise((resolve) => { + const channel = message.member.voice ? message.member.voice.channel : null + if (!channel) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_CONNECTED, message, new PlayerError("Voice connection is not available in this server!")); + + const queue = new Queue(this, message, this.filters); + this.queues.set(message.guild.id, queue); + + channel.join().then((connection) => { + this.emit(PlayerEvents.CONNECTION_CREATE, message, connection); + + queue.voiceConnection = connection; + if (this.options.autoSelfDeaf) connection.voice.setSelfDeaf(true); + queue.tracks.push(track); + this.emit(PlayerEvents.QUEUE_CREATE, message, queue); + resolve(queue); + // this._playTrack(queue, true) + }).catch((err) => { + this.queues.delete(message.guild.id); + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.UNABLE_TO_JOIN, message, new PlayerError(err.message ?? err)); + }); + }); + } + + private async _playTrack(queue: Queue, firstPlay: boolean) { + if (queue.stopped) return; + + if (queue.tracks.length === 1 && !queue.loopMode && !queue.repeatMode && !firstPlay) { + if (this.options.leaveOnEnd && !queue.stopped) { + this.queues.delete(queue.guildID) + const timeout = setTimeout(() => { + queue.voiceConnection.channel.leave(); + }, this.options.leaveOnEndCooldown || 0); + this._cooldownsTimeout.set(`end_${queue.guildID}`, timeout); + } + + this.queues.delete(queue.guildID) + + if (queue.stopped) { + return this.emit(PlayerEvents.MUSIC_STOP, queue.firstMessage); + } + + return this.emit(PlayerEvents.QUEUE_END, queue.firstMessage, queue); + } + + if (!queue.repeatMode && !firstPlay) { + const oldTrack = queue.tracks.shift(); + if (queue.loopMode) queue.tracks.push(oldTrack); + queue.previousTracks.push(oldTrack); + } + + const track = queue.playing; + + queue.lastSkipped = false; + this._playStream(queue, false).then(() => { + if (!firstPlay) this.emit(PlayerEvents.TRACK_START, queue.firstMessage, track, queue); + }); + } + + private _playStream(queue: Queue, updateFilter: boolean, seek?: number): Promise { + return new Promise(async (resolve) => { + const ffmeg = Util.checkFFmpeg(); + if (!ffmeg) return; + + const seekTime = typeof seek === "number" ? seek : updateFilter ? queue.voiceConnection.dispatcher.streamTime + queue.additionalStreamTime : undefined; + const encoderArgsFilters: string[] = []; + + Object.keys(queue.filters).forEach((filterName) => { + // @ts-ignore + if (queue.filters[filterName]) { + // @ts-ignore + encoderArgsFilters.push(this.filters[filterName]); + } + }); + + let encoderArgs: string[]; + if (encoderArgsFilters.length < 1) { + encoderArgs = [] + } else { + encoderArgs = ['-af', encoderArgsFilters.join(',')] + } + + let newStream: any; + if (queue.playing.raw.source === "youtube") { + newStream = ytdl(queue.playing.url, { + filter: 'audioonly', + opusEncoded: true, + encoderArgs, + seek: seekTime / 1000, + highWaterMark: 1 << 25, + ...this.options.ytdlDownloadOptions + }); + } else { + newStream = ytdl.arbitraryStream(queue.playing.raw.source === "soundcloud" ? await queue.playing.raw.engine.downloadProgressive() : queue.playing.raw.engine, { + opusEncoded: true, + encoderArgs, + seek: seekTime / 1000 + }); + } + + setTimeout(() => { + if (queue.stream) queue.stream.destroy(); + queue.stream = newStream; + queue.voiceConnection.play(newStream, { + type: 'opus', + bitrate: 'auto' + }); + + if (seekTime) { + queue.additionalStreamTime = seekTime; + } + queue.voiceConnection.dispatcher.setVolumeLogarithmic(queue.calculatedVolume / 200); + queue.voiceConnection.dispatcher.on('start', () => { + resolve(); + }); + + queue.voiceConnection.dispatcher.on('finish', () => { + queue.additionalStreamTime = 0; + return this._playTrack(queue, false); + }); + + newStream.on('error', (error: Error) => { + if (error.message.toLowerCase().includes('video unavailable')) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.VIDEO_UNAVAILABLE, queue.firstMessage, queue.playing, error); + this._playTrack(queue, false); + } else { + this.emit(PlayerEvents.ERROR, error, queue.firstMessage, error); + } + }); + }, 1000); + }); + } + } diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index 1b501e7..e44ff01 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -1,7 +1,9 @@ export const PlayerEvents = { BOT_DISCONNECT: 'botDisconnect', CHANNEL_EMPTY: 'channelEmpty', + CONNECTION_CREATE: 'connectionCreate', ERROR: 'error', + MUSIC_STOP: 'musicStop', NO_RESULTS: 'noResults', PLAYLIST_ADD: 'playlistAdd', PLAYLIST_PARSE_END: 'playlistParseEnd', @@ -12,5 +14,14 @@ export const PlayerEvents = { SEARCH_INVALID_RESPONSE: 'searchInvalidResponse', SEARCH_RESULTS: 'searchResults', TRACK_ADD: 'trackAdd', - TRACK_START: 'trackStart' + TRACK_START: 'trackStart', +}; + +export const PlayerErrorEventCodes = { + LIVE_VIDEO: "LiveVideo", + NOT_CONNECTED: "NotConnected", + UNABLE_TO_JOIN: "UnableToJoin", + NOT_PLAYING: "NotPlaying", + PARSE_ERROR: "ParseError", + VIDEO_UNAVAILABLE: "VideoUnavailable" }; diff --git a/src/utils/PlayerError.ts b/src/utils/PlayerError.ts new file mode 100644 index 0000000..2c362eb --- /dev/null +++ b/src/utils/PlayerError.ts @@ -0,0 +1,8 @@ +export default class PlayerError extends Error { + constructor(msg: string, name?: string) { + super(); + this.name = name ?? "PlayerError"; + this.message = msg; + Error.captureStackTrace(this); + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 441108e..d75c6d9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "outDir": "./lib", "strict": true, "strictNullChecks": false, - "resolveJsonModule": true + "resolveJsonModule": true, + "esModuleInterop": true }, "include": [ "src/**/*" From 2fb209ad287b7bc6fe16a85c246b1c7d969431db Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 19:53:01 +0545 Subject: [PATCH 016/131] format --- src/Player.ts | 122 +++++++++++++++++++++++++-------------- src/utils/Constants.ts | 14 ++--- src/utils/PlayerError.ts | 4 +- 3 files changed, 89 insertions(+), 51 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index f4f69df..a3baab8 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -7,8 +7,8 @@ import AudioFilters from './utils/AudioFilters'; import Queue from './Structures/Queue'; import Track from './Structures/Track'; import { PlayerErrorEventCodes, PlayerEvents } from './utils/Constants'; -import PlayerError from "./utils/PlayerError"; -import ytdl from "discord-ytdl-core"; +import PlayerError from './utils/PlayerError'; +import ytdl from 'discord-ytdl-core'; // @ts-ignore import spotify from 'spotify-url-info'; @@ -59,11 +59,7 @@ export default class Player extends EventEmitter { return AudioFilters; } - private _searchTracks( - message: Message, - query: string, - firstResult?: boolean - ): Promise { + private _searchTracks(message: Message, query: string, firstResult?: boolean): Promise { return new Promise(async (resolve) => { let tracks: Track[] = []; const queryType = Util.getQueryType(query); @@ -151,15 +147,15 @@ export default class Player extends EventEmitter { } async play(message: Message, query: string | Track, firstResult?: boolean) { - 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 (!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'); + if (typeof query === 'string') query = query.replace(/<(.+)>/g, '$1'); let track; if (query instanceof Track) track = query; @@ -167,7 +163,13 @@ export default class Player extends EventEmitter { if (ytdl.validateURL(query)) { const info = await ytdl.getBasicInfo(query).catch(() => {}); if (!info) return this.emit(PlayerEvents.NO_RESULTS, message, query); - if (info.videoDetails.isLiveContent && !this.options.enableLive) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.LIVE_VIDEO, message, new PlayerError("Live video is not enabled!")); + if (info.videoDetails.isLiveContent && !this.options.enableLive) + return this.emit( + PlayerEvents.ERROR, + PlayerErrorEventCodes.LIVE_VIDEO, + message, + new PlayerError('Live video is not enabled!') + ); const lastThumbnail = info.videoDetails.thumbnails[info.videoDetails.thumbnails.length - 1]; track = new Track(this, { @@ -180,7 +182,7 @@ export default class Player extends EventEmitter { views: parseInt(info.videoDetails.viewCount), requestedBy: message.author, fromPlaylist: false, - source: "youtube" + source: 'youtube' }); } else { track = await this._searchTracks(message, query, firstResult); @@ -199,16 +201,22 @@ export default class Player extends EventEmitter { } isPlaying(message: Message) { - return this.queues.some(g => g.guildID === message.guild.id); + return this.queues.some((g) => g.guildID === message.guild.id); } getQueue(message: Message) { - return this.queues.find(g => g.guildID === message.guild.id); + return this.queues.find((g) => g.guildID === message.guild.id); } private _addTrackToQueue(message: Message, track: Track) { const queue = this.getQueue(message); - if (!queue) this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message, new PlayerError("Player is not available in this server")); + if (!queue) + this.emit( + PlayerEvents.ERROR, + PlayerErrorEventCodes.NOT_PLAYING, + message, + new PlayerError('Player is not available in this server') + ); if (!track || !(track instanceof Track)) throw new PlayerError('No track specified to add to the queue'); queue.tracks.push(track); return queue; @@ -216,25 +224,39 @@ export default class Player extends EventEmitter { private _createQueue(message: Message, track: Track): Promise { return new Promise((resolve) => { - const channel = message.member.voice ? message.member.voice.channel : null - if (!channel) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_CONNECTED, message, new PlayerError("Voice connection is not available in this server!")); + const channel = message.member.voice ? message.member.voice.channel : null; + if (!channel) + return this.emit( + PlayerEvents.ERROR, + PlayerErrorEventCodes.NOT_CONNECTED, + message, + new PlayerError('Voice connection is not available in this server!') + ); const queue = new Queue(this, message, this.filters); this.queues.set(message.guild.id, queue); - channel.join().then((connection) => { - this.emit(PlayerEvents.CONNECTION_CREATE, message, connection); + channel + .join() + .then((connection) => { + this.emit(PlayerEvents.CONNECTION_CREATE, message, connection); - queue.voiceConnection = connection; - if (this.options.autoSelfDeaf) connection.voice.setSelfDeaf(true); - queue.tracks.push(track); - this.emit(PlayerEvents.QUEUE_CREATE, message, queue); - resolve(queue); - // this._playTrack(queue, true) - }).catch((err) => { - this.queues.delete(message.guild.id); - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.UNABLE_TO_JOIN, message, new PlayerError(err.message ?? err)); - }); + queue.voiceConnection = connection; + if (this.options.autoSelfDeaf) connection.voice.setSelfDeaf(true); + queue.tracks.push(track); + this.emit(PlayerEvents.QUEUE_CREATE, message, queue); + resolve(queue); + // this._playTrack(queue, true) + }) + .catch((err) => { + this.queues.delete(message.guild.id); + this.emit( + PlayerEvents.ERROR, + PlayerErrorEventCodes.UNABLE_TO_JOIN, + message, + new PlayerError(err.message ?? err) + ); + }); }); } @@ -243,14 +265,14 @@ export default class Player extends EventEmitter { if (queue.tracks.length === 1 && !queue.loopMode && !queue.repeatMode && !firstPlay) { if (this.options.leaveOnEnd && !queue.stopped) { - this.queues.delete(queue.guildID) + this.queues.delete(queue.guildID); const timeout = setTimeout(() => { queue.voiceConnection.channel.leave(); }, this.options.leaveOnEndCooldown || 0); this._cooldownsTimeout.set(`end_${queue.guildID}`, timeout); } - this.queues.delete(queue.guildID) + this.queues.delete(queue.guildID); if (queue.stopped) { return this.emit(PlayerEvents.MUSIC_STOP, queue.firstMessage); @@ -278,7 +300,12 @@ export default class Player extends EventEmitter { const ffmeg = Util.checkFFmpeg(); if (!ffmeg) return; - const seekTime = typeof seek === "number" ? seek : updateFilter ? queue.voiceConnection.dispatcher.streamTime + queue.additionalStreamTime : undefined; + const seekTime = + typeof seek === 'number' + ? seek + : updateFilter + ? queue.voiceConnection.dispatcher.streamTime + queue.additionalStreamTime + : undefined; const encoderArgsFilters: string[] = []; Object.keys(queue.filters).forEach((filterName) => { @@ -291,27 +318,33 @@ export default class Player extends EventEmitter { let encoderArgs: string[]; if (encoderArgsFilters.length < 1) { - encoderArgs = [] + encoderArgs = []; } else { - encoderArgs = ['-af', encoderArgsFilters.join(',')] + encoderArgs = ['-af', encoderArgsFilters.join(',')]; } let newStream: any; - if (queue.playing.raw.source === "youtube") { + if (queue.playing.raw.source === 'youtube') { newStream = ytdl(queue.playing.url, { filter: 'audioonly', opusEncoded: true, encoderArgs, seek: seekTime / 1000, + // tslint:disable-next-line:no-bitwise highWaterMark: 1 << 25, ...this.options.ytdlDownloadOptions }); } else { - newStream = ytdl.arbitraryStream(queue.playing.raw.source === "soundcloud" ? await queue.playing.raw.engine.downloadProgressive() : queue.playing.raw.engine, { - opusEncoded: true, - encoderArgs, - seek: seekTime / 1000 - }); + newStream = ytdl.arbitraryStream( + queue.playing.raw.source === 'soundcloud' + ? await queue.playing.raw.engine.downloadProgressive() + : queue.playing.raw.engine, + { + opusEncoded: true, + encoderArgs, + seek: seekTime / 1000 + } + ); } setTimeout(() => { @@ -337,7 +370,13 @@ export default class Player extends EventEmitter { newStream.on('error', (error: Error) => { if (error.message.toLowerCase().includes('video unavailable')) { - this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.VIDEO_UNAVAILABLE, queue.firstMessage, queue.playing, error); + this.emit( + PlayerEvents.ERROR, + PlayerErrorEventCodes.VIDEO_UNAVAILABLE, + queue.firstMessage, + queue.playing, + error + ); this._playTrack(queue, false); } else { this.emit(PlayerEvents.ERROR, error, queue.firstMessage, error); @@ -346,5 +385,4 @@ export default class Player extends EventEmitter { }, 1000); }); } - } diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index e44ff01..bc91621 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -14,14 +14,14 @@ export const PlayerEvents = { SEARCH_INVALID_RESPONSE: 'searchInvalidResponse', SEARCH_RESULTS: 'searchResults', TRACK_ADD: 'trackAdd', - TRACK_START: 'trackStart', + TRACK_START: 'trackStart' }; export const PlayerErrorEventCodes = { - LIVE_VIDEO: "LiveVideo", - NOT_CONNECTED: "NotConnected", - UNABLE_TO_JOIN: "UnableToJoin", - NOT_PLAYING: "NotPlaying", - PARSE_ERROR: "ParseError", - VIDEO_UNAVAILABLE: "VideoUnavailable" + LIVE_VIDEO: 'LiveVideo', + NOT_CONNECTED: 'NotConnected', + UNABLE_TO_JOIN: 'UnableToJoin', + NOT_PLAYING: 'NotPlaying', + PARSE_ERROR: 'ParseError', + VIDEO_UNAVAILABLE: 'VideoUnavailable' }; diff --git a/src/utils/PlayerError.ts b/src/utils/PlayerError.ts index 2c362eb..32cd56a 100644 --- a/src/utils/PlayerError.ts +++ b/src/utils/PlayerError.ts @@ -1,8 +1,8 @@ export default class PlayerError extends Error { constructor(msg: string, name?: string) { super(); - this.name = name ?? "PlayerError"; + this.name = name ?? 'PlayerError'; this.message = msg; Error.captureStackTrace(this); } -} \ No newline at end of file +} From fc8d0d08eeadf7177c2efe0e663cd02f3d5f1e84 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 20:09:42 +0545 Subject: [PATCH 017/131] export everything --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index 9cce00d..e7420c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,9 @@ export * as AudioFilters from './utils/AudioFilters'; +export * as Constants from './utils/Constants'; export * as Player from './Player'; export * as Util from './utils/Util'; export * as Track from './Structures/Track'; export * as Queue from './Structures/Queue'; export * from './types/types'; +export * as PlayerError from './utils/PlayerError'; export { version } from '../package.json'; From c1a8de52f36108647fc15c8aaedbbaec578e00cb Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 21:23:17 +0545 Subject: [PATCH 018/131] fix player --- package.json | 4 +- src/Player.ts | 52 +++++++++++++++++------ src/Structures/Queue.ts | 8 ++-- src/Structures/Track.ts | 6 ++- src/index.ts | 12 +++--- src/types/types.ts | 86 +++++++++++++-------------------------- src/utils/AudioFilters.ts | 1 + src/utils/PlayerError.ts | 2 + src/utils/Util.ts | 6 ++- yarn.lock | 21 ++++++---- 10 files changed, 106 insertions(+), 92 deletions(-) diff --git a/package.json b/package.json index d8ccef4..cf4f549 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "lib/**/*" ], "scripts": { - "test": "cd test && node index.js", + "test": "yarn build && cd test && node index.js", "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", "lint": "tslint -p tsconfig.json" @@ -47,7 +47,7 @@ "@discordjs/opus": "^0.5.0", "@types/node": "^14.14.37", "@types/ws": "^7.4.1", - "discord.js": "discordjs/discord.js", + "discord.js": "^12.5.3", "prettier": "^2.2.1", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", diff --git a/src/Player.ts b/src/Player.ts index a3baab8..20597f3 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,11 +1,10 @@ -import YouTube from 'youtube-sr'; import { EventEmitter } from 'events'; import { Client, Collection, Snowflake, Collector, Message } from 'discord.js'; -import { PlayerOptions } from './types/types'; +import { PlayerOptions, QueueFilters } from './types/types'; import Util from './utils/Util'; import AudioFilters from './utils/AudioFilters'; -import Queue from './Structures/Queue'; -import Track from './Structures/Track'; +import { Queue } from './Structures/Queue'; +import { Track } from './Structures/Track'; import { PlayerErrorEventCodes, PlayerEvents } from './utils/Constants'; import PlayerError from './utils/PlayerError'; import ytdl from 'discord-ytdl-core'; @@ -17,7 +16,7 @@ import { Client as SoundCloudClient } from 'soundcloud-scraper'; const SoundCloud = new SoundCloudClient(); -export default class Player extends EventEmitter { +export class Player extends EventEmitter { public client!: Client; public options: PlayerOptions; public filters: typeof AudioFilters; @@ -53,6 +52,9 @@ export default class Player extends EventEmitter { * Player queues */ this.queues = new Collection(); + + this._resultsCollectors = new Collection(); + this._cooldownsTimeout = new Collection(); } static get AudioFilters() { @@ -146,7 +148,7 @@ export default class Player extends EventEmitter { }); } - async play(message: Message, query: string | Track, firstResult?: boolean) { + 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'); @@ -162,9 +164,9 @@ export default class Player extends EventEmitter { else { if (ytdl.validateURL(query)) { const info = await ytdl.getBasicInfo(query).catch(() => {}); - if (!info) return this.emit(PlayerEvents.NO_RESULTS, message, query); + if (!info) return void this.emit(PlayerEvents.NO_RESULTS, message, query); if (info.videoDetails.isLiveContent && !this.options.enableLive) - return this.emit( + return void this.emit( PlayerEvents.ERROR, PlayerErrorEventCodes.LIVE_VIDEO, message, @@ -208,6 +210,28 @@ export default class Player extends EventEmitter { return this.queues.find((g) => g.guildID === message.guild.id); } + setFilters(message: Message, newFilters: QueueFilters): Promise { + return new Promise((resolve) => { + const queue = this.queues.find((g) => g.guildID === message.guild.id); + if (!queue) + this.emit( + PlayerEvents.ERROR, + PlayerErrorEventCodes.NOT_PLAYING, + message, + new PlayerError('Not playing') + ); + + Object.keys(newFilters).forEach((filterName) => { + // @ts-ignore + queue.filters[filterName] = newFilters[filterName]; + }); + + this._playStream(queue, true).then(() => { + resolve(); + }); + }); + } + private _addTrackToQueue(message: Message, track: Track) { const queue = this.getQueue(message); if (!queue) @@ -246,7 +270,7 @@ export default class Player extends EventEmitter { queue.tracks.push(track); this.emit(PlayerEvents.QUEUE_CREATE, message, queue); resolve(queue); - // this._playTrack(queue, true) + this._playTrack(queue, true); }) .catch((err) => { this.queues.delete(message.guild.id); @@ -260,7 +284,7 @@ export default class Player extends EventEmitter { }); } - private async _playTrack(queue: Queue, firstPlay: boolean) { + private async _playTrack(queue: Queue, firstPlay: boolean): Promise { if (queue.stopped) return; if (queue.tracks.length === 1 && !queue.loopMode && !queue.repeatMode && !firstPlay) { @@ -275,10 +299,10 @@ export default class Player extends EventEmitter { this.queues.delete(queue.guildID); if (queue.stopped) { - return this.emit(PlayerEvents.MUSIC_STOP, queue.firstMessage); + return void this.emit(PlayerEvents.MUSIC_STOP, queue.firstMessage); } - return this.emit(PlayerEvents.QUEUE_END, queue.firstMessage, queue); + return void this.emit(PlayerEvents.QUEUE_END, queue.firstMessage, queue); } if (!queue.repeatMode && !firstPlay) { @@ -316,7 +340,7 @@ export default class Player extends EventEmitter { } }); - let encoderArgs: string[]; + let encoderArgs: string[] = []; if (encoderArgsFilters.length < 1) { encoderArgs = []; } else { @@ -386,3 +410,5 @@ export default class Player extends EventEmitter { }); } } + +export default Player; diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 41a48ab..76294ed 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -1,11 +1,11 @@ import { Message, Snowflake, VoiceConnection } from 'discord.js'; import AudioFilters from '../utils/AudioFilters'; -import Player from '../Player'; +import { Player } from '../Player'; import { EventEmitter } from 'events'; -import Track from './Track'; +import { Track } from './Track'; import { QueueFilters } from '../types/types'; -export default class Queue extends EventEmitter { +export class Queue extends EventEmitter { public player!: Player; public guildID: Snowflake; public voiceConnection?: VoiceConnection; @@ -127,3 +127,5 @@ export default class Queue extends EventEmitter { return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; } } + +export default Queue; diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index b74bef0..c40b41d 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,8 +1,8 @@ -import Player from '../Player'; +import { Player } from '../Player'; import { User } from 'discord.js'; import { TrackData } from '../types/types'; -export default class Track { +export class Track { public player!: Player; public title!: string; public description!: string; @@ -67,3 +67,5 @@ export default class Track { return `${this.title} by ${this.author}`; } } + +export default Track; diff --git a/src/index.ts b/src/index.ts index e7420c2..1f75632 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,9 @@ -export * as AudioFilters from './utils/AudioFilters'; +export { AudioFilters } from './utils/AudioFilters'; export * as Constants from './utils/Constants'; -export * as Player from './Player'; -export * as Util from './utils/Util'; -export * as Track from './Structures/Track'; -export * as Queue from './Structures/Queue'; +export { Player } from './Player'; +export { Util } from './utils/Util'; +export { Track } from './Structures/Track'; +export { Queue } from './Structures/Queue'; export * from './types/types'; -export * as PlayerError from './utils/PlayerError'; +export { PlayerError } from './utils/PlayerError'; export { version } from '../package.json'; diff --git a/src/types/types.ts b/src/types/types.ts index 69c5214..192c826 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -13,35 +13,7 @@ export interface PlayerOptions { useSafeSearch?: boolean; } -export type FiltersName = - | 'bassboost' - | '8D' - | 'vaporwave' - | 'nightcore' - | 'phaser' - | 'tremolo' - | 'vibrato' - | 'reverse' - | 'treble' - | 'normalizer' - | 'surrounding' - | 'pulsator' - | 'subboost' - | 'karaoke' - | 'flanger' - | 'gate' - | 'haas' - | 'mcompand' - | 'mono' - | 'mstlr' - | 'mstrr' - | 'compressor' - | 'expander' - | 'softlimiter' - | 'chorus' - | 'chorus2d' - | 'chorus3d' - | 'fadein'; +export type FiltersName = keyof QueueFilters; export type TrackSource = 'soundcloud' | 'youtube' | 'arbitrary'; @@ -60,34 +32,34 @@ export interface TrackData { } 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; + 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 = diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 736e300..4c1fa3f 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -55,3 +55,4 @@ const FilterList = { }; export default FilterList; +export { FilterList as AudioFilters }; diff --git a/src/utils/PlayerError.ts b/src/utils/PlayerError.ts index 32cd56a..c87e1f6 100644 --- a/src/utils/PlayerError.ts +++ b/src/utils/PlayerError.ts @@ -6,3 +6,5 @@ export default class PlayerError extends Error { Error.captureStackTrace(this); } } + +export { PlayerError }; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 3e7bb19..87517b8 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -1,7 +1,7 @@ import { PlayerOptions, QueryType } from '../types/types'; import { FFmpeg } from 'prism-media'; import YouTube from 'youtube-sr'; -import Track from '../Structures/Track'; +import { Track } from '../Structures/Track'; // @ts-ignore import { validateURL as SoundcloudValidateURL } from 'soundcloud-scraper'; @@ -12,7 +12,7 @@ const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/ const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/; const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/; -export default class Util { +export class Util { constructor() { throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); } @@ -127,3 +127,5 @@ export default class Util { }); } } + +export default Util; diff --git a/yarn.lock b/yarn.lock index ab51860..e4eb2ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -300,17 +300,19 @@ discord-ytdl-core@^5.0.2: dependencies: prism-media "^1.2.7" -discord.js@discordjs/discord.js: - version "12.5.0" - resolved "https://codeload.github.com/discordjs/discord.js/tar.gz/e848d25c86fcd4a11a7879f7dcd55d0bc93faa6d" +discord.js@^12.5.3: + version "12.5.3" + resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-12.5.3.tgz#56820d473c24320871df9ea0bbc6b462f21cf85c" + integrity sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw== dependencies: "@discordjs/collection" "^0.1.6" "@discordjs/form-data" "^3.0.1" abort-controller "^3.0.0" node-fetch "^2.6.1" - prism-media "^1.2.2" + prism-media "^1.2.9" + setimmediate "^1.0.5" tweetnacl "^1.0.3" - ws "^7.3.1" + ws "^7.4.4" dom-serializer@^1.0.1, dom-serializer@~1.2.0: version "1.2.0" @@ -667,7 +669,7 @@ prettier@^2.2.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== -prism-media@^1.2.2, prism-media@^1.2.7: +prism-media@^1.2.7, prism-media@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.2.9.tgz#8d4f97b36efdfc82483eb8d3db64020767866f36" integrity sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q== @@ -737,6 +739,11 @@ set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + signal-exit@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -898,7 +905,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^7.3.1: +ws@^7.4.4: version "7.4.4" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== From d19106f8053e362b54f558c7fb547c0e19e4a5bd Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 21:30:11 +0545 Subject: [PATCH 019/131] define custom filters --- src/utils/AudioFilters.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 4c1fa3f..9544903 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -51,6 +51,16 @@ const FilterList = { .filter((predicate) => typeof predicate === 'string') .map((m) => this[m]) .join(','); + }, + define(filterName: string, value: string) { + /* @ts-ignore */ + if (typeof this[filterName] !== "string") return; + + /* @ts-ignore */ + this[filterName] = value; + }, + defineBulk(filterArray: { name: string, value: string }[]) { + filterArray.forEach(arr => this.define(arr.name, arr.value)); } }; From fabe38c0a6c0409fcd67e5cdb1c20d6375bfefea Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 21:31:48 +0545 Subject: [PATCH 020/131] format --- src/utils/AudioFilters.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 9544903..238fb33 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -54,13 +54,13 @@ const FilterList = { }, define(filterName: string, value: string) { /* @ts-ignore */ - if (typeof this[filterName] !== "string") return; + if (typeof this[filterName] !== 'string') return; /* @ts-ignore */ this[filterName] = value; }, - defineBulk(filterArray: { name: string, value: string }[]) { - filterArray.forEach(arr => this.define(arr.name, arr.value)); + defineBulk(filterArray: { name: string; value: string }[]) { + filterArray.forEach((arr) => this.define(arr.name, arr.value)); } }; From a83f72bdb34f84c3bedbc34a861ae8c0e9eff8aa Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 21:37:40 +0545 Subject: [PATCH 021/131] fix filters --- src/utils/AudioFilters.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 238fb33..9d5a624 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -42,9 +42,15 @@ const FilterList = { get length() { return Object.keys(this).length; }, + toString() { return `${Object.values(this).join(',')}`; }, + + /** + * Creates single string of audio filters + * @param filter Array of AudioFilters name + */ create(filter?: FiltersName[]) { if (!filter || !Array.isArray(filter)) return this.toString(); return filter @@ -52,13 +58,27 @@ const FilterList = { .map((m) => this[m]) .join(','); }, + + /** + * Defines custom filter + * @param filterName The filter name + * @param value FFmpeg args to use with -af + * @example Player.AudioFilters.define("3D", "apulsator=hz=0.125") + * + * player.setFilters(message, { "3D": true }) + */ define(filterName: string, value: string) { /* @ts-ignore */ - if (typeof this[filterName] !== 'string') return; + if (typeof this[filterName] && typeof this[filterName] === "function") return; /* @ts-ignore */ this[filterName] = value; }, + + /** + * Defines filters in bulk + * @param filterArray Array of filters containing object with `name` and `value` prop + */ defineBulk(filterArray: { name: string; value: string }[]) { filterArray.forEach((arr) => this.define(arr.name, arr.value)); } From 9128411d3a0762c482819e56833e6c67b8bab746 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 21:38:07 +0545 Subject: [PATCH 022/131] format --- src/utils/AudioFilters.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 9d5a624..153c13a 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -64,12 +64,12 @@ const FilterList = { * @param filterName The filter name * @param value FFmpeg args to use with -af * @example Player.AudioFilters.define("3D", "apulsator=hz=0.125") - * + * * player.setFilters(message, { "3D": true }) */ define(filterName: string, value: string) { /* @ts-ignore */ - if (typeof this[filterName] && typeof this[filterName] === "function") return; + if (typeof this[filterName] && typeof this[filterName] === 'function') return; /* @ts-ignore */ this[filterName] = value; From 224473d63d41de1de52bed8d94230306f3ce7da7 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Tue, 6 Apr 2021 22:06:43 +0545 Subject: [PATCH 023/131] disable some filters for live content --- src/Player.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Player.ts b/src/Player.ts index 20597f3..6aeb252 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -333,6 +333,8 @@ export class Player extends EventEmitter { const encoderArgsFilters: string[] = []; Object.keys(queue.filters).forEach((filterName) => { + if (this.options.enableLive && ["nightcore", "vaporwave", "reverse"].includes(filterName)) return; + // @ts-ignore if (queue.filters[filterName]) { // @ts-ignore From 610edb9755c01b27a8c774e08f8abb476941306f Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 7 Apr 2021 19:50:35 +0545 Subject: [PATCH 024/131] playlists and some methods --- src/Player.ts | 240 +++++++++++++++++++++++++++++++++++++++-- src/utils/Constants.ts | 3 +- src/utils/Util.ts | 7 +- 3 files changed, 238 insertions(+), 12 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 6aeb252..7a95a89 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'events'; -import { Client, Collection, Snowflake, Collector, Message } from 'discord.js'; +import { Client, Collection, Snowflake, Collector, Message, VoiceChannel } from 'discord.js'; import { PlayerOptions, QueueFilters } from './types/types'; import Util from './utils/Util'; import AudioFilters from './utils/AudioFilters'; @@ -13,6 +13,7 @@ import ytdl from 'discord-ytdl-core'; import spotify from 'spotify-url-info'; // @ts-ignore import { Client as SoundCloudClient } from 'soundcloud-scraper'; +import YouTube from 'youtube-sr'; const SoundCloud = new SoundCloudClient(); @@ -99,18 +100,172 @@ export class Player extends EventEmitter { if (spotifyData) { tracks = await Util.ytSearch(`${spotifyData.artist} - ${spotifyData.title}`, { user: message.author, - player: this + player: this, + limit: 1 }); } } } break; + + // todo: make spotify playlist/album load faster + case 'spotify_album': + case 'spotify_playlist': { + this.emit(PlayerEvents.PLAYLIST_PARSE_START, null, message); + const playlist = await spotify.getData(query); + if (!playlist) return void this.emit(PlayerEvents.NO_RESULTS, message, query); + + // tslint:disable:no-shadowed-variable + const tracks = []; + + for (const item of playlist.tracks.items) { + const sq = + queryType === 'spotify_album' + ? `${item.artists[0].name} - ${item.name}` + : `${item.track.artists[0].name} - ${item.name}`; + const data = await Util.ytSearch(sq, { + limit: 1, + player: this, + user: message.author, + pl: true + }); + + if (data[0]) tracks.push(data[0]); + } + + if (!tracks.length) return void this.emit(PlayerEvents.NO_RESULTS, message, query); + + const pl = { + ...playlist, + tracks, + duration: tracks.reduce((a, c) => a + c.durationMS, 0), + thumbnail: playlist.images[0]?.url ?? tracks[0].thumbnail + }; + + this.emit(PlayerEvents.PLAYLIST_PARSE_END, pl, message); + + if (this.isPlaying(message)) { + const queue = this._addTracksToQueue(message, tracks); + this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl); + } else { + const track = tracks.shift(); + const queue = (await this._createQueue(message, track).catch( + (e) => void this.emit(PlayerEvents.ERROR, e, message) + )) as Queue; + this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); + this._addTracksToQueue(message, tracks); + } + + return; + } + case 'youtube_playlist': { + this.emit(PlayerEvents.PLAYLIST_PARSE_START, null, message); + const playlist = await YouTube.getPlaylist(query); + if (!playlist) return void this.emit(PlayerEvents.NO_RESULTS, message, query); + + // @ts-ignore + playlist.videos = playlist.videos.map( + (data) => + new Track(this, { + title: data.title, + url: data.url, + duration: Util.durationString(Util.parseMS(data.duration)), + description: data.description, + thumbnail: data.thumbnail?.displayThumbnailURL(), + views: data.views, + author: data.channel.name, + requestedBy: message.author, + fromPlaylist: true, + source: 'youtube' + }) + ); + + // @ts-ignore + playlist.duration = playlist.videos.reduce((a, c) => a + c.durationMS, 0); + + // @ts-ignore + playlist.thumbnail = playlist.thumbnail?.url ?? playlist.videos[0].thumbnail; + + // @ts-ignore + playlist.requestedBy = message.author; + + this.emit(PlayerEvents.PLAYLIST_PARSE_END, playlist, message); + + // @ts-ignore + const tracks = playlist.videos as Track[]; + + if (this.isPlaying(message)) { + const queue = this._addTracksToQueue(message, tracks); + this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist); + } else { + const track = tracks.shift(); + const queue = (await this._createQueue(message, track).catch( + (e) => void this.emit(PlayerEvents.ERROR, e, message) + )) as Queue; + this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); + this._addTracksToQueue(message, tracks); + } + } + case 'soundcloud_playlist': { + this.emit(PlayerEvents.PLAYLIST_PARSE_START, null, message); + + const data = await SoundCloud.getPlaylist(query).catch(() => {}); + if (!data) return void this.emit(PlayerEvents.NO_RESULTS, message, query); + + const res = { + id: data.id, + title: data.title, + tracks: [] as Track[], + author: data.author, + duration: 0, + thumbnail: data.thumbnail, + requestedBy: message.author + }; + + for (const song of data.tracks) { + const r = new Track(this, { + title: song.title, + url: song.url, + duration: Util.durationString(Util.parseMS(song.duration / 1000)), + description: song.description, + thumbnail: song.thumbnail ?? 'https://soundcloud.com/pwa-icon-192.png', + views: song.playCount ?? 0, + author: song.author ?? data.author, + requestedBy: message.author, + fromPlaylist: true, + source: 'soundcloud', + engine: song + }); + + res.tracks.push(r); + } + + if (!res.tracks.length) + return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.PARSE_ERROR, message); + res.duration = res.tracks.reduce((a, c) => a + c.durationMS, 0); + + this.emit(PlayerEvents.PLAYLIST_PARSE_END, res, message); + + if (this.isPlaying(message)) { + const queue = this._addTracksToQueue(message, res.tracks); + this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, res); + } else { + const track = res.tracks.shift(); + const queue = (await this._createQueue(message, track).catch( + (e) => void this.emit(PlayerEvents.ERROR, e, message) + )) as Queue; + this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); + this._addTracksToQueue(message, res.tracks); + } + + return; + } default: tracks = await Util.ytSearch(query, { user: message.author, player: this }); } - if (tracks.length < 1) return this.emit(PlayerEvents.NO_RESULTS, message, query); - if (firstResult) return resolve(tracks[0]); + 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); @@ -140,7 +295,7 @@ export class Player extends EventEmitter { } }); - collector.on('end', (collected, reason) => { + collector.on('end', (_, reason) => { if (reason === 'time') { this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); } @@ -232,6 +387,67 @@ export class Player extends EventEmitter { }); } + setPosition(message: Message, time: number): Promise { + return new Promise((resolve) => { + const queue = this.queues.find((g) => g.guildID === message.guild.id); + if (!queue) return this.emit('error', 'NotPlaying', message); + + if (typeof time !== 'number' && !isNaN(time)) time = parseInt(time); + if (queue.playing.durationMS >= time) return this.skip(message); + if ( + queue.voiceConnection.dispatcher.streamTime === time || + queue.voiceConnection.dispatcher.streamTime + queue.additionalStreamTime === time + ) + return resolve(); + if (time < 0) this._playStream(queue, false).then(() => resolve()); + + this._playStream(queue, false, time).then(() => resolve()); + }); + } + + seek(message: Message, time: number) { + return this.setPosition(message, time); + } + + skip(message: Message): boolean { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); + return false; + } + + queue.voiceConnection.dispatcher.end(); + queue.lastSkipped = true; + + return true; + } + + moveTo(message: Message, channel?: VoiceChannel) { + if (!channel || channel.type !== 'voice') return; + const queue = this.queues.find((g) => g.guildID === message.guild.id); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); + return false; + } + if (queue.voiceConnection.channel.id === channel.id) return; + + queue.voiceConnection.dispatcher.pause(); + channel + .join() + .then(() => queue.voiceConnection.dispatcher.resume()) + .catch(() => this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.UNABLE_TO_JOIN, message)); + + return true; + } + private _addTrackToQueue(message: Message, track: Track) { const queue = this.getQueue(message); if (!queue) @@ -246,11 +462,21 @@ export class Player extends EventEmitter { return queue; } + private _addTracksToQueue(message: Message, tracks: Track[]) { + const queue = this.getQueue(message); + if (!queue) + throw new PlayerError( + 'Cannot add tracks to queue because no song is currently being played on the server.' + ); + queue.tracks.push(...tracks); + return queue; + } + private _createQueue(message: Message, track: Track): Promise { return new Promise((resolve) => { const channel = message.member.voice ? message.member.voice.channel : null; if (!channel) - return this.emit( + return void this.emit( PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_CONNECTED, message, @@ -333,8 +559,6 @@ export class Player extends EventEmitter { const encoderArgsFilters: string[] = []; Object.keys(queue.filters).forEach((filterName) => { - if (this.options.enableLive && ["nightcore", "vaporwave", "reverse"].includes(filterName)) return; - // @ts-ignore if (queue.filters[filterName]) { // @ts-ignore diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index bc91621..7b075ed 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -23,5 +23,6 @@ export const PlayerErrorEventCodes = { UNABLE_TO_JOIN: 'UnableToJoin', NOT_PLAYING: 'NotPlaying', PARSE_ERROR: 'ParseError', - VIDEO_UNAVAILABLE: 'VideoUnavailable' + VIDEO_UNAVAILABLE: 'VideoUnavailable', + MUSIC_STARTING: 'MusicStarting' }; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 87517b8..f1f4d21 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -54,8 +54,8 @@ export class Util { if (spotifySongRegex.test(query)) return 'spotify_song'; if (spotifyAlbumRegex.test(query)) return 'spotify_album'; if (spotifyPlaylistRegex.test(query)) return 'spotify_playlist'; - if (YouTube.validate(query, 'VIDEO')) return 'youtube_video'; if (YouTube.validate(query, 'PLAYLIST')) return 'youtube_playlist'; + if (YouTube.validate(query, 'VIDEO')) return 'youtube_video'; if (vimeoRegex.test(query)) return 'vimeo'; if (facebookRegex.test(query)) return 'facebook'; if (reverbnationRegex.test(query)) return 'reverbnation'; @@ -102,7 +102,8 @@ export class Util { return new Promise(async (resolve) => { await YouTube.search(query, { type: 'video', - safeSearch: Boolean(options?.player.options.useSafeSearch) + safeSearch: Boolean(options?.player.options.useSafeSearch), + limit: options.limit ?? 10 }) .then((results) => { resolve( @@ -117,7 +118,7 @@ export class Util { duration: r.durationFormatted, views: r.views, requestedBy: options?.user, - fromPlaylist: false, + fromPlaylist: Boolean(options?.pl), source: 'youtube' }) ) From 647535b5de6fc16c0e2cb8512f56aff0657583ea Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 7 Apr 2021 20:10:45 +0545 Subject: [PATCH 025/131] check repl.it --- src/Player.ts | 6 +++++- src/utils/Util.ts | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index 7a95a89..340bd3e 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -602,7 +602,11 @@ export class Player extends EventEmitter { queue.stream = newStream; queue.voiceConnection.play(newStream, { type: 'opus', - bitrate: 'auto' + bitrate: 'auto', + + // disable inline volume for replit.com, leave it as it is for other platforms + // thx Amish Shah for this info :D + volume: Util.isRepl() ? false : undefined }); if (seekTime) { diff --git a/src/utils/Util.ts b/src/utils/Util.ts index f1f4d21..a5ce8f3 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -127,6 +127,24 @@ export class Util { .catch(() => resolve([])); }); } + + static isRepl() { + if ('DP_REPL_NOCHECK' in process.env) return false; + + const REPL_IT_PROPS = [ + 'REPL_SLUG', + 'REPL_OWNER', + 'REPL_IMAGE', + 'REPL_PUBKEYS', + 'REPL_ID', + 'REPL_LANGUAGE', + 'REPLIT_DB_URL' + ]; + + for (const prop of REPL_IT_PROPS) if (prop in process.env) return true; + + return false; + } } export default Util; From 72af2eb46b21c1f7b65e7a01983813ad1ff68b42 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Thu, 8 Apr 2021 17:55:23 +0545 Subject: [PATCH 026/131] remove comment --- src/Player.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 340bd3e..69e7d83 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -603,9 +603,6 @@ export class Player extends EventEmitter { queue.voiceConnection.play(newStream, { type: 'opus', bitrate: 'auto', - - // disable inline volume for replit.com, leave it as it is for other platforms - // thx Amish Shah for this info :D volume: Util.isRepl() ? false : undefined }); From 7d19bae7272d68d4767186ad65d1574b6ec6ebef Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Thu, 8 Apr 2021 18:48:04 +0545 Subject: [PATCH 027/131] custom extractors support --- src/Player.ts | 59 ++++++++++++++++++++++++++++++-- src/Structures/ExtractorModel.ts | 44 ++++++++++++++++++++++++ src/types/types.ts | 13 +++++++ 3 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/Structures/ExtractorModel.ts diff --git a/src/Player.ts b/src/Player.ts index 69e7d83..ad922d4 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -8,6 +8,7 @@ import { Track } from './Structures/Track'; import { PlayerErrorEventCodes, PlayerEvents } from './utils/Constants'; import PlayerError from './utils/PlayerError'; import ytdl from 'discord-ytdl-core'; +import { ExtractorModel } from "./Structures/ExtractorModel"; // @ts-ignore import spotify from 'spotify-url-info'; @@ -24,6 +25,7 @@ export class Player extends EventEmitter { public queues: Collection; private _resultsCollectors: Collection>; private _cooldownsTimeout: Collection; + public Extractors = new Collection(); constructor(client: Client, options?: PlayerOptions) { super(); @@ -62,6 +64,35 @@ export class Player extends EventEmitter { return AudioFilters; } + /** + * Define custom extractor in this player + * @param extractorName The extractor name + * @param extractor The extractor itself + */ + use(extractorName: string, extractor: any) { + if (!extractorName) throw new PlayerError("Missing extractor name!", "PlayerExtractorError"); + + const methods = ["validate", "getInfo"]; + + for (const method of methods) { + if (typeof extractor[method] !== "function") throw new PlayerError("Invalid extractor supplied!", "PlayerExtractorError"); + } + + this.Extractors.set(extractorName, new ExtractorModel(extractorName, extractor)); + + return Player; + } + + /** + * Remove existing extractor from this player + * @param extractorName The extractor name + */ + unuse(extractorName: string) { + if (!extractorName) throw new PlayerError("Missing extractor name!", "PlayerExtractorError"); + + return this.Extractors.delete(extractorName); + } + private _searchTracks(message: Message, query: string, firstResult?: boolean): Promise { return new Promise(async (resolve) => { let tracks: Track[] = []; @@ -83,7 +114,7 @@ export class Player extends EventEmitter { requestedBy: message.author, fromPlaylist: false, source: 'soundcloud', - engine: data + engine: data.engine }); tracks.push(track); @@ -342,7 +373,31 @@ export class Player extends EventEmitter { source: 'youtube' }); } else { - track = await this._searchTracks(message, query, firstResult); + for (const [_, extractor] of this.Extractors) { + if (extractor.validate(query)) { + const data = await extractor.handle(query); + if (data) { + console.log(data) + track = new Track(this, { + title: data.title, + description: data.description, + duration: Util.durationString(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); } } diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts new file mode 100644 index 0000000..f0c004b --- /dev/null +++ b/src/Structures/ExtractorModel.ts @@ -0,0 +1,44 @@ +import { ExtractorModelData } from "../types/types"; + +class ExtractorModel { + name: string; + private _raw: any; + + constructor(extractorName: string, data: any) { + this.name = extractorName; + + Object.defineProperty(this, "_raw", { value: data, configurable: false, writable: false, enumerable: false }); + } + + async handle(query: string) { + 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 + } as ExtractorModelData; + } + + validate(query: string) { + return Boolean(this._raw.validate(query)); + } + + get version() { + return this._raw.version ?? "0.0.0"; + } + + get important() { + return Boolean(this._raw.important); + } + +} + +export default ExtractorModel; +export { ExtractorModel }; \ No newline at end of file diff --git a/src/types/types.ts b/src/types/types.ts index 192c826..60c379f 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,5 +1,6 @@ import { downloadOptions } from 'ytdl-core'; import { User } from 'discord.js'; +import { Readable, Duplex } from "stream"; export interface PlayerOptions { leaveOnEnd?: boolean; @@ -75,3 +76,15 @@ export type QueryType = | '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; +} \ No newline at end of file From 7a2a0f2820110a4d1a9c8a8c3965d701e17cd1eb Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Thu, 8 Apr 2021 18:50:23 +0545 Subject: [PATCH 028/131] readmeDOTmd --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d39934d..e48636d 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ $ npm install --save @discordjs/opus - Beginner friendly 😱 - Audio filters 🎸 - Lightweight 🛬 +- Custom extractors 🌌 # License MIT License From 7e9a59981fc43d6c22b2b640afd2541d8a967f35 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Thu, 8 Apr 2021 20:27:08 +0545 Subject: [PATCH 029/131] apply some extractors --- package.json | 1 + src/Player.ts | 17 +- src/Structures/ExtractorModel.ts | 9 +- src/types/types.ts | 4 +- yarn.lock | 625 ++++++++++++++++++++++++++++++- 5 files changed, 638 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index cf4f549..111880c 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ }, "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { + "@discord-player/extractor": "^1.0.4", "discord-ytdl-core": "^5.0.2", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", diff --git a/src/Player.ts b/src/Player.ts index ad922d4..96c7df5 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -8,7 +8,7 @@ import { Track } from './Structures/Track'; import { PlayerErrorEventCodes, PlayerEvents } from './utils/Constants'; import PlayerError from './utils/PlayerError'; import ytdl from 'discord-ytdl-core'; -import { ExtractorModel } from "./Structures/ExtractorModel"; +import { ExtractorModel } from './Structures/ExtractorModel'; // @ts-ignore import spotify from 'spotify-url-info'; @@ -16,6 +16,9 @@ import spotify from 'spotify-url-info'; import { Client as SoundCloudClient } from 'soundcloud-scraper'; import YouTube from 'youtube-sr'; +// @ts-ignore +import * as DP_EXTRACTORS from '@discord-player/extractor'; + const SoundCloud = new SoundCloudClient(); export class Player extends EventEmitter { @@ -58,6 +61,8 @@ export class Player extends EventEmitter { this._resultsCollectors = new Collection(); this._cooldownsTimeout = new Collection(); + + ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => this.use(ext, DP_EXTRACTORS[ext])); } static get AudioFilters() { @@ -70,12 +75,13 @@ export class Player extends EventEmitter { * @param extractor The extractor itself */ use(extractorName: string, extractor: any) { - if (!extractorName) throw new PlayerError("Missing extractor name!", "PlayerExtractorError"); + if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); - const methods = ["validate", "getInfo"]; + const methods = ['validate', 'getInfo']; for (const method of methods) { - if (typeof extractor[method] !== "function") throw new PlayerError("Invalid extractor supplied!", "PlayerExtractorError"); + if (typeof extractor[method] !== 'function') + throw new PlayerError('Invalid extractor supplied!', 'PlayerExtractorError'); } this.Extractors.set(extractorName, new ExtractorModel(extractorName, extractor)); @@ -88,7 +94,7 @@ export class Player extends EventEmitter { * @param extractorName The extractor name */ unuse(extractorName: string) { - if (!extractorName) throw new PlayerError("Missing extractor name!", "PlayerExtractorError"); + if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); return this.Extractors.delete(extractorName); } @@ -377,7 +383,6 @@ export class Player extends EventEmitter { if (extractor.validate(query)) { const data = await extractor.handle(query); if (data) { - console.log(data) track = new Track(this, { title: data.title, description: data.description, diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index f0c004b..9242a5f 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -1,4 +1,4 @@ -import { ExtractorModelData } from "../types/types"; +import { ExtractorModelData } from '../types/types'; class ExtractorModel { name: string; @@ -7,7 +7,7 @@ class ExtractorModel { constructor(extractorName: string, data: any) { this.name = extractorName; - Object.defineProperty(this, "_raw", { value: data, configurable: false, writable: false, enumerable: false }); + Object.defineProperty(this, '_raw', { value: data, configurable: false, writable: false, enumerable: false }); } async handle(query: string) { @@ -31,14 +31,13 @@ class ExtractorModel { } get version() { - return this._raw.version ?? "0.0.0"; + return this._raw.version ?? '0.0.0'; } get important() { return Boolean(this._raw.important); } - } export default ExtractorModel; -export { ExtractorModel }; \ No newline at end of file +export { ExtractorModel }; diff --git a/src/types/types.ts b/src/types/types.ts index 60c379f..5a6d21c 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,6 +1,6 @@ import { downloadOptions } from 'ytdl-core'; import { User } from 'discord.js'; -import { Readable, Duplex } from "stream"; +import { Readable, Duplex } from 'stream'; export interface PlayerOptions { leaveOnEnd?: boolean; @@ -87,4 +87,4 @@ export interface ExtractorModelData { description: string; url: string; version?: string; -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index e4eb2ac..5335074 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@discord-player/extractor@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-1.0.4.tgz#e593fed1749cb859554e79967b88937d9e08f4ec" + integrity sha512-zzCK1GQ7szpZD6fmf9LMxrlLt6r+h0gpjo/yMXmmT+xmLpfayZbT36sfEZV8WkMnN7vhr9z6qzDDDC1v7BBbDg== + dependencies: + jsdom "^16.5.2" + node-fetch "^2.6.1" + reverbnation-scraper "^2.0.0" + "@discordjs/collection@^0.1.6": version "0.1.6" resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c" @@ -77,6 +86,11 @@ dependencies: "@types/node" "*" +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -89,6 +103,29 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" + integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -96,6 +133,16 @@ agent-base@6: dependencies: debug "4" +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -133,16 +180,45 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -156,11 +232,21 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chalk@^2.0.0, chalk@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -216,7 +302,7 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -combined-stream@^1.0.8: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -238,7 +324,7 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -core-util-is@~1.0.0: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -266,6 +352,39 @@ css-what@^4.0.0: resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== +cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + debug@4: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" @@ -273,6 +392,16 @@ debug@4: dependencies: ms "2.1.2" +decimal.js@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" + integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -328,6 +457,13 @@ domelementtype@^2.0.1, domelementtype@^2.1.0, domelementtype@^2.2.0: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + domhandler@^4.0.0, domhandler@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43" @@ -344,6 +480,14 @@ domutils@^2.4.3, domutils@^2.4.4: domelementtype "^2.2.0" domhandler "^4.1.0" +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" @@ -359,16 +503,82 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -esprima@^4.0.0: +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -400,6 +610,13 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + glob@^7.1.1, glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -412,6 +629,19 @@ glob@^7.1.1, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -434,6 +664,13 @@ himalaya@^1.1.0: resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a" integrity sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw== +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + htmlparser2@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.1.tgz#422521231ef6d42e56bd411da8ba40aa36e91446" @@ -453,6 +690,22 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -485,6 +738,16 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-potential-custom-element-name@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -495,6 +758,11 @@ iso8601-duration@^1.2.0: resolved "https://registry.yarnpkg.com/iso8601-duration/-/iso8601-duration-1.3.0.tgz#29d7b69e0574e4acdee50c5e5e09adab4137ba5a" integrity sha512-K4CiUBzo3YeWk76FuET/dQPH03WE04R94feo5TSKQCXpoXQt9E4yx2CnY737QZnSAI3PI4WlKo/zfqizGx52QQ== +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -508,6 +776,81 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^16.5.2: + version "16.5.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.2.tgz#583fac89a0aea31dbf6237e7e4bedccd9beab472" + integrity sha512-JxNtPt9C1ut85boCbJmffaQ06NBnzkQY/MWO3YxPW8IWS38A26z+B1oBvA9LwKrytewdfymnhi4UNH3/RAgZrg== + dependencies: + abab "^2.0.5" + acorn "^8.1.0" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + html-encoding-sniffer "^2.0.1" + is-potential-custom-element-name "^1.0.0" + nwsapi "^2.2.0" + parse5 "6.0.1" + request "^2.88.2" + request-promise-native "^1.0.9" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.4" + xml-name-validator "^3.0.0" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lodash@^4.17.19, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -535,7 +878,7 @@ mime-db@1.47.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== -mime-types@^2.1.12: +mime-types@^2.1.12, mime-types@~2.1.19: version "2.1.30" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== @@ -630,6 +973,16 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -642,6 +995,18 @@ once@^1.3.0: dependencies: wrappy "1" +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + parse5-htmlparser2-tree-adapter@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" @@ -649,7 +1014,7 @@ parse5-htmlparser2-tree-adapter@^6.0.0: dependencies: parse5 "^6.0.1" -parse5@^6.0.0, parse5@^6.0.1: +parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== @@ -664,6 +1029,16 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + prettier@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" @@ -679,6 +1054,21 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +psl@^1.1.28, psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + readable-stream@^2.0.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -692,6 +1082,48 @@ readable-stream@^2.0.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +request-promise-core@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" + integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== + dependencies: + lodash "^4.17.19" + +request-promise-native@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" + integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== + dependencies: + request-promise-core "1.1.4" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + resolve@^1.3.2: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" @@ -700,6 +1132,13 @@ resolve@^1.3.2: is-core-module "^2.2.0" path-parse "^1.0.6" +reverbnation-scraper@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/reverbnation-scraper/-/reverbnation-scraper-2.0.0.tgz#c17539aba218cc29033a63e732ba3e4953cb5bd5" + integrity sha512-t1Mew5QC9QEVEry5DXyagvci2O+TgXTGoMHbNoW5NRz6LTOzK/DLHUpnrQwloX8CVX5z1a802vwHM3YgUVOvKg== + dependencies: + node-fetch "^2.6.0" + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -707,16 +1146,33 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +safe-buffer@^5.0.1, safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + sax@^1.1.3, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + semver@^5.3.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -766,6 +1222,11 @@ soundcloud-scraper@^4.0.3: m3u8stream "^0.8.0" node-fetch "^2.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== + spotify-uri@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/spotify-uri/-/spotify-uri-2.2.0.tgz#8db641615cf6e122284874287fe39e89595922df" @@ -785,6 +1246,26 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -830,6 +1311,11 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" @@ -842,6 +1328,30 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" +tough-cookie@^2.3.3, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tr46@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== + dependencies: + punycode "^2.1.1" + tslib@^1.13.0, tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -878,21 +1388,111 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + typescript@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + +webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" + integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== + dependencies: + lodash "^4.7.0" + tr46 "^2.0.2" + webidl-conversions "^6.1.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -900,6 +1500,11 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -910,6 +1515,16 @@ ws@^7.4.4: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" From f7779be50abcb1b135ea4361c12634233359bbd0 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Thu, 8 Apr 2021 20:28:33 +0545 Subject: [PATCH 030/131] return this --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index 96c7df5..318bb96 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -86,7 +86,7 @@ export class Player extends EventEmitter { this.Extractors.set(extractorName, new ExtractorModel(extractorName, extractor)); - return Player; + return this; } /** From 19b5818d59b06aa43887f8aa561457ddfa9c5b35 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Thu, 8 Apr 2021 20:30:22 +0545 Subject: [PATCH 031/131] bump deps --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 111880c..dc0fc0c 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "discord-ytdl-core": "^5.0.2", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", - "youtube-sr": "^4.0.3", + "youtube-sr": "^4.0.4", "ytdl-core": "^4.5.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 5335074..88cc8f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1530,10 +1530,10 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -youtube-sr@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/youtube-sr/-/youtube-sr-4.0.3.tgz#f9ac3dc0f730770d52f9d14efbd645db8413043a" - integrity sha512-BijdoA3ahTfqpl8IYszjFYZA+oRNJekt/5qs8g7bJ5N36hv5viA4iyMX2PolOorh+K5Wqra1/ReqEp1WuGjkQQ== +youtube-sr@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/youtube-sr/-/youtube-sr-4.0.4.tgz#48369b0cb1c53bd84c366a5420bb8f35b1db2329" + integrity sha512-Wf6YlANcCjAweY2MQuqJqusmMcGzaSDWE6ZTD8vifb9i9oFyKQpWuV58fnebJCFJE8G8pTLidmj5aRV7x384EQ== dependencies: node-fetch "^2.6.1" simple-youtube-api "^5.2.1" From 8c5014630083b989d80fe87bc7c8abdea40336a8 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 14:49:30 +0545 Subject: [PATCH 032/131] export ExtractorModel --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index 1f75632..70f10f1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ 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'; From 249a7e71acda5b6f23aae721d6ba55ac4c8f13de Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 15:49:36 +0545 Subject: [PATCH 033/131] add missing methods --- src/Player.ts | 288 +++++++++++++++++++++++++++++++++++++++++++-- src/types/types.ts | 6 + src/utils/Util.ts | 17 +++ 3 files changed, 299 insertions(+), 12 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 318bb96..0878b85 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; -import { Client, Collection, Snowflake, Collector, Message, VoiceChannel } from 'discord.js'; -import { PlayerOptions, QueueFilters } from './types/types'; +import { Client, Collection, Snowflake, Collector, Message, VoiceChannel, VoiceState } from 'discord.js'; +import { PlayerOptions, PlayerProgressbarOptions, QueueFilters } from './types/types'; import Util from './utils/Util'; import AudioFilters from './utils/AudioFilters'; import { Queue } from './Structures/Queue'; @@ -25,9 +25,9 @@ export class Player extends EventEmitter { public client!: Client; public options: PlayerOptions; public filters: typeof AudioFilters; - public queues: Collection; - private _resultsCollectors: Collection>; - private _cooldownsTimeout: Collection; + public queues = new Collection(); + private _resultsCollectors = new Collection>(); + private _cooldownsTimeout = new Collection(); public Extractors = new Collection(); constructor(client: Client, options?: PlayerOptions) { @@ -54,13 +54,7 @@ export class Player extends EventEmitter { */ this.filters = AudioFilters; - /** - * Player queues - */ - this.queues = new Collection(); - - this._resultsCollectors = new Collection(); - this._cooldownsTimeout = new Collection(); + this.client.on('voiceStateUpdate', (o, n) => this._handleVoiceStateUpdate(o, n)); ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => this.use(ext, DP_EXTRACTORS[ext])); } @@ -508,6 +502,276 @@ export class Player extends EventEmitter { return true; } + pause(message: Message) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); + return false; + } + + queue.voiceConnection.dispatcher.pause(); + queue.paused = true; + return true; + } + + resume(message: Message) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); + return false; + } + + queue.voiceConnection.dispatcher.resume(); + queue.paused = false; + return true; + } + + stop(message: Message) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); + return false; + } + + queue.stopped = true; + queue.tracks = []; + if (queue.stream) queue.stream.destroy(); + queue.voiceConnection.dispatcher.end(); + if (this.options.leaveOnStop) queue.voiceConnection.channel.leave(); + this.queues.delete(message.guild.id); + return true; + } + + setVolume(message: Message, percent: number) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); + return false; + } + + queue.volume = percent; + queue.voiceConnection.dispatcher.setVolumeLogarithmic(queue.calculatedVolume / 200); + + return true; + } + + clearQueue(message: Message) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + + queue.tracks = queue.playing ? [queue.playing] : []; + + return true; + } + + back(message: Message) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return false; + } + if (!queue.voiceConnection || !queue.voiceConnection.dispatcher) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.MUSIC_STARTING, message); + return false; + } + + queue.tracks.splice(1, 0, queue.previousTracks.shift()); + queue.voiceConnection.dispatcher.end(); + queue.lastSkipped = true; + + return true; + } + + setRepeatMode(message: Message, enabled: boolean) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return; + } + + queue.repeatMode = Boolean(enabled); + + return queue.repeatMode; + } + + setLoopMode(message: Message, enabled: boolean) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return; + } + + queue.loopMode = Boolean(enabled); + + return queue.loopMode; + } + + nowPlaying(message: Message) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return; + } + + return queue.tracks[0]; + } + + shuffle(message: Message) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return; + } + + const currentTrack = queue.tracks.shift(); + + for (let i = queue.tracks.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [queue.tracks[i], queue.tracks[j]] = [queue.tracks[j], queue.tracks[i]]; + } + + queue.tracks.unshift(currentTrack); + + return queue; + } + + remove(message: Message, track: Track | number) { + const queue = this.getQueue(message); + if (!queue) { + this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + return; + } + + let trackFound: Track = null; + if (typeof track === 'number') { + trackFound = queue.tracks[track]; + if (trackFound) { + queue.tracks = queue.tracks.filter((t) => t !== trackFound); + } + } else { + trackFound = queue.tracks.find((s) => s === track); + if (trackFound) { + queue.tracks = queue.tracks.filter((s) => s !== trackFound); + } + } + + return trackFound; + } + + getTimeCode(message: Message, queueTime?: boolean) { + const queue = this.getQueue(message); + if (!queue) return; + + const previousTracksTime = + queue.previousTracks.length > 0 ? queue.previousTracks.reduce((p, c) => p + c.durationMS, 0) : 0; + const currentStreamTime = queueTime ? previousTracksTime + queue.currentStreamTime : queue.currentStreamTime; + const totalTracksTime = queue.totalTime; + const totalTime = queueTime ? previousTracksTime + totalTracksTime : queue.playing.durationMS; + + const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); + const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); + + return { + current: currentTimecode, + end: endTimecode + }; + } + + createProgressBar(message: Message, options?: PlayerProgressbarOptions) { + const queue = this.getQueue(message); + if (!queue) return; + + const previousTracksTime = + queue.previousTracks.length > 0 ? queue.previousTracks.reduce((p, c) => p + c.durationMS, 0) : 0; + const currentStreamTime = options?.queue + ? previousTracksTime + queue.currentStreamTime + : queue.currentStreamTime; + const totalTracksTime = queue.totalTime; + const totalTime = options?.queue ? previousTracksTime + totalTracksTime : queue.playing.durationMS; + const length = + typeof options?.length === 'number' + ? options?.length <= 0 || options?.length === Infinity + ? 15 + : options?.length + : options?.length; + + const index = Math.round((currentStreamTime / totalTime) * length); + const indicator = '🔘'; + const line = '▬'; + + if (index >= 1 && index <= length) { + const bar = line.repeat(length - 1).split(''); + bar.splice(index, 0, indicator); + if (Boolean(options?.timecodes)) { + const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); + const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); + return `${currentTimecode} ┃ ${bar.join('')} ┃ ${endTimecode}`; + } else { + return `${bar.join('')}`; + } + } else { + if (Boolean(options?.timecodes)) { + const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); + const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); + return `${currentTimecode} ┃ ${indicator}${line.repeat(length)} ┃ ${endTimecode}`; + } else { + return `${indicator}${line.repeat(length)}`; + } + } + } + + _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { + const queue = this.queues.find((g) => g.guildID === oldState.guild.id); + if (!queue) return; + + if (newState.member.id === this.client.user.id && !newState.channelID) { + queue.stream.destroy(); + this.queues.delete(newState.guild.id); + this.emit(PlayerEvents.BOT_DISCONNECT, queue.firstMessage); + } + + if (!queue.voiceConnection || !queue.voiceConnection.channel) return; + if (!this.options.leaveOnEmpty) return; + + if (!oldState.channelID || newState.channelID) { + const emptyTimeout = this._cooldownsTimeout.get(`empty_${oldState.guild.id}`); + const channelEmpty = Util.isVoiceEmpty(queue.voiceConnection.channel); + if (!channelEmpty && emptyTimeout) { + clearTimeout(emptyTimeout); + this._cooldownsTimeout.delete(`empty_${oldState.guild.id}`); + } + } else { + if (!Util.isVoiceEmpty(queue.voiceConnection.channel)) return; + const timeout = setTimeout(() => { + if (!Util.isVoiceEmpty(queue.voiceConnection.channel)) return; + if (!this.queues.has(queue.guildID)) return; + queue.voiceConnection.channel.leave(); + this.queues.delete(queue.guildID); + this.emit(PlayerEvents.CHANNEL_EMPTY, queue.firstMessage, queue); + }, this.options.leaveOnEmptyCooldown || 0); + this._cooldownsTimeout.set(`empty_${oldState.guild.id}`, timeout); + } + } + private _addTrackToQueue(message: Message, track: Track) { const queue = this.getQueue(message); if (!queue) diff --git a/src/types/types.ts b/src/types/types.ts index 5a6d21c..e626c96 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -88,3 +88,9 @@ export interface ExtractorModelData { url: string; version?: string; } + +export interface PlayerProgressbarOptions { + timecodes?: boolean; + queue?: boolean; + length?: number; +} diff --git a/src/utils/Util.ts b/src/utils/Util.ts index a5ce8f3..2c6e6ec 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -4,6 +4,7 @@ import YouTube from 'youtube-sr'; import { Track } from '../Structures/Track'; // @ts-ignore import { validateURL as SoundcloudValidateURL } from 'soundcloud-scraper'; +import { VoiceChannel } from 'discord.js'; const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/; const spotifyPlaylistRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/; @@ -145,6 +146,22 @@ export class Util { return false; } + + static isVoiceEmpty(channel: VoiceChannel) { + return channel.members.filter((member) => !member.user.bot).size === 0; + } + + static buildTimeCode(data: any) { + const items = Object.keys(data); + const required = ['days', 'hours', 'minutes', 'seconds']; + + const parsed = items.filter((x) => required.includes(x)).map((m) => (data[m] > 0 ? data[m] : '')); + const final = parsed + .filter((x) => !!x) + .map((x) => x.toString().padStart(2, '0')) + .join(':'); + return final.length <= 3 ? `0:${final.padStart(2, '0') || 0}` : final; + } } export default Util; From cf1def610451442b1a9e7388866c38a6659f34fb Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 15:58:07 +0545 Subject: [PATCH 034/131] fix progressbar --- src/Player.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 0878b85..88950b5 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -732,9 +732,9 @@ export class Player extends EventEmitter { if (Boolean(options?.timecodes)) { const currentTimecode = Util.buildTimeCode(Util.parseMS(currentStreamTime)); const endTimecode = Util.buildTimeCode(Util.parseMS(totalTime)); - return `${currentTimecode} ┃ ${indicator}${line.repeat(length)} ┃ ${endTimecode}`; + return `${currentTimecode} ┃ ${indicator}${line.repeat(length - 1)} ┃ ${endTimecode}`; } else { - return `${indicator}${line.repeat(length)}`; + return `${indicator}${line.repeat(length - 1)}`; } } } From 4918c83ac9297c12d09141080947e1ced561cf6d Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 16:00:38 +0545 Subject: [PATCH 035/131] void some stuff --- src/Player.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 88950b5..18c955d 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -54,9 +54,9 @@ export class Player extends EventEmitter { */ this.filters = AudioFilters; - this.client.on('voiceStateUpdate', (o, n) => this._handleVoiceStateUpdate(o, n)); + this.client.on('voiceStateUpdate', (o, n) => void this._handleVoiceStateUpdate(o, n)); - ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => this.use(ext, DP_EXTRACTORS[ext])); + ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => void this.use(ext, DP_EXTRACTORS[ext])); } static get AudioFilters() { From deb60ada5f98b069f1664adcf4e616312cfa0789 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 16:18:01 +0545 Subject: [PATCH 036/131] update dep --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index dc0fc0c..b69a7e7 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ }, "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { - "@discord-player/extractor": "^1.0.4", + "@discord-player/extractor": "^1.0.5", "discord-ytdl-core": "^5.0.2", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index 88cc8f0..2e6fa83 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,10 +23,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@discord-player/extractor@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-1.0.4.tgz#e593fed1749cb859554e79967b88937d9e08f4ec" - integrity sha512-zzCK1GQ7szpZD6fmf9LMxrlLt6r+h0gpjo/yMXmmT+xmLpfayZbT36sfEZV8WkMnN7vhr9z6qzDDDC1v7BBbDg== +"@discord-player/extractor@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-1.0.5.tgz#d38f6d73cec5efe2d7b23c62eb12fac0b54514cf" + integrity sha512-lw7ebA7gazoOMzCbwdBPwGlsh6d2/sp/DMDTeBQa9S6HO4wGP1lIjaEt2ipduYRhBP2vlY3iEs5ryFiZwbLraA== dependencies: jsdom "^16.5.2" node-fetch "^2.6.1" From 4c8f1221adc5c486fb2f74de9676981bc1a782d5 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 18:44:14 +0545 Subject: [PATCH 037/131] some jsdoc --- src/Player.ts | 120 ++++++++++++++++++++++++++++++++++++++-- src/Structures/Queue.ts | 6 +- src/Structures/Track.ts | 6 +- 3 files changed, 122 insertions(+), 10 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 18c955d..29e1ac8 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -22,20 +22,33 @@ import * as DP_EXTRACTORS from '@discord-player/extractor'; const SoundCloud = new SoundCloudClient(); export class Player extends EventEmitter { + /** + * The discord client that instantiated this player + */ public client!: Client; public options: PlayerOptions; public filters: typeof AudioFilters; + + /** + * The collection of queues in this player + */ public queues = new Collection(); private _resultsCollectors = new Collection>(); private _cooldownsTimeout = new Collection(); + + /** + * The extractor model collection + */ public Extractors = new Collection(); + /** + * Creates new Player instance + * @param client The discord.js client + * @param options Player options + */ constructor(client: Client, options?: PlayerOptions) { super(); - /** - * The discord client that instantiated this player - */ Object.defineProperty(this, 'client', { value: client, enumerable: false @@ -334,6 +347,13 @@ export class Player extends EventEmitter { }); } + /** + * Play a song + * @param message The discord.js message object + * @param query Search query, can be `Player.Track` instance + * @param firstResult If it should play the first result + * @example await player.play(message, "never gonna give you up", true) + */ 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'); @@ -411,14 +431,27 @@ export class Player extends EventEmitter { } } + /** + * Checks if this player is playing in a server + * @param message The message object + */ isPlaying(message: Message) { return this.queues.some((g) => g.guildID === message.guild.id); } + /** + * Returns guild queue object + * @param message The message object + */ getQueue(message: Message) { return this.queues.find((g) => g.guildID === message.guild.id); } + /** + * Sets audio filters in this player + * @param message The message object + * @param newFilters Audio filters object + */ setFilters(message: Message, newFilters: QueueFilters): Promise { return new Promise((resolve) => { const queue = this.queues.find((g) => g.guildID === message.guild.id); @@ -441,6 +474,12 @@ export class Player extends EventEmitter { }); } + /** + * Sets track position + * @param message The message object + * @param time Time in ms to set + * @alias seek + */ setPosition(message: Message, time: number): Promise { return new Promise((resolve) => { const queue = this.queues.find((g) => g.guildID === message.guild.id); @@ -459,10 +498,20 @@ export class Player extends EventEmitter { }); } + /** + * Sets track position + * @param message The message object + * @param time Time in ms to set + * @alias setPosition + */ seek(message: Message, time: number) { return this.setPosition(message, time); } + /** + * Skips current track + * @param message The message object + */ skip(message: Message): boolean { const queue = this.getQueue(message); if (!queue) { @@ -480,6 +529,11 @@ export class Player extends EventEmitter { return true; } + /** + * Moves to a new voice channel + * @param message The message object + * @param channel New voice channel to move to + */ moveTo(message: Message, channel?: VoiceChannel) { if (!channel || channel.type !== 'voice') return; const queue = this.queues.find((g) => g.guildID === message.guild.id); @@ -502,6 +556,10 @@ export class Player extends EventEmitter { return true; } + /** + * Pause the playback + * @param message The message object + */ pause(message: Message) { const queue = this.getQueue(message); if (!queue) { @@ -518,6 +576,10 @@ export class Player extends EventEmitter { return true; } + /** + * Resume the playback + * @param message The message object + */ resume(message: Message) { const queue = this.getQueue(message); if (!queue) { @@ -534,6 +596,10 @@ export class Player extends EventEmitter { return true; } + /** + * Stops the player + * @param message The message object + */ stop(message: Message) { const queue = this.getQueue(message); if (!queue) { @@ -554,6 +620,11 @@ export class Player extends EventEmitter { return true; } + /** + * Sets music volume + * @param message The message object + * @param percent The volume percentage/amount to set + */ setVolume(message: Message, percent: number) { const queue = this.getQueue(message); if (!queue) { @@ -571,6 +642,10 @@ export class Player extends EventEmitter { return true; } + /** + * Clears the queue + * @param message The message object + */ clearQueue(message: Message) { const queue = this.getQueue(message); if (!queue) { @@ -583,6 +658,10 @@ export class Player extends EventEmitter { return true; } + /** + * Plays previous track + * @param message The message object + */ back(message: Message) { const queue = this.getQueue(message); if (!queue) { @@ -601,6 +680,11 @@ export class Player extends EventEmitter { return true; } + /** + * Sets repeat mode + * @param message The message object + * @param enabled If it should enable the repeat mode + */ setRepeatMode(message: Message, enabled: boolean) { const queue = this.getQueue(message); if (!queue) { @@ -613,6 +697,11 @@ export class Player extends EventEmitter { return queue.repeatMode; } + /** + * Sets loop mode + * @param message The message object + * @param enabled If it should enable the loop mode + */ setLoopMode(message: Message, enabled: boolean) { const queue = this.getQueue(message); if (!queue) { @@ -625,6 +714,10 @@ export class Player extends EventEmitter { return queue.loopMode; } + /** + * Returns currently playing track + * @param message The message object + */ nowPlaying(message: Message) { const queue = this.getQueue(message); if (!queue) { @@ -635,6 +728,10 @@ export class Player extends EventEmitter { return queue.tracks[0]; } + /** + * Shuffles the queue + * @param message The message object + */ shuffle(message: Message) { const queue = this.getQueue(message); if (!queue) { @@ -654,6 +751,11 @@ export class Player extends EventEmitter { return queue; } + /** + * Removes specified track + * @param message The message object + * @param track The track object/id to remove + */ remove(message: Message, track: Track | number) { const queue = this.getQueue(message); if (!queue) { @@ -677,6 +779,11 @@ export class Player extends EventEmitter { return trackFound; } + /** + * Returns time code of currently playing song + * @param message The message object + * @param queueTime If it should make the time code of the whole queue + */ getTimeCode(message: Message, queueTime?: boolean) { const queue = this.getQueue(message); if (!queue) return; @@ -696,6 +803,11 @@ export class Player extends EventEmitter { }; } + /** + * Creates progressbar + * @param message The message object + * @param options Progressbar options + */ createProgressBar(message: Message, options?: PlayerProgressbarOptions) { const queue = this.getQueue(message); if (!queue) return; @@ -739,7 +851,7 @@ export class Player extends EventEmitter { } } - _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { + private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { const queue = this.queues.find((g) => g.guildID === oldState.guild.id); if (!queue) return; diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 76294ed..17ec077 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -6,6 +6,9 @@ import { Track } from './Track'; import { QueueFilters } from '../types/types'; export class Queue extends EventEmitter { + /** + * The player that instantiated this Queue + */ public player!: Player; public guildID: Snowflake; public voiceConnection?: VoiceConnection; @@ -25,9 +28,6 @@ export class Queue extends EventEmitter { constructor(player: Player, message: Message, filters: typeof AudioFilters) { super(); - /** - * The player that instantiated this Queue - */ Object.defineProperty(this, 'player', { value: player, enumerable: false }); /** diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index c40b41d..70bea6b 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -3,6 +3,9 @@ import { User } from 'discord.js'; import { TrackData } from '../types/types'; export class Track { + /** + * The player that instantiated this Track + */ public player!: Player; public title!: string; public description!: string; @@ -16,9 +19,6 @@ export class Track { public raw!: TrackData; constructor(player: Player, data: TrackData) { - /** - * The player that instantiated this Track - */ Object.defineProperty(this, 'player', { value: player, enumerable: false }); void this._patch(data); From 6ba3f5b12fe7b43eacbc9cda4f2f9b95bd5f4ccd Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 18:46:16 +0545 Subject: [PATCH 038/131] regex --- src/utils/Util.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 2c6e6ec..556e129 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -12,6 +12,7 @@ const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:alb const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/; const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/; const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/; +const attachmentRegex = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/; export class Util { constructor() { @@ -66,10 +67,7 @@ export class Util { } static isURL(str: string) { - const urlRegex = - '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$'; - const url = new RegExp(urlRegex, 'i'); - return str.length < 2083 && url.test(str); + return str.length < 2083 && attachmentRegex.test(str); } static getVimeoID(query: string) { From e617d8acf34e9c042ce46a4c23d4323fd52d0309 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Fri, 9 Apr 2021 19:49:39 +0545 Subject: [PATCH 039/131] some changes --- package.json | 3 ++- src/Player.ts | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index b69a7e7..e1f6cc9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "discord-player", "version": "4.0.0-dev", "description": "Complete framework to facilitate music commands using discord.js", - "main": "lib/index.js", + "main": "lib/src/index.js", + "types": "lib/src/index.d.ts", "files": [ "lib/**/*" ], diff --git a/src/Player.ts b/src/Player.ts index 29e1ac8..36b0c4b 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -123,11 +123,11 @@ export class Player extends EventEmitter { description: data.description, thumbnail: data.thumbnail, views: data.playCount, - author: data.author, + author: data.author.name, requestedBy: message.author, fromPlaylist: false, source: 'soundcloud', - engine: data.engine + engine: data }); tracks.push(track); @@ -249,6 +249,8 @@ export class Player extends EventEmitter { this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); this._addTracksToQueue(message, tracks); } + + return; } case 'soundcloud_playlist': { this.emit(PlayerEvents.PLAYLIST_PARSE_START, null, message); @@ -824,7 +826,7 @@ export class Player extends EventEmitter { ? options?.length <= 0 || options?.length === Infinity ? 15 : options?.length - : options?.length; + : 15; const index = Math.round((currentStreamTime / totalTime) * length); const indicator = '🔘'; From facdc537552effc51f5d79c8360882aab47ca6c9 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 10 Apr 2021 11:40:17 +0545 Subject: [PATCH 040/131] lyrics support --- src/Player.ts | 13 ++++++++++++- src/types/types.ts | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index 36b0c4b..3cd809b 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; import { Client, Collection, Snowflake, Collector, Message, VoiceChannel, VoiceState } from 'discord.js'; -import { PlayerOptions, PlayerProgressbarOptions, QueueFilters } from './types/types'; +import { LyricsData, PlayerOptions, PlayerProgressbarOptions, QueueFilters } from './types/types'; import Util from './utils/Util'; import AudioFilters from './utils/AudioFilters'; import { Queue } from './Structures/Queue'; @@ -853,6 +853,17 @@ export class Player extends EventEmitter { } } + /** + * Gets lyrics of a song + * @param query Search query + */ + async lyrics(query: string) { + const data = await DP_EXTRACTORS.Lyrics(query); + if (Array.isArray(data)) return null; + + return data as LyricsData; + } + private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { const queue = this.queues.find((g) => g.guildID === oldState.guild.id); if (!queue) return; diff --git a/src/types/types.ts b/src/types/types.ts index e626c96..000fd06 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -94,3 +94,18 @@ export interface PlayerProgressbarOptions { queue?: boolean; length?: number; } + +export interface LyricsData { + title: string; + id: number; + thumbnail: string; + image: string; + url: string; + artist: { + name: string; + id: number; + url: string; + image: string; + }; + lyrics?: string; +} \ No newline at end of file From c43f31290ef6876f37a5d08d375f358ed5644a0a Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 10 Apr 2021 11:55:37 +0545 Subject: [PATCH 041/131] fix lyrics --- package.json | 2 +- src/types/types.ts | 2 +- yarn.lock | 42 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e1f6cc9..8bbdb3c 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ }, "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { - "@discord-player/extractor": "^1.0.5", + "@discord-player/extractor": "^2.0.0", "discord-ytdl-core": "^5.0.2", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", diff --git a/src/types/types.ts b/src/types/types.ts index 000fd06..ac42b83 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -108,4 +108,4 @@ export interface LyricsData { image: string; }; lyrics?: string; -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 2e6fa83..7e214dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,11 +23,12 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@discord-player/extractor@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-1.0.5.tgz#d38f6d73cec5efe2d7b23c62eb12fac0b54514cf" - integrity sha512-lw7ebA7gazoOMzCbwdBPwGlsh6d2/sp/DMDTeBQa9S6HO4wGP1lIjaEt2ipduYRhBP2vlY3iEs5ryFiZwbLraA== +"@discord-player/extractor@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-2.0.0.tgz#3879e51d64b72d4dcee9338bdece5251d006c746" + integrity sha512-qNyF0dkLNRYvtVtLLO022RV8DzToCPJqbuAOqSWCSdkXiKSGoqTdKcZI9I/Lb87mchYuuakOXyPRvRwkAruX6w== dependencies: + genius-lyrics "^4.2.7" jsdom "^16.5.2" node-fetch "^2.6.1" reverbnation-scraper "^2.0.0" @@ -207,6 +208,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== +axios@^0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== + dependencies: + follow-redirects "^1.10.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -565,6 +573,11 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +follow-redirects@^1.10.0: + version "1.13.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" + integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA== + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -610,6 +623,14 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +genius-lyrics@^4.2.7: + version "4.2.7" + resolved "https://registry.yarnpkg.com/genius-lyrics/-/genius-lyrics-4.2.7.tgz#e85f65eb2de4ea2c0af1e11b13dda11e0c9744a9" + integrity sha512-laoeF2/P+Ed4uewuG6OeqymKTNdfGuymkCohMHIgr3g2DwziW49USXcEGCog1vnEDCpf2LhznNi3WOeLeSmAww== + dependencies: + axios "^0.21.1" + node-html-parser "^3.0.4" + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -659,6 +680,11 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + himalaya@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a" @@ -944,6 +970,14 @@ node-fetch@2.6.1, node-fetch@^2.6.0, node-fetch@^2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-html-parser@^3.0.4: + version "3.1.3" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-3.1.3.tgz#987d39bc8df27bc70cbe3b4e9a31fd84f7454dfb" + integrity sha512-pCE2I5UY5iOBnWdJQkbYZSk+fyq2zepw0nsELpHQjVFyCzOeZhkMhnvKqGceKgzWsWx7EG4KtMqsy9Eklf5Thw== + dependencies: + css-select "^3.1.2" + he "1.2.0" + nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" From 66c3103f18ef5664690e3aac585a4c24faff9e72 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 10 Apr 2021 11:58:23 +0545 Subject: [PATCH 042/131] jsdoc example --- src/Player.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Player.ts b/src/Player.ts index 3cd809b..72bfd9d 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -856,6 +856,8 @@ export class Player extends EventEmitter { /** * Gets lyrics of a song * @param query Search query + * @example const lyrics = await player.lyrics("alan walker faded") + * message.channel.send(lyrics.lyrics); */ async lyrics(query: string) { const data = await DP_EXTRACTORS.Lyrics(query); From 5573d5dfd90a9e7174240ad5268c45aff101a88c Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 10 Apr 2021 11:59:50 +0545 Subject: [PATCH 043/131] readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e48636d..969d031 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,8 @@ $ npm install --save @discordjs/opus - Beginner friendly 😱 - Audio filters 🎸 - Lightweight 🛬 -- Custom extractors 🌌 +- Custom extractors support 🌌 +- Lyrics 📃 # License MIT License From fbf4a50884d26581d388f0cfb5da13e7a1c9e17d Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 10 Apr 2021 12:39:03 +0545 Subject: [PATCH 044/131] readme --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 969d031..a8994ed 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,19 @@ $ npm install --save @discordjs/opus - Custom extractors support 🌌 - Lyrics 📃 +# Sources supported +> By default, **discord-player** supports `youtube`, `spotify`, `soundcloud`, `vimeo`, `reverbnation`, `facebook` and `attachment links` only. + +**Discord Player** provides **extractor API** that enables you to use your custom stream extractor with it. For example, you can use **youtube-dl** with **discord-player** like this: + +```js +const { Downloader } = require("@discord-player/downloader"); // YouTubeDL instance + +player.use("EXAMPLE", Downloader); // now discord-player supports 700+ sites :poggies: +``` + +or you can build your own :D + # License MIT License From 809139782ed80f6240d8d8e17738708fc730aa82 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 10 Apr 2021 23:37:48 +0545 Subject: [PATCH 045/131] refactor --- README.md | 2 ++ src/Player.ts | 10 +++++----- src/utils/Util.ts | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a8994ed..4ada687 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ $ npm install --save @discordjs/opus - Lightweight 🛬 - Custom extractors support 🌌 - Lyrics 📃 +- Multiple sources support ✌ +- Play in multiple servers at the same time 🚗 # Sources supported > By default, **discord-player** supports `youtube`, `spotify`, `soundcloud`, `vimeo`, `reverbnation`, `facebook` and `attachment links` only. diff --git a/src/Player.ts b/src/Player.ts index 72bfd9d..853b496 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -119,7 +119,7 @@ export class Player extends EventEmitter { const track = new Track(this, { title: data.title, url: data.url, - duration: Util.durationString(Util.parseMS(data.duration / 1000)), + duration: Util.buildTimeCode(Util.parseMS(data.duration / 1000)), description: data.description, thumbnail: data.thumbnail, views: data.playCount, @@ -213,7 +213,7 @@ export class Player extends EventEmitter { new Track(this, { title: data.title, url: data.url, - duration: Util.durationString(Util.parseMS(data.duration)), + duration: Util.buildTimeCode(Util.parseMS(data.duration)), description: data.description, thumbnail: data.thumbnail?.displayThumbnailURL(), views: data.views, @@ -272,7 +272,7 @@ export class Player extends EventEmitter { const r = new Track(this, { title: song.title, url: song.url, - duration: Util.durationString(Util.parseMS(song.duration / 1000)), + duration: Util.buildTimeCode(Util.parseMS(song.duration / 1000)), description: song.description, thumbnail: song.thumbnail ?? 'https://soundcloud.com/pwa-icon-192.png', views: song.playCount ?? 0, @@ -388,7 +388,7 @@ export class Player extends EventEmitter { author: info.videoDetails.author.name, url: info.videoDetails.video_url, thumbnail: lastThumbnail.url, - duration: Util.durationString(Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)), + duration: Util.buildTimeCode(Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)), views: parseInt(info.videoDetails.viewCount), requestedBy: message.author, fromPlaylist: false, @@ -402,7 +402,7 @@ export class Player extends EventEmitter { track = new Track(this, { title: data.title, description: data.description, - duration: Util.durationString(Util.parseMS(data.duration)), + duration: Util.buildTimeCode(Util.parseMS(data.duration)), thumbnail: data.thumbnail, author: data.author, views: data.views, diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 556e129..bf3f76b 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -114,7 +114,7 @@ export class Util { author: r.channel.name, url: r.url, thumbnail: r.thumbnail.displayThumbnailURL(), - duration: r.durationFormatted, + duration: Util.buildTimeCode(Util.parseMS(r.duration)), views: r.views, requestedBy: options?.user, fromPlaylist: Boolean(options?.pl), From 72bd3bf6457669853c90a1c9aed42432834031ff Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 11 Apr 2021 18:36:50 +0545 Subject: [PATCH 046/131] update --- src/Player.ts | 2 +- src/Structures/Queue.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 853b496..0814a4b 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -934,7 +934,7 @@ export class Player extends EventEmitter { new PlayerError('Voice connection is not available in this server!') ); - const queue = new Queue(this, message, this.filters); + const queue = new Queue(this, message); this.queues.set(message.guild.id, queue); channel diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 17ec077..2243d76 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -24,8 +24,9 @@ export class Queue extends EventEmitter { public filters: QueueFilters; public additionalStreamTime: number; public firstMessage: Message; + public ytLast?: Track; - constructor(player: Player, message: Message, filters: typeof AudioFilters) { + constructor(player: Player, message: Message) { super(); Object.defineProperty(this, 'player', { value: player, enumerable: false }); From 66ed2b711729bed8f6481efd42a147c83a68c073 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 11 Apr 2021 19:12:48 +0545 Subject: [PATCH 047/131] implement youtube autoplay --- src/Player.ts | 35 +++++++++++++++++++++++++++++++---- src/Structures/Queue.ts | 2 +- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 0814a4b..738cd1b 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -866,6 +866,18 @@ export class Player extends EventEmitter { return data as LyricsData; } + /** + * Toggle autoplay for youtube streams + * @param message The message object + * @param enable Enable/Disable autoplay + */ + setAutoplay(message: Message, enable: boolean): void { + const queue = this.getQueue(message); + if (!queue) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); + + queue.autoPlay = Boolean(enable); + } + private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { const queue = this.queues.find((g) => g.guildID === oldState.guild.id); if (!queue) return; @@ -964,7 +976,7 @@ export class Player extends EventEmitter { private async _playTrack(queue: Queue, firstPlay: boolean): Promise { if (queue.stopped) return; - if (queue.tracks.length === 1 && !queue.loopMode && !queue.repeatMode && !firstPlay) { + if (!queue.autoPlay && queue.tracks.length === 1 && !queue.loopMode && !queue.repeatMode && !firstPlay) { if (this.options.leaveOnEnd && !queue.stopped) { this.queues.delete(queue.guildID); const timeout = setTimeout(() => { @@ -982,7 +994,22 @@ export class Player extends EventEmitter { return void this.emit(PlayerEvents.QUEUE_END, queue.firstMessage, queue); } - if (!queue.repeatMode && !firstPlay) { + if (queue.autoPlay && !queue.repeatMode && !firstPlay) { + const oldTrack = queue.tracks.shift(); + + const info = oldTrack.raw.source === 'youtube' ? await ytdl.getInfo(oldTrack.url).catch((e) => {}) : null; + if (info) { + const res = await Util.ytSearch(info.related_videos[0].title, { player: this, limit: 1 }) + .then((v) => v[0]) + .catch((e) => {}); + + if (res) { + queue.tracks.push(res); + if (queue.loopMode) queue.tracks.push(oldTrack); + queue.previousTracks.push(oldTrack); + } + } + } else if (!queue.autoPlay && !queue.repeatMode && !firstPlay) { const oldTrack = queue.tracks.shift(); if (queue.loopMode) queue.tracks.push(oldTrack); queue.previousTracks.push(oldTrack); @@ -998,8 +1025,8 @@ export class Player extends EventEmitter { private _playStream(queue: Queue, updateFilter: boolean, seek?: number): Promise { return new Promise(async (resolve) => { - const ffmeg = Util.checkFFmpeg(); - if (!ffmeg) return; + const ffmpeg = Util.checkFFmpeg(); + if (!ffmpeg) return; const seekTime = typeof seek === 'number' diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 2243d76..da496ca 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -24,7 +24,7 @@ export class Queue extends EventEmitter { public filters: QueueFilters; public additionalStreamTime: number; public firstMessage: Message; - public ytLast?: Track; + public autoPlay = false; constructor(player: Player, message: Message) { super(); From 8b6cf39f270b4666212cff760abe1caa00fa7bd0 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 11 Apr 2021 20:00:58 +0545 Subject: [PATCH 048/131] fix things --- src/Player.ts | 2 +- src/Structures/Queue.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 738cd1b..49c8a1b 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -999,7 +999,7 @@ export class Player extends EventEmitter { const info = oldTrack.raw.source === 'youtube' ? await ytdl.getInfo(oldTrack.url).catch((e) => {}) : null; if (info) { - const res = await Util.ytSearch(info.related_videos[0].title, { player: this, limit: 1 }) + const res = await Util.ytSearch(info.related_videos[0].title, { player: this, limit: 1, user: oldTrack.requestedBy }) .then((v) => v[0]) .catch((e) => {}); diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index da496ca..b3ad1d6 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -111,7 +111,7 @@ export class Queue extends EventEmitter { * Calculated volume of this queue */ get calculatedVolume() { - return this.filters.bassboost ? this.volume + 50 : this.volume; + return this.filters.normalizer ? this.volume + 70 : this.volume; } /** From b51f30f1aaa9f1f5f79a0f1bf49a5dfbfae9f6f2 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 12 Apr 2021 20:36:11 +0545 Subject: [PATCH 049/131] some stuff for now --- package.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8bbdb3c..447a35f 100644 --- a/package.json +++ b/package.json @@ -4,14 +4,12 @@ "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", - "files": [ - "lib/**/*" - ], "scripts": { "test": "yarn build && cd test && node index.js", "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", - "lint": "tslint -p tsconfig.json" + "lint": "tslint -p tsconfig.json", + "postinstall": "npm run build" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ From bfed268e7aae7b0634b97792b0de0c3634e14c2f Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 14 Apr 2021 08:44:06 +0545 Subject: [PATCH 050/131] fix: live content --- src/Player.ts | 12 ++++++++---- src/types/types.ts | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 49c8a1b..4e224a4 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -392,7 +392,8 @@ export class Player extends EventEmitter { views: parseInt(info.videoDetails.viewCount), requestedBy: message.author, fromPlaylist: false, - source: 'youtube' + source: 'youtube', + live: Boolean(info.videoDetails.isLiveContent) }); } else { for (const [_, extractor] of this.Extractors) { @@ -999,7 +1000,11 @@ export class Player extends EventEmitter { const info = oldTrack.raw.source === 'youtube' ? await ytdl.getInfo(oldTrack.url).catch((e) => {}) : null; if (info) { - const res = await Util.ytSearch(info.related_videos[0].title, { player: this, limit: 1, user: oldTrack.requestedBy }) + const res = await Util.ytSearch(info.related_videos[0].title, { + player: this, + limit: 1, + user: oldTrack.requestedBy + }) .then((v) => v[0]) .catch((e) => {}); @@ -1054,9 +1059,8 @@ export class Player extends EventEmitter { let newStream: any; if (queue.playing.raw.source === 'youtube') { newStream = ytdl(queue.playing.url, { - filter: 'audioonly', opusEncoded: true, - encoderArgs, + encoderArgs: queue.playing.raw.live ? [] : encoderArgs, seek: seekTime / 1000, // tslint:disable-next-line:no-bitwise highWaterMark: 1 << 25, diff --git a/src/types/types.ts b/src/types/types.ts index ac42b83..61bfd1b 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -30,6 +30,7 @@ export interface TrackData { fromPlaylist: boolean; source?: TrackSource; engine?: any; + live?: boolean; } export type QueueFilters = { From 54e22e6e7747c0ec82fa89a3ab287dbf4c4a1520 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 14 Apr 2021 08:44:39 +0545 Subject: [PATCH 051/131] fmt --- src/Player.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Player.ts b/src/Player.ts index 4e224a4..bc9afc1 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1059,6 +1059,7 @@ export class Player extends EventEmitter { let newStream: any; if (queue.playing.raw.source === 'youtube') { newStream = ytdl(queue.playing.url, { + filter: queue.playing.raw.live ? undefined : "audioonly", opusEncoded: true, encoderArgs: queue.playing.raw.live ? [] : encoderArgs, seek: seekTime / 1000, From 7f39ee07fec3b55fa83338f54879e4263a26af0b Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 14 Apr 2021 08:45:06 +0545 Subject: [PATCH 052/131] prettier --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index bc9afc1..e747711 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1059,7 +1059,7 @@ export class Player extends EventEmitter { let newStream: any; if (queue.playing.raw.source === 'youtube') { newStream = ytdl(queue.playing.url, { - filter: queue.playing.raw.live ? undefined : "audioonly", + filter: queue.playing.raw.live ? undefined : 'audioonly', opusEncoded: true, encoderArgs: queue.playing.raw.live ? [] : encoderArgs, seek: seekTime / 1000, From 763a9b2dfcaf19a4aea28093a797473c3d910927 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 14 Apr 2021 08:47:02 +0545 Subject: [PATCH 053/131] disable filters for livestream --- src/Player.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Player.ts b/src/Player.ts index e747711..5bf31fe 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -466,6 +466,14 @@ export class Player extends EventEmitter { new PlayerError('Not playing') ); + if (queue.playing.raw.live) + return void this.emit( + PlayerEvents.ERROR, + PlayerErrorEventCodes.LIVE_VIDEO, + message, + new PlayerError('Cannot use setFilters on livestream') + ); + Object.keys(newFilters).forEach((filterName) => { // @ts-ignore queue.filters[filterName] = newFilters[filterName]; From 27f142d84a820f140ed00b73e7978c4e2c2c9ff9 Mon Sep 17 00:00:00 2001 From: MegaPixel Date: Fri, 16 Apr 2021 18:43:01 +0545 Subject: [PATCH 054/131] should fix EPIPE --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 70cdee1..1183afa 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { "chalk": "^4.1.0", - "discord-ytdl-core": "^5.0.1", + "discord-ytdl-core": "^5.0.2", "jsdom": "^16.4.0", "merge-options": "^3.0.4", "node-fetch": "^2.6.0", @@ -39,7 +39,7 @@ "reverbnation-scraper": "^2.0.0", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", - "youtube-sr": "^4.0.2", + "youtube-sr": "^4.0.4", "ytdl-core": "^4.5.0" }, "devDependencies": { From 60b870d30eee981b89c77ae9acb1b1fe9c2622ec Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 17 Apr 2021 09:46:06 +0545 Subject: [PATCH 055/131] stats --- src/Player.ts | 30 +++++++++++++++++++++++++++++- src/types/types.ts | 35 +++++++++++++++++++++++++++++++++++ src/utils/Util.ts | 13 +++++++++---- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 5bf31fe..f9c83e0 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; import { Client, Collection, Snowflake, Collector, Message, VoiceChannel, VoiceState } from 'discord.js'; -import { LyricsData, PlayerOptions, PlayerProgressbarOptions, QueueFilters } from './types/types'; +import { LyricsData, PlayerOptions, PlayerProgressbarOptions, PlayerStats, QueueFilters } from './types/types'; import Util from './utils/Util'; import AudioFilters from './utils/AudioFilters'; import { Queue } from './Structures/Queue'; @@ -9,6 +9,7 @@ import { PlayerErrorEventCodes, PlayerEvents } from './utils/Constants'; import PlayerError from './utils/PlayerError'; import ytdl from 'discord-ytdl-core'; import { ExtractorModel } from './Structures/ExtractorModel'; +import os from 'os'; // @ts-ignore import spotify from 'spotify-url-info'; @@ -887,6 +888,33 @@ export class Player extends EventEmitter { queue.autoPlay = Boolean(enable); } + getStats(): PlayerStats { + return { + uptime: this.client.uptime, + connections: this.client.voice.connections.size, + users: this.client.voice.connections.reduce((a, c) => a + c.channel.members.size, 0), + queues: this.queues.size, + extractors: this.Extractors.size, + versions: { + ffmpeg: Util.getFFmpegVersion(), + node: process.version, + v8: process.versions.v8 + }, + system: { + arch: process.arch, + platform: process.platform, + cpu: os.cpus().length, + memory: { + total: (process.memoryUsage().heapTotal / 1024 / 1024).toFixed(2), + usage: (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2), + rss: (process.memoryUsage().rss / 1024 / 1024).toFixed(2), + arrayBuffers: (process.memoryUsage().arrayBuffers / 1024 / 1024).toFixed(2) + }, + uptime: process.uptime() + } + }; + } + private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { const queue = this.queues.find((g) => g.guildID === oldState.guild.id); if (!queue) return; diff --git a/src/types/types.ts b/src/types/types.ts index 61bfd1b..11d950b 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -110,3 +110,38 @@ export interface LyricsData { }; 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; + }; +} diff --git a/src/utils/Util.ts b/src/utils/Util.ts index bf3f76b..abf5b08 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -31,16 +31,21 @@ export class Util { } as PlayerOptions; } - static checkFFmpeg(force?: boolean) { + static getFFmpegVersion(force?: boolean) { try { - FFmpeg.getInfo(Boolean(force)); + const info = FFmpeg.getInfo(Boolean(force)); - return true; + return info.version; } catch { - return false; + return null; } } + static checkFFmpeg(force?: boolean) { + const version = Util.getFFmpegVersion(force); + return version === null ? false : true; + } + static alertFFmpeg() { const hasFFmpeg = Util.checkFFmpeg(); From f4deb40adbfab4076edb14bc4eb54bf2dca235a8 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 17 Apr 2021 09:46:42 +0545 Subject: [PATCH 056/131] some jsdoc --- src/Player.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Player.ts b/src/Player.ts index f9c83e0..b9245d7 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -888,6 +888,9 @@ export class Player extends EventEmitter { queue.autoPlay = Boolean(enable); } + /** + * Player stats + */ getStats(): PlayerStats { return { uptime: this.client.uptime, From 0ff076b583d498795b56f4becceee2796fe69211 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 17 Apr 2021 09:47:40 +0545 Subject: [PATCH 057/131] accurate stat --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index b9245d7..baefe80 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -895,7 +895,7 @@ export class Player extends EventEmitter { return { uptime: this.client.uptime, connections: this.client.voice.connections.size, - users: this.client.voice.connections.reduce((a, c) => a + c.channel.members.size, 0), + users: this.client.voice.connections.reduce((a, c) => a + c.channel.members.filter(a => a.user.id !== this.client.user.id).size, 0), queues: this.queues.size, extractors: this.Extractors.size, versions: { From c505b177adce3445da3cf68f905029bc19bb6089 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 17 Apr 2021 19:56:18 +0545 Subject: [PATCH 058/131] move default player options to constants --- src/Player.ts | 21 +++++++++++++++------ src/utils/Constants.ts | 12 ++++++++++++ src/utils/Util.ts | 14 +------------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index baefe80..9bdd4e5 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1,11 +1,17 @@ import { EventEmitter } from 'events'; import { Client, Collection, Snowflake, Collector, Message, VoiceChannel, VoiceState } from 'discord.js'; -import { LyricsData, PlayerOptions, PlayerProgressbarOptions, PlayerStats, QueueFilters } from './types/types'; +import { + LyricsData, + PlayerOptions as PlayerOptionsType, + PlayerProgressbarOptions, + PlayerStats, + QueueFilters +} from './types/types'; import Util from './utils/Util'; import AudioFilters from './utils/AudioFilters'; import { Queue } from './Structures/Queue'; import { Track } from './Structures/Track'; -import { PlayerErrorEventCodes, PlayerEvents } from './utils/Constants'; +import { PlayerErrorEventCodes, PlayerEvents, PlayerOptions } from './utils/Constants'; import PlayerError from './utils/PlayerError'; import ytdl from 'discord-ytdl-core'; import { ExtractorModel } from './Structures/ExtractorModel'; @@ -27,7 +33,7 @@ export class Player extends EventEmitter { * The discord client that instantiated this player */ public client!: Client; - public options: PlayerOptions; + public options: PlayerOptionsType; public filters: typeof AudioFilters; /** @@ -47,7 +53,7 @@ export class Player extends EventEmitter { * @param client The discord.js client * @param options Player options */ - constructor(client: Client, options?: PlayerOptions) { + constructor(client: Client, options?: PlayerOptionsType) { super(); Object.defineProperty(this, 'client', { @@ -58,7 +64,7 @@ export class Player extends EventEmitter { /** * The player options */ - this.options = Object.assign({}, Util.DefaultPlayerOptions, options ?? {}); + this.options = Object.assign({}, PlayerOptions, options ?? {}); // check FFmpeg void Util.alertFFmpeg(); @@ -895,7 +901,10 @@ export class Player extends EventEmitter { return { uptime: this.client.uptime, connections: this.client.voice.connections.size, - users: this.client.voice.connections.reduce((a, c) => a + c.channel.members.filter(a => a.user.id !== this.client.user.id).size, 0), + users: this.client.voice.connections.reduce( + (a, c) => a + c.channel.members.filter((a) => a.user.id !== this.client.user.id).size, + 0 + ), queues: this.queues.size, extractors: this.Extractors.size, versions: { diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index 7b075ed..ef5eb1b 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -1,3 +1,5 @@ +import { PlayerOptions as DP_OPTIONS } from '../types/types'; + export const PlayerEvents = { BOT_DISCONNECT: 'botDisconnect', CHANNEL_EMPTY: 'channelEmpty', @@ -26,3 +28,13 @@ export const PlayerErrorEventCodes = { VIDEO_UNAVAILABLE: 'VideoUnavailable', MUSIC_STARTING: 'MusicStarting' }; + +export const PlayerOptions: DP_OPTIONS = { + leaveOnEnd: true, + leaveOnStop: true, + leaveOnEmpty: true, + leaveOnEmptyCooldown: 0, + autoSelfDeaf: true, + enableLive: false, + ytdlDownloadOptions: {} +}; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index abf5b08..9a6eb6e 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -1,4 +1,4 @@ -import { PlayerOptions, QueryType } from '../types/types'; +import { QueryType } from '../types/types'; import { FFmpeg } from 'prism-media'; import YouTube from 'youtube-sr'; import { Track } from '../Structures/Track'; @@ -19,18 +19,6 @@ export class Util { throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); } - static get DefaultPlayerOptions() { - return { - leaveOnEnd: true, - leaveOnStop: true, - leaveOnEmpty: true, - leaveOnEmptyCooldown: 0, - autoSelfDeaf: true, - enableLive: false, - ytdlDownloadOptions: {} - } as PlayerOptions; - } - static getFFmpegVersion(force?: boolean) { try { const info = FFmpeg.getInfo(Boolean(force)); From 23121ed24fa4d82658de539f0ffcccd0c69fcb81 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 17 Apr 2021 20:13:12 +0545 Subject: [PATCH 059/131] some methods --- src/Structures/Queue.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index b3ad1d6..b25cb12 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -127,6 +127,40 @@ export class Queue extends EventEmitter { get currentStreamTime() { return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; } + + /** + * Sets audio filters in this player + * @param filters Audio filters to set + */ + setFilters(filters: QueueFilters) { + return this.player.setFilters(this.firstMessage, filters); + } + + /** + * Returns array of all enabled filters + */ + getFiltersEnabled() { + const filters: string[] = []; + + for (const filter in this.filters) { + if (this.filters[filter as keyof QueueFilters] !== false) filters.push(filter); + } + + return filters; + } + + /** + * Returns all disabled filters + */ + getFiltersDisabled() { + const enabled = this.getFiltersEnabled(); + + return Object.keys(this.filters).filter((f) => !enabled.includes(f)); + } + + toString() { + return ``; + } } export default Queue; From 7a915d6cf04e935ce9554ebf5024fcb0c7ad7a24 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 17 Apr 2021 22:44:46 +0545 Subject: [PATCH 060/131] some postinstall script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 447a35f..ac7e382 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", "lint": "tslint -p tsconfig.json", - "postinstall": "npm run build" + "postinstall": "npx tsc" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ From 5898c0f40d90c997792de9cdbb4690f4380aad9c Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 17 Apr 2021 22:50:26 +0545 Subject: [PATCH 061/131] aaah --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ac7e382..06ea28a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", "lint": "tslint -p tsconfig.json", - "postinstall": "npx tsc" + "postinstall": "npx tsc --build tsconfig.json" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ From 651e2fb85fbced3a7554b18572c6d0b9d8a447a7 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 12:11:06 +0545 Subject: [PATCH 062/131] .npmignore --- .npmignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.npmignore b/.npmignore index 90bfa96..f2e7e52 100644 --- a/.npmignore +++ b/.npmignore @@ -1,5 +1,4 @@ src/ -tsconfig.json tslint.json .prettierrc test/ \ No newline at end of file From b674b2b33979afdb1b47f26aeccd9eb50358de9d Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 12:18:09 +0545 Subject: [PATCH 063/131] development --- package.json | 4 ++-- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 06ea28a..6df8ed8 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { "@discord-player/extractor": "^2.0.0", + "@types/node": "^14.14.41", + "@types/ws": "^7.4.1", "discord-ytdl-core": "^5.0.2", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", @@ -45,8 +47,6 @@ }, "devDependencies": { "@discordjs/opus": "^0.5.0", - "@types/node": "^14.14.37", - "@types/ws": "^7.4.1", "discord.js": "^12.5.3", "prettier": "^2.2.1", "tslint": "^6.1.3", diff --git a/yarn.lock b/yarn.lock index 7e214dd..8ca877e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -75,10 +75,10 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@types/node@*", "@types/node@^14.14.37": - version "14.14.37" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" - integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== +"@types/node@*", "@types/node@^14.14.41": + version "14.14.41" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615" + integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g== "@types/ws@^7.4.1": version "7.4.1" From a3d3ca572242dfd03db3555c284136768f42c1a3 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 12:31:51 +0545 Subject: [PATCH 064/131] remove dev stuff --- .npmignore | 1 + package.json | 7 +++---- src/utils/Util.ts | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.npmignore b/.npmignore index f2e7e52..ff95fea 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,5 @@ src/ tslint.json +tsconfig.json .prettierrc test/ \ No newline at end of file diff --git a/package.json b/package.json index 6df8ed8..7f91270 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,7 @@ "test": "yarn build && cd test && node index.js", "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", - "lint": "tslint -p tsconfig.json", - "postinstall": "npx tsc --build tsconfig.json" + "lint": "tslint -p tsconfig.json" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ @@ -37,8 +36,6 @@ "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { "@discord-player/extractor": "^2.0.0", - "@types/node": "^14.14.41", - "@types/ws": "^7.4.1", "discord-ytdl-core": "^5.0.2", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", @@ -47,6 +44,8 @@ }, "devDependencies": { "@discordjs/opus": "^0.5.0", + "@types/node": "^14.14.41", + "@types/ws": "^7.4.1", "discord.js": "^12.5.3", "prettier": "^2.2.1", "tslint": "^6.1.3", diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 9a6eb6e..940fec1 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -73,7 +73,6 @@ export class Util { } static parseMS(milliseconds: number) { - // taken from ms package :: https://github.com/sindresorhus/parse-ms/blob/main/index.js const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; return { From 33a37c106052c04a73e6a89d5c03e652bf1500ab Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 22:52:56 +0545 Subject: [PATCH 065/131] files --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 7f91270..65b13de 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", + "files": ["lib/"], "scripts": { "test": "yarn build && cd test && node index.js", "build": "tsc", From 2015970641481bd11e74943f6b2c861c75c7d123 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 22:53:14 +0545 Subject: [PATCH 066/131] stable version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 65b13de..c518005 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.0-dev", + "version": "4.0.0", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", From c4ce0542d898882c24e80d7c68a00617335547b5 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 23:05:12 +0545 Subject: [PATCH 067/131] some examples --- README.md | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ada687..78c85d7 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ Complete framework to facilitate music commands using **[discord.js](https://dis [![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) [![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) -> WIP - ## Installation ### Install **[discord-player](https://npmjs.com/package/discord-player)** @@ -37,6 +35,83 @@ $ npm install --save @discordjs/opus - Multiple sources support ✌ - Play in multiple servers at the same time 🚗 +## [Documentation](https://discord-player.js.org) + +## Getting Started + +Here is the code you will need to get started with discord-player. Then, you will be able to use `client.player` everywhere in your code! + +```js +const Discord = require("discord.js"), +client = new Discord.Client, +settings = { + prefix: "!", + token: "Your Discord Token" +}; + +const { Player } = require("discord-player"); + +// Create a new Player (you don't need any API Key) +const player = new Player(client); + +// To easily access the player +client.player = player; + +// add the trackStart event so when a song will be played this message will be sent +client.player.on("trackStart", (message, track) => message.channel.send(`Now playing ${track.title}...`)) + +client.once("ready", () => { + console.log("I'm ready !"); +}); + +client.on("message", async (message) => { + + const args = message.content.slice(settings.prefix.length).trim().split(/ +/g); + const command = args.shift().toLowerCase(); + + // !play Despacito + // will play "Despacito" in the voice channel + if(command === "play"){ + client.player.play(message, args[0]); + // as we registered the event above, no need to send a success message here + } + +}); + +client.login(settings.token); +``` + +# Other Examples +## Using Cookies + +```js +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { + headers: { + cookie: "YOUR_YOUTUBE_COOKIE" + } + } + } +}); +``` + +## Using Proxy + +```js +const HttpsProxyAgent = require("https-proxy-agent"); + +// Remove "user:pass@" if you don't need to authenticate to your proxy. +const proxy = "http://user:pass@111.111.111.111:8080"; +const agent = HttpsProxyAgent(proxy); + +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { agent } + } +}); +``` + # Sources supported > By default, **discord-player** supports `youtube`, `spotify`, `soundcloud`, `vimeo`, `reverbnation`, `facebook` and `attachment links` only. @@ -50,6 +125,14 @@ player.use("EXAMPLE", Downloader); // now discord-player supports 700+ sites :po or you can build your own :D +## Examples of bots made with Discord Player + +These bots are made by the community, they can help you build your own! + +* [AtlantaBot](https://github.com/Androz2091/AtlantaBot) by [Androz2091](https://github.com/Androz2091) +* [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) +* [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) + # License MIT License From 191c36d63ec4e0dc14e42efe7e5d70cc93ede7bf Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 23:29:12 +0545 Subject: [PATCH 068/131] CODE_OF_CONDUCT --- CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..6ac2874 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +androz2091@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. \ No newline at end of file From a1203c14455f88e4ceb271755aa5513f24c115ea Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 23:32:18 +0545 Subject: [PATCH 069/131] CONTRIBUTING --- CONTRIBUTING.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..c1043a4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,22 @@ +# Hello +This document is for people who want to contribute to this project! + +# Code Style + +## Formatting +We are using **[Prettier](https://prettier.io)** to format the code. + +## File names +- Always use `PascalCase` for the files containing classes (example: `Queue`, `Track`, `Player` etc.) + +## Some Rules +- Use `camelCase` for `Function names`, `Variables`, etc. and `PascalCase` for `Class name` +- Do not make unused variables/imports +- Don't forget to write `JSDOC` for each properties and methods +- Use English language + +# Pull Requests +- Use English language +- Explain what your update does + +- Run tests, formatting, etc. before making Pull Requests \ No newline at end of file From 9771ee6c694a21ece765b63d7c4ed082c595729e Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 23:35:01 +0545 Subject: [PATCH 070/131] issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 32 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++ .github/ISSUE_TEMPLATE/question.md | 11 ++++++++ .github/PULL_REQUEST_TEMPLATE.md | 8 ++++++ 4 files changed, 71 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/question.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..325fe93 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Create a bug report to help us improve +title: "[BUG] " +labels: bug +assignees: '' + +--- + +**Describe the bug** + + +**To Reproduce** +Steps to reproduce the behavior: + + +**Expected behavior** + + +**Screenshots** + + +**Please complete the following information:** + - Node Version: [x.x.x] + - Library Version: [x.x.x] + - Discord.js Version: [x.x.x] + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..16ba85a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Feature Request] " +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** + + +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 0000000..2953cde --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,11 @@ +--- +name: Question +about: Some questions related to this lib +title: "[QUESTION] " +labels: question +assignees: '' + +--- + +**Question** + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..2004733 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ +## Changes + + +## Status + +- [ ] These changes have been tested and formatted properly. +- [ ] This PR includes only documentation changes, no code change. +- [ ] This PR introduces some Breaking changes. \ No newline at end of file From 9d175d3f3ff9dedf65a0df6f43312dfa25a76c4b Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sun, 18 Apr 2021 23:39:24 +0545 Subject: [PATCH 071/131] discord invite --- .github/ISSUE_TEMPLATE/config.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..6635d17 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Discord Community Support + url: https://discord.gg/J4kK8ygxmW + about: Join our Discord server for further support \ No newline at end of file From 63e0e7bece848d2b486fd0241d08ab6a3e7df99b Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 19 Apr 2021 14:18:34 +0545 Subject: [PATCH 072/131] @discord-player/extractor as dev dependency --- package.json | 6 ++++-- src/Player.ts | 14 +++++++++----- src/utils/Util.ts | 12 ++++++++++++ yarn.lock | 18 +++++++++--------- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index c518005..2f65a75 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", - "files": ["lib/"], + "files": [ + "lib/" + ], "scripts": { "test": "yarn build && cd test && node index.js", "build": "tsc", @@ -36,7 +38,6 @@ }, "homepage": "https://github.com/Androz2091/discord-player#readme", "dependencies": { - "@discord-player/extractor": "^2.0.0", "discord-ytdl-core": "^5.0.2", "soundcloud-scraper": "^4.0.3", "spotify-url-info": "^2.2.0", @@ -44,6 +45,7 @@ "ytdl-core": "^4.5.0" }, "devDependencies": { + "@discord-player/extractor": "^2.0.0", "@discordjs/opus": "^0.5.0", "@types/node": "^14.14.41", "@types/ws": "^7.4.1", diff --git a/src/Player.ts b/src/Player.ts index 9bdd4e5..235f9df 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -23,9 +23,6 @@ import spotify from 'spotify-url-info'; import { Client as SoundCloudClient } from 'soundcloud-scraper'; import YouTube from 'youtube-sr'; -// @ts-ignore -import * as DP_EXTRACTORS from '@discord-player/extractor'; - const SoundCloud = new SoundCloudClient(); export class Player extends EventEmitter { @@ -76,7 +73,11 @@ export class Player extends EventEmitter { this.client.on('voiceStateUpdate', (o, n) => void this._handleVoiceStateUpdate(o, n)); - ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => void this.use(ext, DP_EXTRACTORS[ext])); + // auto detect @discord-player/extractor + let nv: any; + if ((nv = Util.require('@discord-player/extractor'))) { + ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => void this.use(ext, nv[ext])); + } } static get AudioFilters() { @@ -876,7 +877,10 @@ export class Player extends EventEmitter { * message.channel.send(lyrics.lyrics); */ async lyrics(query: string) { - const data = await DP_EXTRACTORS.Lyrics(query); + const extractor = Util.require('@discord-player/extractor'); + if (!extractor) throw new PlayerError("Cannot call 'Player.lyrics()' without '@discord-player/extractor'"); + + const data = await extractor.Lyrics(query); if (Array.isArray(data)) return null; return data as LyricsData; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 940fec1..a8af3b4 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -152,6 +152,18 @@ export class Util { .join(':'); return final.length <= 3 ? `0:${final.padStart(2, '0') || 0}` : final; } + + /** + * Manage CJS require + * @param id id to require + */ + static require(id: string): any { + try { + return require(id); + } catch { + return null; + } + } } export default Util; diff --git a/yarn.lock b/yarn.lock index 8ca877e..6569a5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -123,9 +123,9 @@ acorn@^7.1.1: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" - integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== + version "8.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.1.tgz#fb0026885b9ac9f48bac1e185e4af472971149ff" + integrity sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g== agent-base@6: version "6.0.2" @@ -808,9 +808,9 @@ jsbn@~0.1.0: integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsdom@^16.5.2: - version "16.5.2" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.2.tgz#583fac89a0aea31dbf6237e7e4bedccd9beab472" - integrity sha512-JxNtPt9C1ut85boCbJmffaQ06NBnzkQY/MWO3YxPW8IWS38A26z+B1oBvA9LwKrytewdfymnhi4UNH3/RAgZrg== + version "16.5.3" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" + integrity sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA== dependencies: abab "^2.0.5" acorn "^8.1.0" @@ -971,9 +971,9 @@ node-fetch@2.6.1, node-fetch@^2.6.0, node-fetch@^2.6.1: integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== node-html-parser@^3.0.4: - version "3.1.3" - resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-3.1.3.tgz#987d39bc8df27bc70cbe3b4e9a31fd84f7454dfb" - integrity sha512-pCE2I5UY5iOBnWdJQkbYZSk+fyq2zepw0nsELpHQjVFyCzOeZhkMhnvKqGceKgzWsWx7EG4KtMqsy9Eklf5Thw== + version "3.1.5" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-3.1.5.tgz#ffb62f2a336b6b634f41f3315487fe446fb9d7b5" + integrity sha512-/XKKdWbSUymlXTjtNBcDlmM7Jp8S/BqGMzLx7r2bd2NMjTXz+ofuLcz0Bl3VT0vTvVzF+N511FNLrZt4HVitXA== dependencies: css-select "^3.1.2" he "1.2.0" From 4d37f51299d2d3de516355b7194a1625c9e02709 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 19 Apr 2021 14:22:48 +0545 Subject: [PATCH 073/131] describe extractors --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 466bb91..0cbdfbd 100644 --- a/README.md +++ b/README.md @@ -113,17 +113,14 @@ const player = new Player(client, { ``` # Sources supported -> By default, **discord-player** supports `youtube`, `spotify`, `soundcloud`, `vimeo`, `reverbnation`, `facebook` and `attachment links` only. +> By default, **discord-player** supports `youtube`, `spotify` and `soundcloud` streams only. -**Discord Player** provides **extractor API** that enables you to use your custom stream extractor with it. For example, you can use **youtube-dl** with **discord-player** like this: +**Discord Player** provides **Extractor API** that enables you to use your custom stream extractor with it. -```js -const { Downloader } = require("@discord-player/downloader"); // YouTubeDL instance +# Using @discord-player/extractor [optional] +> Adds support for `vimeo`, `reverbnation`, `facebook` and `attachment links` and `lyrics` -player.use("EXAMPLE", Downloader); // now discord-player supports 700+ sites :poggies: -``` - -or you can build your own :D +**Discord Player** automatically detects and uses `@discord-player/extractor`. You just need to install it via `npm i --save @discord-player/extractor`. ## Examples of bots made with Discord Player From 9e30219f8e813e25c22d363b898c1d319ae8f229 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 19 Apr 2021 18:48:04 +0545 Subject: [PATCH 074/131] ouch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cbdfbd..24e20e4 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ const player = new Player(client, { **Discord Player** provides **Extractor API** that enables you to use your custom stream extractor with it. # Using @discord-player/extractor [optional] -> Adds support for `vimeo`, `reverbnation`, `facebook` and `attachment links` and `lyrics` +> Adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics` **Discord Player** automatically detects and uses `@discord-player/extractor`. You just need to install it via `npm i --save @discord-player/extractor`. From 4a345d80979ad45d3e21242b3e8be054486530fa Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 19 Apr 2021 19:17:10 +0545 Subject: [PATCH 075/131] documentation --- src/Player.ts | 156 ++++++++++++++++++++++++++----- src/Structures/ExtractorModel.ts | 33 ++++++- src/Structures/Queue.ts | 31 +++--- src/Structures/Track.ts | 55 ++++++++++- src/types/types.ts | 7 ++ src/utils/Util.ts | 22 ++--- 6 files changed, 249 insertions(+), 55 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 235f9df..b3d44ee 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -80,7 +80,7 @@ export class Player extends EventEmitter { } } - static get AudioFilters() { + static get AudioFilters(): typeof AudioFilters { return AudioFilters; } @@ -89,7 +89,7 @@ export class Player extends EventEmitter { * @param extractorName The extractor name * @param extractor The extractor itself */ - use(extractorName: string, extractor: any) { + use(extractorName: string, extractor: any): Player { if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); const methods = ['validate', 'getInfo']; @@ -108,7 +108,7 @@ export class Player extends EventEmitter { * Remove existing extractor from this player * @param extractorName The extractor name */ - unuse(extractorName: string) { + unuse(extractorName: string): boolean { if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); return this.Extractors.delete(extractorName); @@ -446,7 +446,7 @@ export class Player extends EventEmitter { * Checks if this player is playing in a server * @param message The message object */ - isPlaying(message: Message) { + isPlaying(message: Message): boolean { return this.queues.some((g) => g.guildID === message.guild.id); } @@ -454,7 +454,7 @@ export class Player extends EventEmitter { * Returns guild queue object * @param message The message object */ - getQueue(message: Message) { + getQueue(message: Message): Queue { return this.queues.find((g) => g.guildID === message.guild.id); } @@ -523,7 +523,7 @@ export class Player extends EventEmitter { * @param time Time in ms to set * @alias setPosition */ - seek(message: Message, time: number) { + seek(message: Message, time: number): Promise { return this.setPosition(message, time); } @@ -553,7 +553,7 @@ export class Player extends EventEmitter { * @param message The message object * @param channel New voice channel to move to */ - moveTo(message: Message, channel?: VoiceChannel) { + moveTo(message: Message, channel?: VoiceChannel): boolean { if (!channel || channel.type !== 'voice') return; const queue = this.queues.find((g) => g.guildID === message.guild.id); if (!queue) { @@ -579,7 +579,7 @@ export class Player extends EventEmitter { * Pause the playback * @param message The message object */ - pause(message: Message) { + pause(message: Message): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -599,7 +599,7 @@ export class Player extends EventEmitter { * Resume the playback * @param message The message object */ - resume(message: Message) { + resume(message: Message): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -619,7 +619,7 @@ export class Player extends EventEmitter { * Stops the player * @param message The message object */ - stop(message: Message) { + stop(message: Message): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -644,7 +644,7 @@ export class Player extends EventEmitter { * @param message The message object * @param percent The volume percentage/amount to set */ - setVolume(message: Message, percent: number) { + setVolume(message: Message, percent: number): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -665,7 +665,7 @@ export class Player extends EventEmitter { * Clears the queue * @param message The message object */ - clearQueue(message: Message) { + clearQueue(message: Message): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -681,7 +681,7 @@ export class Player extends EventEmitter { * Plays previous track * @param message The message object */ - back(message: Message) { + back(message: Message): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -704,7 +704,7 @@ export class Player extends EventEmitter { * @param message The message object * @param enabled If it should enable the repeat mode */ - setRepeatMode(message: Message, enabled: boolean) { + setRepeatMode(message: Message, enabled: boolean): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -721,7 +721,7 @@ export class Player extends EventEmitter { * @param message The message object * @param enabled If it should enable the loop mode */ - setLoopMode(message: Message, enabled: boolean) { + setLoopMode(message: Message, enabled: boolean): boolean { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -737,7 +737,7 @@ export class Player extends EventEmitter { * Returns currently playing track * @param message The message object */ - nowPlaying(message: Message) { + nowPlaying(message: Message): Track { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -751,7 +751,7 @@ export class Player extends EventEmitter { * Shuffles the queue * @param message The message object */ - shuffle(message: Message) { + shuffle(message: Message): Queue { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -775,7 +775,7 @@ export class Player extends EventEmitter { * @param message The message object * @param track The track object/id to remove */ - remove(message: Message, track: Track | number) { + remove(message: Message, track: Track | number): Track { const queue = this.getQueue(message); if (!queue) { this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); @@ -803,7 +803,7 @@ export class Player extends EventEmitter { * @param message The message object * @param queueTime If it should make the time code of the whole queue */ - getTimeCode(message: Message, queueTime?: boolean) { + getTimeCode(message: Message, queueTime?: boolean): { current: string; end: string } { const queue = this.getQueue(message); if (!queue) return; @@ -827,7 +827,7 @@ export class Player extends EventEmitter { * @param message The message object * @param options Progressbar options */ - createProgressBar(message: Message, options?: PlayerProgressbarOptions) { + createProgressBar(message: Message, options?: PlayerProgressbarOptions): string { const queue = this.getQueue(message); if (!queue) return; @@ -876,14 +876,14 @@ export class Player extends EventEmitter { * @example const lyrics = await player.lyrics("alan walker faded") * message.channel.send(lyrics.lyrics); */ - async lyrics(query: string) { + async lyrics(query: string): Promise { const extractor = Util.require('@discord-player/extractor'); if (!extractor) throw new PlayerError("Cannot call 'Player.lyrics()' without '@discord-player/extractor'"); const data = await extractor.Lyrics(query); if (Array.isArray(data)) return null; - return data as LyricsData; + return data; } /** @@ -931,7 +931,7 @@ export class Player extends EventEmitter { }; } - private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState) { + private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState): void { const queue = this.queues.find((g) => g.guildID === oldState.guild.id); if (!queue) return; @@ -964,7 +964,7 @@ export class Player extends EventEmitter { } } - private _addTrackToQueue(message: Message, track: Track) { + private _addTrackToQueue(message: Message, track: Track): Queue { const queue = this.getQueue(message); if (!queue) this.emit( @@ -978,7 +978,7 @@ export class Player extends EventEmitter { return queue; } - private _addTracksToQueue(message: Message, tracks: Track[]) { + private _addTracksToQueue(message: Message, tracks: Track[]): Queue { const queue = this.getQueue(message); if (!queue) throw new PlayerError( @@ -1174,3 +1174,109 @@ export class Player extends EventEmitter { } export default Player; + +/** + * Emitted when a track starts + * @event Player#trackStart + * @param {Discord.Message} message + * @param {Track} track + * @param {Queue} queue + */ + +/** + * Emitted when a playlist is started + * @event Player#queueCreate + * @param {Discord.Message} message + * @param {Queue} queue + */ + +/** + * Emitted when the bot is awaiting search results + * @event Player#searchResults + * @param {Discord.Message} message + * @param {string} query + * @param {Track[]} tracks + * @param {Discord.Collector} collector + */ + +/** + * Emitted when the user has sent an invalid response for search results + * @event Player#searchInvalidResponse + * @param {Discord.Message} message + * @param {string} query + * @param {Track[]} tracks + * @param {string} invalidResponse + * @param {Discord.MessageCollector} collector + */ + +/** + * Emitted when the bot has stopped awaiting search results (timeout) + * @event Player#searchCancel + * @param {Discord.Message} message + * @param {string} query + * @param {Track[]} tracks + */ + +/** + * Emitted when the bot can't find related results to the query + * @event Player#noResults + * @param {Discord.Message} message + * @param {string} query + */ + +/** + * Emitted when the bot is disconnected from the channel + * @event Player#botDisconnect + * @param {Discord.Message} message + */ + +/** + * Emitted when the channel of the bot is empty + * @event Player#channelEmpty + * @param {Discord.Message} message + * @param {Queue} queue + */ + +/** + * Emitted when the queue of the server is ended + * @event Player#queueEnd + * @param {Discord.Message} message + * @param {Queue} queue + */ + +/** + * Emitted when a track is added to the queue + * @event Player#trackAdd + * @param {Discord.Message} message + * @param {Queue} queue + * @param {Track} track + */ + +/** + * Emitted when a playlist is added to the queue + * @event Player#playlistAdd + * @param {Discord.Message} message + * @param {Queue} queue + * @param {Object} playlist + */ + +/** + * Emitted when an error is triggered + * @event Player#error + * @param {string} error It can be `NotConnected`, `UnableToJoin`, `NotPlaying`, `ParseError`, `LiveVideo` or `VideoUnavailable`. + * @param {Discord.Message} message + */ + +/** + * Emitted when discord-player attempts to parse playlist contents (mostly soundcloud playlists) + * @event Player#playlistParseStart + * @param {Object} playlist Raw playlist (unparsed) + * @param {Discord.Message} message The message + */ + +/** + * Emitted when discord-player finishes parsing playlist contents (mostly soundcloud playlists) + * @event Player#playlistParseEnd + * @param {Object} playlist The playlist data (parsed) + * @param {Discord.Message} message The message + */ \ No newline at end of file diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index 9242a5f..7838b96 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -4,13 +4,26 @@ class ExtractorModel { name: string; private _raw: any; + /** + * Model for raw Discord Player extractors + * @param extractorName Name of the extractor + * @param data Extractor object + */ constructor(extractorName: string, data: any) { + + /** + * The extractor name + */ this.name = extractorName; Object.defineProperty(this, '_raw', { value: data, configurable: false, writable: false, enumerable: false }); } - async handle(query: string) { + /** + * Method to handle requests from `Player.play()` + * @param query Query to handle + */ + async handle(query: string): Promise { const data = await this._raw.getInfo(query); if (!data) return null; @@ -23,18 +36,28 @@ class ExtractorModel { author: data.author, description: data.description, url: data.url - } as ExtractorModelData; + }; } - validate(query: string) { + /** + * Method used by Discord Player to validate query with this extractor + * @param query The query to validate + */ + validate(query: string): boolean { return Boolean(this._raw.validate(query)); } - get version() { + /** + * The extractor version + */ + get version(): string { return this._raw.version ?? '0.0.0'; } - get important() { + /** + * If player should mark this extractor as important + */ + get important(): boolean { return Boolean(this._raw.important); } } diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index b25cb12..64c2555 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -26,6 +26,11 @@ export class Queue extends EventEmitter { public firstMessage: Message; public autoPlay = false; + /** + * Queue constructor + * @param player The player that instantiated this Queue + * @param message The message object + */ constructor(player: Player, message: Message) { super(); @@ -91,40 +96,41 @@ export class Queue extends EventEmitter { */ this.firstMessage = message; - // @ts-ignore + /** + * The audio filters in this queue + */ this.filters = {}; Object.keys(AudioFilters).forEach((fn) => { - // @ts-ignore - this.filters[fn] = false; + this.filters[fn as keyof QueueFilters] = false; }); } /** * Currently playing track */ - get playing() { + get playing(): Track { return this.tracks[0]; } /** * Calculated volume of this queue */ - get calculatedVolume() { + get calculatedVolume(): number { return this.filters.normalizer ? this.volume + 70 : this.volume; } /** * Total duration */ - get totalTime() { + get totalTime(): number { return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0; } /** * Current stream time */ - get currentStreamTime() { + get currentStreamTime(): number { return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; } @@ -132,14 +138,14 @@ export class Queue extends EventEmitter { * Sets audio filters in this player * @param filters Audio filters to set */ - setFilters(filters: QueueFilters) { + setFilters(filters: QueueFilters): Promise { return this.player.setFilters(this.firstMessage, filters); } /** * Returns array of all enabled filters */ - getFiltersEnabled() { + getFiltersEnabled(): string[] { const filters: string[] = []; for (const filter in this.filters) { @@ -152,13 +158,16 @@ export class Queue extends EventEmitter { /** * Returns all disabled filters */ - getFiltersDisabled() { + getFiltersDisabled(): string[] { const enabled = this.getFiltersEnabled(); return Object.keys(this.filters).filter((f) => !enabled.includes(f)); } - toString() { + /** + * String representation of this Queue + */ + toString(): string { return ``; } } diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 70bea6b..31c4130 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -1,23 +1,69 @@ import { Player } from '../Player'; import { User } from 'discord.js'; import { TrackData } from '../types/types'; +import Queue from './Queue'; export class Track { /** * The player that instantiated this Track */ public player!: Player; + + /** + * Title of this track + */ public title!: string; + + /** + * Description of this track + */ public description!: string; + + /** + * Author of this track + */ public author!: string; + + /** + * Link of this track + */ public url!: string; + + /** + * Thumbnail of this track + */ public thumbnail!: string; + + /** + * Duration of this track + */ public duration!: string; + + /** + * View count of this track + */ public views!: number; + + /** + * Person who requested this track + */ public requestedBy!: User; + + /** + * If this track belongs to a playlist + */ public fromPlaylist!: boolean; + + /** + * Raw data of this track + */ public raw!: TrackData; + /** + * Track constructor + * @param player The player that instantiated this Track + * @param data Track data + */ constructor(player: Player, data: TrackData) { Object.defineProperty(this, 'player', { value: player, enumerable: false }); @@ -42,14 +88,14 @@ export class Track { /** * The queue in which this track is located */ - get queue() { + get queue(): Queue { return this.player.queues.find((q) => q.tracks.includes(this)); } /** * The track duration in millisecond */ - get durationMS() { + get durationMS(): number { const times = (n: number, t: number) => { let tn = 1; for (let i = 0; i < t; i++) tn *= n; @@ -63,7 +109,10 @@ export class Track { .reduce((a, c) => a + c, 0); } - toString() { + /** + * String representation of this track + */ + toString(): string { return `${this.title} by ${this.author}`; } } diff --git a/src/types/types.ts b/src/types/types.ts index 11d950b..f687a9a 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -145,3 +145,10 @@ export interface PlayerStats { uptime: number; }; } + +export interface TimeData { + days: number; + hours: number; + minutes: number; + seconds: number; +} \ No newline at end of file diff --git a/src/utils/Util.ts b/src/utils/Util.ts index a8af3b4..95af9aa 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -1,4 +1,4 @@ -import { QueryType } from '../types/types'; +import { QueryType, TimeData } from '../types/types'; import { FFmpeg } from 'prism-media'; import YouTube from 'youtube-sr'; import { Track } from '../Structures/Track'; @@ -19,7 +19,7 @@ export class Util { throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); } - static getFFmpegVersion(force?: boolean) { + static getFFmpegVersion(force?: boolean): string { try { const info = FFmpeg.getInfo(Boolean(force)); @@ -29,12 +29,12 @@ export class Util { } } - static checkFFmpeg(force?: boolean) { + static checkFFmpeg(force?: boolean): boolean { const version = Util.getFFmpegVersion(force); return version === null ? false : true; } - static alertFFmpeg() { + static alertFFmpeg(): void { const hasFFmpeg = Util.checkFFmpeg(); if (!hasFFmpeg) @@ -59,11 +59,11 @@ export class Util { return 'youtube_search'; } - static isURL(str: string) { + static isURL(str: string): boolean { return str.length < 2083 && attachmentRegex.test(str); } - static getVimeoID(query: string) { + static getVimeoID(query: string): string { return Util.getQueryType(query) === 'vimeo' ? query .split('/') @@ -72,7 +72,7 @@ export class Util { : null; } - static parseMS(milliseconds: number) { + static parseMS(milliseconds: number): TimeData { const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; return { @@ -83,7 +83,7 @@ export class Util { }; } - static durationString(durObj: object) { + static durationString(durObj: object): string { return Object.values(durObj) .map((m) => (isNaN(m) ? 0 : m)) .join(':'); @@ -119,7 +119,7 @@ export class Util { }); } - static isRepl() { + static isRepl(): boolean { if ('DP_REPL_NOCHECK' in process.env) return false; const REPL_IT_PROPS = [ @@ -137,11 +137,11 @@ export class Util { return false; } - static isVoiceEmpty(channel: VoiceChannel) { + static isVoiceEmpty(channel: VoiceChannel): boolean { return channel.members.filter((member) => !member.user.bot).size === 0; } - static buildTimeCode(data: any) { + static buildTimeCode(data: any): string { const items = Object.keys(data); const required = ['days', 'hours', 'minutes', 'seconds']; From 55a7d162db328c172001e0ede3c747148e1a0a62 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 19 Apr 2021 19:17:28 +0545 Subject: [PATCH 076/131] prettier --- src/Player.ts | 2 +- src/Structures/ExtractorModel.ts | 1 - src/types/types.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index b3d44ee..3c120ba 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1279,4 +1279,4 @@ export default Player; * @event Player#playlistParseEnd * @param {Object} playlist The playlist data (parsed) * @param {Discord.Message} message The message - */ \ No newline at end of file + */ diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index 7838b96..17756af 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -10,7 +10,6 @@ class ExtractorModel { * @param data Extractor object */ constructor(extractorName: string, data: any) { - /** * The extractor name */ diff --git a/src/types/types.ts b/src/types/types.ts index f687a9a..e1e885a 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -151,4 +151,4 @@ export interface TimeData { hours: number; minutes: number; seconds: number; -} \ No newline at end of file +} From c2b1e8861443eaf34c807d33ca8e97374e31421a Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Mon, 19 Apr 2021 15:59:17 +0200 Subject: [PATCH 077/131] :pencil: Some changes to readme --- README.md | 73 ++++++++++++++++++++++--------------------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 24e20e4..a18cce7 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,34 @@ client.on("message", async (message) => { client.login(settings.token); ``` -# Other Examples -## Using Cookies +## Supported websites + +By default, discord-player supports **YouTube**, **Spotify** and **SoundCloud** streams only. + +### Extractor API + +Discord Player provides an **Extractor API** that enables you to use your custom stream extractor with it. + +#### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) + +`@discord-player/extractor` is an optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. +You just need to install it via `npm i --save @discord-player/extractor` (discord-player will automatically detects and uses it). + +#### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) + +`@discord-player/downloader` is an optional package that brings support for +700 websites. The documentation is available [here](https://github.com/DevSnowflake/discord-player-downloader). + +## Examples of bots made with Discord Player + +These bots are made by the community, they can help you build your own! + +* [AtlantaBot](https://github.com/Androz2091/AtlantaBot) by [Androz2091](https://github.com/Androz2091) +* [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) +* [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) + +## FAQ + +### How to use cookies? ```js const player = new Player(client, { @@ -96,7 +122,7 @@ const player = new Player(client, { }); ``` -## Using Proxy +### How to use custom proxies? ```js const HttpsProxyAgent = require("https-proxy-agent"); @@ -111,44 +137,3 @@ const player = new Player(client, { } }); ``` - -# Sources supported -> By default, **discord-player** supports `youtube`, `spotify` and `soundcloud` streams only. - -**Discord Player** provides **Extractor API** that enables you to use your custom stream extractor with it. - -# Using @discord-player/extractor [optional] -> Adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics` - -**Discord Player** automatically detects and uses `@discord-player/extractor`. You just need to install it via `npm i --save @discord-player/extractor`. - -## Examples of bots made with Discord Player - -These bots are made by the community, they can help you build your own! - -* [AtlantaBot](https://github.com/Androz2091/AtlantaBot) by [Androz2091](https://github.com/Androz2091) -* [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) -* [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) - -# License -MIT License - -Copyright (c) 2020-present Androz - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From f4337ee0c9f421814c3275327485cbac5274aa7e Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Mon, 19 Apr 2021 16:01:36 +0200 Subject: [PATCH 078/131] :pencil: Some changes to README --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a18cce7..f9e7535 100644 --- a/README.md +++ b/README.md @@ -85,16 +85,16 @@ client.login(settings.token); By default, discord-player supports **YouTube**, **Spotify** and **SoundCloud** streams only. -### Extractor API +### Optional dependencies -Discord Player provides an **Extractor API** that enables you to use your custom stream extractor with it. +Discord Player provides an **Extractor API** that enables you to use your custom stream extractor with it. Some packages have been made by the community to add new features using this API. -#### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) +#### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) (optional) -`@discord-player/extractor` is an optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. -You just need to install it via `npm i --save @discord-player/extractor` (discord-player will automatically detects and uses it). +Optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. +You just need to install it using `npm i --save @discord-player/extractor` (discord-player will automatically detects and uses it). -#### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) +#### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) (optional) `@discord-player/downloader` is an optional package that brings support for +700 websites. The documentation is available [here](https://github.com/DevSnowflake/discord-player-downloader). From 536ccb90b286ae8e83332b75c80eefbc79435b5b Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Mon, 19 Apr 2021 16:11:38 +0200 Subject: [PATCH 079/131] :bug: Fix player error --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index 3c120ba..b1e321d 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -502,7 +502,7 @@ export class Player extends EventEmitter { setPosition(message: Message, time: number): Promise { return new Promise((resolve) => { const queue = this.queues.find((g) => g.guildID === message.guild.id); - if (!queue) return this.emit('error', 'NotPlaying', message); + if (!queue) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); if (typeof time !== 'number' && !isNaN(time)) time = parseInt(time); if (queue.playing.durationMS >= time) return this.skip(message); From 8c7bda9ca290458a86610bf5396a172eec33cbfe Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Mon, 19 Apr 2021 16:22:54 +0200 Subject: [PATCH 080/131] :bug: Fix auto play function name --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index b1e321d..e8d8493 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -891,7 +891,7 @@ export class Player extends EventEmitter { * @param message The message object * @param enable Enable/Disable autoplay */ - setAutoplay(message: Message, enable: boolean): void { + setAutoPlay(message: Message, enable: boolean): void { const queue = this.getQueue(message); if (!queue) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); From c2f3190f592051799320a4293324606cb115e344 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 19 Apr 2021 20:31:58 +0545 Subject: [PATCH 081/131] grammatical mistake --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9e7535..7171319 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ Discord Player provides an **Extractor API** that enables you to use your custom #### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) (optional) Optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. -You just need to install it using `npm i --save @discord-player/extractor` (discord-player will automatically detects and uses it). +You just need to install it using `npm i --save @discord-player/extractor` (discord-player will automatically detect and use it). #### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) (optional) From 893767a2118772882afd4c2acda3c93efa4c86ea Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Mon, 19 Apr 2021 20:39:47 +0545 Subject: [PATCH 082/131] setAutoPlay should return boolean --- src/Player.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index e8d8493..f978c61 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -891,11 +891,13 @@ export class Player extends EventEmitter { * @param message The message object * @param enable Enable/Disable autoplay */ - setAutoPlay(message: Message, enable: boolean): void { + setAutoPlay(message: Message, enable: boolean): boolean { const queue = this.getQueue(message); if (!queue) return void this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); queue.autoPlay = Boolean(enable); + + return queue.autoPlay; } /** From e1cc416c845c8c15754cd34708bdc1617ebab6b6 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Mon, 19 Apr 2021 17:44:37 +0200 Subject: [PATCH 083/131] :construction_worker: Fix publish workflow --- .github/workflows/npm-publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 8b152aa..36d7e35 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -14,6 +14,8 @@ jobs: with: node-version: 12 registry-url: https://registry.npmjs.org/ + - run: npm run install + - run: npm run build - run: npm publish env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} \ No newline at end of file From 9d5f06558292f6af1737e68bb38f098040bbc836 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 10:53:33 +0545 Subject: [PATCH 084/131] fix docs --- .gitignore | 3 + .npmignore | 1 + docs/extractors/extractor.md | 2 + docs/general/Welcome.md | 139 ++ docs/index.yml | 8 + jsdoc.json | 17 + package.json | 10 +- src/Player.ts | 103 +- src/Structures/ExtractorModel.ts | 11 +- src/Structures/Queue.ts | 31 +- src/Structures/Track.ts | 18 +- src/utils/AudioFilters.ts | 28 +- src/utils/Util.ts | 53 +- yarn.lock | 3109 +++++++++++++++++++++++++++++- 14 files changed, 3427 insertions(+), 106 deletions(-) create mode 100644 docs/extractors/extractor.md create mode 100644 docs/general/Welcome.md create mode 100644 docs/index.yml create mode 100644 jsdoc.json diff --git a/.gitignore b/.gitignore index 3d3e935..5faffcc 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ lib/ # error logs yarn-error.log + +# demo +demo/ \ No newline at end of file diff --git a/.npmignore b/.npmignore index 52dfa36..412f4d3 100644 --- a/.npmignore +++ b/.npmignore @@ -3,3 +3,4 @@ tslint.json tsconfig.json .prettierrc test/ +demo/ \ No newline at end of file diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md new file mode 100644 index 0000000..5e6fc9c --- /dev/null +++ b/docs/extractors/extractor.md @@ -0,0 +1,2 @@ +# Discord Player Extractor API +The extractor API \ No newline at end of file diff --git a/docs/general/Welcome.md b/docs/general/Welcome.md new file mode 100644 index 0000000..7171319 --- /dev/null +++ b/docs/general/Welcome.md @@ -0,0 +1,139 @@ +# Discord Player +Complete framework to facilitate music commands using **[discord.js](https://discord.js.org)**. + +[![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) +[![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) + +## Installation + +### Install **[discord-player](https://npmjs.com/package/discord-player)** + +```sh +$ npm install --save discord-player +``` + +### Install **[@discordjs/opus](https://npmjs.com/package/@discordjs/opus)** + +```sh +$ npm install --save @discordjs/opus +``` + +### Install FFmpeg or Avconv +- Official FFMPEG Website: **[https://www.ffmpeg.org/download.html](https://www.ffmpeg.org/download.html)** + +- Node Module (FFMPEG): **[https://npmjs.com/package/ffmpeg-static](https://npmjs.com/package/ffmpeg-static)** + +- Avconv: **[https://libav.org/download](https://libav.org/download)** + +# Features +- Simple & easy to use 🤘 +- Beginner friendly 😱 +- Audio filters 🎸 +- Lightweight 🛬 +- Custom extractors support 🌌 +- Lyrics 📃 +- Multiple sources support ✌ +- Play in multiple servers at the same time 🚗 + +## [Documentation](https://discord-player.js.org) + +## Getting Started + +Here is the code you will need to get started with discord-player. Then, you will be able to use `client.player` everywhere in your code! + +```js +const Discord = require("discord.js"), +client = new Discord.Client, +settings = { + prefix: "!", + token: "Your Discord Token" +}; + +const { Player } = require("discord-player"); + +// Create a new Player (you don't need any API Key) +const player = new Player(client); + +// To easily access the player +client.player = player; + +// add the trackStart event so when a song will be played this message will be sent +client.player.on("trackStart", (message, track) => message.channel.send(`Now playing ${track.title}...`)) + +client.once("ready", () => { + console.log("I'm ready !"); +}); + +client.on("message", async (message) => { + + const args = message.content.slice(settings.prefix.length).trim().split(/ +/g); + const command = args.shift().toLowerCase(); + + // !play Despacito + // will play "Despacito" in the voice channel + if(command === "play"){ + client.player.play(message, args[0]); + // as we registered the event above, no need to send a success message here + } + +}); + +client.login(settings.token); +``` + +## Supported websites + +By default, discord-player supports **YouTube**, **Spotify** and **SoundCloud** streams only. + +### Optional dependencies + +Discord Player provides an **Extractor API** that enables you to use your custom stream extractor with it. Some packages have been made by the community to add new features using this API. + +#### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) (optional) + +Optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. +You just need to install it using `npm i --save @discord-player/extractor` (discord-player will automatically detect and use it). + +#### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) (optional) + +`@discord-player/downloader` is an optional package that brings support for +700 websites. The documentation is available [here](https://github.com/DevSnowflake/discord-player-downloader). + +## Examples of bots made with Discord Player + +These bots are made by the community, they can help you build your own! + +* [AtlantaBot](https://github.com/Androz2091/AtlantaBot) by [Androz2091](https://github.com/Androz2091) +* [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) +* [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) + +## FAQ + +### How to use cookies? + +```js +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { + headers: { + cookie: "YOUR_YOUTUBE_COOKIE" + } + } + } +}); +``` + +### How to use custom proxies? + +```js +const HttpsProxyAgent = require("https-proxy-agent"); + +// Remove "user:pass@" if you don't need to authenticate to your proxy. +const proxy = "http://user:pass@111.111.111.111:8080"; +const agent = HttpsProxyAgent(proxy); + +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { agent } + } +}); +``` diff --git a/docs/index.yml b/docs/index.yml new file mode 100644 index 0000000..4d66eb1 --- /dev/null +++ b/docs/index.yml @@ -0,0 +1,8 @@ +- name: General + files: + - name: Welcome + path: welcome.md +- name: Extractors + files: + - name: Extractors + path: extractor.md \ No newline at end of file diff --git a/jsdoc.json b/jsdoc.json new file mode 100644 index 0000000..6aeb5e9 --- /dev/null +++ b/jsdoc.json @@ -0,0 +1,17 @@ +{ + "source": { + "includePattern": ".+\\.ts(doc|x)?$" + }, + "plugins": [ + "plugins/markdown", + "node_modules/jsdoc-babel" + ], + "babel": { + "extensions": ["ts"], + "babelrc": false, + "presets": [ + ["@babel/preset-env", { "targets": { "node": true } }], + "@babel/preset-typescript" + ] + } +} \ No newline at end of file diff --git a/package.json b/package.json index 2f65a75..8768789 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "test": "yarn build && cd test && node index.js", "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", - "lint": "tslint -p tsconfig.json" + "lint": "tslint -p tsconfig.json", + "docs": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml --output demo/docs.json", + "docs:test": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ @@ -45,11 +47,17 @@ "ytdl-core": "^4.5.0" }, "devDependencies": { + "@babel/cli": "^7.13.16", + "@babel/core": "^7.13.16", + "@babel/preset-env": "^7.13.15", + "@babel/preset-typescript": "^7.13.0", "@discord-player/extractor": "^2.0.0", "@discordjs/opus": "^0.5.0", "@types/node": "^14.14.41", "@types/ws": "^7.4.1", "discord.js": "^12.5.3", + "discord.js-docgen": "discordjs/docgen#ts-patch", + "jsdoc-babel": "^0.5.0", "prettier": "^2.2.1", "tslint": "^6.1.3", "tslint-config-prettier": "^1.18.0", diff --git a/src/Player.ts b/src/Player.ts index f978c61..fb60e95 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -28,13 +28,23 @@ const SoundCloud = new SoundCloudClient(); export class Player extends EventEmitter { /** * The discord client that instantiated this player + * @type {Discord.Client} */ public client!: Client; + + /** + * The player options + */ public options: PlayerOptionsType; + + /** + * The audio filters + */ public filters: typeof AudioFilters; /** * The collection of queues in this player + * @type {Discord.Collection} */ public queues = new Collection(); private _resultsCollectors = new Collection>(); @@ -42,13 +52,14 @@ export class Player extends EventEmitter { /** * The extractor model collection + * @type {Discord.Collection} */ public Extractors = new Collection(); /** * Creates new Player instance - * @param client The discord.js client - * @param options Player options + * @param {Discord.Client} client The discord.js client + * @param {PlayerOptionsType} options Player options */ constructor(client: Client, options?: PlayerOptionsType) { super(); @@ -58,17 +69,11 @@ export class Player extends EventEmitter { enumerable: false }); - /** - * The player options - */ this.options = Object.assign({}, PlayerOptions, options ?? {}); // check FFmpeg void Util.alertFFmpeg(); - /** - * The audio filters - */ this.filters = AudioFilters; this.client.on('voiceStateUpdate', (o, n) => void this._handleVoiceStateUpdate(o, n)); @@ -86,8 +91,8 @@ export class Player extends EventEmitter { /** * Define custom extractor in this player - * @param extractorName The extractor name - * @param extractor The extractor itself + * @param {string} extractorName The extractor name + * @param {any} extractor The extractor itself */ use(extractorName: string, extractor: any): Player { if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); @@ -106,7 +111,7 @@ export class Player extends EventEmitter { /** * Remove existing extractor from this player - * @param extractorName The extractor name + * @param {string} extractorName The extractor name */ unuse(extractorName: string): boolean { if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); @@ -359,9 +364,9 @@ export class Player extends EventEmitter { /** * Play a song - * @param message The discord.js message object - * @param query Search query, can be `Player.Track` instance - * @param firstResult If it should play the first result + * @param {Discord.Message} message The discord.js message object + * @param {string|Track} query Search query, can be `Player.Track` instance + * @param {boolean} [firstResult] If it should play the first result * @example await player.play(message, "never gonna give you up", true) */ async play(message: Message, query: string | Track, firstResult?: boolean): Promise { @@ -444,7 +449,7 @@ export class Player extends EventEmitter { /** * Checks if this player is playing in a server - * @param message The message object + * @param {Discord.Message} message The message object */ isPlaying(message: Message): boolean { return this.queues.some((g) => g.guildID === message.guild.id); @@ -452,7 +457,7 @@ export class Player extends EventEmitter { /** * Returns guild queue object - * @param message The message object + * @param {Discord.Message} message The message object */ getQueue(message: Message): Queue { return this.queues.find((g) => g.guildID === message.guild.id); @@ -460,8 +465,8 @@ export class Player extends EventEmitter { /** * Sets audio filters in this player - * @param message The message object - * @param newFilters Audio filters object + * @param {Discord.Message} message The message object + * @param {QueueFilters} newFilters Audio filters object */ setFilters(message: Message, newFilters: QueueFilters): Promise { return new Promise((resolve) => { @@ -495,9 +500,9 @@ export class Player extends EventEmitter { /** * Sets track position - * @param message The message object - * @param time Time in ms to set - * @alias seek + * @param {Discord.Message} message The message object + * @param {number} time Time in ms to set + * @alias Player.seek */ setPosition(message: Message, time: number): Promise { return new Promise((resolve) => { @@ -519,9 +524,9 @@ export class Player extends EventEmitter { /** * Sets track position - * @param message The message object - * @param time Time in ms to set - * @alias setPosition + * @param {Discord.Message} message The message object + * @param {number} time Time in ms to set + * @alias Player.setPosition */ seek(message: Message, time: number): Promise { return this.setPosition(message, time); @@ -529,7 +534,7 @@ export class Player extends EventEmitter { /** * Skips current track - * @param message The message object + * @param {Discord.Message} message The message object */ skip(message: Message): boolean { const queue = this.getQueue(message); @@ -550,8 +555,8 @@ export class Player extends EventEmitter { /** * Moves to a new voice channel - * @param message The message object - * @param channel New voice channel to move to + * @param {Discord.Message} message The message object + * @param {Discord.VoiceChannel} channel New voice channel to move to */ moveTo(message: Message, channel?: VoiceChannel): boolean { if (!channel || channel.type !== 'voice') return; @@ -577,7 +582,7 @@ export class Player extends EventEmitter { /** * Pause the playback - * @param message The message object + * @param {Discord.Message} message The message object */ pause(message: Message): boolean { const queue = this.getQueue(message); @@ -597,7 +602,7 @@ export class Player extends EventEmitter { /** * Resume the playback - * @param message The message object + * @param {Discord.Message} message The message object */ resume(message: Message): boolean { const queue = this.getQueue(message); @@ -617,7 +622,7 @@ export class Player extends EventEmitter { /** * Stops the player - * @param message The message object + * @param {Discord.Message} message The message object */ stop(message: Message): boolean { const queue = this.getQueue(message); @@ -641,8 +646,8 @@ export class Player extends EventEmitter { /** * Sets music volume - * @param message The message object - * @param percent The volume percentage/amount to set + * @param {Discord.Message} message The message object + * @param {number} percent The volume percentage/amount to set */ setVolume(message: Message, percent: number): boolean { const queue = this.getQueue(message); @@ -663,7 +668,7 @@ export class Player extends EventEmitter { /** * Clears the queue - * @param message The message object + * @param {Discord.Message} message The message object */ clearQueue(message: Message): boolean { const queue = this.getQueue(message); @@ -679,7 +684,7 @@ export class Player extends EventEmitter { /** * Plays previous track - * @param message The message object + * @param {Discord.Message} message The message object */ back(message: Message): boolean { const queue = this.getQueue(message); @@ -701,8 +706,8 @@ export class Player extends EventEmitter { /** * Sets repeat mode - * @param message The message object - * @param enabled If it should enable the repeat mode + * @param {Discord.Message} message The message object + * @param {boolean} enabled If it should enable the repeat mode */ setRepeatMode(message: Message, enabled: boolean): boolean { const queue = this.getQueue(message); @@ -718,8 +723,8 @@ export class Player extends EventEmitter { /** * Sets loop mode - * @param message The message object - * @param enabled If it should enable the loop mode + * @param {Discord.Message} message The message object + * @param {boolean} enabled If it should enable the loop mode */ setLoopMode(message: Message, enabled: boolean): boolean { const queue = this.getQueue(message); @@ -735,7 +740,7 @@ export class Player extends EventEmitter { /** * Returns currently playing track - * @param message The message object + * @param {Discord.Message} message The message object */ nowPlaying(message: Message): Track { const queue = this.getQueue(message); @@ -749,7 +754,7 @@ export class Player extends EventEmitter { /** * Shuffles the queue - * @param message The message object + * @param {Discord.Message} message The message object */ shuffle(message: Message): Queue { const queue = this.getQueue(message); @@ -772,8 +777,8 @@ export class Player extends EventEmitter { /** * Removes specified track - * @param message The message object - * @param track The track object/id to remove + * @param {Discord.Message} message The message object + * @param {Track|number} track The track object/id to remove */ remove(message: Message, track: Track | number): Track { const queue = this.getQueue(message); @@ -800,8 +805,8 @@ export class Player extends EventEmitter { /** * Returns time code of currently playing song - * @param message The message object - * @param queueTime If it should make the time code of the whole queue + * @param {Discord.Message} message The message object + * @param {boolean} [queueTime] If it should make the time code of the whole queue */ getTimeCode(message: Message, queueTime?: boolean): { current: string; end: string } { const queue = this.getQueue(message); @@ -824,8 +829,8 @@ export class Player extends EventEmitter { /** * Creates progressbar - * @param message The message object - * @param options Progressbar options + * @param {Discord.Message} message The message object + * @param {PlayerProgressbarOptions} [options] Progressbar options */ createProgressBar(message: Message, options?: PlayerProgressbarOptions): string { const queue = this.getQueue(message); @@ -872,7 +877,7 @@ export class Player extends EventEmitter { /** * Gets lyrics of a song - * @param query Search query + * @param {string} query Search query * @example const lyrics = await player.lyrics("alan walker faded") * message.channel.send(lyrics.lyrics); */ @@ -888,8 +893,8 @@ export class Player extends EventEmitter { /** * Toggle autoplay for youtube streams - * @param message The message object - * @param enable Enable/Disable autoplay + * @param {Discord.Message} message The message object + * @param {boolean} enable Enable/Disable autoplay */ setAutoPlay(message: Message, enable: boolean): boolean { const queue = this.getQueue(message); diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index 17756af..6c25fab 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -6,12 +6,13 @@ class ExtractorModel { /** * Model for raw Discord Player extractors - * @param extractorName Name of the extractor - * @param data Extractor object + * @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; @@ -20,7 +21,7 @@ class ExtractorModel { /** * Method to handle requests from `Player.play()` - * @param query Query to handle + * @param {string} query Query to handle */ async handle(query: string): Promise { const data = await this._raw.getInfo(query); @@ -40,7 +41,7 @@ class ExtractorModel { /** * Method used by Discord Player to validate query with this extractor - * @param query The query to validate + * @param {string} query The query to validate */ validate(query: string): boolean { return Boolean(this._raw.validate(query)); @@ -48,6 +49,7 @@ class ExtractorModel { /** * The extractor version + * @type {string} */ get version(): string { return this._raw.version ?? '0.0.0'; @@ -55,6 +57,7 @@ class ExtractorModel { /** * If player should mark this extractor as important + * @type {boolean} */ get important(): boolean { return Boolean(this._raw.important); diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 64c2555..41391a9 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -24,12 +24,16 @@ export class Queue extends EventEmitter { public filters: QueueFilters; public additionalStreamTime: number; public firstMessage: Message; + + /** + * @type {boolean} + */ public autoPlay = false; /** * Queue constructor - * @param player The player that instantiated this Queue - * @param message The message object + * @param {Player} player The player that instantiated this Queue + * @param {Discord.Message} message The message object */ constructor(player: Player, message: Message) { super(); @@ -38,66 +42,79 @@ export class Queue extends EventEmitter { /** * ID of the guild assigned to this queue + * @type {Discord.Snowflake} */ this.guildID = message.guild.id; /** * The voice connection of this queue + * @type {Discord.VoiceConnection} */ this.voiceConnection = null; /** * Tracks of this queue + * @type {Track[]} */ this.tracks = []; /** * Previous tracks of this queue + * @type {Track[]} */ this.previousTracks = []; /** * If the player of this queue is stopped + * @type {boolean} */ this.stopped = false; /** * If last track was skipped + * @type {boolean} */ this.lastSkipped = false; /** * Queue volume + * @type {number} */ this.volume = 100; /** * If the player of this queue is paused + * @type {boolean} */ this.paused = Boolean(this.voiceConnection?.dispatcher?.paused); /** * If repeat mode is enabled in this queue + * @type {boolean} */ this.repeatMode = false; /** * If loop mode is enabled in this queue + * @type {boolean} */ this.loopMode = false; /** * The additional calculated stream time + * @type {number} */ this.additionalStreamTime = 0; /** * The initial message object + * @type {Discord.Message} */ this.firstMessage = message; /** * The audio filters in this queue + * @type {QueueFilters} */ this.filters = {}; @@ -108,6 +125,7 @@ export class Queue extends EventEmitter { /** * Currently playing track + * @type {Track} */ get playing(): Track { return this.tracks[0]; @@ -115,6 +133,7 @@ export class Queue extends EventEmitter { /** * Calculated volume of this queue + * @type {number} */ get calculatedVolume(): number { return this.filters.normalizer ? this.volume + 70 : this.volume; @@ -122,6 +141,7 @@ export class Queue extends EventEmitter { /** * Total duration + * @type {number} */ get totalTime(): number { return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0; @@ -129,6 +149,7 @@ export class Queue extends EventEmitter { /** * Current stream time + * @type {number} */ get currentStreamTime(): number { return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; @@ -136,7 +157,8 @@ export class Queue extends EventEmitter { /** * Sets audio filters in this player - * @param filters Audio filters to set + * @param {QueueFilters} filters Audio filters to set + * @type {Promise} */ setFilters(filters: QueueFilters): Promise { return this.player.setFilters(this.firstMessage, filters); @@ -144,6 +166,7 @@ export class Queue extends EventEmitter { /** * Returns array of all enabled filters + * @type {string[]} */ getFiltersEnabled(): string[] { const filters: string[] = []; @@ -157,6 +180,7 @@ export class Queue extends EventEmitter { /** * Returns all disabled filters + * @type {string[]} */ getFiltersDisabled(): string[] { const enabled = this.getFiltersEnabled(); @@ -166,6 +190,7 @@ export class Queue extends EventEmitter { /** * String representation of this Queue + * @type {string} */ toString(): string { return ``; diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 31c4130..10c98e2 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -6,63 +6,74 @@ import Queue from './Queue'; export class Track { /** * The player that instantiated this Track + * @type {Player} */ public player!: Player; /** * Title of this track + * @type {string} */ public title!: string; /** * Description of this track + * @type {string} */ public description!: string; /** * Author of this track + * @type {string} */ public author!: string; /** * Link of this track + * @type {string} */ public url!: string; /** * Thumbnail of this track + * @type {string} */ public thumbnail!: string; /** * Duration of this track + * @type {string} */ public duration!: string; /** * View count of this track + * @type {number} */ public views!: number; /** * Person who requested this track + * @type {Discord.User} */ public requestedBy!: User; /** * If this track belongs to a playlist + * @type {boolean} */ public fromPlaylist!: boolean; /** * Raw data of this track + * @type {TrackData} */ public raw!: TrackData; /** * Track constructor - * @param player The player that instantiated this Track - * @param data Track data + * @param {Player} player The player that instantiated this Track + * @param {TrackData} data Track data */ constructor(player: Player, data: TrackData) { Object.defineProperty(this, 'player', { value: player, enumerable: false }); @@ -87,6 +98,7 @@ export class Track { /** * The queue in which this track is located + * @type {Queue} */ get queue(): Queue { return this.player.queues.find((q) => q.tracks.includes(this)); @@ -94,6 +106,7 @@ export class Track { /** * The track duration in millisecond + * @type {number} */ get durationMS(): number { const times = (n: number, t: number) => { @@ -111,6 +124,7 @@ export class Track { /** * String representation of this track + * @type {string} */ toString(): string { return `${this.title} by ${this.author}`; diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 153c13a..1f03c58 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -47,11 +47,7 @@ const FilterList = { return `${Object.values(this).join(',')}`; }, - /** - * Creates single string of audio filters - * @param filter Array of AudioFilters name - */ - create(filter?: FiltersName[]) { + create(filter?: FiltersName[]): string { if (!filter || !Array.isArray(filter)) return this.toString(); return filter .filter((predicate) => typeof predicate === 'string') @@ -59,27 +55,13 @@ const FilterList = { .join(','); }, - /** - * Defines custom filter - * @param filterName The filter name - * @param value FFmpeg args to use with -af - * @example Player.AudioFilters.define("3D", "apulsator=hz=0.125") - * - * player.setFilters(message, { "3D": true }) - */ - define(filterName: string, value: string) { - /* @ts-ignore */ - if (typeof this[filterName] && typeof this[filterName] === 'function') return; + define(filterName: string, value: string): void { + if (typeof this[filterName as FiltersName] && typeof this[filterName as FiltersName] === 'function') return; - /* @ts-ignore */ - this[filterName] = value; + this[filterName as FiltersName] = value; }, - /** - * Defines filters in bulk - * @param filterArray Array of filters containing object with `name` and `value` prop - */ - defineBulk(filterArray: { name: string; value: string }[]) { + defineBulk(filterArray: { name: string; value: string }[]): void { filterArray.forEach((arr) => this.define(arr.name, arr.value)); } }; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index 95af9aa..e3645d8 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -15,10 +15,17 @@ const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/; const attachmentRegex = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/; export class Util { + /** + * Static Player Util class + */ constructor() { throw new Error(`The ${this.constructor.name} class is static and cannot be instantiated!`); } + /** + * Checks FFmpeg Version + * @param {boolean} [force] If it should forcefully get the version + */ static getFFmpegVersion(force?: boolean): string { try { const info = FFmpeg.getInfo(Boolean(force)); @@ -29,11 +36,18 @@ export class Util { } } + /** + * Checks FFmpeg + * @param {boolean} [force] If it should forcefully get the version + */ static checkFFmpeg(force?: boolean): boolean { const version = Util.getFFmpegVersion(force); return version === null ? false : true; } + /** + * Alerts if FFmpeg is not available + */ static alertFFmpeg(): void { const hasFFmpeg = Util.checkFFmpeg(); @@ -43,6 +57,10 @@ export class Util { ); } + /** + * Resolves query type + * @param {string} query The query + */ static getQueryType(query: string): QueryType { if (SoundcloudValidateURL(query) && !query.includes('/sets/')) return 'soundcloud_track'; if (SoundcloudValidateURL(query) && query.includes('/sets/')) return 'soundcloud_playlist'; @@ -59,10 +77,18 @@ export class Util { return 'youtube_search'; } + /** + * Checks if the given string is url + * @param {string} str URL to check + */ static isURL(str: string): boolean { return str.length < 2083 && attachmentRegex.test(str); } + /** + * Returns Vimeo ID + * @param {string} query Vimeo link + */ static getVimeoID(query: string): string { return Util.getQueryType(query) === 'vimeo' ? query @@ -72,6 +98,10 @@ export class Util { : null; } + /** + * Parses ms time + * @param {number} milliseconds Time to parse + */ static parseMS(milliseconds: number): TimeData { const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; @@ -83,12 +113,22 @@ export class Util { }; } + /** + * Creates simple duration string + * @param {object} durObj Duration object + */ static durationString(durObj: object): string { return Object.values(durObj) .map((m) => (isNaN(m) ? 0 : m)) .join(':'); } + /** + * Makes youtube searches + * @param {string} query The query + * @param {any} options Options + * @returns {Promise} + */ static ytSearch(query: string, options?: any): Promise { return new Promise(async (resolve) => { await YouTube.search(query, { @@ -119,6 +159,9 @@ export class Util { }); } + /** + * Checks if this system is running in replit.com + */ static isRepl(): boolean { if ('DP_REPL_NOCHECK' in process.env) return false; @@ -137,10 +180,18 @@ export class Util { return false; } + /** + * Checks if the given voice channel is empty + * @param {Discord.VoiceChannel} channel The voice channel + */ static isVoiceEmpty(channel: VoiceChannel): boolean { return channel.members.filter((member) => !member.user.bot).size === 0; } + /** + * Builds time code + * @param {object} data The data to build time code from + */ static buildTimeCode(data: any): string { const items = Object.keys(data); const required = ['days', 'hours', 'minutes', 'seconds']; @@ -155,7 +206,7 @@ export class Util { /** * Manage CJS require - * @param id id to require + * @param {string} id id to require */ static require(id: string): any { try { diff --git a/yarn.lock b/yarn.lock index 6569a5f..8b2d9c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,18 +2,262 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": +"@babel/cli@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.13.16.tgz#9d372e943ced0cc291f068204a9b010fd9cfadbc" + integrity sha512-cL9tllhqvsQ6r1+d9Invf7nNXg/3BlfL1vvvL/AdH9fZ2l5j0CeBcoq6UjsqHpvyN1v5nXSZgqJZoGeK+ZOAbw== + dependencies: + commander "^4.0.1" + convert-source-map "^1.1.0" + fs-readdir-recursive "^1.1.0" + glob "^7.0.0" + make-dir "^2.1.0" + slash "^2.0.0" + source-map "^0.5.0" + optionalDependencies: + "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents" + chokidar "^3.4.0" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== dependencies: "@babel/highlight" "^7.12.13" +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.15.tgz#7e8eea42d0b64fda2b375b22d06c605222e848f4" + integrity sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA== + +"@babel/core@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.16.tgz#7756ab24396cc9675f1c3fcd5b79fcce192ea96a" + integrity sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.16" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.13.14" + "@babel/helpers" "^7.13.16" + "@babel/parser" "^7.13.16" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.16.tgz#0befc287031a201d84cdfc173b46b320ae472d14" + integrity sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg== + dependencies: + "@babel/types" "^7.13.16" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" + integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc" + integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.13", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" + integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== + dependencies: + "@babel/compat-data" "^7.13.15" + "@babel/helper-validator-option" "^7.12.17" + browserslist "^4.14.5" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.13.0": + version "7.13.11" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" + integrity sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.0" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-replace-supers" "^7.13.0" + "@babel/helper-split-export-declaration" "^7.12.13" + +"@babel/helper-create-regexp-features-plugin@^7.12.13": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" + integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + regexpu-core "^4.7.1" + +"@babel/helper-define-polyfill-provider@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz#a640051772045fedaaecc6f0c6c69f02bdd34bf1" + integrity sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-explode-assignable-expression@^7.12.13": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" + integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== + dependencies: + "@babel/types" "^7.13.0" + +"@babel/helper-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" + integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== + dependencies: + "@babel/helper-get-function-arity" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/helper-get-function-arity@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" + integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-hoist-variables@^7.13.0": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" + integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== + dependencies: + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" + +"@babel/helper-member-expression-to-functions@^7.13.0", "@babel/helper-member-expression-to-functions@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" + integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" + integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.13.14": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" + integrity sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g== + dependencies: + "@babel/helper-module-imports" "^7.13.12" + "@babel/helper-replace-supers" "^7.13.12" + "@babel/helper-simple-access" "^7.13.12" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/helper-validator-identifier" "^7.12.11" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.13" + "@babel/types" "^7.13.14" + +"@babel/helper-optimise-call-expression@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea" + integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA== + dependencies: + "@babel/types" "^7.12.13" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== + +"@babel/helper-remap-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" + integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-wrap-function" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" + integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.13.12" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.12" + +"@babel/helper-simple-access@^7.12.13", "@babel/helper-simple-access@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" + integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== + dependencies: + "@babel/types" "^7.13.12" + +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== + dependencies: + "@babel/types" "^7.12.1" + +"@babel/helper-split-export-declaration@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05" + integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg== + dependencies: + "@babel/types" "^7.12.13" + "@babel/helper-validator-identifier@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== +"@babel/helper-validator-option@^7.12.17": + version "7.12.17" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" + integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== + +"@babel/helper-wrap-function@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" + integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" + +"@babel/helpers@^7.13.16": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.17.tgz#b497c7a00e9719d5b613b8982bda6ed3ee94caf6" + integrity sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg== + dependencies: + "@babel/template" "^7.12.13" + "@babel/traverse" "^7.13.17" + "@babel/types" "^7.13.17" + "@babel/highlight@^7.12.13": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" @@ -23,6 +267,610 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/parser@^7.12.13", "@babel/parser@^7.13.16", "@babel/parser@^7.9.4": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.16.tgz#0f18179b0448e6939b1f3f5c4c355a3a9bcdfd37" + integrity sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw== + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" + integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" + +"@babel/plugin-proposal-async-generator-functions@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz#80e549df273a3b3050431b148c892491df1bcc5b" + integrity sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" + integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-proposal-dynamic-import@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" + integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" + integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" + integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" + integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" + integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" + integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" + integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== + dependencies: + "@babel/compat-data" "^7.13.8" + "@babel/helper-compilation-targets" "^7.13.8" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.13.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" + integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.13.12": + version "7.13.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" + integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" + integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" + integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" + integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-typescript@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz#9dff111ca64154cef0f4dc52cf843d9f12ce4474" + integrity sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-arrow-functions@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" + integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" + integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== + dependencies: + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + +"@babel/plugin-transform-block-scoped-functions@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4" + integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-block-scoping@^7.12.13": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.13.16.tgz#a9c0f10794855c63b1d629914c7dcfeddd185892" + integrity sha512-ad3PHUxGnfWF4Efd3qFuznEtZKoBp0spS+DgqzVzRPV7urEBvPLue3y2j80w4Jf2YLzZHj8TOv/Lmvdmh3b2xg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-classes@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" + integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-optimise-call-expression" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-replace-supers" "^7.13.0" + "@babel/helper-split-export-declaration" "^7.12.13" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" + integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-destructuring@^7.13.0": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz#678d96576638c19d5b36b332504d3fd6e06dea27" + integrity sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad" + integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-duplicate-keys@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de" + integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-exponentiation-operator@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1" + integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-for-of@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" + integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-function-name@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051" + integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ== + dependencies: + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9" + integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-member-expression-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40" + integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-modules-amd@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz#19f511d60e3d8753cc5a6d4e775d3a5184866cc3" + integrity sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ== + dependencies: + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b" + integrity sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw== + dependencies: + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-simple-access" "^7.12.13" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" + integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== + dependencies: + "@babel/helper-hoist-variables" "^7.13.0" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-identifier" "^7.12.11" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz#8a3d96a97d199705b9fd021580082af81c06e70b" + integrity sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw== + dependencies: + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9" + integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + +"@babel/plugin-transform-new-target@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c" + integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-object-super@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7" + integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-replace-supers" "^7.12.13" + +"@babel/plugin-transform-parameters@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" + integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-property-literals@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81" + integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-regenerator@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" + integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695" + integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-shorthand-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad" + integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-spread@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" + integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + +"@babel/plugin-transform-sticky-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f" + integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-template-literals@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" + integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + +"@babel/plugin-transform-typeof-symbol@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f" + integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-typescript@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853" + integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-typescript" "^7.12.13" + +"@babel/plugin-transform-unicode-escapes@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74" + integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-transform-unicode-regex@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac" + integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.13" + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/preset-env@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.15.tgz#c8a6eb584f96ecba183d3d414a83553a599f478f" + integrity sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA== + dependencies: + "@babel/compat-data" "^7.13.15" + "@babel/helper-compilation-targets" "^7.13.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-async-generator-functions" "^7.13.15" + "@babel/plugin-proposal-class-properties" "^7.13.0" + "@babel/plugin-proposal-dynamic-import" "^7.13.8" + "@babel/plugin-proposal-export-namespace-from" "^7.12.13" + "@babel/plugin-proposal-json-strings" "^7.13.8" + "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" + "@babel/plugin-proposal-numeric-separator" "^7.12.13" + "@babel/plugin-proposal-object-rest-spread" "^7.13.8" + "@babel/plugin-proposal-optional-catch-binding" "^7.13.8" + "@babel/plugin-proposal-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-private-methods" "^7.13.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.12.13" + "@babel/plugin-transform-arrow-functions" "^7.13.0" + "@babel/plugin-transform-async-to-generator" "^7.13.0" + "@babel/plugin-transform-block-scoped-functions" "^7.12.13" + "@babel/plugin-transform-block-scoping" "^7.12.13" + "@babel/plugin-transform-classes" "^7.13.0" + "@babel/plugin-transform-computed-properties" "^7.13.0" + "@babel/plugin-transform-destructuring" "^7.13.0" + "@babel/plugin-transform-dotall-regex" "^7.12.13" + "@babel/plugin-transform-duplicate-keys" "^7.12.13" + "@babel/plugin-transform-exponentiation-operator" "^7.12.13" + "@babel/plugin-transform-for-of" "^7.13.0" + "@babel/plugin-transform-function-name" "^7.12.13" + "@babel/plugin-transform-literals" "^7.12.13" + "@babel/plugin-transform-member-expression-literals" "^7.12.13" + "@babel/plugin-transform-modules-amd" "^7.13.0" + "@babel/plugin-transform-modules-commonjs" "^7.13.8" + "@babel/plugin-transform-modules-systemjs" "^7.13.8" + "@babel/plugin-transform-modules-umd" "^7.13.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" + "@babel/plugin-transform-new-target" "^7.12.13" + "@babel/plugin-transform-object-super" "^7.12.13" + "@babel/plugin-transform-parameters" "^7.13.0" + "@babel/plugin-transform-property-literals" "^7.12.13" + "@babel/plugin-transform-regenerator" "^7.13.15" + "@babel/plugin-transform-reserved-words" "^7.12.13" + "@babel/plugin-transform-shorthand-properties" "^7.12.13" + "@babel/plugin-transform-spread" "^7.13.0" + "@babel/plugin-transform-sticky-regex" "^7.12.13" + "@babel/plugin-transform-template-literals" "^7.13.0" + "@babel/plugin-transform-typeof-symbol" "^7.12.13" + "@babel/plugin-transform-unicode-escapes" "^7.12.13" + "@babel/plugin-transform-unicode-regex" "^7.12.13" + "@babel/preset-modules" "^0.1.4" + "@babel/types" "^7.13.14" + babel-plugin-polyfill-corejs2 "^0.2.0" + babel-plugin-polyfill-corejs3 "^0.2.0" + babel-plugin-polyfill-regenerator "^0.2.0" + core-js-compat "^3.9.0" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-typescript@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.13.0.tgz#ab107e5f050609d806fbb039bec553b33462c60a" + integrity sha512-LXJwxrHy0N3f6gIJlYbLta1D9BDtHpQeqwzM0LIfjDlr6UE/D5Mc7W4iDiQzaE+ks0sTjT26ArcHWnJVt0QiHw== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-validator-option" "^7.12.17" + "@babel/plugin-transform-typescript" "^7.13.0" + +"@babel/runtime@^7.8.4": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec" + integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" + integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/parser" "^7.12.13" + "@babel/types" "^7.12.13" + +"@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.13.15", "@babel/traverse@^7.13.17": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.17.tgz#c85415e0c7d50ac053d758baec98b28b2ecfeea3" + integrity sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.16" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.13.16" + "@babel/types" "^7.13.17" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.14", "@babel/types@^7.13.16", "@babel/types@^7.13.17", "@babel/types@^7.4.4": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.17.tgz#48010a115c9fba7588b4437dd68c9469012b38b4" + integrity sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + to-fast-properties "^2.0.0" + "@discord-player/extractor@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@discord-player/extractor/-/extractor-2.0.0.tgz#3879e51d64b72d4dcee9338bdece5251d006c746" @@ -70,6 +918,23 @@ "@discordjs/node-pre-gyp" "^0.3.2" node-addon-api "^3.1.0" +"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": + version "2.1.8-no-fsevents" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" + integrity sha512-+nb9vWloHNNMFHjGofEam3wopE3m1yuambrrd/fnPc+lFOMB9ROTqQlche9ByFWNkdNqfSgR/kkQtQ8DzEWt2w== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -112,6 +977,11 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" +acorn-jsx@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" @@ -134,7 +1004,7 @@ agent-base@6: dependencies: debug "4" -ajv@^6.12.3: +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -144,6 +1014,20 @@ ajv@^6.12.3: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-escape-sequences@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz#2483c8773f50dd9174dd9557e92b1718f1816097" + integrity sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw== + dependencies: + array-back "^3.0.1" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -154,13 +1038,46 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-styles@^3.2.1: +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -181,6 +1098,50 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-back@^1.0.2, array-back@^1.0.3, array-back@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-1.0.4.tgz#644ba7f095f7ffcf7c43b5f0dc39d3c1f03c063b" + integrity sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs= + dependencies: + typical "^2.6.0" + +array-back@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-2.0.0.tgz#6877471d51ecc9c9bfa6136fb6c7d5fe69748022" + integrity sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw== + dependencies: + typical "^2.6.1" + +array-back@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== + +array-back@^4.0.0, array-back@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.1.tgz#9b80312935a52062e1a233a9c7abeb5481b30e90" + integrity sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -193,11 +1154,31 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -215,11 +1196,55 @@ axios@^0.21.1: dependencies: follow-redirects "^1.10.0" +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-polyfill-corejs2@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz#686775bf9a5aa757e10520903675e3889caeedc4" + integrity sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.2.0" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz#f4b4bb7b19329827df36ff56f6e6d367026cb7a2" + integrity sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.0" + core-js-compat "^3.9.1" + +babel-plugin-polyfill-regenerator@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz#853f5f5716f4691d98c84f8069c7636ea8da7ab8" + integrity sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -227,6 +1252,21 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -240,22 +1280,110 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + browser-process-hrtime@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== +browserslist@^4.14.5, browserslist@^4.16.4: + version "4.16.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.4.tgz#7ebf913487f40caf4637b892b268069951c35d58" + integrity sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ== + dependencies: + caniuse-lite "^1.0.30001208" + colorette "^1.2.2" + electron-to-chromium "^1.3.712" + escalade "^3.1.1" + node-releases "^1.1.71" + builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cache-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cache-point/-/cache-point-1.0.0.tgz#3d9769fc04d7a5b3005fc6258e6ebcaccb5f15f3" + integrity sha512-ZqrZp9Hi5Uq7vfSGmNP2bUT/9DzZC2Y/GXjHB8rUJN1a+KLmbV05+vxHipNsg8+CSVgjcVVzLV8VZms6w8ZeRw== + dependencies: + array-back "^4.0.0" + fs-then-native "^2.0.0" + mkdirp2 "^1.0.4" + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001208: + version "1.0.30001214" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz#70f153c78223515c6d37a9fde6cd69250da9d872" + integrity sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg== + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@^2.0.0, chalk@^2.3.0: +catharsis@^0.8.11: + version "0.8.11" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.11.tgz#d0eb3d2b82b7da7a3ce2efb1a7b00becc6643468" + integrity sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g== + dependencies: + lodash "^4.17.14" + +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -264,6 +1392,19 @@ chalk@^2.0.0, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + cheerio-select-tmp@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646" @@ -288,16 +1429,78 @@ cheerio@^1.0.0-rc.3: parse5 "^6.0.0" parse5-htmlparser2-tree-adapter "^6.0.0" +chokidar@^3.4.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= +collect-all@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/collect-all/-/collect-all-1.0.4.tgz#50cd7119ac24b8e12a661f0f8c3aa0ea7222ddfc" + integrity sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA== + dependencies: + stream-connect "^1.0.2" + stream-via "^1.0.4" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -305,11 +1508,28 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -317,21 +1537,94 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +command-line-args@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.1.1.tgz#88e793e5bb3ceb30754a86863f0401ac92fd369a" + integrity sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg== + dependencies: + array-back "^3.0.1" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +command-line-tool@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/command-line-tool/-/command-line-tool-0.8.0.tgz#b00290ef1dfc11cc731dd1f43a92cfa5f21e715b" + integrity sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g== + dependencies: + ansi-escape-sequences "^4.0.0" + array-back "^2.0.0" + command-line-args "^5.0.0" + command-line-usage "^4.1.0" + typical "^2.6.1" + +command-line-usage@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-4.1.0.tgz#a6b3b2e2703b4dcf8bd46ae19e118a9a52972882" + integrity sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g== + dependencies: + ansi-escape-sequences "^4.0.0" + array-back "^2.0.0" + table-layout "^0.4.2" + typical "^2.6.1" + commander@^2.12.1: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +common-sequence@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/common-sequence/-/common-sequence-2.0.2.tgz#accc76bdc5876a1fcd92b73484d4285fff99d838" + integrity sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +config-master@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/config-master/-/config-master-3.1.0.tgz#667663590505a283bf26a484d68489d74c5485da" + integrity sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo= + dependencies: + walk-back "^2.0.1" + console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +convert-source-map@^1.1.0, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js-compat@^3.9.0, core-js-compat@^3.9.1: + version "3.10.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.10.2.tgz#0a675b4e1cde599616322a72c8886bcf696f3ec3" + integrity sha512-IGHnpuaM1N++gLSPI1F1wu3WXICPxSyj/Q++clcwsIOnUVp5uKUIPl/+6h0TQ112KU3fMiSxqJuM+OrCyKj5+A== + dependencies: + browserslist "^4.16.4" + semver "7.0.0" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -344,6 +1637,17 @@ cross-fetch@^3.0.5: dependencies: node-fetch "2.6.1" +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + css-select@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" @@ -393,23 +1697,74 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -debug@4: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + decimal.js@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-extend@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -437,6 +1792,16 @@ discord-ytdl-core@^5.0.2: dependencies: prism-media "^1.2.7" +discord.js-docgen@discordjs/docgen#ts-patch: + version "0.9.0" + resolved "https://codeload.github.com/discordjs/docgen/tar.gz/9c58620ea4fcdeda432a1370d4333e8537b37491" + dependencies: + eslint "^6.3.0" + js-yaml "^3.13.1" + jsdoc-to-markdown "^5.0.1" + tsubaki "^1.3.2" + yargs "^14.0.0" + discord.js@^12.5.3: version "12.5.3" resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-12.5.3.tgz#56820d473c24320871df9ea0bbc6b462f21cf85c" @@ -451,6 +1816,31 @@ discord.js@^12.5.3: tweetnacl "^1.0.3" ws "^7.4.4" +dmd@^4.0.5: + version "4.0.6" + resolved "https://registry.yarnpkg.com/dmd/-/dmd-4.0.6.tgz#c533cae847307984527263a4b41a1c6e3ef344a2" + integrity sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ== + dependencies: + array-back "^4.0.1" + cache-point "^1.0.0" + common-sequence "^2.0.0" + file-set "^3.0.0" + handlebars "^4.5.3" + marked "^0.7.0" + object-get "^2.1.0" + reduce-flatten "^3.0.0" + reduce-unique "^2.0.1" + reduce-without "^1.0.1" + test-value "^3.0.0" + walk-back "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + dom-serializer@^1.0.1, dom-serializer@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1" @@ -496,21 +1886,51 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +electron-to-chromium@^1.3.712: + version "1.3.718" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.718.tgz#a192981ced608978410ebc011e24ecab1bb4beb3" + integrity sha512-CikzdUSShGXwjq1pcW740wK8j+KbazgHZiwzlHICejDaczM6OVsPcrZmBHPwzj9i2rj5twg20MBwp+cYZwldYA== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + entities@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +entities@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + entities@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escodegen@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" @@ -523,12 +1943,103 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" +eslint-scope@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint@^6.3.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^7.0.0" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -estraverse@^5.2.0: +esquery@^1.0.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== @@ -543,11 +2054,62 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -573,11 +2135,91 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-set@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/file-set/-/file-set-2.0.1.tgz#db9bc4b70a7e5ba81c9d279c20a37f13369c7850" + integrity sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA== + dependencies: + array-back "^2.0.0" + glob "^7.1.3" + +file-set@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/file-set/-/file-set-3.0.0.tgz#85e689c7fe7b95bdd7e11bab0dd50488cd8e01be" + integrity sha512-B/SdeSIeRv7VlOgIjtH3dkxMI+tEy5m+OeCXfAUsirBoVoY+bGtsmvmmTFPm/G23TBY4RiTtjpcgePCfwXRjqA== + dependencies: + array-back "^4.0.0" + glob "^7.1.5" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + follow-redirects@^1.10.0: version "1.13.3" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA== +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -592,6 +2234,13 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -599,16 +2248,36 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" +fs-readdir-recursive@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + +fs-then-native@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fs-then-native/-/fs-then-native-2.0.0.tgz#19a124d94d90c22c8e045f2e8dd6ebea36d48c67" + integrity sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc= + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -631,6 +2300,30 @@ genius-lyrics@^4.2.7: axios "^0.21.1" node-html-parser "^3.0.4" +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -638,7 +2331,22 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob@^7.1.1, glob@^7.1.3: +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.0.0, glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.5: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -650,6 +2358,35 @@ glob@^7.1.1, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.9: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +handlebars@^4.5.3: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -668,11 +2405,52 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -725,13 +2503,31 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" -iconv-lite@0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-fresh@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -740,11 +2536,63 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inquirer@^7.0.0: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + is-core-module@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" @@ -752,6 +2600,55 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -764,6 +2661,44 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + is-potential-custom-element-name@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" @@ -774,16 +2709,38 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -isarray@~1.0.0: +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + iso8601-duration@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/iso8601-duration/-/iso8601-duration-1.3.0.tgz#29d7b69e0574e4acdee50c5e5e09adab4137ba5a" integrity sha512-K4CiUBzo3YeWk76FuET/dQPH03WE04R94feo5TSKQCXpoXQt9E4yx2CnY737QZnSAI3PI4WlKo/zfqizGx52QQ== +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -802,11 +2759,91 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js2xmlparser@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.1.tgz#670ef71bc5661f089cc90481b99a05a1227ae3bd" + integrity sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw== + dependencies: + xmlcreate "^2.0.3" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsdoc-api@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/jsdoc-api/-/jsdoc-api-5.0.4.tgz#6b60cddaa4e7ff9a2e139acfc19ecaa9c48f8575" + integrity sha512-1KMwLnfo0FyhF06TQKzqIm8BiY1yoMIGICxRdJHUjzskaHMzHMmpLlmNFgzoa4pAC8t1CDPK5jWuQTvv1pBsEQ== + dependencies: + array-back "^4.0.0" + cache-point "^1.0.0" + collect-all "^1.0.3" + file-set "^2.0.1" + fs-then-native "^2.0.0" + jsdoc "^3.6.3" + object-to-spawn-args "^1.1.1" + temp-path "^1.0.0" + walk-back "^3.0.1" + +jsdoc-babel@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsdoc-babel/-/jsdoc-babel-0.5.0.tgz#7217b8820469fe600dccfdee895648c6a0dd4a2e" + integrity sha512-PYfTbc3LNTeR8TpZs2M94NLDWqARq0r9gx3SvuziJfmJS7/AeMKvtj0xjzOX0R/4MOVA7/FqQQK7d6U0iEoztQ== + dependencies: + jsdoc-regex "^1.0.1" + lodash "^4.17.10" + +jsdoc-parse@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsdoc-parse/-/jsdoc-parse-4.0.1.tgz#07949b13b1659c2bbc5217560d77b46a060cb86d" + integrity sha512-qIObw8yqYZjrP2qxWROB5eLQFLTUX2jRGLhW9hjo2CC2fQVlskidCIzjCoctwsDvauBp2a/lR31jkSleczSo8Q== + dependencies: + array-back "^4.0.0" + lodash.omit "^4.5.0" + lodash.pick "^4.4.0" + reduce-extract "^1.0.0" + sort-array "^2.0.0" + test-value "^3.0.0" + +jsdoc-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jsdoc-regex/-/jsdoc-regex-1.0.1.tgz#8424428d5b563ad8c5c7fbec079b9a8b09c8dcfa" + integrity sha1-hCRCjVtWOtjFx/vsB5uaiwnI3Po= + +jsdoc-to-markdown@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/jsdoc-to-markdown/-/jsdoc-to-markdown-5.0.3.tgz#32cdd8683609141199b42a5b7045d91647a5758b" + integrity sha512-tQv5tBV0fTYidRQtE60lJKxE98mmuLcYuITFDKQiDPE9hGccpeEGUNFcVkInq1vigyuPnZmt79bQ8wv2GKjY0Q== + dependencies: + array-back "^4.0.1" + command-line-tool "^0.8.0" + config-master "^3.1.0" + dmd "^4.0.5" + jsdoc-api "^5.0.4" + jsdoc-parse "^4.0.1" + walk-back "^4.0.0" + +jsdoc@^3.6.3: + version "3.6.6" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.6.tgz#9fe162bbdb13ee7988bf74352b5147565bcfd8e1" + integrity sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ== + dependencies: + "@babel/parser" "^7.9.4" + bluebird "^3.7.2" + catharsis "^0.8.11" + escape-string-regexp "^2.0.0" + js2xmlparser "^4.0.1" + klaw "^3.0.0" + markdown-it "^10.0.0" + markdown-it-anchor "^5.2.7" + marked "^0.8.2" + mkdirp "^1.0.4" + requizzle "^0.2.3" + strip-json-comments "^3.1.0" + taffydb "2.6.2" + underscore "~1.10.2" + jsdom@^16.5.2: version "16.5.3" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.3.tgz#13a755b3950eb938b4482c407238ddf16f0d2136" @@ -839,6 +2876,16 @@ jsdom@^16.5.2: ws "^7.4.4" xml-name-validator "^3.0.0" +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -849,11 +2896,23 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -864,7 +2923,38 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -levn@~0.3.0: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + +levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= @@ -872,7 +2962,47 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lodash@^4.17.19, lodash@^4.7.0: +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== + dependencies: + uc.micro "^1.0.1" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.omit@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" + integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA= + +lodash.padend@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= + +lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= + +lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -892,6 +3022,14 @@ m3u8stream@^0.8.0, m3u8stream@^0.8.3: miniget "^4.0.0" sax "^1.2.4" +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -899,6 +3037,68 @@ make-dir@^3.1.0: dependencies: semver "^6.0.0" +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-it-anchor@^5.2.7: + version "5.3.0" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz#d549acd64856a8ecd1bea58365ef385effbac744" + integrity sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA== + +markdown-it@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc" + integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg== + dependencies: + argparse "^1.0.7" + entities "~2.0.0" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +marked@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.7.0.tgz#b64201f051d271b1edc10a04d1ae9b74bb8e5c0e" + integrity sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg== + +marked@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355" + integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw== + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + mime-db@1.47.0: version "1.47.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" @@ -911,6 +3111,11 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "1.47.0" +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + miniget@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/miniget/-/miniget-4.2.0.tgz#0004e95536b192d95a7d09f4435d67b9285481d0" @@ -943,23 +3148,78 @@ minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" -mkdirp@^0.5.3: +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp2@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp2/-/mkdirp2-1.0.4.tgz#56de1f8f5c93cf2199906362eba0f9f262ee4437" + integrity sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw== + +mkdirp@^0.5.1, mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mkdirp@^1.0.3: +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +neo-async@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + node-addon-api@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" @@ -978,6 +3238,11 @@ node-html-parser@^3.0.4: css-select "^3.1.2" he "1.2.0" +node-releases@^1.1.71: + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== + nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -985,6 +3250,18 @@ nopt@^5.0.0: dependencies: abbrev "1" +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -1022,6 +3299,54 @@ object-assign@^4.1.0: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-get@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/object-get/-/object-get-2.1.1.tgz#1dad63baf6d94df184d1c58756cc9be55b174dac" + integrity sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-to-spawn-args@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz#77da8827f073d011c9e1b173f895781470246785" + integrity sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1029,7 +3354,14 @@ once@^1.3.0: dependencies: wrappy "1" -optionator@^0.8.1: +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.1, optionator@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -1041,6 +3373,37 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse5-htmlparser2-tree-adapter@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" @@ -1053,11 +3416,31 @@ parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -1068,6 +3451,21 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" + integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -1088,6 +3486,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -1103,7 +3506,7 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -readable-stream@^2.0.6: +readable-stream@^2.0.2, readable-stream@^2.0.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -1116,6 +3519,127 @@ readable-stream@^2.0.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + +reduce-extract@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/reduce-extract/-/reduce-extract-1.0.0.tgz#67f2385beda65061b5f5f4312662e8b080ca1525" + integrity sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU= + dependencies: + test-value "^1.0.1" + +reduce-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-1.0.1.tgz#258c78efd153ddf93cb561237f61184f3696e327" + integrity sha1-JYx479FT3fk8tWEjf2EYTzaW4yc= + +reduce-flatten@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-3.0.0.tgz#da477d68453fd9510f9a5fbef86e0fa04b4fd315" + integrity sha512-eczl8wAYBxJ6Egl6I1ECIF+8z6sHu+KE7BzaEDZTpPXKXfy9SUDQlVYwkRcNTjJLC3Iakxbhss50KuT/R6SYfg== + +reduce-unique@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/reduce-unique/-/reduce-unique-2.0.1.tgz#fb34b90e89297c1e08d75dcf17e9a6443ea71081" + integrity sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA== + +reduce-without@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/reduce-without/-/reduce-without-1.0.1.tgz#68ad0ead11855c9a37d4e8256c15bbf87972fc8c" + integrity sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw= + dependencies: + test-value "^2.0.0" + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== + +regjsparser@^0.6.4: + version "0.6.9" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" + integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + request-promise-core@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" @@ -1158,7 +3682,34 @@ request@^2.88.2: tunnel-agent "^0.6.0" uuid "^3.3.2" -resolve@^1.3.2: +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requizzle@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.3.tgz#4675c90aacafb2c036bd39ba2daa4a1cb777fded" + integrity sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ== + dependencies: + lodash "^4.17.14" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.14.2, resolve@^1.3.2: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -1166,6 +3717,19 @@ resolve@^1.3.2: is-core-module "^2.2.0" path-parse "^1.0.6" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + reverbnation-scraper@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/reverbnation-scraper/-/reverbnation-scraper-2.0.0.tgz#c17539aba218cc29033a63e732ba3e4953cb5bd5" @@ -1173,6 +3737,13 @@ reverbnation-scraper@^2.0.0: dependencies: node-fetch "^2.6.0" +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -1180,6 +3751,18 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +rxjs@^6.6.0: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + safe-buffer@^5.0.1, safe-buffer@^5.1.2: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -1190,6 +3773,13 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -1207,12 +3797,17 @@ saxes@^5.0.1: dependencies: xmlchars "^2.2.0" -semver@^5.3.0: +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^5.3.0, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.0.0: +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -1224,17 +3819,39 @@ semver@^7.3.4: dependencies: lru-cache "^6.0.0" -set-blocking@~2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= -signal-exit@^3.0.0: +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== @@ -1247,6 +3864,59 @@ simple-youtube-api@^5.2.1: iso8601-duration "^1.2.0" node-fetch "^2.6.0" +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sort-array@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-array/-/sort-array-2.0.0.tgz#38a9c6da27fd7d147b42e60554f281187b4df472" + integrity sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI= + dependencies: + array-back "^1.0.4" + object-get "^2.1.0" + typical "^2.6.0" + soundcloud-scraper@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/soundcloud-scraper/-/soundcloud-scraper-4.0.3.tgz#cd7ed1d7b6ed1d7729fd7580c011281f652b920f" @@ -1256,11 +3926,39 @@ soundcloud-scraper@^4.0.3: m3u8stream "^0.8.0" node-fetch "^2.6.1" -source-map@~0.6.1: +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.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" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + 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: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + spotify-uri@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/spotify-uri/-/spotify-uri-2.2.0.tgz#8db641615cf6e122284874287fe39e89595922df" @@ -1295,11 +3993,31 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= +stream-connect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-connect/-/stream-connect-1.0.2.tgz#18bc81f2edb35b8b5d9a8009200a985314428a97" + integrity sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc= + dependencies: + array-back "^1.0.2" + +stream-via@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/stream-via/-/stream-via-1.0.4.tgz#8dccbb0ac909328eb8bc8e2a4bd3934afdaf606c" + integrity sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ== + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -1317,6 +4035,24 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -1338,6 +4074,25 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-json-comments@^3.0.1, strip-json-comments@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -1345,11 +4100,44 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +table-layout@^0.4.2: + version "0.4.5" + resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-0.4.5.tgz#d906de6a25fa09c0c90d1d08ecd833ecedcb7378" + integrity sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw== + dependencies: + array-back "^2.0.0" + deep-extend "~0.6.0" + lodash.padend "^4.6.1" + typical "^2.6.1" + wordwrapjs "^3.0.0" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +taffydb@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" + integrity sha1-fLy2S1oUG2ou/CxdLGe04VCyomg= + tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" @@ -1362,6 +4150,89 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" +temp-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-path/-/temp-path-1.0.0.tgz#24b1543973ab442896d9ad367dd9cbdbfafe918b" + integrity sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs= + +test-value@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-1.1.0.tgz#a09136f72ec043d27c893707c2b159bfad7de93f" + integrity sha1-oJE29y7AQ9J8iTcHwrFZv6196T8= + dependencies: + array-back "^1.0.2" + typical "^2.4.2" + +test-value@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-2.1.0.tgz#11da6ff670f3471a73b625ca4f3fdcf7bb748291" + integrity sha1-Edpv9nDzRxpztiXKTz/c97t0gpE= + dependencies: + array-back "^1.0.3" + typical "^2.6.0" + +test-value@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/test-value/-/test-value-3.0.0.tgz#9168c062fab11a86b8d444dd968bb4b73851ce92" + integrity sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ== + dependencies: + array-back "^2.0.0" + typical "^2.6.1" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -1386,7 +4257,7 @@ tr46@^2.0.2: dependencies: punycode "^2.1.1" -tslib@^1.13.0, tslib@^1.8.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" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -1415,6 +4286,11 @@ tslint@^6.1.3: tslib "^1.13.0" tsutils "^2.29.0" +tsubaki@^1.3.2: + version "1.3.9" + resolved "https://registry.yarnpkg.com/tsubaki/-/tsubaki-1.3.9.tgz#3e7e3eeb1e85ab010329ebd84266b9b4ef5ccb6c" + integrity sha512-neUK2wk0vu12jbuyTDYx9UcYZFXsyjkbQmZAWOKQ6d+dBnJG6E7VTS+3jUjEpwapLyp7bfojbl/pHVZj7oqbPw== + tsutils@^2.29.0: version "2.29.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" @@ -1446,16 +4322,97 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + typescript@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== +typical@^2.4.2, typical@^2.6.0, typical@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/typical/-/typical-2.6.1.tgz#5c080e5d661cbbe38259d2e70a3c7253e873881d" + integrity sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0= + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +uglify-js@^3.1.4: + version "3.13.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.4.tgz#592588bb9f47ae03b24916e2471218d914955574" + integrity sha512-kv7fCkIXyQIilD5/yQy8O+uagsYIOt5cZvs890W40/e/rvjMSzJw81o9Bg0tkURxzZBROtDQhW2LFjOGoK3RZw== + +underscore@~1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" + integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -1463,6 +4420,16 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -1473,6 +4440,11 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -1496,6 +4468,21 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" +walk-back@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-2.0.1.tgz#554e2a9d874fac47a8cb006bf44c2f0c4998a0a4" + integrity sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ= + +walk-back@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-3.0.1.tgz#0c0012694725604960d6c2f75aaf1a1e7d455d35" + integrity sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ== + +walk-back@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/walk-back/-/walk-back-4.0.0.tgz#9e4ad2bd72038f3beed2d83180f9fd40b233bfab" + integrity sha512-kudCA8PXVQfrqv2mFTG72vDBRi8BKWxGgFLwPpzHcpZnSwZk93WMwUDVcLHWNsnm+Y0AC4Vb6MUNRgaHfyV2DQ== + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -1527,6 +4514,18 @@ whatwg-url@^8.0.0, whatwg-url@^8.5.0: tr46 "^2.0.2" webidl-conversions "^6.1.0" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -1539,11 +4538,40 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wordwrapjs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-3.0.0.tgz#c94c372894cadc6feb1a66bff64e1d9af92c5d1e" + integrity sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw== + dependencies: + reduce-flatten "^1.0.1" + typical "^2.6.1" + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + ws@^7.4.4: version "7.4.4" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" @@ -1559,11 +4587,46 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xmlcreate@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.3.tgz#df9ecd518fd3890ab3548e1b811d040614993497" + integrity sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yargs-parser@^15.0.1: + version "15.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3" + integrity sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^14.0.0: + version "14.2.3" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" + integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== + dependencies: + cliui "^5.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^15.0.1" + youtube-sr@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/youtube-sr/-/youtube-sr-4.0.4.tgz#48369b0cb1c53bd84c366a5420bb8f35b1db2329" From 7e72074f7b7f2a8f8c19e8e1f7d628946639cf7e Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 10:59:21 +0545 Subject: [PATCH 085/131] workflow for docs --- .github/workflows/deploy.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..f75630c --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,27 @@ +name: Deployment +on: + push: + branches: + - '*' + - '!docs' + - '!gh-pages' +jobs: + docs: + name: Documentation + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@master + + - name: Install Node v14 + uses: actions/setup-node@master + with: + node-version: 14 + + - name: Install dependencies + run: npm install + + - name: Build and deploy documentation + uses: discordjs/action-docs@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From b336faf43e2dfb1798e5ce492a7bac45168a4de4 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 11:01:38 +0545 Subject: [PATCH 086/131] doc comamnd --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8768789..3a1219e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", "lint": "tslint -p tsconfig.json", - "docs": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml --output demo/docs.json", + "docs": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json", "docs:test": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", From d2bb3087a69012b0ce7cea2316e309a1d6e9d69c Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 11:06:47 +0545 Subject: [PATCH 087/131] docs work --- docs/extractors/extractor.md | 2 +- docs/general/Welcome.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md index 5e6fc9c..c109ade 100644 --- a/docs/extractors/extractor.md +++ b/docs/extractors/extractor.md @@ -1,2 +1,2 @@ # Discord Player Extractor API -The extractor API \ No newline at end of file +The Extractor API \ No newline at end of file diff --git a/docs/general/Welcome.md b/docs/general/Welcome.md index 7171319..a5d8c77 100644 --- a/docs/general/Welcome.md +++ b/docs/general/Welcome.md @@ -70,7 +70,7 @@ client.on("message", async (message) => { const command = args.shift().toLowerCase(); // !play Despacito - // will play "Despacito" in the voice channel + // will play the song "Despacito" in the voice channel if(command === "play"){ client.player.play(message, args[0]); // as we registered the event above, no need to send a success message here From 928ab4214b7165f8952af107e05d519b525323c7 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 11:08:37 +0545 Subject: [PATCH 088/131] I tried --- README.md | 4 ++-- docs/general/Welcome.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7171319..058ccd1 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ These bots are made by the community, they can help you build your own! ## FAQ -### How to use cookies? +### How to use cookies ```js const player = new Player(client, { @@ -122,7 +122,7 @@ const player = new Player(client, { }); ``` -### How to use custom proxies? +### How to use custom proxies ```js const HttpsProxyAgent = require("https-proxy-agent"); diff --git a/docs/general/Welcome.md b/docs/general/Welcome.md index a5d8c77..2075526 100644 --- a/docs/general/Welcome.md +++ b/docs/general/Welcome.md @@ -108,7 +108,7 @@ These bots are made by the community, they can help you build your own! ## FAQ -### How to use cookies? +### How to use cookies ```js const player = new Player(client, { @@ -122,7 +122,7 @@ const player = new Player(client, { }); ``` -### How to use custom proxies? +### How to use custom proxies ```js const HttpsProxyAgent = require("https-proxy-agent"); From cefca57b000c51579608ccb266686c4c57217290 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 11:09:45 +0545 Subject: [PATCH 089/131] windows bad --- docs/index.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.yml b/docs/index.yml index 4d66eb1..7ecd859 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -1,7 +1,7 @@ - name: General files: - name: Welcome - path: welcome.md + path: Welcome.md - name: Extractors files: - name: Extractors From cdbb1e5fc384d343f3e1d9c87d0bbf4545c59fc4 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 11:27:20 +0545 Subject: [PATCH 090/131] extractor doc --- docs/extractors/extractor.md | 44 +++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md index c109ade..c5222f0 100644 --- a/docs/extractors/extractor.md +++ b/docs/extractors/extractor.md @@ -1,2 +1,44 @@ # Discord Player Extractor API -The Extractor API \ No newline at end of file +The Extractor API allows you to build your own stream extractor for **Discord Player**. + +# Example Extractor +Your extractor should have 2 methods (required): + - `validate(query): boolean` + + This method is called by Discord Player while validating the query provided via `Player.play()`. (Note that only `string` queries are passed to your extractor) + + - `getInfo(query): object` + + This method is used by Discord Player to create `Track` object. You can return your data here that gets passed to `Track`. + Your info must be similar to this: + + ```js + { + // the title + title: "Extracted by custom extractor", + // the duration in ms + duration: 20000, + // the thumbnail + thumbnail: data.thumbnail, + // engine, can be Readable streams or link to raw stream that gets played + engine: data.streamURL, + // number of views + views: 0, + // author of this stream + author: data.artist.name, + // description + description: "", + // link of this stream + url: data.url + } + ``` + - `important: boolean` + + You can mark your Extractor as `important` by adding `important: true` to your extractor object. Doing this will disable rest of the extractors that comes after your extractor and use your extractor to get data. By default, it is set to `false`. + + - `version: string` + + This should be the version of your extractor. It is not really important and is set to `0.0.0` by default. + +# Examples +### You can check out **[@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors)** \ No newline at end of file From e2914efe025df6b6b611b78d27d43c64e795c6f4 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 11:48:12 +0545 Subject: [PATCH 091/131] remove @alias --- src/Player.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index fb60e95..6fdeaa5 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -502,7 +502,6 @@ export class Player extends EventEmitter { * Sets track position * @param {Discord.Message} message The message object * @param {number} time Time in ms to set - * @alias Player.seek */ setPosition(message: Message, time: number): Promise { return new Promise((resolve) => { @@ -526,7 +525,6 @@ export class Player extends EventEmitter { * Sets track position * @param {Discord.Message} message The message object * @param {number} time Time in ms to set - * @alias Player.setPosition */ seek(message: Message, time: number): Promise { return this.setPosition(message, time); From 497611483c78d8e57c432e19ab24de36092eee53 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 12:20:57 +0545 Subject: [PATCH 092/131] some jsdoc --- src/Player.ts | 62 ++++++++++++++-------------- src/types/types.ts | 101 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 32 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 6fdeaa5..d8cda8a 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1183,93 +1183,93 @@ export default Player; /** * Emitted when a track starts * @event Player#trackStart - * @param {Discord.Message} message - * @param {Track} track - * @param {Queue} queue + * @param {Discord.Message} message The message + * @param {Track} track The track + * @param {Queue} queue The queue */ /** * Emitted when a playlist is started * @event Player#queueCreate - * @param {Discord.Message} message - * @param {Queue} queue + * @param {Discord.Message} message The message + * @param {Queue} queue The queue */ /** * Emitted when the bot is awaiting search results * @event Player#searchResults - * @param {Discord.Message} message - * @param {string} query - * @param {Track[]} tracks - * @param {Discord.Collector} collector + * @param {Discord.Message} message The message + * @param {string} query The query + * @param {Track[]} tracks The tracks + * @param {Discord.Collector} collector The collector */ /** * Emitted when the user has sent an invalid response for search results * @event Player#searchInvalidResponse - * @param {Discord.Message} message - * @param {string} query - * @param {Track[]} tracks - * @param {string} invalidResponse - * @param {Discord.MessageCollector} collector + * @param {Discord.Message} message The message + * @param {string} query The query + * @param {Track[]} tracks The tracks + * @param {string} invalidResponse The `invalidResponse` string + * @param {Discord.MessageCollector} collector The collector */ /** * Emitted when the bot has stopped awaiting search results (timeout) * @event Player#searchCancel - * @param {Discord.Message} message - * @param {string} query - * @param {Track[]} tracks + * @param {Discord.Message} message The message + * @param {string} query The query + * @param {Track[]} tracks The tracks */ /** * Emitted when the bot can't find related results to the query * @event Player#noResults - * @param {Discord.Message} message - * @param {string} query + * @param {Discord.Message} message The message + * @param {string} query The query */ /** * Emitted when the bot is disconnected from the channel * @event Player#botDisconnect - * @param {Discord.Message} message + * @param {Discord.Message} message The message */ /** * Emitted when the channel of the bot is empty * @event Player#channelEmpty - * @param {Discord.Message} message - * @param {Queue} queue + * @param {Discord.Message} message The message + * @param {Queue} queue The queue */ /** * Emitted when the queue of the server is ended * @event Player#queueEnd - * @param {Discord.Message} message - * @param {Queue} queue + * @param {Discord.Message} message The message + * @param {Queue} queue The queue */ /** * Emitted when a track is added to the queue * @event Player#trackAdd - * @param {Discord.Message} message - * @param {Queue} queue - * @param {Track} track + * @param {Discord.Message} message The message + * @param {Queue} queue The queue + * @param {Track} track The track */ /** * Emitted when a playlist is added to the queue * @event Player#playlistAdd - * @param {Discord.Message} message - * @param {Queue} queue - * @param {Object} playlist + * @param {Discord.Message} message The message + * @param {Queue} queue The queue + * @param {Object} playlist The playlist */ /** * Emitted when an error is triggered * @event Player#error * @param {string} error It can be `NotConnected`, `UnableToJoin`, `NotPlaying`, `ParseError`, `LiveVideo` or `VideoUnavailable`. - * @param {Discord.Message} message + * @param {Discord.Message} message The message */ /** diff --git a/src/types/types.ts b/src/types/types.ts index e1e885a..ee5034e 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -2,6 +2,18 @@ import { downloadOptions } from 'ytdl-core'; import { User } from 'discord.js'; import { Readable, Duplex } from 'stream'; +/** + * @typedef {object} PlayerOptions + * @property {boolean} [leaveOnEnd=false] If it should leave on queue end + * @property {number} [leaveOnEndCooldown=0] Time in ms to wait before executing `leaveOnEnd` + * @property {boolean} [leaveOnStop=false] If it should leave on stop command + * @property {boolean} [leaveOnEmpty=false] If it should leave on empty voice channel + * @property {number} [leaveOnEmptyCooldown=0] Time in ms to wait before executing `leaveOnEmpty` + * @property {boolean} [autoSelfDeaf=false] If it should set the client to `self deaf` mode on joining + * @property {boolean} [enableLive=false] If it should enable live videos support + * @property {YTDLDownloadOptions} [ytdlDownloadOptions={}] The download options passed to `ytdl-core` + * @property {boolean} [useSafeSearch=false] If it should use `safe search` method for youtube searches + */ export interface PlayerOptions { leaveOnEnd?: boolean; leaveOnEndCooldown?: number; @@ -16,8 +28,25 @@ export interface PlayerOptions { export type FiltersName = keyof QueueFilters; -export type TrackSource = 'soundcloud' | 'youtube' | 'arbitrary'; +/** + * @typedef {'soundcloud'|'youtube'|'arbitrary'} TrackSource + */ +export type TrackSource = 'soundcloud'|'youtube'|'arbitrary'; +/** + * @typedef {object} TrackData + * @property {string} title The title + * @property {string} description The description + * @property {string} author The author + * @property {string} url The url + * @property {string} duration The duration + * @property {number} views The view count + * @property {Discord.User} requestedBy The user who requested this track + * @property {boolean} fromPlaylist If this track came from a playlist + * @property {TrackSource} [source] The track source + * @property {string|Readable} [engine] The stream engine + * @property {boolean} [live=false] If this track is livestream instance + */ export interface TrackData { title: string; description: string; @@ -33,6 +62,10 @@ export interface TrackData { live?: boolean; } +/** + * @typedef {object} QueueFilters + * The FFmpeg Filters + */ export type QueueFilters = { bassboost?: boolean; '8D'?: boolean; @@ -64,6 +97,9 @@ export type QueueFilters = { fadein?: boolean; }; +/** + * @typedef {'soundcloud_track'|'soundcloud_playlist'|'spotify_song'|'spotify_album'|'spotify_playlist'|'youtube_video'|'youtube_playlist'|'vimeo'|'facebook'|'reverbnation'|'attachment'|'youtube_search'} QueryType The query type + */ export type QueryType = | 'soundcloud_track' | 'soundcloud_playlist' @@ -78,6 +114,19 @@ export type QueryType = | 'attachment' | 'youtube_search'; +/** + * @typedef {object} ExtractorModelData + * @property {string} title The title + * @property {number} duration The duration in ms + * @property {string} thumbnail The thumbnail url + * @property {string|Readable} engine The audio engine + * @property {number} views The views count of this stream + * @property {string} author The author + * @property {string} description The description + * @property {string} url The url + * @property {string} [version='0.0.0'] The extractor version + * @property {boolean} [important=false] Mark as important + */ export interface ExtractorModelData { title: string; duration: number; @@ -88,14 +137,35 @@ export interface ExtractorModelData { description: string; url: string; version?: string; + important?: boolean; } +/** + * @typedef {object} PlayerProgressbarOptions + * @property {boolean} [timecodes] If it should return progres bar with time codes + * @property {boolean} [queue] if it should return the progress bar of the whole queue + * @property {number} [length] The length of progress bar to build + */ export interface PlayerProgressbarOptions { timecodes?: boolean; queue?: boolean; length?: number; } +/** + * @typedef {object} LyricsData + * @property {string} title The title of the lyrics + * @property {number} id The song id + * @property {string} thumbnail The thumbnail + * @property {string} image The image + * @property {string} url The url + * @property {object} artist The artust info + * @property {string} [artist.name] The name of the artist + * @property {number} [artist.id] The ID of the artist + * @property {string} [artist.url] The profile link of the artist + * @property {string} [artist.image] The artist image url + * @property {string?} lyrics The lyrics + */ export interface LyricsData { title: string; id: number; @@ -111,6 +181,28 @@ export interface LyricsData { lyrics?: string; } +/** + * @typedef {object} PlayerStats + * @property {number} uptime The uptime in ms + * @property {number} connections The number of connections + * @property {number} users The number of users + * @property {number} queues The number of queues + * @property {number} extractors The number of custom extractors registered + * @property {object} versions The versions metadata + * @property {string} [versions.ffmpeg] The ffmpeg version + * @property {string} [versions.node] The node version + * @property {string} [versions.v8] The v8 JavaScript engine version + * @property {object} system The system data + * @property {string} [system.arch] The system arch + * @property {'aix'|'android'|'darwin'|'freebsd'|'linux'|'openbsd'|'sunos'|'win32'|'cygwin'|'netbsd'} [system.platform] The system platform + * @property {number} [system.cpu] The cpu count + * @property {object} [system.memory] The memory info + * @property {string} [system.memory.total] The total memory + * @property {string} [system.memory.usage] The memory usage + * @property {string} [system.memory.rss] The memory usage in RSS + * @property {string} [system.memory.arrayBuffers] The memory usage in ArrayBuffers + * @property {number} [system.uptime] The system uptime + */ export interface PlayerStats { uptime: number; connections: number; @@ -146,6 +238,13 @@ export interface PlayerStats { }; } +/** + * @typedef {object} TimeData + * @property {number} days The time in days + * @property {number} hours The time in hours + * @property {number} minutes The time in minutes + * @property {number} seconds The time in seconds + */ export interface TimeData { days: number; hours: number; From 6e71a9c8b0b7f084023a5a2e0eb3108f9c59c2e8 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 12:25:48 +0545 Subject: [PATCH 093/131] format --- src/types/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/types.ts b/src/types/types.ts index ee5034e..a302503 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -31,7 +31,7 @@ export type FiltersName = keyof QueueFilters; /** * @typedef {'soundcloud'|'youtube'|'arbitrary'} TrackSource */ -export type TrackSource = 'soundcloud'|'youtube'|'arbitrary'; +export type TrackSource = 'soundcloud' | 'youtube' | 'arbitrary'; /** * @typedef {object} TrackData From ef07e0f3c8a94abbdbd457e98b822094b5244830 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 12:37:59 +0545 Subject: [PATCH 094/131] jsdoc --- src/Player.ts | 142 +++++++++++++++++++++++++++---- src/Structures/ExtractorModel.ts | 12 +-- src/Structures/Queue.ts | 16 ++-- src/Structures/Track.ts | 20 ++--- src/types/types.ts | 98 --------------------- src/utils/Util.ts | 16 ++-- 6 files changed, 157 insertions(+), 147 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index d8cda8a..7892599 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -91,7 +91,7 @@ export class Player extends EventEmitter { /** * Define custom extractor in this player - * @param {string} extractorName The extractor name + * @param {String} extractorName The extractor name * @param {any} extractor The extractor itself */ use(extractorName: string, extractor: any): Player { @@ -111,7 +111,7 @@ export class Player extends EventEmitter { /** * Remove existing extractor from this player - * @param {string} extractorName The extractor name + * @param {String} extractorName The extractor name */ unuse(extractorName: string): boolean { if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); @@ -366,7 +366,7 @@ export class Player extends EventEmitter { * Play a song * @param {Discord.Message} message The discord.js message object * @param {string|Track} query Search query, can be `Player.Track` instance - * @param {boolean} [firstResult] If it should play the first result + * @param {Boolean} [firstResult] If it should play the first result * @example await player.play(message, "never gonna give you up", true) */ async play(message: Message, query: string | Track, firstResult?: boolean): Promise { @@ -501,7 +501,7 @@ export class Player extends EventEmitter { /** * Sets track position * @param {Discord.Message} message The message object - * @param {number} time Time in ms to set + * @param {Number} time Time in ms to set */ setPosition(message: Message, time: number): Promise { return new Promise((resolve) => { @@ -524,7 +524,7 @@ export class Player extends EventEmitter { /** * Sets track position * @param {Discord.Message} message The message object - * @param {number} time Time in ms to set + * @param {Number} time Time in ms to set */ seek(message: Message, time: number): Promise { return this.setPosition(message, time); @@ -645,7 +645,7 @@ export class Player extends EventEmitter { /** * Sets music volume * @param {Discord.Message} message The message object - * @param {number} percent The volume percentage/amount to set + * @param {Number} percent The volume percentage/amount to set */ setVolume(message: Message, percent: number): boolean { const queue = this.getQueue(message); @@ -705,7 +705,7 @@ export class Player extends EventEmitter { /** * Sets repeat mode * @param {Discord.Message} message The message object - * @param {boolean} enabled If it should enable the repeat mode + * @param {Boolean} enabled If it should enable the repeat mode */ setRepeatMode(message: Message, enabled: boolean): boolean { const queue = this.getQueue(message); @@ -722,7 +722,7 @@ export class Player extends EventEmitter { /** * Sets loop mode * @param {Discord.Message} message The message object - * @param {boolean} enabled If it should enable the loop mode + * @param {Boolean} enabled If it should enable the loop mode */ setLoopMode(message: Message, enabled: boolean): boolean { const queue = this.getQueue(message); @@ -804,7 +804,7 @@ export class Player extends EventEmitter { /** * Returns time code of currently playing song * @param {Discord.Message} message The message object - * @param {boolean} [queueTime] If it should make the time code of the whole queue + * @param {Boolean} [queueTime] If it should make the time code of the whole queue */ getTimeCode(message: Message, queueTime?: boolean): { current: string; end: string } { const queue = this.getQueue(message); @@ -875,7 +875,7 @@ export class Player extends EventEmitter { /** * Gets lyrics of a song - * @param {string} query Search query + * @param {String} query Search query * @example const lyrics = await player.lyrics("alan walker faded") * message.channel.send(lyrics.lyrics); */ @@ -892,7 +892,7 @@ export class Player extends EventEmitter { /** * Toggle autoplay for youtube streams * @param {Discord.Message} message The message object - * @param {boolean} enable Enable/Disable autoplay + * @param {Boolean} enable Enable/Disable autoplay */ setAutoPlay(message: Message, enable: boolean): boolean { const queue = this.getQueue(message); @@ -1199,7 +1199,7 @@ export default Player; * Emitted when the bot is awaiting search results * @event Player#searchResults * @param {Discord.Message} message The message - * @param {string} query The query + * @param {String} query The query * @param {Track[]} tracks The tracks * @param {Discord.Collector} collector The collector */ @@ -1208,9 +1208,9 @@ export default Player; * Emitted when the user has sent an invalid response for search results * @event Player#searchInvalidResponse * @param {Discord.Message} message The message - * @param {string} query The query + * @param {String} query The query * @param {Track[]} tracks The tracks - * @param {string} invalidResponse The `invalidResponse` string + * @param {String} invalidResponse The `invalidResponse` string * @param {Discord.MessageCollector} collector The collector */ @@ -1218,7 +1218,7 @@ export default Player; * Emitted when the bot has stopped awaiting search results (timeout) * @event Player#searchCancel * @param {Discord.Message} message The message - * @param {string} query The query + * @param {String} query The query * @param {Track[]} tracks The tracks */ @@ -1226,7 +1226,7 @@ export default Player; * Emitted when the bot can't find related results to the query * @event Player#noResults * @param {Discord.Message} message The message - * @param {string} query The query + * @param {String} query The query */ /** @@ -1268,7 +1268,7 @@ export default Player; /** * Emitted when an error is triggered * @event Player#error - * @param {string} error It can be `NotConnected`, `UnableToJoin`, `NotPlaying`, `ParseError`, `LiveVideo` or `VideoUnavailable`. + * @param {String} error It can be `NotConnected`, `UnableToJoin`, `NotPlaying`, `ParseError`, `LiveVideo` or `VideoUnavailable`. * @param {Discord.Message} message The message */ @@ -1285,3 +1285,111 @@ export default Player; * @param {Object} playlist The playlist data (parsed) * @param {Discord.Message} message The message */ + +/** + * @typedef {Object} PlayerOptions + * @property {Boolean} [leaveOnEnd=false] If it should leave on queue end + * @property {Number} [leaveOnEndCooldown=0] Time in ms to wait before executing `leaveOnEnd` + * @property {Boolean} [leaveOnStop=false] If it should leave on stop command + * @property {Boolean} [leaveOnEmpty=false] If it should leave on empty voice channel + * @property {Number} [leaveOnEmptyCooldown=0] Time in ms to wait before executing `leaveOnEmpty` + * @property {Boolean} [autoSelfDeaf=false] If it should set the client to `self deaf` mode on joining + * @property {Boolean} [enableLive=false] If it should enable live videos support + * @property {YTDLDownloadOptions} [ytdlDownloadOptions={}] The download options passed to `ytdl-core` + * @property {Boolean} [useSafeSearch=false] If it should use `safe search` method for youtube searches + */ + +/** + * @typedef {'soundcloud'|'youtube'|'arbitrary'} TrackSource + */ + +/** + * @typedef {Object} TrackData + * @property {String} title The title + * @property {String} description The description + * @property {String} author The author + * @property {String} url The url + * @property {String} duration The duration + * @property {Number} views The view count + * @property {Discord.User} requestedBy The user who requested this track + * @property {Boolean} fromPlaylist If this track came from a playlist + * @property {TrackSource} [source] The track source + * @property {string|Readable} [engine] The stream engine + * @property {Boolean} [live=false] If this track is livestream instance + */ + +/** + * @typedef {Object} QueueFilters + * The FFmpeg Filters + */ + +/** + * @typedef {'soundcloud_track'|'soundcloud_playlist'|'spotify_song'|'spotify_album'|'spotify_playlist'|'youtube_video'|'youtube_playlist'|'vimeo'|'facebook'|'reverbnation'|'attachment'|'youtube_search'} QueryType The query type + */ + +/** + * @typedef {Object} ExtractorModelData + * @property {String} title The title + * @property {Number} duration The duration in ms + * @property {String} thumbnail The thumbnail url + * @property {string|Readable} engine The audio engine + * @property {Number} views The views count of this stream + * @property {String} author The author + * @property {String} description The description + * @property {String} url The url + * @property {String} [version='0.0.0'] The extractor version + * @property {Boolean} [important=false] Mark as important + */ + +/** + * @typedef {Object} PlayerProgressbarOptions + * @property {Boolean} [timecodes] If it should return progres bar with time codes + * @property {Boolean} [queue] if it should return the progress bar of the whole queue + * @property {Number} [length] The length of progress bar to build + */ + +/** + * @typedef {Object} LyricsData + * @property {String} title The title of the lyrics + * @property {Number} id The song id + * @property {String} thumbnail The thumbnail + * @property {String} image The image + * @property {String} url The url + * @property {Object} artist The artust info + * @property {String} [artist.name] The name of the artist + * @property {Number} [artist.id] The ID of the artist + * @property {String} [artist.url] The profile link of the artist + * @property {String} [artist.image] The artist image url + * @property {String?} lyrics The lyrics + */ + +/** + * @typedef {Object} PlayerStats + * @property {Number} uptime The uptime in ms + * @property {Number} connections The number of connections + * @property {Number} users The number of users + * @property {Number} queues The number of queues + * @property {Number} extractors The number of custom extractors registered + * @property {Object} versions The versions metadata + * @property {String} [versions.ffmpeg] The ffmpeg version + * @property {String} [versions.node] The node version + * @property {String} [versions.v8] The v8 JavaScript engine version + * @property {Object} system The system data + * @property {String} [system.arch] The system arch + * @property {'aix'|'android'|'darwin'|'freebsd'|'linux'|'openbsd'|'sunos'|'win32'|'cygwin'|'netbsd'} [system.platform] The system platform + * @property {Number} [system.cpu] The cpu count + * @property {Object} [system.memory] The memory info + * @property {String} [system.memory.total] The total memory + * @property {String} [system.memory.usage] The memory usage + * @property {String} [system.memory.rss] The memory usage in RSS + * @property {String} [system.memory.arrayBuffers] The memory usage in ArrayBuffers + * @property {Number} [system.uptime] The system uptime + */ + +/** + * @typedef {Object} TimeData + * @property {Number} days The time in days + * @property {Number} hours The time in hours + * @property {Number} minutes The time in minutes + * @property {Number} seconds The time in seconds + */ \ No newline at end of file diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index 6c25fab..00d5902 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -6,13 +6,13 @@ class ExtractorModel { /** * Model for raw Discord Player extractors - * @param {string} extractorName Name of the extractor + * @param {String} extractorName Name of the extractor * @param {Object} data Extractor object */ constructor(extractorName: string, data: any) { /** * The extractor name - * @type {string} + * @type {String} */ this.name = extractorName; @@ -21,7 +21,7 @@ class ExtractorModel { /** * Method to handle requests from `Player.play()` - * @param {string} query Query to handle + * @param {String} query Query to handle */ async handle(query: string): Promise { const data = await this._raw.getInfo(query); @@ -41,7 +41,7 @@ class ExtractorModel { /** * Method used by Discord Player to validate query with this extractor - * @param {string} query The query to validate + * @param {String} query The query to validate */ validate(query: string): boolean { return Boolean(this._raw.validate(query)); @@ -49,7 +49,7 @@ class ExtractorModel { /** * The extractor version - * @type {string} + * @type {String} */ get version(): string { return this._raw.version ?? '0.0.0'; @@ -57,7 +57,7 @@ class ExtractorModel { /** * If player should mark this extractor as important - * @type {boolean} + * @type {Boolean} */ get important(): boolean { return Boolean(this._raw.important); diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 41391a9..50d64b8 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -78,7 +78,7 @@ export class Queue extends EventEmitter { /** * Queue volume - * @type {number} + * @type {Number} */ this.volume = 100; @@ -102,7 +102,7 @@ export class Queue extends EventEmitter { /** * The additional calculated stream time - * @type {number} + * @type {Number} */ this.additionalStreamTime = 0; @@ -133,7 +133,7 @@ export class Queue extends EventEmitter { /** * Calculated volume of this queue - * @type {number} + * @type {Number} */ get calculatedVolume(): number { return this.filters.normalizer ? this.volume + 70 : this.volume; @@ -141,7 +141,7 @@ export class Queue extends EventEmitter { /** * Total duration - * @type {number} + * @type {Number} */ get totalTime(): number { return this.tracks.length > 0 ? this.tracks.map((t) => t.durationMS).reduce((p, c) => p + c) : 0; @@ -149,7 +149,7 @@ export class Queue extends EventEmitter { /** * Current stream time - * @type {number} + * @type {Number} */ get currentStreamTime(): number { return this.voiceConnection?.dispatcher?.streamTime + this.additionalStreamTime || 0; @@ -166,7 +166,7 @@ export class Queue extends EventEmitter { /** * Returns array of all enabled filters - * @type {string[]} + * @type {String[]} */ getFiltersEnabled(): string[] { const filters: string[] = []; @@ -180,7 +180,7 @@ export class Queue extends EventEmitter { /** * Returns all disabled filters - * @type {string[]} + * @type {String[]} */ getFiltersDisabled(): string[] { const enabled = this.getFiltersEnabled(); @@ -190,7 +190,7 @@ export class Queue extends EventEmitter { /** * String representation of this Queue - * @type {string} + * @type {String} */ toString(): string { return ``; diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 10c98e2..c257374 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -12,43 +12,43 @@ export class Track { /** * Title of this track - * @type {string} + * @type {String} */ public title!: string; /** * Description of this track - * @type {string} + * @type {String} */ public description!: string; /** * Author of this track - * @type {string} + * @type {String} */ public author!: string; /** * Link of this track - * @type {string} + * @type {String} */ public url!: string; /** * Thumbnail of this track - * @type {string} + * @type {String} */ public thumbnail!: string; /** * Duration of this track - * @type {string} + * @type {String} */ public duration!: string; /** * View count of this track - * @type {number} + * @type {Number} */ public views!: number; @@ -60,7 +60,7 @@ export class Track { /** * If this track belongs to a playlist - * @type {boolean} + * @type {Boolean} */ public fromPlaylist!: boolean; @@ -106,7 +106,7 @@ export class Track { /** * The track duration in millisecond - * @type {number} + * @type {Number} */ get durationMS(): number { const times = (n: number, t: number) => { @@ -124,7 +124,7 @@ export class Track { /** * String representation of this track - * @type {string} + * @type {String} */ toString(): string { return `${this.title} by ${this.author}`; diff --git a/src/types/types.ts b/src/types/types.ts index a302503..5be7d34 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -2,18 +2,6 @@ import { downloadOptions } from 'ytdl-core'; import { User } from 'discord.js'; import { Readable, Duplex } from 'stream'; -/** - * @typedef {object} PlayerOptions - * @property {boolean} [leaveOnEnd=false] If it should leave on queue end - * @property {number} [leaveOnEndCooldown=0] Time in ms to wait before executing `leaveOnEnd` - * @property {boolean} [leaveOnStop=false] If it should leave on stop command - * @property {boolean} [leaveOnEmpty=false] If it should leave on empty voice channel - * @property {number} [leaveOnEmptyCooldown=0] Time in ms to wait before executing `leaveOnEmpty` - * @property {boolean} [autoSelfDeaf=false] If it should set the client to `self deaf` mode on joining - * @property {boolean} [enableLive=false] If it should enable live videos support - * @property {YTDLDownloadOptions} [ytdlDownloadOptions={}] The download options passed to `ytdl-core` - * @property {boolean} [useSafeSearch=false] If it should use `safe search` method for youtube searches - */ export interface PlayerOptions { leaveOnEnd?: boolean; leaveOnEndCooldown?: number; @@ -28,25 +16,8 @@ export interface PlayerOptions { export type FiltersName = keyof QueueFilters; -/** - * @typedef {'soundcloud'|'youtube'|'arbitrary'} TrackSource - */ export type TrackSource = 'soundcloud' | 'youtube' | 'arbitrary'; -/** - * @typedef {object} TrackData - * @property {string} title The title - * @property {string} description The description - * @property {string} author The author - * @property {string} url The url - * @property {string} duration The duration - * @property {number} views The view count - * @property {Discord.User} requestedBy The user who requested this track - * @property {boolean} fromPlaylist If this track came from a playlist - * @property {TrackSource} [source] The track source - * @property {string|Readable} [engine] The stream engine - * @property {boolean} [live=false] If this track is livestream instance - */ export interface TrackData { title: string; description: string; @@ -62,10 +33,6 @@ export interface TrackData { live?: boolean; } -/** - * @typedef {object} QueueFilters - * The FFmpeg Filters - */ export type QueueFilters = { bassboost?: boolean; '8D'?: boolean; @@ -97,9 +64,6 @@ export type QueueFilters = { fadein?: boolean; }; -/** - * @typedef {'soundcloud_track'|'soundcloud_playlist'|'spotify_song'|'spotify_album'|'spotify_playlist'|'youtube_video'|'youtube_playlist'|'vimeo'|'facebook'|'reverbnation'|'attachment'|'youtube_search'} QueryType The query type - */ export type QueryType = | 'soundcloud_track' | 'soundcloud_playlist' @@ -114,19 +78,6 @@ export type QueryType = | 'attachment' | 'youtube_search'; -/** - * @typedef {object} ExtractorModelData - * @property {string} title The title - * @property {number} duration The duration in ms - * @property {string} thumbnail The thumbnail url - * @property {string|Readable} engine The audio engine - * @property {number} views The views count of this stream - * @property {string} author The author - * @property {string} description The description - * @property {string} url The url - * @property {string} [version='0.0.0'] The extractor version - * @property {boolean} [important=false] Mark as important - */ export interface ExtractorModelData { title: string; duration: number; @@ -140,32 +91,12 @@ export interface ExtractorModelData { important?: boolean; } -/** - * @typedef {object} PlayerProgressbarOptions - * @property {boolean} [timecodes] If it should return progres bar with time codes - * @property {boolean} [queue] if it should return the progress bar of the whole queue - * @property {number} [length] The length of progress bar to build - */ export interface PlayerProgressbarOptions { timecodes?: boolean; queue?: boolean; length?: number; } -/** - * @typedef {object} LyricsData - * @property {string} title The title of the lyrics - * @property {number} id The song id - * @property {string} thumbnail The thumbnail - * @property {string} image The image - * @property {string} url The url - * @property {object} artist The artust info - * @property {string} [artist.name] The name of the artist - * @property {number} [artist.id] The ID of the artist - * @property {string} [artist.url] The profile link of the artist - * @property {string} [artist.image] The artist image url - * @property {string?} lyrics The lyrics - */ export interface LyricsData { title: string; id: number; @@ -181,28 +112,6 @@ export interface LyricsData { lyrics?: string; } -/** - * @typedef {object} PlayerStats - * @property {number} uptime The uptime in ms - * @property {number} connections The number of connections - * @property {number} users The number of users - * @property {number} queues The number of queues - * @property {number} extractors The number of custom extractors registered - * @property {object} versions The versions metadata - * @property {string} [versions.ffmpeg] The ffmpeg version - * @property {string} [versions.node] The node version - * @property {string} [versions.v8] The v8 JavaScript engine version - * @property {object} system The system data - * @property {string} [system.arch] The system arch - * @property {'aix'|'android'|'darwin'|'freebsd'|'linux'|'openbsd'|'sunos'|'win32'|'cygwin'|'netbsd'} [system.platform] The system platform - * @property {number} [system.cpu] The cpu count - * @property {object} [system.memory] The memory info - * @property {string} [system.memory.total] The total memory - * @property {string} [system.memory.usage] The memory usage - * @property {string} [system.memory.rss] The memory usage in RSS - * @property {string} [system.memory.arrayBuffers] The memory usage in ArrayBuffers - * @property {number} [system.uptime] The system uptime - */ export interface PlayerStats { uptime: number; connections: number; @@ -238,13 +147,6 @@ export interface PlayerStats { }; } -/** - * @typedef {object} TimeData - * @property {number} days The time in days - * @property {number} hours The time in hours - * @property {number} minutes The time in minutes - * @property {number} seconds The time in seconds - */ export interface TimeData { days: number; hours: number; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index e3645d8..d569a22 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -24,7 +24,7 @@ export class Util { /** * Checks FFmpeg Version - * @param {boolean} [force] If it should forcefully get the version + * @param {Boolean} [force] If it should forcefully get the version */ static getFFmpegVersion(force?: boolean): string { try { @@ -38,7 +38,7 @@ export class Util { /** * Checks FFmpeg - * @param {boolean} [force] If it should forcefully get the version + * @param {Boolean} [force] If it should forcefully get the version */ static checkFFmpeg(force?: boolean): boolean { const version = Util.getFFmpegVersion(force); @@ -59,7 +59,7 @@ export class Util { /** * Resolves query type - * @param {string} query The query + * @param {String} query The query */ static getQueryType(query: string): QueryType { if (SoundcloudValidateURL(query) && !query.includes('/sets/')) return 'soundcloud_track'; @@ -79,7 +79,7 @@ export class Util { /** * Checks if the given string is url - * @param {string} str URL to check + * @param {String} str URL to check */ static isURL(str: string): boolean { return str.length < 2083 && attachmentRegex.test(str); @@ -87,7 +87,7 @@ export class Util { /** * Returns Vimeo ID - * @param {string} query Vimeo link + * @param {String} query Vimeo link */ static getVimeoID(query: string): string { return Util.getQueryType(query) === 'vimeo' @@ -100,7 +100,7 @@ export class Util { /** * Parses ms time - * @param {number} milliseconds Time to parse + * @param {Number} milliseconds Time to parse */ static parseMS(milliseconds: number): TimeData { const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; @@ -125,7 +125,7 @@ export class Util { /** * Makes youtube searches - * @param {string} query The query + * @param {String} query The query * @param {any} options Options * @returns {Promise} */ @@ -206,7 +206,7 @@ export class Util { /** * Manage CJS require - * @param {string} id id to require + * @param {String} id id to require */ static require(id: string): any { try { From c9f748aa6430379099a6fbd68ef08ae29b53c577 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 12:54:16 +0545 Subject: [PATCH 095/131] fix jsdoc --- src/Player.ts | 91 +++++++++++++++++++++-------------------- src/Structures/Queue.ts | 9 ++-- src/Structures/Track.ts | 2 +- src/utils/Util.ts | 2 +- 4 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 7892599..18167ab 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -28,12 +28,13 @@ const SoundCloud = new SoundCloudClient(); export class Player extends EventEmitter { /** * The discord client that instantiated this player - * @type {Discord.Client} + * @type {DiscordClient} */ - public client!: Client; + public client: Client; /** * The player options + * @type {PlayerOptions} */ public options: PlayerOptionsType; @@ -44,7 +45,7 @@ export class Player extends EventEmitter { /** * The collection of queues in this player - * @type {Discord.Collection} + * @type {DiscordCollection} */ public queues = new Collection(); private _resultsCollectors = new Collection>(); @@ -52,13 +53,13 @@ export class Player extends EventEmitter { /** * The extractor model collection - * @type {Discord.Collection} + * @type {DiscordCollection} */ public Extractors = new Collection(); /** * Creates new Player instance - * @param {Discord.Client} client The discord.js client + * @param {DiscordClient} client The discord.js client * @param {PlayerOptionsType} options Player options */ constructor(client: Client, options?: PlayerOptionsType) { @@ -364,7 +365,7 @@ export class Player extends EventEmitter { /** * Play a song - * @param {Discord.Message} message The discord.js message object + * @param {DiscordMessage} message The discord.js message object * @param {string|Track} query Search query, can be `Player.Track` instance * @param {Boolean} [firstResult] If it should play the first result * @example await player.play(message, "never gonna give you up", true) @@ -449,7 +450,7 @@ export class Player extends EventEmitter { /** * Checks if this player is playing in a server - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ isPlaying(message: Message): boolean { return this.queues.some((g) => g.guildID === message.guild.id); @@ -457,7 +458,7 @@ export class Player extends EventEmitter { /** * Returns guild queue object - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ getQueue(message: Message): Queue { return this.queues.find((g) => g.guildID === message.guild.id); @@ -465,7 +466,7 @@ export class Player extends EventEmitter { /** * Sets audio filters in this player - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {QueueFilters} newFilters Audio filters object */ setFilters(message: Message, newFilters: QueueFilters): Promise { @@ -500,7 +501,7 @@ export class Player extends EventEmitter { /** * Sets track position - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Number} time Time in ms to set */ setPosition(message: Message, time: number): Promise { @@ -523,7 +524,7 @@ export class Player extends EventEmitter { /** * Sets track position - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Number} time Time in ms to set */ seek(message: Message, time: number): Promise { @@ -532,7 +533,7 @@ export class Player extends EventEmitter { /** * Skips current track - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ skip(message: Message): boolean { const queue = this.getQueue(message); @@ -553,8 +554,8 @@ export class Player extends EventEmitter { /** * Moves to a new voice channel - * @param {Discord.Message} message The message object - * @param {Discord.VoiceChannel} channel New voice channel to move to + * @param {DiscordMessage} message The message object + * @param {DiscordVoiceChannel} channel New voice channel to move to */ moveTo(message: Message, channel?: VoiceChannel): boolean { if (!channel || channel.type !== 'voice') return; @@ -580,7 +581,7 @@ export class Player extends EventEmitter { /** * Pause the playback - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ pause(message: Message): boolean { const queue = this.getQueue(message); @@ -600,7 +601,7 @@ export class Player extends EventEmitter { /** * Resume the playback - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ resume(message: Message): boolean { const queue = this.getQueue(message); @@ -620,7 +621,7 @@ export class Player extends EventEmitter { /** * Stops the player - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ stop(message: Message): boolean { const queue = this.getQueue(message); @@ -644,7 +645,7 @@ export class Player extends EventEmitter { /** * Sets music volume - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Number} percent The volume percentage/amount to set */ setVolume(message: Message, percent: number): boolean { @@ -666,7 +667,7 @@ export class Player extends EventEmitter { /** * Clears the queue - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ clearQueue(message: Message): boolean { const queue = this.getQueue(message); @@ -682,7 +683,7 @@ export class Player extends EventEmitter { /** * Plays previous track - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ back(message: Message): boolean { const queue = this.getQueue(message); @@ -704,7 +705,7 @@ export class Player extends EventEmitter { /** * Sets repeat mode - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Boolean} enabled If it should enable the repeat mode */ setRepeatMode(message: Message, enabled: boolean): boolean { @@ -721,7 +722,7 @@ export class Player extends EventEmitter { /** * Sets loop mode - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Boolean} enabled If it should enable the loop mode */ setLoopMode(message: Message, enabled: boolean): boolean { @@ -738,7 +739,7 @@ export class Player extends EventEmitter { /** * Returns currently playing track - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ nowPlaying(message: Message): Track { const queue = this.getQueue(message); @@ -752,7 +753,7 @@ export class Player extends EventEmitter { /** * Shuffles the queue - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ shuffle(message: Message): Queue { const queue = this.getQueue(message); @@ -775,7 +776,7 @@ export class Player extends EventEmitter { /** * Removes specified track - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Track|number} track The track object/id to remove */ remove(message: Message, track: Track | number): Track { @@ -803,7 +804,7 @@ export class Player extends EventEmitter { /** * Returns time code of currently playing song - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Boolean} [queueTime] If it should make the time code of the whole queue */ getTimeCode(message: Message, queueTime?: boolean): { current: string; end: string } { @@ -827,7 +828,7 @@ export class Player extends EventEmitter { /** * Creates progressbar - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {PlayerProgressbarOptions} [options] Progressbar options */ createProgressBar(message: Message, options?: PlayerProgressbarOptions): string { @@ -891,7 +892,7 @@ export class Player extends EventEmitter { /** * Toggle autoplay for youtube streams - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object * @param {Boolean} enable Enable/Disable autoplay */ setAutoPlay(message: Message, enable: boolean): boolean { @@ -1183,7 +1184,7 @@ export default Player; /** * Emitted when a track starts * @event Player#trackStart - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {Track} track The track * @param {Queue} queue The queue */ @@ -1191,33 +1192,33 @@ export default Player; /** * Emitted when a playlist is started * @event Player#queueCreate - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {Queue} queue The queue */ /** * Emitted when the bot is awaiting search results * @event Player#searchResults - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {String} query The query * @param {Track[]} tracks The tracks - * @param {Discord.Collector} collector The collector + * @param {DiscordCollector} collector The collector */ /** * Emitted when the user has sent an invalid response for search results * @event Player#searchInvalidResponse - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {String} query The query * @param {Track[]} tracks The tracks * @param {String} invalidResponse The `invalidResponse` string - * @param {Discord.MessageCollector} collector The collector + * @param {DiscordMessageCollector} collector The collector */ /** * Emitted when the bot has stopped awaiting search results (timeout) * @event Player#searchCancel - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {String} query The query * @param {Track[]} tracks The tracks */ @@ -1225,34 +1226,34 @@ export default Player; /** * Emitted when the bot can't find related results to the query * @event Player#noResults - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {String} query The query */ /** * Emitted when the bot is disconnected from the channel * @event Player#botDisconnect - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message */ /** * Emitted when the channel of the bot is empty * @event Player#channelEmpty - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {Queue} queue The queue */ /** * Emitted when the queue of the server is ended * @event Player#queueEnd - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {Queue} queue The queue */ /** * Emitted when a track is added to the queue * @event Player#trackAdd - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {Queue} queue The queue * @param {Track} track The track */ @@ -1260,7 +1261,7 @@ export default Player; /** * Emitted when a playlist is added to the queue * @event Player#playlistAdd - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message * @param {Queue} queue The queue * @param {Object} playlist The playlist */ @@ -1269,21 +1270,21 @@ export default Player; * Emitted when an error is triggered * @event Player#error * @param {String} error It can be `NotConnected`, `UnableToJoin`, `NotPlaying`, `ParseError`, `LiveVideo` or `VideoUnavailable`. - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message */ /** * Emitted when discord-player attempts to parse playlist contents (mostly soundcloud playlists) * @event Player#playlistParseStart * @param {Object} playlist Raw playlist (unparsed) - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message */ /** * Emitted when discord-player finishes parsing playlist contents (mostly soundcloud playlists) * @event Player#playlistParseEnd * @param {Object} playlist The playlist data (parsed) - * @param {Discord.Message} message The message + * @param {DiscordMessage} message The message */ /** @@ -1311,7 +1312,7 @@ export default Player; * @property {String} url The url * @property {String} duration The duration * @property {Number} views The view count - * @property {Discord.User} requestedBy The user who requested this track + * @property {DiscordUser} requestedBy The user who requested this track * @property {Boolean} fromPlaylist If this track came from a playlist * @property {TrackSource} [source] The track source * @property {string|Readable} [engine] The stream engine diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 50d64b8..c29f028 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -26,6 +26,7 @@ export class Queue extends EventEmitter { public firstMessage: Message; /** + * If autoplay is enabled in this queue * @type {boolean} */ public autoPlay = false; @@ -33,7 +34,7 @@ export class Queue extends EventEmitter { /** * Queue constructor * @param {Player} player The player that instantiated this Queue - * @param {Discord.Message} message The message object + * @param {DiscordMessage} message The message object */ constructor(player: Player, message: Message) { super(); @@ -42,13 +43,13 @@ export class Queue extends EventEmitter { /** * ID of the guild assigned to this queue - * @type {Discord.Snowflake} + * @type {DiscordSnowflake} */ this.guildID = message.guild.id; /** * The voice connection of this queue - * @type {Discord.VoiceConnection} + * @type {DiscordVoiceConnection} */ this.voiceConnection = null; @@ -108,7 +109,7 @@ export class Queue extends EventEmitter { /** * The initial message object - * @type {Discord.Message} + * @type {DiscordMessage} */ this.firstMessage = message; diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index c257374..9327330 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -54,7 +54,7 @@ export class Track { /** * Person who requested this track - * @type {Discord.User} + * @type {DiscordUser} */ public requestedBy!: User; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index d569a22..d33fb53 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -182,7 +182,7 @@ export class Util { /** * Checks if the given voice channel is empty - * @param {Discord.VoiceChannel} channel The voice channel + * @param {DiscordVoiceChannel} channel The voice channel */ static isVoiceEmpty(channel: VoiceChannel): boolean { return channel.members.filter((member) => !member.user.bot).size === 0; From c129cccdfe82cab378f6d2adccb42d7d18ba17ad Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 13:00:09 +0545 Subject: [PATCH 096/131] fix this again --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index 18167ab..05a85be 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -60,7 +60,7 @@ export class Player extends EventEmitter { /** * Creates new Player instance * @param {DiscordClient} client The discord.js client - * @param {PlayerOptionsType} options Player options + * @param {PlayerOptions} options Player options */ constructor(client: Client, options?: PlayerOptionsType) { super(); From 1c99c751cf4b678204f449f80b176c77b040413a Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 13:08:13 +0545 Subject: [PATCH 097/131] def --- docs/extractors/extractor.md | 44 ----------- docs/general/Welcome.md | 139 ----------------------------------- docs/index.yml | 8 -- 3 files changed, 191 deletions(-) delete mode 100644 docs/extractors/extractor.md delete mode 100644 docs/general/Welcome.md delete mode 100644 docs/index.yml diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md deleted file mode 100644 index c5222f0..0000000 --- a/docs/extractors/extractor.md +++ /dev/null @@ -1,44 +0,0 @@ -# Discord Player Extractor API -The Extractor API allows you to build your own stream extractor for **Discord Player**. - -# Example Extractor -Your extractor should have 2 methods (required): - - `validate(query): boolean` - - This method is called by Discord Player while validating the query provided via `Player.play()`. (Note that only `string` queries are passed to your extractor) - - - `getInfo(query): object` - - This method is used by Discord Player to create `Track` object. You can return your data here that gets passed to `Track`. - Your info must be similar to this: - - ```js - { - // the title - title: "Extracted by custom extractor", - // the duration in ms - duration: 20000, - // the thumbnail - thumbnail: data.thumbnail, - // engine, can be Readable streams or link to raw stream that gets played - engine: data.streamURL, - // number of views - views: 0, - // author of this stream - author: data.artist.name, - // description - description: "", - // link of this stream - url: data.url - } - ``` - - `important: boolean` - - You can mark your Extractor as `important` by adding `important: true` to your extractor object. Doing this will disable rest of the extractors that comes after your extractor and use your extractor to get data. By default, it is set to `false`. - - - `version: string` - - This should be the version of your extractor. It is not really important and is set to `0.0.0` by default. - -# Examples -### You can check out **[@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors)** \ No newline at end of file diff --git a/docs/general/Welcome.md b/docs/general/Welcome.md deleted file mode 100644 index 2075526..0000000 --- a/docs/general/Welcome.md +++ /dev/null @@ -1,139 +0,0 @@ -# Discord Player -Complete framework to facilitate music commands using **[discord.js](https://discord.js.org)**. - -[![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) -[![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) - -## Installation - -### Install **[discord-player](https://npmjs.com/package/discord-player)** - -```sh -$ npm install --save discord-player -``` - -### Install **[@discordjs/opus](https://npmjs.com/package/@discordjs/opus)** - -```sh -$ npm install --save @discordjs/opus -``` - -### Install FFmpeg or Avconv -- Official FFMPEG Website: **[https://www.ffmpeg.org/download.html](https://www.ffmpeg.org/download.html)** - -- Node Module (FFMPEG): **[https://npmjs.com/package/ffmpeg-static](https://npmjs.com/package/ffmpeg-static)** - -- Avconv: **[https://libav.org/download](https://libav.org/download)** - -# Features -- Simple & easy to use 🤘 -- Beginner friendly 😱 -- Audio filters 🎸 -- Lightweight 🛬 -- Custom extractors support 🌌 -- Lyrics 📃 -- Multiple sources support ✌ -- Play in multiple servers at the same time 🚗 - -## [Documentation](https://discord-player.js.org) - -## Getting Started - -Here is the code you will need to get started with discord-player. Then, you will be able to use `client.player` everywhere in your code! - -```js -const Discord = require("discord.js"), -client = new Discord.Client, -settings = { - prefix: "!", - token: "Your Discord Token" -}; - -const { Player } = require("discord-player"); - -// Create a new Player (you don't need any API Key) -const player = new Player(client); - -// To easily access the player -client.player = player; - -// add the trackStart event so when a song will be played this message will be sent -client.player.on("trackStart", (message, track) => message.channel.send(`Now playing ${track.title}...`)) - -client.once("ready", () => { - console.log("I'm ready !"); -}); - -client.on("message", async (message) => { - - const args = message.content.slice(settings.prefix.length).trim().split(/ +/g); - const command = args.shift().toLowerCase(); - - // !play Despacito - // will play the song "Despacito" in the voice channel - if(command === "play"){ - client.player.play(message, args[0]); - // as we registered the event above, no need to send a success message here - } - -}); - -client.login(settings.token); -``` - -## Supported websites - -By default, discord-player supports **YouTube**, **Spotify** and **SoundCloud** streams only. - -### Optional dependencies - -Discord Player provides an **Extractor API** that enables you to use your custom stream extractor with it. Some packages have been made by the community to add new features using this API. - -#### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) (optional) - -Optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. -You just need to install it using `npm i --save @discord-player/extractor` (discord-player will automatically detect and use it). - -#### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) (optional) - -`@discord-player/downloader` is an optional package that brings support for +700 websites. The documentation is available [here](https://github.com/DevSnowflake/discord-player-downloader). - -## Examples of bots made with Discord Player - -These bots are made by the community, they can help you build your own! - -* [AtlantaBot](https://github.com/Androz2091/AtlantaBot) by [Androz2091](https://github.com/Androz2091) -* [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) -* [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) - -## FAQ - -### How to use cookies - -```js -const player = new Player(client, { - ytdlDownloadOptions: { - requestOptions: { - headers: { - cookie: "YOUR_YOUTUBE_COOKIE" - } - } - } -}); -``` - -### How to use custom proxies - -```js -const HttpsProxyAgent = require("https-proxy-agent"); - -// Remove "user:pass@" if you don't need to authenticate to your proxy. -const proxy = "http://user:pass@111.111.111.111:8080"; -const agent = HttpsProxyAgent(proxy); - -const player = new Player(client, { - ytdlDownloadOptions: { - requestOptions: { agent } - } -}); -``` diff --git a/docs/index.yml b/docs/index.yml deleted file mode 100644 index 7ecd859..0000000 --- a/docs/index.yml +++ /dev/null @@ -1,8 +0,0 @@ -- name: General - files: - - name: Welcome - path: Welcome.md -- name: Extractors - files: - - name: Extractors - path: extractor.md \ No newline at end of file From ada97a2286eb626d02e39c4d857b904f122637fc Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 13:09:52 +0545 Subject: [PATCH 098/131] rebuild --- docs/extractors/extractor.md | 44 +++++++++++ docs/general/welcome.md | 139 +++++++++++++++++++++++++++++++++++ docs/index.yml | 8 ++ 3 files changed, 191 insertions(+) create mode 100644 docs/extractors/extractor.md create mode 100644 docs/general/welcome.md create mode 100644 docs/index.yml diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md new file mode 100644 index 0000000..c5222f0 --- /dev/null +++ b/docs/extractors/extractor.md @@ -0,0 +1,44 @@ +# Discord Player Extractor API +The Extractor API allows you to build your own stream extractor for **Discord Player**. + +# Example Extractor +Your extractor should have 2 methods (required): + - `validate(query): boolean` + + This method is called by Discord Player while validating the query provided via `Player.play()`. (Note that only `string` queries are passed to your extractor) + + - `getInfo(query): object` + + This method is used by Discord Player to create `Track` object. You can return your data here that gets passed to `Track`. + Your info must be similar to this: + + ```js + { + // the title + title: "Extracted by custom extractor", + // the duration in ms + duration: 20000, + // the thumbnail + thumbnail: data.thumbnail, + // engine, can be Readable streams or link to raw stream that gets played + engine: data.streamURL, + // number of views + views: 0, + // author of this stream + author: data.artist.name, + // description + description: "", + // link of this stream + url: data.url + } + ``` + - `important: boolean` + + You can mark your Extractor as `important` by adding `important: true` to your extractor object. Doing this will disable rest of the extractors that comes after your extractor and use your extractor to get data. By default, it is set to `false`. + + - `version: string` + + This should be the version of your extractor. It is not really important and is set to `0.0.0` by default. + +# Examples +### You can check out **[@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors)** \ No newline at end of file diff --git a/docs/general/welcome.md b/docs/general/welcome.md new file mode 100644 index 0000000..2075526 --- /dev/null +++ b/docs/general/welcome.md @@ -0,0 +1,139 @@ +# Discord Player +Complete framework to facilitate music commands using **[discord.js](https://discord.js.org)**. + +[![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) +[![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) + +## Installation + +### Install **[discord-player](https://npmjs.com/package/discord-player)** + +```sh +$ npm install --save discord-player +``` + +### Install **[@discordjs/opus](https://npmjs.com/package/@discordjs/opus)** + +```sh +$ npm install --save @discordjs/opus +``` + +### Install FFmpeg or Avconv +- Official FFMPEG Website: **[https://www.ffmpeg.org/download.html](https://www.ffmpeg.org/download.html)** + +- Node Module (FFMPEG): **[https://npmjs.com/package/ffmpeg-static](https://npmjs.com/package/ffmpeg-static)** + +- Avconv: **[https://libav.org/download](https://libav.org/download)** + +# Features +- Simple & easy to use 🤘 +- Beginner friendly 😱 +- Audio filters 🎸 +- Lightweight 🛬 +- Custom extractors support 🌌 +- Lyrics 📃 +- Multiple sources support ✌ +- Play in multiple servers at the same time 🚗 + +## [Documentation](https://discord-player.js.org) + +## Getting Started + +Here is the code you will need to get started with discord-player. Then, you will be able to use `client.player` everywhere in your code! + +```js +const Discord = require("discord.js"), +client = new Discord.Client, +settings = { + prefix: "!", + token: "Your Discord Token" +}; + +const { Player } = require("discord-player"); + +// Create a new Player (you don't need any API Key) +const player = new Player(client); + +// To easily access the player +client.player = player; + +// add the trackStart event so when a song will be played this message will be sent +client.player.on("trackStart", (message, track) => message.channel.send(`Now playing ${track.title}...`)) + +client.once("ready", () => { + console.log("I'm ready !"); +}); + +client.on("message", async (message) => { + + const args = message.content.slice(settings.prefix.length).trim().split(/ +/g); + const command = args.shift().toLowerCase(); + + // !play Despacito + // will play the song "Despacito" in the voice channel + if(command === "play"){ + client.player.play(message, args[0]); + // as we registered the event above, no need to send a success message here + } + +}); + +client.login(settings.token); +``` + +## Supported websites + +By default, discord-player supports **YouTube**, **Spotify** and **SoundCloud** streams only. + +### Optional dependencies + +Discord Player provides an **Extractor API** that enables you to use your custom stream extractor with it. Some packages have been made by the community to add new features using this API. + +#### [@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors) (optional) + +Optional package that adds support for `vimeo`, `reverbnation`, `facebook`, `attachment links` and `lyrics`. +You just need to install it using `npm i --save @discord-player/extractor` (discord-player will automatically detect and use it). + +#### [@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader) (optional) + +`@discord-player/downloader` is an optional package that brings support for +700 websites. The documentation is available [here](https://github.com/DevSnowflake/discord-player-downloader). + +## Examples of bots made with Discord Player + +These bots are made by the community, they can help you build your own! + +* [AtlantaBot](https://github.com/Androz2091/AtlantaBot) by [Androz2091](https://github.com/Androz2091) +* [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) +* [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) + +## FAQ + +### How to use cookies + +```js +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { + headers: { + cookie: "YOUR_YOUTUBE_COOKIE" + } + } + } +}); +``` + +### How to use custom proxies + +```js +const HttpsProxyAgent = require("https-proxy-agent"); + +// Remove "user:pass@" if you don't need to authenticate to your proxy. +const proxy = "http://user:pass@111.111.111.111:8080"; +const agent = HttpsProxyAgent(proxy); + +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { agent } + } +}); +``` diff --git a/docs/index.yml b/docs/index.yml new file mode 100644 index 0000000..93b985f --- /dev/null +++ b/docs/index.yml @@ -0,0 +1,8 @@ +- name: General + files: + - name: Welcome + path: welcome.md +- name: Extractors + files: + - name: Extractors API + path: extractor.md \ No newline at end of file From 78b9b9ebc818c0f5c289b84f3b871d15973fac13 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 14:15:40 +0545 Subject: [PATCH 099/131] more pages --- docs/extractors/extractor.md | 41 ++++++++++++++++++++++++++++++++---- docs/index.yml | 8 ++++++- docs/youtube/cookies.md | 15 +++++++++++++ docs/youtube/proxy.md | 16 ++++++++++++++ 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 docs/youtube/cookies.md create mode 100644 docs/youtube/proxy.md diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md index c5222f0..c4c5bd0 100644 --- a/docs/extractors/extractor.md +++ b/docs/extractors/extractor.md @@ -19,17 +19,17 @@ Your extractor should have 2 methods (required): // the duration in ms duration: 20000, // the thumbnail - thumbnail: data.thumbnail, + thumbnail: "some thumbnail link", // engine, can be Readable streams or link to raw stream that gets played - engine: data.streamURL, + engine: "someStreamLink", // number of views views: 0, // author of this stream - author: data.artist.name, + author: "Some Artist", // description description: "", // link of this stream - url: data.url + url: "Some Link" } ``` - `important: boolean` @@ -40,5 +40,38 @@ Your extractor should have 2 methods (required): This should be the version of your extractor. It is not really important and is set to `0.0.0` by default. +# Loading Extractors +Discord Player Extractors can be loaded using `Player.use(ExtractorName, Extractor)` method. + +## Register Extractor + +```js +const myExtractor = { + version: "1.0.0", + important: false, + validate: (query) => true, + getInfo: async (query) => { + return { + title: "Extracted by custom extractor", + duration: 20000, + thumbnail: "some thumbnail link", + engine: "someStreamLink", + views: 0, + author: "Some Artist", + description: "", + url: "Some Link" + }; + } +}; + +player.use("GiveItSomeName", myExtractor); +``` + +## Remove Extractor + +```js +player.unuse("GiveItSomeName"); +``` + # Examples ### You can check out **[@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors)** \ No newline at end of file diff --git a/docs/index.yml b/docs/index.yml index 93b985f..f367636 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -5,4 +5,10 @@ - name: Extractors files: - name: Extractors API - path: extractor.md \ No newline at end of file + path: extractor.md +- name: YouTube + files: + - name: Using Cookies + path: cookies.md + - name: Using Proxy + path: proxy.md \ No newline at end of file diff --git a/docs/youtube/cookies.md b/docs/youtube/cookies.md new file mode 100644 index 0000000..3149972 --- /dev/null +++ b/docs/youtube/cookies.md @@ -0,0 +1,15 @@ +# Using Cookies to avoid 429 + +```js +const { Player } = require("discord-player"); + +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { + headers: { + cookie: "YOUR_YOUTUBE_COOKIE" + } + } + } +}); +``` \ No newline at end of file diff --git a/docs/youtube/proxy.md b/docs/youtube/proxy.md new file mode 100644 index 0000000..3dc8ba5 --- /dev/null +++ b/docs/youtube/proxy.md @@ -0,0 +1,16 @@ +# Using Proxy to avoid 429 + +```js +const { Player } = require("discord-player"); +const HttpsProxyAgent = require("https-proxy-agent"); + +// Remove "user:pass@" if you don't need to authenticate to your proxy. +const proxy = "http://user:pass@111.111.111.111:8080"; +const agent = HttpsProxyAgent(proxy); + +const player = new Player(client, { + ytdlDownloadOptions: { + requestOptions: { agent } + } +}); +``` \ No newline at end of file From d3fdc045e2c15066012f67082a2b51eb72dd02dd Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 14:15:54 +0545 Subject: [PATCH 100/131] prettier --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index 05a85be..fcba88a 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1393,4 +1393,4 @@ export default Player; * @property {Number} hours The time in hours * @property {Number} minutes The time in minutes * @property {Number} seconds The time in seconds - */ \ No newline at end of file + */ From 32a7be23a1a573eaec4ec37d60932d77ecbe8381 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 14:55:44 +0545 Subject: [PATCH 101/131] fix jsdoc --- src/Player.ts | 56 +++++++++++--- src/Structures/ExtractorModel.ts | 2 + src/Structures/Queue.ts | 11 ++- src/Structures/Track.ts | 122 +++++++++++++++++-------------- src/utils/Util.ts | 11 +++ 5 files changed, 132 insertions(+), 70 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index fcba88a..5c23749 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -26,16 +26,7 @@ import YouTube from 'youtube-sr'; const SoundCloud = new SoundCloudClient(); export class Player extends EventEmitter { - /** - * The discord client that instantiated this player - * @type {DiscordClient} - */ public client: Client; - - /** - * The player options - * @type {PlayerOptions} - */ public options: PlayerOptionsType; /** @@ -45,7 +36,7 @@ export class Player extends EventEmitter { /** * The collection of queues in this player - * @type {DiscordCollection} + * @type {DiscordCollection} */ public queues = new Collection(); private _resultsCollectors = new Collection>(); @@ -53,7 +44,7 @@ export class Player extends EventEmitter { /** * The extractor model collection - * @type {DiscordCollection} + * @type {DiscordCollection} */ public Extractors = new Collection(); @@ -65,16 +56,30 @@ export class Player extends EventEmitter { constructor(client: Client, options?: PlayerOptionsType) { super(); + /** + * The discord client that instantiated this player + * @name Player#client + * @type {DiscordClient} + * @readonly + */ Object.defineProperty(this, 'client', { value: client, enumerable: false }); + /** + * The player options + * @type {PlayerOptions} + */ this.options = Object.assign({}, PlayerOptions, options ?? {}); // check FFmpeg void Util.alertFFmpeg(); + /** + * Audio filters + * @type {Object} + */ this.filters = AudioFilters; this.client.on('voiceStateUpdate', (o, n) => void this._handleVoiceStateUpdate(o, n)); @@ -86,6 +91,10 @@ export class Player extends EventEmitter { } } + /** + * The audio filters + * @returns {Object} + */ static get AudioFilters(): typeof AudioFilters { return AudioFilters; } @@ -94,6 +103,7 @@ export class Player extends EventEmitter { * Define custom extractor in this player * @param {String} extractorName The extractor name * @param {any} extractor The extractor itself + * @returns {Player} */ use(extractorName: string, extractor: any): Player { if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); @@ -113,6 +123,7 @@ export class Player extends EventEmitter { /** * Remove existing extractor from this player * @param {String} extractorName The extractor name + * @returns {Boolean} */ unuse(extractorName: string): boolean { if (!extractorName) throw new PlayerError('Missing extractor name!', 'PlayerExtractorError'); @@ -369,6 +380,7 @@ export class Player extends EventEmitter { * @param {string|Track} query Search query, can be `Player.Track` instance * @param {Boolean} [firstResult] If it should play the first result * @example await player.play(message, "never gonna give you up", true) + * @returns {Promise} */ async play(message: Message, query: string | Track, firstResult?: boolean): Promise { if (!message) throw new PlayerError('Play function needs message'); @@ -451,6 +463,7 @@ export class Player extends EventEmitter { /** * Checks if this player is playing in a server * @param {DiscordMessage} message The message object + * @returns {Boolean} */ isPlaying(message: Message): boolean { return this.queues.some((g) => g.guildID === message.guild.id); @@ -459,6 +472,7 @@ export class Player extends EventEmitter { /** * Returns guild queue object * @param {DiscordMessage} message The message object + * @returns {Queue} */ getQueue(message: Message): Queue { return this.queues.find((g) => g.guildID === message.guild.id); @@ -468,6 +482,7 @@ export class Player extends EventEmitter { * Sets audio filters in this player * @param {DiscordMessage} message The message object * @param {QueueFilters} newFilters Audio filters object + * @returns {Promise} */ setFilters(message: Message, newFilters: QueueFilters): Promise { return new Promise((resolve) => { @@ -503,6 +518,7 @@ export class Player extends EventEmitter { * Sets track position * @param {DiscordMessage} message The message object * @param {Number} time Time in ms to set + * @returns {Promise} */ setPosition(message: Message, time: number): Promise { return new Promise((resolve) => { @@ -526,6 +542,7 @@ export class Player extends EventEmitter { * Sets track position * @param {DiscordMessage} message The message object * @param {Number} time Time in ms to set + * @returns {Promise} */ seek(message: Message, time: number): Promise { return this.setPosition(message, time); @@ -534,6 +551,7 @@ export class Player extends EventEmitter { /** * Skips current track * @param {DiscordMessage} message The message object + * @returns {Boolean} */ skip(message: Message): boolean { const queue = this.getQueue(message); @@ -556,6 +574,7 @@ export class Player extends EventEmitter { * Moves to a new voice channel * @param {DiscordMessage} message The message object * @param {DiscordVoiceChannel} channel New voice channel to move to + * @returns {Boolean} */ moveTo(message: Message, channel?: VoiceChannel): boolean { if (!channel || channel.type !== 'voice') return; @@ -582,6 +601,7 @@ export class Player extends EventEmitter { /** * Pause the playback * @param {DiscordMessage} message The message object + * @returns {Boolean} */ pause(message: Message): boolean { const queue = this.getQueue(message); @@ -602,6 +622,7 @@ export class Player extends EventEmitter { /** * Resume the playback * @param {DiscordMessage} message The message object + * @returns {Boolean} */ resume(message: Message): boolean { const queue = this.getQueue(message); @@ -622,6 +643,7 @@ export class Player extends EventEmitter { /** * Stops the player * @param {DiscordMessage} message The message object + * @returns {Boolean} */ stop(message: Message): boolean { const queue = this.getQueue(message); @@ -647,6 +669,7 @@ export class Player extends EventEmitter { * Sets music volume * @param {DiscordMessage} message The message object * @param {Number} percent The volume percentage/amount to set + * @returns {Boolean} */ setVolume(message: Message, percent: number): boolean { const queue = this.getQueue(message); @@ -668,6 +691,7 @@ export class Player extends EventEmitter { /** * Clears the queue * @param {DiscordMessage} message The message object + * @returns {Boolean} */ clearQueue(message: Message): boolean { const queue = this.getQueue(message); @@ -684,6 +708,7 @@ export class Player extends EventEmitter { /** * Plays previous track * @param {DiscordMessage} message The message object + * @returns {Boolean} */ back(message: Message): boolean { const queue = this.getQueue(message); @@ -724,6 +749,7 @@ export class Player extends EventEmitter { * Sets loop mode * @param {DiscordMessage} message The message object * @param {Boolean} enabled If it should enable the loop mode + * @returns {Boolean} */ setLoopMode(message: Message, enabled: boolean): boolean { const queue = this.getQueue(message); @@ -740,6 +766,7 @@ export class Player extends EventEmitter { /** * Returns currently playing track * @param {DiscordMessage} message The message object + * @returns {Track} */ nowPlaying(message: Message): Track { const queue = this.getQueue(message); @@ -754,6 +781,7 @@ export class Player extends EventEmitter { /** * Shuffles the queue * @param {DiscordMessage} message The message object + * @returns {Queue} */ shuffle(message: Message): Queue { const queue = this.getQueue(message); @@ -778,6 +806,7 @@ export class Player extends EventEmitter { * Removes specified track * @param {DiscordMessage} message The message object * @param {Track|number} track The track object/id to remove + * @returns {Track} */ remove(message: Message, track: Track | number): Track { const queue = this.getQueue(message); @@ -806,6 +835,7 @@ export class Player extends EventEmitter { * Returns time code of currently playing song * @param {DiscordMessage} message The message object * @param {Boolean} [queueTime] If it should make the time code of the whole queue + * @returns {Object} */ getTimeCode(message: Message, queueTime?: boolean): { current: string; end: string } { const queue = this.getQueue(message); @@ -830,6 +860,7 @@ export class Player extends EventEmitter { * Creates progressbar * @param {DiscordMessage} message The message object * @param {PlayerProgressbarOptions} [options] Progressbar options + * @returns {String} */ createProgressBar(message: Message, options?: PlayerProgressbarOptions): string { const queue = this.getQueue(message); @@ -879,6 +910,7 @@ export class Player extends EventEmitter { * @param {String} query Search query * @example const lyrics = await player.lyrics("alan walker faded") * message.channel.send(lyrics.lyrics); + * @returns {Promise} */ async lyrics(query: string): Promise { const extractor = Util.require('@discord-player/extractor'); @@ -894,6 +926,7 @@ export class Player extends EventEmitter { * Toggle autoplay for youtube streams * @param {DiscordMessage} message The message object * @param {Boolean} enable Enable/Disable autoplay + * @returns {boolean} */ setAutoPlay(message: Message, enable: boolean): boolean { const queue = this.getQueue(message); @@ -906,6 +939,7 @@ export class Player extends EventEmitter { /** * Player stats + * @returns {PlayerStats} */ getStats(): PlayerStats { return { diff --git a/src/Structures/ExtractorModel.ts b/src/Structures/ExtractorModel.ts index 00d5902..578470a 100644 --- a/src/Structures/ExtractorModel.ts +++ b/src/Structures/ExtractorModel.ts @@ -22,6 +22,7 @@ class ExtractorModel { /** * 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); @@ -42,6 +43,7 @@ class ExtractorModel { /** * 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)); diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index c29f028..1cee68b 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -6,9 +6,6 @@ import { Track } from './Track'; import { QueueFilters } from '../types/types'; export class Queue extends EventEmitter { - /** - * The player that instantiated this Queue - */ public player!: Player; public guildID: Snowflake; public voiceConnection?: VoiceConnection; @@ -39,6 +36,12 @@ export class Queue extends EventEmitter { constructor(player: Player, message: Message) { super(); + /** + * The player that instantiated this Queue + * @name Queue#player + * @type {Player} + * @readonly + */ Object.defineProperty(this, 'player', { value: player, enumerable: false }); /** @@ -191,7 +194,7 @@ export class Queue extends EventEmitter { /** * String representation of this Queue - * @type {String} + * @returns {String} */ toString(): string { return ``; diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 9327330..9ac73ad 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -4,70 +4,16 @@ import { TrackData } from '../types/types'; import Queue from './Queue'; export class Track { - /** - * The player that instantiated this Track - * @type {Player} - */ public player!: Player; - - /** - * Title of this track - * @type {String} - */ public title!: string; - - /** - * Description of this track - * @type {String} - */ public description!: string; - - /** - * Author of this track - * @type {String} - */ public author!: string; - - /** - * Link of this track - * @type {String} - */ public url!: string; - - /** - * Thumbnail of this track - * @type {String} - */ public thumbnail!: string; - - /** - * Duration of this track - * @type {String} - */ public duration!: string; - - /** - * View count of this track - * @type {Number} - */ public views!: number; - - /** - * Person who requested this track - * @type {DiscordUser} - */ public requestedBy!: User; - - /** - * If this track belongs to a playlist - * @type {Boolean} - */ public fromPlaylist!: boolean; - - /** - * Raw data of this track - * @type {TrackData} - */ public raw!: TrackData; /** @@ -76,8 +22,74 @@ export class Track { * @param {TrackData} data Track data */ constructor(player: Player, data: TrackData) { + /** + * The player that instantiated this Queue + * @name Track#player + * @type {Player} + * @readonly + */ Object.defineProperty(this, 'player', { value: player, enumerable: false }); + /** + * Title of this track + * @name Track#title + * @type {String} + */ + + /** + * Description of this track + * @name Track#description + * @type {String} + */ + + /** + * Author of this track + * @name Track#author + * @type {String} + */ + + /** + * URL of this track + * @name Track#url + * @type {String} + */ + + /** + * Thumbnail of this track + * @name Track#thumbnail + * @type {String} + */ + + /** + * Duration of this track + * @name Track#duration + * @type {String} + */ + + /** + * Views count of this track + * @name Track#views + * @type {Number} + */ + + /** + * Person who requested this track + * @name Track#requestedBy + * @type {DiscordUser} + */ + + /** + * If this track belongs to playlist + * @name Track#fromPlaylist + * @type {Boolean} + */ + + /** + * Raw track data + * @name Track#raw + * @type {TrackData} + */ + void this._patch(data); } @@ -124,7 +136,7 @@ export class Track { /** * String representation of this track - * @type {String} + * @returns {String} */ toString(): string { return `${this.title} by ${this.author}`; diff --git a/src/utils/Util.ts b/src/utils/Util.ts index d33fb53..7826f5d 100644 --- a/src/utils/Util.ts +++ b/src/utils/Util.ts @@ -25,6 +25,7 @@ export class Util { /** * Checks FFmpeg Version * @param {Boolean} [force] If it should forcefully get the version + * @returns {String} */ static getFFmpegVersion(force?: boolean): string { try { @@ -39,6 +40,7 @@ export class Util { /** * Checks FFmpeg * @param {Boolean} [force] If it should forcefully get the version + * @returns {Boolean} */ static checkFFmpeg(force?: boolean): boolean { const version = Util.getFFmpegVersion(force); @@ -60,6 +62,7 @@ export class Util { /** * Resolves query type * @param {String} query The query + * @returns {QueryType} */ static getQueryType(query: string): QueryType { if (SoundcloudValidateURL(query) && !query.includes('/sets/')) return 'soundcloud_track'; @@ -80,6 +83,7 @@ export class Util { /** * Checks if the given string is url * @param {String} str URL to check + * @returns {Boolean} */ static isURL(str: string): boolean { return str.length < 2083 && attachmentRegex.test(str); @@ -88,6 +92,7 @@ export class Util { /** * Returns Vimeo ID * @param {String} query Vimeo link + * @returns {String} */ static getVimeoID(query: string): string { return Util.getQueryType(query) === 'vimeo' @@ -101,6 +106,7 @@ export class Util { /** * Parses ms time * @param {Number} milliseconds Time to parse + * @returns {TimeData} */ static parseMS(milliseconds: number): TimeData { const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; @@ -116,6 +122,7 @@ export class Util { /** * Creates simple duration string * @param {object} durObj Duration object + * @returns {String} */ static durationString(durObj: object): string { return Object.values(durObj) @@ -161,6 +168,7 @@ export class Util { /** * Checks if this system is running in replit.com + * @returns {Boolean} */ static isRepl(): boolean { if ('DP_REPL_NOCHECK' in process.env) return false; @@ -183,6 +191,7 @@ export class Util { /** * Checks if the given voice channel is empty * @param {DiscordVoiceChannel} channel The voice channel + * @returns {Boolean} */ static isVoiceEmpty(channel: VoiceChannel): boolean { return channel.members.filter((member) => !member.user.bot).size === 0; @@ -191,6 +200,7 @@ export class Util { /** * Builds time code * @param {object} data The data to build time code from + * @returns {String} */ static buildTimeCode(data: any): string { const items = Object.keys(data); @@ -207,6 +217,7 @@ export class Util { /** * Manage CJS require * @param {String} id id to require + * @returns {any} */ static require(id: string): any { try { From 3e5f911ce98305bfab3e455e2dd4d821966d750f Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 14:59:04 +0545 Subject: [PATCH 102/131] fix --- src/Player.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 5c23749..ca5298c 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -25,13 +25,13 @@ import YouTube from 'youtube-sr'; const SoundCloud = new SoundCloudClient(); +/** + * The Player class + * @extends {EventEmitter} + */ export class Player extends EventEmitter { public client: Client; public options: PlayerOptionsType; - - /** - * The audio filters - */ public filters: typeof AudioFilters; /** @@ -91,10 +91,6 @@ export class Player extends EventEmitter { } } - /** - * The audio filters - * @returns {Object} - */ static get AudioFilters(): typeof AudioFilters { return AudioFilters; } From eef4f50144003579c3c432e782df7d50bb9d98e9 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 16:24:51 +0545 Subject: [PATCH 103/131] docs --- docs/extractors/extractor.md | 16 ++++++++++++++-- docs/youtube/cookies.md | 5 ++++- src/Player.ts | 2 +- src/Structures/Track.ts | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/extractors/extractor.md b/docs/extractors/extractor.md index c4c5bd0..9510969 100644 --- a/docs/extractors/extractor.md +++ b/docs/extractors/extractor.md @@ -73,5 +73,17 @@ player.use("GiveItSomeName", myExtractor); player.unuse("GiveItSomeName"); ``` -# Examples -### You can check out **[@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors)** \ No newline at end of file +# Readymade Extractors +## **[@discord-player/extractor](https://github.com/Snowflake107/discord-player-extractors)** +This extractor enables optional sources such as `Discord Attachments`, `Vimeo`, `Facebook` and `Reverbnation`. It also enables the `Lyrics` feature! + +## **[@discord-player/downloader](https://github.com/DevSnowflake/discord-player-downloader)** +This extractor is based on **[YouTube DL](https://youtube-dl.org)**. This extractor enables `700+ websites` support. However, this extractor can get buggy and is not updated frequently. So, it is suggested to make your own extractor if you want to use it! + +```js +const downloader = require("@discord-player/downloader").Downloader; + +player.use("YOUTUBE_DL", downloader); +``` + +> Discord Player auto-detects and uses `@discord-player/extractor` if it is installed! \ No newline at end of file diff --git a/docs/youtube/cookies.md b/docs/youtube/cookies.md index 3149972..2405dcf 100644 --- a/docs/youtube/cookies.md +++ b/docs/youtube/cookies.md @@ -12,4 +12,7 @@ const player = new Player(client, { } } }); -``` \ No newline at end of file +``` + +> Keep in mind that using `cookies` after getting `429` **does not fix the problem**. +> You should use `cookies` before getting `429` which helps to **_reduce_** `Error: Status Code 429` \ No newline at end of file diff --git a/src/Player.ts b/src/Player.ts index ca5298c..1fb1be0 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1232,7 +1232,7 @@ export default Player; * @param {DiscordMessage} message The message * @param {String} query The query * @param {Track[]} tracks The tracks - * @param {DiscordCollector} collector The collector + * @param {DiscordMessageCollector} collector The collector */ /** diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 9ac73ad..b2759f1 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -23,7 +23,7 @@ export class Track { */ constructor(player: Player, data: TrackData) { /** - * The player that instantiated this Queue + * The player that instantiated this Track * @name Track#player * @type {Player} * @readonly From ffa9b347fec6d6715a580c188c8389a7e4234b51 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 16:32:14 +0545 Subject: [PATCH 104/131] some changes --- CONTRIBUTING.md | 4 ++-- package.json | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c1043a4..dd2bd5e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,5 +18,5 @@ We are using **[Prettier](https://prettier.io)** to format the code. # Pull Requests - Use English language - Explain what your update does - -- Run tests, formatting, etc. before making Pull Requests \ No newline at end of file +- Run `npm run docs:test` command to make sure documentation is working +- Format the code properly with `npm run format` \ No newline at end of file diff --git a/package.json b/package.json index 3a1219e..e999bde 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,17 @@ "discord", "volume", "queue", - "youtube" + "youtube", + "discord.js", + "musicbot", + "discord-music-player", + "discord-music", + "music-player", + "youtube-dl", + "ytdl-core", + "ytdl", + "lavalink", + "api" ], "author": "Androz2091", "license": "MIT", From 97c6d9d9959735a4a65765a230d92742bb7d62e5 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 16:33:07 +0545 Subject: [PATCH 105/131] jsdoc --- src/Player.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 1fb1be0..831b4d4 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1232,7 +1232,7 @@ export default Player; * @param {DiscordMessage} message The message * @param {String} query The query * @param {Track[]} tracks The tracks - * @param {DiscordMessageCollector} collector The collector + * @param {DiscordCollector} collector The collector */ /** @@ -1242,7 +1242,7 @@ export default Player; * @param {String} query The query * @param {Track[]} tracks The tracks * @param {String} invalidResponse The `invalidResponse` string - * @param {DiscordMessageCollector} collector The collector + * @param {DiscordCollector} collector The collector */ /** From 4f5d49d677a12c98921fc109ca5bc32eb6ebd52d Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 16:34:16 +0545 Subject: [PATCH 106/131] toString tag --- src/Player.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Player.ts b/src/Player.ts index 831b4d4..b22021a 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1207,6 +1207,10 @@ export class Player extends EventEmitter { }, 1000); }); } + + toString() { + return `` + } } export default Player; From d94752da249eec50728cc97b0cd2a404423fddd5 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 17:29:24 +0545 Subject: [PATCH 107/131] this should fix something --- src/Player.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index b22021a..81841eb 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1335,7 +1335,7 @@ export default Player; */ /** - * @typedef {'soundcloud'|'youtube'|'arbitrary'} TrackSource + * @typedef {('soundcloud'|'youtube'|'arbitrary')} TrackSource */ /** @@ -1359,7 +1359,7 @@ export default Player; */ /** - * @typedef {'soundcloud_track'|'soundcloud_playlist'|'spotify_song'|'spotify_album'|'spotify_playlist'|'youtube_video'|'youtube_playlist'|'vimeo'|'facebook'|'reverbnation'|'attachment'|'youtube_search'} QueryType The query type + * @typedef {('soundcloud_track'|'soundcloud_playlist'|'spotify_song'|'spotify_album'|'spotify_playlist'|'youtube_video'|'youtube_playlist'|'vimeo'|'facebook'|'reverbnation'|'attachment'|'youtube_search')} QueryType The query type */ /** @@ -1411,7 +1411,7 @@ export default Player; * @property {String} [versions.v8] The v8 JavaScript engine version * @property {Object} system The system data * @property {String} [system.arch] The system arch - * @property {'aix'|'android'|'darwin'|'freebsd'|'linux'|'openbsd'|'sunos'|'win32'|'cygwin'|'netbsd'} [system.platform] The system platform + * @property {('aix'|'android'|'darwin'|'freebsd'|'linux'|'openbsd'|'sunos'|'win32'|'cygwin'|'netbsd')} [system.platform] The system platform * @property {Number} [system.cpu] The cpu count * @property {Object} [system.memory] The memory info * @property {String} [system.memory.total] The total memory From fa41ef65ecc89a7487e4da37f530fda69856bcf1 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 17:53:24 +0545 Subject: [PATCH 108/131] FIX! --- package.json | 4 ++-- src/Player.ts | 23 ++++++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e999bde..1f051ae 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "build": "tsc", "format": "prettier --write \"src/**/*.ts\"", "lint": "tslint -p tsconfig.json", - "docs": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json", - "docs:test": "docgen --jsdoc jsdoc.json --source src/*.ts src/**/*.ts --custom docs/index.yml" + "docs": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml --output docs/docs.json", + "docs:test": "docgen --jsdoc jsdoc.json --verbose --source src/*.ts src/**/*.ts --custom docs/index.yml" }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ diff --git a/src/Player.ts b/src/Player.ts index 81841eb..21360d3 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1335,7 +1335,11 @@ export default Player; */ /** - * @typedef {('soundcloud'|'youtube'|'arbitrary')} TrackSource + * The type of Track source, either: + * * `soundcloud` - a stream from SoundCloud + * * `youtube` - a stream from YouTube + * * `arbitrary` - arbitrary stream + * @typedef {String} TrackSource */ /** @@ -1359,7 +1363,20 @@ export default Player; */ /** - * @typedef {('soundcloud_track'|'soundcloud_playlist'|'spotify_song'|'spotify_album'|'spotify_playlist'|'youtube_video'|'youtube_playlist'|'vimeo'|'facebook'|'reverbnation'|'attachment'|'youtube_search')} QueryType The query type + * The query type, either: + * * `soundcloud_track` - a SoundCloud Track + * * `soundcloud_playlist` - a SoundCloud Playlist + * * `spotify_song` - a Spotify Song + * * `spotify_album` - a Spotify album + * * `spotify_playlist` - a Spotify playlist + * * `youtube_video` - a YouTube video + * * `youtube_playlist` - a YouTube playlist + * * `vimeo` - a Vimeo link + * * `facebook` - a Facebook link + * * `reverbnation` - a Reverbnation link + * * `attachment` - an attachment link + * * `youtube_search` - a YouTube search keyword + * @typedef {String} QueryType The query type */ /** @@ -1411,7 +1428,7 @@ export default Player; * @property {String} [versions.v8] The v8 JavaScript engine version * @property {Object} system The system data * @property {String} [system.arch] The system arch - * @property {('aix'|'android'|'darwin'|'freebsd'|'linux'|'openbsd'|'sunos'|'win32'|'cygwin'|'netbsd')} [system.platform] The system platform + * @property {String} [system.platform] The system platform * @property {Number} [system.cpu] The cpu count * @property {Object} [system.memory] The memory info * @property {String} [system.memory.total] The total memory From 17ae6b2fe778e2de0651b0836dda3fba623e7719 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Wed, 21 Apr 2021 18:02:43 +0545 Subject: [PATCH 109/131] add: disableAutoRegister option --- src/Player.ts | 12 ++++++++---- src/types/types.ts | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Player.ts b/src/Player.ts index 21360d3..1455a6d 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -85,9 +85,11 @@ export class Player extends EventEmitter { this.client.on('voiceStateUpdate', (o, n) => void this._handleVoiceStateUpdate(o, n)); // auto detect @discord-player/extractor - let nv: any; - if ((nv = Util.require('@discord-player/extractor'))) { - ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => void this.use(ext, nv[ext])); + if (!this.options.disableAutoRegister) { + let nv: any; + if ((nv = Util.require('@discord-player/extractor'))) { + ['Attachment', 'Facebook', 'Reverbnation', 'Vimeo'].forEach((ext) => void this.use(ext, nv[ext])); + } } } @@ -903,6 +905,7 @@ export class Player extends EventEmitter { /** * Gets lyrics of a song + * You need to have `@discord-player/extractor` installed in order to use this method! * @param {String} query Search query * @example const lyrics = await player.lyrics("alan walker faded") * message.channel.send(lyrics.lyrics); @@ -1209,7 +1212,7 @@ export class Player extends EventEmitter { } toString() { - return `` + return ``; } } @@ -1332,6 +1335,7 @@ export default Player; * @property {Boolean} [enableLive=false] If it should enable live videos support * @property {YTDLDownloadOptions} [ytdlDownloadOptions={}] The download options passed to `ytdl-core` * @property {Boolean} [useSafeSearch=false] If it should use `safe search` method for youtube searches + * @property {Boolean} [disableAutoRegister=false] If it should disable auto-registeration of `@discord-player/extractor` */ /** diff --git a/src/types/types.ts b/src/types/types.ts index 5be7d34..81ee970 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -12,6 +12,7 @@ export interface PlayerOptions { enableLive?: boolean; ytdlDownloadOptions?: downloadOptions; useSafeSearch?: boolean; + disableAutoRegister?: boolean; } export type FiltersName = keyof QueueFilters; From 705443fa7ed9c24bdb8e8fb976102c2255397fbe Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 24 Apr 2021 00:12:51 +0545 Subject: [PATCH 110/131] jump peature --- src/Player.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Player.ts b/src/Player.ts index 1455a6d..eca3af4 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -970,6 +970,22 @@ export class Player extends EventEmitter { }; } + /** + * Jumps to particular track + * @param {DiscordMessage} message The message + * @param {Track|number} track The track to jump to + * @returns {boolean} + */ + jump(message: Message, track: Track | number): boolean { + const toJUMP = this.remove(message, track); + const queue = this.getQueue(message); + if (!toJUMP || !queue) throw new PlayerError('Track not found'); + + queue.tracks.splice(1, 0, toJUMP); + + return this.skip(message); + } + private _handleVoiceStateUpdate(oldState: VoiceState, newState: VoiceState): void { const queue = this.queues.find((g) => g.guildID === oldState.guild.id); if (!queue) return; From c7b43ddce52d0b8c6632872fbbc35005ef247aed Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 24 Apr 2021 00:15:45 +0545 Subject: [PATCH 111/131] jump feature --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index eca3af4..42921b4 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -979,7 +979,7 @@ export class Player extends EventEmitter { jump(message: Message, track: Track | number): boolean { const toJUMP = this.remove(message, track); const queue = this.getQueue(message); - if (!toJUMP || !queue) throw new PlayerError('Track not found'); + if (!toJUMP || !queue) throw new PlayerError('Specified Track not found'); queue.tracks.splice(1, 0, toJUMP); From c93c25e897e5d373b4913cf0cdfc3c2c225d88c6 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 24 Apr 2021 10:04:33 +0545 Subject: [PATCH 112/131] fix live content for searches --- src/Player.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index 42921b4..eff1d9b 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -1166,7 +1166,6 @@ export class Player extends EventEmitter { let newStream: any; if (queue.playing.raw.source === 'youtube') { newStream = ytdl(queue.playing.url, { - filter: queue.playing.raw.live ? undefined : 'audioonly', opusEncoded: true, encoderArgs: queue.playing.raw.live ? [] : encoderArgs, seek: seekTime / 1000, From ddb3ae76f7d754eef610ffebd812f979587dd8a8 Mon Sep 17 00:00:00 2001 From: Snowflake107 Date: Sat, 24 Apr 2021 11:50:46 +0545 Subject: [PATCH 113/131] audio filters jsdoc --- src/utils/AudioFilters.ts | 44 ++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 1f03c58..37b52da 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -1,5 +1,38 @@ import { FiltersName } from '../types/types'; +/** + * The available audio filters + * @typedef {Object} AudioFilters + * @property {String} bassboost The bassboost filter + * @property {String} 8D The 8D filter + * @property {String} vaporwave The vaporwave filter + * @property {String} nightcore The nightcore filter + * @property {String} phaser The phaser filter + * @property {String} tremolo The tremolo filter + * @property {String} vibrato The vibrato filter + * @property {String} reverse The reverse filter + * @property {String} treble The treble filter + * @property {String} normalizer The normalizer filter + * @property {String} surrounding The surrounding filter + * @property {String} pulsator The pulsator filter + * @property {String} subboost The subboost filter + * @property {String} kakaoke The kakaoke filter + * @property {String} flanger The flanger filter + * @property {String} gate The gate filter + * @property {String} haas The haas filter + * @property {String} mcompand The mcompand filter + * @property {String} mono The mono filter + * @property {String} mstlr The mstlr filter + * @property {String} mstrr The mstrr filter + * @property {String} compressor The compressor filter + * @property {String} expander The expander filter + * @property {String} softlimiter The softlimiter filter + * @property {String} chorus The chorus filter + * @property {String} chorus2d The chorus2d filter + * @property {String} chorus3d The chorus3d filter + * @property {String} fadein The fadein filter + */ + const FilterList = { bassboost: 'bass=g=20', '8D': 'apulsator=hz=0.09', @@ -30,17 +63,18 @@ const FilterList = { chorus3d: 'chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3', fadein: 'afade=t=in:ss=0:d=10', - *[Symbol.iterator](): IterableIterator<{ name: string; value: string }> { + *[Symbol.iterator](): IterableIterator<{ name: FiltersName; value: string }> { for (const [k, v] of Object.entries(this)) { - // @ts-ignore - yield { name: k, value: v }; + if (typeof this[k as FiltersName] === 'string') yield { name: k as FiltersName, value: v as string }; } }, + get names() { - return Object.keys(this); + return Object.keys(this).filter((p) => ['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function'); }, + get length() { - return Object.keys(this).length; + return Object.keys(this).filter((p) => ['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function').length; }, toString() { From c009ed27f3e809051e981e792f06d1c5d189e29b Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 11:16:48 +0200 Subject: [PATCH 114/131] :construction_worker: Fix github workflows --- .../workflows/{deploy.yml => docs-deploy.yml} | 0 .github/workflows/jsdoc-deploy.yml | 28 ------------------- package.json | 2 +- 3 files changed, 1 insertion(+), 29 deletions(-) rename .github/workflows/{deploy.yml => docs-deploy.yml} (100%) delete mode 100644 .github/workflows/jsdoc-deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/docs-deploy.yml similarity index 100% rename from .github/workflows/deploy.yml rename to .github/workflows/docs-deploy.yml diff --git a/.github/workflows/jsdoc-deploy.yml b/.github/workflows/jsdoc-deploy.yml deleted file mode 100644 index ce11890..0000000 --- a/.github/workflows/jsdoc-deploy.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: GitHub pages - -on: - push: - branches: - - master - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Build - uses: andstor/jsdoc-action@v1 - with: - output_dir: ./docs - config_file: .jsdoc.json - template: Androz2091/jsdoc-skyceil - front_page: README.md - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - personal_token: ${{ secrets.ACTIONS_DEPLOY_KEY }} - publish_dir: ./docs - cname: discord-player.js.org diff --git a/package.json b/package.json index 1f051ae..84b6fbb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.0", + "version": "4.0.0-dev", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", From 7a59094aa3a12682f92d4b1afb6af02354053acb Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 11:18:56 +0200 Subject: [PATCH 115/131] :pencil: Update advanced section of README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 058ccd1..3207ead 100644 --- a/README.md +++ b/README.md @@ -106,9 +106,9 @@ These bots are made by the community, they can help you build your own! * [Discord-Music](https://github.com/inhydrox/discord-music) by [inhydrox](https://github.com/inhydrox) * [Music-bot](https://github.com/ZerioDev/Music-bot) by [ZerioDev](https://github.com/ZerioDev) -## FAQ +## Advanced -### How to use cookies +### Use cookies ```js const player = new Player(client, { @@ -122,7 +122,7 @@ const player = new Player(client, { }); ``` -### How to use custom proxies +### Use custom proxies ```js const HttpsProxyAgent = require("https-proxy-agent"); From 4b5875a08ca7449c19eca3d774042a88b2641021 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 11:20:49 +0200 Subject: [PATCH 116/131] :see_no_evil: Update gitignore --- .gitignore | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 5faffcc..7033b56 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,15 @@ -# Modules -node_modules/ +# Node +node_modules +package-lock.json -# Test dir -test/ +# Tests +test -# Compiled -lib/ +# Compiled files +lib -# error logs -yarn-error.log +# Yarn logs +yarn*.log -# demo -demo/ \ No newline at end of file +# Demo +demo From 5c97f9ff96790cc04d47b6f439c8e562fc84dbfc Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 11:23:45 +0200 Subject: [PATCH 117/131] :pencil: Add discord badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3207ead..7357eb1 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ Complete framework to facilitate music commands using **[discord.js](https://dis [![downloadsBadge](https://img.shields.io/npm/dt/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) [![versionBadge](https://img.shields.io/npm/v/discord-player?style=for-the-badge)](https://npmjs.com/discord-player) +[![discordBadge](https://img.shields.io/discord/558328638911545423?style=for-the-badge&color=7289da)](https://androz2091.fr/discord) ## Installation From 569aaccc619a72f6baa4f00dee3c6ffcf7553042 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 11:24:25 +0200 Subject: [PATCH 118/131] :bookmark: v4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 84b6fbb..1f051ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.0-dev", + "version": "4.0.0", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", From 877dc1be77c810912ea424a4b3f388cb98748587 Mon Sep 17 00:00:00 2001 From: Androz Date: Sun, 25 Apr 2021 12:33:51 +0200 Subject: [PATCH 119/131] :bug: Fix seek method --- src/Player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player.ts b/src/Player.ts index eff1d9b..a46af6e 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -524,7 +524,7 @@ export class Player extends EventEmitter { if (!queue) return this.emit(PlayerEvents.ERROR, PlayerErrorEventCodes.NOT_PLAYING, message); if (typeof time !== 'number' && !isNaN(time)) time = parseInt(time); - if (queue.playing.durationMS >= time) return this.skip(message); + if (queue.playing.durationMS <= time) return this.skip(message); if ( queue.voiceConnection.dispatcher.streamTime === time || queue.voiceConnection.dispatcher.streamTime + queue.additionalStreamTime === time From fa59ded7720a4d2a8d27b529c154f2952676c0dd Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 12:40:21 +0200 Subject: [PATCH 120/131] :bookmark: v4.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f051ae..2f4c0a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.0", + "version": "4.0.1", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", From 15b09d945505b98ab4ad959bab323539a71f8a88 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 12:43:02 +0200 Subject: [PATCH 121/131] :construction_worker: Fix github publish workflow --- .github/workflows/npm-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 36d7e35..f61dff2 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -14,7 +14,7 @@ jobs: with: node-version: 12 registry-url: https://registry.npmjs.org/ - - run: npm run install + - run: npm install - run: npm run build - run: npm publish env: From 314155719218ae838ca4752e35c0ce013b4cf00d Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 12:43:14 +0200 Subject: [PATCH 122/131] :bookmark: v4.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2f4c0a1..11a3428 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.1", + "version": "4.0.2", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", From eacab30451ec98529eaaae519f689e6e9a5c37fe Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 12:48:11 +0200 Subject: [PATCH 123/131] :construction_worker: Use yarn instead of npm --- .github/workflows/npm-publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index f61dff2..fb09852 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -14,8 +14,8 @@ jobs: with: node-version: 12 registry-url: https://registry.npmjs.org/ - - run: npm install - - run: npm run build - - run: npm publish + - run: yarn install + - run: yarn run build + - run: yarn publish env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} \ No newline at end of file From 3349e9a4ca132ba59159ef196e26fef4aee98254 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 12:52:06 +0200 Subject: [PATCH 124/131] :bookmark: v4.0.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 11a3428..9d892e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.2", + "version": "4.0.3", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", From 13cdb49856c3fa7e0bbbf4f535b6cc2c65bf5f32 Mon Sep 17 00:00:00 2001 From: MegaPixel Date: Sun, 25 Apr 2021 21:35:28 +0545 Subject: [PATCH 125/131] :bug: Mistake in filters length (#367) --- src/utils/AudioFilters.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/AudioFilters.ts b/src/utils/AudioFilters.ts index 37b52da..ff21b68 100644 --- a/src/utils/AudioFilters.ts +++ b/src/utils/AudioFilters.ts @@ -70,11 +70,11 @@ const FilterList = { }, get names() { - return Object.keys(this).filter((p) => ['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function'); + return Object.keys(this).filter((p) => !['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function'); }, get length() { - return Object.keys(this).filter((p) => ['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function').length; + return Object.keys(this).filter((p) => !['names', 'length'].includes(p) && typeof this[p as FiltersName] !== 'function').length; }, toString() { From c9adc80fee895bafb8e6acce8c82d1f660ffc84a Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 18:00:35 +0200 Subject: [PATCH 126/131] :construction_worker: Fix npm publish workflow --- .github/workflows/npm-publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index fb09852..2147d77 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -14,8 +14,8 @@ jobs: with: node-version: 12 registry-url: https://registry.npmjs.org/ - - run: yarn install - - run: yarn run build - - run: yarn publish + - run: npm install + - run: npm run build + - run: npm publish --access public env: NODE_AUTH_TOKEN: ${{secrets.npm_token}} \ No newline at end of file From 87533ab94fbcb83cad88ca96577e765800c22120 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 18:00:43 +0200 Subject: [PATCH 127/131] :bookmark: v4.0.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d892e7..169e3c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.3", + "version": "4.0.4", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/src/index.js", "types": "lib/src/index.d.ts", From f1e6dd477e8a4d5a84c9f85e74f6971ae43a0337 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 18:21:49 +0200 Subject: [PATCH 128/131] :fire: Remove version export --- src/index.ts | 1 - tsconfig.json | 1 - 2 files changed, 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 70f10f1..4dd3a82 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,4 +7,3 @@ export { Track } from './Structures/Track'; export { Queue } from './Structures/Queue'; export * from './types/types'; export { PlayerError } from './utils/PlayerError'; -export { version } from '../package.json'; diff --git a/tsconfig.json b/tsconfig.json index 3566c04..629bcf8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,6 @@ "outDir": "./lib", "strict": true, "strictNullChecks": false, - "resolveJsonModule": true, "esModuleInterop": true }, "include": [ From 6b63b5494622e9e3807eb1d924d5e7d637d2626f Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 18:22:35 +0200 Subject: [PATCH 129/131] :bug: Change default files --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 169e3c0..0dc7a91 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "discord-player", "version": "4.0.4", "description": "Complete framework to facilitate music commands using discord.js", - "main": "lib/src/index.js", - "types": "lib/src/index.d.ts", + "main": "lib/index.js", + "types": "lib/index.d.ts", "files": [ "lib/" ], From d4035cf643f65ca09259555d2e1c357c90c42276 Mon Sep 17 00:00:00 2001 From: Androz2091 Date: Sun, 25 Apr 2021 18:23:15 +0200 Subject: [PATCH 130/131] :bookmark: v4.0.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0dc7a91..7e94075 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "4.0.4", + "version": "4.0.5", "description": "Complete framework to facilitate music commands using discord.js", "main": "lib/index.js", "types": "lib/index.d.ts", From 67ec2faf3dc46788aec0a8084b18b63ea0e0d70e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 29 Apr 2021 15:37:14 +0000 Subject: [PATCH 131/131] Upgrade to GitHub-native Dependabot --- .github/dependabot.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a9702c2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,27 @@ +version: 2 +updates: +- package-ecosystem: npm + directory: "/" + schedule: + interval: daily + time: "04:00" + open-pull-requests-limit: 10 + target-branch: develop + ignore: + - dependency-name: "@types/node" + versions: + - 14.14.32 + - 14.14.33 + - 14.14.34 + - 14.14.35 + - 14.14.37 + - 14.14.39 + - 14.14.41 + - 15.0.0 + - 15.0.1 + - dependency-name: parse-ms + versions: + - 3.0.0 + - dependency-name: "@discordjs/opus" + versions: + - 0.5.0