diff --git a/example.config.json b/example.config.json index 02e0e6c25..f016ecbcf 100644 --- a/example.config.json +++ b/example.config.json @@ -10,5 +10,14 @@ "bigNumberStrings": true }, "prefix": "!", - "googleapikey":"google API Key" + "googleapikey":"google API Key", + "monitoring": { + "enabeled": false, + "project_id": "000", + "log_name": "modbot", + "credentials": { + "client_email": "modbot@example.com", + "private_key": "google service account private key" + } + } } diff --git a/index.js b/index.js index 8e26fd528..eecce1f11 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,13 @@ const Bot = require("./src/Bot"); +const Monitor = require("./src/Monitor"); -Bot.getInstance().start().catch((error) => { +Bot.getInstance().start().catch(async (error) => { + try { + await Monitor.getInstance().emergency('Bot crashed', error); + } + catch (e) { + console.error('Failed to send fatal error to monitoring'); + } console.error(error); process.exit(1) }); diff --git a/package-lock.json b/package-lock.json index e115c8890..4e1403e41 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,10 @@ "version": "0.2.0", "license": "MIT", "dependencies": { + "@google-cloud/logging": "^9.1.1", "diff": "^4.0.2", - "discord.js": "^12.4.0", - "fuse.js": "^6.4.1", + "discord.js": "^12.5.2", + "fuse.js": "^6.4.6", "googleapis": "^61.0.0", "got": "^11.8.2", "mysql": "^2.18.1", @@ -68,6 +69,15 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/core/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -112,6 +122,15 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-function-name": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", @@ -550,6 +569,181 @@ "node": ">= 6" } }, + "node_modules/@google-cloud/common": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.6.0.tgz", + "integrity": "sha512-aHIFTqJZmeTNO9md8XxV+ywuvXF3xBm5WNmgWeeCK+XN5X+kGW0WEX94wGwj+/MdOnrVf4dL2RvSIt9J5yJG6Q==", + "dependencies": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^7.0.2", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/common/node_modules/gaxios": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.0.tgz", + "integrity": "sha512-Ms7fNifGv0XVU+6eIyL9LB7RVESeML9+cMvkwGS70xyD6w2Z80wl6RiqiJ9k1KFlJCUTQqFFc8tXmPQfSKUe8g==", + "dependencies": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/common/node_modules/google-auth-library": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz", + "integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==", + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/logging": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@google-cloud/logging/-/logging-9.2.0.tgz", + "integrity": "sha512-eQRDKPq9Pq0pbDeo2/OaVrPRX+TDqaxZ7JagDAJx20dqxVwBtaA1rBUcCEXCAFrMZ2cUYhj3sDVuzqNwSObF2Q==", + "dependencies": { + "@google-cloud/common": "^3.4.1", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "@opencensus/propagation-stackdriver": "0.0.22", + "arrify": "^2.0.1", + "dot-prop": "^6.0.0", + "eventid": "^1.0.0", + "extend": "^3.0.2", + "gcp-metadata": "^4.0.0", + "google-auth-library": "^7.0.0", + "google-gax": "^2.9.2", + "on-finished": "^2.3.0", + "pumpify": "^2.0.1", + "snakecase-keys": "^3.1.2", + "stream-events": "^1.0.5", + "through2": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/logging/node_modules/gaxios": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.0.tgz", + "integrity": "sha512-Ms7fNifGv0XVU+6eIyL9LB7RVESeML9+cMvkwGS70xyD6w2Z80wl6RiqiJ9k1KFlJCUTQqFFc8tXmPQfSKUe8g==", + "dependencies": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/logging/node_modules/google-auth-library": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz", + "integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==", + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.5.tgz", + "integrity": "sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw==", + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@google-cloud/promisify": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.2.12.tgz", + "integrity": "sha512-+gPCklP1eqIgrNPyzddYQdt9+GvZqPlLpIjIo+TveE+gbtp74VV1A2ju8ExeO8ma8f7MbpaGZx/KJPYVWL9eDw==", + "dependencies": { + "@types/node": ">=12.12.47", + "google-auth-library": "^6.1.1", + "semver": "^6.2.0" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/grpc-js/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.6.tgz", + "integrity": "sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -802,6 +996,85 @@ "node": ">= 10.14.2" } }, + "node_modules/@opencensus/core": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", + "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", + "dependencies": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^7.0.0", + "shimmer": "^1.2.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@opencensus/propagation-stackdriver": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-stackdriver/-/propagation-stackdriver-0.0.22.tgz", + "integrity": "sha512-eBvf/ihb1mN8Yz/ASkz8nHzuMKqygu77+VNnUeR0yEh3Nj+ykB8VVR6lK+NAFXo1Rd1cOsTmgvuXAZgDAGleQQ==", + "dependencies": { + "@opencensus/core": "^0.0.22", + "hex2dec": "^1.0.1", + "uuid": "^8.0.0" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "node_modules/@sindresorhus/is": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz", @@ -842,6 +1115,14 @@ "node": ">=10" } }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/@types/babel__core": { "version": "7.1.14", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", @@ -940,6 +1221,11 @@ "@types/node": "*" } }, + "node_modules/@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, "node_modules/@types/node": { "version": "14.14.35", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz", @@ -1004,9 +1290,9 @@ } }, "node_modules/acorn": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.0.tgz", - "integrity": "sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", + "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1205,6 +1491,26 @@ "node": ">=0.10.0" } }, + "node_modules/async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "dependencies": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "engines": { + "node": "<=0.11.8 || >0.11.10" + } + }, + "node_modules/async-listener/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1422,16 +1728,16 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", - "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001208", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.712", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.71" }, "bin": { "browserslist": "cli.js" @@ -1781,6 +2087,15 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "node_modules/continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "dependencies": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, "node_modules/convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -1842,6 +2157,11 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/d64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", + "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1999,18 +2319,18 @@ } }, "node_modules/discord.js": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.4.0.tgz", - "integrity": "sha512-Lc+/vKzih1DPEya/0MO0BAp4Ru/4+MfDsOJkfbyzGoyIlFqiWSQ78RdyRk4tqAtabl6d5QR4Ygo0Ub0TGEsXBg==", + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.3.tgz", + "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" }, "engines": { "node": ">=12.0.0" @@ -2037,6 +2357,44 @@ "node": ">=8" } }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -2055,12 +2413,25 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, "node_modules/electron-to-chromium": { "version": "1.3.712", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.712.tgz", "integrity": "sha512-3kRVibBeCM4vsgoHHGKHmPocLqtFAGTrebXxxtgKs87hNUzXrX2NuS3jnBys7IozCnw7viQlozxKkmty2KNfrw==", "dev": true }, + "node_modules/emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "dependencies": { + "shimmer": "^1.2.0" + } + }, "node_modules/emittery": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", @@ -2087,6 +2458,11 @@ "once": "^1.4.0" } }, + "node_modules/ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2175,6 +2551,26 @@ "node": ">=6" } }, + "node_modules/eventid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eventid/-/eventid-1.0.0.tgz", + "integrity": "sha512-4upSDsvpxhWPsmw4fsJCp0zj8S7I0qh1lCDTmZXP8V3TtryQKDI8CgQPN+e5JakbWwzaAX3lrdp2b3KSoMSUpw==", + "dependencies": { + "d64": "^1.0.0", + "uuid": "^3.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eventid/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/exec-sh": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", @@ -2574,9 +2970,9 @@ "dev": true }, "node_modules/fuse.js": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.4.1.tgz", - "integrity": "sha512-+hAS7KYgLXontDh/vqffs7wIBw0ceb9Sx8ywZQhOsiQGcSO5zInGhttWOUYQYlvV/yYMJOacQ129Xs3mP3+oZQ==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.4.6.tgz", + "integrity": "sha512-/gYxR/0VpXmWSfZOIPS3rWwU8SHgsRTwWuXhyb2O6s7aRuVtHtxCkR33bNYu3wyLyNx/Wpv0vU7FZy8Vj53VNw==", "engines": { "node": ">=10" } @@ -2715,6 +3111,64 @@ "node": ">=10" } }, + "node_modules/google-gax": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.11.2.tgz", + "integrity": "sha512-PNqXv7Oi5XBMgoMWVxLZHUidfMv7cPHrDSDXqLyEd6kY6pqFnVKC8jt2T1df4JPSc2+VLPdeo6L7X9mbdQG8Xw==", + "dependencies": { + "@grpc/grpc-js": "~1.2.0", + "@grpc/proto-loader": "^0.5.1", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^7.0.2", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "protobufjs": "^6.10.2", + "retry-request": "^4.0.0" + }, + "bin": { + "compileProtos": "build/tools/compileProtos.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-gax/node_modules/gaxios": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.0.tgz", + "integrity": "sha512-Ms7fNifGv0XVU+6eIyL9LB7RVESeML9+cMvkwGS70xyD6w2Z80wl6RiqiJ9k1KFlJCUTQqFFc8tXmPQfSKUe8g==", + "dependencies": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/google-gax/node_modules/google-auth-library": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz", + "integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==", + "dependencies": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/google-p12-pem": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", @@ -2915,6 +3369,11 @@ "node": ">=0.10.0" } }, + "node_modules/hex2dec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz", + "integrity": "sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==" + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -2944,6 +3403,19 @@ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3173,6 +3645,14 @@ "node": ">=0.12.0" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -3199,6 +3679,11 @@ "node": ">=8" } }, + "node_modules/is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==" + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -3277,6 +3762,15 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -3788,21 +4282,6 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/jest-util": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", @@ -3907,9 +4386,9 @@ "dev": true }, "node_modules/jsdom": { - "version": "16.5.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.2.tgz", - "integrity": "sha512-JxNtPt9C1ut85boCbJmffaQ06NBnzkQY/MWO3YxPW8IWS38A26z+B1oBvA9LwKrytewdfymnhi4UNH3/RAgZrg==", + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.3.tgz", + "integrity": "sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==", "dev": true, "dependencies": { "abab": "^2.0.5", @@ -4121,6 +4600,24 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "node_modules/log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "engines": { + "node": ">=0.8.6" + } + }, + "node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -4155,6 +4652,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/makeerror": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", @@ -4173,6 +4679,17 @@ "node": ">=0.10.0" } }, + "node_modules/map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -4381,22 +4898,6 @@ "which": "^2.0.2" } }, - "node_modules/node-notifier/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-releases": { "version": "1.1.71", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", @@ -4577,6 +5078,17 @@ "node": ">=0.10.0" } }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4824,9 +5336,29 @@ } }, "node_modules/prism-media": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.2.tgz", - "integrity": "sha512-I+nkWY212lJ500jLe4tN9tWO7nRiBAVdMv76P9kffZjYhw20raMlW1HSSvS+MLXC9MmbNZCazMrAr+5jEEgTuw==" + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==", + "peerDependencies": { + "@discordjs/opus": "^0.5.0", + "ffmpeg-static": "^4.2.7 || ^3.0.0 || ^2.4.0", + "node-opus": "^0.3.3", + "opusscript": "^0.0.8" + }, + "peerDependenciesMeta": { + "@discordjs/opus": { + "optional": true + }, + "ffmpeg-static": { + "optional": true + }, + "node-opus": { + "optional": true + }, + "opusscript": { + "optional": true + } + } }, "node_modules/process-nextick-args": { "version": "2.0.1", @@ -4846,6 +5378,36 @@ "node": ">= 6" } }, + "node_modules/protobufjs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/protobufjs/node_modules/@types/node": { + "version": "13.13.48", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.48.tgz", + "integrity": "sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ==" + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -4861,6 +5423,16 @@ "once": "^1.3.1" } }, + "node_modules/pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "dependencies": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -5183,6 +5755,17 @@ "node": ">=0.12" } }, + "node_modules/retry-request": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.3.tgz", + "integrity": "sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ==", + "dependencies": { + "debug": "^4.1.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -5533,12 +6116,17 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/set-blocking": { @@ -5616,6 +6204,11 @@ "dev": true, "optional": true }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "node_modules/signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -5637,6 +6230,18 @@ "node": ">=8" } }, + "node_modules/snakecase-keys": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-3.2.1.tgz", + "integrity": "sha512-CjU5pyRfwOtaOITYv5C8DzpZ8XA/ieRsDpr93HI2r6e3YInC6moZpSQbmUtg8cTk58tq2x3jcG2gv+p1IZGmMA==", + "dependencies": { + "map-obj": "^4.1.0", + "to-snake-case": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -5946,11 +6551,6 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { "node": ">=0.10.0" } @@ -6078,6 +6678,19 @@ "node": ">=0.10.0" } }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -6157,6 +6770,11 @@ "node": ">=6" } }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6188,6 +6806,21 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/teeny-request": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", + "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", + "dependencies": { + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -6224,6 +6857,27 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -6239,6 +6893,11 @@ "node": ">=4" } }, + "node_modules/to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + }, "node_modules/to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -6290,6 +6949,22 @@ "node": ">=8.0" } }, + "node_modules/to-snake-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", + "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", + "dependencies": { + "to-space-case": "^1.0.0" + } + }, + "node_modules/to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "dependencies": { + "to-no-case": "^1.0.0" + } + }, "node_modules/tough-cookie": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", @@ -6793,6 +7468,12 @@ "source-map": "^0.5.0" }, "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -6830,6 +7511,14 @@ "@babel/helper-validator-option": "^7.12.17", "browserslist": "^4.14.5", "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/helper-function-name": { @@ -7206,6 +7895,151 @@ "mime-types": "^2.1.12" } }, + "@google-cloud/common": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.6.0.tgz", + "integrity": "sha512-aHIFTqJZmeTNO9md8XxV+ywuvXF3xBm5WNmgWeeCK+XN5X+kGW0WEX94wGwj+/MdOnrVf4dL2RvSIt9J5yJG6Q==", + "requires": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^7.0.2", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "dependencies": { + "gaxios": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.0.tgz", + "integrity": "sha512-Ms7fNifGv0XVU+6eIyL9LB7RVESeML9+cMvkwGS70xyD6w2Z80wl6RiqiJ9k1KFlJCUTQqFFc8tXmPQfSKUe8g==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + }, + "google-auth-library": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz", + "integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + } + } + }, + "@google-cloud/logging": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@google-cloud/logging/-/logging-9.2.0.tgz", + "integrity": "sha512-eQRDKPq9Pq0pbDeo2/OaVrPRX+TDqaxZ7JagDAJx20dqxVwBtaA1rBUcCEXCAFrMZ2cUYhj3sDVuzqNwSObF2Q==", + "requires": { + "@google-cloud/common": "^3.4.1", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "@opencensus/propagation-stackdriver": "0.0.22", + "arrify": "^2.0.1", + "dot-prop": "^6.0.0", + "eventid": "^1.0.0", + "extend": "^3.0.2", + "gcp-metadata": "^4.0.0", + "google-auth-library": "^7.0.0", + "google-gax": "^2.9.2", + "on-finished": "^2.3.0", + "pumpify": "^2.0.1", + "snakecase-keys": "^3.1.2", + "stream-events": "^1.0.5", + "through2": "^4.0.0" + }, + "dependencies": { + "gaxios": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.0.tgz", + "integrity": "sha512-Ms7fNifGv0XVU+6eIyL9LB7RVESeML9+cMvkwGS70xyD6w2Z80wl6RiqiJ9k1KFlJCUTQqFFc8tXmPQfSKUe8g==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + }, + "google-auth-library": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz", + "integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + } + } + }, + "@google-cloud/paginator": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.5.tgz", + "integrity": "sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw==", + "requires": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + } + }, + "@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" + }, + "@google-cloud/promisify": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" + }, + "@grpc/grpc-js": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.2.12.tgz", + "integrity": "sha512-+gPCklP1eqIgrNPyzddYQdt9+GvZqPlLpIjIo+TveE+gbtp74VV1A2ju8ExeO8ma8f7MbpaGZx/KJPYVWL9eDw==", + "requires": { + "@types/node": ">=12.12.47", + "google-auth-library": "^6.1.1", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@grpc/proto-loader": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.6.tgz", + "integrity": "sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==", + "requires": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -7417,6 +8251,82 @@ "chalk": "^4.0.0" } }, + "@opencensus/core": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", + "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", + "requires": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^7.0.0", + "shimmer": "^1.2.0", + "uuid": "^8.0.0" + } + }, + "@opencensus/propagation-stackdriver": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-stackdriver/-/propagation-stackdriver-0.0.22.tgz", + "integrity": "sha512-eBvf/ihb1mN8Yz/ASkz8nHzuMKqygu77+VNnUeR0yEh3Nj+ykB8VVR6lK+NAFXo1Rd1cOsTmgvuXAZgDAGleQQ==", + "requires": { + "@opencensus/core": "^0.0.22", + "hex2dec": "^1.0.1", + "uuid": "^8.0.0" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@sindresorhus/is": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz", @@ -7448,6 +8358,11 @@ "defer-to-connect": "^2.0.0" } }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" + }, "@types/babel__core": { "version": "7.1.14", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", @@ -7546,6 +8461,11 @@ "@types/node": "*" } }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, "@types/node": { "version": "14.14.35", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz", @@ -7607,9 +8527,9 @@ } }, "acorn": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.0.tgz", - "integrity": "sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", + "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==", "dev": true }, "acorn-globals": { @@ -7749,6 +8669,22 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "requires": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -7928,16 +8864,16 @@ "dev": true }, "browserslist": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", - "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", + "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001208", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.712", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.71" } }, "bser": { @@ -8219,6 +9155,15 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "requires": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -8273,6 +9218,11 @@ } } }, + "d64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", + "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -8384,18 +9334,18 @@ "dev": true }, "discord.js": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.4.0.tgz", - "integrity": "sha512-Lc+/vKzih1DPEya/0MO0BAp4Ru/4+MfDsOJkfbyzGoyIlFqiWSQ78RdyRk4tqAtabl6d5QR4Ygo0Ub0TGEsXBg==", + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.5.3.tgz", + "integrity": "sha512-D3nkOa/pCkNyn6jLZnAiJApw2N9XrIsXUAdThf01i7yrEuqUmDGc7/CexVWwEcgbQR97XQ+mcnqJpmJ/92B4Aw==", "requires": { "@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" } }, "domexception": { @@ -8415,6 +9365,37 @@ } } }, + "dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -8433,12 +9414,25 @@ "safe-buffer": "^5.0.1" } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, "electron-to-chromium": { "version": "1.3.712", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.712.tgz", "integrity": "sha512-3kRVibBeCM4vsgoHHGKHmPocLqtFAGTrebXxxtgKs87hNUzXrX2NuS3jnBys7IozCnw7viQlozxKkmty2KNfrw==", "dev": true }, + "emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "requires": { + "shimmer": "^1.2.0" + } + }, "emittery": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", @@ -8459,6 +9453,11 @@ "once": "^1.4.0" } }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -8516,6 +9515,22 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, + "eventid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eventid/-/eventid-1.0.0.tgz", + "integrity": "sha512-4upSDsvpxhWPsmw4fsJCp0zj8S7I0qh1lCDTmZXP8V3TtryQKDI8CgQPN+e5JakbWwzaAX3lrdp2b3KSoMSUpw==", + "requires": { + "d64": "^1.0.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } + } + }, "exec-sh": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", @@ -8838,9 +9853,9 @@ "dev": true }, "fuse.js": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.4.1.tgz", - "integrity": "sha512-+hAS7KYgLXontDh/vqffs7wIBw0ceb9Sx8ywZQhOsiQGcSO5zInGhttWOUYQYlvV/yYMJOacQ129Xs3mP3+oZQ==" + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.4.6.tgz", + "integrity": "sha512-/gYxR/0VpXmWSfZOIPS3rWwU8SHgsRTwWuXhyb2O6s7aRuVtHtxCkR33bNYu3wyLyNx/Wpv0vU7FZy8Vj53VNw==" }, "gaxios": { "version": "3.2.0", @@ -8940,6 +9955,54 @@ "lru-cache": "^6.0.0" } }, + "google-gax": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.11.2.tgz", + "integrity": "sha512-PNqXv7Oi5XBMgoMWVxLZHUidfMv7cPHrDSDXqLyEd6kY6pqFnVKC8jt2T1df4JPSc2+VLPdeo6L7X9mbdQG8Xw==", + "requires": { + "@grpc/grpc-js": "~1.2.0", + "@grpc/proto-loader": "^0.5.1", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^7.0.2", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "protobufjs": "^6.10.2", + "retry-request": "^4.0.0" + }, + "dependencies": { + "gaxios": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.0.tgz", + "integrity": "sha512-Ms7fNifGv0XVU+6eIyL9LB7RVESeML9+cMvkwGS70xyD6w2Z80wl6RiqiJ9k1KFlJCUTQqFFc8tXmPQfSKUe8g==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + }, + "google-auth-library": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz", + "integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + } + } + }, "google-p12-pem": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", @@ -9095,6 +10158,11 @@ } } }, + "hex2dec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz", + "integrity": "sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==" + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -9121,6 +10189,16 @@ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -9289,6 +10367,11 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -9309,6 +10392,11 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, + "is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==" + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -9370,6 +10458,14 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.0.0", "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "istanbul-lib-report": { @@ -9774,17 +10870,6 @@ "natural-compare": "^1.4.0", "pretty-format": "^26.6.2", "semver": "^7.3.2" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "jest-util": { @@ -9872,9 +10957,9 @@ "dev": true }, "jsdom": { - "version": "16.5.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.2.tgz", - "integrity": "sha512-JxNtPt9C1ut85boCbJmffaQ06NBnzkQY/MWO3YxPW8IWS38A26z+B1oBvA9LwKrytewdfymnhi4UNH3/RAgZrg==", + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.3.tgz", + "integrity": "sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==", "dev": true, "requires": { "abab": "^2.0.5", @@ -10045,6 +11130,21 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -10065,6 +11165,14 @@ "dev": true, "requires": { "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "makeerror": { @@ -10082,6 +11190,11 @@ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true }, + "map-obj": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", + "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==" + }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -10243,18 +11356,6 @@ "shellwords": "^0.1.1", "uuid": "^8.3.0", "which": "^2.0.2" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "node-releases": { @@ -10401,6 +11502,14 @@ "isobject": "^3.0.1" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -10576,9 +11685,10 @@ } }, "prism-media": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.2.tgz", - "integrity": "sha512-I+nkWY212lJ500jLe4tN9tWO7nRiBAVdMv76P9kffZjYhw20raMlW1HSSvS+MLXC9MmbNZCazMrAr+5jEEgTuw==" + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==", + "requires": {} }, "process-nextick-args": { "version": "2.0.1", @@ -10595,6 +11705,33 @@ "sisteransi": "^1.0.5" } }, + "protobufjs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "13.13.48", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.48.tgz", + "integrity": "sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ==" + } + } + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -10610,6 +11747,16 @@ "once": "^1.3.1" } }, + "pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "requires": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -10859,6 +12006,14 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "retry-request": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.3.tgz", + "integrity": "sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ==", + "requires": { + "debug": "^4.1.1" + } + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -11139,10 +12294,12 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } }, "set-blocking": { "version": "2.0.0", @@ -11206,6 +12363,11 @@ "dev": true, "optional": true }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", @@ -11224,6 +12386,15 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "snakecase-keys": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-3.2.1.tgz", + "integrity": "sha512-CjU5pyRfwOtaOITYv5C8DzpZ8XA/ieRsDpr93HI2r6e3YInC6moZpSQbmUtg8cTk58tq2x3jcG2gv+p1IZGmMA==", + "requires": { + "map-obj": "^4.1.0", + "to-snake-case": "^1.0.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -11591,6 +12762,19 @@ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", "dev": true }, + "stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "requires": { + "stubs": "^3.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -11652,6 +12836,11 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11677,6 +12866,18 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "teeny-request": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", + "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", + "requires": { + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + } + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -11704,6 +12905,26 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "requires": { + "readable-stream": "3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -11716,6 +12937,11 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, + "to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -11757,6 +12983,22 @@ "is-number": "^7.0.0" } }, + "to-snake-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", + "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", + "requires": { + "to-space-case": "^1.0.0" + } + }, + "to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "requires": { + "to-no-case": "^1.0.0" + } + }, "tough-cookie": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", diff --git a/package.json b/package.json index 6bbf496e7..32e2e3540 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,10 @@ "node": ">=14.0.0" }, "dependencies": { + "@google-cloud/logging": "^9.1.1", "diff": "^4.0.2", - "discord.js": "^12.4.0", - "fuse.js": "^6.4.1", + "discord.js": "^12.5.2", + "fuse.js": "^6.4.6", "googleapis": "^61.0.0", "got": "^11.8.2", "mysql": "^2.18.1", diff --git a/src/Bot.js b/src/Bot.js index 60051c680..a3e120251 100644 --- a/src/Bot.js +++ b/src/Bot.js @@ -3,6 +3,7 @@ const Database = require('./Database'); const util = require('./util'); const fs = require('fs').promises; const config = require('../config.json'); +const Monitor = require('./Monitor'); class Bot { static instance = new Bot(); @@ -21,6 +22,11 @@ class Bot { */ #database; + /** + * @type {Monitor} + */ + #monitor = Monitor.getInstance(); + constructor() { this.#client = new Discord.Client({ disableMentions: 'everyone', @@ -31,21 +37,19 @@ class Bot { } async start(){ + await this.#monitor.notice('Starting modbot'); await this.#database.waitForConnection(); + await this.#monitor.info('Connected to database!'); console.log("Connected!"); await this.#database.createTables(); util.init(this.#database, this.#client); await this.#client.login(config.auth_token); + await this.#monitor.info('Logged into Discord'); await this._loadChecks(); await this._loadFeatures(); - - // errors - this.#client.on('error', (error) => { - console.error('An error occurred',error); - }); } async _loadChecks(){ @@ -54,12 +58,23 @@ class Bot { if (!file.endsWith('.js') || !(await fs.lstat(path)).isFile()) { continue; } + + let check; + try { + check = require(path); + } + catch (e) { + await this.#monitor.critical(`Failed to load check '${file}'`, e); + console.error(`Failed to load check '${file}'`, e); + continue; + } + try { - let check = require(path); check.check(this.#database, this.#client); setInterval(check.check, check.interval * 1000, this.#database, this.#client); } catch (e) { - console.error(`Failed to load feature '${file}'`, e); + await this.#monitor.error(`Failed to execute check '${file}'`, e); + console.error(`Failed to execute check '${file}'`, e); } } } @@ -70,20 +85,21 @@ class Bot { if (!(await fs.lstat(folderPath)).isDirectory()) { continue; } - let feature = []; + let features = []; for (let file of await fs.readdir(folderPath)) { let path = `${__dirname}/features/${folder}/${file}`; if (!file.endsWith('.js') || !(await fs.lstat(path)).isFile()) { continue; } try { - feature.push(require(path)); + features.push(require(path)); } catch (e) { - console.error(`Failed to load message feature '${file}'`, e); + await this.#monitor.critical(`Failed to load feature '${folder}/${file}'`, e) + console.error(`Failed to load feature '${folder}/${file}'`, e); } } this.#client.on(folder, async (...args) => { - for (let f of feature) { + for (let f of features) { await Promise.resolve(f.event({database: this.#database,bot: this.#client}, ...args)); } }); diff --git a/src/ChannelConfig.js b/src/ChannelConfig.js index 19e31bdf6..22e3b5c08 100644 --- a/src/ChannelConfig.js +++ b/src/ChannelConfig.js @@ -1,4 +1,5 @@ const Config = require('./Config'); +const {APIErrors} = require('discord.js').Constants; /** * Class representing the config of a channel @@ -38,8 +39,7 @@ class ChannelConfig extends Config { return channel.guild.id; } catch (e) { - // unknown channel, missing access - if ([10003, 50001].includes(e.code)) { + if ([APIErrors.UNKNOWN_CHANNEL, APIErrors.MISSING_ACCESS].includes(e.code)) { return null; } throw e; diff --git a/src/Database.js b/src/Database.js index d8c3cd3dd..bdcd64760 100644 --- a/src/Database.js +++ b/src/Database.js @@ -1,4 +1,5 @@ const mysql = require('mysql'); +const monitor = require('./Monitor').getInstance(); class Database { /** @@ -58,6 +59,7 @@ class Database { * @private */ _handleConnectionError(err) { + monitor.error('A fatal database error occurred', err) if (err.code === 'ER_ACCESS_DENIED_ERROR') { console.error('Access to database denied. Make sure your config and database are set up correctly!'); process.exit(1); diff --git a/src/Guild.js b/src/Guild.js index b36e4a6fc..4412d15fb 100644 --- a/src/Guild.js +++ b/src/Guild.js @@ -1,5 +1,6 @@ const RateLimiter = require('./RateLimiter'); const Discord = require('discord.js'); +const {APIErrors} = require('discord.js').Constants; class Guild { @@ -33,7 +34,7 @@ class Guild { return await this.guild.members.fetch(id); } catch (e) { - if (e.code === 10007) { + if (e.code === APIErrors.UNKNOWN_MEMBER) { return null; } else { @@ -53,7 +54,7 @@ class Guild { await RateLimiter.sendDM(this.guild, user, message); } catch (e) { - if (e.code === 50007) { + if (e.code === APIErrors.CANNOT_MESSAGE_USER) { return false; } else { diff --git a/src/Monitor.js b/src/Monitor.js new file mode 100644 index 000000000..d57c7b024 --- /dev/null +++ b/src/Monitor.js @@ -0,0 +1,140 @@ +const {Logging} = require('@google-cloud/logging'); + +class Monitor { + + /** + * + * @type {Monitor} + */ + static #instance = new Monitor(require('../config.json')); + + /** + * @type {boolean} + */ + #enabled; + + /** + * Monitoring configuration + * @type {Object} + * @property {String} project_id + * @property {String} log_name + */ + #config = {}; + + #logging; + + #log; + + /** + * + * @param {Object} [config] + * @property {String} project_id + * @property {String} log_name + */ + constructor(config) { + this.#enabled = config.monitoring && config.monitoring.enabled; + + if (!this.#enabled) return; + + this.#config = config.monitoring; + + this.#logging = new Logging({ + projectId: config.monitoring.project_id, + credentials: config.monitoring.credentials + }); + + this.#log = this.#logging.log(config.monitoring.log_name) + } + + /** + * @return {Monitor} + */ + static getInstance() { + return this.#instance; + } + + /** + * @param {String|Object} messages + * @return {Promise<*>} + */ + info(...messages){ + return this._log({ + severity: 'INFO' + }, ...messages) + } + + /** + * @param {String|Object} messages + * @return {Promise<*>} + */ + notice(...messages){ + return this._log({ + severity: 'NOTICE' + }, ...messages) + } + + /** + * @param {String|Object} messages + * @return {Promise<*>} + */ + warn(...messages){ + return this._log({ + severity: 'WARNING' + }, ...messages) + } + + /** + * @param {String|Object} messages + * @return {Promise<*>} + */ + error(...messages){ + return this._log({ + severity: 'ERROR' + }, ...messages) + } + + /** + * @param {String|Object} messages + * @return {Promise<*>} + */ + critical(...messages){ + return this._log({ + severity: 'CRITICAL' + }, ...messages) + } + + /** + * @param {String|Object} messages + * @return {Promise<*>} + */ + emergency(...messages){ + return this._log({ + severity: 'EMERGENCY' + }, ...messages) + } + + /** + * @param {Object} metadata + * @param {String|Object} messages + * @return {Promise<*>} + * @private + */ + async _log(metadata, ...messages) { + if (!this.#enabled) return null; + metadata.resource = {type: 'global'}; + + const entries = []; + for (let msg of messages) { + if (msg instanceof Error) { + msg = msg.toString(); + } + else if (typeof(msg) === "object") { + msg = JSON.stringify(msg); + } + entries.push(this.#log.entry(metadata,msg)); + } + return this.#log.write(entries); + } +} + +module.exports = Monitor; diff --git a/src/RateLimiter.js b/src/RateLimiter.js index 1409ba80d..012e79cb1 100644 --- a/src/RateLimiter.js +++ b/src/RateLimiter.js @@ -1,4 +1,5 @@ const Discord = require('discord.js'); +const monitor = require('./Monitor').getInstance(); /** * Database @@ -47,7 +48,13 @@ class RateLimiter { await user.send(message); } else { - console.log(`Didn't send DM in guild ${guild.id}, count: ${count}`); + await monitor.warn(`Guild ${guild.name}(${guild.id}) exceeded DM limit`, { + dms: count, + memberCount: guild.memberCount, + guildID: guild.id, + guildName: guild.name + }) + console.log(`Didn't send DM in guild ${guild.name}(${guild.id}), count: ${count}`); } } diff --git a/src/User.js b/src/User.js index 30d70b6b3..0abcb9c27 100644 --- a/src/User.js +++ b/src/User.js @@ -1,3 +1,5 @@ +const {APIErrors} = require('discord.js').Constants; + class User { /** @@ -34,8 +36,7 @@ class User { this.user = await this.client.users.fetch(this.id); } catch (e) { - //Unknown User - if (e.code === 10013) { + if (e.code === APIErrors.UNKNOWN_USER) { this.user = null; } else { diff --git a/src/checks/tempban.js b/src/checks/tempban.js index 2a848e4ac..965e03868 100644 --- a/src/checks/tempban.js +++ b/src/checks/tempban.js @@ -14,6 +14,7 @@ exports.check = async (database, bot) => { await Log.logCheck(result.guildid, user, reason, insert.insertId, "Unban"); } catch (e) { + await monitor.error('Failed to run tempban check: ', e, result); console.error(`Couldn't unban user ${result.userid} in ${result.guildid}`, e); } } diff --git a/src/checks/tempmute.js b/src/checks/tempmute.js index 374a34e8e..ba130ef40 100644 --- a/src/checks/tempmute.js +++ b/src/checks/tempmute.js @@ -1,6 +1,9 @@ const Log = require('../Log'); const GuildConfig = require('../GuildConfig'); const RateLimiter = require('../RateLimiter'); +const {APIErrors} = require('discord.js').Constants; +const deleteGuild = require('../features/guildDelete/deleteConfig'); +const monitor = require('../Monitor').getInstance(); exports.check = async (database, bot) => { let results = await database.queryAll("SELECT * FROM moderations WHERE action = 'mute' AND active = TRUE AND expireTime IS NOT NULL AND expireTime <= ?", [Math.floor(Date.now()/1000)]); @@ -19,7 +22,14 @@ exports.check = async (database, bot) => { } } } - catch (e) {} + catch (e) { + if (e.code === APIErrors.UNKNOWN_GUILD) { + await deleteGuild.delete(database, result.guildid); + } + else if (![APIErrors.UNKNOWN_MEMBER, APIErrors.MISSING_PERMISSIONS, APIErrors.CANNOT_MESSAGE_USER].includes(e.code)) { + throw e; + } + } let user = await bot.users.fetch(result.userid); let insert = await database.queryAll("INSERT INTO moderations (guildid, userid, action, created, reason, active) VALUES (?,?,?,?,?,?)",[result.guildid,result.userid,'unmute',Math.floor(Date.now()/1000),"Temporary mute completed!", false]); @@ -30,6 +40,7 @@ exports.check = async (database, bot) => { await database.query("UPDATE moderations SET active = FALSE WHERE action = 'mute' AND userid = ? AND guildid = ?",[result.userid,result.guildid]); } catch (e) { + await monitor.error('Failed to run tempmute check: ', e, result); console.error(`Couldn't unmute user ${result.userid} in ${result.guildid}`, e); } } diff --git a/src/commands/legacy/help.js b/src/commands/legacy/help.js index b88dca71a..34e702c43 100644 --- a/src/commands/legacy/help.js +++ b/src/commands/legacy/help.js @@ -3,6 +3,7 @@ const Discord = require('discord.js'); const fs = require('fs').promises; const GuildConfig = require('../../GuildConfig'); const CommandHandler = require('../../features/message/commands'); +const monitor = require('../../Monitor').getInstance(); const command = {}; @@ -28,7 +29,8 @@ let commandList = ''; } commandList += `\`${cmd.names[0]}\`, `; } catch (e) { - console.error(`Failed to load command '${file}'`, e); + await monitor.error(`(help) Failed to load legacy command 'legacy/${file}'`, e); + console.error(`(help) Failed to load legacy command 'legacy/${file}'`, e); } } commandList = commandList.substring(0, commandList.length - 2); diff --git a/src/commands/legacy/import.js b/src/commands/legacy/import.js index 0aca907ac..87d7c14bd 100644 --- a/src/commands/legacy/import.js +++ b/src/commands/legacy/import.js @@ -1,5 +1,6 @@ const Request = require('../../Request'); const util = require('../../util.js'); +const monitor = require('../../Monitor').getInstance(); const command = {}; @@ -41,7 +42,7 @@ command.execute = async (message, args, database, bot) => { for (let /** @type {module:"discord.js".Snowflake} */ key of Object.keys(data.tempmutes)) { if (mutes.successful / mutes.total * 100 > percent + 0.5) { percent = mutes.successful / mutes.total * 100; - response.edit(`Importing mutes (${percent.toFixed(1)}%)...`).catch(console.error); + edit(response,`Importing mutes (${percent.toFixed(1)}%)...`) } let endsAt = data.tempmutes[key]; if (endsAt > Number.MAX_SAFE_INTEGER) { @@ -67,7 +68,7 @@ command.execute = async (message, args, database, bot) => { let now = Math.floor(Date.now()/1000); if (strikes.successful / strikes.total * 100 > percent + 0.5) { percent = strikes.successful / strikes.total * 100; - response.edit(`Importing strikes (${percent.toFixed(1)}%)...`).catch(console.error); + edit(response, `Importing strikes (${percent.toFixed(1)}%)...`); } let count = data.strikes[key]; @@ -86,7 +87,7 @@ command.execute = async (message, args, database, bot) => { for (let /** @type {module:"discord.js".Snowflake} */ key of Object.keys(data.tempbans)) { if (bans.successful / bans.total * 100 > percent + 0.5) { percent = bans.successful / bans.total * 100; - response.edit(`Importing bans (${percent.toFixed(1)}%)...`).catch(console.error); + edit(response, `Importing bans (${percent.toFixed(1)}%)...`); } let endsAt = data.tempbans[key]; if (endsAt > Number.MAX_SAFE_INTEGER) { @@ -104,4 +105,17 @@ command.execute = async (message, args, database, bot) => { await response.edit(`Imported ${mutes.successful} of ${mutes.total} mutes, ${strikes.successful} of ${strikes.total} strikes and ${bans.successful} of ${bans.total} bans in ${time}!`); }; +/** + * edit a message and handle errors + * @param {module:"discord.js".Message} message + * @param {String} content + * @return {Promise} + */ +function edit(message, content) { + return message.edit(content).catch(async (e) => { + console.error('Failed to edit message: ', e); + await monitor.error('Failed to edit message', e) + }); +} + module.exports = command; diff --git a/src/commands/legacy/kick.js b/src/commands/legacy/kick.js index 5c7da53bd..d41bc8c4a 100644 --- a/src/commands/legacy/kick.js +++ b/src/commands/legacy/kick.js @@ -3,6 +3,8 @@ const Log = require('../../Log'); const GuildConfig = require('../../GuildConfig'); const RateLimiter = require('../../RateLimiter'); const icons = require('../../icons'); +const {APIErrors} = require('discord.js').Constants; + const command = {}; command.description = 'Kick a user'; @@ -33,9 +35,14 @@ command.execute = async (message, args, database, bot) => { try { member = await message.guild.members.fetch(userId); } catch (e) { - await message.react(icons.error); - await message.channel.send("User not found or not in guild!"); - continue; + if (e.code === APIErrors.UNKNOWN_MEMBER) { + await message.react(icons.error); + await message.channel.send("User not found or not in guild!"); + continue; + } + else { + throw e; + } } if (member.user.bot) { @@ -71,7 +78,11 @@ command.kick = async (guild, member, moderator, reason, channel) => { try { await RateLimiter.sendDM(guild, member, `You were kicked from \`${guild.name}\` | ${reason}`); - } catch (e) {} + } catch (e) { + if (e.code !== APIErrors.CANNOT_MESSAGE_USER) { + throw e; + } + } await member.kick(`${moderator.username}#${moderator.discriminator} | `+reason); if (channel) { diff --git a/src/commands/legacy/moderations.js b/src/commands/legacy/moderations.js index 3e1850399..a065fe049 100644 --- a/src/commands/legacy/moderations.js +++ b/src/commands/legacy/moderations.js @@ -2,6 +2,7 @@ const util = require('../../util.js'); const Discord = require('discord.js'); const GuildConfig = require('../../GuildConfig'); const icons = require('../../icons'); +const {APIErrors} = require('discord.js').Constants; /** * timeout after last reaction in ms @@ -34,10 +35,16 @@ command.execute = async (message, args, database, bot) => { let user; try { user = await bot.users.fetch(userId); - } catch { - await message.react(icons.error); - await message.channel.send("User not found!"); - return; + } + catch (e) { + if (e.code === APIErrors.UNKNOWN_USER) { + await message.react(icons.error); + await message.channel.send("User not found!"); + return; + } + else { + throw e; + } } /** @type {ModerationData[]} */ diff --git a/src/commands/legacy/mute.js b/src/commands/legacy/mute.js index d553822b0..fd8127d89 100644 --- a/src/commands/legacy/mute.js +++ b/src/commands/legacy/mute.js @@ -4,6 +4,7 @@ const GuildConfig = require('../../GuildConfig'); const RateLimiter = require('../../RateLimiter'); const icons = require('../../icons'); const command = {}; +const {APIErrors} = require('discord.js').Constants; command.description = 'Mute a user'; @@ -45,7 +46,11 @@ command.execute = async (message, args, database, bot) => { try { member = await message.guild.members.fetch(userId); } - catch{} + catch (e) { + if (![APIErrors.UNKNOWN_MEMBER, APIErrors.UNKNOWN_USER].includes(e.code)) { + throw e; + } + } //highest role check if(member && (message.member.roles.highest.comparePositionTo((await message.guild.members.fetch(userId)).roles.highest) <= 0 || guildconfig.isProtected(member))) { @@ -93,7 +98,16 @@ command.mute = async (guild, user, moderator, reason, duration, channel) => { text = `You were permanently muted in \`${guild.name}\` | ${reason}`; } await RateLimiter.sendDM(guild, member, text); - } catch (e) {} + } catch (e) { + if (APIErrors.MISSING_PERMISSIONS === e.code) { + if (channel) { + await channel.send('I am missing the required permissions to perform this command!') + } + } + else if (![APIErrors.UNKNOWN_MEMBER, APIErrors.UNKNOWN_USER, APIErrors.CANNOT_MESSAGE_USER, APIErrors.MISSING_PERMISSIONS, ].includes(e.code)) { + throw e; + } + } let insert = await util.moderationDBAdd(guild.id, user.id, "mute", reason, duration, moderator.id); if (channel) { diff --git a/src/commands/legacy/mutedrole.js b/src/commands/legacy/mutedrole.js index 77e98371e..96db40c99 100644 --- a/src/commands/legacy/mutedrole.js +++ b/src/commands/legacy/mutedrole.js @@ -1,5 +1,6 @@ const util = require('../../util.js'); const GuildConfig = require('../../GuildConfig'); +const {APIErrors} = require('discord.js').Constants; const command = {}; @@ -70,8 +71,14 @@ command.execute = async (message, args, database, bot) => { if (member.roles.cache.get(oldRole)) { await member.roles.remove(oldRole); } - } catch (e) { - console.error("Couldn't change muted role",e); + } + catch (e) { + if (e.code === APIErrors.MISSING_PERMISSIONS) { + await message.channel.send(`Missing permissions to edit these roles. Please make sure that both muted roles are below me!`); + } + else { + throw e; + } } } } diff --git a/src/commands/legacy/pardon.js b/src/commands/legacy/pardon.js index c4c02a2ae..6be1aaf18 100644 --- a/src/commands/legacy/pardon.js +++ b/src/commands/legacy/pardon.js @@ -4,6 +4,7 @@ const GuildConfig = require('../../GuildConfig'); const RateLimiter = require('../../RateLimiter'); const maxStrikesAtOnce = 5; const icons = require('../../icons'); +const {APIErrors} = require('discord.js').Constants; const command = {}; @@ -58,12 +59,17 @@ command.execute = async (message, args, database, bot) => { let member; try { member = await message.guild.members.fetch(user); - if(message.member.roles.highest.comparePositionTo(member.roles.highest) <= 0 || guildconfig.isProtected(member)){ - await message.react(icons.error); - await message.channel.send(`You don't have the permission to pardon strikes of <@${member.id}>!`); - continue; + } catch (e) { + if (![APIErrors.UNKNOWN_MEMBER].includes(e.code)) { + throw e; } - } catch (e) {} + } + + if(member && message.member.roles.highest.comparePositionTo(member.roles.highest) <= 0 || guildconfig.isProtected(member)){ + await message.react(icons.error); + await message.channel.send(`You don't have the permission to pardon strikes of <@${member.id}>!`); + continue; + } let now = Math.floor(Date.now()/1000); diff --git a/src/commands/legacy/purge.js b/src/commands/legacy/purge.js index 07776b28d..b452afeb7 100644 --- a/src/commands/legacy/purge.js +++ b/src/commands/legacy/purge.js @@ -135,26 +135,17 @@ command.execute = async (message, args, database, bot) => { return; } - try { - await util.delete(message); - } catch (e) {} - - try { - await util.bulkDelete(message.channel, messages); - } catch (e) { - console.log('bulkDelete failed ', e); - } + await util.delete(message); + + await util.bulkDelete(message.channel, messages); let response = await message.channel.send(new Discord.MessageEmbed({ color: util.color.green, description: `Deleted **${messages.size}** ${messages.size === 1 ? 'message' : 'messages'}.` })); - try { - await util.delete(response,{timeout: 3000}); - } catch (e) {} + await util.delete(response,{timeout: 3000}); - let guildConfig = await GuildConfig.get(message.guild.id); const logembed = new Discord.MessageEmbed() .setColor(util.color.orange) .setAuthor(`${message.author.username}#${message.author.discriminator} purged ${messages.size} ${messages.size === 1 ? 'message' : 'messages'}.`) diff --git a/src/commands/legacy/softban.js b/src/commands/legacy/softban.js index 3c8a95190..5ef9e987d 100644 --- a/src/commands/legacy/softban.js +++ b/src/commands/legacy/softban.js @@ -3,6 +3,7 @@ const Log = require('../../Log'); const GuildConfig = require('../../GuildConfig'); const RateLimiter = require('../../RateLimiter'); const icons = require('../../icons'); +const {APIErrors} = require('discord.js').Constants; const command = {}; @@ -33,10 +34,16 @@ command.execute = async (message, args, database, bot) => { let member; try { member = await message.guild.members.fetch(userId); - } catch (e) { - await message.react(icons.error); - await message.channel.send("User not found or not in guild!"); - continue; + } + catch (e) { + if (e.code === APIErrors.UNKNOWN_MEMBER) { + await message.react(icons.error); + await message.channel.send("User not found or not in guild!"); + continue; + } + else { + throw e; + } } if (member.user.bot) { @@ -70,7 +77,11 @@ command.softban = async (guild, member, moderator, reason, channel) => { try { await RateLimiter.sendDM(guild, member, `You were softbanned from \`${guild.name}\` | ${reason}`); - } catch (e) {} + } catch (e) { + if (e.code !== APIErrors.CANNOT_MESSAGE_USER) { + throw e; + } + } await guild.members.ban(member.id,{days: 1, reason: `${moderator.username}#${moderator.discriminator} | `+reason}); await guild.members.unban(member.id,`Softban`); diff --git a/src/commands/legacy/strike.js b/src/commands/legacy/strike.js index 0686fe513..3fc672f26 100644 --- a/src/commands/legacy/strike.js +++ b/src/commands/legacy/strike.js @@ -7,6 +7,7 @@ const GuildConfig = require('../../GuildConfig'); const Log = require('../../Log'); const RateLimiter = require('../../RateLimiter'); const icons = require('../../icons'); +const {APIErrors} = require('discord.js').Constants; const maxStrikesAtOnce = 5; @@ -49,10 +50,8 @@ command.execute = async (message, args, database, bot) => { } for (let userId of users) { - let user; - try { - user = await bot.users.fetch(util.userMentionToId(userId)); - } catch (e) {} + /** @type {module:"discord.js".User} */ + const user = await bot.users.fetch(util.userMentionToId(userId)); if (user.bot) { await message.react(icons.error); @@ -69,7 +68,11 @@ command.execute = async (message, args, database, bot) => { await message.channel.send(`You don't have the permission to strike <@${member.id}>!`); continue; } - } catch (e) {} + } catch (e) { + if (![APIErrors.UNKNOWN_MEMBER, APIErrors.MISSING_PERMISSIONS].includes(e.code)) { + throw e; + } + } await command.add(message.guild, user, count, message.author, args.join(' '), message.channel, database, bot); } @@ -83,6 +86,8 @@ command.execute = async (message, args, database, bot) => { * @param {module:"discord.js".User} moderator * @param {String} reason * @param {module:"discord.js".TextChannel} channel + * @param {Database} database + * @param {module:"discord.js".Client} bot * @return {Promise} */ command.add = async (guild, user, count, moderator, reason, channel, database, bot) => { @@ -100,7 +105,12 @@ command.add = async (guild, user, count, moderator, reason, channel, database, b try { member = await guild.members.fetch(user); await RateLimiter.sendDM(guild, member, `You received ${count} ${count === 1 ? "strike" : "strikes"} in \`${guild.name}\` | ${reason}\nYou now have ${total} ${total === 1 ? "strike" : "strikes"}`); - } catch{} + } + catch (e){ + if (![APIErrors.UNKNOWN_MEMBER, APIErrors.CANNOT_MESSAGE_USER].includes(e.code)) { + throw e; + } + } if (channel) { await util.chatSuccess(channel, user, reason, "striked"); } @@ -154,8 +164,14 @@ command.executePunishment = async (punishment, guild, user, bot, database, reaso case 'kick': try { member = await guild.members.fetch(user.id); - } catch (e) { - return; + } + catch (e) { + if (e.code === APIErrors.UNKNOWN_MEMBER) { + return; + } + else { + throw e; + } } await kick.kick(guild, member, bot.user, reason); break; @@ -165,8 +181,14 @@ command.executePunishment = async (punishment, guild, user, bot, database, reaso case 'softban': try { member = await guild.members.fetch(user.id); - } catch (e) { - return; + } + catch (e) { + if (e.code === APIErrors.UNKNOWN_MEMBER) { + return; + } + else { + throw e; + } } await softban.softban(guild, member, bot.user, reason); break; @@ -182,9 +204,9 @@ command.executePunishment = async (punishment, guild, user, bot, database, reaso await RateLimiter.sendDM(guild, user, `Your message in \`${guild.name}\` was removed: ` + punishment.message); } catch (e) { - const codes = [/* Cannot send messages to this user */50007] - if (codes.includes(e.code)) return; - throw e; + if (![APIErrors.CANNOT_MESSAGE_USER].includes(e.code)) { + throw e; + } } break; diff --git a/src/commands/legacy/unban.js b/src/commands/legacy/unban.js index 4a13ac046..0f300120b 100644 --- a/src/commands/legacy/unban.js +++ b/src/commands/legacy/unban.js @@ -2,6 +2,8 @@ const util = require('../../util.js'); const Log = require('../../Log'); const GuildConfig = require('../../GuildConfig'); const icons = require('../../icons'); +const {APIErrors} = require('discord.js').Constants; + const command = {}; command.description = 'Unban a user'; @@ -40,7 +42,9 @@ command.execute = async (message, args, database, bot) => { try { ban = await message.guild.fetchBan(userId); } catch (e) { - + if (e.code !== APIErrors.UNKNOWN_BAN) { + throw e; + } } if(!await database.query("SELECT * FROM moderations WHERE active = TRUE AND guildid = ? AND userid = ? AND action = 'ban'", [message.guild.id, userId]) && !ban) { await message.react(icons.error); diff --git a/src/commands/legacy/unmute.js b/src/commands/legacy/unmute.js index fa713bdc1..b3e2f3027 100644 --- a/src/commands/legacy/unmute.js +++ b/src/commands/legacy/unmute.js @@ -3,6 +3,8 @@ const Log = require('../../Log'); const GuildConfig = require('../../GuildConfig'); const RateLimiter = require('../../RateLimiter'); const icons = require('../../icons'); +const {APIErrors} = require('discord.js').Constants; + const command = {}; command.description = 'Unmute a user'; @@ -34,7 +36,11 @@ command.execute = async (message, args, database, bot) => { let member; try { member = await message.guild.members.fetch(userId); - } catch (e) {} + } catch (e) { + if (e.code !== APIErrors.UNKNOWN_MEMBER) { + throw e; + } + } let guildConfig = await GuildConfig.get(message.guild.id); if (user.bot) { @@ -60,7 +66,11 @@ command.execute = async (message, args, database, bot) => { if (member) { try { await RateLimiter.sendDM(message.guild, user, `You were unmuted in \`${message.guild.name}\` | ${reason}`); - } catch (e) {} + } catch (e) { + if (e.code !== APIErrors.CANNOT_MESSAGE_USER) { + throw e; + } + } } await util.chatSuccess(message.channel, user, reason, "unmuted"); diff --git a/src/commands/legacy/userinfo.js b/src/commands/legacy/userinfo.js index c86d30eb6..343e3ddd3 100644 --- a/src/commands/legacy/userinfo.js +++ b/src/commands/legacy/userinfo.js @@ -3,6 +3,7 @@ const Discord = require('discord.js'); const GuildConfig = require('../../GuildConfig'); const icons = require('../../icons'); const command = {}; +const {APIErrors} = require('discord.js').Constants; command.description = 'Show information about a user'; @@ -27,16 +28,27 @@ command.execute = async (message, args, database, bot) => { let user; try { user = await bot.users.fetch(userId); - } catch (e) { - await message.react(icons.error); - await message.channel.send("User not found!"); - return; + } + catch (e) { + if (e.code === APIErrors.UNKNOWN_USER) { + await message.react(icons.error); + await message.channel.send("User not found!"); + return; + } + else { + throw e; + } } let member; try { member = await message.guild.members.fetch(userId); - } catch (e) {} + } + catch (e) { + if (e.code !== APIErrors.UNKNOWN_MEMBER) { + throw e; + } + } let embed = new Discord.MessageEmbed({ description: `` @@ -92,8 +104,14 @@ command.execute = async (message, args, database, bot) => { banInfo = await message.guild.fetchBan(/** @type {UserResolvable} */ userId); banInfo = `${icons.yes} - ${decodeURIComponent(banInfo.reason || 'Unknown reason')}`; embed.setDescription(embed.description + `**Banned:** ${banInfo}`); - } catch (e) { - embed.setDescription(embed.description + `**Banned:** ${icons.no}`); + } + catch (e) { + if (e.code === APIErrors.UNKNOWN_BAN) { + embed.setDescription(embed.description + `**Banned:** ${icons.no}`); + } + else { + throw e; + } } } await message.channel.send(embed); diff --git a/src/commands/settings/HelpCenterCommand.js b/src/commands/settings/HelpCenterCommand.js index 90bc6ca97..9bd7b8c19 100644 --- a/src/commands/settings/HelpCenterCommand.js +++ b/src/commands/settings/HelpCenterCommand.js @@ -43,8 +43,13 @@ class HelpCenterCommand extends Command { try { await request.getJSON(); } catch (e) { - await this.message.channel.send('This is not a valid helpcenter subdomain!'); - return; + if (e.response?.statusCode === 404 || e.code === 'ENOTFOUND') { + await this.message.channel.send('This is not a valid helpcenter subdomain!'); + return; + } + else { + throw e; + } } this.guildConfig.helpcenter = subdomain; await this.guildConfig.save(); diff --git a/src/features/error/errorAlert.js b/src/features/error/errorAlert.js new file mode 100644 index 000000000..20debe3e6 --- /dev/null +++ b/src/features/error/errorAlert.js @@ -0,0 +1,6 @@ +const monitor = require('../../Monitor').getInstance(); + +exports.event = async (error) => { + await monitor.error('The discord client experienced an error', error); + console.error('The discord client experienced an error', error); +} diff --git a/src/features/message/commands.js b/src/features/message/commands.js index 16a87585c..295a55896 100644 --- a/src/features/message/commands.js +++ b/src/features/message/commands.js @@ -3,6 +3,9 @@ const defaultPrefix = require('../../../config.json').prefix; const Discord = require('discord.js'); const util = require('../../util'); const GuildConfig = require('../../GuildConfig'); +const {APIErrors} = Discord.Constants; + +const monitor = require('../../Monitor').getInstance(); class CommandHandler { /** @@ -33,7 +36,8 @@ class CommandHandler { commands[name] = command; } } catch (e) { - console.error(`Failed to load command '${file}'`, e); + monitor.error(`Failed to load command '${folder}/${file}'`, e); + console.error(`Failed to load command '${folder}/${file}'`, e); } } } @@ -72,12 +76,21 @@ class CommandHandler { } await cmd.execute(); } catch (e) { - let embed = new Discord.MessageEmbed({ - color: util.color.red, - description: `An error occurred while executing that command!` - }); - await message.channel.send(embed); - console.error(`An error occurred while executing command ${Command.names[0]}:`,e); + try { + if (e.code === APIErrors.MISSING_PERMISSIONS) { + await message.channel.send('I am missing permissions to execute that command!'); + } + else { + await message.channel.send('An error occurred while executing that command!'); + } + } + catch (e2) { + if (e2.code === APIErrors.MISSING_PERMISSIONS) { + return; + } + } + await monitor.error(`Failed to execute command ${name}`, e); + console.error(`An error occurred while executing command ${name}:`,e); } } diff --git a/src/features/message/legacyCommands.js b/src/features/message/legacyCommands.js index d495e61a1..582d1f723 100644 --- a/src/features/message/legacyCommands.js +++ b/src/features/message/legacyCommands.js @@ -3,6 +3,8 @@ const { prefix } = require('../../../config.json'); const Discord = require('discord.js'); const util = require('../../util'); const GuildConfig = require('../../GuildConfig'); +const monitor = require('../../Monitor').getInstance(); +const {APIErrors} = Discord.Constants; /** * loaded commands @@ -19,7 +21,8 @@ const commands = []; try { commands.push(require(path)); } catch (e) { - console.error(`Failed to load command '${file}'`, e); + await monitor.error(`Failed to load legacy command 'legacy/${file}'`, e); + console.error(`Failed to load legacy command 'legacy/${file}'`, e); } } })() @@ -40,12 +43,21 @@ exports.event = async(options, message) => { try { await Promise.resolve(command.execute(message, args, options.database, options.bot)); } catch (e) { - let embed = new Discord.MessageEmbed({ - color: util.color.red, - description: `An error occurred while executing that command!` - }); - await message.channel.send(embed); - console.error(`An error occurred while executing command ${command.names[0]}:`,e); + try { + if (e.code === APIErrors.MISSING_PERMISSIONS) { + await message.channel.send('I am missing permissions to execute that command!'); + } + else { + await message.channel.send('An error occurred while executing that command!'); + } + } + catch (e2) { + if (e2.code === APIErrors.MISSING_PERMISSIONS) { + return; + } + } + await monitor.error(`Failed to execute command ${name}`, e); + console.error(`An error occurred while executing command ${name}:`,e); } } diff --git a/src/features/rateLimit/rateLimitAlert.js b/src/features/rateLimit/rateLimitAlert.js new file mode 100644 index 000000000..985babb6a --- /dev/null +++ b/src/features/rateLimit/rateLimitAlert.js @@ -0,0 +1,6 @@ +const monitor = require('../../Monitor').getInstance(); + +exports.event = async(rateLimitInfo) => { + await monitor.warn('The bot hit a ratelimit', rateLimitInfo); + console.log('The bot hit a ratelimit', rateLimitInfo); +} diff --git a/src/features/warn/warningAlert.js b/src/features/warn/warningAlert.js new file mode 100644 index 000000000..1dcb890a0 --- /dev/null +++ b/src/features/warn/warningAlert.js @@ -0,0 +1,6 @@ +const monitor = require('../../Monitor').getInstance(); + +exports.event = async (warning) => { + await monitor.error('The discord client emitted a warning', warning); + console.error('The discord client emitted a warning', warning); +} diff --git a/src/util.js b/src/util.js index 4906d807b..f21488d36 100644 --- a/src/util.js +++ b/src/util.js @@ -3,6 +3,7 @@ const GuildConfig = require('./GuildConfig.js'); const ChatTriggeredFeature = require('./ChatTriggeredFeature'); const Config = require('./Config'); const RateLimiter = require('./RateLimiter'); +const {APIErrors} = require('discord.js').Constants; /** * Default timeout for responses in minutes @@ -173,13 +174,17 @@ util.isUserMention = async(mention) => { * @return {Promise} */ util.isUser = async (id) => { - let notUser; try { await bot.users.fetch(/** @type {Snowflake} */ id); } catch (e) { - notUser = true; + if (e.code === APIErrors.UNKNOWN_USER) { + return false; + } + else { + throw e; + } } - return !notUser; + return true; }; /** @@ -305,8 +310,14 @@ util.resolveGuild = async (guildInfo) => { } try { return await bot.guilds.fetch(/** @type {Snowflake} */ guildInfo); - } catch (e) { - return null; + } + catch (e) { + if (e.code === APIErrors.UNKNOWN_GUILD) { + return null; + } + else { + throw e; + } } }; @@ -557,7 +568,7 @@ util.delete = async(message, options) => { try { return await util.retry(message.delete, message, [options]); } catch (e) { - if (e.code === 10008) { + if (e.code === APIErrors.UNKNOWN_MESSAGE) { return Promise.resolve(message); } throw e;