From 9fc045cd38c11400a3530409b34d37477357af23 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Mon, 31 May 2021 03:30:55 +0200 Subject: [PATCH 01/79] Start move to d.js --- backend/package-lock.json | 6365 +---------------- backend/package.json | 9 +- backend/src/index.ts | 53 +- backend/src/types.ts | 12 + backend/src/utils.ts | 120 +- backend/src/utils/createPaginatedMessage.ts | 24 +- backend/src/utils/getChunkedEmbedFields.ts | 4 +- .../src/utils/getMissingChannelPermissions.ts | 7 +- backend/src/utils/getMissingPermissions.ts | 13 +- backend/src/utils/getPermissionNames.ts | 6 +- backend/src/utils/hasDiscordPermissions.ts | 6 +- backend/src/utils/lockNameHelpers.ts | 8 +- backend/src/utils/messageHasContent.ts | 4 +- backend/src/utils/messageIsEmpty.ts | 4 +- backend/src/utils/readChannelPermissions.ts | 4 +- backend/src/utils/resolveMessageTarget.ts | 4 +- backend/src/utils/sendDM.ts | 13 +- 17 files changed, 339 insertions(+), 6317 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 6edbab28..ca572ce5 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,6090 +1,8 @@ { "name": "@zeppelin/backend", "version": "0.0.1", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "@zeppelin/backend", - "version": "0.0.1", - "dependencies": { - "@types/sharp": "^0.23.1", - "@types/twemoji": "^12.1.0", - "bufferutil": "^4.0.1", - "cors": "^2.8.5", - "cross-env": "^5.2.0", - "deep-diff": "^1.0.2", - "dotenv": "^4.0.0", - "emoji-regex": "^8.0.0", - "eris": "^0.15.1", - "erlpack": "github:abalabahaha/erlpack", - "escape-string-regexp": "^1.0.5", - "express": "^4.17.0", - "fp-ts": "^2.0.1", - "humanize-duration": "^3.15.0", - "io-ts": "^2.0.0", - "js-yaml": "^3.13.1", - "knub": "^30.0.0-beta.37", - "knub-command-manager": "^8.1.2", - "last-commit-log": "^2.1.0", - "lodash.chunk": "^4.2.0", - "lodash.clonedeep": "^4.5.0", - "lodash.difference": "^4.5.0", - "lodash.intersection": "^4.4.0", - "lodash.isequal": "^4.5.0", - "lodash.pick": "^4.4.0", - "moment-timezone": "^0.5.21", - "mysql": "^2.16.0", - "parse-color": "^1.0.0", - "passport": "^0.4.0", - "passport-custom": "^1.0.5", - "passport-oauth2": "^1.5.0", - "pkg-up": "^3.1.0", - "reflect-metadata": "^0.1.12", - "regexp-worker": "^1.1.0", - "safe-regex": "^2.0.2", - "seedrandom": "^3.0.1", - "sharp": "^0.23.4", - "strip-combining-marks": "^1.0.0", - "tlds": "^1.203.1", - "tmp": "0.0.33", - "tsconfig-paths": "^3.9.0", - "twemoji": "^12.1.4", - "typeorm": "^0.2.31", - "uuid": "^3.3.2", - "yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build", - "zlib-sync": "^0.1.7" - }, - "devDependencies": { - "@types/cors": "^2.8.5", - "@types/express": "^4.16.1", - "@types/jest": "^24.0.15", - "@types/js-yaml": "^3.12.1", - "@types/lodash.at": "^4.6.3", - "@types/moment-timezone": "^0.5.6", - "@types/node": "^14.0.14", - "@types/passport": "^1.0.0", - "@types/passport-oauth2": "^1.4.8", - "@types/passport-strategy": "^0.2.35", - "@types/safe-regex": "^1.1.2", - "@types/tmp": "0.0.33", - "ava": "^3.10.0", - "rimraf": "^2.6.2", - "source-map-support": "^0.5.16", - "tsc-watch": "^4.0.0", - "typescript": "^4.1.3" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true - }, - "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", - "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", - "dev": true, - "dependencies": { - "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@concordance/react": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", - "integrity": "sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1" - }, - "engines": { - "node": ">=6.12.3 <7 || >=8.9.4 <9 || >=10.0.0" - } - }, - "node_modules/@concordance/react/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@sqltools/formatter": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.2.tgz", - "integrity": "sha512-/5O7Fq6Vnv8L6ucmPjaWbVG1XkP4FO+w5glqfkIsq3Xw4oyNAdJddbnYodNDAfjVUvo/rrSCTom4kAND7T1o5Q==" - }, - "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@types/body-parser": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", - "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "node_modules/@types/connect": { - "version": "3.4.32", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", - "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cors": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.6.tgz", - "integrity": "sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz", - "integrity": "sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.16.11", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.11.tgz", - "integrity": "sha512-K8d2M5t3tBQimkyaYTXxtHYyoJPUEhy2/omVRnTAKw5FEdT+Ft6lTaTOpoJdHeG+mIwQXXtqiTcYZ6IR8LTzjQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/jest": { - "version": "24.0.21", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.21.tgz", - "integrity": "sha512-uyqFvx78Tuy0h5iLCPWRCvi5HhWwEqhIj30doitp191oYLqlCxUyAJHdWVm5+Nr271/vPnkyt6rWeEIjGowBTg==", - "dev": true, - "dependencies": { - "@types/jest-diff": "*" - } - }, - "node_modules/@types/jest-diff": { - "version": "20.0.1", - "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", - "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", - "dev": true - }, - "node_modules/@types/js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, - "node_modules/@types/lodash": { - "version": "4.14.144", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.144.tgz", - "integrity": "sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg==", - "dev": true - }, - "node_modules/@types/lodash.at": { - "version": "4.6.6", - "resolved": "https://registry.npmjs.org/@types/lodash.at/-/lodash.at-4.6.6.tgz", - "integrity": "sha512-OAfIqBWv0HjWVxKF8y6ZFTEwLM1wgpvsrMOb/fEKp8/HM2JO2V555Au5JZkiTnXOF453rqCooGKYFzNrR/kaAA==", - "dev": true, - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/mime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", - "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "node_modules/@types/moment-timezone": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/@types/moment-timezone/-/moment-timezone-0.5.12.tgz", - "integrity": "sha512-hnHH2+Efg2vExr/dSz+IX860nSiyk9Sk4pJF2EmS11lRpMcNXeB4KBW5xcgw2QPsb9amTXdsVNEe5IoJXiT0uw==", - "dev": true, - "dependencies": { - "moment": ">=2.14.0" - } - }, - "node_modules/@types/node": { - "version": "14.0.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", - "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==" - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true - }, - "node_modules/@types/oauth": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz", - "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/passport": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.1.tgz", - "integrity": "sha512-oK87JjN8i8kmqb0RN0sCUB/ZjrWf3b8U45eAzZVy1ssYYgBrMOuALmvoqp7MglsilXAjxum+LS29VQqeQx6ddA==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/passport-oauth2": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.8.tgz", - "integrity": "sha512-tlX16wyFE5YJR2pHpZ308dgB1MV9/Ra2wfQh71eWk+/umPoD1Rca2D4N5M27W7nZm1wqUNGTk1I864nHvEgiFA==", - "dev": true, - "dependencies": { - "@types/express": "*", - "@types/oauth": "*", - "@types/passport": "*" - } - }, - "node_modules/@types/passport-strategy": { - "version": "0.2.35", - "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz", - "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==", - "dev": true, - "dependencies": { - "@types/express": "*", - "@types/passport": "*" - } - }, - "node_modules/@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", - "dev": true - }, - "node_modules/@types/safe-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/safe-regex/-/safe-regex-1.1.2.tgz", - "integrity": "sha512-wuS9LVpgIiTYaGKd+s6Dj0kRXBkttaXjVxzaXmviCACi8RO+INPayND+VNjAcall/l1Jkyhh9lyPfKW/aP/Yug==", - "dev": true - }, - "node_modules/@types/serve-static": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", - "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", - "dev": true, - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/mime": "*" - } - }, - "node_modules/@types/sharp": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz", - "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0=", - "dev": true - }, - "node_modules/@types/twemoji": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.0.tgz", - "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==" - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", - "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-align": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", - "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", - "dev": true, - "dependencies": { - "string-width": "^3.0.0" - } - }, - "node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/arrgv": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", - "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/ava/-/ava-3.10.0.tgz", - "integrity": "sha512-CxcYQYeE39pcLWrN2/TASMpnqH/SoaX+W61+4m3saETU041PIDcoP9LLNWPAE/yJZXjp0M1RWTohSkmGqJZKww==", - "dev": true, - "dependencies": { - "@concordance/react": "^2.0.0", - "acorn": "^7.3.1", - "acorn-walk": "^7.2.0", - "ansi-styles": "^4.2.1", - "arrgv": "^1.0.2", - "arrify": "^2.0.1", - "callsites": "^3.1.0", - "chalk": "^4.1.0", - "chokidar": "^3.4.0", - "chunkd": "^2.0.1", - "ci-info": "^2.0.0", - "ci-parallel-vars": "^1.0.1", - "clean-yaml-object": "^0.1.0", - "cli-cursor": "^3.1.0", - "cli-truncate": "^2.1.0", - "code-excerpt": "^3.0.0", - "common-path-prefix": "^3.0.0", - "concordance": "^5.0.0", - "convert-source-map": "^1.7.0", - "currently-unhandled": "^0.4.1", - "debug": "^4.1.1", - "del": "^5.1.0", - "emittery": "^0.7.0", - "equal-length": "^1.0.0", - "figures": "^3.2.0", - "globby": "^11.0.1", - "ignore-by-default": "^2.0.0", - "import-local": "^3.0.2", - "indent-string": "^4.0.0", - "is-error": "^2.2.2", - "is-plain-object": "^3.0.1", - "is-promise": "^4.0.0", - "lodash": "^4.17.15", - "matcher": "^3.0.0", - "md5-hex": "^3.0.1", - "mem": "^6.1.0", - "ms": "^2.1.2", - "ora": "^4.0.4", - "p-map": "^4.0.0", - "picomatch": "^2.2.2", - "pkg-conf": "^3.1.0", - "plur": "^4.0.0", - "pretty-ms": "^7.0.0", - "read-pkg": "^5.2.0", - "resolve-cwd": "^3.0.0", - "slash": "^3.0.0", - "source-map-support": "^0.5.19", - "stack-utils": "^2.0.2", - "strip-ansi": "^6.0.0", - "supertap": "^1.0.0", - "temp-dir": "^2.0.0", - "trim-off-newlines": "^1.0.1", - "update-notifier": "^4.1.0", - "write-file-atomic": "^3.0.3", - "yargs": "^15.4.0" - }, - "bin": { - "ava": "cli.js" - }, - "engines": { - "node": ">=10.18.0 <11 || >=12.14.0 <12.17.0 || >=12.17.0 <13 || >=14.0.0" - } - }, - "node_modules/ava/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ava/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/ava/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ava/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ava/node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/ava/node_modules/decamelize": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", - "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", - "dev": true, - "dependencies": { - "xregexp": "^4.2.4" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ava/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/ava/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/ava/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/yargs": { - "version": "15.4.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", - "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^3.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ava/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ava/node_modules/yargs-parser/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "node_modules/base64url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", - "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", - "dependencies": { - "readable-stream": "^3.0.1" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/blueimp-md5": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.16.0.tgz", - "integrity": "sha512-j4nzWIqEFpLSbdhUApHRGDwfXbV8ALhqOn+FY5L6XBdKPAXU9BpGgFSbDsgqogfqPPR9R2WooseWCsfhfEC6uQ==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/boxen": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", - "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "cli-boxes": "^2.2.0", - "string-width": "^4.1.0", - "term-size": "^2.1.0", - "type-fest": "^0.8.1", - "widest-line": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/boxen/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/boxen/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "node_modules/bufferutil": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", - "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", - "dependencies": { - "node-gyp-build": "~3.7.0" - } - }, - "node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chokidar": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", - "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.2" - } - }, - "node_modules/chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" - }, - "node_modules/chunkd": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", - "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", - "dev": true - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "node_modules/ci-parallel-vars": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", - "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", - "dev": true - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cli-boxes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-highlight": { - "version": "2.1.10", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.10.tgz", - "integrity": "sha512-CcPFD3JwdQ2oSzy+AMG6j3LRTkNjM82kzcSKzoVw6cLanDCJNlsLjeqVTOTfOfucnWv5F0rmBemVf1m9JiIasw==", - "dependencies": { - "chalk": "^4.0.0", - "highlight.js": "^10.0.0", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.0", - "yargs": "^16.0.0" - }, - "bin": { - "highlight": "bin/highlight" - }, - "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" - } - }, - "node_modules/cli-highlight/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-highlight/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cli-highlight/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/cli-highlight/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/cli-highlight/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-highlight/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", - "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/code-excerpt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", - "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", - "dev": true, - "dependencies": { - "convert-to-spaces": "^1.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", - "dependencies": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/concordance": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.0.tgz", - "integrity": "sha512-stOCz9ffg0+rytwTaL2njUOIyMfANwfwmqc9Dr4vTUS/x/KkVFlWx9Zlzu6tHYtjKxxaCF/cEAZgPDac+n35sg==", - "dev": true, - "dependencies": { - "date-time": "^3.1.0", - "esutils": "^2.0.3", - "fast-diff": "^1.2.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.17.15", - "md5-hex": "^3.0.1", - "semver": "^7.3.2", - "well-known-symbols": "^2.0.0" - }, - "engines": { - "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=13.5.0" - } - }, - "node_modules/concordance/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/convert-to-spaces": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", - "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", - "dev": true - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cross-env": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz", - "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==", - "dependencies": { - "cross-spawn": "^6.0.5" - }, - "bin": { - "cross-env": "dist/bin/cross-env.js", - "cross-env-shell": "dist/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/date-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", - "dev": true, - "dependencies": { - "time-zone": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/deep-diff": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-1.0.2.tgz", - "integrity": "sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==" - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - } - }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "node_modules/del": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", - "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", - "dev": true, - "dependencies": { - "globby": "^10.0.1", - "graceful-fs": "^4.2.2", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.1", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/del/node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/del/node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/del/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=", - "engines": { - "node": ">=4.6.0" - } - }, - "node_modules/dotgitconfig": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dotgitconfig/-/dotgitconfig-1.0.1.tgz", - "integrity": "sha512-a6RPc5Cco7ogiKLVExcGBMEEP6jHkzJFYbS/HYGFvQSZrm3EkC876YIqqrj92N8SZYGLqPz6pU522/LlNAaedQ==", - "dependencies": { - "ini": "^1.3.5" - } - }, - "node_modules/duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "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/emittery": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", - "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/equal-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", - "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eris": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/eris/-/eris-0.15.1.tgz", - "integrity": "sha512-IQ3BPW6OjgFoqjdh+irPOa1jFlkotk+WNu2GQQ7QAQfbzQEPZgn+F+hpOxfMUXPHOZMX4sPKLkVDkMHAssBYhw==", - "dependencies": { - "ws": "^7.2.1" - }, - "engines": { - "node": ">=10.4.0" - }, - "optionalDependencies": { - "opusscript": "^0.0.8", - "tweetnacl": "^1.0.1" - } - }, - "node_modules/erlpack": { - "resolved": "git+ssh://git@github.com/abalabahaha/erlpack.git#5d0064f9e106841e1eead711a6451f99b0d289fd", - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.14.0" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figlet": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", - "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fp-ts": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.1.1.tgz", - "integrity": "sha512-YcWhMdDCFCja0MmaDroTgNu+NWWrrnUEn92nvDgrtVy9Z71YFnhNVIghoHPt8gs82ijoMzFGeWKvArbyICiJgw==" - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-extra/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/fs-minipass": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz", - "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" - }, - "node_modules/glob": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", - "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", - "dev": true, - "dependencies": { - "ini": "^1.3.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/highlight.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.6.0.tgz", - "integrity": "sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==", - "engines": { - "node": "*" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true - }, - "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/humanize-duration": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.21.0.tgz", - "integrity": "sha512-7BLsrQZ2nMGeakmGDUl1pDne6/7iAdvwf1RtDLCOPHNFIHjkOVW7lcu7xHkIM9HhZAlSSO5crhC1dHvtl4dIQw==" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.0.0.tgz", - "integrity": "sha512-+mQSgMRiFD3L3AOxLYOCxjIq4OnAmo5CIuC+lj5ehCJcPtV++QacEV7FdpzvYxH6DaOySWzQU6RR0lPLy37ckA==", - "dev": true, - "engines": { - "node": ">=10 <11 || >=12 <13 || >=14" - } - }, - "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "engines": { - "node": "*" - } - }, - "node_modules/io-ts": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-2.0.1.tgz", - "integrity": "sha512-RezD+WcCfW4VkMkEcQWL/Nmy/nqsWTvTYg7oUmTGzglvSSV2P9h2z1PVeREPFf0GWNzruYleAt1XCMQZSg1xxQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/irregular-plurals": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz", - "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-error": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", - "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-installed-globally": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", - "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", - "dev": true, - "dependencies": { - "global-dirs": "^2.0.1", - "is-path-inside": "^3.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-npm": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", - "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", - "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", - "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz", - "integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==", - "dependencies": { - "graceful-fs": "^4.1.6", - "universalify": "^0.1.2" - } - }, - "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/knub": { - "version": "30.0.0-beta.37", - "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.37.tgz", - "integrity": "sha512-eXgdhmD1bvGlqLG80mfLGwvkjgGZnTOhUXkO5dAjGujfiE02FbamKnVovw92ruUaB4HS35ydwJPTG3vvUuh/Sg==", - "dependencies": { - "knub-command-manager": "^9.1.0", - "ts-essentials": "^6.0.7" - }, - "peerDependencies": { - "eris": "^0.15.1" - } - }, - "node_modules/knub-command-manager": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-8.1.2.tgz", - "integrity": "sha512-/ooWzol2uxKRSi8INDaexXeRfLRJyboQUbwFFljkE3aYHihnf4ZNuKNgQImq2aUhSdLl9Jy/A1fCSjuooNsbtw==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - } - }, - "node_modules/knub-command-manager/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/knub/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/knub/node_modules/knub-command-manager": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-9.1.0.tgz", - "integrity": "sha512-pEtpWElbBoTRSL8kWSPRrTIuTIdvYGkP/wzOn77cieumC02adfwEt1Cc09HFvVT4ib35nf1y31oul36csaG7Vg==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - } - }, - "node_modules/last-commit-log": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/last-commit-log/-/last-commit-log-2.1.0.tgz", - "integrity": "sha512-vvZNAaiPSQ/PtyfDP2UrIRwKx0xttliGSwEfd/4tU1B/2iD/g4e3nWbttYb6YLarpULpM6s5OW5JWl97ogB6jA==", - "dependencies": { - "dotgitconfig": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "dependencies": { - "package-json": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "node_modules/load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "node_modules/lodash.chunk": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", - "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "node_modules/lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" - }, - "node_modules/lodash.intersection": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.intersection/-/lodash.intersection-4.4.0.tgz", - "integrity": "sha1-ChG6Yx0OlcI8fy9Mu5ppLtF45wU=" - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" - }, - "node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/matcher/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/md5-hex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", - "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", - "dev": true, - "dependencies": { - "blueimp-md5": "^2.10.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mem": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.0.tgz", - "integrity": "sha512-RlbnLQgRHk5lwqTtpEkBTQ2ll/CG/iB+J4Hy2Wh97PjgZgXgWJWrFF+XXujh3UUVLvR4OOTgZzcWMMwnehlEUg==", - "dev": true, - "dependencies": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mem/node_modules/mimic-fn": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.0.0.tgz", - "integrity": "sha512-PiVO95TKvhiwgSwg1IdLYlCTdul38yZxZMIcnDSFIBUm4BNZha2qpQ4GpJ++15bHoKDtrW2D69lMfFwdFYtNZQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "dependencies": { - "mime-db": "1.40.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "node_modules/minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/minizlib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", - "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dependencies": { - "minimist": "0.0.8" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mkdirp/node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "node_modules/moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", - "engines": { - "node": "*" - } - }, - "node_modules/moment-timezone": { - "version": "0.5.27", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.27.tgz", - "integrity": "sha512-EIKQs7h5sAsjhPCqN6ggx6cEbs94GK050254TIJySD1bzoM5JTYDwAU1IoVOeTOL6Gm27kYJ51/uuvq1kIlrbw==", - "dependencies": { - "moment": ">= 2.9.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/mysql": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz", - "integrity": "sha512-7vMqHQ673SAk5C8fOzTG2LpPcf3bNt0oL3sFpxPEEFp1mdlDcrLK0On7z8ZYKaaHrHwNcQ/MTUz7/oobZ2OyyA==", - "dependencies": { - "bignumber.js": "7.2.1", - "readable-stream": "2.3.6", - "safe-buffer": "5.1.2", - "sqlstring": "2.3.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "node_modules/napi-build-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", - "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==" - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/node-abi": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.13.0.tgz", - "integrity": "sha512-9HrZGFVTR5SOu3PZAnAY2hLO36aW1wmA+FDsVkr85BTST32TLCA1H/AEcatVRAsWLyXS3bqUDYCAjq5/QGuSTA==", - "dependencies": { - "semver": "^5.4.1" - } - }, - "node_modules/node-cleanup": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", - "integrity": "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=", - "dev": true - }, - "node_modules/node-gyp-build": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", - "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/oauth": { - "version": "0.9.15", - "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", - "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "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", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/opusscript": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.8.tgz", - "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==", - "optional": true - }, - "node_modules/ora": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz", - "integrity": "sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.2.0", - "is-interactive": "^1.0.0", - "log-symbols": "^3.0.0", - "mute-stream": "0.0.8", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ora/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ora/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/package-json/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/parent-require": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", - "integrity": "sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/parse-color": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", - "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=", - "dependencies": { - "color-convert": "~0.5.0" - } - }, - "node_modules/parse-color/node_modules/color-convert": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "dependencies": { - "parse5": "^6.0.1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/passport": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", - "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", - "dependencies": { - "passport-strategy": "1.x.x", - "pause": "0.0.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/passport-custom": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/passport-custom/-/passport-custom-1.1.0.tgz", - "integrity": "sha512-wWlewQHKQfiQPY7SwQj1w+/MioiVRc/rBuNEgLaBKinKoFkiTDOFVzJ03wYK5e0i9h9Rk6AOf1k6lIpVNYGQiA==", - "dependencies": { - "passport-strategy": "1.x.x" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/passport-oauth2": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", - "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", - "dependencies": { - "base64url": "3.x.x", - "oauth": "0.9.x", - "passport-strategy": "1.x.x", - "uid2": "0.0.x", - "utils-merge": "1.x.x" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/passport-strategy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", - "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" - }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "dependencies": { - "through": "~2.3" - } - }, - "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-conf": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", - "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0", - "load-json-file": "^5.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/plur": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", - "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", - "dev": true, - "dependencies": { - "irregular-plurals": "^3.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz", - "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==", - "dependencies": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pretty-ms": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz", - "integrity": "sha512-J3aPWiC5e9ZeZFuSeBraGxSkGMOvulSWsxDByOcbD1Pr75YL3LSNIKIb52WXbCLE1sS5s4inBBbryjF4Y05Ceg==", - "dev": true, - "dependencies": { - "parse-ms": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", - "dependencies": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, - "dependencies": { - "event-stream": "=3.3.4" - }, - "bin": { - "ps-tree": "bin/ps-tree.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", - "dev": true, - "dependencies": { - "escape-goat": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "node_modules/regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true - }, - "node_modules/regexp-tree": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.14.tgz", - "integrity": "sha512-59v5A90TAh4cAMyDQEOzcnsu4q7Wb10RsyTjngEnJIZsWYM4siVGu+JmLT1WsxHvOWhiu4YS20XiTuxWMeVoHQ==", - "bin": { - "regexp-tree": "bin/regexp-tree" - } - }, - "node_modules/regexp-worker": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexp-worker/-/regexp-worker-1.1.0.tgz", - "integrity": "sha512-IDDOhDlI972T7bexYwyw+JKdqFsBtJvX8RA+ChVwjhgcK/gv4eG3oZu8Rbidnamh2U2b0ZWdawKksjzY2dmVFw==", - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/registry-auth-token": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", - "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "dependencies": { - "rc": "^1.2.8" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safe-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", - "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", - "dependencies": { - "regexp-tree": "~0.1.1" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/seedrandom": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", - "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" - }, - "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/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "dependencies": { - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/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/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node_modules/serialize-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", - "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sharp": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.4.tgz", - "integrity": "sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q==", - "dependencies": { - "color": "^3.1.2", - "detect-libc": "^1.0.3", - "nan": "^2.14.0", - "npmlog": "^4.1.2", - "prebuild-install": "^5.3.3", - "semver": "^6.3.0", - "simple-get": "^3.1.0", - "tar": "^5.0.5", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=8.5.0" - } - }, - "node_modules/sharp/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/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "node_modules/simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" - }, - "node_modules/simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-get/node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/simple-get/node_modules/mimic-response": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz", - "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "node_modules/split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/sqlstring": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", - "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-argv": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz", - "integrity": "sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-combining-marks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-combining-marks/-/strip-combining-marks-1.0.0.tgz", - "integrity": "sha1-gpXK/RGDN+u+Rt3Fgizb2flb6nE=" - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supertap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supertap/-/supertap-1.0.0.tgz", - "integrity": "sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "indent-string": "^3.2.0", - "js-yaml": "^3.10.0", - "serialize-error": "^2.1.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supertap/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/supertap/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supertap/node_modules/indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/supertap/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tar": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz", - "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==", - "dependencies": { - "chownr": "^1.1.3", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.0", - "mkdirp": "^0.5.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/tar-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", - "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp": "^0.5.1", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, - "node_modules/tar-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", - "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", - "dependencies": { - "bl": "^3.0.0", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tlds": { - "version": "1.203.1", - "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.203.1.tgz", - "integrity": "sha512-7MUlYyGJ6rSitEZ3r1Q1QNV8uSIzapS8SmmhSusBuIc7uIxPPwsKllEP0GRp1NS6Ik6F+fRZvnjDWm3ecv2hDw==", - "bin": { - "tlds": "bin.js" - } - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/trim-off-newlines": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", - "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==" - }, - "node_modules/tsc-watch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-4.0.0.tgz", - "integrity": "sha512-I+1cE7WN9YhDknNRAO5NRI7jzeiIZCxUZ0dFEM/Gf+3KTlHasusDEftwezJ+PSFkECSn3RQmf28RdovjTptkRA==", - "dev": true, - "dependencies": { - "cross-spawn": "^5.1.0", - "node-cleanup": "^2.1.2", - "ps-tree": "^1.2.0", - "string-argv": "^0.1.1", - "strip-ansi": "^4.0.0" - }, - "bin": { - "tsc-watch": "index.js" - }, - "engines": { - "node": ">=6.4.0" - } - }, - "node_modules/tsc-watch/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tsc-watch/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/tsc-watch/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "optional": true - }, - "node_modules/twemoji": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/twemoji/-/twemoji-12.1.4.tgz", - "integrity": "sha512-e37lUlVijmABF7wPCc09s1kKj3hcpzU8KL5zw2bBDIXOtOr4luLF+ODJaEqca8dZPmLR5ezrJYI93nhPovKBiQ==", - "dependencies": { - "fs-extra": "^8.0.1", - "jsonfile": "^5.0.0", - "twemoji-parser": "12.1.1", - "universalify": "^0.1.2" - } - }, - "node_modules/twemoji-parser": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-12.1.1.tgz", - "integrity": "sha512-XFUB4ReEvPbNPtiuyo/+crM4RldYbRRAhyE7Hw6EnfBdXECGydw7a49EGADayRvaeierP/m4DSv/OZQObh0LGA==" - }, - "node_modules/type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typeorm": { - "version": "0.2.31", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.31.tgz", - "integrity": "sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==", - "dependencies": { - "@sqltools/formatter": "1.2.2", - "app-root-path": "^3.0.0", - "buffer": "^5.5.0", - "chalk": "^4.1.0", - "cli-highlight": "^2.1.10", - "debug": "^4.1.1", - "dotenv": "^8.2.0", - "glob": "^7.1.6", - "js-yaml": "^3.14.0", - "mkdirp": "^1.0.4", - "reflect-metadata": "^0.1.13", - "sha.js": "^2.4.11", - "tslib": "^1.13.0", - "xml2js": "^0.4.23", - "yargonaut": "^1.1.2", - "yargs": "^16.0.3" - }, - "bin": { - "typeorm": "cli.js" - } - }, - "node_modules/typeorm/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/typeorm/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typeorm/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/typeorm/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/typeorm/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/typeorm/node_modules/dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/typeorm/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/typeorm/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/typeorm/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/typeorm/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/typeorm/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/typeorm/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", - "dev": true, - "dependencies": { - "boxen": "^4.2.0", - "chalk": "^3.0.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.3.1", - "is-npm": "^4.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.0.0", - "pupa": "^2.0.1", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "dependencies": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/update-notifier/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/update-notifier/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/well-known-symbols": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", - "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/widest-line/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xregexp": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", - "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", - "dev": true, - "dependencies": { - "@babel/runtime-corejs3": "^7.8.3" - } - }, - "node_modules/y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "node_modules/yaml-js": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/yaml-js/-/yaml-js-0.2.3.tgz", - "integrity": "sha512-6xUQtVKl1qcd0EXtTEzUDVJy9Ji1fYa47LtkDtYKlIjhibPE9knNPmoRyf6SGREFHlOAUyDe9OdYqRP4DuSi5Q==" - }, - "node_modules/yargonaut": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", - "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", - "dependencies": { - "chalk": "^1.1.1", - "figlet": "^1.1.1", - "parent-require": "^1.0.0" - } - }, - "node_modules/yargonaut/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/yargonaut/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.5", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", - "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yawn-yaml": { - "resolved": "git+ssh://git@github.com/dragory/yawn-yaml.git#77ab3870ca53c4693002c4a41336e7476e7934ed", - "dependencies": { - "js-yaml": "^3.4.2", - "lodash": "^4.17.11", - "yaml-js": "^0.2.3" - } - }, - "node_modules/zlib-sync": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/zlib-sync/-/zlib-sync-0.1.7.tgz", - "integrity": "sha512-UmciU6ZrIwtwPC8noMzq+kGMdiWwNRZ3wC0SbED4Ew5Ikqx14MqDPRs/Pbk+3rZPh5SzsOgUBs1WRE0iieddpg==", - "dependencies": { - "nan": "^2.14.0" - } - } - }, "dependencies": { "@babel/code-frame": { "version": "7.10.4", @@ -6139,6 +57,21 @@ } } }, + "@discordjs/collection": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", + "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" + }, + "@discordjs/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "@nodelib/fs.scandir": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", @@ -6165,6 +98,11 @@ "fastq": "^1.6.0" } }, + "@sapphire/async-queue": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.2.tgz", + "integrity": "sha512-NkR7AzC9uyb++tMIZgG4X0ci8JM1rnvNmKbLwY42RgotRV8JGUntZ7ZpR7MN7p5zPlVdKo/YmOqcCCsBJ6LNuw==" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -6403,6 +341,14 @@ "resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.0.tgz", "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==" }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -6535,6 +481,11 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, "ava": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/ava/-/ava-3.10.0.tgz", @@ -6787,6 +738,14 @@ "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" + }, + "dependencies": { + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + } } }, "yargs-parser": { @@ -6844,17 +803,24 @@ } }, "bl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", - "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "requires": { - "readable-stream": "^3.0.1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" }, "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "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", @@ -7026,11 +992,11 @@ "dev": true }, "bufferutil": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", - "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", "requires": { - "node-gyp-build": "~3.7.0" + "node-gyp-build": "^4.2.0" } }, "bytes": { @@ -7367,6 +1333,14 @@ "simple-swizzle": "^0.2.2" } }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "common-path-prefix": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", @@ -7617,6 +1591,11 @@ } } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -7646,6 +1625,25 @@ "path-type": "^4.0.0" } }, + "discord-api-types": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.18.1.tgz", + "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" + }, + "discord.js": { + "version": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", + "from": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", + "requires": { + "@discordjs/collection": "^0.1.6", + "@discordjs/form-data": "^3.0.1", + "@sapphire/async-queue": "^1.1.2", + "abort-controller": "^3.0.0", + "node-fetch": "^2.6.1", + "prism-media": "^1.2.9", + "tweetnacl": "^1.0.3", + "ws": "^7.4.5" + } + }, "dot-prop": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", @@ -7715,19 +1713,9 @@ "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", "dev": true }, - "eris": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/eris/-/eris-0.15.1.tgz", - "integrity": "sha512-IQ3BPW6OjgFoqjdh+irPOa1jFlkotk+WNu2GQQ7QAQfbzQEPZgn+F+hpOxfMUXPHOZMX4sPKLkVDkMHAssBYhw==", - "requires": { - "opusscript": "^0.0.8", - "tweetnacl": "^1.0.1", - "ws": "^7.2.1" - } - }, "erlpack": { - "version": "git+ssh://git@github.com/abalabahaha/erlpack.git#5d0064f9e106841e1eead711a6451f99b0d289fd", - "from": "erlpack@github:abalabahaha/erlpack", + "version": "github:discord/erlpack#e27db8f82892bdb9b28a0547cc394d68b5d2242d", + "from": "github:discord/erlpack", "requires": { "bindings": "^1.5.0", "nan": "^2.14.0" @@ -7794,6 +1782,11 @@ "through": "~2.3.1" } }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, "expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -8156,9 +2149,9 @@ "integrity": "sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==" }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "http-cache-semantics": { @@ -8252,9 +2245,9 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "io-ts": { "version": "2.0.1", @@ -8462,10 +2455,12 @@ } }, "knub": { - "version": "30.0.0-beta.37", - "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.37.tgz", - "integrity": "sha512-eXgdhmD1bvGlqLG80mfLGwvkjgGZnTOhUXkO5dAjGujfiE02FbamKnVovw92ruUaB4HS35ydwJPTG3vvUuh/Sg==", + "version": "30.0.0-beta.38", + "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.38.tgz", + "integrity": "sha512-/c1JgFoI/ezzVSC9fXxdeqv3EE5b4w/WC15UcJY2+EjJHlzuFAePK6pZynNRM7y8c/O35/jslkpSwnDrPMrhRg==", "requires": { + "discord-api-types": "^0.18.1", + "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -8546,9 +2541,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.chunk": { "version": "4.2.0", @@ -8751,9 +2746,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { "version": "3.1.1", @@ -8787,20 +2782,18 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } + "minimist": "^1.2.5" } }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "moment": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", @@ -8852,9 +2845,9 @@ "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, "napi-build-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", - "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "negotiator": { "version": "0.6.2", @@ -8867,9 +2860,9 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-abi": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.13.0.tgz", - "integrity": "sha512-9HrZGFVTR5SOu3PZAnAY2hLO36aW1wmA+FDsVkr85BTST32TLCA1H/AEcatVRAsWLyXS3bqUDYCAjq5/QGuSTA==", + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.0.tgz", + "integrity": "sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg==", "requires": { "semver": "^5.4.1" } @@ -8880,10 +2873,15 @@ "integrity": "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=", "dev": true }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, "node-gyp-build": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", - "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==" + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" }, "noop-logger": { "version": "0.1.1", @@ -8965,12 +2963,6 @@ "mimic-fn": "^2.1.0" } }, - "opusscript": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.8.tgz", - "integrity": "sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==", - "optional": true - }, "ora": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz", @@ -9347,15 +3339,15 @@ } }, "prebuild-install": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz", - "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==", + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", + "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", "requires": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", "github-from-package": "0.0.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^2.7.0", "noop-logger": "^0.1.1", @@ -9383,6 +3375,11 @@ "parse-ms": "^2.1.0" } }, + "prism-media": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", + "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -9978,14 +3975,6 @@ "duplexer": "~0.1.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "string-argv": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz", @@ -10011,6 +4000,14 @@ } } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -10107,22 +4104,22 @@ } }, "tar-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", - "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "requires": { "chownr": "^1.1.1", - "mkdirp": "^0.5.1", + "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" + "tar-stream": "^2.1.4" } }, "tar-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", - "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "requires": { - "bl": "^3.0.0", + "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", @@ -10130,9 +4127,9 @@ }, "dependencies": { "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "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", @@ -10293,8 +4290,7 @@ "tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "optional": true + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, "twemoji": { "version": "12.1.4", @@ -10561,6 +4557,14 @@ "prepend-http": "^2.0.0" } }, + "utf-8-validate": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.5.tgz", + "integrity": "sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ==", + "requires": { + "node-gyp-build": "^4.2.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -10779,10 +4783,9 @@ } }, "ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "requires": {} + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" }, "xdg-basedir": { "version": "4.0.0", @@ -10813,12 +4816,6 @@ "@babel/runtime-corejs3": "^7.8.3" } }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/backend/package.json b/backend/package.json index 45332a42..b92b0ff1 100644 --- a/backend/package.json +++ b/backend/package.json @@ -25,21 +25,21 @@ "dependencies": { "@types/sharp": "^0.23.1", "@types/twemoji": "^12.1.0", - "bufferutil": "^4.0.1", + "bufferutil": "^4.0.3", "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", + "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", - "eris": "^0.15.1", - "erlpack": "github:abalabahaha/erlpack", + "erlpack": "github:discord/erlpack", "escape-string-regexp": "^1.0.5", "express": "^4.17.0", "fp-ts": "^2.0.1", "humanize-duration": "^3.15.0", "io-ts": "^2.0.0", "js-yaml": "^3.13.1", - "knub": "^30.0.0-beta.37", + "knub": "^30.0.0-beta.38", "knub-command-manager": "^8.1.2", "last-commit-log": "^2.1.0", "lodash.chunk": "^4.2.0", @@ -66,6 +66,7 @@ "tsconfig-paths": "^3.9.0", "twemoji": "^12.1.4", "typeorm": "^0.2.31", + "utf-8-validate": "^5.0.5", "uuid": "^3.3.2", "yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build", "zlib-sync": "^0.1.7" diff --git a/backend/src/index.ts b/backend/src/index.ts index 00312b43..ad40ab22 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -11,7 +11,6 @@ import { Configs } from "./data/Configs"; // Always use UTC internally // This is also enforced for the database in data/db.ts import moment from "moment-timezone"; -import { Client, DiscordHTTPError, TextChannel } from "eris"; import { connect } from "./data/db"; import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availablePlugins"; import { errorMessage, isDiscordHTTPError, isDiscordRESTError, MINUTES, successMessage } from "./utils"; @@ -21,10 +20,10 @@ import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; import { RecoverablePluginError } from "./RecoverablePluginError"; import { GuildLogs } from "./data/GuildLogs"; import { LogType } from "./data/LogType"; -import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; import { logger } from "./logger"; import { PluginLoadError } from "knub/dist/plugins/PluginLoadError"; import { ErisError } from "./ErisError"; +import { Client, Intents, TextChannel } from "discord.js"; const fsp = fs.promises; @@ -96,7 +95,7 @@ function errorHandler(err) { } } - if (err instanceof DiscordHTTPError && err.code >= 500) { + if (isDiscordHTTPError(err) && err.code >= 500) { // Don't need stack traces on HTTP 500 errors // These also shouldn't count towards RECENT_DISCORD_ERROR_EXIT_THRESHOLD because they don't indicate an error in our code console.error(err.message); @@ -151,36 +150,32 @@ moment.tz.setDefault("UTC"); logger.info("Connecting to database"); connect().then(async () => { - const client = new Client(`Bot ${process.env.TOKEN}`, { - getAllUsers: false, - restMode: true, - compress: false, - guildCreateTimeout: 0, - rest: { - ratelimiterOffset: 150, - }, + const client = new Client({ + partials: ["USER", "CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION"], + restTimeOffset: 150, + restGlobalRateLimit: 50, // Disable mentions by default allowedMentions: { - everyone: false, - users: false, - roles: false, + parse: [], + users: [], + roles: [], repliedUser: false, }, intents: [ // Privileged - "guildMembers", + Intents.FLAGS.GUILD_MEMBERS, // "guildPresences", - "guildMessageTyping", + Intents.FLAGS.GUILD_MESSAGE_TYPING, // Regular - "directMessages", - "guildBans", - "guildEmojis", - "guildInvites", - "guildMessageReactions", - "guildMessages", - "guilds", - "guildVoiceStates", + Intents.FLAGS.DIRECT_MESSAGES, + Intents.FLAGS.GUILD_BANS, + Intents.FLAGS.GUILD_EMOJIS, + Intents.FLAGS.GUILD_INVITES, + Intents.FLAGS.GUILD_MESSAGE_REACTIONS, + Intents.FLAGS.GUILD_MESSAGES, + Intents.FLAGS.GUILDS, + Intents.FLAGS.GUILD_VOICE_STATES, ], }); client.setMaxListeners(200); @@ -191,8 +186,8 @@ connect().then(async () => { } }); - client.on("error", (err, shardId) => { - errorHandler(new ErisError(err.message, (err as any).code, shardId)); + client.on("error", err => { + errorHandler(new ErisError(err.message, (err as any).code, 0)); }); const allowedGuilds = new AllowedGuilds(); @@ -257,13 +252,13 @@ connect().then(async () => { sendSuccessMessageFn(channel, body) { const guildId = channel instanceof TextChannel ? channel.guild.id : undefined; const emoji = guildId ? bot.getLoadedGuild(guildId)!.config.success_emoji : undefined; - channel.createMessage(successMessage(body, emoji)); + channel.send(successMessage(body, emoji)); }, sendErrorMessageFn(channel, body) { const guildId = channel instanceof TextChannel ? channel.guild.id : undefined; const emoji = guildId ? bot.getLoadedGuild(guildId)!.config.error_emoji : undefined; - channel.createMessage(errorMessage(body, emoji)); + channel.send(errorMessage(body, emoji)); }, }, }); @@ -273,5 +268,5 @@ connect().then(async () => { }); logger.info("Starting the bot"); - bot.run(); + bot.initialize(); }); diff --git a/backend/src/types.ts b/backend/src/types.ts index d9fc3803..324817bb 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -64,3 +64,15 @@ export interface CommandInfo { [key: string]: TMarkdown; }; } + +export enum ChannelTypeStrings { + TEXT = "text", + DM = "dm", + VOICE = "voice", + GROUP = "group", + CATEGORY = "category", + NEWS = "news", + STORE = "store", + STAGE = "stage", + UNKNOWN = "unknown", +} diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 74e5c4a2..549ebdd1 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1,25 +1,3 @@ -import { - AllowedMentions, - Attachment, - Client, - Constants, - Embed, - EmbedOptions, - Emoji, - Guild, - GuildAuditLog, - GuildAuditLogEntry, - GuildChannel, - Invite, - InvitePartialChannel, - Member, - Message, - MessageContent, - PossiblyUncachedMessage, - TextableChannel, - TextChannel, - User, -} from "eris"; import { URL } from "url"; import tlds from "tlds"; import emojiRegex from "emoji-regex"; @@ -38,6 +16,29 @@ import { logger } from "./logger"; import { unsafeCoerce } from "fp-ts/lib/function"; import { sendDM } from "./utils/sendDM"; import { LogType } from "./data/LogType"; +import { + APIMessage, + Channel, + Client, + Constants, + Emoji, + Guild, + GuildAuditLogs, + GuildAuditLogsEntry, + GuildChannel, + GuildMember, + Invite, + Message, + MessageAttachment, + MessageEmbed, + MessageEmbedOptions, + MessageMentionOptions, + MessageOptions, + StringResolvable, + TextChannel, + User, +} from "discord.js"; +import { ChannelTypeStrings } from "./types"; const fsp = fs.promises; @@ -202,7 +203,7 @@ export type InviteOpts = "withMetadata" | "withCount" | "withoutCount"; export type GuildInvite = Invite & { guild: Guild }; export type GroupDMInvite = Invite & { channel: InvitePartialChannel; - type: typeof Constants.ChannelTypes.GROUP_DM; + type: typeof Constants.ChannelTypes.GROUP; }; /** @@ -269,9 +270,15 @@ export const tEmbed = t.type({ ), }); -export type EmbedWith = EmbedOptions & Pick, T>; +export type EmbedWith = MessageEmbedOptions & + Pick, T>; -export type StrictMessageContent = { content?: string; tts?: boolean; disableEveryone?: boolean; embed?: EmbedOptions }; +export type StrictMessageContent = { + content?: string; + tts?: boolean; + disableEveryone?: boolean; + embed?: MessageEmbedOptions; +}; export const tStrictMessageContent = t.type({ content: tNullable(t.string), @@ -458,14 +465,14 @@ export async function findRelevantAuditLogEntry( userId: string, attempts: number = 3, attemptDelay: number = 3000, -): Promise { +): Promise { if (auditLogNextAttemptAfterFail.has(guild.id) && auditLogNextAttemptAfterFail.get(guild.id)! > Date.now()) { return null; } - let auditLogs: GuildAuditLog | null = null; + let auditLogs: GuildAuditLogs | null = null; try { - auditLogs = await guild.getAuditLogs(5, undefined, actionType); + auditLogs = await guild.fetchAuditLogs({ limit: 5, type: actionType }); } catch (e) { if (isDiscordRESTError(e) && e.code === 50013) { // If we don't have permission to read audit log, set audit log requests on cooldown @@ -830,13 +837,13 @@ export function chunkMessageLines(str: string, maxChunkLength = 1990): string[] } export async function createChunkedMessage( - channel: TextableChannel, + channel: TextChannel | User, messageText: string, - allowedMentions?: AllowedMentions, + allowedMentions?: MessageMentionOptions, ) { const chunks = chunkMessageLines(messageText); for (const chunk of chunks) { - await channel.createMessage({ content: chunk, allowedMentions }); + await channel.send({ content: chunk, allowedMentions }); } } @@ -1011,7 +1018,7 @@ export async function notifyUser( } } else if (method.type === "channel") { try { - await method.channel.createMessage({ + await method.channel.send({ content: `<@!${user.id}> ${body}`, allowedMentions: { users: [user.id] }, }); @@ -1130,7 +1137,7 @@ export function resolveUserId(bot: Client, value: string) { */ export function getUser(client: Client, userResolvable: string): User | UnknownUser { const id = resolveUserId(client, userResolvable); - return id ? client.users.get(id) || new UnknownUser({ id }) : new UnknownUser(); + return id ? client.users.resolve(id) || new UnknownUser({ id }) : new UnknownUser(); } /** @@ -1176,13 +1183,18 @@ export async function resolveUser(bot, value) { * Resolves a guild Member from the passed user id, user mention, or full username (with discriminator). * If the member is not found in the cache, it's fetched from the API. */ -export async function resolveMember(bot: Client, guild: Guild, value: string, fresh = false): Promise { +export async function resolveMember( + bot: Client, + guild: Guild, + value: string, + fresh = false, +): Promise { const userId = resolveUserId(bot, value); if (!userId) return null; // If we have the member cached, return that directly - if (guild.members.has(userId) && !fresh) { - return guild.members.get(userId) || null; + if (guild.members.cache.has(userId) && !fresh) { + return guild.members.cache.get(userId) || null; } // We don't want to spam the API by trying to fetch unknown members again and again, @@ -1192,9 +1204,9 @@ export async function resolveMember(bot: Client, guild: Guild, value: string, fr return null; } - const freshMember = await bot.getRESTGuildMember(guild.id, userId).catch(noop); + const freshMember = await guild.members.fetch({ user: userId, force: true }).catch(noop); if (freshMember) { - freshMember.id = userId; + // freshMember.id = userId; // I dont even know why this is here -Dark return freshMember; } @@ -1222,7 +1234,7 @@ export async function resolveRoleId(bot: Client, guildId: string, value: string) } // Role name - const roleList = await bot.getRESTGuildRoles(guildId); + const roleList = await (await bot.guilds.fetch(guildId)).roles.cache; const role = roleList.filter(x => x.name.toLocaleLowerCase() === value.toLocaleLowerCase()); if (role[0]) { return role[0].id; @@ -1236,7 +1248,7 @@ export async function resolveRoleId(bot: Client, guildId: string, value: string) return null; } -const inviteCache = new SimpleCache | null>>(10 * MINUTES, 200); +const inviteCache = new SimpleCache>(10 * MINUTES, 200); type ResolveInviteReturnType = Promise< (T extends true ? Invite<"withCount" | "withMetadata"> : Invite<"withMetadata">) | null @@ -1259,8 +1271,13 @@ export async function resolveInvite( return promise as ResolveInviteReturnType; } -export async function confirm(bot: Client, channel: TextableChannel, userId: string, content: MessageContent) { - const msg = await channel.createMessage(content); +export async function confirm( + bot: Client, + channel: TextChannel, + userId: string, + content: StringResolvable | MessageOptions, +) { + const msg = await channel.send(content); const reply = await helpers.waitForReaction(bot, msg, ["✅", "❌"], userId); msg.delete().catch(noop); return reply && reply.name === "✅"; @@ -1271,13 +1288,15 @@ export function messageSummary(msg: SavedMessage) { let result = "```\n" + (msg.data.content ? disableCodeBlocks(msg.data.content) : "") + "```"; // Rich embed - const richEmbed = (msg.data.embeds || []).find(e => (e as Embed).type === "rich"); + const richEmbed = (msg.data.embeds || []).find(e => (e as MessageEmbed).type === "rich"); if (richEmbed) result += "Embed:```" + disableCodeBlocks(JSON.stringify(richEmbed)) + "```"; // Attachments if (msg.data.attachments) { result += - "Attachments:\n" + msg.data.attachments.map((a: Attachment) => disableLinkPreviews(a.url)).join("\n") + "\n"; + "Attachments:\n" + + msg.data.attachments.map((a: MessageAttachment) => disableLinkPreviews(a.url)).join("\n") + + "\n"; } return result; @@ -1300,10 +1319,7 @@ export function verboseUserName(user: User | UnknownUser): string { } export function verboseChannelMention(channel: GuildChannel): string { - const plainTextName = - channel.type === Constants.ChannelTypes.GUILD_VOICE || channel.type === Constants.ChannelTypes.GUILD_STAGE - ? channel.name - : `#${channel.name}`; + const plainTextName = channel.type === "voice" || channel.type === "stage" ? channel.name : `#${channel.name}`; return `<#${channel.id}> (**${plainTextName}**, \`${channel.id}\`)`; } @@ -1396,8 +1412,8 @@ export function canUseEmoji(client: Client, emoji: string): boolean { if (isUnicodeEmoji(emoji)) { return true; } else if (isSnowflake(emoji)) { - for (const guild of client.guilds.values()) { - if (guild.emojis.some(e => (e as any).id === emoji)) { + for (const guild of client.guilds.cache) { + if (guild[1].emojis.cache.some(e => (e as any).id === emoji)) { return true; } } @@ -1429,10 +1445,10 @@ export function isGuildInvite(invite: Invite): invite } export function isGroupDMInvite(invite: Invite): invite is GroupDMInvite { - return invite.guild == null && invite.channel?.type === Constants.ChannelTypes.GROUP_DM; + return invite.guild == null && invite.channel?.type === "group"; } -export function inviteHasCounts(invite: Invite): invite is Invite<"withCount"> { +export function inviteHasCounts(invite: Invite): invite is Invite<"withCount"> { return invite.memberCount != null; } diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index 76e55225..e3289881 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,4 +1,4 @@ -import { Client, Emoji, MemberPartial, Message, MessageContent, TextableChannel } from "eris"; +import { APIMessage, Client, Message, MessageReaction, PartialUser, TextChannel, User } from "discord.js"; import { Awaitable } from "knub/dist/utils"; import { MINUTES, noop } from "../utils"; import Timeout = NodeJS.Timeout; @@ -17,19 +17,19 @@ const defaultOpts: PaginateMessageOpts = { export async function createPaginatedMessage( client: Client, - channel: TextableChannel, + channel: TextChannel | User, totalPages: number, loadPageFn: LoadPageFn, opts: Partial = {}, ): Promise { const fullOpts = { ...defaultOpts, ...opts } as PaginateMessageOpts; const firstPageContent = await loadPageFn(1); - const message = await channel.createMessage(firstPageContent); + const message = await channel.send(firstPageContent); let page = 1; let pageLoadId = 0; // Used to avoid race conditions when rapidly switching pages - const reactionListener = async (reactionMessage: Message, emoji: Emoji, reactor: MemberPartial) => { - if (reactionMessage.id !== message.id) { + const reactionListener = async (reactionMessage: MessageReaction, reactor: User | PartialUser) => { + if (reactionMessage.message.id !== message.id) { return; } @@ -37,14 +37,14 @@ export async function createPaginatedMessage( return; } - if (reactor.id === client.user.id) { + if (reactor.id === client.user!.id) { return; } let pageDelta = 0; - if (emoji.name === "⬅️") { + if (reactionMessage.emoji.name === "⬅️") { pageDelta = -1; - } else if (emoji.name === "➡️") { + } else if (reactionMessage.emoji.name === "➡️") { pageDelta = 1; } @@ -65,7 +65,7 @@ export async function createPaginatedMessage( } message.edit(newPageContent).catch(noop); - message.removeReaction(emoji.name, reactor.id); + reactionMessage.users.remove(reactor.id).catch(noop); refreshTimeout(); }; client.on("messageReactionAdd", reactionListener); @@ -76,7 +76,7 @@ export async function createPaginatedMessage( const refreshTimeout = () => { clearTimeout(timeout); timeout = setTimeout(() => { - message.removeReactions().catch(noop); + message.reactions.removeAll().catch(noop); client.off("messageReactionAdd", reactionListener); }, fullOpts.timeout); }; @@ -84,8 +84,8 @@ export async function createPaginatedMessage( refreshTimeout(); // Add reactions - message.addReaction("⬅️").catch(noop); - message.addReaction("➡️").catch(noop); + message.react("⬅️").catch(noop); + message.react("➡️").catch(noop); return message; } diff --git a/backend/src/utils/getChunkedEmbedFields.ts b/backend/src/utils/getChunkedEmbedFields.ts index 7b692164..0568e840 100644 --- a/backend/src/utils/getChunkedEmbedFields.ts +++ b/backend/src/utils/getChunkedEmbedFields.ts @@ -1,4 +1,4 @@ -import { EmbedField } from "eris"; +import { EmbedField } from "discord.js"; import { chunkMessageLines, emptyEmbedValue } from "../utils"; export function getChunkedEmbedFields(name: string, value: string, inline?: boolean): EmbedField[] { @@ -10,11 +10,13 @@ export function getChunkedEmbedFields(name: string, value: string, inline?: bool fields.push({ name, value: chunks[i], + inline: false, }); } else { fields.push({ name: emptyEmbedValue, value: chunks[i], + inline: false, }); } } diff --git a/backend/src/utils/getMissingChannelPermissions.ts b/backend/src/utils/getMissingChannelPermissions.ts index 4701ddb4..f7e99cb6 100644 --- a/backend/src/utils/getMissingChannelPermissions.ts +++ b/backend/src/utils/getMissingChannelPermissions.ts @@ -1,4 +1,4 @@ -import { Constants, GuildChannel, Member, Permission } from "eris"; +import { GuildMember, GuildChannel } from "discord.js"; import { getMissingPermissions } from "./getMissingPermissions"; /** @@ -6,10 +6,11 @@ import { getMissingPermissions } from "./getMissingPermissions"; * @return Bitmask of missing permissions */ export function getMissingChannelPermissions( - member: Member, + member: GuildMember, channel: GuildChannel, requiredPermissions: number | bigint, ): bigint { - const memberChannelPermissions = channel.permissionsOf(member.id); + const memberChannelPermissions = channel.permissionsFor(member.id); + if (!memberChannelPermissions) return BigInt(requiredPermissions); return getMissingPermissions(memberChannelPermissions, requiredPermissions); } diff --git a/backend/src/utils/getMissingPermissions.ts b/backend/src/utils/getMissingPermissions.ts index 9dd6881a..d9863c24 100644 --- a/backend/src/utils/getMissingPermissions.ts +++ b/backend/src/utils/getMissingPermissions.ts @@ -1,15 +1,18 @@ -import { Constants, Permission } from "eris"; +import { PermissionOverwrites, Permissions } from "discord.js"; /** - * @param resolvedPermissions A Permission object from e.g. GuildChannel#permissionsOf() or Member#permission + * @param resolvedPermissions A Permission object from e.g. GuildChannel#permissionsFor() or Member#permission * @param requiredPermissions Bitmask of required permissions * @return Bitmask of missing permissions */ -export function getMissingPermissions(resolvedPermissions: Permission, requiredPermissions: number | bigint): bigint { - const allowedPermissions = BigInt(resolvedPermissions.allow); +export function getMissingPermissions( + resolvedPermissions: Permissions | Readonly, + requiredPermissions: number | bigint, +): bigint { + const allowedPermissions = BigInt(resolvedPermissions); const nRequiredPermissions = BigInt(requiredPermissions); - if (Boolean(allowedPermissions & BigInt(Constants.Permissions.administrator))) { + if (Boolean(allowedPermissions & BigInt(Permissions.FLAGS.ADMINISTRATOR))) { return BigInt(0); } diff --git a/backend/src/utils/getPermissionNames.ts b/backend/src/utils/getPermissionNames.ts index 48e057bc..47202c96 100644 --- a/backend/src/utils/getPermissionNames.ts +++ b/backend/src/utils/getPermissionNames.ts @@ -1,4 +1,4 @@ -import { Constants } from "eris"; +import { Permissions } from "discord.js"; const camelCaseToTitleCase = str => str @@ -10,9 +10,9 @@ const camelCaseToTitleCase = str => const permissionNumberToName: Map = new Map(); const ignoredPermissionConstants = ["all", "allGuild", "allText", "allVoice"]; -for (const key in Constants.Permissions) { +for (const key in Permissions.FLAGS) { if (ignoredPermissionConstants.includes(key)) continue; - permissionNumberToName.set(BigInt(Constants.Permissions[key]), camelCaseToTitleCase(key)); + permissionNumberToName.set(BigInt(Permissions.FLAGS[key]), camelCaseToTitleCase(key)); } /** diff --git a/backend/src/utils/hasDiscordPermissions.ts b/backend/src/utils/hasDiscordPermissions.ts index f4aefcab..28391195 100644 --- a/backend/src/utils/hasDiscordPermissions.ts +++ b/backend/src/utils/hasDiscordPermissions.ts @@ -1,14 +1,14 @@ -import { Constants, Permission } from "eris"; +import { PermissionOverwrites, Permissions } from "discord.js"; /** * @param resolvedPermissions A Permission object from e.g. GuildChannel#permissionsOf() or Member#permission * @param requiredPermissions Bitmask of required permissions */ -export function hasDiscordPermissions(resolvedPermissions: Permission, requiredPermissions: number | bigint) { +export function hasDiscordPermissions(resolvedPermissions: PermissionOverwrites, requiredPermissions: number | bigint) { const allowedPermissions = BigInt(resolvedPermissions.allow); const nRequiredPermissions = BigInt(requiredPermissions); - if (Boolean(allowedPermissions & BigInt(Constants.Permissions.administrator))) { + if (Boolean(allowedPermissions & BigInt(Permissions.FLAGS.ADMINISTRATOR))) { return true; } diff --git a/backend/src/utils/lockNameHelpers.ts b/backend/src/utils/lockNameHelpers.ts index 4a16bd33..81f3bc04 100644 --- a/backend/src/utils/lockNameHelpers.ts +++ b/backend/src/utils/lockNameHelpers.ts @@ -1,11 +1,11 @@ -import { Member, Message, User } from "eris"; +import { GuildMember, Message, User } from "discord.js"; import { SavedMessage } from "../data/entities/SavedMessage"; export function allStarboardsLock() { return `starboards`; } -export function banLock(user: Member | User | { id: string }) { +export function banLock(user: GuildMember | User | { id: string }) { return `ban-${user.id}`; } @@ -13,7 +13,7 @@ export function counterIdLock(counterId: number | string) { return `counter-${counterId}`; } -export function memberRolesLock(member: Member | User | { id: string }) { +export function memberRolesLock(member: GuildMember | User | { id: string }) { return `member-roles-${member.id}`; } @@ -21,6 +21,6 @@ export function messageLock(message: Message | SavedMessage | { id: string }) { return `message-${message.id}`; } -export function muteLock(user: Member | User | { id: string }) { +export function muteLock(user: GuildMember | User | { id: string }) { return `mute-${user.id}`; } diff --git a/backend/src/utils/messageHasContent.ts b/backend/src/utils/messageHasContent.ts index ca3dd8bf..40aaca8e 100644 --- a/backend/src/utils/messageHasContent.ts +++ b/backend/src/utils/messageHasContent.ts @@ -1,4 +1,4 @@ -import { MessageContent } from "eris"; +import { APIMessage, MessageOptions } from "discord.js"; function embedHasContent(embed: any) { for (const [key, value] of Object.entries(embed)) { @@ -18,7 +18,7 @@ function embedHasContent(embed: any) { return false; } -export function messageHasContent(content: MessageContent): boolean { +export function messageHasContent(content: string | MessageOptions): boolean { if (typeof content === "string") { return content.trim() !== ""; } diff --git a/backend/src/utils/messageIsEmpty.ts b/backend/src/utils/messageIsEmpty.ts index 2cd3f255..d1b1f117 100644 --- a/backend/src/utils/messageIsEmpty.ts +++ b/backend/src/utils/messageIsEmpty.ts @@ -1,6 +1,6 @@ -import { MessageContent } from "eris"; +import { MessageOptions } from "discord.js"; import { messageHasContent } from "./messageHasContent"; -export function messageIsEmpty(content: MessageContent): boolean { +export function messageIsEmpty(content: string | MessageOptions): boolean { return !messageHasContent(content); } diff --git a/backend/src/utils/readChannelPermissions.ts b/backend/src/utils/readChannelPermissions.ts index fdfb4aac..16dae413 100644 --- a/backend/src/utils/readChannelPermissions.ts +++ b/backend/src/utils/readChannelPermissions.ts @@ -1,9 +1,9 @@ -import { Constants } from "eris"; +import { Permissions } from "discord.js"; /** * Bitmask of permissions required to read messages in a channel */ -export const readChannelPermissions = Constants.Permissions.readMessages | Constants.Permissions.readMessageHistory; +export const readChannelPermissions = Permissions.FLAGS.VIEW_CHANNEL | Permissions.FLAGS.READ_MESSAGE_HISTORY; /** * Bitmask of permissions required to read messages in a channel (bigint) diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts index 4e06c52a..4d2a6a62 100644 --- a/backend/src/utils/resolveMessageTarget.ts +++ b/backend/src/utils/resolveMessageTarget.ts @@ -1,7 +1,7 @@ import { disableInlineCode, isSnowflake } from "../utils"; import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; import { GuildPluginData, TypeConversionError } from "knub"; -import { TextChannel } from "eris"; +import { TextChannel } from "discord.js"; const channelAndMessageIdRegex = /^(\d+)[\-\/](\d+)$/; const messageLinkRegex = /^https:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/\d+\/(\d+)\/(\d+)$/i; @@ -46,7 +46,7 @@ export async function resolveMessageTarget(pluginData: GuildPluginData, val return null; } - const channel = pluginData.guild.channels.get(result.channelId); + const channel = pluginData.guild.channels.resolve(result.channelId); if (!channel || !(channel instanceof TextChannel)) { return null; } diff --git a/backend/src/utils/sendDM.ts b/backend/src/utils/sendDM.ts index 8e8261bf..3679dbc5 100644 --- a/backend/src/utils/sendDM.ts +++ b/backend/src/utils/sendDM.ts @@ -1,7 +1,7 @@ -import { MessageContent, MessageFile, User } from "eris"; import { createChunkedMessage, HOURS, isDiscordRESTError } from "../utils"; import { logger } from "../logger"; import Timeout = NodeJS.Timeout; +import { APIMessage, User } from "discord.js"; let dmsDisabled = false; let dmsDisabledTimeout: Timeout; @@ -16,7 +16,7 @@ export class DMError extends Error {} const error20026 = "The bot cannot currently send DMs"; -export async function sendDM(user: User, content: MessageContent, source: string) { +export async function sendDM(user: User, content: string | APIMessage, source: string) { if (dmsDisabled) { throw new DMError(error20026); } @@ -24,15 +24,10 @@ export async function sendDM(user: User, content: MessageContent, source: string logger.debug(`Sending ${source} DM to ${user.id}`); try { - const dmChannel = await user.getDMChannel(); - if (!dmChannel) { - throw new DMError("Unable to open DM channel"); - } - if (typeof content === "string") { - await createChunkedMessage(dmChannel, content); + await createChunkedMessage(user, content); } else { - await dmChannel.createMessage(content); + await user.send(content); } } catch (e) { if (isDiscordRESTError(e) && e.code === 20026) { From 8f7a6510eb6e6525a40b7eff540bfd8a4d86afa5 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Mon, 31 May 2021 21:12:24 +0200 Subject: [PATCH 02/79] Pre-plugin moves --- backend/src/RecoverablePluginError.ts | 2 +- backend/src/commandTypes.ts | 6 ++-- backend/src/data/GuildArchives.ts | 4 +-- backend/src/data/GuildSavedMessages.ts | 16 +++++----- backend/src/data/entities/SavedMessage.ts | 4 +-- backend/src/data/entities/ScheduledPost.ts | 4 +-- backend/src/pluginUtils.ts | 35 +++++++++++---------- backend/src/types.ts | 1 - backend/src/utils/canAssignRole.ts | 12 +++---- backend/src/utils/canReadChannel.ts | 4 +-- backend/src/utils/createPaginatedMessage.ts | 15 +++++++-- backend/src/utils/hasDiscordPermissions.ts | 9 ++++-- backend/src/utils/messageHasContent.ts | 2 +- 13 files changed, 62 insertions(+), 52 deletions(-) diff --git a/backend/src/RecoverablePluginError.ts b/backend/src/RecoverablePluginError.ts index 3cb1c7ac..e34a2ab2 100644 --- a/backend/src/RecoverablePluginError.ts +++ b/backend/src/RecoverablePluginError.ts @@ -1,4 +1,4 @@ -import { Guild } from "eris"; +import { Guild } from "discord.js"; export enum ERRORS { NO_MUTE_ROLE_IN_CONFIG = 1, diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index cfebf1ac..647dde5c 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -3,7 +3,6 @@ import { convertDelayStringToMS, disableCodeBlocks, disableInlineCode, - isSnowflake, isValidSnowflake, resolveMember, resolveUser, @@ -11,13 +10,12 @@ import { roleMentionRegex, UnknownUser, } from "./utils"; -import { GuildChannel, Member, TextChannel, User } from "eris"; import { baseTypeConverters, baseCommandParameterTypeHelpers, CommandContext, TypeConversionError } from "knub"; import { createTypeHelper } from "knub-command-manager"; -import { getChannelIdFromMessageId } from "./data/getChannelIdFromMessageId"; import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget"; import { inputPatternToRegExp } from "./validatorUtils"; import { isValidTimezone } from "./utils/isValidTimezone"; +import { GuildChannel, GuildMember, User } from "discord.js"; export const commandTypes = { ...baseTypeConverters, @@ -112,7 +110,7 @@ export const commandTypeHelpers = { delay: createTypeHelper(commandTypes.delay), resolvedUser: createTypeHelper>(commandTypes.resolvedUser), resolvedUserLoose: createTypeHelper>(commandTypes.resolvedUserLoose), - resolvedMember: createTypeHelper>(commandTypes.resolvedMember), + resolvedMember: createTypeHelper>(commandTypes.resolvedMember), messageTarget: createTypeHelper>(commandTypes.messageTarget), anyId: createTypeHelper>(commandTypes.anyId), regex: createTypeHelper(commandTypes.regex), diff --git a/backend/src/data/GuildArchives.ts b/backend/src/data/GuildArchives.ts index a67048d5..9c1ea69c 100644 --- a/backend/src/data/GuildArchives.ts +++ b/backend/src/data/GuildArchives.ts @@ -4,8 +4,8 @@ import { getRepository, Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { trimLines } from "../utils"; import { SavedMessage } from "./entities/SavedMessage"; -import { Guild } from "eris"; import { renderTemplate } from "../templateFormatter"; +import { Guild } from "discord.js"; const DEFAULT_EXPIRY_DAYS = 30; @@ -73,7 +73,7 @@ export class GuildArchives extends BaseGuildRepository { protected async renderLinesFromSavedMessages(savedMessages: SavedMessage[], guild: Guild) { const msgLines: string[] = []; for (const msg of savedMessages) { - const channel = guild.channels.get(msg.channel_id); + const channel = guild.channels.cache.get(msg.channel_id); const user = { ...msg.data.author, id: msg.user_id }; const line = await renderTemplate(MESSAGE_ARCHIVE_MESSAGE_FORMAT, { diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index 5653fb84..7bc4134d 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -2,11 +2,11 @@ import { getRepository, Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage"; import { QueuedEventEmitter } from "../QueuedEventEmitter"; -import { GuildChannel, Message, PossiblyUncachedTextableChannel } from "eris"; import moment from "moment-timezone"; import { MINUTES, SECONDS } from "../utils"; import { isAPI } from "../globals"; import { cleanupMessages } from "./cleanup/messages"; +import { GuildChannel, Message } from "discord.js"; if (!isAPI()) { const CLEANUP_INTERVAL = 5 * MINUTES; @@ -34,19 +34,19 @@ export class GuildSavedMessages extends BaseGuildRepository { this.toBePermanent = new Set(); } - public msgToSavedMessageData(msg: Message): ISavedMessageData { + public msgToSavedMessageData(msg: Message): ISavedMessageData { const data: ISavedMessageData = { author: { username: msg.author.username, discriminator: msg.author.discriminator, }, content: msg.content, - timestamp: msg.timestamp, + timestamp: msg.createdTimestamp, }; - if (msg.attachments.length) data.attachments = msg.attachments; + if (msg.attachments.size) data.attachments = msg.attachments.array(); if (msg.embeds.length) data.embeds = msg.embeds; - if (msg.stickers?.length) data.stickers = msg.stickers; + if (msg.stickers?.size) data.stickers = msg.stickers.array(); return data; } @@ -139,12 +139,12 @@ export class GuildSavedMessages extends BaseGuildRepository { this.events.emit(`create:${data.id}`, [inserted]); } - async createFromMsg(msg: Message, overrides = {}) { + async createFromMsg(msg: Message, overrides = {}) { const existingSavedMsg = await this.find(msg.id); if (existingSavedMsg) return; const savedMessageData = this.msgToSavedMessageData(msg); - const postedAt = moment.utc(msg.timestamp, "x").format("YYYY-MM-DD HH:mm:ss"); + const postedAt = moment.utc(msg.createdTimestamp, "x").format("YYYY-MM-DD HH:mm:ss"); const data = { id: msg.id, @@ -222,7 +222,7 @@ export class GuildSavedMessages extends BaseGuildRepository { this.events.emit(`update:${id}`, [newMessage, oldMessage]); } - async saveEditFromMsg(msg: Message) { + async saveEditFromMsg(msg: Message) { const newData = this.msgToSavedMessageData(msg); return this.saveEdit(msg.id, newData); } diff --git a/backend/src/data/entities/SavedMessage.ts b/backend/src/data/entities/SavedMessage.ts index ccccf7a2..77294366 100644 --- a/backend/src/data/entities/SavedMessage.ts +++ b/backend/src/data/entities/SavedMessage.ts @@ -1,9 +1,9 @@ +import { MessageAttachment, Sticker } from "discord.js"; import { Column, Entity, PrimaryColumn } from "typeorm"; import { createEncryptedJsonTransformer } from "../encryptedJsonTransformer"; -import { Attachment, Sticker } from "eris"; export interface ISavedMessageData { - attachments?: Attachment[]; + attachments?: MessageAttachment[]; author: { username: string; discriminator: string; diff --git a/backend/src/data/entities/ScheduledPost.ts b/backend/src/data/entities/ScheduledPost.ts index 0d136045..8b7d4088 100644 --- a/backend/src/data/entities/ScheduledPost.ts +++ b/backend/src/data/entities/ScheduledPost.ts @@ -1,5 +1,5 @@ +import { MessageAttachment } from "discord.js"; import { Column, Entity, PrimaryColumn } from "typeorm"; -import { Attachment } from "eris"; import { StrictMessageContent } from "../../utils"; @Entity("scheduled_posts") @@ -18,7 +18,7 @@ export class ScheduledPost { @Column("simple-json") content: StrictMessageContent; - @Column("simple-json") attachments: Attachment[]; + @Column("simple-json") attachments: MessageAttachment[]; @Column({ type: String, nullable: true }) post_at: string | null; diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index f1ea4616..23b21d0f 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -2,7 +2,6 @@ * @file Utility functions that are plugin-instance-specific (i.e. use PluginData) */ -import { AdvancedMessageContent, AllowedMentions, GuildTextableChannel, Member, Message, TextableChannel } from "eris"; import { CommandContext, configUtils, ConfigValidationError, GuildPluginData, helpers, PluginOptions } from "knub"; import { decodeAndValidateStrict, StrictValidationError, validate } from "./validatorUtils"; import { deepKeyIntersect, errorMessage, successMessage, tDeepPartial, tNullable } from "./utils"; @@ -14,11 +13,17 @@ import { Tail } from "./utils/typeUtils"; import { AnyPluginData } from "knub/dist/plugins/PluginData"; import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; import { logger } from "./logger"; +import { APIMessage, GuildMember, Message, MessageMentionOptions, MessageOptions, TextChannel, User } from "discord.js"; const { getMemberLevel } = helpers; -export function canActOn(pluginData: GuildPluginData, member1: Member, member2: Member, allowSameLevel = false) { - if (member2.id === pluginData.client.user.id) { +export function canActOn( + pluginData: GuildPluginData, + member1: GuildMember, + member2: GuildMember, + allowSameLevel = false, +) { + if (member2.id === pluginData.client.user!.id) { return false; } @@ -180,21 +185,19 @@ export function getPluginConfigPreprocessor( export function sendSuccessMessage( pluginData: AnyPluginData, - channel: TextableChannel, + channel: TextChannel, body: string, - allowedMentions?: AllowedMentions, + allowedMentions?: MessageMentionOptions, ): Promise { const emoji = pluginData.fullConfig.success_emoji || undefined; const formattedBody = successMessage(body, emoji); - const content: AdvancedMessageContent = allowedMentions + const content: MessageOptions = allowedMentions ? { content: formattedBody, allowedMentions } : { content: formattedBody }; return channel - .createMessage(content) // Force line break + .send({ content }) // Force line break .catch(err => { - const channelInfo = (channel as GuildTextableChannel).guild - ? `${channel.id} (${(channel as GuildTextableChannel).guild.id})` - : `${channel.id}`; + const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : `${channel.id}`; logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); return undefined; }); @@ -202,21 +205,19 @@ export function sendSuccessMessage( export function sendErrorMessage( pluginData: AnyPluginData, - channel: TextableChannel, + channel: TextChannel, body: string, - allowedMentions?: AllowedMentions, + allowedMentions?: MessageMentionOptions, ): Promise { const emoji = pluginData.fullConfig.error_emoji || undefined; const formattedBody = errorMessage(body, emoji); - const content: AdvancedMessageContent = allowedMentions + const content: MessageOptions = allowedMentions ? { content: formattedBody, allowedMentions } : { content: formattedBody }; return channel - .createMessage(content) // Force line break + .send({ ...content, split: false }) // Force line break .catch(err => { - const channelInfo = (channel as GuildTextableChannel).guild - ? `${channel.id} (${(channel as GuildTextableChannel).guild.id})` - : `${channel.id}`; + const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : `${channel.id}`; logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); return undefined; }); diff --git a/backend/src/types.ts b/backend/src/types.ts index 324817bb..6378ad27 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -1,6 +1,5 @@ import { BaseConfig, Knub } from "knub"; import * as t from "io-ts"; -import { Message } from "eris"; export interface ZeppelinGuildConfig extends BaseConfig { success_emoji?: string; diff --git a/backend/src/utils/canAssignRole.ts b/backend/src/utils/canAssignRole.ts index f42778bd..17de0e45 100644 --- a/backend/src/utils/canAssignRole.ts +++ b/backend/src/utils/canAssignRole.ts @@ -1,9 +1,9 @@ -import { Constants, Guild, Member, Role } from "eris"; +import { Guild, GuildMember, Permissions, Role } from "discord.js"; import { getMissingPermissions } from "./getMissingPermissions"; import { hasDiscordPermissions } from "./hasDiscordPermissions"; -export function canAssignRole(guild: Guild, member: Member, roleId: string) { - if (getMissingPermissions(member.permission, Constants.Permissions.manageRoles)) { +export function canAssignRole(guild: Guild, member: GuildMember, roleId: string) { + if (getMissingPermissions(member.permissions, Permissions.FLAGS.MANAGE_ROLES)) { return false; } @@ -11,14 +11,14 @@ export function canAssignRole(guild: Guild, member: Member, roleId: string) { return false; } - const targetRole = guild.roles.get(roleId); + const targetRole = guild.roles.cache.get(roleId); if (!targetRole) { return false; } - const memberRoles = member.roles.map(_roleId => guild.roles.get(_roleId)!); + const memberRoles = member.roles.cache; const highestRoleWithManageRoles = memberRoles.reduce((highest, role) => { - if (!hasDiscordPermissions(role.permissions, Constants.Permissions.manageRoles)) return highest; + if (!hasDiscordPermissions(role.permissions, Permissions.FLAGS.MANAGE_ROLES)) return highest; if (highest == null) return role; if (role.position > highest.position) return role; return highest; diff --git a/backend/src/utils/canReadChannel.ts b/backend/src/utils/canReadChannel.ts index fb14874a..6f1b3fe2 100644 --- a/backend/src/utils/canReadChannel.ts +++ b/backend/src/utils/canReadChannel.ts @@ -1,8 +1,8 @@ -import { Constants, GuildChannel, Member } from "eris"; import { readChannelPermissions } from "./readChannelPermissions"; import { getMissingChannelPermissions } from "./getMissingChannelPermissions"; +import { GuildChannel, GuildMember } from "discord.js"; -export function canReadChannel(channel: GuildChannel, member: Member) { +export function canReadChannel(channel: GuildChannel, member: GuildMember) { // Not missing permissions required to read the channel = can read channel return !getMissingChannelPermissions(member, channel, readChannelPermissions); } diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index e3289881..a398c8da 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,9 +1,18 @@ -import { APIMessage, Client, Message, MessageReaction, PartialUser, TextChannel, User } from "discord.js"; +import { + APIMessage, + Client, + Message, + MessageOptions, + MessageReaction, + PartialUser, + TextChannel, + User, +} from "discord.js"; import { Awaitable } from "knub/dist/utils"; import { MINUTES, noop } from "../utils"; import Timeout = NodeJS.Timeout; -export type LoadPageFn = (page: number) => Awaitable; +export type LoadPageFn = (page: number) => Awaitable; export interface PaginateMessageOpts { timeout: number; @@ -24,7 +33,7 @@ export async function createPaginatedMessage( ): Promise { const fullOpts = { ...defaultOpts, ...opts } as PaginateMessageOpts; const firstPageContent = await loadPageFn(1); - const message = await channel.send(firstPageContent); + const message = await channel.send({ content: firstPageContent }); let page = 1; let pageLoadId = 0; // Used to avoid race conditions when rapidly switching pages diff --git a/backend/src/utils/hasDiscordPermissions.ts b/backend/src/utils/hasDiscordPermissions.ts index 28391195..34b6d9e1 100644 --- a/backend/src/utils/hasDiscordPermissions.ts +++ b/backend/src/utils/hasDiscordPermissions.ts @@ -1,11 +1,14 @@ -import { PermissionOverwrites, Permissions } from "discord.js"; +import { Permissions } from "discord.js"; /** * @param resolvedPermissions A Permission object from e.g. GuildChannel#permissionsOf() or Member#permission * @param requiredPermissions Bitmask of required permissions */ -export function hasDiscordPermissions(resolvedPermissions: PermissionOverwrites, requiredPermissions: number | bigint) { - const allowedPermissions = BigInt(resolvedPermissions.allow); +export function hasDiscordPermissions( + resolvedPermissions: Permissions | Readonly, + requiredPermissions: number | bigint, +) { + const allowedPermissions = BigInt(resolvedPermissions); const nRequiredPermissions = BigInt(requiredPermissions); if (Boolean(allowedPermissions & BigInt(Permissions.FLAGS.ADMINISTRATOR))) { diff --git a/backend/src/utils/messageHasContent.ts b/backend/src/utils/messageHasContent.ts index 40aaca8e..e333f5c9 100644 --- a/backend/src/utils/messageHasContent.ts +++ b/backend/src/utils/messageHasContent.ts @@ -1,4 +1,4 @@ -import { APIMessage, MessageOptions } from "discord.js"; +import { MessageOptions } from "discord.js"; function embedHasContent(embed: any) { for (const [key, value] of Object.entries(embed)) { From 52839cc9f39a3058ab1dc67d23313106a4880acd Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 1 Jun 2021 02:05:55 +0200 Subject: [PATCH 03/79] More rework progress, remove all eris imports --- .../plugins/AutoDelete/util/deleteNextItem.ts | 12 +++--- .../commands/NewAutoReactionsCmd.ts | 7 +-- .../AutoReactions/events/AddReactionsEvt.ts | 14 +++--- .../src/plugins/Automod/actions/addRoles.ts | 21 +++++---- backend/src/plugins/Automod/actions/alert.ts | 17 ++++---- backend/src/plugins/Automod/actions/ban.ts | 2 +- backend/src/plugins/Automod/actions/clean.ts | 4 +- backend/src/plugins/Automod/actions/kick.ts | 2 +- backend/src/plugins/Automod/actions/mute.ts | 2 +- .../plugins/Automod/actions/removeRoles.ts | 11 ++--- backend/src/plugins/Automod/actions/reply.ts | 20 +++++---- .../plugins/Automod/actions/setSlowmode.ts | 21 +++++---- backend/src/plugins/Automod/actions/warn.ts | 2 +- .../Automod/commands/ViewAntiraidCmd.ts | 4 +- .../events/RunAutomodOnMemberUpdate.ts | 12 +++--- .../events/runAutomodOnAntiraidLevel.ts | 2 +- .../Automod/events/runAutomodOnMessage.ts | 4 +- .../functions/getTextMatchPartialSummary.ts | 5 +-- .../matchMultipleTextTypesOnMessage.ts | 15 ++++--- .../functions/resolveActionContactMethods.ts | 5 ++- .../plugins/Automod/functions/runAutomod.ts | 8 ++-- .../Automod/functions/setAntiraidLevel.ts | 2 +- .../plugins/Automod/triggers/anyMessage.ts | 2 +- .../Automod/triggers/matchAttachmentType.ts | 2 +- .../src/plugins/Automod/triggers/roleAdded.ts | 2 +- .../plugins/Automod/triggers/roleRemoved.ts | 2 +- backend/src/plugins/Automod/types.ts | 5 ++- .../plugins/BotControl/BotControlPlugin.ts | 9 ++-- .../commands/ListDashboardUsersCmd.ts | 1 - .../commands/ReloadGlobalPluginsCmd.ts | 1 - .../plugins/Cases/functions/getCaseEmbed.ts | 5 ++- .../Cases/functions/postToCaseLogChannel.ts | 18 +++++--- .../plugins/Censor/util/applyFiltersToMsg.ts | 2 +- .../src/plugins/Censor/util/censorMessage.ts | 2 +- .../ChannelArchiver/rehostAttachment.ts | 1 - ...etCompanionChannelOptsForVoiceChannelId.ts | 1 - .../functions/handleCompanionPermissions.ts | 6 +-- .../Counters/commands/AddCounterCmd.ts | 2 +- .../commands/ResetAllCounterValuesCmd.ts | 2 +- .../Counters/commands/ResetCounterCmd.ts | 2 +- .../Counters/commands/SetCounterCmd.ts | 2 +- .../Counters/commands/ViewCounterCmd.ts | 2 +- .../CustomEvents/actions/addRoleAction.ts | 1 - .../actions/makeRoleMentionableAction.ts | 2 +- .../actions/makeRoleUnmentionableAction.ts | 2 +- .../CustomEvents/actions/messageAction.ts | 3 +- .../actions/moveToVoiceChannelAction.ts | 3 +- .../actions/setChannelPermissionOverrides.ts | 2 +- .../CustomEvents/functions/runEvent.ts | 2 +- .../GuildAccessMonitorPlugin.ts | 1 - .../LocateUser/events/SendAlertsEvts.ts | 1 - .../LocateUser/utils/createOrReuseInvite.ts | 2 - .../plugins/LocateUser/utils/moveMember.ts | 1 - .../plugins/LocateUser/utils/sendAlerts.ts | 2 +- .../src/plugins/LocateUser/utils/sendWhere.ts | 3 +- backend/src/plugins/Logs/LogsPlugin.ts | 6 +-- .../plugins/Logs/events/LogsGuildBanEvts.ts | 2 +- .../plugins/Logs/events/LogsRoleModifyEvts.ts | 4 +- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 10 ++--- .../Logs/events/LogsVoiceChannelEvts.ts | 11 ++++- .../src/plugins/Logs/util/getLogMessage.ts | 1 - backend/src/plugins/Logs/util/log.ts | 6 +-- .../src/plugins/Logs/util/onMessageDelete.ts | 4 +- .../plugins/Logs/util/onMessageDeleteBulk.ts | 2 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 4 +- .../MessageSaver/events/SaveMessagesEvts.ts | 3 +- .../plugins/MessageSaver/saveMessagesToDB.ts | 1 - .../plugins/ModActions/ModActionsPlugin.ts | 2 +- .../ModActions/commands/CasesModCmd.ts | 2 +- .../ModActions/commands/CasesUserCmd.ts | 2 +- .../ModActions/commands/DeleteCaseCmd.ts | 2 +- .../plugins/ModActions/commands/MassBanCmd.ts | 4 +- .../ModActions/commands/MassUnbanCmd.ts | 2 +- .../ModActions/commands/MassmuteCmd.ts | 4 +- .../plugins/ModActions/commands/MuteCmd.ts | 2 +- .../plugins/ModActions/commands/WarnCmd.ts | 1 - .../events/CreateBanCaseOnManualBanEvt.ts | 2 +- .../events/CreateKickCaseOnManualKickEvt.ts | 2 +- .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 2 +- .../events/PostAlertOnMemberJoinEvt.ts | 8 ++-- .../functions/actualKickMemberCmd.ts | 1 - .../ModActions/functions/actualMuteUserCmd.ts | 1 - .../functions/actualUnmuteUserCmd.ts | 2 +- .../plugins/ModActions/functions/banUserId.ts | 6 +-- .../functions/formatReasonWithAttachments.ts | 2 - .../functions/getDefaultContactMethods.ts | 3 +- .../plugins/ModActions/functions/isBanned.ts | 3 +- .../ModActions/functions/kickMember.ts | 4 +- .../functions/readContactMethodsFromArgs.ts | 1 - .../ModActions/functions/updateCase.ts | 1 - .../ModActions/functions/warnMember.ts | 4 +- backend/src/plugins/ModActions/types.ts | 2 +- backend/src/plugins/Mutes/MutesPlugin.ts | 2 +- .../Mutes/commands/ClearBannedMutesCmd.ts | 2 +- .../src/plugins/Mutes/commands/MutesCmd.ts | 3 +- .../Mutes/functions/clearExpiredMutes.ts | 2 +- .../Mutes/functions/memberHasMutedRole.ts | 1 - .../src/plugins/Mutes/functions/muteUser.ts | 8 ++-- .../src/plugins/Mutes/functions/unmuteUser.ts | 6 +-- backend/src/plugins/Mutes/types.ts | 2 +- .../plugins/NameHistory/commands/NamesCmd.ts | 2 +- .../NameHistory/events/UpdateNameEvts.ts | 2 +- .../src/plugins/NameHistory/updateNickname.ts | 1 - .../src/plugins/Persist/events/LoadDataEvt.ts | 4 +- .../plugins/Persist/events/StoreDataEvt.ts | 2 +- .../events/ChangePingableEvts.ts | 2 +- .../utils/disablePingableRoles.ts | 2 +- .../utils/enablePingableRoles.ts | 2 +- backend/src/plugins/Post/commands/EditCmd.ts | 2 +- .../src/plugins/Post/commands/EditEmbedCmd.ts | 2 +- .../src/plugins/Post/commands/PostEmbedCmd.ts | 2 +- .../Post/commands/ScheduledPostsShowCmd.ts | 1 - .../src/plugins/Post/util/actualPostCmd.ts | 1 - backend/src/plugins/Post/util/postMessage.ts | 2 +- .../plugins/Post/util/scheduledPostLoop.ts | 6 +-- .../commands/ClearReactionRolesCmd.ts | 2 +- .../commands/InitReactionRolesCmd.ts | 2 +- .../events/AddReactionRoleEvt.ts | 4 +- .../applyReactionRoleReactionsToMessage.ts | 4 +- .../Reminders/utils/postDueRemindersLoop.ts | 3 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 1 - .../plugins/Roles/commands/MassAddRoleCmd.ts | 3 +- .../Roles/commands/MassRemoveRoleCmd.ts | 3 +- .../plugins/Roles/commands/RemoveRoleCmd.ts | 2 +- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 8 ++-- .../commands/RoleRemoveCmd.ts | 2 +- .../Slowmode/commands/SlowmodeClearCmd.ts | 2 +- .../Slowmode/commands/SlowmodeGetCmd.ts | 2 +- .../Slowmode/commands/SlowmodeListCmd.ts | 2 +- .../Slowmode/commands/SlowmodeSetCmd.ts | 4 +- .../plugins/Slowmode/requiredPermissions.ts | 2 - .../Slowmode/util/actualDisableSlowmodeCmd.ts | 3 +- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 4 +- .../util/clearBotSlowmodeFromUserId.ts | 1 - .../Slowmode/util/clearExpiredSlowmodes.ts | 6 +-- .../util/disableBotSlowmodeForChannel.ts | 1 - .../plugins/Slowmode/util/onMessageCreate.ts | 6 +-- .../Spam/util/logAndDetectMessageSpam.ts | 6 +-- .../Spam/util/logAndDetectOtherSpam.ts | 4 +- backend/src/plugins/Spam/util/logCensor.ts | 2 +- .../src/plugins/Spam/util/onMessageCreate.ts | 2 +- .../Starboard/commands/MigratePinsCmd.ts | 4 +- .../events/StarboardReactionAddEvt.ts | 2 +- .../util/createStarboardEmbedFromMessage.ts | 2 +- .../createStarboardPseudoFooterForMessage.ts | 1 - .../Starboard/util/saveMessageToStarboard.ts | 4 +- .../util/updateStarboardMessageStarCount.ts | 1 - backend/src/plugins/Tags/TagsPlugin.ts | 2 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 2 +- .../Tags/util/matchAndRenderTagFromString.ts | 1 - .../src/plugins/Tags/util/onMessageCreate.ts | 4 +- .../src/plugins/Tags/util/onMessageDelete.ts | 5 +-- .../plugins/Tags/util/renderTagFromString.ts | 2 +- .../events/UpdateUsernameEvts.ts | 2 +- .../plugins/UsernameSaver/updateUsername.ts | 1 - .../src/plugins/Utility/commands/AboutCmd.ts | 11 ++--- .../src/plugins/Utility/commands/AvatarCmd.ts | 1 - .../src/plugins/Utility/commands/CleanCmd.ts | 4 +- .../plugins/Utility/commands/ContextCmd.ts | 2 +- .../src/plugins/Utility/commands/InfoCmd.ts | 4 +- .../src/plugins/Utility/commands/PingCmd.ts | 1 - .../Utility/commands/ReloadGuildCmd.ts | 2 +- .../src/plugins/Utility/commands/RolesCmd.ts | 2 +- .../src/plugins/Utility/commands/SourceCmd.ts | 2 +- .../Utility/commands/VcdisconnectCmd.ts | 2 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 12 +++--- .../Utility/functions/getChannelInfoEmbed.ts | 4 +- .../Utility/functions/getEmojiInfoEmbed.ts | 1 - .../Utility/functions/getGuildPreview.ts | 1 - .../Utility/functions/getInviteInfoEmbed.ts | 2 +- .../Utility/functions/getMessageInfoEmbed.ts | 2 +- .../Utility/functions/getRoleInfoEmbed.ts | 1 - .../Utility/functions/getServerInfoEmbed.ts | 2 +- .../functions/getSnowflakeInfoEmbed.ts | 1 - .../Utility/functions/getUserInfoEmbed.ts | 5 +-- backend/src/plugins/Utility/guildReloads.ts | 2 - backend/src/plugins/Utility/refreshMembers.ts | 1 - backend/src/plugins/Utility/search.ts | 3 +- .../events/SendWelcomeMessageEvt.ts | 4 +- .../erisAllowedMentionsToDjsMentionOptions.ts | 43 +++++++++++++++++++ backend/src/utils/hasDiscordPermissions.ts | 2 +- 181 files changed, 352 insertions(+), 343 deletions(-) create mode 100644 backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts index c5ff6d23..2ec8b598 100644 --- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts +++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts @@ -7,8 +7,8 @@ import { logger } from "../../../logger"; import { scheduleNextDeletion } from "./scheduleNextDeletion"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { Constants } from "eris"; import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { Permissions, TextChannel } from "discord.js"; export async function deleteNextItem(pluginData: GuildPluginData) { const [itemToDelete] = pluginData.state.deletionQueue.splice(0, 1); @@ -16,16 +16,16 @@ export async function deleteNextItem(pluginData: GuildPluginData { + (channel as TextChannel).messages.delete(itemToDelete.message.id).catch(err => { if (err.code === 10008) { // "Unknown Message", probably already deleted by automod or another bot, ignore return; diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 8a4a67e1..f1fb64ff 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -3,11 +3,12 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { Constants, GuildChannel } from "eris"; + import { readChannelPermissions } from "../../../utils/readChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { GuildChannel, Permissions } from "discord.js"; -const requiredPermissions = readChannelPermissions | Constants.Permissions.addReactions; +const requiredPermissions = readChannelPermissions | Permissions.FLAGS.ADD_REACTIONS; export const NewAutoReactionsCmd = autoReactionsCmd({ trigger: "auto_reactions", @@ -22,7 +23,7 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ async run({ message: msg, args, pluginData }) { const finalReactions: string[] = []; - const me = pluginData.guild.members.get(pluginData.client.user.id)!; + const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel as GuildChannel, requiredPermissions); if (missingPermissions) { sendErrorMessage( diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index 54f44951..06ca2bb2 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -1,17 +1,17 @@ import { autoReactionsEvt } from "../types"; import { isDiscordRESTError } from "../../../utils"; import { LogType } from "../../../data/LogType"; -import { logger } from "../../../logger"; import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { Constants, GuildChannel } from "eris"; + import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { readChannelPermissions } from "../../../utils/readChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { GuildChannel, Permissions } from "discord.js"; -const p = Constants.Permissions; +const p = Permissions.FLAGS; export const AddReactionsEvt = autoReactionsEvt({ - event: "messageCreate", + event: "message", allowBots: true, allowSelf: true, @@ -19,11 +19,11 @@ export const AddReactionsEvt = autoReactionsEvt({ const autoReaction = await pluginData.state.autoReactions.getForChannel(message.channel.id); if (!autoReaction) return; - const me = pluginData.guild.members.get(pluginData.client.user.id)!; + const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions( me, message.channel as GuildChannel, - readChannelPermissions | p.addReactions, + readChannelPermissions | p.ADD_REACTIONS, ); if (missingPermissions) { const logs = pluginData.getPlugin(LogsPlugin); @@ -35,7 +35,7 @@ export const AddReactionsEvt = autoReactionsEvt({ for (const reaction of autoReaction.reactions) { try { - await message.addReaction(reaction); + await message.react(reaction); } catch (e) { if (isDiscordRESTError(e)) { const logs = pluginData.getPlugin(LogsPlugin); diff --git a/backend/src/plugins/Automod/actions/addRoles.ts b/backend/src/plugins/Automod/actions/addRoles.ts index 976300a5..39f59870 100644 --- a/backend/src/plugins/Automod/actions/addRoles.ts +++ b/backend/src/plugins/Automod/actions/addRoles.ts @@ -1,17 +1,16 @@ +import { Permissions } from "discord.js"; import * as t from "io-ts"; -import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; import { nonNullish, unique } from "../../../utils"; -import { Constants } from "eris"; -import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { canAssignRole } from "../../../utils/canAssignRole"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; +import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; +import { automodAction } from "../helpers"; -const p = Constants.Permissions; +const p = Permissions.FLAGS; export const AddRolesAction = automodAction({ configType: t.array(t.string), @@ -19,9 +18,9 @@ export const AddRolesAction = automodAction({ async apply({ pluginData, contexts, actionConfig, ruleName }) { const members = unique(contexts.map(c => c.member).filter(nonNullish)); - const me = pluginData.guild.members.get(pluginData.client.user.id)!; + const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; - const missingPermissions = getMissingPermissions(me.permission, p.manageRoles); + const missingPermissions = getMissingPermissions(me.permissions, p.MANAGE_ROLES); if (missingPermissions) { const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { @@ -42,7 +41,7 @@ export const AddRolesAction = automodAction({ if (rolesWeCannotAssign.length) { const roleNamesWeCannotAssign = rolesWeCannotAssign.map( - roleId => pluginData.guild.roles.get(roleId)?.name || roleId, + roleId => pluginData.guild.roles.cache.get(roleId)?.name || roleId, ); const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { diff --git a/backend/src/plugins/Automod/actions/alert.ts b/backend/src/plugins/Automod/actions/alert.ts index 2076ae55..7b932639 100644 --- a/backend/src/plugins/Automod/actions/alert.ts +++ b/backend/src/plugins/Automod/actions/alert.ts @@ -2,22 +2,17 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; import { - asyncMap, createChunkedMessage, - isDiscordRESTError, messageLink, - resolveMember, stripObjectToScalars, tAllowedMentions, tNormalizedNullOptional, - tNullable, verboseChannelMention, } from "../../../utils"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { TextChannel } from "eris"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { TextChannel } from "discord.js"; +import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; export const AlertAction = automodAction({ configType: t.type({ @@ -29,7 +24,7 @@ export const AlertAction = automodAction({ defaultConfig: {}, async apply({ pluginData, contexts, actionConfig, ruleName, matchResult }) { - const channel = pluginData.guild.channels.get(actionConfig.channel); + const channel = pluginData.guild.channels.cache.get(actionConfig.channel); const logs = pluginData.getPlugin(LogsPlugin); if (channel && channel instanceof TextChannel) { @@ -73,7 +68,11 @@ export const AlertAction = automodAction({ } try { - await createChunkedMessage(channel, rendered, actionConfig.allowed_mentions); + await createChunkedMessage( + channel, + rendered, + erisAllowedMentionsToDjsMentionOptions(actionConfig.allowed_mentions), + ); } catch (err) { if (err.code === 50001) { logs.log(LogType.BOT_ALERT, { diff --git a/backend/src/plugins/Automod/actions/ban.ts b/backend/src/plugins/Automod/actions/ban.ts index 4867ead7..9ca09086 100644 --- a/backend/src/plugins/Automod/actions/ban.ts +++ b/backend/src/plugins/Automod/actions/ban.ts @@ -37,7 +37,7 @@ export const BanAction = automodAction({ const deleteMessageDays = actionConfig.deleteMessageDays || undefined; const caseArgs: Partial = { - modId: pluginData.client.user.id, + modId: pluginData.client.user!.id, extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [], automatic: true, postInCaseLogOverride: actionConfig.postInCaseLog ?? undefined, diff --git a/backend/src/plugins/Automod/actions/clean.ts b/backend/src/plugins/Automod/actions/clean.ts index 3c2c0c7d..4f505cfb 100644 --- a/backend/src/plugins/Automod/actions/clean.ts +++ b/backend/src/plugins/Automod/actions/clean.ts @@ -2,6 +2,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; import { noop } from "../../../utils"; +import { TextChannel } from "discord.js"; export const CleanAction = automodAction({ configType: t.boolean, @@ -29,7 +30,8 @@ export const CleanAction = automodAction({ pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE, id); } - await pluginData.client.deleteMessages(channelId, messageIds).catch(noop); + const channel = pluginData.guild.channels.cache.get(channelId) as TextChannel; + await channel.bulkDelete(messageIds).catch(noop); } }, }); diff --git a/backend/src/plugins/Automod/actions/kick.ts b/backend/src/plugins/Automod/actions/kick.ts index 879a541d..0b0fafa5 100644 --- a/backend/src/plugins/Automod/actions/kick.ts +++ b/backend/src/plugins/Automod/actions/kick.ts @@ -25,7 +25,7 @@ export const KickAction = automodAction({ const contactMethods = actionConfig.notify ? resolveActionContactMethods(pluginData, actionConfig) : undefined; const caseArgs: Partial = { - modId: pluginData.client.user.id, + modId: pluginData.client.user!.id, extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [], automatic: true, postInCaseLogOverride: actionConfig.postInCaseLog ?? undefined, diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index 798b8b10..3bc7a90b 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -42,7 +42,7 @@ export const MuteAction = automodAction({ const rolesToRestore = actionConfig.restore_roles_on_mute; const caseArgs: Partial = { - modId: pluginData.client.user.id, + modId: pluginData.client.user!.id, extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [], automatic: true, postInCaseLogOverride: actionConfig.postInCaseLog ?? undefined, diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index c6c74e49..dcfbd9d3 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -8,11 +8,12 @@ import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { canAssignRole } from "../../../utils/canAssignRole"; -import { Constants } from "eris"; + import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { Permissions } from "discord.js"; -const p = Constants.Permissions; +const p = Permissions.FLAGS; export const RemoveRolesAction = automodAction({ configType: t.array(t.string), @@ -21,9 +22,9 @@ export const RemoveRolesAction = automodAction({ async apply({ pluginData, contexts, actionConfig, ruleName }) { const members = unique(contexts.map(c => c.member).filter(nonNullish)); - const me = pluginData.guild.members.get(pluginData.client.user.id)!; + const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; - const missingPermissions = getMissingPermissions(me.permission, p.manageRoles); + const missingPermissions = getMissingPermissions(me.permissions, p.MANAGE_ROLES); if (missingPermissions) { const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { @@ -44,7 +45,7 @@ export const RemoveRolesAction = automodAction({ if (rolesWeCannotRemove.length) { const roleNamesWeCannotRemove = rolesWeCannotRemove.map( - roleId => pluginData.guild.roles.get(roleId)?.name || roleId, + roleId => pluginData.guild.roles.cache.get(roleId)?.name || roleId, ); const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index c8291e43..8357edb9 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -12,11 +12,12 @@ import { unique, verboseChannelMention, } from "../../../utils"; -import { AdvancedMessageContent, Constants, MessageContent, TextChannel, User } from "eris"; + import { AutomodContext } from "../types"; import { renderTemplate } from "../../../templateFormatter"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogType } from "../../../data/LogType"; +import { TextChannel, User, Constants, MessageOptions, Permissions } from "discord.js"; export const ReplyAction = automodAction({ configType: t.union([ @@ -32,7 +33,7 @@ export const ReplyAction = automodAction({ async apply({ pluginData, contexts, actionConfig, ruleName }) { const contextsWithTextChannels = contexts .filter(c => c.message?.channel_id) - .filter(c => pluginData.guild.channels.get(c.message!.channel_id) instanceof TextChannel); + .filter(c => pluginData.guild.channels.cache.get(c.message!.channel_id) instanceof TextChannel); const contextsByChannelId = contextsWithTextChannels.reduce((map: Map, context) => { if (!map.has(context.message!.channel_id)) { @@ -54,16 +55,16 @@ export const ReplyAction = automodAction({ const formatted = typeof actionConfig === "string" ? await renderReplyText(actionConfig) - : ((await renderRecursively(actionConfig.text, renderReplyText)) as AdvancedMessageContent); + : ((await renderRecursively(actionConfig.text, renderReplyText)) as MessageOptions); if (formatted) { - const channel = pluginData.guild.channels.get(channelId) as TextChannel; + const channel = pluginData.guild.channels.cache.get(channelId) as TextChannel; // Check for basic Send Messages and View Channel permissions if ( !hasDiscordPermissions( - channel.permissionsOf(pluginData.client.user.id), - Constants.Permissions.sendMessages | Constants.Permissions.readMessages, + channel.permissionsFor(pluginData.client.user!.id), + Permissions.FLAGS.SEND_MESSAGES | Permissions.FLAGS.VIEW_CHANNEL, ) ) { pluginData.state.logs.log(LogType.BOT_ALERT, { @@ -75,7 +76,7 @@ export const ReplyAction = automodAction({ // If the message is an embed, check for embed permissions if ( typeof formatted !== "string" && - !hasDiscordPermissions(channel.permissionsOf(pluginData.client.user.id), Constants.Permissions.embedLinks) + !hasDiscordPermissions(channel.permissionsFor(pluginData.client.user!.id), Permissions.FLAGS.EMBED_LINKS) ) { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Missing permissions to reply **with an embed** in ${verboseChannelMention( @@ -85,12 +86,13 @@ export const ReplyAction = automodAction({ continue; } - const messageContent: StrictMessageContent = typeof formatted === "string" ? { content: formatted } : formatted; - const replyMsg = await channel.createMessage({ + const messageContent: MessageOptions = typeof formatted === "string" ? { content: formatted } : formatted; + const replyMsg = await channel.send({ ...messageContent, allowedMentions: { users: [user.id], }, + split: false, }); if (typeof actionConfig === "object" && actionConfig.auto_delete) { diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index 6c69f019..a2bacc38 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -2,7 +2,8 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { convertDelayStringToMS, isDiscordRESTError, tDelayString, tNullable } from "../../../utils"; import { LogType } from "../../../data/LogType"; -import { Constants, TextChannel } from "eris"; +import { Constants, TextChannel } from "discord.js"; +import { ChannelTypeStrings } from "src/types"; export const SetSlowmodeAction = automodAction({ configType: t.type({ @@ -18,24 +19,22 @@ export const SetSlowmodeAction = automodAction({ const slowmodeMs = Math.max(actionConfig.duration ? convertDelayStringToMS(actionConfig.duration)! : 0, 0); for (const channelId of actionConfig.channels) { - const channel = pluginData.guild.channels.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId); // Only text channels and text channels within categories support slowmodes - if ( - !channel || - !(channel.type === Constants.ChannelTypes.GUILD_TEXT || channel.type === Constants.ChannelTypes.GUILD_CATEGORY) - ) { + if (!channel || !(channel.type === ChannelTypeStrings.TEXT || ChannelTypeStrings.CATEGORY)) { continue; } let channelsToSlowmode: TextChannel[] = []; - if (channel.type === Constants.ChannelTypes.GUILD_CATEGORY) { + if (channel.type === ChannelTypeStrings.CATEGORY) { // Find all text channels within the category - channelsToSlowmode = pluginData.guild.channels.filter( - ch => ch.parentID === channel.id && ch.type === Constants.ChannelTypes.GUILD_TEXT, - ) as TextChannel[]; + for (const ch of pluginData.guild.channels.cache.values()) { + if (ch.parentID === channel.id && ch.type === ChannelTypeStrings.TEXT) + channelsToSlowmode.push(ch as TextChannel); + } } else { - channelsToSlowmode.push(channel); + channelsToSlowmode.push(channel as TextChannel); } const slowmodeSeconds = Math.ceil(slowmodeMs / 1000); diff --git a/backend/src/plugins/Automod/actions/warn.ts b/backend/src/plugins/Automod/actions/warn.ts index feccf2b0..38f131b8 100644 --- a/backend/src/plugins/Automod/actions/warn.ts +++ b/backend/src/plugins/Automod/actions/warn.ts @@ -25,7 +25,7 @@ export const WarnAction = automodAction({ const contactMethods = actionConfig.notify ? resolveActionContactMethods(pluginData, actionConfig) : undefined; const caseArgs: Partial = { - modId: pluginData.client.user.id, + modId: pluginData.client.user!.id, extraNotes: matchResult.fullSummary ? [matchResult.fullSummary] : [], automatic: true, postInCaseLogOverride: actionConfig.postInCaseLog ?? undefined, diff --git a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts index 76cf64b1..397e60e1 100644 --- a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts @@ -10,9 +10,9 @@ export const ViewAntiraidCmd = typedGuildCommand()({ async run({ pluginData, message }) { if (pluginData.state.cachedAntiraidLevel) { - message.channel.createMessage(`Anti-raid is set to **${pluginData.state.cachedAntiraidLevel}**`); + message.channel.send(`Anti-raid is set to **${pluginData.state.cachedAntiraidLevel}**`); } else { - message.channel.createMessage(`Anti-raid is **off**`); + message.channel.send(`Anti-raid is **off**`); } }, }); diff --git a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts index 275865cf..8ef0b461 100644 --- a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts +++ b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts @@ -7,19 +7,19 @@ import diff from "lodash.difference"; export const RunAutomodOnMemberUpdate = typedGuildEventListener()({ event: "guildMemberUpdate", - listener({ pluginData, args: { member, oldMember } }) { + listener({ pluginData, args: { oldMember, newMember } }) { if (!oldMember) return; - if (isEqual(oldMember.roles, member.roles)) return; + if (isEqual(oldMember.roles, newMember.roles)) return; - const addedRoles = diff(member.roles, oldMember.roles); - const removedRoles = diff(oldMember.roles, member.roles); + const addedRoles = diff(newMember.roles, oldMember.roles); + const removedRoles = diff(oldMember.roles, newMember.roles); if (addedRoles.length || removedRoles.length) { const context: AutomodContext = { timestamp: Date.now(), - user: member.user, - member, + user: newMember.user, + member: newMember, rolesChanged: { added: addedRoles, removed: removedRoles, diff --git a/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts b/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts index f36e1067..4145cb19 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { AutomodContext, AutomodPluginType } from "../types"; import { runAutomod } from "../functions/runAutomod"; -import { User } from "eris"; +import { User } from "discord.js"; export async function runAutomodOnAntiraidLevel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts index 0ae87a6f..a3db2cf4 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts @@ -11,8 +11,8 @@ export function runAutomodOnMessage( message: SavedMessage, isEdit: boolean, ) { - const user = pluginData.client.users.get(message.user_id); - const member = pluginData.guild.members.get(message.user_id); + const user = pluginData.client.users.cache!.get(message.user_id); + const member = pluginData.guild.members.cache.get(message.user_id); const context: AutomodContext = { timestamp: moment.utc(message.posted_at).valueOf(), diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts index 9a86dc13..37a04fe4 100644 --- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts +++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts @@ -2,7 +2,6 @@ import { MatchableTextType } from "./matchMultipleTextTypesOnMessage"; import { AutomodContext, AutomodPluginType } from "../types"; import { messageSummary, verboseChannelMention } from "../../../utils"; import { GuildPluginData } from "knub"; -import { User } from "eris"; export function getTextMatchPartialSummary( pluginData: GuildPluginData, @@ -11,13 +10,13 @@ export function getTextMatchPartialSummary( ) { if (type === "message") { const message = context.message!; - const channel = pluginData.guild.channels.get(message.channel_id); + const channel = pluginData.guild.channels.cache.get(message.channel_id); const channelMention = channel ? verboseChannelMention(channel) : `\`#${message.channel_id}\``; return `message in ${channelMention}:\n${messageSummary(message)}`; } else if (type === "embed") { const message = context.message!; - const channel = pluginData.guild.channels.get(message.channel_id); + const channel = pluginData.guild.channels.cache.get(message.channel_id); const channelMention = channel ? verboseChannelMention(channel) : `\`#${message.channel_id}\``; return `message embed in ${channelMention}:\n${messageSummary(message)}`; diff --git a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts index a51ad74d..2638d677 100644 --- a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts +++ b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts @@ -2,6 +2,7 @@ import { SavedMessage } from "../../../data/entities/SavedMessage"; import { resolveMember } from "../../../utils"; import { GuildPluginData } from "knub"; import { AutomodPluginType } from "../types"; +import { Activity, Constants } from "discord.js"; type TextTriggerWithMultipleMatchTypes = { match_messages: boolean; @@ -40,19 +41,21 @@ export async function* matchMultipleTextTypesOnMessage( } if (trigger.match_visible_names) { - yield ["visiblename", member.nick || msg.data.author.username]; + yield ["visiblename", member.nickname || msg.data.author.username]; } if (trigger.match_usernames) { yield ["username", `${msg.data.author.username}#${msg.data.author.discriminator}`]; } - if (trigger.match_nicknames && member.nick) { - yield ["nickname", member.nick]; + if (trigger.match_nicknames && member.nickname) { + yield ["nickname", member.nickname]; } - // type 4 = custom status - if (trigger.match_custom_status && member.game?.type === 4 && member.game?.state) { - yield ["customstatus", member.game.state]; + for (const activity of member.presence.activities) { + if (activity.type === Constants.ActivityTypes[4]) { + yield ["customstatus", `${activity.emoji} ${activity.name}`]; + break; + } } } diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts index 2309a95a..83753a02 100644 --- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts +++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts @@ -1,8 +1,9 @@ import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { TextChannel } from "eris"; + import { GuildPluginData } from "knub"; import { AutomodPluginType } from "../types"; +import { TextChannel } from "discord.js"; export function resolveActionContactMethods( pluginData: GuildPluginData, @@ -18,7 +19,7 @@ export function resolveActionContactMethods( throw new RecoverablePluginError(ERRORS.NO_USER_NOTIFICATION_CHANNEL); } - const channel = pluginData.guild.channels.get(actionConfig.notifyChannel); + const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel); if (!(channel instanceof TextChannel)) { throw new RecoverablePluginError(ERRORS.INVALID_USER_NOTIFICATION_CHANNEL); } diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts index 0e7ee471..f95a9abf 100644 --- a/backend/src/plugins/Automod/functions/runAutomod.ts +++ b/backend/src/plugins/Automod/functions/runAutomod.ts @@ -5,14 +5,14 @@ import { availableActions } from "../actions/availableActions"; import { AutomodTriggerMatchResult } from "../helpers"; import { CleanAction } from "../actions/clean"; import { checkAndUpdateCooldown } from "./checkAndUpdateCooldown"; -import { TextChannel } from "eris"; +import { TextChannel } from "discord.js"; export async function runAutomod(pluginData: GuildPluginData, context: AutomodContext) { const userId = context.user?.id || context.member?.id || context.message?.user_id; - const user = context.user || (userId && pluginData.client.users.get(userId)); - const member = context.member || (userId && pluginData.guild.members.get(userId)) || null; + const user = context.user || (userId && pluginData.client.users!.cache.get(userId)); + const member = context.member || (userId && pluginData.guild.members.cache.get(userId)) || null; const channelId = context.message?.channel_id; - const channel = channelId ? (pluginData.guild.channels.get(channelId) as TextChannel) : null; + const channel = channelId ? (pluginData.guild.channels.cache.get(channelId) as TextChannel) : null; const categoryId = channel?.parentID; const config = await pluginData.config.getMatchingConfig({ diff --git a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts index eb72c3ec..8d926525 100644 --- a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts @@ -1,10 +1,10 @@ -import { User } from "eris"; import { GuildPluginData } from "knub"; import { AutomodPluginType } from "../types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars } from "../../../utils"; import { runAutomodOnAntiraidLevel } from "../events/runAutomodOnAntiraidLevel"; +import { User } from "discord.js"; export async function setAntiraidLevel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/triggers/anyMessage.ts b/backend/src/plugins/Automod/triggers/anyMessage.ts index 466f0460..4f15c3cb 100644 --- a/backend/src/plugins/Automod/triggers/anyMessage.ts +++ b/backend/src/plugins/Automod/triggers/anyMessage.ts @@ -21,7 +21,7 @@ export const AnyMessageTrigger = automodTrigger()({ }, renderMatchInformation({ pluginData, contexts, matchResult }) { - const channel = pluginData.guild.channels.get(contexts[0].message!.channel_id); + const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id); return `Matched message (\`${contexts[0].message!.id}\`) in ${ channel ? verboseChannelMention(channel) : "Unknown Channel" }`; diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 45f29697..39163095 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -73,7 +73,7 @@ export const MatchAttachmentTypeTrigger = automodTrigger()({ }, renderMatchInformation({ pluginData, contexts, matchResult }) { - const channel = pluginData.guild.channels.get(contexts[0].message!.channel_id)!; + const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id)!; const prettyChannel = verboseChannelMention(channel); return ( diff --git a/backend/src/plugins/Automod/triggers/roleAdded.ts b/backend/src/plugins/Automod/triggers/roleAdded.ts index d7c97171..f3a4d7cb 100644 --- a/backend/src/plugins/Automod/triggers/roleAdded.ts +++ b/backend/src/plugins/Automod/triggers/roleAdded.ts @@ -33,7 +33,7 @@ export const RoleAddedTrigger = automodTrigger()({ }, renderMatchInformation({ matchResult, pluginData, contexts }) { - const role = pluginData.guild.roles.get(matchResult.extra.matchedRoleId); + const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId); const roleName = role?.name || "Unknown"; const member = contexts[0].member!; const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; diff --git a/backend/src/plugins/Automod/triggers/roleRemoved.ts b/backend/src/plugins/Automod/triggers/roleRemoved.ts index 1613f91d..430ec746 100644 --- a/backend/src/plugins/Automod/triggers/roleRemoved.ts +++ b/backend/src/plugins/Automod/triggers/roleRemoved.ts @@ -33,7 +33,7 @@ export const RoleRemovedTrigger = automodTrigger()({ }, renderMatchInformation({ matchResult, pluginData, contexts }) { - const role = pluginData.guild.roles.get(matchResult.extra.matchedRoleId); + const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId); const roleName = role?.name || "Unknown"; const member = contexts[0].member!; const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index cd7ebacf..08b49ee4 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -4,7 +4,7 @@ import { BasePluginType, CooldownManager } from "knub"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildLogs } from "../../data/GuildLogs"; import { SavedMessage } from "../../data/entities/SavedMessage"; -import { Member, User } from "eris"; + import { AvailableTriggers } from "./triggers/availableTriggers"; import { AvailableActions } from "./actions/availableActions"; import { Queue } from "../../Queue"; @@ -16,6 +16,7 @@ import { RegExpRunner } from "../../RegExpRunner"; import { CounterEvents } from "../Counters/types"; import { ModActionsEvents, ModActionType } from "../ModActions/types"; import { MutesEvents } from "../Mutes/types"; +import { GuildMember, User } from "discord.js"; export const Rule = t.type({ enabled: t.boolean, @@ -113,7 +114,7 @@ export interface AutomodContext { }; user?: User; message?: SavedMessage; - member?: Member; + member?: GuildMember; joined?: boolean; rolesChanged?: { added?: string[]; diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index e8151be1..6c5cffc3 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -1,7 +1,7 @@ import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; import { BotControlPluginType, ConfigSchema } from "./types"; import { GuildArchives } from "../../data/GuildArchives"; -import { TextChannel } from "eris"; + import { sendSuccessMessage } from "../../pluginUtils"; import { getActiveReload, resetActiveReload } from "./activeReload"; import { ReloadGlobalPluginsCmd } from "./commands/ReloadGlobalPluginsCmd"; @@ -18,6 +18,7 @@ import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; import { ListDashboardUsersCmd } from "./commands/ListDashboardUsersCmd"; import { ListDashboardPermsCmd } from "./commands/ListDashboardPermsCmd"; import { EligibleCmd } from "./commands/EligibleCmd"; +import { TextChannel } from "discord.js"; const defaultOptions = { config: { @@ -47,7 +48,7 @@ export const BotControlPlugin = zeppelinGlobalPlugin()({ EligibleCmd, ], - afterLoad(pluginData) { + async afterLoad(pluginData) { pluginData.state.archives = new GuildArchives(0); pluginData.state.allowedGuilds = new AllowedGuilds(); pluginData.state.configs = new Configs(); @@ -58,9 +59,9 @@ export const BotControlPlugin = zeppelinGlobalPlugin()({ const [guildId, channelId] = activeReload; resetActiveReload(); - const guild = pluginData.client.guilds.get(guildId); + const guild = await pluginData.client.guilds.fetch(guildId); if (guild) { - const channel = guild.channels.get(channelId); + const channel = guild.channels.cache.get(channelId); if (channel instanceof TextChannel) { sendSuccessMessage(pluginData, channel, "Global plugins reloaded!"); } diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index f4f89838..5d65525b 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -3,7 +3,6 @@ import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../.. import { commandTypeHelpers as ct } from "../../../commandTypes"; import { ApiPermissions } from "@shared/apiPermissions"; import { resolveUser, UnknownUser } from "../../../utils"; -import { User } from "eris"; export const ListDashboardUsersCmd = botControlCmd({ trigger: ["list_dashboard_users"], diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index 6abc0c5f..1e341d00 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -1,7 +1,6 @@ import { botControlCmd } from "../types"; import { isOwnerPreFilter } from "../../../pluginUtils"; import { getActiveReload, setActiveReload } from "../activeReload"; -import { TextChannel } from "eris"; export const ReloadGlobalPluginsCmd = botControlCmd({ trigger: "bot_reload_global_plugins", diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index ec92e059..a73c5e15 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -1,5 +1,5 @@ import { Case } from "../../../data/entities/Case"; -import { AdvancedMessageContent, MessageContent } from "eris"; + import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; import { GuildPluginData, helpers } from "knub"; @@ -8,13 +8,14 @@ import { resolveCaseId } from "./resolveCaseId"; import { chunkLines, chunkMessageLines, emptyEmbedValue, messageLink } from "../../../utils"; import { getCaseColor } from "./getCaseColor"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageOptions } from "discord.js"; export async function getCaseEmbed( pluginData: GuildPluginData, caseOrCaseId: Case | number, requestMemberId?: string, noOriginalCaseLink?: boolean, -): Promise { +): Promise { const theCase = await pluginData.state.cases.with("notes").find(resolveCaseId(caseOrCaseId)); if (!theCase) { throw new Error("Unknown case"); diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index 604293e1..6d80698f 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -1,27 +1,30 @@ import { GuildPluginData } from "knub"; import { CasesPluginType } from "../types"; -import { Message, MessageContent, MessageFile, TextChannel } from "eris"; + import { isDiscordRESTError } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { Case } from "../../../data/entities/Case"; import { getCaseEmbed } from "./getCaseEmbed"; import { resolveCaseId } from "./resolveCaseId"; -import { logger } from "../../../logger"; +import { FileOptions, Message, MessageOptions, TextChannel } from "discord.js"; export async function postToCaseLogChannel( pluginData: GuildPluginData, - content: MessageContent, - file?: MessageFile, + content: MessageOptions, + file?: FileOptions[], ): Promise { const caseLogChannelId = pluginData.config.get().case_log_channel; if (!caseLogChannelId) return null; - const caseLogChannel = pluginData.guild.channels.get(caseLogChannelId); + const caseLogChannel = pluginData.guild.channels.cache.get(caseLogChannelId); if (!caseLogChannel || !(caseLogChannel instanceof TextChannel)) return null; let result; try { - result = await caseLogChannel.createMessage(content, file); + if (file != undefined) { + content.files = file; + } + result = await caseLogChannel.send({ ...content, split: false }); } catch (e) { if (isDiscordRESTError(e) && (e.code === 50013 || e.code === 50001)) { pluginData.state.logs.log(LogType.BOT_ALERT, { @@ -50,7 +53,8 @@ export async function postCaseToCaseLogChannel( const [channelId, messageId] = theCase.log_message_id.split("-"); try { - await pluginData.client.editMessage(channelId, messageId, caseEmbed); + const channel = pluginData.guild.channels.resolve(channelId) as TextChannel; + await channel.messages.edit(messageId, caseEmbed); return null; } catch {} // tslint:disable-line:no-empty } diff --git a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts index 4e9f3691..6e83acc6 100644 --- a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts +++ b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { CensorPluginType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { Embed, Invite } from "eris"; + import { ZalgoRegex } from "../../../data/Zalgo"; import { getInviteCodesInString, getUrlsInString, resolveMember, resolveInvite, isGuildInvite } from "../../../utils"; import cloneDeep from "lodash.clonedeep"; diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index 91302acf..df0011ca 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -19,7 +19,7 @@ export async function censorMessage( } const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.get(savedMessage.channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); pluginData.state.serverLogs.log(LogType.CENSOR, { user: stripObjectToScalars(user), diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index c0bbd289..09aa338f 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -1,4 +1,3 @@ -import { Attachment, TextChannel } from "eris"; import { downloadFile } from "../../utils"; import fs from "fs"; const fsp = fs.promises; diff --git a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts index 1090acc4..d0392467 100644 --- a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts +++ b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts @@ -1,4 +1,3 @@ -import { VoiceChannel } from "eris"; import { GuildPluginData } from "knub"; import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index 1dbdfe27..0806da09 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -1,7 +1,7 @@ import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId"; import { GuildPluginData } from "knub"; -import { TextChannel, VoiceChannel } from "eris"; + import { isDiscordRESTError, MINUTES } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; @@ -63,13 +63,13 @@ export async function handleCompanionPermissions( try { for (const channelId of permsToDelete) { - const channel = pluginData.guild.channels.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId); if (!channel || !(channel instanceof TextChannel)) continue; await channel.deletePermission(userId, `Companion Channel for ${oldChannel!.id} | User Left`); } for (const [channelId, permissions] of permsToSet) { - const channel = pluginData.guild.channels.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId); if (!channel || !(channel instanceof TextChannel)) continue; await channel.editPermission( userId, diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 0119c0cb..f67fd6a6 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -3,7 +3,7 @@ import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveChannel, waitForReply } from "knub/dist/helpers"; -import { TextChannel, User } from "eris"; + import { resolveUser, UnknownUser } from "../../../utils"; import { changeCounterValue } from "../functions/changeCounterValue"; diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 50fa7483..2bf6e714 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -3,7 +3,7 @@ import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveChannel, waitForReply } from "knub/dist/helpers"; -import { TextChannel, User } from "eris"; + import { confirm, MINUTES, noop, resolveUser, trimMultilineString, UnknownUser } from "../../../utils"; import { changeCounterValue } from "../functions/changeCounterValue"; import { setCounterValue } from "../functions/setCounterValue"; diff --git a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts index 166aea66..ed858a0f 100644 --- a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts @@ -3,7 +3,7 @@ import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveChannel, waitForReply } from "knub/dist/helpers"; -import { TextChannel } from "eris"; + import { resolveUser, UnknownUser } from "../../../utils"; import { setCounterValue } from "../functions/setCounterValue"; diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 9c84e63f..b90bdfb8 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -3,7 +3,7 @@ import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveChannel, waitForReply } from "knub/dist/helpers"; -import { TextChannel, User } from "eris"; + import { resolveUser, UnknownUser } from "../../../utils"; import { changeCounterValue } from "../functions/changeCounterValue"; import { setCounterValue } from "../functions/setCounterValue"; diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index 2a19c9f7..6fed0607 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -3,7 +3,7 @@ import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { resolveChannel, waitForReply } from "knub/dist/helpers"; -import { TextChannel, User } from "eris"; + import { resolveUser, UnknownUser } from "../../../utils"; export const ViewCounterCmd = typedGuildCommand()({ diff --git a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts index 77e28878..1780ba60 100644 --- a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts +++ b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts @@ -5,7 +5,6 @@ import { renderTemplate } from "../../../templateFormatter"; import { resolveMember } from "../../../utils"; import { ActionError } from "../ActionError"; import { canActOn } from "../../../pluginUtils"; -import { Message } from "eris"; export const AddRoleAction = t.type({ type: t.literal("add_role"), diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts index 90ddd45b..d08abfcb 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts @@ -18,7 +18,7 @@ export async function makeRoleMentionableAction( event: TCustomEvent, eventData: any, ) { - const role = pluginData.guild.roles.get(action.role); + const role = pluginData.guild.roles.cache.get(action.role); if (!role) { throw new ActionError(`Unknown role: ${role}`); } diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts index 0ceef330..ea75ff12 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts @@ -16,7 +16,7 @@ export async function makeRoleUnmentionableAction( event: TCustomEvent, eventData: any, ) { - const role = pluginData.guild.roles.get(action.role); + const role = pluginData.guild.roles.cache.get(action.role); if (!role) { throw new ActionError(`Unknown role: ${role}`); } diff --git a/backend/src/plugins/CustomEvents/actions/messageAction.ts b/backend/src/plugins/CustomEvents/actions/messageAction.ts index f137d6b0..bd4e6300 100644 --- a/backend/src/plugins/CustomEvents/actions/messageAction.ts +++ b/backend/src/plugins/CustomEvents/actions/messageAction.ts @@ -3,7 +3,6 @@ import { CustomEventsPluginType } from "../types"; import * as t from "io-ts"; import { renderTemplate } from "../../../templateFormatter"; import { ActionError } from "../ActionError"; -import { TextChannel } from "eris"; export const MessageAction = t.type({ type: t.literal("message"), @@ -18,7 +17,7 @@ export async function messageAction( values: any, ) { const targetChannelId = await renderTemplate(action.channel, values, false); - const targetChannel = pluginData.guild.channels.get(targetChannelId); + const targetChannel = pluginData.guild.channels.cache.get(targetChannelId); if (!targetChannel) throw new ActionError("Unknown target channel"); if (!(targetChannel instanceof TextChannel)) throw new ActionError("Target channel is not a text channel"); diff --git a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts index d138c61d..33636c5c 100644 --- a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts +++ b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts @@ -5,7 +5,6 @@ import { renderTemplate } from "../../../templateFormatter"; import { resolveMember } from "../../../utils"; import { ActionError } from "../ActionError"; import { canActOn } from "../../../pluginUtils"; -import { Message, VoiceChannel } from "eris"; export const MoveToVoiceChannelAction = t.type({ type: t.literal("move_to_vc"), @@ -30,7 +29,7 @@ export async function moveToVoiceChannelAction( } const targetChannelId = await renderTemplate(action.channel, values, false); - const targetChannel = pluginData.guild.channels.get(targetChannelId); + const targetChannel = pluginData.guild.channels.cache.get(targetChannelId); if (!targetChannel) throw new ActionError("Unknown target channel"); if (!(targetChannel instanceof VoiceChannel)) throw new ActionError("Target channel is not a voice channel"); diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index 595a56e2..48114ec0 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -24,7 +24,7 @@ export async function setChannelPermissionOverridesAction( event: TCustomEvent, eventData: any, ) { - const channel = pluginData.guild.channels.get(action.channel); + const channel = pluginData.guild.channels.cache.get(action.channel); if (!channel) { throw new ActionError(`Unknown channel: ${action.channel}`); } diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 3b304ff9..e6e909da 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -2,7 +2,7 @@ import { GuildPluginData } from "knub"; import { CustomEventsPluginType, TCustomEvent } from "../types"; import { sendErrorMessage } from "../../../pluginUtils"; import { ActionError } from "../ActionError"; -import { Message } from "eris"; + import { addRoleAction } from "../actions/addRoleAction"; import { createCaseAction } from "../actions/createCaseAction"; import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction"; diff --git a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts index 62b77c29..5689cd73 100644 --- a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts +++ b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts @@ -2,7 +2,6 @@ import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; import { BasePluginType, typedGlobalEventListener, GlobalPluginData } from "knub"; import * as t from "io-ts"; import { AllowedGuilds } from "../../data/AllowedGuilds"; -import { Guild } from "eris"; interface GuildAccessMonitorPluginType extends BasePluginType { config: {}; diff --git a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts index e426e704..353a2c26 100644 --- a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts +++ b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts @@ -1,6 +1,5 @@ import { locateUserEvt } from "../types"; import { sendAlerts } from "../utils/sendAlerts"; -import { TextableChannel, VoiceChannel } from "eris"; export const ChannelJoinAlertsEvt = locateUserEvt({ event: "voiceChannelJoin", diff --git a/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts b/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts index 9f453e21..8ba7f2e1 100644 --- a/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts +++ b/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts @@ -1,5 +1,3 @@ -import { VoiceChannel } from "eris"; - export async function createOrReuseInvite(vc: VoiceChannel) { const existingInvites = await vc.getInvites(); diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index e3c75b16..6966d10f 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,4 +1,3 @@ -import { Member, TextableChannel } from "eris"; import { GuildPluginData } from "knub"; import { LocateUserPluginType } from "../types"; import { sendErrorMessage } from "../../../pluginUtils"; diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts index df49c3d1..bb47168a 100644 --- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts @@ -2,7 +2,7 @@ import { GuildPluginData } from "knub"; import { LocateUserPluginType } from "../types"; import { resolveMember } from "../../../utils"; import { sendWhere } from "./sendWhere"; -import { TextableChannel } from "eris"; + import { moveMember } from "./moveMember"; export async function sendAlerts(pluginData: GuildPluginData, userId: string) { diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index d6667748..8b9678a7 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -1,4 +1,3 @@ -import { Invite, Member, TextableChannel, VoiceChannel } from "eris"; import { getInviteLink } from "knub/dist/helpers"; import { createOrReuseInvite } from "./createOrReuseInvite"; import { GuildPluginData } from "knub"; @@ -12,7 +11,7 @@ export async function sendWhere( prepend: string, ) { const voice = member.voiceState.channelID - ? (pluginData.guild.channels.get(member.voiceState.channelID) as VoiceChannel) + ? (pluginData.guild.channels.cache.get(member.voiceState.channelID) as VoiceChannel) : null; if (voice == null) { diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 216be6d6..2d2be7b2 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -14,7 +14,6 @@ import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt"; import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts"; import { LogsChannelCreateEvt, LogsChannelDeleteEvt } from "./events/LogsChannelModifyEvts"; import { LogsRoleCreateEvt, LogsRoleDeleteEvt } from "./events/LogsRoleModifyEvts"; -import { LogsVoiceJoinEvt, LogsVoiceLeaveEvt, LogsVoiceSwitchEvt } from "./events/LogsVoiceChannelEvts"; import { log } from "./util/log"; import { LogType } from "../../data/LogType"; import { getLogMessage } from "./util/getLogMessage"; @@ -23,6 +22,7 @@ import { disableCodeBlocks } from "../../utils"; import { logger } from "../../logger"; import { CasesPlugin } from "../Cases/CasesPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts"; const defaultOptions: PluginOptions = { config: { @@ -66,9 +66,7 @@ export const LogsPlugin = zeppelinGuildPlugin()({ LogsChannelDeleteEvt, LogsRoleCreateEvt, LogsRoleDeleteEvt, - LogsVoiceJoinEvt, - LogsVoiceLeaveEvt, - LogsVoiceSwitchEvt, + LogsVoiceStateUpdateEvt, ], public: { diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index 27bbbe87..ef61f5e3 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -1,7 +1,7 @@ import { logsEvt } from "../types"; import { stripObjectToScalars, UnknownUser } from "../../../utils"; import { LogType } from "../../../data/LogType"; -import { Constants as ErisConstants } from "eris"; + import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; export const LogsGuildBanAddEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts index a24d7929..48a85448 100644 --- a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts @@ -3,7 +3,7 @@ import { stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; export const LogsRoleCreateEvt = logsEvt({ - event: "guildRoleCreate", + event: "roleCreate", async listener(meta) { meta.pluginData.state.guildLogs.log(LogType.ROLE_CREATE, { @@ -13,7 +13,7 @@ export const LogsRoleCreateEvt = logsEvt({ }); export const LogsRoleDeleteEvt = logsEvt({ - event: "guildRoleDelete", + event: "roleDelete", async listener(meta) { meta.pluginData.state.guildLogs.log(LogType.ROLE_DELETE, { diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index 46228646..396cbbc8 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -1,6 +1,6 @@ import { logsEvt } from "../types"; import { stripObjectToScalars, UnknownUser } from "../../../utils"; -import { Constants as ErisConstants } from "eris"; + import { LogType } from "../../../data/LogType"; import isEqual from "lodash.isequal"; import diff from "lodash.difference"; @@ -61,11 +61,11 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ { member: logMember, addedRoles: addedRoles - .map(roleId => pluginData.guild.roles.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), removedRoles: removedRoles - .map(roleId => pluginData.guild.roles.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), mod: stripObjectToScalars(mod), @@ -79,7 +79,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ { member: logMember, roles: addedRoles - .map(roleId => pluginData.guild.roles.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), mod: stripObjectToScalars(mod), @@ -93,7 +93,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ { member: logMember, roles: removedRoles - .map(roleId => pluginData.guild.roles.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), mod: stripObjectToScalars(mod), diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index a1899d5c..55d115ec 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -1,7 +1,7 @@ import { logsEvt } from "../types"; import { stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; - +/** Merge into single event export const LogsVoiceJoinEvt = logsEvt({ event: "voiceChannelJoin", @@ -35,3 +35,12 @@ export const LogsVoiceSwitchEvt = logsEvt({ }); }, }); +**/ + +export const LogsVoiceStateUpdateEvt = logsEvt({ + event: "voiceStateUpdate", + + async listener(meta) { + console.error(`Fixme @LogsVoiceChannelEvts.ts`); + }, +}); diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts index d107b7ef..89542467 100644 --- a/backend/src/plugins/Logs/util/getLogMessage.ts +++ b/backend/src/plugins/Logs/util/getLogMessage.ts @@ -14,7 +14,6 @@ import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { logger } from "../../../logger"; import moment from "moment-timezone"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { MessageContent } from "eris"; export async function getLogMessage( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 6072284e..8e4840aa 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { LogsPluginType, TLogChannelMap } from "../types"; import { LogType } from "../../../data/LogType"; -import { TextChannel } from "eris"; + import { createChunkedMessage, get, noop } from "../../../utils"; import { getLogMessage } from "./getLogMessage"; import { allowTimeout } from "../../../RegExpRunner"; @@ -19,7 +19,7 @@ export async function log(pluginData: GuildPluginData, type: Log const typeStr = LogType[type]; logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) { - const channel = pluginData.guild.channels.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId); if (!channel || !(channel instanceof TextChannel)) continue; if ((opts.include && opts.include.includes(typeStr)) || (opts.exclude && !opts.exclude.includes(typeStr))) { @@ -45,7 +45,7 @@ export async function log(pluginData: GuildPluginData, type: Log if (opts.excluded_roles) { for (const value of Object.values(data || {})) { if (value instanceof SavedMessage) { - const member = pluginData.guild.members.get(value.user_id); + const member = pluginData.guild.members.cache.get(value.user_id); for (const role of member?.roles || []) { if (opts.excluded_roles.includes(role)) { continue logChannelLoop; diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index 3319f4f2..eae416fd 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -1,5 +1,5 @@ import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { Attachment } from "eris"; + import { useMediaUrls, stripObjectToScalars, resolveUser } from "../../../utils"; import { LogType } from "../../../data/LogType"; import moment from "moment-timezone"; @@ -9,7 +9,7 @@ import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.get(savedMessage.channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); if (user) { // Replace attachment URLs with media URLs diff --git a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts index f7b7e571..d0fac9c5 100644 --- a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts @@ -5,7 +5,7 @@ import { LogType } from "../../../data/LogType"; import { getBaseUrl } from "../../../pluginUtils"; export async function onMessageDeleteBulk(pluginData: GuildPluginData, savedMessages: SavedMessage[]) { - const channel = pluginData.guild.channels.get(savedMessages[0].channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessages[0].channel_id); const archiveId = await pluginData.state.archives.createFromSavedMessages(savedMessages, pluginData.guild); const archiveUrl = pluginData.state.archives.getUrl(getBaseUrl(pluginData), archiveId); const authorIds = Array.from(new Set(savedMessages.map(item => `\`${item.user_id}\``))).join(", "); diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index 91eb7abb..87f204a4 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { LogsPluginType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { Embed } from "eris"; + import { LogType } from "../../../data/LogType"; import { stripObjectToScalars, resolveUser } from "../../../utils"; import cloneDeep from "lodash.clonedeep"; @@ -47,7 +47,7 @@ export async function onMessageUpdate( } const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.get(savedMessage.channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); pluginData.state.guildLogs.log(LogType.MESSAGE_EDIT, { user: stripObjectToScalars(user), diff --git a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts index 00d83fcd..51e34ff1 100644 --- a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts +++ b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts @@ -1,8 +1,7 @@ import { messageSaverEvt } from "../types"; -import { Message } from "eris"; export const MessageCreateEvt = messageSaverEvt({ - event: "messageCreate", + event: "message", allowBots: true, allowSelf: true, diff --git a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts index 13217074..8e1635b9 100644 --- a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts @@ -1,6 +1,5 @@ import { MessageSaverPluginType } from "./types"; import { GuildPluginData } from "knub"; -import { Message, TextChannel } from "eris"; export async function saveMessagesToDB( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index f78f7c37..499f8176 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -30,7 +30,7 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { ForceUnmuteCmd } from "./commands/ForceunmuteCmd"; import { warnMember } from "./functions/warnMember"; -import { Member, Message } from "eris"; + import { kickMember } from "./functions/kickMember"; import { banUserId } from "./functions/banUserId"; import { MassmuteCmd } from "./commands/MassmuteCmd"; diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index f9f4667d..8a4d7d79 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -4,7 +4,7 @@ import { sendErrorMessage } from "../../../pluginUtils"; import { trimLines, createChunkedMessage, emptyEmbedValue, sorter, resolveUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { asyncMap } from "../../../utils/async"; -import { EmbedOptions, User } from "eris"; + import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index b3da7899..8cfade7a 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -12,7 +12,7 @@ import { chunkArray, } from "../../../utils"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; -import { EmbedOptions, User } from "eris"; + import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { asyncMap } from "../../../utils/async"; import { CaseTypes } from "../../../data/CaseTypes"; diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 519f3a28..1756b2b7 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -3,7 +3,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { helpers } from "knub"; import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { TextChannel } from "eris"; + import { SECONDS, stripObjectToScalars, trimLines } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 93fa7f9c..73b93174 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -7,7 +7,7 @@ import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromA import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { banUserId } from "../functions/banUserId"; import { CaseTypes } from "../../../data/CaseTypes"; -import { TextChannel } from "eris"; + import { waitForReply } from "knub/dist/helpers"; import { ignoreEvent } from "../functions/ignoreEvent"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; @@ -46,7 +46,7 @@ export const MassbanCmd = modActionsCmd({ // Verify we can act on each of the users specified for (const userId of args.userIds) { - const member = pluginData.guild.members.get(userId); // TODO: Get members on demand? + const member = pluginData.guild.members.cache.get(userId); // TODO: Get members on demand? if (member && !canActOn(pluginData, msg.member, member)) { sendErrorMessage(pluginData, msg.channel, "Cannot massban one or more users: insufficient permissions"); return; diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index e11289c8..ac0b3f39 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -5,7 +5,7 @@ import { stripObjectToScalars } from "../../../utils"; import { isBanned } from "../functions/isBanned"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { CaseTypes } from "../../../data/CaseTypes"; -import { TextChannel } from "eris"; + import { waitForReply } from "knub/dist/helpers"; import { ignoreEvent } from "../functions/ignoreEvent"; import { CasesPlugin } from "../../Cases/CasesPlugin"; diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index 73e329d0..eeceabd3 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -3,7 +3,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { stripObjectToScalars } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { TextChannel } from "eris"; + import { waitForReply } from "knub/dist/helpers"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; @@ -43,7 +43,7 @@ export const MassmuteCmd = modActionsCmd({ // Verify we can act upon all users for (const userId of args.userIds) { - const member = pluginData.guild.members.get(userId); + const member = pluginData.guild.members.cache.get(userId); if (member && !canActOn(pluginData, msg.member, member)) { sendErrorMessage(pluginData, msg.channel, "Cannot massmute one or more users: insufficient permissions"); return; diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/MuteCmd.ts index 3aa96c38..c8336aae 100644 --- a/backend/src/plugins/ModActions/commands/MuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MuteCmd.ts @@ -11,7 +11,7 @@ import { isBanned } from "../functions/isBanned"; import { waitForReaction } from "knub/dist/helpers"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; import { warnMember } from "../functions/warnMember"; -import { TextChannel } from "eris"; + import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; const opts = { diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index 7fc92b49..22e4e660 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -11,7 +11,6 @@ import { isBanned } from "../functions/isBanned"; import { waitForReaction } from "knub/dist/helpers"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; import { warnMember } from "../functions/warnMember"; -import { TextChannel } from "eris"; export const WarnCmd = modActionsCmd({ trigger: "warn", diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index c3b10cdc..1d206a7c 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -1,7 +1,7 @@ import { IgnoredEventType, modActionsEvt } from "../types"; import { isEventIgnored } from "../functions/isEventIgnored"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; -import { Constants as ErisConstants, User } from "eris"; + import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index 65cb7636..07d9f01f 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -1,7 +1,7 @@ import { IgnoredEventType, modActionsEvt } from "../types"; import { isEventIgnored } from "../functions/isEventIgnored"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; -import { Constants as ErisConstants, User } from "eris"; + import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { logger } from "../../../logger"; diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index 52d132f3..00d21ab2 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -1,7 +1,7 @@ import { IgnoredEventType, modActionsEvt } from "../types"; import { isEventIgnored } from "../functions/isEventIgnored"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; -import { Constants as ErisConstants, User } from "eris"; + import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index 00b4110e..cef6c2e5 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -1,7 +1,7 @@ import { modActionsEvt } from "../types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; -import { Constants, TextChannel } from "eris"; + import { resolveMember } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; @@ -22,7 +22,7 @@ export const PostAlertOnMemberJoinEvt = modActionsEvt({ const logs = pluginData.getPlugin(LogsPlugin); if (actions.length) { - const alertChannel = pluginData.guild.channels.get(alertChannelId); + const alertChannel = pluginData.guild.channels.cache.get(alertChannelId); if (!alertChannel) { logs.log(LogType.BOT_ALERT, { body: `Unknown \`alert_channel\` configured for \`mod_actions\`: \`${alertChannelId}\``, @@ -37,8 +37,8 @@ export const PostAlertOnMemberJoinEvt = modActionsEvt({ return; } - const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user.id); - const botPerms = alertChannel.permissionsOf(botMember ?? pluginData.client.user.id); + const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user!.id); + const botPerms = alertChannel.permissionsOf(botMember ?? pluginData.client.user!.id); if (!hasDiscordPermissions(botPerms, Constants.Permissions.sendMessages)) { logs.log(LogType.BOT_ALERT, { body: `Missing "Send Messages" permissions for the \`alert_channel\` configured in \`mod_actions\`: \`${alertChannelId}\``, diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index bac7fa0a..906cc375 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -1,4 +1,3 @@ -import { Member, TextChannel } from "eris"; import { LogType } from "../../../data/LogType"; import { IgnoredEventType, ModActionsPluginType } from "../types"; import { errorMessage, resolveUser, resolveMember } from "../../../utils"; diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index aa5310b7..bbf2ac99 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -1,4 +1,3 @@ -import { GuildTextableChannel, Member, Message, TextChannel, User } from "eris"; import { asSingleLine, isDiscordRESTError, UnknownUser } from "../../../utils"; import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { GuildPluginData } from "knub"; diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts index 41a8b1a1..badfccd5 100644 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { ModActionsPluginType } from "../types"; -import { User, Message, Member } from "eris"; + import { UnknownUser, asSingleLine } from "../../../utils"; import { sendErrorMessage, sendSuccessMessage, hasPermission } from "../../../pluginUtils"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index 709ba994..f259dca9 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -8,7 +8,7 @@ import { ucfirst, UserNotificationResult, } from "../../../utils"; -import { DiscordRESTError, User } from "eris"; + import { renderTemplate } from "../../../templateFormatter"; import { getDefaultContactMethods } from "./getDefaultContactMethods"; import { LogType } from "../../../data/LogType"; @@ -99,7 +99,7 @@ export async function banUserId( const existingTempban = await pluginData.state.tempbans.findExistingTempbanForUserId(user.id); if (banTime && banTime > 0) { - const selfId = pluginData.client.user.id; + const selfId = pluginData.client.user!.id; if (existingTempban) { pluginData.state.tempbans.updateExpiryTime(user.id, banTime, banOptions.modId ?? selfId); } else { @@ -108,7 +108,7 @@ export async function banUserId( } // Create a case for this action - const modId = banOptions.caseArgs?.modId || pluginData.client.user.id; + const modId = banOptions.caseArgs?.modId || pluginData.client.user!.id; const casesPlugin = pluginData.getPlugin(CasesPlugin); const noteDetails: string[] = []; diff --git a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts index d8a6b4e4..abf820c6 100644 --- a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts +++ b/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts @@ -1,5 +1,3 @@ -import { Attachment } from "eris"; - export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) { const attachmentUrls = attachments.map(a => a.url); return ((reason || "") + " " + attachmentUrls.join(" ")).trim(); diff --git a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts index 4ebc4d8d..1d2484c3 100644 --- a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts +++ b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts @@ -1,7 +1,6 @@ import { GuildPluginData } from "knub"; import { ModActionsPluginType } from "../types"; import { UserNotificationMethod } from "../../../utils"; -import { TextChannel } from "eris"; export function getDefaultContactMethods( pluginData: GuildPluginData, @@ -15,7 +14,7 @@ export function getDefaultContactMethods( } if (config[`message_on_${type}`] && config.message_channel) { - const channel = pluginData.guild.channels.get(config.message_channel); + const channel = pluginData.guild.channels.cache.get(config.message_channel); if (channel instanceof TextChannel) { methods.push({ type: "channel", diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index 7bcd22d8..bac97e91 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -4,14 +4,13 @@ import { isDiscordHTTPError, isDiscordRESTError, SECONDS, sleep } from "../../.. import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { Constants } from "eris"; export async function isBanned( pluginData: GuildPluginData, userId: string, timeout: number = 5 * SECONDS, ): Promise { - const botMember = pluginData.guild.members.get(pluginData.client.user.id); + const botMember = pluginData.guild.members.cache.get(pluginData.client.user!.id); if (botMember && !hasDiscordPermissions(botMember.permissions, Constants.Permissions.banMembers)) { pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, { body: `Missing "Ban Members" permission to check for existing bans`, diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index b682018e..eaaa2f69 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types"; -import { Member } from "eris"; + import { createUserNotificationError, notifyUser, @@ -63,7 +63,7 @@ export async function kickMember( }; } - const modId = kickOptions.caseArgs?.modId || pluginData.client.user.id; + const modId = kickOptions.caseArgs?.modId || pluginData.client.user!.id; // Create a case for this action const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts index c5bc7009..93ae0882 100644 --- a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts +++ b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts @@ -1,4 +1,3 @@ -import { TextChannel } from "eris"; import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; export function readContactMethodsFromArgs(args: { diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index 12257269..02b5fab6 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -1,4 +1,3 @@ -import { Message } from "eris"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index d61b183d..74d65640 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { ModActionsPluginType, WarnOptions, WarnResult } from "../types"; -import { Member } from "eris"; + import { getDefaultContactMethods } from "./getDefaultContactMethods"; import { createUserNotificationError, @@ -62,7 +62,7 @@ export async function warnMember( } } - const modId = warnOptions.caseArgs?.modId ?? pluginData.client.user.id; + const modId = warnOptions.caseArgs?.modId ?? pluginData.client.user!.id; const casesPlugin = pluginData.getPlugin(CasesPlugin); const createdCase = await casesPlugin.createCase({ diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index 61568a78..3ebeacec 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -6,7 +6,7 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { Case } from "../../data/entities/Case"; import { CaseArgs } from "../Cases/types"; -import { TextChannel } from "eris"; + import { GuildTempbans } from "../../data/GuildTempbans"; import Timeout = NodeJS.Timeout; import { EventEmitter } from "events"; diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index 05671350..5e8c0045 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -13,7 +13,7 @@ import { ClearMutesWithoutRoleCmd } from "./commands/ClearMutesWithoutRoleCmd"; import { ClearMutesCmd } from "./commands/ClearMutesCmd"; import { muteUser } from "./functions/muteUser"; import { unmuteUser } from "./functions/unmuteUser"; -import { Member } from "eris"; + import { ClearActiveMuteOnMemberBanEvt } from "./events/ClearActiveMuteOnMemberBanEvt"; import { ReapplyActiveMuteOnJoinEvt } from "./events/ReapplyActiveMuteOnJoinEvt"; import { mapToPublicFn } from "../../pluginUtils"; diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index b59f1165..37f78f6f 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,5 +1,5 @@ import { mutesCmd } from "../types"; -import { User } from "eris"; + import { sendSuccessMessage } from "../../../pluginUtils"; export const ClearBannedMutesCmd = mutesCmd({ diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 9636141a..7e52589a 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -4,7 +4,6 @@ import { DBDateFormat, isFullMessage, MINUTES, noop, resolveMember } from "../.. import moment from "moment-timezone"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { getBaseUrl } from "../../../pluginUtils"; -import { Member } from "eris"; export const MutesCmd = mutesCmd({ trigger: "mutes", @@ -112,7 +111,7 @@ export const MutesCmd = mutesCmd({ const muteCasesById = muteCases.reduce((map, c) => map.set(c.id, c), new Map()); lines = filteredMutes.map(mute => { - const user = pluginData.client.users.get(mute.user_id); + const user = pluginData.client.user!.get(mute.user_id); const username = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; const theCase = muteCasesById.get(mute.case_id); const caseName = theCase ? `Case #${theCase.case_number}` : "No case"; diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index 60395d02..65bd2b72 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -2,7 +2,7 @@ import { GuildPluginData } from "knub"; import { MutesPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { resolveMember, stripObjectToScalars, UnknownUser } from "../../../utils"; -import { MemberOptions } from "eris"; + import { memberRolesLock } from "../../../utils/lockNameHelpers"; export async function clearExpiredMutes(pluginData: GuildPluginData) { diff --git a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts index 21a3bf88..8b296f19 100644 --- a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts +++ b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts @@ -1,4 +1,3 @@ -import { Member } from "eris"; import { GuildPluginData } from "knub"; import { MutesPluginType } from "../types"; diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 046568b2..16ef5479 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -12,7 +12,7 @@ import { UserNotificationMethod, } from "../../../utils"; import { renderTemplate } from "../../../templateFormatter"; -import { MemberOptions, TextChannel, User } from "eris"; + import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; @@ -42,7 +42,7 @@ export async function muteUser( // No mod specified -> mark Zeppelin as the mod if (!muteOptions.caseArgs?.modId) { muteOptions.caseArgs = muteOptions.caseArgs ?? {}; - muteOptions.caseArgs.modId = pluginData.client.user.id; + muteOptions.caseArgs.modId = pluginData.client.user!.id; } const user = await resolveUser(pluginData.client, userId); @@ -99,7 +99,7 @@ export async function muteUser( throw new RecoverablePluginError(ERRORS.INVALID_MUTE_ROLE_ID); } - const zep = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user.id); + const zep = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user!.id); const zepRoles = pluginData.guild.roles.filter(x => zep!.roles.includes(x.id)); // If we have roles and one of them is above the muted role, throw generic error if (zepRoles.length >= 0 && zepRoles.some(zepRole => zepRole.position > actualMuteRole.position)) { @@ -172,7 +172,7 @@ export async function muteUser( } const useChannel = existingMute ? config.message_on_update : config.message_on_mute; - const channel = config.message_channel && pluginData.guild.channels.get(config.message_channel); + const channel = config.message_channel && pluginData.guild.channels.cache.get(config.message_channel); if (useChannel && channel instanceof TextChannel) { contactMethods.push({ type: "channel", channel }); } diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index 53b7cabe..c71096be 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -7,7 +7,7 @@ import humanizeDuration from "humanize-duration"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; -import { MemberOptions } from "eris"; + import { memberRolesLock } from "../../../utils/lockNameHelpers"; export async function unmuteUser( @@ -19,7 +19,7 @@ export async function unmuteUser( const existingMute = await pluginData.state.mutes.findExistingMuteForUserId(userId); const user = await resolveUser(pluginData.client, userId); const member = await resolveMember(pluginData.client, pluginData.guild, userId); // Grab the fresh member so we don't have stale role info - const modId = caseArgs.modId || pluginData.client.user.id; + const modId = caseArgs.modId || pluginData.client.user!.id; if (!existingMute && member && !memberHasMutedRole(pluginData, member)) return null; @@ -85,7 +85,7 @@ export async function unmuteUser( }); // Log the action - const mod = pluginData.client.users.get(modId); + const mod = pluginData.client.user!.get(modId); if (unmuteTime) { pluginData.state.serverLogs.log(LogType.MEMBER_TIMED_UNMUTE, { mod: stripObjectToScalars(mod), diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index cb0a6820..e87e8a6e 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils"; import { Mute } from "../../data/entities/Mute"; -import { Member } from "eris"; + import { Case } from "../../data/entities/Case"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index 78456820..c47f1912 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -29,7 +29,7 @@ export const NamesCmd = nameHistoryCmd({ ); const usernameRows = usernames.map(r => `\`[${r.timestamp}]\` **${disableCodeBlocks(r.username)}**`); - const user = pluginData.client.users.get(args.userId); + const user = pluginData.client.user!.get(args.userId); const currentUsername = user ? `${user.username}#${user.discriminator}` : args.userId; const nicknameDays = Math.round(NICKNAME_RETENTION_PERIOD / DAYS); diff --git a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts index dc3d451b..66947b22 100644 --- a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts +++ b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts @@ -10,7 +10,7 @@ export const ChannelJoinEvt = nameHistoryEvt({ }); export const MessageCreateEvt = nameHistoryEvt({ - event: "messageCreate", + event: "message", async listener(meta) { meta.pluginData.state.updateQueue.add(() => updateNickname(meta.pluginData, meta.args.message.member!)); diff --git a/backend/src/plugins/NameHistory/updateNickname.ts b/backend/src/plugins/NameHistory/updateNickname.ts index 2ac8471f..290ac4d1 100644 --- a/backend/src/plugins/NameHistory/updateNickname.ts +++ b/backend/src/plugins/NameHistory/updateNickname.ts @@ -1,4 +1,3 @@ -import { Member } from "eris"; import { GuildPluginData } from "knub"; import { NameHistoryPluginType } from "./types"; diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index cef12dbf..76cf5366 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -1,5 +1,5 @@ import { persistEvt } from "../types"; -import { Constants, MemberOptions } from "eris"; + import intersection from "lodash.intersection"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars } from "../../../utils"; @@ -31,7 +31,7 @@ export const LoadDataEvt = persistEvt({ const restoredData: string[] = []; // Check permissions - const me = pluginData.guild.members.get(pluginData.client.user.id)!; + const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; let requiredPermissions = 0n; if (config.persist_nicknames) requiredPermissions |= p.manageNicknames; if (config.persisted_roles) requiredPermissions |= p.manageRoles; diff --git a/backend/src/plugins/Persist/events/StoreDataEvt.ts b/backend/src/plugins/Persist/events/StoreDataEvt.ts index 66d2c79e..2b9ded49 100644 --- a/backend/src/plugins/Persist/events/StoreDataEvt.ts +++ b/backend/src/plugins/Persist/events/StoreDataEvt.ts @@ -1,6 +1,6 @@ import { persistEvt } from "../types"; import { IPartialPersistData } from "../../../data/GuildPersistedData"; -import { Member } from "eris"; + import intersection from "lodash.intersection"; export const StoreDataEvt = persistEvt({ diff --git a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts index 82afa7f2..5efbba02 100644 --- a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts +++ b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts @@ -29,7 +29,7 @@ export const TypingEnablePingableEvt = pingableRolesEvt({ }); export const MessageCreateDisablePingableEvt = pingableRolesEvt({ - event: "messageCreate", + event: "message", async listener(meta) { const pluginData = meta.pluginData; diff --git a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts index f4d735b1..21e96189 100644 --- a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts @@ -7,7 +7,7 @@ export function disablePingableRoles( pingableRoles: PingableRole[], ) { for (const pingableRole of pingableRoles) { - const role = pluginData.guild.roles.get(pingableRole.role_id); + const role = pluginData.guild.roles.cache.get(pingableRole.role_id); if (!role) continue; role.edit( diff --git a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts index f4ab93c9..972495e3 100644 --- a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts @@ -7,7 +7,7 @@ export function enablePingableRoles( pingableRoles: PingableRole[], ) { for (const pingableRole of pingableRoles) { - const role = pluginData.guild.roles.get(pingableRole.role_id); + const role = pluginData.guild.roles.cache.get(pingableRole.role_id); if (!role) continue; role.edit( diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index 64f471e2..9cac7d16 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -19,7 +19,7 @@ export const EditCmd = postCmd({ return; } - if (savedMessage.user_id !== pluginData.client.user.id) { + if (savedMessage.user_id !== pluginData.client.user!.id) { sendErrorMessage(pluginData, msg.channel, "Message wasn't posted by me"); return; } diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index edd1a49c..64ec7e81 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -1,7 +1,7 @@ import { postCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { Embed } from "eris"; + import { trimLines } from "../../../utils"; import { formatContent } from "../util/formatContent"; import { parseColor } from "../../../utils/parseColor"; diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index 324effdd..5868f2b8 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -2,7 +2,7 @@ import { postCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { actualPostCmd } from "../util/actualPostCmd"; import { sendErrorMessage } from "../../../pluginUtils"; -import { Embed } from "eris"; + import { isValidEmbed, trimLines } from "../../../utils"; import { formatContent } from "../util/formatContent"; import { parseColor } from "../../../utils/parseColor"; diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index 25ecdede..6501f835 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -3,7 +3,6 @@ import { sorter } from "../../../utils"; import { sendErrorMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { postMessage } from "../util/postMessage"; -import { TextChannel } from "eris"; export const ScheduledPostsShowCmd = postCmd({ trigger: ["scheduled_posts", "scheduled_posts show"], diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index b8c8cbc8..2adddad2 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -1,4 +1,3 @@ -import { Message, Channel, TextChannel } from "eris"; import { StrictMessageContent, errorMessage, stripObjectToScalars, MINUTES, DBDateFormat } from "../../../utils"; import moment from "moment-timezone"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index 97726869..fc31b063 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { PostPluginType } from "../types"; -import { Attachment, Message, MessageContent, TextChannel } from "eris"; + import { downloadFile } from "../../../utils"; import fs from "fs"; import { formatContent } from "./formatContent"; diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts index 08ebd516..ac2f2519 100644 --- a/backend/src/plugins/Post/util/scheduledPostLoop.ts +++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts @@ -4,7 +4,7 @@ import { logger } from "../../../logger"; import { stripObjectToScalars, SECONDS, DBDateFormat } from "../../../utils"; import { LogType } from "../../../data/LogType"; import moment from "moment-timezone"; -import { TextChannel, User } from "eris"; + import { postMessage } from "./postMessage"; const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS; @@ -12,10 +12,10 @@ const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS; export async function scheduledPostLoop(pluginData: GuildPluginData) { const duePosts = await pluginData.state.scheduledPosts.getDueScheduledPosts(); for (const post of duePosts) { - const channel = pluginData.guild.channels.get(post.channel_id); + const channel = pluginData.guild.channels.cache.get(post.channel_id); if (channel instanceof TextChannel) { const [username, discriminator] = post.author_name.split("#"); - const author: Partial = pluginData.client.users.get(post.author_id) || { + const author: Partial = pluginData.client.user!.get(post.author_id) || { id: post.author_id, username, discriminator, diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index b5f78fe7..828ba54e 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -1,7 +1,7 @@ import { reactionRolesCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { Message, TextChannel } from "eris"; + import { isDiscordRESTError } from "../../../utils"; export const ClearReactionRolesCmd = reactionRolesCmd({ diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 119b7b27..8518518f 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -1,7 +1,7 @@ import { reactionRolesCmd, TReactionRolePair } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { TextChannel } from "eris"; + import { RecoverablePluginError, ERRORS } from "../../../RecoverablePluginError"; import { canUseEmoji, isDiscordRESTError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; diff --git a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts index b93c9456..63fef94f 100644 --- a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts @@ -1,7 +1,7 @@ import { reactionRolesEvt } from "../types"; import { noop, resolveMember, sleep } from "../../../utils"; import { addMemberPendingRoleChange } from "../util/addMemberPendingRoleChange"; -import { DiscordRESTError, Message } from "eris"; + import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; @@ -16,7 +16,7 @@ export const AddReactionRoleEvt = reactionRolesEvt({ const emoji = meta.args.emoji; const userId = meta.args.member.id; - if (userId === pluginData.client.user.id) { + if (userId === pluginData.client.user!.id) { // Don't act on own reactions // FIXME: This may not be needed? Knub currently requires the *member* to be found for the user to be resolved as well. Need to look into it more. return; diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index 7de45269..63421863 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { ReactionRolesPluginType } from "../types"; import { ReactionRole } from "../../../data/entities/ReactionRole"; -import { TextChannel } from "eris"; + import { isDiscordRESTError, sleep, isSnowflake } from "../../../utils"; import { logger } from "../../../logger"; import { LogsPlugin } from "../../Logs/LogsPlugin"; @@ -18,7 +18,7 @@ export async function applyReactionRoleReactionsToMessage( messageId: string, reactionRoles: ReactionRole[], ): Promise { - const channel = pluginData.guild.channels.get(channelId) as TextChannel; + const channel = pluginData.guild.channels.cache.get(channelId) as TextChannel; if (!channel) return; const errors: string[] = []; diff --git a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts index 36c2fb5e..d0c4765d 100644 --- a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts +++ b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts @@ -1,4 +1,3 @@ -import { TextChannel } from "eris"; import { GuildPluginData } from "knub"; import { RemindersPluginType } from "../types"; import moment from "moment-timezone"; @@ -12,7 +11,7 @@ const MAX_TRIES = 3; export async function postDueRemindersLoop(pluginData: GuildPluginData) { const pendingReminders = await pluginData.state.reminders.getDueReminders(); for (const reminder of pendingReminders) { - const channel = pluginData.guild.channels.get(reminder.channel_id); + const channel = pluginData.guild.channels.cache.get(reminder.channel_id); if (channel && channel instanceof TextChannel) { try { // Only show created at date if one exists diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index 49a69b08..e49b6d7f 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -3,7 +3,6 @@ import { sendErrorMessage, sendSuccessMessage, canActOn } from "../../../pluginU import { rolesCmd } from "../types"; import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; import { LogType } from "../../../data/LogType"; -import { GuildChannel } from "eris"; export const AddRoleCmd = rolesCmd({ trigger: "addrole", diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index d709edde..32b953a7 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -4,7 +4,6 @@ import { rolesCmd } from "../types"; import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { Member } from "eris"; export const MassAddRoleCmd = rolesCmd({ trigger: "massaddrole", @@ -49,7 +48,7 @@ export const MassAddRoleCmd = rolesCmd({ return; } - const role = pluginData.guild.roles.get(roleId); + const role = pluginData.guild.roles.cache.get(roleId); if (!role) { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Unknown role configured for 'roles' plugin: ${roleId}`, diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index 8253b4ed..b9d085f1 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -4,7 +4,6 @@ import { rolesCmd } from "../types"; import { resolveMember, stripObjectToScalars, successMessage, resolveRoleId } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { Member } from "eris"; export const MassRemoveRoleCmd = rolesCmd({ trigger: "massremoverole", @@ -49,7 +48,7 @@ export const MassRemoveRoleCmd = rolesCmd({ return; } - const role = pluginData.guild.roles.get(roleId); + const role = pluginData.guild.roles.cache.get(roleId); if (!role) { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Unknown role configured for 'roles' plugin: ${roleId}`, diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index 107b88e4..12f5b640 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage, canActOn } from "../../../pluginUtils"; import { rolesCmd } from "../types"; -import { GuildChannel } from "eris"; + import { LogType } from "../../../data/LogType"; import { stripObjectToScalars, verboseUserMention, resolveRoleId } from "../../../utils"; diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index 34c660a7..3f165e4e 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -5,7 +5,7 @@ import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { splitRoleNames } from "../util/splitRoleNames"; import { normalizeRoleNames } from "../util/normalizeRoleNames"; import { findMatchingRoles } from "../util/findMatchingRoles"; -import { Role } from "eris"; + import { memberRolesLock } from "../../../utils/lockNameHelpers"; export const RoleAddCmd = selfGrantableRolesCmd({ @@ -31,7 +31,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ const hasUnknownRoles = matchedRoleIds.length !== roleNames.length; const rolesToAdd: Map = Array.from(matchedRoleIds.values()) - .map(id => pluginData.guild.roles.get(id)!) + .map(id => pluginData.guild.roles.cache.get(id)!) .filter(Boolean) .reduce((map, role) => { map.set(role.id, role); @@ -69,9 +69,9 @@ export const RoleAddCmd = selfGrantableRolesCmd({ rolesToAdd.delete(roleId); if (msg.member.roles.includes(roleId)) { - removed.add(pluginData.guild.roles.get(roleId)!); + removed.add(pluginData.guild.roles.cache.get(roleId)!); } else { - skipped.add(pluginData.guild.roles.get(roleId)!); + skipped.add(pluginData.guild.roles.cache.get(roleId)!); } } } diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index 3462d86f..ba4240f6 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -27,7 +27,7 @@ export const RoleRemoveCmd = selfGrantableRolesCmd({ const roleNames = normalizeRoleNames(splitRoleNames(args.roleNames)); const matchedRoleIds = findMatchingRoles(roleNames, applyingEntries); - const rolesToRemove = Array.from(matchedRoleIds.values()).map(id => pluginData.guild.roles.get(id)!); + const rolesToRemove = Array.from(matchedRoleIds.values()).map(id => pluginData.guild.roles.cache.get(id)!); const roleIdsToRemove = rolesToRemove.map(r => r.id); // Remove the roles diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index c650cd8c..f8da441e 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -25,7 +25,7 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } - const me = pluginData.guild.members.get(pluginData.client.user.id)!; + const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_CLEAR_PERMISSIONS); if (missingPermissions) { sendErrorMessage( diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts index e9ffe108..567a2da9 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { slowmodeCmd } from "../types"; -import { TextChannel } from "eris"; + import humanizeDuration from "humanize-duration"; export const SlowmodeGetCmd = slowmodeCmd({ diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts index 136ff277..7571b358 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts @@ -1,5 +1,5 @@ import { slowmodeCmd } from "../types"; -import { GuildChannel, TextChannel } from "eris"; + import { createChunkedMessage } from "knub/dist/helpers"; import { errorMessage } from "../../../utils"; import humanizeDuration from "humanize-duration"; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 7039b7e7..aeebeb35 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { slowmodeCmd } from "../types"; -import { TextChannel } from "eris"; + import humanizeDuration from "humanize-duration"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { asSingleLine, DAYS, disableInlineCode, HOURS, MINUTES } from "../../../utils"; @@ -84,7 +84,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ } // Verify permissions - const channelPermissions = channel.permissionsOf(pluginData.client.user.id); + const channelPermissions = channel.permissionsOf(pluginData.client.user!.id); if (mode === "native") { const missingPermissions = getMissingPermissions(channelPermissions, NATIVE_SLOWMODE_PERMISSIONS); diff --git a/backend/src/plugins/Slowmode/requiredPermissions.ts b/backend/src/plugins/Slowmode/requiredPermissions.ts index 7b1b52f5..bee1a4bc 100644 --- a/backend/src/plugins/Slowmode/requiredPermissions.ts +++ b/backend/src/plugins/Slowmode/requiredPermissions.ts @@ -1,5 +1,3 @@ -import { Constants } from "eris"; - const p = Constants.Permissions; export const NATIVE_SLOWMODE_PERMISSIONS = p.readMessages | p.manageChannels; diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index cd29bc08..41e5660e 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -1,4 +1,3 @@ -import { Message } from "eris"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel"; import { noop } from "../../../utils"; @@ -15,7 +14,7 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { return; } - const me = pluginData.guild.members.get(pluginData.client.user.id); + const me = pluginData.guild.members.cache.get(pluginData.client.user!.id); const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_DISABLE_PERMISSIONS); if (missingPermissions) { sendErrorMessage( diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 356f0bdb..775a29a3 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -1,6 +1,6 @@ import { SlowmodePluginType } from "../types"; import { GuildPluginData } from "knub"; -import { Constants, GuildChannel, TextChannel } from "eris"; + import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; @@ -18,7 +18,7 @@ export async function applyBotSlowmodeToUserId( try { await channel.editPermission(userId, newAllowedPermissions, newDeniedPermissions, "member"); } catch (e) { - const user = pluginData.client.users.get(userId) || new UnknownUser({ id: userId }); + const user = pluginData.client.user!.get(userId) || new UnknownUser({ id: userId }); if (isDiscordRESTError(e) && e.code === 50013) { logger.warn( diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index 7a33d4aa..c44e1754 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,6 +1,5 @@ import { GuildPluginData } from "knub"; import { SlowmodePluginType } from "../types"; -import { GuildChannel, TextChannel } from "eris"; export async function clearBotSlowmodeFromUserId( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index 5bf650c2..51764846 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -2,14 +2,14 @@ import { GuildPluginData } from "knub"; import { SlowmodePluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { GuildChannel, TextChannel } from "eris"; + import { stripObjectToScalars, UnknownUser } from "../../../utils"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; export async function clearExpiredSlowmodes(pluginData: GuildPluginData) { const expiredSlowmodeUsers = await pluginData.state.slowmodes.getExpiredSlowmodeUsers(); for (const user of expiredSlowmodeUsers) { - const channel = pluginData.guild.channels.get(user.channel_id); + const channel = pluginData.guild.channels.cache.get(user.channel_id); if (!channel) { await pluginData.state.slowmodes.clearSlowmodeUser(user.channel_id, user.user_id); continue; @@ -20,7 +20,7 @@ export async function clearExpiredSlowmodes(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; - const channel = pluginData.guild.channels.get(msg.channel_id) as TextChannel; + const channel = pluginData.guild.channels.cache.get(msg.channel_id) as TextChannel; if (!channel) return; // Don't apply slowmode if the lock was interrupted earlier (e.g. the message was caught by word filters) @@ -36,7 +36,7 @@ export async function onMessageCreate(pluginData: GuildPluginData, savedMessage: SavedMessage) { - const member = pluginData.guild.members.get(savedMessage.user_id); + const member = pluginData.guild.members.cache.get(savedMessage.user_id); const config = await pluginData.config.getMatchingConfig({ userId: savedMessage.user_id, channelId: savedMessage.channel_id, diff --git a/backend/src/plugins/Spam/util/onMessageCreate.ts b/backend/src/plugins/Spam/util/onMessageCreate.ts index 71e1bb3f..cedb0616 100644 --- a/backend/src/plugins/Spam/util/onMessageCreate.ts +++ b/backend/src/plugins/Spam/util/onMessageCreate.ts @@ -7,7 +7,7 @@ import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam"; export async function onMessageCreate(pluginData: GuildPluginData, savedMessage: SavedMessage) { if (savedMessage.is_bot) return; - const member = pluginData.guild.members.get(savedMessage.user_id); + const member = pluginData.guild.members.cache.get(savedMessage.user_id); const config = await pluginData.config.getMatchingConfig({ userId: savedMessage.user_id, channelId: savedMessage.channel_id, diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index f109150a..990ccd06 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { starboardCmd } from "../types"; import { sendSuccessMessage, sendErrorMessage } from "../../../pluginUtils"; -import { TextChannel } from "eris"; + import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; export const MigratePinsCmd = starboardCmd({ @@ -23,7 +23,7 @@ export const MigratePinsCmd = starboardCmd({ return; } - const starboardChannel = pluginData.guild.channels.get(starboard.channel_id); + const starboardChannel = pluginData.guild.channels.cache.get(starboard.channel_id); if (!starboardChannel || !(starboardChannel instanceof TextChannel)) { sendErrorMessage(pluginData, msg.channel, "Starboard has an unknown/invalid channel id"); return; diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts index 4c123ac8..4356a1f8 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts @@ -1,5 +1,5 @@ import { starboardEvt } from "../types"; -import { Message, TextChannel } from "eris"; + import { UnknownUser, resolveMember, noop, resolveUser } from "../../../utils"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; import { updateStarboardMessageStarCount } from "../util/updateStarboardMessageStarCount"; diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 9625556c..304bb410 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -1,5 +1,5 @@ import { EmbedWith, EMPTY_CHAR, messageLink } from "../../../utils"; -import { EmbedOptions, GuildChannel, Message } from "eris"; + import path from "path"; const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"]; diff --git a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts index 08172831..d33413c0 100644 --- a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts @@ -1,4 +1,3 @@ -import { EmbedField, EmojiOptions, GuildChannel, Message } from "eris"; import { EMPTY_CHAR, messageLink } from "../../../utils"; import { TStarboardOpts } from "../types"; diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index e7587abd..99c74ad0 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { StarboardPluginType, TStarboardOpts } from "../types"; -import { Message, GuildChannel, TextChannel, Embed } from "eris"; + import moment from "moment-timezone"; import { EmbedWith, EMPTY_CHAR, messageLink } from "../../../utils"; import path from "path"; @@ -12,7 +12,7 @@ export async function saveMessageToStarboard( msg: Message, starboard: TStarboardOpts, ) { - const channel = pluginData.guild.channels.get(starboard.channel_id); + const channel = pluginData.guild.channels.cache.get(starboard.channel_id); if (!channel) return; const starCount = (await pluginData.state.starboardReactions.getAllReactionsForMessageId(msg.id)).length; diff --git a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts index f476444e..0d26f7c1 100644 --- a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts +++ b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts @@ -1,4 +1,3 @@ -import { Client, GuildTextableChannel, Message } from "eris"; import { noop } from "../../../utils"; import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; import { TStarboardOpts } from "../types"; diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 5a26af84..a17f9345 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -214,7 +214,7 @@ export const TagsPlugin = zeppelinGuildPlugin()({ return input; } - if (pluginData.guild.members.has(input) || pluginData.client.users.has(input)) { + if (pluginData.guild.members.has(input) || pluginData.client.user!.has(input)) { return `<@!${input}>`; } diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 61dbea9e..1569aeed 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -1,6 +1,6 @@ import { tagsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { MessageContent } from "eris"; + import { TemplateParseError } from "../../../templateFormatter"; import { sendErrorMessage } from "../../../pluginUtils"; import { renderTagBody } from "../util/renderTagBody"; diff --git a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts index bddc41cc..d44415fc 100644 --- a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts +++ b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts @@ -4,7 +4,6 @@ import { TagsPluginType, TTagCategory } from "../types"; import { renderTagFromString } from "./renderTagFromString"; import { convertDelayStringToMS, StrictMessageContent } from "../../../utils"; import escapeStringRegexp from "escape-string-regexp"; -import { Member } from "eris"; interface BaseResult { renderedContent: StrictMessageContent; diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index 4a58e5a6..1171216c 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -4,7 +4,7 @@ import { GuildPluginData } from "knub"; import { convertDelayStringToMS, noop, resolveMember, tStrictMessageContent } from "../../../utils"; import { validate } from "../../../validatorUtils"; import { LogType } from "../../../data/LogType"; -import { TextChannel } from "eris"; + import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString"; import { messageIsEmpty } from "../../../utils/messageIsEmpty"; @@ -15,7 +15,7 @@ export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { // Command message was deleted -> delete the response as well const commandMsgResponse = await pluginData.state.tags.findResponseByCommandMessageId(msg.id); if (commandMsgResponse) { - const channel = pluginData.guild.channels.get(msg.channel_id) as TextChannel; + const channel = pluginData.guild.channels.cache.get(msg.channel_id) as TextChannel; if (!channel) return; const responseMsg = await pluginData.state.savedMessages.find(commandMsgResponse.response_message_id); @@ -20,7 +19,7 @@ export async function onMessageDelete(pluginData: GuildPluginData delete the command message as well const responseMsgResponse = await pluginData.state.tags.findResponseByResponseMessageId(msg.id); if (responseMsgResponse) { - const channel = pluginData.guild.channels.get(msg.channel_id) as TextChannel; + const channel = pluginData.guild.channels.cache.get(msg.channel_id) as TextChannel; if (!channel) return; const commandMsg = await pluginData.state.savedMessages.find(responseMsgResponse.command_message_id); diff --git a/backend/src/plugins/Tags/util/renderTagFromString.ts b/backend/src/plugins/Tags/util/renderTagFromString.ts index 5c9986ac..86e2f842 100644 --- a/backend/src/plugins/Tags/util/renderTagFromString.ts +++ b/backend/src/plugins/Tags/util/renderTagFromString.ts @@ -1,5 +1,5 @@ import { Tag, TagsPluginType } from "../types"; -import { Member } from "eris"; + import * as t from "io-ts"; import { renderRecursively, StrictMessageContent, stripObjectToScalars } from "../../../utils"; import { parseArguments } from "knub-command-manager"; diff --git a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts index 8b8a8fb8..9165952e 100644 --- a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts +++ b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts @@ -2,7 +2,7 @@ import { usernameSaverEvt } from "../types"; import { updateUsername } from "../updateUsername"; export const MessageCreateUpdateUsernameEvt = usernameSaverEvt({ - event: "messageCreate", + event: "message", async listener(meta) { if (meta.args.message.author.bot) return; diff --git a/backend/src/plugins/UsernameSaver/updateUsername.ts b/backend/src/plugins/UsernameSaver/updateUsername.ts index 5e0a3288..f29ed600 100644 --- a/backend/src/plugins/UsernameSaver/updateUsername.ts +++ b/backend/src/plugins/UsernameSaver/updateUsername.ts @@ -1,4 +1,3 @@ -import { User } from "eris"; import { GuildPluginData } from "knub"; import { UsernameSaverPluginType } from "./types"; diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index e3f968ae..264723b8 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -1,6 +1,7 @@ import { utilityCmd } from "../types"; import { EmbedWith, multiSorter, resolveMember, sorter } from "../../../utils"; -import { GuildChannel, MessageContent, Role } from "eris"; + + import { getCurrentUptime } from "../../../uptime"; import humanizeDuration from "humanize-duration"; import LCL from "last-commit-log"; @@ -66,7 +67,7 @@ export const AboutCmd = utilityCmd({ const aboutContent: MessageContent & { embed: EmbedWith<"title" | "fields"> } = { embed: { - title: `About ${pluginData.client.user.username}`, + title: `About ${pluginData.client.user!.username}`, fields: [ { name: "Status", @@ -100,7 +101,7 @@ export const AboutCmd = utilityCmd({ } // For the embed color, find the highest colored role the bot has - this is their color on the server as well - const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user.id); + const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user!.id); let botRoles = botMember?.roles.map(r => (msg.channel as GuildChannel).guild.roles.get(r)!) || []; botRoles = botRoles.filter(r => !!r); // Drop any unknown roles botRoles = botRoles.filter(r => r.color); // Filter to those with a color @@ -110,8 +111,8 @@ export const AboutCmd = utilityCmd({ } // Use the bot avatar as the embed image - if (pluginData.client.user.avatarURL) { - aboutContent.embed.thumbnail = { url: pluginData.client.user.avatarURL }; + if (pluginData.client.user!avatarURL) { + aboutContent.embed.thumbnail = { url: pluginData.client.user!.avatarURL }; } msg.channel.createMessage(aboutContent); diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index 7ab1fac8..51814d9e 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -2,7 +2,6 @@ import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { UnknownUser } from "../../../utils"; import { sendErrorMessage } from "../../../pluginUtils"; -import { EmbedOptions } from "eris"; export const AvatarCmd = utilityCmd({ trigger: ["avatar", "av"], diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 992a8b8a..72287c56 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -2,7 +2,7 @@ import { utilityCmd, UtilityPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { DAYS, getInviteCodesInString, noop, SECONDS, stripObjectToScalars } from "../../../utils"; import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { Message, TextChannel, User } from "eris"; + import moment from "moment-timezone"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; @@ -87,7 +87,7 @@ export const CleanCmd = utilityCmd({ return; } - const targetChannel = args.channel ? pluginData.guild.channels.get(args.channel) : msg.channel; + const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel) : msg.channel; if (!targetChannel || !(targetChannel instanceof TextChannel)) { sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`); return; diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index 81a488b3..1ab2269d 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -2,7 +2,7 @@ import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { messageLink } from "../../../utils"; import { sendErrorMessage } from "../../../pluginUtils"; -import { TextChannel } from "eris"; + import { canReadChannel } from "../../../utils/canReadChannel"; export const ContextCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 6e84e3d3..19870f25 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -38,7 +38,7 @@ export const InfoCmd = utilityCmd({ // 1. Channel if (userCfg.can_channelinfo) { const channelId = getChannelId(value); - const channel = channelId && pluginData.guild.channels.get(channelId); + const channel = channelId && pluginData.guild.channels.cache.get(channelId); if (channel) { const embed = await getChannelInfoEmbed(pluginData, channelId!, message.author.id); if (embed) { @@ -121,7 +121,7 @@ export const InfoCmd = utilityCmd({ // 7. Role if (userCfg.can_roleinfo) { const roleId = getRoleId(value); - const role = roleId && pluginData.guild.roles.get(roleId); + const role = roleId && pluginData.guild.roles.cache.get(roleId); if (role) { const embed = await getRoleInfoEmbed(pluginData, role, message.author.id); message.channel.createMessage({ embed }); diff --git a/backend/src/plugins/Utility/commands/PingCmd.ts b/backend/src/plugins/Utility/commands/PingCmd.ts index b8304182..0bf671bc 100644 --- a/backend/src/plugins/Utility/commands/PingCmd.ts +++ b/backend/src/plugins/Utility/commands/PingCmd.ts @@ -1,6 +1,5 @@ import { utilityCmd } from "../types"; import { noop, trimLines } from "../../../utils"; -import { Message } from "eris"; const { performance } = require("perf_hooks"); diff --git a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts index e6a3074d..d7abeac8 100644 --- a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts +++ b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts @@ -1,5 +1,5 @@ import { utilityCmd } from "../types"; -import { TextChannel } from "eris"; + import { activeReloads } from "../guildReloads"; export const ReloadGuildCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index 5aa52452..e98c46e7 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -1,6 +1,6 @@ import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { Role, TextChannel } from "eris"; + import { chunkArray, sorter, trimLines } from "../../../utils"; import { refreshMembersIfNeeded } from "../refreshMembers"; import { sendErrorMessage } from "../../../pluginUtils"; diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index 47ae3658..83e76e15 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -3,7 +3,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { errorMessage } from "../../../utils"; import { getBaseUrl, sendErrorMessage } from "../../../pluginUtils"; import moment from "moment-timezone"; -import { Constants, TextChannel } from "eris"; + import { canReadChannel } from "../../../utils/canReadChannel"; export const SourceCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index abd988ab..c0e0cf63 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -8,7 +8,7 @@ import { stripObjectToScalars, } from "../../../utils"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { VoiceChannel } from "eris"; + import { LogType } from "../../../data/LogType"; import { resolveChannel } from "knub/dist/helpers"; diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index eb85ef71..ae28f873 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -9,7 +9,7 @@ import { stripObjectToScalars, } from "../../../utils"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { Member, VoiceChannel } from "eris"; + import { LogType } from "../../../data/LogType"; export const VcmoveCmd = utilityCmd({ @@ -28,7 +28,7 @@ export const VcmoveCmd = utilityCmd({ if (isSnowflake(args.channel)) { // Snowflake -> resolve channel directly - const potentialChannel = pluginData.guild.channels.get(args.channel); + const potentialChannel = pluginData.guild.channels.cache.get(args.channel); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; @@ -38,7 +38,7 @@ export const VcmoveCmd = utilityCmd({ } else if (channelMentionRegex.test(args.channel)) { // Channel mention -> parse channel id and resolve channel from that const channelId = args.channel.match(channelMentionRegex)![1]; - const potentialChannel = pluginData.guild.channels.get(channelId); + const potentialChannel = pluginData.guild.channels.cache.get(channelId); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; @@ -69,7 +69,7 @@ export const VcmoveCmd = utilityCmd({ return; } - const oldVoiceChannel = pluginData.guild.channels.get(args.member.voiceState.channelID); + const oldVoiceChannel = pluginData.guild.channels.cache.get(args.member.voiceState.channelID); try { await args.member.edit({ @@ -111,7 +111,7 @@ export const VcmoveAllCmd = utilityCmd({ if (isSnowflake(args.channel)) { // Snowflake -> resolve channel directly - const potentialChannel = pluginData.guild.channels.get(args.channel); + const potentialChannel = pluginData.guild.channels.cache.get(args.channel); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; @@ -121,7 +121,7 @@ export const VcmoveAllCmd = utilityCmd({ } else if (channelMentionRegex.test(args.channel)) { // Channel mention -> parse channel id and resolve channel from that const channelId = args.channel.match(channelMentionRegex)![1]; - const potentialChannel = pluginData.guild.channels.get(channelId); + const potentialChannel = pluginData.guild.channels.cache.get(channelId); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index c2f41f74..45756642 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; -import { Constants, EmbedOptions } from "eris"; + import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; import { EmbedWith, formatNumber, preEmbedPadding, trimLines } from "../../../utils"; @@ -20,7 +20,7 @@ export async function getChannelInfoEmbed( channelId: string, requestMemberId?: string, ): Promise { - const channel = pluginData.guild.channels.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId); if (!channel) { return null; } diff --git a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts index 28ee5712..b1e8297e 100644 --- a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts @@ -1,4 +1,3 @@ -import { EmbedOptions } from "eris"; import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; import { trimLines, preEmbedPadding, EmbedWith } from "../../../utils"; diff --git a/backend/src/plugins/Utility/functions/getGuildPreview.ts b/backend/src/plugins/Utility/functions/getGuildPreview.ts index a72be048..34d7f73c 100644 --- a/backend/src/plugins/Utility/functions/getGuildPreview.ts +++ b/backend/src/plugins/Utility/functions/getGuildPreview.ts @@ -1,4 +1,3 @@ -import { Client, GuildPreview } from "eris"; import { memoize, MINUTES } from "../../../utils"; /** diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index 84760b1f..dff670b5 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; -import { Constants, EmbedOptions } from "eris"; + import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 3c74fc3a..798ec63a 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; -import { Constants, EmbedOptions } from "eris"; + import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils"; diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts index 5dcfcb26..e5dff015 100644 --- a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -1,4 +1,3 @@ -import { EmbedOptions, Role } from "eris"; import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; import { trimLines, preEmbedPadding, EmbedWith } from "../../../utils"; diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 0a7564cc..a49deea6 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -12,7 +12,7 @@ import { resolveUser, trimLines, } from "../../../utils"; -import { CategoryChannel, EmbedOptions, Guild, TextChannel, VoiceChannel } from "eris"; + import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; import { getGuildPreview } from "./getGuildPreview"; diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index 5a9e9dc4..bd0e39fc 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -1,4 +1,3 @@ -import { Message, GuildTextableChannel, EmbedOptions } from "eris"; import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; import { diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index c3acdda3..d6c2a0be 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -1,4 +1,3 @@ -import { Message, GuildTextableChannel, EmbedOptions, Role } from "eris"; import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; import { @@ -102,7 +101,7 @@ export async function getUserInfoEmbed( largest: 2, round: true, }); - const roles = member.roles.map(id => pluginData.guild.roles.get(id)).filter(r => r != null) as Role[]; + const roles = member.roles.map(id => pluginData.guild.roles.cache.get(id)).filter(r => r != null) as Role[]; roles.sort(sorter("position", "DESC")); embed.fields.push({ @@ -114,7 +113,7 @@ export async function getUserInfoEmbed( }); const voiceChannel = member.voiceState.channelID - ? pluginData.guild.channels.get(member.voiceState.channelID) + ? pluginData.guild.channels.cache.get(member.voiceState.channelID) : null; if (voiceChannel || member.voiceState.mute || member.voiceState.deaf) { embed.fields.push({ diff --git a/backend/src/plugins/Utility/guildReloads.ts b/backend/src/plugins/Utility/guildReloads.ts index 3de20bb8..a44b514d 100644 --- a/backend/src/plugins/Utility/guildReloads.ts +++ b/backend/src/plugins/Utility/guildReloads.ts @@ -1,3 +1 @@ -import { TextChannel } from "eris"; - export const activeReloads: Map = new Map(); diff --git a/backend/src/plugins/Utility/refreshMembers.ts b/backend/src/plugins/Utility/refreshMembers.ts index 50803e69..a0ffc09f 100644 --- a/backend/src/plugins/Utility/refreshMembers.ts +++ b/backend/src/plugins/Utility/refreshMembers.ts @@ -1,4 +1,3 @@ -import { Guild } from "eris"; import { HOURS, noop } from "../../utils"; const MEMBER_REFRESH_FREQUENCY = 1 * HOURS; // How often to do a full member refresh when using commands that need it diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 751d42ad..4900d0ce 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -1,4 +1,3 @@ -import { Constants, Member, Message, User } from "eris"; import moment from "moment-timezone"; import escapeStringRegexp from "escape-string-regexp"; import { isFullMessage, MINUTES, multiSorter, noop, sorter, trimLines } from "../../utils"; @@ -396,7 +395,7 @@ async function performBanSearch( page = 1, perPage = SEARCH_RESULTS_PER_PAGE, ): Promise<{ results: User[]; totalResults: number; page: number; lastPage: number; from: number; to: number }> { - const member = pluginData.guild.members.get(pluginData.client.user.id); + const member = pluginData.guild.members.cache.get(pluginData.client.user!.id); if (member && !hasDiscordPermissions(member.permissions, Constants.Permissions.banMembers)) { throw new SearchError(`Unable to search bans: missing "Ban Members" permission`); } diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index 9ae1e85f..7317aaac 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -2,7 +2,7 @@ import { welcomeMessageEvt } from "../types"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { createChunkedMessage, stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; -import { TextChannel } from "eris"; + import { sendDM } from "../../../utils/sendDM"; export const SendWelcomeMessageEvt = welcomeMessageEvt({ @@ -55,7 +55,7 @@ export const SendWelcomeMessageEvt = welcomeMessageEvt({ } if (config.send_to_channel) { - const channel = meta.args.guild.channels.get(config.send_to_channel); + const channel = meta.args.guild.channels.cache.get(config.send_to_channel); if (!channel || !(channel instanceof TextChannel)) return; try { diff --git a/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts new file mode 100644 index 00000000..776871d4 --- /dev/null +++ b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts @@ -0,0 +1,43 @@ +import { MessageMentionOptions, MessageMentionTypes } from "discord.js"; + +export function erisAllowedMentionsToDjsMentionOptions( + allowedMentions: erisAllowedMentionFormat | undefined, +): MessageMentionOptions | undefined { + if (allowedMentions === undefined) return undefined; + + let parse: MessageMentionTypes[] = []; + let users: string[] | undefined = undefined; + let roles: string[] | undefined = undefined; + + if (Array.isArray(allowedMentions.users)) { + users = allowedMentions.users; + } else if (allowedMentions.users === true) { + parse.push("users"); + } + + if (Array.isArray(allowedMentions.roles)) { + roles = allowedMentions.roles; + } else if (allowedMentions.roles === true) { + parse.push("roles"); + } + + if (allowedMentions.everyone === true) { + parse.push("everyone"); + } + + const mentions: MessageMentionOptions = { + parse, + users, + roles, + repliedUser: allowedMentions.repliedUser, + }; + + return mentions; +} + +export interface erisAllowedMentionFormat { + everyone: boolean | undefined; + users: boolean | string[] | undefined; + roles: boolean | string[] | undefined; + repliedUser: boolean | undefined; +} diff --git a/backend/src/utils/hasDiscordPermissions.ts b/backend/src/utils/hasDiscordPermissions.ts index 34b6d9e1..7cbe8750 100644 --- a/backend/src/utils/hasDiscordPermissions.ts +++ b/backend/src/utils/hasDiscordPermissions.ts @@ -5,7 +5,7 @@ import { Permissions } from "discord.js"; * @param requiredPermissions Bitmask of required permissions */ export function hasDiscordPermissions( - resolvedPermissions: Permissions | Readonly, + resolvedPermissions: Permissions | Readonly | null, requiredPermissions: number | bigint, ) { const allowedPermissions = BigInt(resolvedPermissions); From 57893e7f76a14d92eef1105433a867ec4bc41800 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 1 Jun 2021 04:33:02 +0200 Subject: [PATCH 04/79] More rework progress, mostly done up to ModActions --- .../plugins/Censor/util/applyFiltersToMsg.ts | 11 ++-- .../src/plugins/Censor/util/censorMessage.ts | 4 +- .../commands/ArchiveChannelCmd.ts | 17 +++--- .../ChannelArchiver/rehostAttachment.ts | 11 ++-- .../CompanionChannelsPlugin.ts | 8 +-- .../events/VoiceChannelJoinEvt.ts | 10 ---- .../events/VoiceChannelLeaveEvt.ts | 9 --- .../events/VoiceChannelSwitchEvt.ts | 9 --- .../events/VoiceStateUpdateEvt.ts | 12 ++++ ...etCompanionChannelOptsForVoiceChannelId.ts | 3 +- .../functions/handleCompanionPermissions.ts | 27 +++------ .../Counters/commands/AddCounterCmd.ts | 19 +++--- .../Counters/commands/CountersListCmd.ts | 2 +- .../commands/ResetAllCounterValuesCmd.ts | 7 +-- .../Counters/commands/ResetCounterCmd.ts | 17 +++--- .../Counters/commands/SetCounterCmd.ts | 20 +++---- .../Counters/commands/ViewCounterCmd.ts | 17 +++--- .../plugins/LocateUser/LocateUserPlugin.ts | 6 +- .../plugins/LocateUser/commands/FollowCmd.ts | 4 +- .../plugins/LocateUser/commands/WhereCmd.ts | 2 +- .../LocateUser/events/BanRemoveAlertsEvt.ts | 2 +- .../LocateUser/events/SendAlertsEvts.ts | 43 +++++-------- .../LocateUser/utils/createOrReuseInvite.ts | 10 ++-- .../plugins/LocateUser/utils/moveMember.ts | 11 ++-- .../plugins/LocateUser/utils/sendAlerts.ts | 3 +- .../src/plugins/LocateUser/utils/sendWhere.ts | 18 +++--- .../plugins/Logs/events/LogsGuildBanEvts.ts | 13 ++-- .../Logs/events/LogsGuildMemberAddEvt.ts | 4 +- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 13 ++-- .../Logs/events/LogsVoiceChannelEvts.ts | 60 ++++++++----------- .../src/plugins/Logs/util/getLogMessage.ts | 4 +- backend/src/plugins/Logs/util/log.ts | 12 ++-- .../src/plugins/Logs/util/onMessageDelete.ts | 3 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 9 +-- .../MessageSaver/commands/SaveMessagesToDB.ts | 2 +- .../MessageSaver/commands/SavePinsToDB.ts | 6 +- .../MessageSaver/events/SaveMessagesEvts.ts | 9 +-- .../plugins/MessageSaver/saveMessagesToDB.ts | 3 +- 38 files changed, 199 insertions(+), 241 deletions(-) delete mode 100644 backend/src/plugins/CompanionChannels/events/VoiceChannelJoinEvt.ts delete mode 100644 backend/src/plugins/CompanionChannels/events/VoiceChannelLeaveEvt.ts delete mode 100644 backend/src/plugins/CompanionChannels/events/VoiceChannelSwitchEvt.ts create mode 100644 backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts diff --git a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts index 6e83acc6..045276f2 100644 --- a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts +++ b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts @@ -9,6 +9,7 @@ import { censorMessage } from "./censorMessage"; import escapeStringRegexp from "escape-string-regexp"; import { logger } from "../../../logger"; import { allowTimeout } from "../../../RegExpRunner"; +import { MessageEmbed, Invite } from "discord.js"; export async function applyFiltersToMsg( pluginData: GuildPluginData, @@ -20,7 +21,7 @@ export async function applyFiltersToMsg( let messageContent = savedMessage.data.content || ""; if (savedMessage.data.attachments) messageContent += " " + JSON.stringify(savedMessage.data.attachments); if (savedMessage.data.embeds) { - const embeds = (savedMessage.data.embeds as Embed[]).map(e => cloneDeep(e)); + const embeds = (savedMessage.data.embeds as MessageEmbed[]).map(e => cloneDeep(e)); for (const embed of embeds) { if (embed.type === "video") { // Ignore video descriptions as they're not actually shown on the embed @@ -69,20 +70,20 @@ export async function applyFiltersToMsg( } if (isGuildInvite(invite)) { - if (inviteGuildWhitelist && !inviteGuildWhitelist.includes(invite.guild.id)) { + if (inviteGuildWhitelist && !inviteGuildWhitelist.includes(invite.guild!.id)) { censorMessage( pluginData, savedMessage, - `invite guild (**${invite.guild.name}** \`${invite.guild.id}\`) not found in whitelist`, + `invite guild (**${invite.guild!.name}** \`${invite.guild!.id}\`) not found in whitelist`, ); return true; } - if (inviteGuildBlacklist && inviteGuildBlacklist.includes(invite.guild.id)) { + if (inviteGuildBlacklist && inviteGuildBlacklist.includes(invite.guild!.id)) { censorMessage( pluginData, savedMessage, - `invite guild (**${invite.guild.name}** \`${invite.guild.id}\`) found in blacklist`, + `invite guild (**${invite.guild!.name}** \`${invite.guild!.id}\`) found in blacklist`, ); return true; } diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index df0011ca..9591e81d 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -4,6 +4,7 @@ import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars, resolveUser } from "../../../utils"; import { disableCodeBlocks, deactivateMentions } from "knub/dist/helpers"; +import { TextChannel } from "discord.js"; export async function censorMessage( pluginData: GuildPluginData, @@ -13,7 +14,8 @@ export async function censorMessage( pluginData.state.serverLogs.ignoreLog(LogType.MESSAGE_DELETE, savedMessage.id); try { - await pluginData.client.deleteMessage(savedMessage.channel_id, savedMessage.id, "Censored"); + const channel = pluginData.guild.channels.resolve(savedMessage.channel_id) as TextChannel + await channel.messages.delete(savedMessage.id); } catch { return; } diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 373f2aa4..b85aeb2f 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -51,7 +51,7 @@ export const ArchiveChannelCmd = channelArchiverCmd({ let previousId: string | undefined; const startTime = Date.now(); - const progressMsg = await msg.channel.createMessage("Creating archive..."); + const progressMsg = await msg.channel.send("Creating archive..."); const progressUpdateInterval = setInterval(() => { const secondsSinceStart = Math.round((Date.now() - startTime) / 1000); progressMsg @@ -61,16 +61,16 @@ export const ArchiveChannelCmd = channelArchiverCmd({ while (archivedMessages < maxMessagesToArchive) { const messagesToFetch = Math.min(MAX_MESSAGES_PER_FETCH, maxMessagesToArchive - archivedMessages); - const messages = await args.channel.getMessages(messagesToFetch, previousId); - if (messages.length === 0) break; + const messages = await args.channel.messages.fetch({ limit: messagesToFetch, before: previousId }); + if (messages.size === 0) break; - for (const message of messages) { - const ts = moment.utc(message.timestamp).format("YYYY-MM-DD HH:mm:ss"); + for (const message of messages.values()) { + const ts = moment.utc(message.createdTimestamp).format("YYYY-MM-DD HH:mm:ss"); let content = `[${ts}] [${message.author.id}] [${message.author.username}#${ message.author.discriminator }]: ${message.content || ""}`; - if (message.attachments.length) { + if (message.attachments.size) { if (args["attachment-channel"]) { const rehostedAttachmentUrl = await rehostAttachment(message.attachments[0], args["attachment-channel"]); content += `\n-- Attachment: ${rehostedAttachmentUrl}`; @@ -104,9 +104,6 @@ export const ArchiveChannelCmd = channelArchiverCmd({ result += `\n\n${archiveLines.join("\n")}\n`; progressMsg.delete().catch(noop); - msg.channel.createMessage("Archive created!", { - file: Buffer.from(result), - name: `archive-${args.channel.name}-${moment.utc().format("YYYY-MM-DD-HH-mm-ss")}.txt`, - }); + msg.channel.send({ content: "Archive created!", files: [{attachment: Buffer.from(result), name: `archive-${args.channel.name}-${moment.utc().format("YYYY-MM-DD-HH-mm-ss")}.txt`}], split: false }); }, }); diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index 09aa338f..56ef2924 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -1,10 +1,11 @@ import { downloadFile } from "../../utils"; import fs from "fs"; +import { MessageAttachment, MessageOptions, TextChannel } from "discord.js"; const fsp = fs.promises; const MAX_ATTACHMENT_REHOST_SIZE = 1024 * 1024 * 8; -export async function rehostAttachment(attachment: Attachment, targetChannel: TextChannel): Promise { +export async function rehostAttachment(attachment: MessageAttachment, targetChannel: TextChannel): Promise { if (attachment.size > MAX_ATTACHMENT_REHOST_SIZE) { return "Attachment too big to rehost"; } @@ -17,11 +18,9 @@ export async function rehostAttachment(attachment: Attachment, targetChannel: Te } try { - const rehostMessage = await targetChannel.createMessage(`Rehost of attachment ${attachment.id}`, { - name: attachment.filename, - file: await fsp.readFile(downloaded.path), - }); - return rehostMessage.attachments[0].url; + const content: MessageOptions = { content: `Rehost of attachment ${attachment.id}`, files: [{ name: attachment.name ? attachment.name : undefined, attachment: await fsp.readFile(downloaded.path)}]} + const rehostMessage = await targetChannel.send({ content, split: false }); + return rehostMessage.attachments.values()[0].url; } catch { return "Failed to rehost attachment"; } diff --git a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts index 91d2358a..d3a89865 100644 --- a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts +++ b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts @@ -1,11 +1,9 @@ import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { CompanionChannelsPluginType, ConfigSchema, TCompanionChannelOpts } from "./types"; -import { VoiceChannelJoinEvt } from "./events/VoiceChannelJoinEvt"; -import { VoiceChannelSwitchEvt } from "./events/VoiceChannelSwitchEvt"; -import { VoiceChannelLeaveEvt } from "./events/VoiceChannelLeaveEvt"; +import { CompanionChannelsPluginType, ConfigSchema } from "./types"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { CooldownManager } from "knub"; +import { VoiceStateUpdateEvt } from "./events/VoiceStateUpdateEvt"; const defaultOptions = { config: { @@ -29,7 +27,7 @@ export const CompanionChannelsPlugin = zeppelinGuildPlugin = { export async function getCompanionChannelOptsForVoiceChannelId( pluginData: GuildPluginData, userId: string, - voiceChannel: VoiceChannel, + voiceChannel: VoiceChannel | StageChannel, ): Promise { const config = await pluginData.config.getMatchingConfig({ userId, channelId: voiceChannel.id }); return Object.values(config.entries) diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index 0806da09..022b01d7 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -5,6 +5,7 @@ import { GuildPluginData } from "knub"; import { isDiscordRESTError, MINUTES } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; +import { VoiceChannel, TextChannel, Permissions, StageChannel } from "discord.js"; const ERROR_COOLDOWN_KEY = "errorCooldown"; const ERROR_COOLDOWN = 5 * MINUTES; @@ -12,20 +13,8 @@ const ERROR_COOLDOWN = 5 * MINUTES; export async function handleCompanionPermissions( pluginData: GuildPluginData, userId: string, - voiceChannel: VoiceChannel, - oldChannel?: VoiceChannel, -); -export async function handleCompanionPermissions( - pluginData: GuildPluginData, - userId: string, - voiceChannel: null, - oldChannel: VoiceChannel, -); -export async function handleCompanionPermissions( - pluginData: GuildPluginData, - userId: string, - voiceChannel: VoiceChannel | null, - oldChannel?: VoiceChannel, + voiceChannel: VoiceChannel | StageChannel | null, + oldChannel?: VoiceChannel | StageChannel | null, ) { if (pluginData.state.errorCooldownManager.isOnCooldown(ERROR_COOLDOWN_KEY)) { return; @@ -65,18 +54,16 @@ export async function handleCompanionPermissions( for (const channelId of permsToDelete) { const channel = pluginData.guild.channels.cache.get(channelId); if (!channel || !(channel instanceof TextChannel)) continue; - await channel.deletePermission(userId, `Companion Channel for ${oldChannel!.id} | User Left`); + await channel.permissionOverwrites.get(userId)?.delete(`Companion Channel for ${oldChannel!.id} | User Left`); } for (const [channelId, permissions] of permsToSet) { const channel = pluginData.guild.channels.cache.get(channelId); if (!channel || !(channel instanceof TextChannel)) continue; - await channel.editPermission( + await channel.updateOverwrite( userId, - permissions, - 0, - "member", - `Companion Channel for ${voiceChannel!.id} | User Joined`, + new Permissions(BigInt(permissions)).serialize(), + {reason: `Companion Channel for ${voiceChannel!.id} | User Joined`}, ); } } catch (e) { diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index f67fd6a6..26c4da25 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -2,10 +2,11 @@ import { typedGuildCommand } from "knub"; import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { resolveChannel, waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/dist/helpers"; import { resolveUser, UnknownUser } from "../../../utils"; import { changeCounterValue } from "../functions/changeCounterValue"; +import { TextChannel } from "discord.js"; export const AddCounterCmd = typedGuildCommand()({ trigger: ["counters add", "counter add", "addcounter"], @@ -66,14 +67,14 @@ export const AddCounterCmd = typedGuildCommand()({ let channel = args.channel; if (!channel && counter.per_channel) { - message.channel.createMessage(`Which channel's counter value would you like to add to?`); + message.channel.send(`Which channel's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); return; } - const potentialChannel = resolveChannel(pluginData.guild, reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; @@ -84,7 +85,7 @@ export const AddCounterCmd = typedGuildCommand()({ let user = args.user; if (!user && counter.per_user) { - message.channel.createMessage(`Which user's counter value would you like to add to?`); + message.channel.send(`Which user's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -102,7 +103,7 @@ export const AddCounterCmd = typedGuildCommand()({ let amount = args.amount; if (!amount) { - message.channel.createMessage("How much would you like to add to the counter's value?"); + message.channel.send("How much would you like to add to the counter's value?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -123,19 +124,19 @@ export const AddCounterCmd = typedGuildCommand()({ const counterName = counter.name || args.counterName; if (channel && user) { - message.channel.createMessage( + message.channel.send( `Added ${amount} to **${counterName}** for <@!${user.id}> in <#${channel.id}>. The value is now ${newValue}.`, ); } else if (channel) { - message.channel.createMessage( + message.channel.send( `Added ${amount} to **${counterName}** in <#${channel.id}>. The value is now ${newValue}.`, ); } else if (user) { - message.channel.createMessage( + message.channel.send( `Added ${amount} to **${counterName}** for <@!${user.id}>. The value is now ${newValue}.`, ); } else { - message.channel.createMessage(`Added ${amount} to **${counterName}**. The value is now ${newValue}.`); + message.channel.send(`Added ${amount} to **${counterName}**. The value is now ${newValue}.`); } }, }); diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index a9316268..5e35a28a 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -41,7 +41,7 @@ export const CountersListCmd = typedGuildCommand()({ hintLines.push(`Use \`${getGuildPrefix(pluginData)}counters reset_all \` to reset a counter entirely`); } - message.channel.createMessage( + message.channel.send( trimMultilineString(` ${counterLines.join("\n\n")} diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 2bf6e714..6b632f95 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -2,11 +2,8 @@ import { typedGuildCommand } from "knub"; import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveChannel, waitForReply } from "knub/dist/helpers"; -import { confirm, MINUTES, noop, resolveUser, trimMultilineString, UnknownUser } from "../../../utils"; -import { changeCounterValue } from "../functions/changeCounterValue"; -import { setCounterValue } from "../functions/setCounterValue"; +import { confirm, MINUTES, noop, trimMultilineString } from "../../../utils"; import { resetAllCounterValues } from "../functions/resetAllCounterValues"; import { counterIdLock } from "../../../utils/lockNameHelpers"; @@ -49,7 +46,7 @@ export const ResetAllCounterValuesCmd = typedGuildCommand()( } const loadingMessage = await message.channel - .createMessage(`Resetting counter **${counterName}**. This might take a while. Please don't reload the config.`) + .send(`Resetting counter **${counterName}**. This might take a while. Please don't reload the config.`) .catch(() => null); const lock = await pluginData.locks.acquire(counterIdLock(counterId), 10 * MINUTES); diff --git a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts index ed858a0f..736f66f8 100644 --- a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts @@ -2,10 +2,11 @@ import { typedGuildCommand } from "knub"; import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { resolveChannel, waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/dist/helpers"; import { resolveUser, UnknownUser } from "../../../utils"; import { setCounterValue } from "../functions/setCounterValue"; +import { TextChannel } from "discord.js"; export const ResetCounterCmd = typedGuildCommand()({ trigger: ["counters reset", "counter reset", "resetcounter"], @@ -61,14 +62,14 @@ export const ResetCounterCmd = typedGuildCommand()({ let channel = args.channel; if (!channel && counter.per_channel) { - message.channel.createMessage(`Which channel's counter value would you like to reset?`); + message.channel.send(`Which channel's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); return; } - const potentialChannel = resolveChannel(pluginData.guild, reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; @@ -79,7 +80,7 @@ export const ResetCounterCmd = typedGuildCommand()({ let user = args.user; if (!user && counter.per_user) { - message.channel.createMessage(`Which user's counter value would you like to reset?`); + message.channel.send(`Which user's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -99,13 +100,13 @@ export const ResetCounterCmd = typedGuildCommand()({ const counterName = counter.name || args.counterName; if (channel && user) { - message.channel.createMessage(`Reset **${counterName}** for <@!${user.id}> in <#${channel.id}>`); + message.channel.send(`Reset **${counterName}** for <@!${user.id}> in <#${channel.id}>`); } else if (channel) { - message.channel.createMessage(`Reset **${counterName}** in <#${channel.id}>`); + message.channel.send(`Reset **${counterName}** in <#${channel.id}>`); } else if (user) { - message.channel.createMessage(`Reset **${counterName}** for <@!${user.id}>`); + message.channel.send(`Reset **${counterName}** for <@!${user.id}>`); } else { - message.channel.createMessage(`Reset **${counterName}**`); + message.channel.send(`Reset **${counterName}**`); } }, }); diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index b90bdfb8..1158b5a6 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -2,11 +2,11 @@ import { typedGuildCommand } from "knub"; import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { resolveChannel, waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/dist/helpers"; import { resolveUser, UnknownUser } from "../../../utils"; -import { changeCounterValue } from "../functions/changeCounterValue"; import { setCounterValue } from "../functions/setCounterValue"; +import { TextChannel } from "discord.js"; export const SetCounterCmd = typedGuildCommand()({ trigger: ["counters set", "counter set", "setcounter"], @@ -67,14 +67,14 @@ export const SetCounterCmd = typedGuildCommand()({ let channel = args.channel; if (!channel && counter.per_channel) { - message.channel.createMessage(`Which channel's counter value would you like to change?`); + message.channel.send(`Which channel's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); return; } - const potentialChannel = resolveChannel(pluginData.guild, reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; @@ -85,7 +85,7 @@ export const SetCounterCmd = typedGuildCommand()({ let user = args.user; if (!user && counter.per_user) { - message.channel.createMessage(`Which user's counter value would you like to change?`); + message.channel.send(`Which user's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -103,7 +103,7 @@ export const SetCounterCmd = typedGuildCommand()({ let value = args.value; if (!value) { - message.channel.createMessage("What would you like to set the counter's value to?"); + message.channel.send("What would you like to set the counter's value to?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -128,13 +128,13 @@ export const SetCounterCmd = typedGuildCommand()({ const counterName = counter.name || args.counterName; if (channel && user) { - message.channel.createMessage(`Set **${counterName}** for <@!${user.id}> in <#${channel.id}> to ${value}`); + message.channel.send(`Set **${counterName}** for <@!${user.id}> in <#${channel.id}> to ${value}`); } else if (channel) { - message.channel.createMessage(`Set **${counterName}** in <#${channel.id}> to ${value}`); + message.channel.send(`Set **${counterName}** in <#${channel.id}> to ${value}`); } else if (user) { - message.channel.createMessage(`Set **${counterName}** for <@!${user.id}> to ${value}`); + message.channel.send(`Set **${counterName}** for <@!${user.id}> to ${value}`); } else { - message.channel.createMessage(`Set **${counterName}** to ${value}`); + message.channel.send(`Set **${counterName}** to ${value}`); } }, }); diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index 6fed0607..bafbcb76 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -2,9 +2,10 @@ import { typedGuildCommand } from "knub"; import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { resolveChannel, waitForReply } from "knub/dist/helpers"; +import { waitForReply } from "knub/dist/helpers"; import { resolveUser, UnknownUser } from "../../../utils"; +import { TextChannel } from "discord.js"; export const ViewCounterCmd = typedGuildCommand()({ trigger: ["counters view", "counter view", "viewcounter", "counter"], @@ -60,14 +61,14 @@ export const ViewCounterCmd = typedGuildCommand()({ let channel = args.channel; if (!channel && counter.per_channel) { - message.channel.createMessage(`Which channel's counter value would you like to view?`); + message.channel.send(`Which channel's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); return; } - const potentialChannel = resolveChannel(pluginData.guild, reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; @@ -78,7 +79,7 @@ export const ViewCounterCmd = typedGuildCommand()({ let user = args.user; if (!user && counter.per_user) { - message.channel.createMessage(`Which user's counter value would you like to view?`); + message.channel.send(`Which user's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { sendErrorMessage(pluginData, message.channel, "Cancelling"); @@ -99,13 +100,13 @@ export const ViewCounterCmd = typedGuildCommand()({ const counterName = counter.name || args.counterName; if (channel && user) { - message.channel.createMessage(`**${counterName}** for <@!${user.id}> in <#${channel.id}> is ${finalValue}`); + message.channel.send(`**${counterName}** for <@!${user.id}> in <#${channel.id}> is ${finalValue}`); } else if (channel) { - message.channel.createMessage(`**${counterName}** in <#${channel.id}> is ${finalValue}`); + message.channel.send(`**${counterName}** in <#${channel.id}> is ${finalValue}`); } else if (user) { - message.channel.createMessage(`**${counterName}** for <@!${user.id}> is ${finalValue}`); + message.channel.send(`**${counterName}** for <@!${user.id}> is ${finalValue}`); } else { - message.channel.createMessage(`**${counterName}** is ${finalValue}`); + message.channel.send(`**${counterName}** is ${finalValue}`); } }, }); diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index ed5c6567..b6bf2538 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -7,7 +7,7 @@ import { fillActiveAlertsList } from "./utils/fillAlertsList"; import { WhereCmd } from "./commands/WhereCmd"; import { FollowCmd } from "./commands/FollowCmd"; import { DeleteFollowCmd, ListFollowCmd } from "./commands/ListFollowCmd"; -import { ChannelJoinAlertsEvt, ChannelLeaveAlertsEvt, ChannelSwitchAlertsEvt } from "./events/SendAlertsEvts"; +import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts"; import { GuildBanRemoveAlertsEvt } from "./events/BanRemoveAlertsEvt"; import { trimPluginDescription } from "../../utils"; import Timeout = NodeJS.Timeout; @@ -53,9 +53,7 @@ export const LocateUserPlugin = zeppelinGuildPlugin()({ // prettier-ignore events: [ - ChannelJoinAlertsEvt, - ChannelSwitchAlertsEvt, - ChannelLeaveAlertsEvt, + VoiceStateUpdateAlertEvt, GuildBanRemoveAlertsEvt ], diff --git a/backend/src/plugins/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts index 08c105ed..3dcfae9b 100644 --- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts @@ -46,7 +46,7 @@ export const FollowCmd = locateUserCmd({ sendSuccessMessage( pluginData, msg.channel, - `Every time ${args.member.mention} joins or switches VC in the next ${humanizeDuration( + `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( time, )} i will notify and move you.\nPlease make sure to be in a voice channel, otherwise i cannot move you!`, ); @@ -54,7 +54,7 @@ export const FollowCmd = locateUserCmd({ sendSuccessMessage( pluginData, msg.channel, - `Every time ${args.member.mention} joins or switches VC in the next ${humanizeDuration( + `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( time, )} i will notify you`, ); diff --git a/backend/src/plugins/LocateUser/commands/WhereCmd.ts b/backend/src/plugins/LocateUser/commands/WhereCmd.ts index 0662e880..5cbdac4a 100644 --- a/backend/src/plugins/LocateUser/commands/WhereCmd.ts +++ b/backend/src/plugins/LocateUser/commands/WhereCmd.ts @@ -14,6 +14,6 @@ export const WhereCmd = locateUserCmd({ }, async run({ message: msg, args, pluginData }) { - sendWhere(pluginData, args.member, msg.channel, `${msg.member.mention} | `); + sendWhere(pluginData, args.member, msg.channel, `<@${msg.member.id}> | `); }, }); diff --git a/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts b/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts index cc6c155f..bc4e8d0f 100644 --- a/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts +++ b/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts @@ -4,7 +4,7 @@ export const GuildBanRemoveAlertsEvt = locateUserEvt({ event: "guildBanAdd", async listener(meta) { - const alerts = await meta.pluginData.state.alerts.getAlertsByUserId(meta.args.user.id); + const alerts = await meta.pluginData.state.alerts.getAlertsByUserId(meta.args.ban.user.id); alerts.forEach(alert => { meta.pluginData.state.alerts.delete(alert.id); }); diff --git a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts index 353a2c26..f506069c 100644 --- a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts +++ b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts @@ -1,38 +1,27 @@ +import { TextChannel } from "discord.js"; import { locateUserEvt } from "../types"; import { sendAlerts } from "../utils/sendAlerts"; -export const ChannelJoinAlertsEvt = locateUserEvt({ - event: "voiceChannelJoin", +export const VoiceStateUpdateAlertEvt = locateUserEvt({ + event: "voiceStateUpdate", async listener(meta) { - if (meta.pluginData.state.usersWithAlerts.includes(meta.args.member.id)) { - sendAlerts(meta.pluginData, meta.args.member.id); - } - }, -}); + const memberId = meta.args.oldState.member ? meta.args.oldState.member.id : meta.args.newState.member!.id; -export const ChannelSwitchAlertsEvt = locateUserEvt({ - event: "voiceChannelSwitch", + if (meta.args.newState.channel != null) { + if (meta.pluginData.state.usersWithAlerts.includes(memberId)) { + sendAlerts(meta.pluginData, memberId); + } + } else { + const triggeredAlerts = await meta.pluginData.state.alerts.getAlertsByUserId(memberId); + const voiceChannel = meta.args.oldState.channel!; - async listener(meta) { - if (meta.pluginData.state.usersWithAlerts.includes(meta.args.member.id)) { - sendAlerts(meta.pluginData, meta.args.member.id); - } - }, -}); - -export const ChannelLeaveAlertsEvt = locateUserEvt({ - event: "voiceChannelLeave", - - async listener(meta) { - const triggeredAlerts = await meta.pluginData.state.alerts.getAlertsByUserId(meta.args.member.id); - const voiceChannel = meta.args.oldChannel as VoiceChannel; - - triggeredAlerts.forEach(alert => { - const txtChannel = meta.pluginData.client.getChannel(alert.channel_id) as TextableChannel; - txtChannel.createMessage( - `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`${voiceChannel.name}\``, + triggeredAlerts.forEach(alert => { + const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id) as TextChannel; + txtChannel.send( + `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`<#!${voiceChannel.id}>\``, ); }); + } }, }); diff --git a/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts b/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts index 8ba7f2e1..2853c7f0 100644 --- a/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts +++ b/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts @@ -1,9 +1,11 @@ -export async function createOrReuseInvite(vc: VoiceChannel) { - const existingInvites = await vc.getInvites(); +import { VoiceChannel } from "discord.js"; - if (existingInvites.length !== 0) { +export async function createOrReuseInvite(vc: VoiceChannel) { + const existingInvites = await vc.fetchInvites(); + + if (existingInvites.size !== 0) { return existingInvites[0]; } else { - return vc.createInvite(undefined); + return vc.createInvite(); } } diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index 6966d10f..4289b2a1 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,18 +1,19 @@ import { GuildPluginData } from "knub"; import { LocateUserPluginType } from "../types"; import { sendErrorMessage } from "../../../pluginUtils"; +import { GuildMember, TextChannel } from "discord.js"; export async function moveMember( pluginData: GuildPluginData, toMoveID: string, - target: Member, - errorChannel: TextableChannel, + target: GuildMember, + errorChannel: TextChannel, ) { - const modMember: Member = await pluginData.client.getRESTGuildMember(pluginData.guild.id, toMoveID); - if (modMember.voiceState.channelID != null) { + const modMember: GuildMember = await pluginData.guild.members.fetch(toMoveID); + if (modMember.voice.channelID != null) { try { await modMember.edit({ - channelID: target.voiceState.channelID, + channel: target.voice.channelID }); } catch { sendErrorMessage(pluginData, errorChannel, "Failed to move you. Are you in a voice channel?"); diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts index bb47168a..882e4344 100644 --- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts @@ -4,6 +4,7 @@ import { resolveMember } from "../../../utils"; import { sendWhere } from "./sendWhere"; import { moveMember } from "./moveMember"; +import { TextChannel } from "discord.js"; export async function sendAlerts(pluginData: GuildPluginData, userId: string) { const triggeredAlerts = await pluginData.state.alerts.getAlertsByUserId(userId); @@ -12,7 +13,7 @@ export async function sendAlerts(pluginData: GuildPluginData { const prepend = `<@!${alert.requestor_id}>, an alert requested by you has triggered!\nReminder: \`${alert.body}\`\n`; - const txtChannel = pluginData.client.getChannel(alert.channel_id) as TextableChannel; + const txtChannel = pluginData.guild.channels.resolve(alert.channel_id) as TextChannel; sendWhere(pluginData, member, txtChannel, prepend); if (alert.active) { moveMember(pluginData, alert.requestor_id, member, txtChannel); diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 8b9678a7..4fb151b6 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -3,19 +3,20 @@ import { createOrReuseInvite } from "./createOrReuseInvite"; import { GuildPluginData } from "knub"; import { LocateUserPluginType } from "../types"; import { sendErrorMessage } from "../../../pluginUtils"; +import { GuildMember, Invite, TextChannel, VoiceChannel } from "discord.js"; export async function sendWhere( pluginData: GuildPluginData, - member: Member, - channel: TextableChannel, + member: GuildMember, + channel: TextChannel, prepend: string, ) { - const voice = member.voiceState.channelID - ? (pluginData.guild.channels.cache.get(member.voiceState.channelID) as VoiceChannel) + const voice = member.voice.channelID + ? (pluginData.guild.channels.resolve(member.voice.channelID) as VoiceChannel) : null; if (voice == null) { - channel.createMessage(prepend + "That user is not in a channel"); + channel.send(prepend + "That user is not in a channel"); } else { let invite: Invite; try { @@ -24,9 +25,10 @@ export async function sendWhere( sendErrorMessage(pluginData, channel, "Cannot create an invite to that channel!"); return; } - channel.createMessage({ - content: prepend + `${member.mention} is in the following channel: \`${voice.name}\` ${getInviteLink(invite)}`, - allowedMentions: { users: true }, + channel.send({ + content: prepend + `<@${member.id}> is in the following channel: \`${voice.name}\` ${getInviteLink(invite)}`, + allowedMentions: { parse: ["users"] }, + split: false, }); } } diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index ef61f5e3..ab7d7498 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -3,20 +3,21 @@ import { stripObjectToScalars, UnknownUser } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; +import { GuildAuditLogs } from "discord.js"; export const LogsGuildBanAddEvt = logsEvt({ event: "guildBanAdd", async listener(meta) { const pluginData = meta.pluginData; - const user = meta.args.user; + const user = meta.args.ban.user; const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry( pluginData, - ErisConstants.AuditLogActions.MEMBER_BAN_ADD, + GuildAuditLogs.Actions.MEMBER_BAN_ADD as number, user.id, ); - const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : new UnknownUser(); + const mod = relevantAuditLogEntry ? relevantAuditLogEntry.executor : new UnknownUser(); pluginData.state.guildLogs.log( LogType.MEMBER_BAN, @@ -34,14 +35,14 @@ export const LogsGuildBanRemoveEvt = logsEvt({ async listener(meta) { const pluginData = meta.pluginData; - const user = meta.args.user; + const user = meta.args.ban.user; const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry( pluginData, - ErisConstants.AuditLogActions.MEMBER_BAN_REMOVE, + GuildAuditLogs.Actions.MEMBER_BAN_REMOVE as number, user.id, ); - const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : new UnknownUser(); + const mod = relevantAuditLogEntry ? relevantAuditLogEntry.executor : new UnknownUser(); pluginData.state.guildLogs.log( LogType.MEMBER_UNBAN, diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts index b7a731f7..71448dbb 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts @@ -13,14 +13,14 @@ export const LogsGuildMemberAddEvt = logsEvt({ const member = meta.args.member; const newThreshold = moment.utc().valueOf() - 1000 * 60 * 60; - const accountAge = humanizeDuration(moment.utc().valueOf() - member.createdAt, { + const accountAge = humanizeDuration(moment.utc().valueOf() - member.user.createdTimestamp, { largest: 2, round: true, }); pluginData.state.guildLogs.log(LogType.MEMBER_JOIN, { member: stripObjectToScalars(member, ["user", "roles"]), - new: member.createdAt >= newThreshold ? " :new:" : "", + new: member.user.createdTimestamp >= newThreshold ? " :new:" : "", account_age: accountAge, }); diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index 396cbbc8..170e8543 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -5,6 +5,7 @@ import { LogType } from "../../../data/LogType"; import isEqual from "lodash.isequal"; import diff from "lodash.difference"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; +import { GuildAuditLogs } from "discord.js"; export const LogsGuildMemberUpdateEvt = logsEvt({ event: "guildMemberUpdate", @@ -12,17 +13,17 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ async listener(meta) { const pluginData = meta.pluginData; const oldMember = meta.args.oldMember; - const member = meta.args.member; + const member = meta.args.newMember; if (!oldMember) return; const logMember = stripObjectToScalars(member, ["user", "roles"]); - if (member.nick !== oldMember.nick) { + if (member.nickname !== oldMember.nickname) { pluginData.state.guildLogs.log(LogType.MEMBER_NICK_CHANGE, { member: logMember, - oldNick: oldMember.nick != null ? oldMember.nick : "", - newNick: member.nick != null ? member.nick : "", + oldNick: oldMember.nickname != null ? oldMember.nickname : "", + newNick: member.nickname != null ? member.nickname : "", }); } @@ -49,10 +50,10 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ if (!skip) { const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry( pluginData, - ErisConstants.AuditLogActions.MEMBER_ROLE_UPDATE, + GuildAuditLogs.Actions.MEMBER_ROLE_UPDATE as number, member.id, ); - const mod = relevantAuditLogEntry ? relevantAuditLogEntry.user : new UnknownUser(); + const mod = relevantAuditLogEntry ? relevantAuditLogEntry.executor : new UnknownUser(); if (addedRoles.length && removedRoles.length) { // Roles added *and* removed diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index 55d115ec..ef0ba7af 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -1,46 +1,34 @@ import { logsEvt } from "../types"; import { stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; -/** Merge into single event -export const LogsVoiceJoinEvt = logsEvt({ - event: "voiceChannelJoin", - - async listener(meta) { - meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_JOIN, { - member: stripObjectToScalars(meta.args.member, ["user", "roles"]), - channel: stripObjectToScalars(meta.args.newChannel), - }); - }, -}); - -export const LogsVoiceLeaveEvt = logsEvt({ - event: "voiceChannelLeave", - - async listener(meta) { - meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_LEAVE, { - member: stripObjectToScalars(meta.args.member, ["user", "roles"]), - channel: stripObjectToScalars(meta.args.oldChannel), - }); - }, -}); - -export const LogsVoiceSwitchEvt = logsEvt({ - event: "voiceChannelSwitch", - - async listener(meta) { - meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_MOVE, { - member: stripObjectToScalars(meta.args.member, ["user", "roles"]), - oldChannel: stripObjectToScalars(meta.args.oldChannel), - newChannel: stripObjectToScalars(meta.args.newChannel), - }); - }, -}); -**/ export const LogsVoiceStateUpdateEvt = logsEvt({ event: "voiceStateUpdate", async listener(meta) { - console.error(`Fixme @LogsVoiceChannelEvts.ts`); + const oldChannel = meta.args.oldState.channel; + const newChannel = meta.args.newState.channel; + const member = meta.args.newState.member ?? meta.args.oldState.member!; + + if (!newChannel) { // Leave evt + meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_LEAVE, { + member: stripObjectToScalars(member, ["user", "roles"]), + oldChannel: stripObjectToScalars(oldChannel), + newChannel: stripObjectToScalars(newChannel), + }); + } else if (!oldChannel) { // Join Evt + meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_JOIN, { + member: stripObjectToScalars(member, ["user", "roles"]), + oldChannel: stripObjectToScalars(oldChannel), + newChannel: stripObjectToScalars(newChannel), + }); + } else { + meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_MOVE, { + member: stripObjectToScalars(member, ["user", "roles"]), + oldChannel: stripObjectToScalars(oldChannel), + newChannel: stripObjectToScalars(newChannel), + }); + } + }, }); diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts index 89542467..06baebc5 100644 --- a/backend/src/plugins/Logs/util/getLogMessage.ts +++ b/backend/src/plugins/Logs/util/getLogMessage.ts @@ -12,15 +12,15 @@ import { import { SavedMessage } from "../../../data/entities/SavedMessage"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { logger } from "../../../logger"; -import moment from "moment-timezone"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageOptions } from "discord.js"; export async function getLogMessage( pluginData: GuildPluginData, type: LogType, data: any, opts?: Pick, -): Promise { +): Promise { const config = pluginData.config.get(); const format = opts?.format?.[LogType[type]] || config.format[LogType[type]] || ""; if (format === "" || format == null) return null; diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 8e4840aa..ea65690d 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -6,6 +6,7 @@ import { createChunkedMessage, get, noop } from "../../../utils"; import { getLogMessage } from "./getLogMessage"; import { allowTimeout } from "../../../RegExpRunner"; import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { MessageMentionTypes, TextChannel } from "discord.js"; const excludedUserProps = ["user", "member", "mod"]; const excludedRoleProps = ["message.member.roles", "member.roles"]; @@ -46,8 +47,8 @@ export async function log(pluginData: GuildPluginData, type: Log for (const value of Object.values(data || {})) { if (value instanceof SavedMessage) { const member = pluginData.guild.members.cache.get(value.user_id); - for (const role of member?.roles || []) { - if (opts.excluded_roles.includes(role)) { + for (const role of member?.roles.cache || []) { + if (opts.excluded_roles.includes(role[0])) { continue logChannelLoop; } } @@ -128,7 +129,7 @@ export async function log(pluginData: GuildPluginData, type: Log if (message) { // For non-string log messages (i.e. embeds) batching or chunking is not possible, so send them immediately if (typeof message !== "string") { - await channel.createMessage(message).catch(noop); + await channel.send(message).catch(noop); return; } @@ -136,6 +137,7 @@ export async function log(pluginData: GuildPluginData, type: Log const batched = opts.batched ?? true; const batchTime = opts.batch_time ?? 1000; const cfg = pluginData.config.get(); + const parse: MessageMentionTypes[] | undefined = cfg.allow_user_mentions ? ["users"] : undefined; if (batched) { // If we're batching log messages, gather all log messages within the set batch_time into a single message @@ -144,14 +146,14 @@ export async function log(pluginData: GuildPluginData, type: Log setTimeout(async () => { const batchedMessage = pluginData.state.batches.get(channel.id)!.join("\n"); pluginData.state.batches.delete(channel.id); - createChunkedMessage(channel, batchedMessage, { users: cfg.allow_user_mentions }).catch(noop); + createChunkedMessage(channel, batchedMessage, { parse }).catch(noop); }, batchTime); } pluginData.state.batches.get(channel.id)!.push(message); } else { // If we're not batching log messages, just send them immediately - await createChunkedMessage(channel, message, { users: cfg.allow_user_mentions }).catch(noop); + await createChunkedMessage(channel, message, { parse }).catch(noop); } } } diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index eae416fd..a7437713 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -6,6 +6,7 @@ import moment from "moment-timezone"; import { GuildPluginData } from "knub"; import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageAttachment } from "discord.js"; export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); @@ -14,7 +15,7 @@ export async function onMessageDelete(pluginData: GuildPluginData, @@ -14,13 +15,13 @@ export async function onMessageUpdate( // To log a message update, either the message content or a rich embed has to change let logUpdate = false; - const oldEmbedsToCompare = ((oldSavedMessage.data.embeds || []) as Embed[]) + const oldEmbedsToCompare = ((oldSavedMessage.data.embeds || []) as MessageEmbed[]) .map(e => cloneDeep(e)) - .filter(e => (e as Embed).type === "rich"); + .filter(e => (e as MessageEmbed).type === "rich"); - const newEmbedsToCompare = ((savedMessage.data.embeds || []) as Embed[]) + const newEmbedsToCompare = ((savedMessage.data.embeds || []) as MessageEmbed[]) .map(e => cloneDeep(e)) - .filter(e => (e as Embed).type === "rich"); + .filter(e => (e as MessageEmbed).type === "rich"); for (const embed of [...oldEmbedsToCompare, ...newEmbedsToCompare]) { if (embed.thumbnail) { diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts index 114da844..226a8a2b 100644 --- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts @@ -14,7 +14,7 @@ export const SaveMessagesToDBCmd = messageSaverCmd({ }, async run({ message: msg, args, pluginData }) { - await msg.channel.createMessage("Saving specified messages..."); + await msg.channel.send("Saving specified messages..."); const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, args.ids.trim().split(" ")); if (failed.length) { diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index 2ecbf8e0..5d9484ed 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -13,13 +13,13 @@ export const SavePinsToDBCmd = messageSaverCmd({ }, async run({ message: msg, args, pluginData }) { - await msg.channel.createMessage(`Saving pins from <#${args.channel.id}>...`); + await msg.channel.send(`Saving pins from <#${args.channel.id}>...`); - const pins = await args.channel.getPins(); + const pins = await args.channel.messages.fetchPinned(); const { savedCount, failed } = await saveMessagesToDB( pluginData, args.channel, - pins.map(m => m.id), + pins.keyArray(), ); if (failed.length) { diff --git a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts index 51e34ff1..c9b093cd 100644 --- a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts +++ b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts @@ -1,3 +1,4 @@ +import { Message } from "discord.js"; import { messageSaverEvt } from "../types"; export const MessageCreateEvt = messageSaverEvt({ @@ -7,7 +8,7 @@ export const MessageCreateEvt = messageSaverEvt({ async listener(meta) { // Only save regular chat messages - if (meta.args.message.type !== 0) { + if (meta.args.message.type !== "DEFAULT" && meta.args.message.type !== "REPLY") { return; } @@ -21,11 +22,11 @@ export const MessageUpdateEvt = messageSaverEvt({ allowSelf: true, async listener(meta) { - if (meta.args.message.type !== 0) { + if (meta.args.newMessage.type !== "DEFAULT" && meta.args.newMessage.type !== "REPLY") { return; } - await meta.pluginData.state.savedMessages.saveEditFromMsg(meta.args.message); + await meta.pluginData.state.savedMessages.saveEditFromMsg(meta.args.newMessage as Message); }, }); @@ -36,7 +37,7 @@ export const MessageDeleteEvt = messageSaverEvt({ async listener(meta) { const msg = meta.args.message as Message; - if (msg.type != null && msg.type !== 0) { + if (msg.type != null && meta.args.message.type !== "DEFAULT" && meta.args.message.type !== "REPLY") { return; } diff --git a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts index 8e1635b9..dd0f3b80 100644 --- a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts @@ -1,5 +1,6 @@ import { MessageSaverPluginType } from "./types"; import { GuildPluginData } from "knub"; +import { TextChannel, Message } from "discord.js"; export async function saveMessagesToDB( pluginData: GuildPluginData, @@ -14,7 +15,7 @@ export async function saveMessagesToDB( let thisMsg: Message; try { - thisMsg = await channel.getMessage(id); + thisMsg = await channel.messages.fetch(id); if (!thisMsg) { failed.push(id); From d0a1beb8093e0dc7e7487b7baf4dc29a4efb9846 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 2 Jun 2021 04:07:50 +0200 Subject: [PATCH 05/79] Finish preliminary rework, ready to test --- .gitignore | 2 + backend/src/data/GuildSavedMessages.ts | 3 +- .../src/plugins/Automod/actions/addRoles.ts | 5 +- .../plugins/Automod/actions/removeRoles.ts | 5 +- .../functions/getTextMatchPartialSummary.ts | 6 +- .../plugins/Automod/triggers/memberJoin.ts | 2 +- .../commands/AddDashboardUserCmd.ts | 5 +- .../BotControl/commands/AllowServerCmd.ts | 9 +- .../BotControl/commands/DisallowServerCmd.ts | 10 ++- .../BotControl/commands/EligibleCmd.ts | 13 +-- .../BotControl/commands/LeaveServerCmd.ts | 13 +-- .../commands/ListDashboardPermsCmd.ts | 17 ++-- .../commands/ListDashboardUsersCmd.ts | 5 +- .../commands/ReloadGlobalPluginsCmd.ts | 3 +- .../BotControl/commands/ReloadServerCmd.ts | 11 +-- .../commands/RemoveDashboardUserCmd.ts | 5 +- .../plugins/BotControl/commands/ServersCmd.ts | 9 +- .../src/plugins/Censor/util/censorMessage.ts | 2 +- .../commands/ArchiveChannelCmd.ts | 11 ++- .../ChannelArchiver/rehostAttachment.ts | 5 +- .../functions/handleCompanionPermissions.ts | 8 +- .../Counters/commands/AddCounterCmd.ts | 8 +- .../CustomEvents/actions/addRoleAction.ts | 2 +- .../CustomEvents/actions/messageAction.ts | 3 +- .../actions/moveToVoiceChannelAction.ts | 5 +- .../actions/setChannelPermissionOverrides.ts | 7 +- .../CustomEvents/functions/runEvent.ts | 3 +- .../GuildAccessMonitorPlugin.ts | 5 +- .../plugins/LocateUser/commands/FollowCmd.ts | 4 +- .../LocateUser/events/SendAlertsEvts.ts | 6 +- .../plugins/LocateUser/utils/moveMember.ts | 2 +- .../Logs/events/LogsVoiceChannelEvts.ts | 7 +- .../MessageSaver/commands/SavePinsToDB.ts | 6 +- .../plugins/ModActions/ModActionsPlugin.ts | 5 +- .../plugins/ModActions/commands/AddCaseCmd.ts | 2 +- .../src/plugins/ModActions/commands/BanCmd.ts | 16 ++-- .../plugins/ModActions/commands/CaseCmd.ts | 2 +- .../ModActions/commands/CasesModCmd.ts | 5 +- .../ModActions/commands/CasesUserCmd.ts | 13 +-- .../ModActions/commands/DeleteCaseCmd.ts | 5 +- .../ModActions/commands/ForcebanCmd.ts | 7 +- .../plugins/ModActions/commands/MassBanCmd.ts | 12 ++- .../ModActions/commands/MassUnbanCmd.ts | 9 +- .../ModActions/commands/MassmuteCmd.ts | 7 +- .../plugins/ModActions/commands/MuteCmd.ts | 18 ++-- .../plugins/ModActions/commands/NoteCmd.ts | 4 +- .../ModActions/commands/SoftbanCommand.ts | 2 +- .../plugins/ModActions/commands/UnbanCmd.ts | 4 +- .../plugins/ModActions/commands/UnmuteCmd.ts | 7 +- .../plugins/ModActions/commands/WarnCmd.ts | 14 +-- .../events/CreateBanCaseOnManualBanEvt.ts | 8 +- .../events/CreateKickCaseOnManualKickEvt.ts | 7 +- .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 8 +- .../events/PostAlertOnMemberJoinEvt.ts | 9 +- .../functions/actualKickMemberCmd.ts | 9 +- .../ModActions/functions/actualMuteUserCmd.ts | 21 ++--- .../functions/actualUnmuteUserCmd.ts | 13 +-- .../plugins/ModActions/functions/banUserId.ts | 12 +-- .../functions/formatReasonWithAttachments.ts | 4 +- .../functions/getDefaultContactMethods.ts | 1 + .../plugins/ModActions/functions/isBanned.ts | 5 +- .../ModActions/functions/kickMember.ts | 3 +- .../functions/outdatedTempbansLoop.ts | 2 +- .../functions/readContactMethodsFromArgs.ts | 1 + .../ModActions/functions/updateCase.ts | 11 +-- .../ModActions/functions/warnMember.ts | 12 +-- backend/src/plugins/ModActions/types.ts | 1 + backend/src/plugins/Mutes/MutesPlugin.ts | 5 +- .../Mutes/commands/ClearBannedMutesCmd.ts | 10 +-- .../commands/ClearMutesWithoutRoleCmd.ts | 4 +- .../src/plugins/Mutes/commands/MutesCmd.ts | 31 ++++--- .../events/ClearActiveMuteOnMemberBanEvt.ts | 6 +- .../events/ClearActiveMuteOnRoleRemovalEvt.ts | 2 +- .../events/ReapplyActiveMuteOnJoinEvt.ts | 2 +- .../Mutes/functions/clearExpiredMutes.ts | 18 ++-- .../Mutes/functions/memberHasMutedRole.ts | 5 +- .../src/plugins/Mutes/functions/muteUser.ts | 27 +++--- .../src/plugins/Mutes/functions/unmuteUser.ts | 21 +++-- backend/src/plugins/Mutes/types.ts | 3 +- .../plugins/NameHistory/commands/NamesCmd.ts | 2 +- .../NameHistory/events/UpdateNameEvts.ts | 9 +- .../src/plugins/NameHistory/updateNickname.ts | 9 +- .../src/plugins/Persist/events/LoadDataEvt.ts | 13 +-- .../plugins/Persist/events/StoreDataEvt.ts | 7 +- backend/src/plugins/Post/commands/EditCmd.ts | 5 +- .../src/plugins/Post/commands/EditEmbedCmd.ts | 9 +- .../src/plugins/Post/commands/PostEmbedCmd.ts | 5 +- .../Post/commands/ScheduledPostsListCmd.ts | 2 +- .../Post/commands/ScheduledPostsShowCmd.ts | 1 + .../src/plugins/Post/util/actualPostCmd.ts | 49 +++++++---- backend/src/plugins/Post/util/postMessage.ts | 13 ++- .../plugins/Post/util/scheduledPostLoop.ts | 3 +- .../commands/ClearReactionRolesCmd.ts | 7 +- .../commands/InitReactionRolesCmd.ts | 8 +- .../events/AddReactionRoleEvt.ts | 12 +-- .../util/addMemberPendingRoleChange.ts | 4 +- .../applyReactionRoleReactionsToMessage.ts | 3 +- .../Reminders/utils/postDueRemindersLoop.ts | 5 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 7 +- .../plugins/Roles/commands/MassAddRoleCmd.ts | 13 +-- .../Roles/commands/MassRemoveRoleCmd.ts | 13 +-- .../plugins/Roles/commands/RemoveRoleCmd.ts | 7 +- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 5 +- .../commands/RoleHelpCmd.ts | 2 +- .../commands/RoleRemoveCmd.ts | 2 +- .../Slowmode/commands/SlowmodeGetCmd.ts | 5 +- .../Slowmode/commands/SlowmodeListCmd.ts | 5 +- .../Slowmode/commands/SlowmodeSetCmd.ts | 13 ++- .../plugins/Slowmode/requiredPermissions.ts | 12 +-- .../Slowmode/util/actualDisableSlowmodeCmd.ts | 11 +-- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 13 ++- .../util/clearBotSlowmodeFromUserId.ts | 3 +- .../Slowmode/util/clearExpiredSlowmodes.ts | 3 +- .../util/disableBotSlowmodeForChannel.ts | 1 + .../plugins/Slowmode/util/onMessageCreate.ts | 3 +- backend/src/plugins/Spam/SpamPlugin.ts | 5 +- .../src/plugins/Spam/events/SpamVoiceEvt.ts | 34 ++------ .../Spam/util/logAndDetectMessageSpam.ts | 3 +- .../Starboard/commands/MigratePinsCmd.ts | 5 +- .../events/StarboardReactionAddEvt.ts | 17 ++-- .../events/StarboardReactionRemoveEvts.ts | 5 +- .../util/createStarboardEmbedFromMessage.ts | 13 +-- .../createStarboardPseudoFooterForMessage.ts | 2 + .../Starboard/util/saveMessageToStarboard.ts | 3 +- .../util/updateStarboardMessageStarCount.ts | 1 + backend/src/plugins/Tags/TagsPlugin.ts | 4 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 2 +- .../src/plugins/Tags/commands/TagListCmd.ts | 2 +- .../src/plugins/Tags/commands/TagSourceCmd.ts | 2 +- .../Tags/util/matchAndRenderTagFromString.ts | 3 +- .../src/plugins/Tags/util/onMessageCreate.ts | 8 +- .../src/plugins/Tags/util/onMessageDelete.ts | 5 +- .../plugins/Tags/util/renderTagFromString.ts | 3 +- .../TimeAndDate/commands/ViewTimezoneCmd.ts | 4 +- .../events/UpdateUsernameEvts.ts | 6 +- .../plugins/UsernameSaver/updateUsername.ts | 1 + .../src/plugins/Utility/commands/AboutCmd.ts | 16 ++-- .../src/plugins/Utility/commands/AvatarCmd.ts | 10 ++- .../Utility/commands/ChannelInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/CleanCmd.ts | 9 +- .../plugins/Utility/commands/ContextCmd.ts | 10 ++- .../plugins/Utility/commands/EmojiInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/HelpCmd.ts | 2 +- .../src/plugins/Utility/commands/InfoCmd.ts | 20 ++--- .../plugins/Utility/commands/InviteInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/JumboCmd.ts | 2 +- .../src/plugins/Utility/commands/LevelCmd.ts | 4 +- .../Utility/commands/MessageInfoCmd.ts | 2 +- .../plugins/Utility/commands/NicknameCmd.ts | 8 +- .../Utility/commands/NicknameResetCmd.ts | 4 +- .../src/plugins/Utility/commands/PingCmd.ts | 19 ++--- .../Utility/commands/ReloadGuildCmd.ts | 3 +- .../plugins/Utility/commands/RoleInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/RolesCmd.ts | 13 +-- .../plugins/Utility/commands/ServerInfoCmd.ts | 2 +- .../Utility/commands/SnowflakeInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/SourceCmd.ts | 6 +- .../plugins/Utility/commands/UserInfoCmd.ts | 2 +- .../Utility/commands/VcdisconnectCmd.ts | 10 +-- .../src/plugins/Utility/commands/VcmoveCmd.ts | 25 +++--- .../Utility/functions/getChannelInfoEmbed.ts | 57 +++++++------ .../Utility/functions/getEmojiInfoEmbed.ts | 5 +- .../Utility/functions/getGuildPreview.ts | 3 +- .../Utility/functions/getInviteInfoEmbed.ts | 24 +++--- .../Utility/functions/getMessageInfoEmbed.ts | 40 +++++---- .../Utility/functions/getRoleInfoEmbed.ts | 9 +- .../Utility/functions/getServerInfoEmbed.ts | 47 +++++----- .../functions/getSnowflakeInfoEmbed.ts | 3 +- .../Utility/functions/getUserInfoEmbed.ts | 29 ++++--- backend/src/plugins/Utility/guildReloads.ts | 2 + backend/src/plugins/Utility/refreshMembers.ts | 3 +- backend/src/plugins/Utility/search.ts | 85 ++++++++++--------- .../events/SendWelcomeMessageEvt.ts | 3 +- backend/src/types.ts | 22 +++++ backend/src/utils.test.ts | 4 +- backend/src/utils.ts | 28 +++--- .../erisAllowedMentionsToDjsMentionOptions.ts | 8 +- 177 files changed, 854 insertions(+), 707 deletions(-) diff --git a/.gitignore b/.gitignore index 2d5e4afe..e3b71ab8 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ npm-audit.txt # Debug files *.debug.ts *.debug.js + +.vscode/ diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index 7bc4134d..b5759fde 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -211,7 +211,8 @@ export class GuildSavedMessages extends BaseGuildRepository { const newMessage = { ...oldMessage, data: newData }; - await this.messages.update( + //@ts-ignore + await this.messages.update( // FIXME? { id }, { data: newData, diff --git a/backend/src/plugins/Automod/actions/addRoles.ts b/backend/src/plugins/Automod/actions/addRoles.ts index 39f59870..ea467446 100644 --- a/backend/src/plugins/Automod/actions/addRoles.ts +++ b/backend/src/plugins/Automod/actions/addRoles.ts @@ -53,13 +53,13 @@ export const AddRolesAction = automodAction({ await Promise.all( members.map(async member => { - const memberRoles = new Set(member.roles); + const memberRoles = new Set(member.roles.cache.keyArray()); for (const roleId of rolesToAssign) { memberRoles.add(roleId); ignoreRoleChange(pluginData, member.id, roleId); } - if (memberRoles.size === member.roles.length) { + if (memberRoles.size === member.roles.cache.size) { // No role changes return; } @@ -70,7 +70,6 @@ export const AddRolesAction = automodAction({ await member.edit({ roles: rolesArr, }); - member.roles = rolesArr; // Make sure we know of the new roles internally as well memberRoleLock.unlock(); }), diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index dcfbd9d3..79e22fae 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -57,13 +57,13 @@ export const RemoveRolesAction = automodAction({ await Promise.all( members.map(async member => { - const memberRoles = new Set(member.roles); + const memberRoles = new Set(member.roles.cache.keyArray()); for (const roleId of rolesToRemove) { memberRoles.delete(roleId); ignoreRoleChange(pluginData, member.id, roleId); } - if (memberRoles.size === member.roles.length) { + if (memberRoles.size === member.roles.cache.size) { // No role changes return; } @@ -74,7 +74,6 @@ export const RemoveRolesAction = automodAction({ await member.edit({ roles: rolesArr, }); - member.roles = rolesArr; // Make sure we know of the new roles internally as well memberRoleLock.unlock(); }), diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts index 37a04fe4..99442b1e 100644 --- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts +++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts @@ -23,11 +23,11 @@ export function getTextMatchPartialSummary( } else if (type === "username") { return `username: ${context.user!.username}`; } else if (type === "nickname") { - return `nickname: ${context.member!.nick}`; + return `nickname: ${context.member!.nickname}`; } else if (type === "visiblename") { - const visibleName = context.member?.nick || context.user!.username; + const visibleName = context.member?.nickname || context.user!.username; return `visible name: ${visibleName}`; } else if (type === "customstatus") { - return `custom status: ${context.member!.game!.state}`; + return `custom status: ${context.member!.presence.activities.find(a => a.type === "CUSTOM_STATUS")?.name}`; } } diff --git a/backend/src/plugins/Automod/triggers/memberJoin.ts b/backend/src/plugins/Automod/triggers/memberJoin.ts index 210cd8e5..a94b6b52 100644 --- a/backend/src/plugins/Automod/triggers/memberJoin.ts +++ b/backend/src/plugins/Automod/triggers/memberJoin.ts @@ -20,7 +20,7 @@ export const MemberJoinTrigger = automodTrigger()({ if (triggerConfig.only_new) { const threshold = Date.now() - convertDelayStringToMS(triggerConfig.new_threshold)!; - return context.member.createdAt >= threshold ? {} : null; + return context.member.user.createdTimestamp >= threshold ? {} : null; } return {}; diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index 5bda2423..3e207b1e 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -2,6 +2,7 @@ import { botControlCmd } from "../types"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { ApiPermissions } from "@shared/apiPermissions"; +import { TextChannel } from "discord.js"; export const AddDashboardUserCmd = botControlCmd({ trigger: ["add_dashboard_user"], @@ -18,7 +19,7 @@ export const AddDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is not using Zeppelin"); return; } @@ -39,7 +40,7 @@ export const AddDashboardUserCmd = botControlCmd({ ); sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `The following users were given dashboard access for **${guild.name}**:\n\n${userNameList}`, ); }, diff --git a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts index 7d969f8f..751fdfcc 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -3,6 +3,7 @@ import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../.. import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isSnowflake } from "../../../utils"; import { ApiPermissions } from "@shared/apiPermissions"; +import { TextChannel } from "discord.js"; export const AllowServerCmd = botControlCmd({ trigger: ["allow_server", "allowserver", "add_server", "addserver"], @@ -19,17 +20,17 @@ export const AllowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (existing) { - sendErrorMessage(pluginData, msg.channel, "Server is already allowed!"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is already allowed!"); return; } if (!isSnowflake(args.guildId)) { - sendErrorMessage(pluginData, msg.channel, "Invalid server ID!"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid server ID!"); return; } if (args.userId && !isSnowflake(args.userId)) { - sendErrorMessage(pluginData, msg.channel, "Invalid user ID!"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid user ID!"); return; } @@ -40,6 +41,6 @@ export const AllowServerCmd = botControlCmd({ await pluginData.state.apiPermissionAssignments.addUser(args.guildId, args.userId, [ApiPermissions.EditConfig]); } - sendSuccessMessage(pluginData, msg.channel, "Server is now allowed to use Zeppelin!"); + sendSuccessMessage(pluginData, msg.channel as TextChannel, "Server is now allowed to use Zeppelin!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index fa882b8e..1fc4916e 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -2,6 +2,7 @@ import { botControlCmd } from "../types"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { noop } from "../../../utils"; +import { TextChannel } from "discord.js"; export const DisallowServerCmd = botControlCmd({ trigger: ["disallow_server", "disallowserver", "remove_server", "removeserver"], @@ -17,12 +18,15 @@ export const DisallowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (!existing) { - sendErrorMessage(pluginData, msg.channel, "That server is not allowed in the first place!"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "That server is not allowed in the first place!"); return; } await pluginData.state.allowedGuilds.remove(args.guildId); - await pluginData.client.leaveGuild(args.guildId).catch(noop); - sendSuccessMessage(pluginData, msg.channel, "Server removed!"); + await pluginData.client.guilds.cache + .get(args.guildId) + ?.leave() + .catch(noop); + sendSuccessMessage(pluginData, msg.channel as TextChannel, "Server removed!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index 922b423b..ff68d1d8 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -2,6 +2,7 @@ import { botControlCmd } from "../types"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { resolveInvite, verboseUserMention } from "../../../utils"; +import { TextChannel } from "discord.js"; const REQUIRED_MEMBER_COUNT = 5000; @@ -18,7 +19,7 @@ export const EligibleCmd = botControlCmd({ if ((await pluginData.state.apiPermissionAssignments.getByUserId(args.user.id)).length) { sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `${verboseUserMention(args.user)} is an existing bot operator. They are eligible!`, ); return; @@ -26,17 +27,17 @@ export const EligibleCmd = botControlCmd({ const invite = await resolveInvite(pluginData.client, args.inviteCode, true); if (!invite || !invite.guild) { - sendErrorMessage(pluginData, msg.channel, "Could not resolve server from invite"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not resolve server from invite"); return; } if (invite.guild.features.includes("PARTNERED")) { - sendSuccessMessage(pluginData, msg.channel, `Server is partnered. It is eligible!`); + sendSuccessMessage(pluginData, msg.channel as TextChannel, `Server is partnered. It is eligible!`); return; } if (invite.guild.features.includes("VERIFIED")) { - sendSuccessMessage(pluginData, msg.channel, `Server is verified. It is eligible!`); + sendSuccessMessage(pluginData, msg.channel as TextChannel, `Server is verified. It is eligible!`); return; } @@ -44,7 +45,7 @@ export const EligibleCmd = botControlCmd({ if (memberCount >= REQUIRED_MEMBER_COUNT) { sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `Server has ${memberCount} members, which is equal or higher than the required ${REQUIRED_MEMBER_COUNT}. It is eligible!`, ); return; @@ -52,7 +53,7 @@ export const EligibleCmd = botControlCmd({ sendErrorMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `Server **${invite.guild.name}** (\`${invite.guild.id}\`) is not eligible`, ); }, diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 51b47d1d..1d96eb96 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -1,6 +1,7 @@ import { botControlCmd } from "../types"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { TextChannel } from "discord.js"; export const LeaveServerCmd = botControlCmd({ trigger: ["leave_server", "leave_guild"], @@ -14,21 +15,21 @@ export const LeaveServerCmd = botControlCmd({ }, async run({ pluginData, message: msg, args }) { - if (!pluginData.client.guilds.has(args.guildId)) { - sendErrorMessage(pluginData, msg.channel, "I am not in that guild"); + if (!pluginData.client.guilds.cache.has(args.guildId)) { + sendErrorMessage(pluginData, msg.channel as TextChannel, "I am not in that guild"); return; } - const guildToLeave = pluginData.client.guilds.get(args.guildId)!; + const guildToLeave = await pluginData.client.guilds.fetch(args.guildId)!; const guildName = guildToLeave.name; try { - await pluginData.client.leaveGuild(args.guildId); + await pluginData.client.guilds.cache.get(args.guildId)?.leave(); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Failed to leave guild: ${e.message}`); + sendErrorMessage(pluginData, msg.channel as TextChannel, `Failed to leave guild: ${e.message}`); return; } - sendSuccessMessage(pluginData, msg.channel, `Left guild **${guildName}**`); + sendSuccessMessage(pluginData, msg.channel as TextChannel, `Left guild **${guildName}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index aa047547..2933cf32 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -4,6 +4,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { createChunkedMessage, resolveUser } from "../../../utils"; import { AllowedGuild } from "../../../data/entities/AllowedGuild"; import { ApiPermissionAssignment } from "../../../data/entities/ApiPermissionAssignment"; +import { TextChannel } from "discord.js"; export const ListDashboardPermsCmd = botControlCmd({ trigger: ["list_dashboard_permissions", "list_dashboard_perms", "list_dash_permissionss", "list_dash_perms"], @@ -19,7 +20,7 @@ export const ListDashboardPermsCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!args.user && !args.guildId) { - sendErrorMessage(pluginData, msg.channel, "Must specify at least guildId, user, or both."); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Must specify at least guildId, user, or both."); return; } @@ -27,7 +28,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.guildId) { guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is not using Zeppelin"); return; } } @@ -36,7 +37,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.user) { existingUserAssignment = await pluginData.state.apiPermissionAssignments.getByUserId(args.user.id); if (existingUserAssignment.length === 0) { - sendErrorMessage(pluginData, msg.channel, "The user has no assigned permissions."); + sendErrorMessage(pluginData, msg.channel as TextChannel, "The user has no assigned permissions."); return; } } @@ -59,7 +60,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (finalMessage === "") { sendErrorMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `The user ${userInfo} has no assigned permissions on the specified server.`, ); return; @@ -70,7 +71,11 @@ export const ListDashboardPermsCmd = botControlCmd({ const existingGuildAssignment = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id); if (existingGuildAssignment.length === 0) { - sendErrorMessage(pluginData, msg.channel, `The server ${guildInfo} has no assigned permissions.`); + sendErrorMessage( + pluginData, + msg.channel as TextChannel, + `The server ${guildInfo} has no assigned permissions.`, + ); return; } @@ -83,6 +88,6 @@ export const ListDashboardPermsCmd = botControlCmd({ } } - await sendSuccessMessage(pluginData, msg.channel, finalMessage.trim(), {}); + await sendSuccessMessage(pluginData, msg.channel as TextChannel, finalMessage.trim(), {}); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index 5d65525b..107579b2 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -3,6 +3,7 @@ import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../.. import { commandTypeHelpers as ct } from "../../../commandTypes"; import { ApiPermissions } from "@shared/apiPermissions"; import { resolveUser, UnknownUser } from "../../../utils"; +import { TextChannel } from "discord.js"; export const ListDashboardUsersCmd = botControlCmd({ trigger: ["list_dashboard_users"], @@ -18,7 +19,7 @@ export const ListDashboardUsersCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is not using Zeppelin"); return; } @@ -30,7 +31,7 @@ export const ListDashboardUsersCmd = botControlCmd({ sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `The following users have dashboard access for **${guild.name}**:\n\n${userNameList}`, {}, ); diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index 1e341d00..8be32a5e 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -1,6 +1,7 @@ import { botControlCmd } from "../types"; import { isOwnerPreFilter } from "../../../pluginUtils"; import { getActiveReload, setActiveReload } from "../activeReload"; +import { TextChannel } from "discord.js"; export const ReloadGlobalPluginsCmd = botControlCmd({ trigger: "bot_reload_global_plugins", @@ -13,7 +14,7 @@ export const ReloadGlobalPluginsCmd = botControlCmd({ if (getActiveReload()) return; setActiveReload((message.channel as TextChannel).guild?.id, message.channel.id); - await message.channel.createMessage("Reloading global plugins..."); + await message.channel.send("Reloading global plugins..."); pluginData.getKnubInstance().reloadGlobalContext(); }, diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 7c725e11..892ef744 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -1,6 +1,7 @@ import { botControlCmd } from "../types"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { TextChannel } from "discord.js"; export const ReloadServerCmd = botControlCmd({ trigger: ["reload_server", "reload_guild"], @@ -14,19 +15,19 @@ export const ReloadServerCmd = botControlCmd({ }, async run({ pluginData, message: msg, args }) { - if (!pluginData.client.guilds.has(args.guildId)) { - sendErrorMessage(pluginData, msg.channel, "I am not in that guild"); + if (!pluginData.client.guilds.cache.has(args.guildId)) { + sendErrorMessage(pluginData, msg.channel as TextChannel, "I am not in that guild"); return; } try { await pluginData.getKnubInstance().reloadGuild(args.guildId); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Failed to reload guild: ${e.message}`); + sendErrorMessage(pluginData, msg.channel as TextChannel, `Failed to reload guild: ${e.message}`); return; } - const guild = pluginData.client.guilds.get(args.guildId); - sendSuccessMessage(pluginData, msg.channel, `Reloaded guild **${guild?.name || "???"}**`); + const guild = await pluginData.client.guilds.fetch(args.guildId); + sendSuccessMessage(pluginData, msg.channel as TextChannel, `Reloaded guild **${guild?.name || "???"}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 078c189c..186e02a2 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -2,6 +2,7 @@ import { botControlCmd } from "../types"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { ApiPermissions } from "@shared/apiPermissions"; +import { TextChannel } from "discord.js"; export const RemoveDashboardUserCmd = botControlCmd({ trigger: ["remove_dashboard_user"], @@ -18,7 +19,7 @@ export const RemoveDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is not using Zeppelin"); return; } @@ -39,7 +40,7 @@ export const RemoveDashboardUserCmd = botControlCmd({ ); sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, ); }, diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index 7d4be31c..1d99230b 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -3,6 +3,7 @@ import { isOwnerPreFilter } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import escapeStringRegexp from "escape-string-regexp"; import { createChunkedMessage, getUser, sorter } from "../../../utils"; +import { TextChannel } from "discord.js"; export const ServersCmd = botControlCmd({ trigger: ["servers", "guilds"], @@ -23,7 +24,7 @@ export const ServersCmd = botControlCmd({ const showList = Boolean(args.all || args.initialized || args.uninitialized || args.search); const search = args.search ? new RegExp([...args.search].map(s => escapeStringRegexp(s)).join(".*"), "i") : null; - const joinedGuilds = Array.from(pluginData.client.guilds.values()); + const joinedGuilds = Array.from(pluginData.client.guilds.cache.values()); const loadedGuilds = pluginData.getKnubInstance().getLoadedGuilds(); const loadedGuildsMap = loadedGuilds.reduce((map, guildData) => map.set(guildData.guildId, guildData), new Map()); @@ -50,16 +51,16 @@ export const ServersCmd = botControlCmd({ const owner = getUser(pluginData.client, g.ownerID); return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.username}#${owner.discriminator}** \`${owner.id}\`)`; }); - createChunkedMessage(msg.channel, lines.join("\n")); + createChunkedMessage(msg.channel as TextChannel, lines.join("\n")); } else { - msg.channel.createMessage("No servers matched the filters"); + msg.channel.send("No servers matched the filters"); } } else { const total = joinedGuilds.length; const initialized = joinedGuilds.filter(g => loadedGuildsMap.has(g.id)).length; const unInitialized = total - initialized; - msg.channel.createMessage( + msg.channel.send( `I am on **${total} total servers**, of which **${initialized} are initialized** and **${unInitialized} are not initialized**`, ); } diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index 9591e81d..ad4c32ba 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -14,7 +14,7 @@ export async function censorMessage( pluginData.state.serverLogs.ignoreLog(LogType.MESSAGE_DELETE, savedMessage.id); try { - const channel = pluginData.guild.channels.resolve(savedMessage.channel_id) as TextChannel + const channel = pluginData.guild.channels.resolve(savedMessage.channel_id) as TextChannel; await channel.messages.delete(savedMessage.id); } catch { return; diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index b85aeb2f..faa67c18 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -104,6 +104,15 @@ export const ArchiveChannelCmd = channelArchiverCmd({ result += `\n\n${archiveLines.join("\n")}\n`; progressMsg.delete().catch(noop); - msg.channel.send({ content: "Archive created!", files: [{attachment: Buffer.from(result), name: `archive-${args.channel.name}-${moment.utc().format("YYYY-MM-DD-HH-mm-ss")}.txt`}], split: false }); + msg.channel.send({ + content: "Archive created!", + files: [ + { + attachment: Buffer.from(result), + name: `archive-${args.channel.name}-${moment.utc().format("YYYY-MM-DD-HH-mm-ss")}.txt`, + }, + ], + split: false, + }); }, }); diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index 56ef2924..bf05d122 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -18,7 +18,10 @@ export async function rehostAttachment(attachment: MessageAttachment, targetChan } try { - const content: MessageOptions = { content: `Rehost of attachment ${attachment.id}`, files: [{ name: attachment.name ? attachment.name : undefined, attachment: await fsp.readFile(downloaded.path)}]} + const content: MessageOptions = { + content: `Rehost of attachment ${attachment.id}`, + files: [{ name: attachment.name ? attachment.name : undefined, attachment: await fsp.readFile(downloaded.path) }], + }; const rehostMessage = await targetChannel.send({ content, split: false }); return rehostMessage.attachments.values()[0].url; } catch { diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index 022b01d7..1a338251 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -60,11 +60,9 @@ export async function handleCompanionPermissions( for (const [channelId, permissions] of permsToSet) { const channel = pluginData.guild.channels.cache.get(channelId); if (!channel || !(channel instanceof TextChannel)) continue; - await channel.updateOverwrite( - userId, - new Permissions(BigInt(permissions)).serialize(), - {reason: `Companion Channel for ${voiceChannel!.id} | User Joined`}, - ); + await channel.updateOverwrite(userId, new Permissions(BigInt(permissions)).serialize(), { + reason: `Companion Channel for ${voiceChannel!.id} | User Joined`, + }); } } catch (e) { if (isDiscordRESTError(e) && e.code === 50001) { diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 26c4da25..779c83f0 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -128,13 +128,9 @@ export const AddCounterCmd = typedGuildCommand()({ `Added ${amount} to **${counterName}** for <@!${user.id}> in <#${channel.id}>. The value is now ${newValue}.`, ); } else if (channel) { - message.channel.send( - `Added ${amount} to **${counterName}** in <#${channel.id}>. The value is now ${newValue}.`, - ); + message.channel.send(`Added ${amount} to **${counterName}** in <#${channel.id}>. The value is now ${newValue}.`); } else if (user) { - message.channel.send( - `Added ${amount} to **${counterName}** for <@!${user.id}>. The value is now ${newValue}.`, - ); + message.channel.send(`Added ${amount} to **${counterName}** for <@!${user.id}>. The value is now ${newValue}.`); } else { message.channel.send(`Added ${amount} to **${counterName}**. The value is now ${newValue}.`); } diff --git a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts index 1780ba60..f356e6f9 100644 --- a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts +++ b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts @@ -30,6 +30,6 @@ export async function addRoleAction( const rolesToAdd = Array.isArray(action.role) ? action.role : [action.role]; await target.edit({ - roles: Array.from(new Set([...target.roles, ...rolesToAdd])), + roles: Array.from(new Set([...target.roles.cache.array(), ...rolesToAdd])), }); } diff --git a/backend/src/plugins/CustomEvents/actions/messageAction.ts b/backend/src/plugins/CustomEvents/actions/messageAction.ts index bd4e6300..fe03eda0 100644 --- a/backend/src/plugins/CustomEvents/actions/messageAction.ts +++ b/backend/src/plugins/CustomEvents/actions/messageAction.ts @@ -3,6 +3,7 @@ import { CustomEventsPluginType } from "../types"; import * as t from "io-ts"; import { renderTemplate } from "../../../templateFormatter"; import { ActionError } from "../ActionError"; +import { TextChannel } from "discord.js"; export const MessageAction = t.type({ type: t.literal("message"), @@ -21,5 +22,5 @@ export async function messageAction( if (!targetChannel) throw new ActionError("Unknown target channel"); if (!(targetChannel instanceof TextChannel)) throw new ActionError("Target channel is not a text channel"); - await targetChannel.createMessage({ content: action.content }); + await targetChannel.send({ content: action.content }); } diff --git a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts index 33636c5c..6d8f0731 100644 --- a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts +++ b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts @@ -5,6 +5,7 @@ import { renderTemplate } from "../../../templateFormatter"; import { resolveMember } from "../../../utils"; import { ActionError } from "../ActionError"; import { canActOn } from "../../../pluginUtils"; +import { VoiceChannel } from "discord.js"; export const MoveToVoiceChannelAction = t.type({ type: t.literal("move_to_vc"), @@ -33,8 +34,8 @@ export async function moveToVoiceChannelAction( if (!targetChannel) throw new ActionError("Unknown target channel"); if (!(targetChannel instanceof VoiceChannel)) throw new ActionError("Target channel is not a voice channel"); - if (!target.voiceState.channelID) return; + if (!target.voice.channelID) return; await target.edit({ - channelID: targetChannel.id, + channel: targetChannel.id, }); } diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index 48114ec0..24555c2e 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -30,11 +30,8 @@ export async function setChannelPermissionOverridesAction( } for (const override of action.overrides) { - await channel.editPermission( - override.id, - override.allow, - override.deny, - override.type, + await channel.overwritePermissions( + [{ id: override.id, allow: BigInt(override.allow), deny: BigInt(override.deny), type: override.type }], `Custom event: ${event.name}`, ); } diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index e6e909da..5a4121ac 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -10,6 +10,7 @@ import { messageAction } from "../actions/messageAction"; import { makeRoleMentionableAction } from "../actions/makeRoleMentionableAction"; import { makeRoleUnmentionableAction } from "../actions/makeRoleUnmentionableAction"; import { setChannelPermissionOverridesAction } from "../actions/setChannelPermissionOverrides"; +import { Message, TextChannel } from "discord.js"; export async function runEvent( pluginData: GuildPluginData, @@ -38,7 +39,7 @@ export async function runEvent( } catch (e) { if (e instanceof ActionError) { if (event.trigger.type === "command") { - sendErrorMessage(pluginData, (eventData.msg as Message).channel, e.message); + sendErrorMessage(pluginData, (eventData.msg as Message).channel as TextChannel, e.message); } else { // TODO: Where to log action errors from other kinds of triggers? } diff --git a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts index 5689cd73..ca322168 100644 --- a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts +++ b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts @@ -2,6 +2,7 @@ import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; import { BasePluginType, typedGlobalEventListener, GlobalPluginData } from "knub"; import * as t from "io-ts"; import { AllowedGuilds } from "../../data/AllowedGuilds"; +import { Guild } from "discord.js"; interface GuildAccessMonitorPluginType extends BasePluginType { config: {}; @@ -27,7 +28,7 @@ export const GuildAccessMonitorPlugin = zeppelinGlobalPlugin()({ - event: "guildAvailable", + event: "guildCreate", listener({ pluginData, args: { guild } }) { checkGuild(pluginData, guild); }, @@ -39,7 +40,7 @@ export const GuildAccessMonitorPlugin = zeppelinGlobalPlugin joins or switches VC in the next ${humanizeDuration( - time, - )} i will notify you`, + `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration(time)} i will notify you`, ); } }, diff --git a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts index f506069c..d1f5e18c 100644 --- a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts +++ b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts @@ -6,7 +6,7 @@ export const VoiceStateUpdateAlertEvt = locateUserEvt({ event: "voiceStateUpdate", async listener(meta) { - const memberId = meta.args.oldState.member ? meta.args.oldState.member.id : meta.args.newState.member!.id; + const memberId = meta.args.oldState.member ? meta.args.oldState.member.id : meta.args.newState.member!.id; if (meta.args.newState.channel != null) { if (meta.pluginData.state.usersWithAlerts.includes(memberId)) { @@ -20,8 +20,8 @@ export const VoiceStateUpdateAlertEvt = locateUserEvt({ const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id) as TextChannel; txtChannel.send( `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`<#!${voiceChannel.id}>\``, - ); - }); + ); + }); } }, }); diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index 4289b2a1..6e74ae4b 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -13,7 +13,7 @@ export async function moveMember( if (modMember.voice.channelID != null) { try { await modMember.edit({ - channel: target.voice.channelID + channel: target.voice.channelID, }); } catch { sendErrorMessage(pluginData, errorChannel, "Failed to move you. Are you in a voice channel?"); diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index ef0ba7af..61ce1593 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -10,13 +10,15 @@ export const LogsVoiceStateUpdateEvt = logsEvt({ const newChannel = meta.args.newState.channel; const member = meta.args.newState.member ?? meta.args.oldState.member!; - if (!newChannel) { // Leave evt + if (!newChannel) { + // Leave evt meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_LEAVE, { member: stripObjectToScalars(member, ["user", "roles"]), oldChannel: stripObjectToScalars(oldChannel), newChannel: stripObjectToScalars(newChannel), }); - } else if (!oldChannel) { // Join Evt + } else if (!oldChannel) { + // Join Evt meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_JOIN, { member: stripObjectToScalars(member, ["user", "roles"]), oldChannel: stripObjectToScalars(oldChannel), @@ -29,6 +31,5 @@ export const LogsVoiceStateUpdateEvt = logsEvt({ newChannel: stripObjectToScalars(newChannel), }); } - }, }); diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index 5d9484ed..a159a642 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -16,11 +16,7 @@ export const SavePinsToDBCmd = messageSaverCmd({ await msg.channel.send(`Saving pins from <#${args.channel.id}>...`); const pins = await args.channel.messages.fetchPinned(); - const { savedCount, failed } = await saveMessagesToDB( - pluginData, - args.channel, - pins.keyArray(), - ); + const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, pins.keyArray()); if (failed.length) { sendSuccessMessage( diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 499f8176..f0a51c69 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -45,6 +45,7 @@ import { onModActionsEvent } from "./functions/onModActionsEvent"; import { offModActionsEvent } from "./functions/offModActionsEvent"; import { updateCase } from "./functions/updateCase"; import { Queue } from "../../Queue"; +import { GuildMember, Message } from "discord.js"; const defaultOptions = { config: { @@ -158,13 +159,13 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ public: { warnMember(pluginData) { - return (member: Member, reason: string, warnOptions?: WarnOptions) => { + return (member: GuildMember, reason: string, warnOptions?: WarnOptions) => { warnMember(pluginData, member, reason, warnOptions); }; }, kickMember(pluginData) { - return (member: Member, reason: string, kickOptions?: KickOptions) => { + return (member: GuildMember, reason: string, kickOptions?: KickOptions) => { kickMember(pluginData, member, reason, kickOptions); }; }, diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts index 6e0caf16..7f2a551d 100644 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts @@ -59,7 +59,7 @@ export const AddCaseCmd = modActionsCmd({ return; } - const reason = formatReasonWithAttachments(args.reason, msg.attachments); + const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); // Create the case const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index 71f61310..f8cb4ff9 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -6,7 +6,7 @@ import { isBanned } from "../functions/isBanned"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { banUserId } from "../functions/banUserId"; -import { getMemberLevel, waitForReaction } from "knub/dist/helpers"; +import { getMemberLevel } from "knub/dist/helpers"; import humanizeDuration from "humanize-duration"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -49,7 +49,7 @@ export const BanCmd = modActionsCmd({ } const time = args["time"] ? args["time"] : null; - const reason = formatReasonWithAttachments(args.reason, msg.attachments); + const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id); // The moderator who did the action is the message author or, if used, the specified -mod let mod = msg.member; @@ -76,11 +76,11 @@ export const BanCmd = modActionsCmd({ } // Ask the mod if we should update the existing ban - const alreadyBannedMsg = await msg.channel.createMessage("User is already banned, update ban?"); - const reply = await waitForReaction(pluginData.client, alreadyBannedMsg, ["✅", "❌"], msg.author.id); + const alreadyBannedMsg = await msg.channel.send("User is already banned, update ban?"); + const reply = false; // await waitForReaction(pluginData.client, alreadyBannedMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton alreadyBannedMsg.delete().catch(noop); - if (!reply || reply.name === "❌") { + if (!reply /* || reply.name === "❌"*/) { sendErrorMessage(pluginData, msg.channel, "User already banned, update cancelled by moderator"); lock.unlock(); return; @@ -124,11 +124,11 @@ export const BanCmd = modActionsCmd({ } } else { // Ask the mod if we should upgrade to a forceban as the user is not on the server - const notOnServerMsg = await msg.channel.createMessage("User not found on the server, forceban instead?"); - const reply = await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); + const notOnServerMsg = await msg.channel.send("User not found on the server, forceban instead?"); + const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); Waiting for waitForButton notOnServerMsg.delete().catch(noop); - if (!reply || reply.name === "❌") { + if (!reply /*|| reply.name === "❌"*/) { sendErrorMessage(pluginData, msg.channel, "User not on server, ban cancelled by moderator"); lock.unlock(); return; diff --git a/backend/src/plugins/ModActions/commands/CaseCmd.ts b/backend/src/plugins/ModActions/commands/CaseCmd.ts index ff5932c5..6c50d4c8 100644 --- a/backend/src/plugins/ModActions/commands/CaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/CaseCmd.ts @@ -24,6 +24,6 @@ export const CaseCmd = modActionsCmd({ const casesPlugin = pluginData.getPlugin(CasesPlugin); const embed = await casesPlugin.getCaseEmbed(theCase.id, msg.author.id); - msg.channel.createMessage(embed); + msg.channel.send(embed); }, }); diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 8a4d7d79..49bbc937 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -9,6 +9,7 @@ import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { createPaginatedMessage } from "../../../utils/createPaginatedMessage"; +import { MessageEmbedOptions, User } from "discord.js"; const opts = { mod: ct.userId({ option: true }), @@ -55,10 +56,10 @@ export const CasesModCmd = modActionsCmd({ const lastCaseNum = page * casesPerPage; const title = `Most recent cases ${firstCaseNum}-${lastCaseNum} of ${totalCases} by ${modName}`; - const embed: EmbedOptions = { + const embed: MessageEmbedOptions = { author: { name: title, - icon_url: mod instanceof User ? mod.avatarURL || mod.defaultAvatarURL : undefined, + iconURL: mod instanceof User ? mod.avatarURL() || mod.defaultAvatarURL : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index 8cfade7a..7fa4f499 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -16,6 +16,7 @@ import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { asyncMap } from "../../../utils/async"; import { CaseTypes } from "../../../data/CaseTypes"; +import { MessageEmbedOptions, User } from "discord.js"; const opts = { expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), @@ -75,13 +76,13 @@ export const CasesUserCmd = modActionsCmd({ : `${user.username}#${user.discriminator}`; if (cases.length === 0) { - msg.channel.createMessage(`No cases found for **${userName}**`); + msg.channel.send(`No cases found for **${userName}**`); } else { const casesToDisplay = args.hidden ? cases : normalCases; if (args.expand) { if (casesToDisplay.length > 8) { - msg.channel.createMessage("Too many cases for expanded view. Please use compact view instead."); + msg.channel.send("Too many cases for expanded view. Please use compact view instead."); return; } @@ -89,7 +90,7 @@ export const CasesUserCmd = modActionsCmd({ const casesPlugin = pluginData.getPlugin(CasesPlugin); for (const theCase of casesToDisplay) { const embed = await casesPlugin.getCaseEmbed(theCase.id); - msg.channel.createMessage(embed); + msg.channel.send(embed); } } else { // Compact view (= regular message with a preview of each case) @@ -121,13 +122,13 @@ export const CasesUserCmd = modActionsCmd({ const chunkStart = i * linesPerChunk + 1; const chunkEnd = Math.min((i + 1) * linesPerChunk, lines.length); - const embed: EmbedOptions = { + const embed: MessageEmbedOptions = { author: { name: lineChunks.length === 1 ? `Cases for ${userName} (${lines.length} total)` : `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`, - icon_url: user instanceof User ? user.avatarURL || user.defaultAvatarURL : undefined, + icon_url: user instanceof User ? user.avatarURL() || user.defaultAvatarURL : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")), @@ -135,7 +136,7 @@ export const CasesUserCmd = modActionsCmd({ ], }; - msg.channel.createMessage({ embed }); + msg.channel.send({ embed }); } } } diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 1756b2b7..ecda9c25 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -10,6 +10,7 @@ import { LogType } from "../../../data/LogType"; import moment from "moment-timezone"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { Case } from "../../../data/entities/Case"; +import { TextChannel } from "discord.js"; export const DeleteCaseCmd = modActionsCmd({ trigger: ["delete_case", "deletecase"], @@ -49,7 +50,7 @@ export const DeleteCaseCmd = modActionsCmd({ if (!args.force) { const cases = pluginData.getPlugin(CasesPlugin); const embedContent = await cases.getCaseEmbed(theCase); - message.channel.createMessage({ + message.channel.send({ content: "Delete the following case? Answer 'Yes' to continue, 'No' to cancel.", embed: embedContent.embed, }); @@ -62,7 +63,7 @@ export const DeleteCaseCmd = modActionsCmd({ ); const normalizedReply = (reply?.content || "").toLowerCase().trim(); if (normalizedReply !== "yes" && normalizedReply !== "y") { - message.channel.createMessage("Cancelled. Case was not deleted."); + message.channel.send("Cancelled. Case was not deleted."); cancelled++; continue; } diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index cdbbbc97..6ba06b74 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -61,14 +61,17 @@ export const ForcebanCmd = modActionsCmd({ mod = args.mod; } - const reason = formatReasonWithAttachments(args.reason, msg.attachments); + const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); ignoreEvent(pluginData, IgnoredEventType.Ban, user.id); pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, user.id); try { // FIXME: Use banUserId()? - await pluginData.guild.banMember(user.id, 1, reason != null ? encodeURIComponent(reason) : undefined); + await pluginData.guild.bans.create(user.id, { + days: 1, + reason: reason != null ? encodeURIComponent(reason) : undefined, + }); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to forceban member"); return; diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 73b93174..758dd268 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -15,6 +15,7 @@ import { LogType } from "../../../data/LogType"; import { performance } from "perf_hooks"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { load } from "js-yaml"; +import { TextChannel } from "discord.js"; export const MassbanCmd = modActionsCmd({ trigger: "massban", @@ -35,14 +36,14 @@ export const MassbanCmd = modActionsCmd({ } // Ask for ban reason (cleaner this way instead of trying to cram it into the args) - msg.channel.createMessage("Ban reason? `cancel` to cancel"); + msg.channel.send("Ban reason? `cancel` to cancel"); const banReasonReply = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id); if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { sendErrorMessage(pluginData, msg.channel, "Cancelled"); return; } - const banReason = formatReasonWithAttachments(banReasonReply.content, msg.attachments); + const banReason = formatReasonWithAttachments(banReasonReply.content, msg.attachments.array()); // Verify we can act on each of the users specified for (const userId of args.userIds) { @@ -60,7 +61,7 @@ export const MassbanCmd = modActionsCmd({ pluginData.state.massbanQueue.length === 0 ? "Banning..." : `Massban queued. Waiting for previous massban to finish (max wait ${maxWaitTimeFormatted}).`; - const loadingMsg = await msg.channel.createMessage(initialLoadingText); + const loadingMsg = await msg.channel.send(initialLoadingText); const waitTimeStart = performance.now(); const waitingInterval = setInterval(() => { @@ -95,7 +96,10 @@ export const MassbanCmd = modActionsCmd({ ignoreEvent(pluginData, IgnoredEventType.Ban, userId, 120 * 1000); pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId, 120 * 1000); - await pluginData.guild.banMember(userId, 1, banReason != null ? encodeURIComponent(banReason) : undefined); + await pluginData.guild.bans.create(userId, { + days: 1, + reason: banReason != null ? encodeURIComponent(banReason) : undefined, + }); await casesPlugin.createCase({ userId, diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index ac0b3f39..d4673dbf 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -10,6 +10,7 @@ import { waitForReply } from "knub/dist/helpers"; import { ignoreEvent } from "../functions/ignoreEvent"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { LogType } from "../../../data/LogType"; +import { TextChannel } from "discord.js"; export const MassunbanCmd = modActionsCmd({ trigger: "massunban", @@ -30,14 +31,14 @@ export const MassunbanCmd = modActionsCmd({ } // Ask for unban reason (cleaner this way instead of trying to cram it into the args) - msg.channel.createMessage("Unban reason? `cancel` to cancel"); + msg.channel.send("Unban reason? `cancel` to cancel"); const unbanReasonReply = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id); if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { sendErrorMessage(pluginData, msg.channel, "Cancelled"); return; } - const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, msg.attachments); + const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, msg.attachments.array()); // Ignore automatic unban cases and logs for these users // We'll create our own cases below and post a single "mass unbanned" log instead @@ -48,7 +49,7 @@ export const MassunbanCmd = modActionsCmd({ }); // Show a loading indicator since this can take a while - const loadingMsg = await msg.channel.createMessage("Unbanning..."); + const loadingMsg = await msg.channel.send("Unbanning..."); // Unban each user and count failed unbans (if any) const failedUnbans: Array<{ userId: string; reason: UnbanFailReasons }> = []; @@ -60,7 +61,7 @@ export const MassunbanCmd = modActionsCmd({ } try { - await pluginData.guild.unbanMember(userId, unbanReason != null ? encodeURIComponent(unbanReason) : undefined); + await pluginData.guild.bans.remove(userId, unbanReason != null ? encodeURIComponent(unbanReason) : undefined); await casesPlugin.createCase({ userId, diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index eeceabd3..15c2e90f 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -8,6 +8,7 @@ import { waitForReply } from "knub/dist/helpers"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; +import { TextChannel } from "discord.js"; export const MassmuteCmd = modActionsCmd({ trigger: "massmute", @@ -28,7 +29,7 @@ export const MassmuteCmd = modActionsCmd({ } // Ask for mute reason - msg.channel.createMessage("Mute reason? `cancel` to cancel"); + msg.channel.send("Mute reason? `cancel` to cancel"); const muteReasonReceived = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id); if ( !muteReasonReceived || @@ -39,7 +40,7 @@ export const MassmuteCmd = modActionsCmd({ return; } - const muteReason = formatReasonWithAttachments(muteReasonReceived.content, msg.attachments); + const muteReason = formatReasonWithAttachments(muteReasonReceived.content, msg.attachments.array()); // Verify we can act upon all users for (const userId of args.userIds) { @@ -58,7 +59,7 @@ export const MassmuteCmd = modActionsCmd({ }); // Show loading indicator - const loadingMsg = await msg.channel.createMessage("Muting..."); + const loadingMsg = await msg.channel.send("Muting..."); // Mute everyone and count fails const modId = msg.author.id; diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/MuteCmd.ts index c8336aae..67f5ce71 100644 --- a/backend/src/plugins/ModActions/commands/MuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MuteCmd.ts @@ -1,16 +1,8 @@ import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { Case } from "../../../data/entities/Case"; -import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogType } from "../../../data/LogType"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { errorMessage, noop, resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { canActOn, sendErrorMessage } from "../../../pluginUtils"; +import { noop, resolveMember, resolveUser } from "../../../utils"; import { isBanned } from "../functions/isBanned"; -import { waitForReaction } from "knub/dist/helpers"; -import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; -import { warnMember } from "../functions/warnMember"; import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; @@ -62,11 +54,11 @@ export const MuteCmd = modActionsCmd({ return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server - const notOnServerMsg = await msg.channel.createMessage("User not found on the server, forcemute instead?"); - const reply = await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); + const notOnServerMsg = await msg.channel.send("User not found on the server, forcemute instead?"); + const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton notOnServerMsg.delete().catch(noop); - if (!reply || reply.name === "❌") { + if (!reply /*|| reply.name === "❌"*/) { sendErrorMessage(pluginData, msg.channel, "User not on server, mute cancelled by moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index af6a1298..4b31954d 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -25,13 +25,13 @@ export const NoteCmd = modActionsCmd({ return; } - if (!args.note && msg.attachments.length === 0) { + if (!args.note && msg.attachments.size === 0) { sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); return; } const userName = `${user.username}#${user.discriminator}`; - const reason = formatReasonWithAttachments(args.note, msg.attachments); + const reason = formatReasonWithAttachments(args.note, msg.attachments.array()); const casesPlugin = pluginData.getPlugin(CasesPlugin); const createdCase = await casesPlugin.createCase({ diff --git a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts index 8105aae3..ea768f09 100644 --- a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts +++ b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts @@ -28,7 +28,7 @@ export const SoftbanCmd = modActionsCmd({ async run({ pluginData, message: msg, args }) { await actualKickMemberCmd(pluginData, msg, { clean: true, ...args }); - await msg.channel.createMessage( + await msg.channel.send( "Softban will be removed in the future - please use the kick command with the `-clean` argument instead!", ); }, diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index c3016a9b..ada9c975 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -45,11 +45,11 @@ export const UnbanCmd = modActionsCmd({ } pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, user.id); - const reason = formatReasonWithAttachments(args.reason, msg.attachments); + const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); try { ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); - await pluginData.guild.unbanMember(user.id, reason != null ? encodeURIComponent(reason) : undefined); + await pluginData.guild.bans.remove(user.id, reason != null ? encodeURIComponent(reason) : undefined); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to unban member; are you sure they're banned?"); return; diff --git a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts index c294517c..53cc6728 100644 --- a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts @@ -5,7 +5,6 @@ import { resolveUser, resolveMember, noop } from "../../../utils"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; import { isBanned } from "../functions/isBanned"; -import { waitForReaction } from "knub/dist/helpers"; const opts = { mod: ct.member({ option: true }), @@ -61,11 +60,11 @@ export const UnmuteCmd = modActionsCmd({ return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server - const notOnServerMsg = await msg.channel.createMessage("User not found on the server, forceunmute instead?"); - const reply = await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); + const notOnServerMsg = await msg.channel.send("User not found on the server, forceunmute instead?"); + const reply = false; //await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton notOnServerMsg.delete().catch(noop); - if (!reply || reply.name === "❌") { + if (!reply /*|| reply.name === "❌"*/) { sendErrorMessage(pluginData, msg.channel, "User not on server, unmute cancelled by moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index 22e4e660..9f347c97 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -8,9 +8,9 @@ import { LogType } from "../../../data/LogType"; import { CaseTypes } from "../../../data/CaseTypes"; import { errorMessage, resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; import { isBanned } from "../functions/isBanned"; -import { waitForReaction } from "knub/dist/helpers"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; import { warnMember } from "../functions/warnMember"; +import { TextChannel } from "discord.js"; export const WarnCmd = modActionsCmd({ trigger: "warn", @@ -56,7 +56,7 @@ export const WarnCmd = modActionsCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - msg.channel.createMessage(errorMessage("You don't have permission to use -mod")); + msg.channel.send(errorMessage("You don't have permission to use -mod")); return; } @@ -64,19 +64,19 @@ export const WarnCmd = modActionsCmd({ } const config = pluginData.config.get(); - const reason = formatReasonWithAttachments(args.reason, msg.attachments); + const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); const casesPlugin = pluginData.getPlugin(CasesPlugin); const priorWarnAmount = await casesPlugin.getCaseTypeAmountForUserId(memberToWarn.id, CaseTypes.Warn); if (config.warn_notify_enabled && priorWarnAmount >= config.warn_notify_threshold) { - const tooManyWarningsMsg = await msg.channel.createMessage( + const tooManyWarningsMsg = await msg.channel.send( config.warn_notify_message.replace("{priorWarnings}", `${priorWarnAmount}`), ); - const reply = await waitForReaction(pluginData.client, tooManyWarningsMsg, ["✅", "❌"], msg.author.id); + const reply = false; //await waitForReaction(pluginData.client, tooManyWarningsMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton tooManyWarningsMsg.delete(); - if (!reply || reply.name === "❌") { - msg.channel.createMessage(errorMessage("Warn cancelled by moderator")); + if (!reply /*|| reply.name === "❌"*/) { + msg.channel.send(errorMessage("Warn cancelled by moderator")); return; } } diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index 1d206a7c..cc9b975c 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -8,6 +8,7 @@ import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAu import { LogType } from "../../../data/LogType"; import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils"; import { Case } from "../../../data/entities/Case"; +import { GuildAuditLogs, User } from "discord.js"; /** * Create a BAN case automatically when a user is banned manually. @@ -15,7 +16,8 @@ import { Case } from "../../../data/entities/Case"; */ export const CreateBanCaseOnManualBanEvt = modActionsEvt({ event: "guildBanAdd", - async listener({ pluginData, args: { guild, user } }) { + async listener({ pluginData, args: { ban } }) { + const user = ban.user; if (isEventIgnored(pluginData, IgnoredEventType.Ban, user.id)) { clearIgnoredEvents(pluginData, IgnoredEventType.Ban, user.id); return; @@ -23,7 +25,7 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt({ const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry( pluginData, - ErisConstants.AuditLogActions.MEMBER_BAN_ADD, + GuildAuditLogs.Actions.MEMBER_BAN_ADD as number, user.id, ); @@ -34,7 +36,7 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt({ let reason = ""; if (relevantAuditLogEntry) { - const modId = relevantAuditLogEntry.user.id; + const modId = relevantAuditLogEntry.executor!.id; const auditLogId = relevantAuditLogEntry.id; mod = await resolveUser(pluginData.client, modId); diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index 07d9f01f..3229058d 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -9,6 +9,7 @@ import { LogType } from "../../../data/LogType"; import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { Case } from "../../../data/entities/Case"; +import { GuildAuditLogs, User } from "discord.js"; /** * Create a KICK case automatically when a user is kicked manually. @@ -24,7 +25,7 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({ const kickAuditLogEntry = await safeFindRelevantAuditLogEntry( pluginData, - ErisConstants.AuditLogActions.MEMBER_KICK, + GuildAuditLogs.Actions.MEMBER_KICK as number, member.id, ); @@ -40,7 +41,7 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({ `Tried to create duplicate case for audit log entry ${kickAuditLogEntry.id}, existing case id ${createdCase.id}`, ); } else { - mod = await resolveUser(pluginData.client, kickAuditLogEntry.user.id); + mod = await resolveUser(pluginData.client, kickAuditLogEntry.executor!.id); const config = mod instanceof UnknownUser ? pluginData.config.get() : await pluginData.config.getForUser(mod); @@ -48,7 +49,7 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({ const casesPlugin = pluginData.getPlugin(CasesPlugin); createdCase = await casesPlugin.createCase({ userId: member.id, - modId: kickAuditLogEntry.user.id, + modId: mod.id, type: CaseTypes.Kick, auditLogId: kickAuditLogEntry.id, reason: kickAuditLogEntry.reason || undefined, diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index 00d21ab2..5d684e97 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -8,6 +8,7 @@ import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAu import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { Case } from "../../../data/entities/Case"; +import { GuildAuditLogs, User } from "discord.js"; /** * Create an UNBAN case automatically when a user is unbanned manually. @@ -15,7 +16,8 @@ import { Case } from "../../../data/entities/Case"; */ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({ event: "guildBanRemove", - async listener({ pluginData, args: { guild, user } }) { + async listener({ pluginData, args: { ban } }) { + const user = ban.user; if (isEventIgnored(pluginData, IgnoredEventType.Unban, user.id)) { clearIgnoredEvents(pluginData, IgnoredEventType.Unban, user.id); return; @@ -23,7 +25,7 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({ const relevantAuditLogEntry = await safeFindRelevantAuditLogEntry( pluginData, - ErisConstants.AuditLogActions.MEMBER_BAN_REMOVE, + GuildAuditLogs.Actions.MEMBER_BAN_REMOVE as number, user.id, ); @@ -33,7 +35,7 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({ let mod: User | UnknownUser | null = null; if (relevantAuditLogEntry) { - const modId = relevantAuditLogEntry.user.id; + const modId = relevantAuditLogEntry.executor!.id; const auditLogId = relevantAuditLogEntry.id; mod = await resolveUser(pluginData.client, modId); diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index cef6c2e5..d13ecef4 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -4,13 +4,14 @@ import { LogType } from "../../../data/LogType"; import { resolveMember } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; +import { TextChannel, Constants, Permissions } from "discord.js"; /** * Show an alert if a member with prior notes joins the server */ export const PostAlertOnMemberJoinEvt = modActionsEvt({ event: "guildMemberAdd", - async listener({ pluginData, args: { guild, member } }) { + async listener({ pluginData, args: { member } }) { const config = pluginData.config.get(); if (!config.alert_on_rejoin) return; @@ -38,15 +39,15 @@ export const PostAlertOnMemberJoinEvt = modActionsEvt({ } const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user!.id); - const botPerms = alertChannel.permissionsOf(botMember ?? pluginData.client.user!.id); - if (!hasDiscordPermissions(botPerms, Constants.Permissions.sendMessages)) { + const botPerms = alertChannel.permissionsFor(botMember ?? pluginData.client.user!.id); + if (!hasDiscordPermissions(botPerms, Permissions.FLAGS.SEND_MESSAGES)) { logs.log(LogType.BOT_ALERT, { body: `Missing "Send Messages" permissions for the \`alert_channel\` configured in \`mod_actions\`: \`${alertChannelId}\``, }); return; } - await alertChannel.createMessage( + await alertChannel.send( `<@!${member.id}> (${member.user.username}#${member.user.discriminator} \`${member.id}\`) joined with ${actions.length} prior record(s)`, ); } diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index 906cc375..290996b0 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -9,6 +9,7 @@ import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; import { kickMember } from "./kickMember"; import { ignoreEvent } from "./ignoreEvent"; import { isBanned } from "./isBanned"; +import { GuildMember, TextChannel } from "discord.js"; export async function actualKickMemberCmd( pluginData: GuildPluginData, @@ -16,7 +17,7 @@ export async function actualKickMemberCmd( args: { user: string; reason: string; - mod: Member; + mod: GuildMember; notify?: string; "notify-channel"?: TextChannel; clean?: boolean; @@ -81,7 +82,7 @@ export async function actualKickMemberCmd( ignoreEvent(pluginData, IgnoredEventType.Ban, memberToKick.id); try { - await memberToKick.ban(1, encodeURIComponent("kick -clean")); + await memberToKick.ban({ days: 1, reason: encodeURIComponent("kick -clean") }); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to ban the user to clean messages (-clean)"); } @@ -90,14 +91,14 @@ export async function actualKickMemberCmd( ignoreEvent(pluginData, IgnoredEventType.Unban, memberToKick.id); try { - await pluginData.guild.unbanMember(memberToKick.id, encodeURIComponent("kick -clean")); + await pluginData.guild.bans.remove(memberToKick.id, encodeURIComponent("kick -clean")); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to unban the user after banning them (-clean)"); } } if (kickResult.status === "failed") { - msg.channel.createMessage(errorMessage(`Failed to kick user`)); + msg.channel.send(errorMessage(`Failed to kick user`)); return; } diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index bbf2ac99..203913b0 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -9,6 +9,7 @@ import { MutesPlugin } from "../../Mutes/MutesPlugin"; import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { logger } from "../../../logger"; +import { User, Message, TextChannel, GuildMember } from "discord.js"; /** * The actual function run by both !mute and !forcemute. @@ -17,16 +18,16 @@ import { logger } from "../../../logger"; export async function actualMuteUserCmd( pluginData: GuildPluginData, user: User | UnknownUser, - msg: Message, - args: { time?: number; reason?: string; mod: Member; notify?: string; "notify-channel"?: TextChannel }, + msg: Message, + args: { time?: number; reason?: string; mod: GuildMember; notify?: string; "notify-channel"?: TextChannel }, ) { // The moderator who did the action is the message author or, if used, the specified -mod - let mod: Member = msg.member; + let mod: GuildMember = msg.member!; let pp: User | null = null; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "You don't have permission to use -mod"); return; } @@ -35,7 +36,7 @@ export async function actualMuteUserCmd( } const timeUntilUnmute = args.time && humanizeDuration(args.time); - const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments) : undefined; + const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments.array()) : undefined; let muteResult: MuteResult; const mutesPlugin = pluginData.getPlugin(MutesPlugin); @@ -44,7 +45,7 @@ export async function actualMuteUserCmd( try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); + sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); return; } @@ -58,16 +59,16 @@ export async function actualMuteUserCmd( }); } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { - sendErrorMessage(pluginData, msg.channel, "Could not mute the user: no mute role set in config"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: no mute role set in config"); } else if (isDiscordRESTError(e) && e.code === 10007) { - sendErrorMessage(pluginData, msg.channel, "Could not mute the user: unknown member"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: unknown member"); } else { logger.error(`Failed to mute user ${user.id}: ${e.stack}`); if (user.id == null) { // tslint-disable-next-line:no-console console.trace("[DEBUG] Null user.id for mute"); } - sendErrorMessage(pluginData, msg.channel, "Could not mute the user"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user"); } return; @@ -102,5 +103,5 @@ export async function actualMuteUserCmd( } if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`; - sendSuccessMessage(pluginData, msg.channel, response); + sendSuccessMessage(pluginData, msg.channel as TextChannel, response); } diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts index badfccd5..72950b82 100644 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts @@ -6,12 +6,13 @@ import { sendErrorMessage, sendSuccessMessage, hasPermission } from "../../../pl import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import humanizeDuration from "humanize-duration"; +import { User, Message, GuildMember, TextChannel } from "discord.js"; export async function actualUnmuteCmd( pluginData: GuildPluginData, user: User | UnknownUser, msg: Message, - args: { time?: number; reason?: string; mod?: Member }, + args: { time?: number; reason?: string; mod?: GuildMember }, ) { // The moderator who did the action is the message author or, if used, the specified -mod let mod = msg.author; @@ -19,7 +20,7 @@ export async function actualUnmuteCmd( if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "You don't have permission to use -mod"); return; } @@ -27,7 +28,7 @@ export async function actualUnmuteCmd( pp = msg.author; } - const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments) : undefined; + const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments.array()) : undefined; const mutesPlugin = pluginData.getPlugin(MutesPlugin); const result = await mutesPlugin.unmuteUser(user.id, args.time, { @@ -37,7 +38,7 @@ export async function actualUnmuteCmd( }); if (!result) { - sendErrorMessage(pluginData, msg.channel, "User is not muted!"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "User is not muted!"); return; } @@ -46,7 +47,7 @@ export async function actualUnmuteCmd( const timeUntilUnmute = args.time && humanizeDuration(args.time); sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, asSingleLine(` Unmuting **${user.username}#${user.discriminator}** in ${timeUntilUnmute} (Case #${result.case.case_number}) @@ -55,7 +56,7 @@ export async function actualUnmuteCmd( } else { sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, asSingleLine(` Unmuted **${user.username}#${user.discriminator}** (Case #${result.case.case_number}) diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index f259dca9..e1da2e2d 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -17,6 +17,7 @@ import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { logger } from "../../../logger"; import humanizeDuration from "humanize-duration"; +import { DiscordAPIError, User } from "discord.js"; /** * Ban the specified user id, whether or not they're actually on the server at the time. Generates a case. @@ -77,14 +78,13 @@ export async function banUserId( ignoreEvent(pluginData, IgnoredEventType.Ban, userId); try { const deleteMessageDays = Math.min(30, Math.max(0, banOptions.deleteMessageDays ?? 1)); - await pluginData.guild.banMember( - userId, - deleteMessageDays, - reason != null ? encodeURIComponent(reason) : undefined, - ); + await pluginData.guild.bans.create(userId, { + days: deleteMessageDays, + reason: reason != null ? encodeURIComponent(reason) : undefined, + }); } catch (e) { let errorMessage; - if (e instanceof DiscordRESTError) { + if (e instanceof DiscordAPIError) { errorMessage = `API error ${e.code}: ${e.message}`; } else { logger.warn(`Error applying ban to ${userId}: ${e}`); diff --git a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts index abf820c6..809fe909 100644 --- a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts +++ b/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts @@ -1,4 +1,6 @@ -export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) { +import { MessageAttachment } from "discord.js"; + +export function formatReasonWithAttachments(reason: string, attachments: MessageAttachment[]) { const attachmentUrls = attachments.map(a => a.url); return ((reason || "") + " " + attachmentUrls.join(" ")).trim(); } diff --git a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts index 1d2484c3..68078a88 100644 --- a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts +++ b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts @@ -1,6 +1,7 @@ import { GuildPluginData } from "knub"; import { ModActionsPluginType } from "../types"; import { UserNotificationMethod } from "../../../utils"; +import { TextChannel } from "discord.js"; export function getDefaultContactMethods( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index bac97e91..4496fe1a 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -4,6 +4,7 @@ import { isDiscordHTTPError, isDiscordRESTError, SECONDS, sleep } from "../../.. import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; +import { Permissions } from "discord.js"; export async function isBanned( pluginData: GuildPluginData, @@ -11,7 +12,7 @@ export async function isBanned( timeout: number = 5 * SECONDS, ): Promise { const botMember = pluginData.guild.members.cache.get(pluginData.client.user!.id); - if (botMember && !hasDiscordPermissions(botMember.permissions, Constants.Permissions.banMembers)) { + if (botMember && !hasDiscordPermissions(botMember.permissions, Permissions.FLAGS.BAN_MEMBERS)) { pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, { body: `Missing "Ban Members" permission to check for existing bans`, }); @@ -19,7 +20,7 @@ export async function isBanned( } try { - const potentialBan = await Promise.race([pluginData.guild.getBan(userId), sleep(timeout)]); + const potentialBan = await Promise.race([pluginData.guild.bans.fetch({ user: userId }), sleep(timeout)]); return potentialBan != null; } catch (e) { if (isDiscordRESTError(e) && e.code === 10026) { diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index eaaa2f69..175a480e 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -15,13 +15,14 @@ import { LogType } from "../../../data/LogType"; import { ignoreEvent } from "./ignoreEvent"; import { CaseTypes } from "../../../data/CaseTypes"; import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { GuildMember } from "discord.js"; /** * Kick the specified server member. Generates a case. */ export async function kickMember( pluginData: GuildPluginData, - member: Member, + member: GuildMember, reason?: string, kickOptions: KickOptions = {}, ): Promise { diff --git a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts index 0fc3749c..bb7fe336 100644 --- a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts +++ b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts @@ -30,7 +30,7 @@ export async function outdatedTempbansLoop(pluginData: GuildPluginData, - member: Member, + member: GuildMember, reason: string, warnOptions: WarnOptions = {}, ): Promise { @@ -42,13 +42,13 @@ export async function warnMember( } if (!notifyResult.success) { - if (warnOptions.retryPromptChannel && pluginData.guild.channels.has(warnOptions.retryPromptChannel.id)) { - const failedMsg = await warnOptions.retryPromptChannel.createMessage( + if (warnOptions.retryPromptChannel && pluginData.guild.channels.resolve(warnOptions.retryPromptChannel.id)) { + const failedMsg = await warnOptions.retryPromptChannel.send( "Failed to message the user. Log the warning anyway?", ); - const reply = await waitForReaction(pluginData.client, failedMsg, ["✅", "❌"]); + const reply = false; //await waitForReaction(pluginData.client, failedMsg, ["✅", "❌"]); FIXME waiting on waitForButton failedMsg.delete(); - if (!reply || reply.name === "❌") { + if (!reply /*|| reply.name === "❌"*/) { return { status: "failed", error: "Failed to message user", diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index 3ebeacec..08c1314a 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -11,6 +11,7 @@ import { GuildTempbans } from "../../data/GuildTempbans"; import Timeout = NodeJS.Timeout; import { EventEmitter } from "events"; import { Queue } from "../../Queue"; +import { TextChannel } from "discord.js"; export const ConfigSchema = t.type({ dm_on_warn: t.boolean, diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index 5e8c0045..acb16e44 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -20,6 +20,7 @@ import { mapToPublicFn } from "../../pluginUtils"; import { EventEmitter } from "events"; import { onMutesEvent } from "./functions/onMutesEvent"; import { offMutesEvent } from "./functions/offMutesEvent"; +import { GuildMember } from "discord.js"; const defaultOptions = { config: { @@ -92,9 +93,9 @@ export const MutesPlugin = zeppelinGuildPlugin()({ muteUser: mapToPublicFn(muteUser), unmuteUser: mapToPublicFn(unmuteUser), hasMutedRole(pluginData) { - return (member: Member) => { + return (member: GuildMember) => { const muteRole = pluginData.config.get().mute_role; - return muteRole ? member.roles.includes(muteRole) : false; + return muteRole ? member.roles.cache.has(muteRole) : false; }; }, diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 37f78f6f..c2fbc844 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,6 +1,7 @@ import { mutesCmd } from "../types"; import { sendSuccessMessage } from "../../../pluginUtils"; +import { User } from "discord.js"; export const ClearBannedMutesCmd = mutesCmd({ trigger: "clear_banned_mutes", @@ -8,17 +9,14 @@ export const ClearBannedMutesCmd = mutesCmd({ description: "Clear dangling mutes for members who have been banned", async run({ pluginData, message: msg }) { - await msg.channel.createMessage("Clearing mutes from banned users..."); + await msg.channel.send("Clearing mutes from banned users..."); const activeMutes = await pluginData.state.mutes.getActiveMutes(); - // Mismatch in Eris docs and actual result here, based on Eris's code comments anyway - const bans: Array<{ reason: string; user: User }> = (await pluginData.guild.getBans()) as any; + const bans: Array<{ reason: string; user: User }> = (await pluginData.guild.bans.fetch({ cache: true })) as any; const bannedIds = bans.map(b => b.user.id); - await msg.channel.createMessage( - `Found ${activeMutes.length} mutes and ${bannedIds.length} bans, cross-referencing...`, - ); + await msg.channel.send(`Found ${activeMutes.length} mutes and ${bannedIds.length} bans, cross-referencing...`); let cleared = 0; for (const mute of activeMutes) { diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index f05b16cf..08aebe63 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -12,14 +12,14 @@ export const ClearMutesWithoutRoleCmd = mutesCmd({ const muteRole = pluginData.config.get().mute_role; if (!muteRole) return; - await msg.channel.createMessage("Clearing mutes from members that don't have the mute role..."); + await msg.channel.send("Clearing mutes from members that don't have the mute role..."); let cleared = 0; for (const mute of activeMutes) { const member = await resolveMember(pluginData.client, pluginData.guild, mute.user_id); if (!member) continue; - if (!member.roles.includes(muteRole)) { + if (!member.roles.cache.has(muteRole)) { await pluginData.state.mutes.clear(mute.user_id); cleared++; } diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 7e52589a..276a6227 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -4,6 +4,7 @@ import { DBDateFormat, isFullMessage, MINUTES, noop, resolveMember } from "../.. import moment from "moment-timezone"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { getBaseUrl } from "../../../pluginUtils"; +import { GuildMember } from "discord.js"; export const MutesCmd = mutesCmd({ trigger: "mutes", @@ -21,7 +22,7 @@ export const MutesCmd = mutesCmd({ }, async run({ pluginData, message: msg, args }) { - const listMessagePromise = msg.channel.createMessage("Loading mutes..."); + const listMessagePromise = msg.channel.send("Loading mutes..."); const mutesPerPage = 10; let totalMutes = 0; let hasFilters = false; @@ -47,13 +48,13 @@ export const MutesCmd = mutesCmd({ if (args.manual) { // Show only manual mutes (i.e. "Muted" role added without a logged mute) const muteUserIds = new Set(activeMutes.map(m => m.user_id)); - const manuallyMutedMembers: Member[] = []; + const manuallyMutedMembers: GuildMember[] = []; const muteRole = pluginData.config.get().mute_role; if (muteRole) { - pluginData.guild.members.forEach(member => { + pluginData.guild.members.cache.forEach(member => { if (muteUserIds.has(member.id)) return; - if (member.roles.includes(muteRole)) manuallyMutedMembers.push(member); + if (member.roles.cache.has(muteRole)) manuallyMutedMembers.push(member); }); } @@ -85,7 +86,7 @@ export const MutesCmd = mutesCmd({ if (!member) { if (!bannedIds) { - const bans = await pluginData.guild.getBans(); + const bans = await pluginData.guild.bans.fetch({ cache: true }); bannedIds = bans.map(u => u.user.id); } @@ -111,7 +112,7 @@ export const MutesCmd = mutesCmd({ const muteCasesById = muteCases.reduce((map, c) => map.set(c.id, c), new Map()); lines = filteredMutes.map(mute => { - const user = pluginData.client.user!.get(mute.user_id); + const user = pluginData.client.users.resolve(mute.user_id); const username = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; const theCase = muteCasesById.get(mute.case_id); const caseName = theCase ? `Case #${theCase.case_number}` : "No case"; @@ -194,29 +195,31 @@ export const MutesCmd = mutesCmd({ if (totalPages > 1) { hasReactions = true; - listMessage.addReaction("⬅"); - listMessage.addReaction("➡"); + listMessage.react("⬅"); + listMessage.react("➡"); const paginationReactionListener = pluginData.events.on( "messageReactionAdd", - ({ args: { message: rMsg, emoji, member } }) => { + async ({ args: { reaction, user } }) => { + const rMsg = reaction.message; + const member = await pluginData.guild.members.fetch(user.id); if (!isFullMessage(rMsg)) return; if (rMsg.id !== listMessage.id) return; if (member.id !== msg.author.id) return; - if (!["⬅", "➡"].includes(emoji.name)) return; + if (!["⬅", "➡"].includes(reaction.emoji.name!)) return; - if (emoji.name === "⬅" && currentPage > 1) { + if (reaction.emoji.name === "⬅" && currentPage > 1) { drawListPage(currentPage - 1); - } else if (emoji.name === "➡" && currentPage < totalPages) { + } else if (reaction.emoji.name === "➡" && currentPage < totalPages) { drawListPage(currentPage + 1); } - rMsg.removeReaction(emoji.name, member.id).catch(noop); + reaction.remove().catch(noop); }, ); clearReactionsFn = () => { - listMessage.removeReactions().catch(noop); + listMessage.reactions.removeAll().catch(noop); pluginData.events.off("messageReactionAdd", paginationReactionListener); }; bumpClearReactionsTimeout(); diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts index 7a40b25e..94604dcd 100644 --- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts +++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts @@ -5,10 +5,10 @@ import { mutesEvt } from "../types"; */ export const ClearActiveMuteOnMemberBanEvt = mutesEvt({ event: "guildBanAdd", - async listener({ pluginData, args: { user } }) { - const mute = await pluginData.state.mutes.findExistingMuteForUserId(user.id); + async listener({ pluginData, args: { ban } }) { + const mute = await pluginData.state.mutes.findExistingMuteForUserId(ban.user.id); if (mute) { - pluginData.state.mutes.clear(user.id); + pluginData.state.mutes.clear(ban.user.id); } }, }); diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts index cba7f2a2..f3b4eeed 100644 --- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts +++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts @@ -6,7 +6,7 @@ import { memberHasMutedRole } from "../functions/memberHasMutedRole"; */ export const ClearActiveMuteOnRoleRemovalEvt = mutesEvt({ event: "guildMemberUpdate", - async listener({ pluginData, args: { member } }) { + async listener({ pluginData, args: { oldMember, newMember: member } }) { const muteRole = pluginData.config.get().mute_role; if (!muteRole) return; diff --git a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts index 2b149eb7..729392b8 100644 --- a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts +++ b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts @@ -15,7 +15,7 @@ export const ReapplyActiveMuteOnJoinEvt = mutesEvt({ if (muteRole) { const memberRoleLock = await pluginData.locks.acquire(memberRolesLock(member)); - await member.addRole(muteRole); + await member.roles.add(muteRole); memberRoleLock.unlock(); } diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index 65bd2b72..7db4e807 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -16,17 +16,17 @@ export async function clearExpiredMutes(pluginData: GuildPluginData r !== muteRole); + await member.roles.remove(muteRole); } if (mute.roles_to_restore) { - const memberOptions: MemberOptions = {}; - const guildRoles = pluginData.guild.roles; - memberOptions.roles = Array.from( - new Set([...mute.roles_to_restore, ...member.roles.filter(x => x !== muteRole && guildRoles.has(x))]), - ); - await member.edit(memberOptions); - member.roles = memberOptions.roles; + const guildRoles = pluginData.guild.roles.cache; + let newRoles: string[] = member.roles.cache.keyArray(); + newRoles = + muteRole && newRoles.includes(muteRole) ? newRoles.splice(newRoles.indexOf(muteRole), 1) : newRoles; + for (const toRestore of mute.roles_to_restore) { + if (guildRoles.has(toRestore) && toRestore !== muteRole) newRoles.push(toRestore); + } + await member.roles.set(newRoles); } lock.unlock(); diff --git a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts index 8b296f19..70180dc9 100644 --- a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts +++ b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts @@ -1,7 +1,8 @@ +import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; import { MutesPluginType } from "../types"; -export function memberHasMutedRole(pluginData: GuildPluginData, member: Member): boolean { +export function memberHasMutedRole(pluginData: GuildPluginData, member: GuildMember): boolean { const muteRole = pluginData.config.get().mute_role; - return muteRole ? member.roles.includes(muteRole) : false; + return muteRole ? member.roles.cache.has(muteRole) : false; } diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 16ef5479..15bef04f 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -19,6 +19,7 @@ import { LogType } from "../../../data/LogType"; import { Case } from "../../../data/entities/Case"; import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; import { muteLock } from "../../../utils/lockNameHelpers"; +import { TextChannel, User } from "discord.js"; export async function muteUser( pluginData: GuildPluginData, @@ -58,8 +59,8 @@ export async function muteUser( if (member) { const logs = pluginData.getPlugin(LogsPlugin); // remove and store any roles to be removed/restored - const currentUserRoles = member.roles; - const memberOptions: MemberOptions = {}; + const currentUserRoles = member.roles.cache.keyArray(); + let newRoles: string[] = currentUserRoles; const removeRoles = removeRolesOnMuteOverride ?? config.remove_roles_on_mute; const restoreRoles = restoreRolesOnMuteOverride ?? config.restore_roles_on_mute; @@ -67,13 +68,13 @@ export async function muteUser( if (!Array.isArray(removeRoles)) { if (removeRoles) { // exclude managed roles from being removed - const managedRoles = pluginData.guild.roles.filter(x => x.managed).map(y => y.id); - memberOptions.roles = managedRoles.filter(x => member.roles.includes(x)); - await member.edit(memberOptions); + const managedRoles = pluginData.guild.roles.cache.filter(x => x.managed).map(y => y.id); + newRoles = currentUserRoles.filter(r => !managedRoles.includes(r)); + await member.roles.set(newRoles); } } else { - memberOptions.roles = currentUserRoles.filter(x => !(removeRoles).includes(x)); - await member.edit(memberOptions); + newRoles = currentUserRoles.filter(x => !(removeRoles).includes(x)); + await member.roles.set(newRoles); } // set roles to be restored @@ -86,11 +87,11 @@ export async function muteUser( } // Apply mute role if it's missing - if (!member.roles.includes(muteRole)) { + if (!currentUserRoles.includes(muteRole)) { try { - await member.addRole(muteRole); + await member.roles.add(muteRole); } catch (e) { - const actualMuteRole = pluginData.guild.roles.find(x => x.id === muteRole); + const actualMuteRole = pluginData.guild.roles.cache.find(x => x.id === muteRole); if (!actualMuteRole) { lock.unlock(); logs.log(LogType.BOT_ALERT, { @@ -100,9 +101,9 @@ export async function muteUser( } const zep = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user!.id); - const zepRoles = pluginData.guild.roles.filter(x => zep!.roles.includes(x.id)); + const zepRoles = pluginData.guild.roles.cache.filter(x => zep!.roles.cache.has(x.id)); // If we have roles and one of them is above the muted role, throw generic error - if (zepRoles.length >= 0 && zepRoles.some(zepRole => zepRole.position > actualMuteRole.position)) { + if (zepRoles.size >= 0 && zepRoles.some(zepRole => zepRole.position > actualMuteRole.position)) { lock.unlock(); logs.log(LogType.BOT_ALERT, { body: `Cannot mute user ${member.id}: ${e}`, @@ -125,7 +126,7 @@ export async function muteUser( if (moveToVoiceChannel || cfg.kick_from_voice_channel) { // TODO: Add back the voiceState check once we figure out how to get voice state for guild members that are loaded on-demand try { - await member.edit({ channelID: moveToVoiceChannel }); + await member.edit({ channel: moveToVoiceChannel }); } catch {} // tslint:disable-line } } diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index c71096be..0fa81dcb 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -36,18 +36,17 @@ export async function unmuteUser( const lock = await pluginData.locks.acquire(memberRolesLock(member)); const muteRole = pluginData.config.get().mute_role; - if (muteRole && member.roles.includes(muteRole)) { - await member.removeRole(muteRole); - member.roles = member.roles.filter(r => r !== muteRole); + if (muteRole && member.roles.cache.has(muteRole)) { + await member.roles.remove(muteRole); } if (existingMute?.roles_to_restore) { - const memberOptions: MemberOptions = {}; - const guildRoles = pluginData.guild.roles; - memberOptions.roles = Array.from( - new Set([...existingMute.roles_to_restore, ...member.roles.filter(x => x !== muteRole && guildRoles.has(x))]), - ); - await member.edit(memberOptions); - member.roles = memberOptions.roles; + const guildRoles = pluginData.guild.roles.cache; + let newRoles: string[] = member.roles.cache.keyArray(); + newRoles = muteRole && newRoles.includes(muteRole) ? newRoles.splice(newRoles.indexOf(muteRole), 1) : newRoles; + for (const toRestore of existingMute.roles_to_restore) { + if (guildRoles.has(toRestore) && toRestore !== muteRole) newRoles.push(toRestore); + } + await member.roles.set(newRoles); } lock.unlock(); @@ -85,7 +84,7 @@ export async function unmuteUser( }); // Log the action - const mod = pluginData.client.user!.get(modId); + const mod = pluginData.client.users.fetch(modId); if (unmuteTime) { pluginData.state.serverLogs.log(LogType.MEMBER_TIMED_UNMUTE, { mod: stripObjectToScalars(mod), diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index e87e8a6e..9fc62f46 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -11,6 +11,7 @@ import { GuildMutes } from "../../data/GuildMutes"; import { CaseArgs } from "../Cases/types"; import Timeout = NodeJS.Timeout; import { EventEmitter } from "events"; +import { GuildMember } from "discord.js"; export const ConfigSchema = t.type({ mute_role: tNullable(t.string), @@ -58,7 +59,7 @@ export interface MutesPluginType extends BasePluginType { } export interface IMuteWithDetails extends Mute { - member?: Member; + member?: GuildMember; banned?: boolean; } diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index c47f1912..90cf80ee 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -29,7 +29,7 @@ export const NamesCmd = nameHistoryCmd({ ); const usernameRows = usernames.map(r => `\`[${r.timestamp}]\` **${disableCodeBlocks(r.username)}**`); - const user = pluginData.client.user!.get(args.userId); + const user = await pluginData.client.users.fetch(args.userId); const currentUsername = user ? `${user.username}#${user.discriminator}` : args.userId; const nicknameDays = Math.round(NICKNAME_RETENTION_PERIOD / DAYS); diff --git a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts index 66947b22..706c93cc 100644 --- a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts +++ b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts @@ -2,10 +2,15 @@ import { nameHistoryEvt } from "../types"; import { updateNickname } from "../updateNickname"; export const ChannelJoinEvt = nameHistoryEvt({ - event: "voiceChannelJoin", + event: "voiceStateUpdate", async listener(meta) { - meta.pluginData.state.updateQueue.add(() => updateNickname(meta.pluginData, meta.args.member)); + meta.pluginData.state.updateQueue.add(() => + updateNickname( + meta.pluginData, + meta.args.newState.member ? meta.args.newState.member : meta.args.oldState.member!, + ), + ); }, }); diff --git a/backend/src/plugins/NameHistory/updateNickname.ts b/backend/src/plugins/NameHistory/updateNickname.ts index 290ac4d1..e843ae3b 100644 --- a/backend/src/plugins/NameHistory/updateNickname.ts +++ b/backend/src/plugins/NameHistory/updateNickname.ts @@ -1,11 +1,12 @@ +import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; import { NameHistoryPluginType } from "./types"; -export async function updateNickname(pluginData: GuildPluginData, member: Member) { +export async function updateNickname(pluginData: GuildPluginData, member: GuildMember) { if (!member) return; const latestEntry = await pluginData.state.nicknameHistory.getLastEntry(member.id); - if (!latestEntry || latestEntry.nickname !== member.nick) { - if (!latestEntry && member.nick == null) return; // No need to save "no nickname" if there's no previous data - await pluginData.state.nicknameHistory.addEntry(member.id, member.nick); + if (!latestEntry || latestEntry.nickname !== member.nickname) { + if (!latestEntry && member.nickname == null) return; // No need to save "no nickname" if there's no previous data + await pluginData.state.nicknameHistory.addEntry(member.id, member.nickname); } } diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 76cf5366..96c63027 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -8,8 +8,9 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { canAssignRole } from "../../../utils/canAssignRole"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { GuildMemberEditData, Permissions } from "discord.js"; -const p = Constants.Permissions; +const p = Permissions.FLAGS; export const LoadDataEvt = persistEvt({ event: "guildMemberAdd", @@ -26,16 +27,16 @@ export const LoadDataEvt = persistEvt({ return; } - const toRestore: MemberOptions = {}; + let toRestore: GuildMemberEditData = {}; const config = await pluginData.config.getForMember(member); const restoredData: string[] = []; // Check permissions const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; let requiredPermissions = 0n; - if (config.persist_nicknames) requiredPermissions |= p.manageNicknames; - if (config.persisted_roles) requiredPermissions |= p.manageRoles; - const missingPermissions = getMissingPermissions(me.permission, requiredPermissions); + if (config.persist_nicknames) requiredPermissions |= p.MANAGE_NICKNAMES; + if (config.persisted_roles) requiredPermissions |= p.MANAGE_ROLES; + const missingPermissions = getMissingPermissions(me.permissions, requiredPermissions); if (missingPermissions) { pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, { body: `Missing permissions for persist plugin: ${missingPermissionError(missingPermissions)}`, @@ -61,7 +62,7 @@ export const LoadDataEvt = persistEvt({ if (rolesToRestore.length) { restoredData.push("roles"); - toRestore.roles = Array.from(new Set([...rolesToRestore, ...member.roles])); + toRestore.roles = Array.from(new Set([...rolesToRestore, ...member.roles.cache])); } } diff --git a/backend/src/plugins/Persist/events/StoreDataEvt.ts b/backend/src/plugins/Persist/events/StoreDataEvt.ts index 2b9ded49..0bc95404 100644 --- a/backend/src/plugins/Persist/events/StoreDataEvt.ts +++ b/backend/src/plugins/Persist/events/StoreDataEvt.ts @@ -2,12 +2,13 @@ import { persistEvt } from "../types"; import { IPartialPersistData } from "../../../data/GuildPersistedData"; import intersection from "lodash.intersection"; +import { GuildMember } from "discord.js"; export const StoreDataEvt = persistEvt({ event: "guildMemberRemove", async listener(meta) { - const member = meta.args.member as Member; + const member = meta.args.member as GuildMember; const pluginData = meta.pluginData; let persist = false; @@ -23,9 +24,9 @@ export const StoreDataEvt = persistEvt({ } } - if (config.persist_nicknames && member.nick) { + if (config.persist_nicknames && member.nickname) { persist = true; - persistData.nickname = member.nick; + persistData.nickname = member.nickname; } if (persist) { diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index 9cac7d16..b0df9b4d 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -2,6 +2,7 @@ import { postCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { formatContent } from "../util/formatContent"; +import { TextChannel } from "discord.js"; export const EditCmd = postCmd({ trigger: "edit", @@ -24,7 +25,9 @@ export const EditCmd = postCmd({ return; } - await pluginData.client.editMessage(savedMessage.channel_id, savedMessage.id, formatContent(args.content)); + (pluginData.guild.channels.cache.get(savedMessage.channel_id) as TextChannel).messages.edit(savedMessage.id, { + content: formatContent(args.content), + }); sendSuccessMessage(pluginData, msg.channel, "Message edited"); }, }); diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 64ec7e81..d832e8aa 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -6,6 +6,7 @@ import { trimLines } from "../../../utils"; import { formatContent } from "../util/formatContent"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; +import { MessageEmbed, TextChannel } from "discord.js"; const COLOR_MATCH_REGEX = /^#?([0-9a-f]{6})$/; @@ -42,17 +43,19 @@ export const EditEmbedCmd = postCmd({ } } - const embed: Embed = savedMessage.data.embeds![0] as Embed; + const embed: MessageEmbed = savedMessage.data.embeds![0] as MessageEmbed; if (args.title) embed.title = args.title; if (content) embed.description = formatContent(content); if (color) embed.color = color; - await pluginData.client.editMessage(savedMessage.channel_id, savedMessage.id, { embed }); + (pluginData.guild.channels.cache.get(savedMessage.channel_id) as TextChannel).messages.edit(savedMessage.id, { + embed, + }); await sendSuccessMessage(pluginData, msg.channel, "Embed edited"); if (args.content) { const prefix = pluginData.fullConfig.prefix || "!"; - msg.channel.createMessage( + msg.channel.send( trimLines(` <@!${msg.author.id}> You can now specify an embed's content directly at the end of the command: \`${prefix}edit_embed -title "Some title" content goes here\` diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index 5868f2b8..344b9e17 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -7,6 +7,7 @@ import { isValidEmbed, trimLines } from "../../../utils"; import { formatContent } from "../util/formatContent"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; +import { MessageEmbed, MessageEmbedOptions } from "discord.js"; export const PostEmbedCmd = postCmd({ trigger: "post_embed", @@ -46,7 +47,7 @@ export const PostEmbedCmd = postCmd({ } } - let embed: Embed = { type: "rich" }; + let embed: MessageEmbedOptions = {}; if (args.title) embed.title = args.title; if (color) embed.color = color; @@ -73,7 +74,7 @@ export const PostEmbedCmd = postCmd({ if (args.content) { const prefix = pluginData.fullConfig.prefix || "!"; - msg.channel.createMessage( + msg.channel.send( trimLines(` <@!${msg.author.id}> You can now specify an embed's content directly at the end of the command: \`${prefix}edit_embed -title "Some title" content goes here\` diff --git a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts index bc61a4ba..3a3a3c8f 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts @@ -20,7 +20,7 @@ export const ScheduledPostsListCmd = postCmd({ async run({ message: msg, pluginData }) { const scheduledPosts = await pluginData.state.scheduledPosts.all(); if (scheduledPosts.length === 0) { - msg.channel.createMessage("No scheduled posts"); + msg.channel.send("No scheduled posts"); return; } diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index 6501f835..a94b8033 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -3,6 +3,7 @@ import { sorter } from "../../../utils"; import { sendErrorMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { postMessage } from "../util/postMessage"; +import { TextChannel } from "discord.js"; export const ScheduledPostsShowCmd = postCmd({ trigger: ["scheduled_posts", "scheduled_posts show"], diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index 2adddad2..c814ae0b 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -8,6 +8,7 @@ import { PostPluginType } from "../types"; import { parseScheduleTime } from "./parseScheduleTime"; import { postMessage } from "./postMessage"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { Message, Channel, TextChannel } from "discord.js"; const MIN_REPEAT_TIME = 5 * MINUTES; const MAX_REPEAT_TIME = Math.pow(2, 32); @@ -27,22 +28,30 @@ export async function actualPostCmd( } = {}, ) { if (!(targetChannel instanceof TextChannel)) { - msg.channel.createMessage(errorMessage("Channel is not a text channel")); + msg.channel.send(errorMessage("Channel is not a text channel")); return; } - if (content == null && msg.attachments.length === 0) { - msg.channel.createMessage(errorMessage("Message content or attachment required")); + if (content == null && msg.attachments.size === 0) { + msg.channel.send(errorMessage("Message content or attachment required")); return; } if (opts.repeat) { if (opts.repeat < MIN_REPEAT_TIME) { - sendErrorMessage(pluginData, msg.channel, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); + sendErrorMessage( + pluginData, + msg.channel as TextChannel, + `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`, + ); return; } if (opts.repeat > MAX_REPEAT_TIME) { - sendErrorMessage(pluginData, msg.channel, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); + sendErrorMessage( + pluginData, + msg.channel as TextChannel, + `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`, + ); return; } } @@ -53,7 +62,7 @@ export async function actualPostCmd( // Schedule the post to be posted later postAt = await parseScheduleTime(pluginData, msg.author.id, opts.schedule); if (!postAt) { - sendErrorMessage(pluginData, msg.channel, "Invalid schedule time"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid schedule time"); return; } } else if (opts.repeat) { @@ -70,17 +79,17 @@ export async function actualPostCmd( // Invalid time if (!repeatUntil) { - sendErrorMessage(pluginData, msg.channel, "Invalid time specified for -repeat-until"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid time specified for -repeat-until"); return; } if (repeatUntil.isBefore(moment.utc())) { - sendErrorMessage(pluginData, msg.channel, "You can't set -repeat-until in the past"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "You can't set -repeat-until in the past"); return; } if (repeatUntil.isAfter(MAX_REPEAT_UNTIL)) { sendErrorMessage( pluginData, - msg.channel, + msg.channel as TextChannel, "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", ); return; @@ -88,18 +97,26 @@ export async function actualPostCmd( } else if (opts["repeat-times"]) { repeatTimes = opts["repeat-times"]; if (repeatTimes <= 0) { - sendErrorMessage(pluginData, msg.channel, "-repeat-times must be 1 or more"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "-repeat-times must be 1 or more"); return; } } if (repeatUntil && repeatTimes) { - sendErrorMessage(pluginData, msg.channel, "You can only use one of -repeat-until or -repeat-times at once"); + sendErrorMessage( + pluginData, + msg.channel as TextChannel, + "You can only use one of -repeat-until or -repeat-times at once", + ); return; } if (opts.repeat && !repeatUntil && !repeatTimes) { - sendErrorMessage(pluginData, msg.channel, "You must specify -repeat-until or -repeat-times for repeated messages"); + sendErrorMessage( + pluginData, + msg.channel as TextChannel, + "You must specify -repeat-until or -repeat-times for repeated messages", + ); return; } @@ -114,7 +131,7 @@ export async function actualPostCmd( // Save schedule/repeat information in DB if (postAt) { if (postAt < moment.utc()) { - sendErrorMessage(pluginData, msg.channel, "Post can't be scheduled to be posted in the past"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Post can't be scheduled to be posted in the past"); return; } @@ -123,7 +140,7 @@ export async function actualPostCmd( author_name: `${msg.author.username}#${msg.author.discriminator}`, channel_id: targetChannel.id, content, - attachments: msg.attachments, + attachments: msg.attachments.array(), post_at: postAt .clone() .tz("Etc/UTC") @@ -162,7 +179,7 @@ export async function actualPostCmd( // When the message isn't scheduled for later, post it immediately if (!opts.schedule) { - await postMessage(pluginData, targetChannel, content, msg.attachments, opts["enable-mentions"]); + await postMessage(pluginData, targetChannel, content, msg.attachments.array(), opts["enable-mentions"]); } if (opts.repeat) { @@ -197,6 +214,6 @@ export async function actualPostCmd( } if (targetChannel.id !== msg.channel.id || opts.schedule || opts.repeat) { - sendSuccessMessage(pluginData, msg.channel, successMessage); + sendSuccessMessage(pluginData, msg.channel as TextChannel, successMessage); } } diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index fc31b063..292fc6b3 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -4,14 +4,15 @@ import { PostPluginType } from "../types"; import { downloadFile } from "../../../utils"; import fs from "fs"; import { formatContent } from "./formatContent"; +import { TextChannel, Message, MessageOptions, MessageAttachment } from "discord.js"; const fsp = fs.promises; export async function postMessage( pluginData: GuildPluginData, channel: TextChannel, - content: MessageContent, - attachments: Attachment[] = [], + content: MessageOptions, + attachments: MessageAttachment[] = [], enableMentions: boolean = false, ): Promise { if (typeof content === "string") { @@ -27,20 +28,18 @@ export async function postMessage( if (attachments.length) { downloadedAttachment = await downloadFile(attachments[0].url); file = { - name: attachments[0].filename, + name: attachments[0].name, file: await fsp.readFile(downloadedAttachment.path), }; } if (enableMentions) { content.allowedMentions = { - everyone: true, - users: true, - roles: true, + parse: ["everyone", "roles", "users"], }; } - const createdMsg = await channel.createMessage(content, file); + const createdMsg = await channel.send(content, file); pluginData.state.savedMessages.setPermanent(createdMsg.id); if (downloadedAttachment) { diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts index ac2f2519..d24f3ec6 100644 --- a/backend/src/plugins/Post/util/scheduledPostLoop.ts +++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts @@ -6,6 +6,7 @@ import { LogType } from "../../../data/LogType"; import moment from "moment-timezone"; import { postMessage } from "./postMessage"; +import { TextChannel, User } from "discord.js"; const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS; @@ -15,7 +16,7 @@ export async function scheduledPostLoop(pluginData: GuildPluginData = pluginData.client.user!.get(post.author_id) || { + const author: User = (await pluginData.client.users.fetch(post.author_id)) || { id: post.author_id, username, discriminator, diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index 828ba54e..1b6bb197 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -3,6 +3,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { isDiscordRESTError } from "../../../utils"; +import { Message } from "discord.js"; export const ClearReactionRolesCmd = reactionRolesCmd({ trigger: "reaction_roles clear", @@ -21,9 +22,9 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ pluginData.state.reactionRoles.removeFromMessage(args.message.messageId); - let targetMessage: Message; + let targetMessage: Message; try { - targetMessage = await args.message.channel.getMessage(args.message.messageId); + targetMessage = await args.message.channel.messages.fetch(args.message.messageId); } catch (err) { if (isDiscordRESTError(err) && err.code === 50001) { sendErrorMessage(pluginData, msg.channel, "Missing access to the specified message"); @@ -33,7 +34,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ throw err; } - await targetMessage.removeReactions(); + await targetMessage.reactions.removeAll(); sendSuccessMessage(pluginData, msg.channel, "Reaction roles cleared"); }, diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 8518518f..2434dde5 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -1,8 +1,6 @@ import { reactionRolesCmd, TReactionRolePair } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; - -import { RecoverablePluginError, ERRORS } from "../../../RecoverablePluginError"; import { canUseEmoji, isDiscordRESTError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; import { canReadChannel } from "../../../utils/canReadChannel"; @@ -41,7 +39,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ let targetMessage; try { - targetMessage = await args.message.channel.getMessage(args.message.messageId).catch(noop); + targetMessage = await args.message.channel.messages.fetch(args.message.messageId).catch(noop); } catch (e) { if (isDiscordRESTError(e)) { sendErrorMessage(pluginData, msg.channel, `Error ${e.code} while getting message: ${e.message}`); @@ -96,13 +94,13 @@ export const InitReactionRolesCmd = reactionRolesCmd({ return; } - if (!pluginData.guild.roles.has(pair[1])) { + if (!pluginData.guild.roles.cache.has(pair[1])) { sendErrorMessage(pluginData, msg.channel, `Unknown role ${pair[1]}`); return; } } - const progressMessage = msg.channel.createMessage("Adding reaction roles..."); + const progressMessage = msg.channel.send("Adding reaction roles..."); // Save the new reaction roles to the database for (const pair of emojiRolePairs) { diff --git a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts index 63fef94f..b8331cf5 100644 --- a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts @@ -4,6 +4,7 @@ import { addMemberPendingRoleChange } from "../util/addMemberPendingRoleChange"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; +import { Message } from "discord.js"; const CLEAR_ROLES_EMOJI = "❌"; @@ -12,9 +13,9 @@ export const AddReactionRoleEvt = reactionRolesEvt({ async listener(meta) { const pluginData = meta.pluginData; - const msg = meta.args.message as Message; - const emoji = meta.args.emoji; - const userId = meta.args.member.id; + const msg = meta.args.reaction.message as Message; + const emoji = meta.args.reaction.emoji; + const userId = meta.args.user.id; if (userId === pluginData.client.user!.id) { // Don't act on own reactions @@ -39,7 +40,7 @@ export const AddReactionRoleEvt = reactionRolesEvt({ // User reacted with a reaction role emoji -> add the role const matchingReactionRole = await pluginData.state.reactionRoles.getByMessageAndEmoji( msg.id, - emoji.id || emoji.name, + emoji.id || emoji.name!, ); if (!matchingReactionRole) return; @@ -59,9 +60,8 @@ export const AddReactionRoleEvt = reactionRolesEvt({ if (config.remove_user_reactions) { setTimeout(() => { pluginData.state.reactionRemoveQueue.add(async () => { - const reaction = emoji.id ? `${emoji.name}:${emoji.id}` : emoji.name; const wait = sleep(1500); - await msg.channel.removeMessageReaction(msg.id, reaction, userId).catch(noop); + await meta.args.reaction.remove().catch(noop); await wait; }); }, 1500); diff --git a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts index 00ae6108..1bc5bf73 100644 --- a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts +++ b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts @@ -23,7 +23,7 @@ export async function addMemberPendingRoleChange( const member = await resolveMember(pluginData.client, pluginData.guild, memberId); if (member) { - const newRoleIds = new Set(member.roles); + const newRoleIds = new Set(member.roles.cache.keyArray()); for (const change of newPendingRoleChangeObj.changes) { if (change.mode === "+") newRoleIds.add(change.roleId); else newRoleIds.delete(change.roleId); @@ -38,7 +38,7 @@ export async function addMemberPendingRoleChange( ); } catch (e) { logger.warn( - `Failed to apply role changes to ${member.username}#${member.discriminator} (${member.id}): ${e.message}`, + `Failed to apply role changes to ${member.user.username}#${member.user.discriminator} (${member.id}): ${e.message}`, ); } } diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index 63421863..ea143838 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -6,6 +6,7 @@ import { isDiscordRESTError, sleep, isSnowflake } from "../../../utils"; import { logger } from "../../../logger"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; +import { TextChannel } from "discord.js"; const CLEAR_ROLES_EMOJI = "❌"; @@ -26,7 +27,7 @@ export async function applyReactionRoleReactionsToMessage( let targetMessage; try { - targetMessage = await channel.getMessage(messageId); + targetMessage = await channel.messages.fetch(messageId); } catch (e) { if (isDiscordRESTError(e)) { if (e.code === 10008) { diff --git a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts index d0c4765d..7a5d447a 100644 --- a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts +++ b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts @@ -4,6 +4,7 @@ import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; import { disableLinkPreviews } from "knub/dist/helpers"; import { SECONDS } from "../../../utils"; +import { TextChannel } from "discord.js"; const REMINDER_LOOP_TIME = 10 * SECONDS; const MAX_TRIES = 3; @@ -19,7 +20,7 @@ export async function postDueRemindersLoop(pluginData: GuildPluginData: ${reminder.body} \n\`Set at ${reminder.created_at} (${result} ago)\``, ), @@ -28,7 +29,7 @@ export async function postDueRemindersLoop(pluginData: GuildPluginData: ${reminder.body}`), allowedMentions: { users: [reminder.user_id], diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index e49b6d7f..cc093d3e 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -3,6 +3,7 @@ import { sendErrorMessage, sendSuccessMessage, canActOn } from "../../../pluginU import { rolesCmd } from "../types"; import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; import { LogType } from "../../../data/LogType"; +import { GuildChannel } from "discord.js"; export const AddRoleCmd = rolesCmd({ trigger: "addrole", @@ -33,7 +34,7 @@ export const AddRoleCmd = rolesCmd({ } // Sanity check: make sure the role is configured properly - const role = (msg.channel as GuildChannel).guild.roles.get(roleId); + const role = (msg.channel as GuildChannel).guild.roles.cache.get(roleId); if (!role) { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Unknown role configured for 'roles' plugin: ${roleId}`, @@ -42,14 +43,14 @@ export const AddRoleCmd = rolesCmd({ return; } - if (args.member.roles.includes(roleId)) { + if (args.member.roles.cache.has(roleId)) { sendErrorMessage(pluginData, msg.channel, "Member already has that role"); return; } pluginData.state.logs.ignoreLog(LogType.MEMBER_ROLE_ADD, args.member.id); - await args.member.addRole(roleId); + await args.member.roles.add(roleId); pluginData.state.logs.log(LogType.MEMBER_ROLE_ADD, { member: stripObjectToScalars(args.member, ["user", "roles"]), diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 32b953a7..f2f0532d 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -4,6 +4,7 @@ import { rolesCmd } from "../types"; import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; +import { GuildMember } from "discord.js"; export const MassAddRoleCmd = rolesCmd({ trigger: "massaddrole", @@ -15,9 +16,9 @@ export const MassAddRoleCmd = rolesCmd({ }, async run({ message: msg, args, pluginData }) { - msg.channel.createMessage(`Resolving members...`); + msg.channel.send(`Resolving members...`); - const members: Member[] = []; + const members: GuildMember[] = []; const unknownMembers: string[] = []; for (const memberId of args.members) { const member = await resolveMember(pluginData.client, pluginData.guild, memberId); @@ -57,12 +58,12 @@ export const MassAddRoleCmd = rolesCmd({ return; } - const membersWithoutTheRole = members.filter(m => !m.roles.includes(roleId)); + const membersWithoutTheRole = members.filter(m => !m.roles.cache.has(roleId)); let assigned = 0; const failed: string[] = []; const alreadyHadRole = members.length - membersWithoutTheRole.length; - msg.channel.createMessage( + msg.channel.send( `Adding role **${role.name}** to ${membersWithoutTheRole.length} ${ membersWithoutTheRole.length === 1 ? "member" : "members" }...`, @@ -71,7 +72,7 @@ export const MassAddRoleCmd = rolesCmd({ for (const member of membersWithoutTheRole) { try { pluginData.state.logs.ignoreLog(LogType.MEMBER_ROLE_ADD, member.id); - await member.addRole(roleId); + await member.roles.add(roleId); pluginData.state.logs.log(LogType.MEMBER_ROLE_ADD, { member: stripObjectToScalars(member, ["user", "roles"]), roles: role.name, @@ -97,6 +98,6 @@ export const MassAddRoleCmd = rolesCmd({ resultMessage += `\nUnknown members: ${unknownMembers.join(", ")}`; } - msg.channel.createMessage(successMessage(resultMessage)); + msg.channel.send(successMessage(resultMessage)); }, }); diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index b9d085f1..42240164 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -4,6 +4,7 @@ import { rolesCmd } from "../types"; import { resolveMember, stripObjectToScalars, successMessage, resolveRoleId } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; +import { GuildMember } from "discord.js"; export const MassRemoveRoleCmd = rolesCmd({ trigger: "massremoverole", @@ -15,9 +16,9 @@ export const MassRemoveRoleCmd = rolesCmd({ }, async run({ message: msg, args, pluginData }) { - msg.channel.createMessage(`Resolving members...`); + msg.channel.send(`Resolving members...`); - const members: Member[] = []; + const members: GuildMember[] = []; const unknownMembers: string[] = []; for (const memberId of args.members) { const member = await resolveMember(pluginData.client, pluginData.guild, memberId); @@ -57,12 +58,12 @@ export const MassRemoveRoleCmd = rolesCmd({ return; } - const membersWithTheRole = members.filter(m => m.roles.includes(roleId)); + const membersWithTheRole = members.filter(m => m.roles.cache.has(roleId)); let assigned = 0; const failed: string[] = []; const didNotHaveRole = members.length - membersWithTheRole.length; - msg.channel.createMessage( + msg.channel.send( `Removing role **${role.name}** from ${membersWithTheRole.length} ${ membersWithTheRole.length === 1 ? "member" : "members" }...`, @@ -71,7 +72,7 @@ export const MassRemoveRoleCmd = rolesCmd({ for (const member of membersWithTheRole) { try { pluginData.state.logs.ignoreLog(LogType.MEMBER_ROLE_REMOVE, member.id); - await member.removeRole(roleId); + await member.roles.remove(roleId); pluginData.state.logs.log(LogType.MEMBER_ROLE_REMOVE, { member: stripObjectToScalars(member, ["user", "roles"]), roles: role.name, @@ -97,6 +98,6 @@ export const MassRemoveRoleCmd = rolesCmd({ resultMessage += `\nUnknown members: ${unknownMembers.join(", ")}`; } - msg.channel.createMessage(successMessage(resultMessage)); + msg.channel.send(successMessage(resultMessage)); }, }); diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index 12f5b640..b160bff3 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -4,6 +4,7 @@ import { rolesCmd } from "../types"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars, verboseUserMention, resolveRoleId } from "../../../utils"; +import { GuildChannel } from "discord.js"; export const RemoveRoleCmd = rolesCmd({ trigger: "removerole", @@ -34,7 +35,7 @@ export const RemoveRoleCmd = rolesCmd({ } // Sanity check: make sure the role is configured properly - const role = (msg.channel as GuildChannel).guild.roles.get(roleId); + const role = (msg.channel as GuildChannel).guild.roles.cache.get(roleId); if (!role) { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Unknown role configured for 'roles' plugin: ${roleId}`, @@ -43,14 +44,14 @@ export const RemoveRoleCmd = rolesCmd({ return; } - if (!args.member.roles.includes(roleId)) { + if (!args.member.roles.cache.has(roleId)) { sendErrorMessage(pluginData, msg.channel, "Member doesn't have that role"); return; } pluginData.state.logs.ignoreLog(LogType.MEMBER_ROLE_REMOVE, args.member.id); - await args.member.removeRole(roleId); + await args.member.roles.remove(roleId); pluginData.state.logs.log(LogType.MEMBER_ROLE_REMOVE, { member: stripObjectToScalars(args.member, ["user", "roles"]), diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index 3f165e4e..cf3d9c84 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -7,6 +7,7 @@ import { normalizeRoleNames } from "../util/normalizeRoleNames"; import { findMatchingRoles } from "../util/findMatchingRoles"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { Role } from "discord.js"; export const RoleAddCmd = selfGrantableRolesCmd({ trigger: ["role", "role add"], @@ -49,7 +50,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ } // Grant the roles - const newRoleIds = new Set([...rolesToAdd.keys(), ...msg.member.roles]); + const newRoleIds = new Set([...rolesToAdd.keys(), ...msg.member.roles.cache.keys()]); // Remove extra roles (max_roles) for each entry const skipped: Set = new Set(); @@ -68,7 +69,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ newRoleIds.delete(roleId); rolesToAdd.delete(roleId); - if (msg.member.roles.includes(roleId)) { + if (msg.member.roles.cache.has(roleId)) { removed.add(pluginData.guild.roles.cache.get(roleId)!); } else { skipped.add(pluginData.guild.roles.cache.get(roleId)!); diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts index 41d96d55..2969ac0b 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts @@ -47,6 +47,6 @@ export const RoleHelpCmd = selfGrantableRolesCmd({ color: parseInt("42bff4", 16), }; - msg.channel.createMessage({ embed: helpEmbed }); + msg.channel.send({ embed: helpEmbed }); }, }); diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index ba4240f6..5d41e639 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -32,7 +32,7 @@ export const RoleRemoveCmd = selfGrantableRolesCmd({ // Remove the roles if (rolesToRemove.length) { - const newRoleIds = msg.member.roles.filter(roleId => !roleIdsToRemove.includes(roleId)); + const newRoleIds = msg.member.roles.cache.filter(role => !roleIdsToRemove.includes(role.id)); try { await msg.member.edit({ diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts index 567a2da9..276e28e9 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts @@ -2,6 +2,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { slowmodeCmd } from "../types"; import humanizeDuration from "humanize-duration"; +import { TextChannel } from "discord.js"; export const SlowmodeGetCmd = slowmodeCmd({ trigger: "slowmode", @@ -29,9 +30,9 @@ export const SlowmodeGetCmd = slowmodeCmd({ if (currentSlowmode) { const humanized = humanizeDuration(channel.rateLimitPerUser * 1000); const slowmodeType = isNative ? "native" : "bot-maintained"; - msg.channel.createMessage(`The current slowmode of <#${channel.id}> is **${humanized}** (${slowmodeType})`); + msg.channel.send(`The current slowmode of <#${channel.id}> is **${humanized}** (${slowmodeType})`); } else { - msg.channel.createMessage("Channel is not on slowmode"); + msg.channel.send("Channel is not on slowmode"); } }, }); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts index 7571b358..0ea52e9f 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts @@ -3,6 +3,7 @@ import { slowmodeCmd } from "../types"; import { createChunkedMessage } from "knub/dist/helpers"; import { errorMessage } from "../../../utils"; import humanizeDuration from "humanize-duration"; +import { GuildChannel, TextChannel } from "discord.js"; export const SlowmodeListCmd = slowmodeCmd({ trigger: ["slowmode list", "slowmode l", "slowmodes"], @@ -12,7 +13,7 @@ export const SlowmodeListCmd = slowmodeCmd({ const channels = pluginData.guild.channels; const slowmodes: Array<{ channel: GuildChannel; seconds: number; native: boolean }> = []; - for (const channel of channels.values()) { + for (const channel of channels.cache.values()) { if (!(channel instanceof TextChannel)) continue; // Bot slowmode @@ -40,7 +41,7 @@ export const SlowmodeListCmd = slowmodeCmd({ createChunkedMessage(msg.channel, lines.join("\n")); } else { - msg.channel.createMessage(errorMessage("No active slowmodes!")); + msg.channel.send(errorMessage("No active slowmodes!")); } }, }); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index aeebeb35..633e77c6 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -9,6 +9,7 @@ import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { BOT_SLOWMODE_PERMISSIONS, NATIVE_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; +import { Permissions, TextChannel } from "discord.js"; const MAX_NATIVE_SLOWMODE = 6 * HOURS; // 6 hours const MAX_BOT_SLOWMODE = DAYS * 365 * 100; // 100 years @@ -84,10 +85,13 @@ export const SlowmodeSetCmd = slowmodeCmd({ } // Verify permissions - const channelPermissions = channel.permissionsOf(pluginData.client.user!.id); + const channelPermissions = channel.permissionsFor(pluginData.client.user!.id); if (mode === "native") { - const missingPermissions = getMissingPermissions(channelPermissions, NATIVE_SLOWMODE_PERMISSIONS); + const missingPermissions = getMissingPermissions( + channelPermissions ? channelPermissions : new Permissions(), + NATIVE_SLOWMODE_PERMISSIONS, + ); if (missingPermissions) { sendErrorMessage( pluginData, @@ -99,7 +103,10 @@ export const SlowmodeSetCmd = slowmodeCmd({ } if (mode === "bot") { - const missingPermissions = getMissingPermissions(channelPermissions, BOT_SLOWMODE_PERMISSIONS); + const missingPermissions = getMissingPermissions( + channelPermissions ? channelPermissions : new Permissions(), + BOT_SLOWMODE_PERMISSIONS, + ); if (missingPermissions) { sendErrorMessage( pluginData, diff --git a/backend/src/plugins/Slowmode/requiredPermissions.ts b/backend/src/plugins/Slowmode/requiredPermissions.ts index bee1a4bc..ea9065be 100644 --- a/backend/src/plugins/Slowmode/requiredPermissions.ts +++ b/backend/src/plugins/Slowmode/requiredPermissions.ts @@ -1,6 +1,8 @@ -const p = Constants.Permissions; +import { Permissions } from "discord.js"; -export const NATIVE_SLOWMODE_PERMISSIONS = p.readMessages | p.manageChannels; -export const BOT_SLOWMODE_PERMISSIONS = p.readMessages | p.manageRoles | p.manageMessages; -export const BOT_SLOWMODE_CLEAR_PERMISSIONS = p.readMessages | p.manageRoles; -export const BOT_SLOWMODE_DISABLE_PERMISSIONS = p.readMessages | p.manageRoles; +const p = Permissions.FLAGS; + +export const NATIVE_SLOWMODE_PERMISSIONS = p.VIEW_CHANNEL | p.MANAGE_CHANNELS; +export const BOT_SLOWMODE_PERMISSIONS = p.VIEW_CHANNEL | p.MANAGE_ROLES | p.MANAGE_MESSAGES; +export const BOT_SLOWMODE_CLEAR_PERMISSIONS = p.VIEW_CHANNEL | p.MANAGE_ROLES; +export const BOT_SLOWMODE_DISABLE_PERMISSIONS = p.VIEW_CHANNEL | p.MANAGE_ROLES; diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index 41e5660e..4d02cf09 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -4,13 +4,14 @@ import { noop } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { Message, TextChannel } from "discord.js"; export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const botSlowmode = await pluginData.state.slowmodes.getChannelSlowmode(args.channel.id); const hasNativeSlowmode = args.channel.rateLimitPerUser; if (!botSlowmode && hasNativeSlowmode === 0) { - sendErrorMessage(pluginData, msg.channel, "Channel is not on slowmode!"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "Channel is not on slowmode!"); return; } @@ -19,13 +20,13 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { if (missingPermissions) { sendErrorMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`, ); return; } - const initMsg = await msg.channel.createMessage("Disabling slowmode..."); + const initMsg = await msg.channel.send("Disabling slowmode..."); // Disable bot-maintained slowmode let failedUsers: string[] = []; @@ -42,11 +43,11 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { if (failedUsers.length) { sendSuccessMessage( pluginData, - msg.channel, + msg.channel as TextChannel, `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, ); } else { - sendSuccessMessage(pluginData, msg.channel, "Slowmode disabled!"); + sendSuccessMessage(pluginData, msg.channel as TextChannel, "Slowmode disabled!"); initMsg.delete().catch(noop); } } diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 775a29a3..02f465ec 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -4,6 +4,7 @@ import { GuildPluginData } from "knub"; import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; +import { GuildChannel, TextChannel, Permissions } from "discord.js"; export async function applyBotSlowmodeToUserId( pluginData: GuildPluginData, @@ -12,13 +13,17 @@ export async function applyBotSlowmodeToUserId( ) { // Deny sendMessage permission from the user. If there are existing permission overwrites, take those into account. const existingOverride = channel.permissionOverwrites.get(userId); - const newDeniedPermissions = (existingOverride ? existingOverride.deny : 0n) | Constants.Permissions.sendMessages; - const newAllowedPermissions = (existingOverride ? existingOverride.allow : 0n) & ~Constants.Permissions.sendMessages; + const newDeniedPermissions = + (existingOverride ? existingOverride.deny.bitfield : 0n) | Permissions.FLAGS.SEND_MESSAGES; + const newAllowedPermissions = + (existingOverride ? existingOverride.allow.bitfield : 0n) & ~Permissions.FLAGS.SEND_MESSAGES; try { - await channel.editPermission(userId, newAllowedPermissions, newDeniedPermissions, "member"); + await channel.overwritePermissions([ + { id: userId, allow: newAllowedPermissions, deny: newDeniedPermissions, type: "member" }, + ]); } catch (e) { - const user = pluginData.client.user!.get(userId) || new UnknownUser({ id: userId }); + const user = pluginData.client.users.fetch(userId) || new UnknownUser({ id: userId }); if (isDiscordRESTError(e) && e.code === 50013) { logger.warn( diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index c44e1754..4f7cb4c6 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,3 +1,4 @@ +import { GuildChannel, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { SlowmodePluginType } from "../types"; @@ -12,7 +13,7 @@ export async function clearBotSlowmodeFromUserId( // Previously we diffed the overrides so we could clear the "send messages" override without touching other // overrides. Unfortunately, it seems that was a bit buggy - we didn't always receive the event for the changed // overrides and then we also couldn't diff against them. For consistency's sake, we just delete the override now. - await channel.deletePermission(userId); + await channel.permissionOverwrites.get(userId)?.delete(); } catch (e) { if (!force) { throw e; diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index 51764846..66357446 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -5,6 +5,7 @@ import { logger } from "../../../logger"; import { stripObjectToScalars, UnknownUser } from "../../../utils"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; +import { GuildChannel, TextChannel } from "discord.js"; export async function clearExpiredSlowmodes(pluginData: GuildPluginData) { const expiredSlowmodeUsers = await pluginData.state.slowmodes.getExpiredSlowmodeUsers(); @@ -20,7 +21,7 @@ export async function clearExpiredSlowmodes(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; @@ -49,7 +50,7 @@ export async function onMessageCreate(pluginData: GuildPluginData()({ // prettier-ignore events: [ - SpamVoiceJoinEvt, - SpamVoiceSwitchEvt, + SpamVoiceStateUpdateEvt, ], beforeLoad(pluginData) { diff --git a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts index ab99afd4..2b553e06 100644 --- a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts +++ b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts @@ -1,37 +1,13 @@ import { spamEvt, RecentActionType } from "../types"; import { logAndDetectOtherSpam } from "../util/logAndDetectOtherSpam"; -export const SpamVoiceJoinEvt = spamEvt({ - event: "voiceChannelJoin", +export const SpamVoiceStateUpdateEvt = spamEvt({ + event: "voiceStateUpdate", async listener(meta) { - const member = meta.args.member; - const channel = meta.args.newChannel; - - const config = await meta.pluginData.config.getMatchingConfig({ member, channelId: channel.id }); - const maxVoiceMoves = config.max_voice_moves; - if (maxVoiceMoves) { - logAndDetectOtherSpam( - meta.pluginData, - RecentActionType.VoiceChannelMove, - maxVoiceMoves, - member.id, - 1, - "0", - Date.now(), - null, - "too many voice channel moves", - ); - } - }, -}); - -export const SpamVoiceSwitchEvt = spamEvt({ - event: "voiceChannelSwitch", - - async listener(meta) { - const member = meta.args.member; - const channel = meta.args.newChannel; + const member = meta.args.newState.member; + if (!member) return; + const channel = meta.args.newState.channel!; const config = await meta.pluginData.config.getMatchingConfig({ member, channelId: channel.id }); const maxVoiceMoves = config.max_voice_moves; diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index 29e5f0b7..0ce54e7f 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -23,6 +23,7 @@ import { clearRecentUserActions } from "./clearRecentUserActions"; import { saveSpamArchives } from "./saveSpamArchives"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { TextChannel } from "discord.js"; export async function logAndDetectMessageSpam( pluginData: GuildPluginData, @@ -122,7 +123,7 @@ export async function logAndDetectMessageSpam( // Then, if enabled, remove the spam messages if (spamConfig.clean !== false) { msgIds.forEach(id => pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE, id)); - pluginData.client.deleteMessages(savedMessage.channel_id, msgIds).catch(noop); + (pluginData.guild.channels.cache.get(savedMessage.channel_id)! as TextChannel).bulkDelete(msgIds).catch(noop); } // Store the ID of the last handled message diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index 990ccd06..27b08d4d 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -3,6 +3,7 @@ import { starboardCmd } from "../types"; import { sendSuccessMessage, sendErrorMessage } from "../../../pluginUtils"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; +import { TextChannel } from "discord.js"; export const MigratePinsCmd = starboardCmd({ trigger: "starboard migrate_pins", @@ -29,9 +30,9 @@ export const MigratePinsCmd = starboardCmd({ return; } - msg.channel.createMessage(`Migrating pins from <#${args.pinChannel.id}> to <#${starboardChannel.id}>...`); + msg.channel.send(`Migrating pins from <#${args.pinChannel.id}> to <#${starboardChannel.id}>...`); - const pins = await args.pinChannel.getPins(); + const pins = (await args.pinChannel.messages.fetchPinned()).array(); pins.reverse(); // Migrate pins starting from the oldest message for (const pin of pins) { diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts index 4356a1f8..ddcdb925 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts @@ -4,6 +4,7 @@ import { UnknownUser, resolveMember, noop, resolveUser } from "../../../utils"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; import { updateStarboardMessageStarCount } from "../util/updateStarboardMessageStarCount"; import { allStarboardsLock } from "../../../utils/lockNameHelpers"; +import { Message, TextChannel } from "discord.js"; export const StarboardReactionAddEvt = starboardEvt({ event: "messageReactionAdd", @@ -11,14 +12,14 @@ export const StarboardReactionAddEvt = starboardEvt({ async listener(meta) { const pluginData = meta.pluginData; - let msg = meta.args.message as Message; - const userId = meta.args.member.id; - const emoji = meta.args.emoji; + let msg = meta.args.reaction.message as Message; + const userId = meta.args.user.id; + const emoji = meta.args.reaction.emoji; if (!msg.author) { // Message is not cached, fetch it try { - msg = await msg.channel.getMessage(msg.id); + msg = await msg.channel.messages.fetch(msg.id); } catch { // Sometimes we get this event for messages we can't fetch with getMessage; ignore silently return; @@ -29,7 +30,7 @@ export const StarboardReactionAddEvt = starboardEvt({ if (msg.author.id === userId) return; const member = await resolveMember(pluginData.client, pluginData.guild, userId); - if (!member || member.bot) return; + if (!member || member.user.bot) return; const config = await pluginData.config.getMatchingConfig({ member, @@ -76,10 +77,8 @@ export const StarboardReactionAddEvt = starboardEvt({ // If the message has already been posted to this starboard, update star counts if (starboard.show_star_count) { for (const starboardMessage of starboardMessages) { - const realStarboardMessage = await pluginData.client.getMessage( - starboardMessage.starboard_channel_id, - starboardMessage.starboard_message_id, - ); + const channel = pluginData.guild.channels.cache.get(starboardMessage.starboard_channel_id) as TextChannel; + const realStarboardMessage = await channel.messages.fetch(starboardMessage.starboard_message_id); await updateStarboardMessageStarCount( starboard, msg, diff --git a/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts b/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts index bc4bfae4..203c4bde 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts @@ -6,7 +6,10 @@ export const StarboardReactionRemoveEvt = starboardEvt({ async listener(meta) { const boardLock = await meta.pluginData.locks.acquire(allStarboardsLock()); - await meta.pluginData.state.starboardReactions.deleteStarboardReaction(meta.args.message.id, meta.args.userID); + await meta.pluginData.state.starboardReactions.deleteStarboardReaction( + meta.args.reaction.message.id, + meta.args.user.id, + ); boardLock.unlock(); }, }); diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 304bb410..7c47e846 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -1,6 +1,7 @@ import { EmbedWith, EMPTY_CHAR, messageLink } from "../../../utils"; import path from "path"; +import { Message, GuildChannel } from "discord.js"; const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"]; const audioAttachmentExtensions = ["wav", "mp3", "m4a"]; @@ -21,15 +22,15 @@ export function createStarboardEmbedFromMessage( name: `${msg.author.username}#${msg.author.discriminator}`, }, fields: [], - timestamp: new Date(msg.timestamp).toISOString(), + timestamp: msg.createdAt, }; if (color != null) { embed.color = color; } - if (msg.author.avatarURL) { - embed.author.icon_url = msg.author.avatarURL; + if (msg.author.avatarURL()) { + embed.author.icon_url = msg.author.avatarURL()!; } // The second condition here checks for messages with only an image link that is then embedded. @@ -59,15 +60,15 @@ export function createStarboardEmbedFromMessage( } // If there are no embeds, add the first image attachment explicitly - else if (msg.attachments.length) { + else if (msg.attachments.size) { for (const attachment of msg.attachments) { const ext = path - .extname(attachment.filename) + .extname(attachment[1].name!) .slice(1) .toLowerCase(); if (imageAttachmentExtensions.includes(ext)) { - embed.image = { url: attachment.url }; + embed.image = { url: attachment[1].url }; break; } diff --git a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts index d33413c0..04f32806 100644 --- a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts @@ -1,3 +1,4 @@ +import { Message, EmbedField } from "discord.js"; import { EMPTY_CHAR, messageLink } from "../../../utils"; import { TStarboardOpts } from "../types"; @@ -22,5 +23,6 @@ export function createStarboardPseudoFooterForMessage( return { name: EMPTY_CHAR, value: content, + inline: false, }; } diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index 99c74ad0..88f6023b 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -6,6 +6,7 @@ import { EmbedWith, EMPTY_CHAR, messageLink } from "../../../utils"; import path from "path"; import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; +import { Message, TextChannel } from "discord.js"; export async function saveMessageToStarboard( pluginData: GuildPluginData, @@ -19,6 +20,6 @@ export async function saveMessageToStarboard( const embed = createStarboardEmbedFromMessage(msg, Boolean(starboard.copy_full_embed), starboard.color); embed.fields!.push(createStarboardPseudoFooterForMessage(starboard, msg, starboard.star_emoji![0], starCount)); - const starboardMessage = await (channel as TextChannel).createMessage({ embed }); + const starboardMessage = await (channel as TextChannel).send(embed); await pluginData.state.starboardMessages.createStarboardMessage(channel.id, msg.id, starboardMessage.id); } diff --git a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts index 0d26f7c1..3cccbd37 100644 --- a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts +++ b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts @@ -2,6 +2,7 @@ import { noop } from "../../../utils"; import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; import { TStarboardOpts } from "../types"; import Timeout = NodeJS.Timeout; +import { Message } from "discord.js"; const DEBOUNCE_DELAY = 1000; const debouncedUpdates: Record = {}; diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index a17f9345..889c92b2 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -214,11 +214,11 @@ export const TagsPlugin = zeppelinGuildPlugin()({ return input; } - if (pluginData.guild.members.has(input) || pluginData.client.user!.has(input)) { + if (pluginData.guild.members.cache.has(input) || pluginData.client.users.resolve(input)) { return `<@!${input}>`; } - if (pluginData.guild.channels.has(input) || pluginData.client.channelGuildMap[input]) { + if (pluginData.guild.channels.cache.has(input)) { return `<#${input}>`; } diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 1569aeed..7d47b8be 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -32,7 +32,7 @@ export const TagEvalCmd = tagsCmd({ return; } - msg.channel.createMessage(rendered); + msg.channel.send(rendered); } catch (e) { if (e instanceof TemplateParseError) { sendErrorMessage(pluginData, msg.channel, `Failed to render tag: ${e.message}`); diff --git a/backend/src/plugins/Tags/commands/TagListCmd.ts b/backend/src/plugins/Tags/commands/TagListCmd.ts index 9e10892e..8ab8d8de 100644 --- a/backend/src/plugins/Tags/commands/TagListCmd.ts +++ b/backend/src/plugins/Tags/commands/TagListCmd.ts @@ -8,7 +8,7 @@ export const TagListCmd = tagsCmd({ async run({ message: msg, pluginData }) { const tags = await pluginData.state.tags.all(); if (tags.length === 0) { - msg.channel.createMessage(`No tags created yet! Use \`tag create\` command to create one.`); + msg.channel.send(`No tags created yet! Use \`tag create\` command to create one.`); return; } diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts index ed3fde87..08847b00 100644 --- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts +++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts @@ -35,6 +35,6 @@ export const TagSourceCmd = tagsCmd({ const archiveId = await pluginData.state.archives.create(tag.body, moment.utc().add(10, "minutes")); const url = pluginData.state.archives.getUrl(getBaseUrl(pluginData), archiveId); - msg.channel.createMessage(`Tag source:\n${url}`); + msg.channel.send(`Tag source:\n${url}`); }, }); diff --git a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts index d44415fc..968fc1e7 100644 --- a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts +++ b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts @@ -4,6 +4,7 @@ import { TagsPluginType, TTagCategory } from "../types"; import { renderTagFromString } from "./renderTagFromString"; import { convertDelayStringToMS, StrictMessageContent } from "../../../utils"; import escapeStringRegexp from "escape-string-regexp"; +import { GuildMember } from "discord.js"; interface BaseResult { renderedContent: StrictMessageContent; @@ -25,7 +26,7 @@ type Result = ResultWithCategory | ResultWithoutCategory; export async function matchAndRenderTagFromString( pluginData: GuildPluginData, str: string, - member: Member, + member: GuildMember, extraMatchParams: ExtendedMatchParams = {}, ): Promise { const config = await pluginData.config.getMatchingConfig({ diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index 1171216c..e6169eb5 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -7,6 +7,8 @@ import { LogType } from "../../../data/LogType"; import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString"; import { messageIsEmpty } from "../../../utils/messageIsEmpty"; +import { TextChannel } from "discord.js"; +import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; @@ -100,9 +102,9 @@ export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { // Command message was deleted -> delete the response as well @@ -12,7 +13,7 @@ export async function onMessageDelete(pluginData: GuildPluginData, @@ -16,7 +17,7 @@ export async function renderTagFromString( prefix: string, tagName: string, tagBody: t.TypeOf, - member: Member, + member: GuildMember, ): Promise { const variableStr = str.slice(prefix.length + tagName.length).trim(); const tagArgs = parseArguments(variableStr).map(v => v.value); diff --git a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts index 292f46de..d1d41694 100644 --- a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts @@ -13,11 +13,11 @@ export const ViewTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message, args }) { const memberTimezone = await pluginData.state.memberTimezones.get(message.author.id); if (memberTimezone) { - message.channel.createMessage(`Your timezone is currently set to **${memberTimezone.timezone}**`); + message.channel.send(`Your timezone is currently set to **${memberTimezone.timezone}**`); return; } const serverTimezone = getGuildTz(pluginData); - message.channel.createMessage(`Your timezone is currently set to **${serverTimezone}** (server default)`); + message.channel.send(`Your timezone is currently set to **${serverTimezone}** (server default)`); }, }); diff --git a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts index 9165952e..10e134b9 100644 --- a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts +++ b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts @@ -11,10 +11,10 @@ export const MessageCreateUpdateUsernameEvt = usernameSaverEvt({ }); export const VoiceChannelJoinUpdateUsernameEvt = usernameSaverEvt({ - event: "voiceChannelJoin", + event: "voiceStateUpdate", async listener(meta) { - if (meta.args.member.bot) return; - meta.pluginData.state.updateQueue.add(() => updateUsername(meta.pluginData, meta.args.member.user)); + if (meta.args.newState.member?.user.bot) return; + meta.pluginData.state.updateQueue.add(() => updateUsername(meta.pluginData, meta.args.newState.member!.user)); }, }); diff --git a/backend/src/plugins/UsernameSaver/updateUsername.ts b/backend/src/plugins/UsernameSaver/updateUsername.ts index f29ed600..56debeac 100644 --- a/backend/src/plugins/UsernameSaver/updateUsername.ts +++ b/backend/src/plugins/UsernameSaver/updateUsername.ts @@ -1,3 +1,4 @@ +import { User } from "discord.js"; import { GuildPluginData } from "knub"; import { UsernameSaverPluginType } from "./types"; diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 264723b8..ad1d2bbf 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -1,7 +1,6 @@ import { utilityCmd } from "../types"; import { EmbedWith, multiSorter, resolveMember, sorter } from "../../../utils"; - import { getCurrentUptime } from "../../../uptime"; import humanizeDuration from "humanize-duration"; import LCL from "last-commit-log"; @@ -9,6 +8,7 @@ import path from "path"; import moment from "moment-timezone"; import { rootDir } from "../../../paths"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { GuildChannel, MessageOptions } from "discord.js"; export const AboutCmd = utilityCmd({ trigger: "about", @@ -41,7 +41,7 @@ export const AboutCmd = utilityCmd({ version = "?"; } - const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; + //const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; FIXME Sharding stuff const lastReload = humanizeDuration(Date.now() - pluginData.state.lastReload, { largest: 2, @@ -53,7 +53,7 @@ export const AboutCmd = utilityCmd({ ["Last reload", `${lastReload} ago`], ["Last update", lastUpdate], ["Version", version], - ["API latency", `${shard.latency}ms`], + // ["API latency", `${shard.latency}ms`], ["Server timezone", timeAndDate.getGuildTz()], ]; @@ -65,7 +65,7 @@ export const AboutCmd = utilityCmd({ ); loadedPlugins.sort(); - const aboutContent: MessageContent & { embed: EmbedWith<"title" | "fields"> } = { + const aboutContent: MessageOptions & { embed: EmbedWith<"title" | "fields"> } = { embed: { title: `About ${pluginData.client.user!.username}`, fields: [ @@ -102,7 +102,7 @@ export const AboutCmd = utilityCmd({ // For the embed color, find the highest colored role the bot has - this is their color on the server as well const botMember = await resolveMember(pluginData.client, pluginData.guild, pluginData.client.user!.id); - let botRoles = botMember?.roles.map(r => (msg.channel as GuildChannel).guild.roles.get(r)!) || []; + let botRoles = botMember?.roles.cache.map(r => (msg.channel as GuildChannel).guild.roles.cache.get(r.id)!) || []; botRoles = botRoles.filter(r => !!r); // Drop any unknown roles botRoles = botRoles.filter(r => r.color); // Filter to those with a color botRoles.sort(sorter("position", "DESC")); // Sort by position (highest first) @@ -111,10 +111,10 @@ export const AboutCmd = utilityCmd({ } // Use the bot avatar as the embed image - if (pluginData.client.user!avatarURL) { - aboutContent.embed.thumbnail = { url: pluginData.client.user!.avatarURL }; + if (pluginData.client.user!.avatarURL()) { + aboutContent.embed.thumbnail = { url: pluginData.client.user!.avatarURL()! }; } - msg.channel.createMessage(aboutContent); + msg.channel.send(aboutContent); }, }); diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index 51814d9e..c267afff 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -2,6 +2,7 @@ import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { UnknownUser } from "../../../utils"; import { sendErrorMessage } from "../../../pluginUtils"; +import { MessageEmbedOptions } from "discord.js"; export const AvatarCmd = utilityCmd({ trigger: ["avatar", "av"], @@ -15,15 +16,16 @@ export const AvatarCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { const user = args.user || msg.author; if (!(user instanceof UnknownUser)) { - let extension = user.avatarURL.slice(user.avatarURL.lastIndexOf("."), user.avatarURL.lastIndexOf("?")); + const avatar = user.avatarURL() || user.defaultAvatarURL; + let extension = avatar.slice(avatar.lastIndexOf("."), avatar.lastIndexOf("?")); // Some pngs can have the .jpg extention for some reason, so we always use .png for static images extension = extension === ".gif" ? extension : ".png"; - const avatarUrl = user.avatarURL.slice(0, user.avatarURL.lastIndexOf(".")); - const embed: EmbedOptions = { + const avatarUrl = avatar.slice(0, avatar.lastIndexOf(".")); + const embed: MessageEmbedOptions = { image: { url: avatarUrl + `${extension}?size=2048` }, }; embed.title = `Avatar of ${user.username}#${user.discriminator}:`; - msg.channel.createMessage({ embed }); + msg.channel.send({ embed }); } else { sendErrorMessage(pluginData, msg.channel, "Invalid user ID"); } diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index 044ba63d..dece87b7 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -20,6 +20,6 @@ export const ChannelInfoCmd = utilityCmd({ return; } - message.channel.createMessage({ embed }); + message.channel.send({ embed }); }, }); diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 72287c56..44db25b6 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -9,6 +9,7 @@ import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { allowTimeout } from "../../../RegExpRunner"; import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; +import { TextChannel, User, Message } from "discord.js"; const MAX_CLEAN_COUNT = 150; const MAX_CLEAN_TIME = 1 * DAYS; @@ -32,7 +33,7 @@ async function cleanMessages( pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE_BULK, idsToDelete[0]); // Actually delete the messages - await pluginData.client.deleteMessages(channel.id, idsToDelete); + (pluginData.guild.channels.cache.get(channel.id) as TextChannel).bulkDelete(idsToDelete); await pluginData.state.savedMessages.markBulkAsDeleted(idsToDelete); // Create an archive @@ -106,18 +107,18 @@ export const CleanCmd = utilityCmd({ } } - const cleaningMessage = msg.channel.createMessage("Cleaning..."); + const cleaningMessage = msg.channel.send("Cleaning..."); const messagesToClean: SavedMessage[] = []; let beforeId = msg.id; - const timeCutoff = msg.timestamp - MAX_CLEAN_TIME; + const timeCutoff = msg.createdTimestamp - MAX_CLEAN_TIME; const upToMsgId = args["to-id"]; let foundId = false; const deletePins = args["delete-pins"] != null ? args["delete-pins"] : false; let pins: Message[] = []; if (!deletePins) { - pins = await msg.channel.getPins(); + pins = (await msg.channel.messages.fetchPinned()).array(); } while (messagesToClean.length < args.count) { diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index 1ab2269d..9a11df10 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -4,6 +4,7 @@ import { messageLink } from "../../../utils"; import { sendErrorMessage } from "../../../pluginUtils"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { TextChannel } from "discord.js"; export const ContextCmd = utilityCmd({ trigger: "context", @@ -35,12 +36,17 @@ export const ContextCmd = utilityCmd({ return; } - const previousMessage = (await pluginData.client.getMessages(channel.id, 1, messageId))[0]; + const previousMessage = ( + await (pluginData.guild.channels.cache.get(channel.id) as TextChannel).messages.fetch({ + limit: 1, + before: messageId, + }) + )[0]; if (!previousMessage) { sendErrorMessage(pluginData, msg.channel, "Message context not found"); return; } - msg.channel.createMessage(messageLink(pluginData.guild.id, previousMessage.channel.id, previousMessage.id)); + msg.channel.send(messageLink(pluginData.guild.id, previousMessage.channel.id, previousMessage.id)); }, }); diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index 41889509..90d272d6 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -27,6 +27,6 @@ export const EmojiInfoCmd = utilityCmd({ return; } - message.channel.createMessage({ embed }); + message.channel.send({ embed }); }, }); diff --git a/backend/src/plugins/Utility/commands/HelpCmd.ts b/backend/src/plugins/Utility/commands/HelpCmd.ts index 8d4af9cc..f677f7d2 100644 --- a/backend/src/plugins/Utility/commands/HelpCmd.ts +++ b/backend/src/plugins/Utility/commands/HelpCmd.ts @@ -71,7 +71,7 @@ export const HelpCmd = utilityCmd({ }); if (totalResults === 0) { - msg.channel.createMessage("No matching commands found!"); + msg.channel.send("No matching commands found!"); return; } diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 19870f25..5a13fbed 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -42,7 +42,7 @@ export const InfoCmd = utilityCmd({ if (channel) { const embed = await getChannelInfoEmbed(pluginData, channelId!, message.author.id); if (embed) { - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -50,11 +50,11 @@ export const InfoCmd = utilityCmd({ // 2. Server if (userCfg.can_server) { - const guild = pluginData.client.guilds.get(value); + const guild = pluginData.client.guilds.fetch(value); if (guild) { const embed = await getServerInfoEmbed(pluginData, value, message.author.id); if (embed) { - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -66,7 +66,7 @@ export const InfoCmd = utilityCmd({ if (user && userCfg.can_userinfo) { const embed = await getUserInfoEmbed(pluginData, user.id, Boolean(args.compact), message.author.id); if (embed) { - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -84,7 +84,7 @@ export const InfoCmd = utilityCmd({ message.author.id, ); if (embed) { - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -99,7 +99,7 @@ export const InfoCmd = utilityCmd({ if (invite) { const embed = await getInviteInfoEmbed(pluginData, inviteCode); if (embed) { - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -112,7 +112,7 @@ export const InfoCmd = utilityCmd({ if (serverPreview) { const embed = await getServerInfoEmbed(pluginData, value, message.author.id); if (embed) { - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -124,7 +124,7 @@ export const InfoCmd = utilityCmd({ const role = roleId && pluginData.guild.roles.cache.get(roleId); if (role) { const embed = await getRoleInfoEmbed(pluginData, role, message.author.id); - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -135,7 +135,7 @@ export const InfoCmd = utilityCmd({ if (emojiIdMatch?.[2]) { const embed = await getEmojiInfoEmbed(pluginData, emojiIdMatch[2]); if (embed) { - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } } @@ -144,7 +144,7 @@ export const InfoCmd = utilityCmd({ // 9. Arbitrary ID if (isValidSnowflake(value) && userCfg.can_snowflake) { const embed = await getSnowflakeInfoEmbed(pluginData, value, true, message.author.id); - message.channel.createMessage({ embed }); + message.channel.send({ embed }); return; } diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index ee876026..a5c7fd9f 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -22,6 +22,6 @@ export const InviteInfoCmd = utilityCmd({ return; } - message.channel.createMessage({ embed }); + message.channel.send({ embed }); }, }); diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index d31e2dcb..276fa257 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -83,6 +83,6 @@ export const JumboCmd = utilityCmd({ }; } - msg.channel.createMessage("", file); + msg.channel.send("", file); }, }); diff --git a/backend/src/plugins/Utility/commands/LevelCmd.ts b/backend/src/plugins/Utility/commands/LevelCmd.ts index 4ad4ce5c..70b6ceae 100644 --- a/backend/src/plugins/Utility/commands/LevelCmd.ts +++ b/backend/src/plugins/Utility/commands/LevelCmd.ts @@ -17,6 +17,8 @@ export const LevelCmd = utilityCmd({ run({ message, args, pluginData }) { const member = args.member || message.member; const level = getMemberLevel(pluginData, member); - message.channel.createMessage(`The permission level of ${member.username}#${member.discriminator} is **${level}**`); + message.channel.send( + `The permission level of ${member.user.username}#${member.user.discriminator} is **${level}**`, + ); }, }); diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index 4681fd2e..e46dbc3a 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -31,6 +31,6 @@ export const MessageInfoCmd = utilityCmd({ return; } - message.channel.createMessage({ embed }); + message.channel.send({ embed }); }, }); diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index 4df752e8..b2da21cf 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -16,24 +16,24 @@ export const NicknameCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (msg.member.id !== args.member.id && !canActOn(pluginData, msg.member, args.member)) { - msg.channel.createMessage(errorMessage("Cannot change nickname: insufficient permissions")); + msg.channel.send(errorMessage("Cannot change nickname: insufficient permissions")); return; } const nicknameLength = [...args.nickname].length; if (nicknameLength < 2 || nicknameLength > 32) { - msg.channel.createMessage(errorMessage("Nickname must be between 2 and 32 characters long")); + msg.channel.send(errorMessage("Nickname must be between 2 and 32 characters long")); return; } - const oldNickname = args.member.nick || ""; + const oldNickname = args.member.nickname || ""; try { await args.member.edit({ nick: args.nickname, }); } catch { - msg.channel.createMessage(errorMessage("Failed to change nickname")); + msg.channel.send(errorMessage("Failed to change nickname")); return; } diff --git a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts index 33085053..e2e5db00 100644 --- a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts @@ -15,7 +15,7 @@ export const NicknameResetCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (msg.member.id !== args.member.id && !canActOn(pluginData, msg.member, args.member)) { - msg.channel.createMessage(errorMessage("Cannot reset nickname: insufficient permissions")); + msg.channel.send(errorMessage("Cannot reset nickname: insufficient permissions")); return; } @@ -24,7 +24,7 @@ export const NicknameResetCmd = utilityCmd({ nick: "", }); } catch { - msg.channel.createMessage(errorMessage("Failed to reset nickname")); + msg.channel.send(errorMessage("Failed to reset nickname")); return; } diff --git a/backend/src/plugins/Utility/commands/PingCmd.ts b/backend/src/plugins/Utility/commands/PingCmd.ts index 0bf671bc..08030f77 100644 --- a/backend/src/plugins/Utility/commands/PingCmd.ts +++ b/backend/src/plugins/Utility/commands/PingCmd.ts @@ -1,5 +1,6 @@ import { utilityCmd } from "../types"; import { noop, trimLines } from "../../../utils"; +import { Message } from "discord.js"; const { performance } = require("perf_hooks"); @@ -15,12 +16,12 @@ export const PingCmd = utilityCmd({ for (let i = 0; i < 4; i++) { const start = performance.now(); - const message = await msg.channel.createMessage(`Calculating ping... ${i + 1}`); + const message = await msg.channel.send(`Calculating ping... ${i + 1}`); times.push(performance.now() - start); messages.push(message); if (msgToMsgDelay === undefined) { - msgToMsgDelay = message.timestamp - msg.timestamp; + msgToMsgDelay = message.createdTimestamp - msg.createdTimestamp; } } @@ -28,25 +29,19 @@ export const PingCmd = utilityCmd({ const lowest = Math.round(Math.min(...times)); const mean = Math.round(times.reduce((total, ms) => total + ms, 0) / times.length); - const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; + // const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; FIXME sharding stuff - msg.channel.createMessage( + msg.channel.send( trimLines(` **Ping:** Lowest: **${lowest}ms** Highest: **${highest}ms** Mean: **${mean}ms** Time between ping command and first reply: **${msgToMsgDelay!}ms** - Shard latency: **${shard.latency}ms** - `), + `), // Omitted line: Shard latency: **${shard.latency}ms** ); // Clean up test messages - pluginData.client - .deleteMessages( - messages[0].channel.id, - messages.map(m => m.id), - ) - .catch(noop); + msg.channel.bulkDelete(messages).catch(noop); }, }); diff --git a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts index d7abeac8..1fc824e6 100644 --- a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts +++ b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts @@ -1,6 +1,7 @@ import { utilityCmd } from "../types"; import { activeReloads } from "../guildReloads"; +import { TextChannel } from "discord.js"; export const ReloadGuildCmd = utilityCmd({ trigger: "reload_guild", @@ -11,7 +12,7 @@ export const ReloadGuildCmd = utilityCmd({ if (activeReloads.has(pluginData.guild.id)) return; activeReloads.set(pluginData.guild.id, msg.channel as TextChannel); - msg.channel.createMessage("Reloading..."); + msg.channel.send("Reloading..."); pluginData.getKnubInstance().reloadGuild(pluginData.guild.id); }, }); diff --git a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts index 1b04bf9b..48406cb3 100644 --- a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts @@ -15,6 +15,6 @@ export const RoleInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const embed = await getRoleInfoEmbed(pluginData, args.role, message.author.id); - message.channel.createMessage({ embed }); + message.channel.send({ embed }); }, }); diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index e98c46e7..ea6ab800 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -4,6 +4,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { chunkArray, sorter, trimLines } from "../../../utils"; import { refreshMembersIfNeeded } from "../refreshMembers"; import { sendErrorMessage } from "../../../pluginUtils"; +import { Role, TextChannel } from "discord.js"; export const RolesCmd = utilityCmd({ trigger: "roles", @@ -21,7 +22,9 @@ export const RolesCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { const { guild } = pluginData; - let roles: Array<{ _memberCount?: number } & Role> = Array.from((msg.channel as TextChannel).guild.roles.values()); + let roles: Array<{ _memberCount?: number } & Role> = Array.from( + (msg.channel as TextChannel).guild.roles.cache.values(), + ); let sort = args.sort; if (args.search) { @@ -33,8 +36,8 @@ export const RolesCmd = utilityCmd({ await refreshMembersIfNeeded(guild); // If the user requested role member counts as well, calculate them and sort the roles by their member count - const roleCounts: Map = Array.from(guild.members.values()).reduce((map, member) => { - for (const roleId of member.roles) { + const roleCounts: Map = Array.from(guild.members.cache.values()).reduce((map, member) => { + for (const roleId of member.roles.cache) { if (!map.has(roleId)) map.set(roleId, 0); map.set(roleId, map.get(roleId) + 1); } @@ -97,14 +100,14 @@ export const RolesCmd = utilityCmd({ }); if (i === 0) { - msg.channel.createMessage( + msg.channel.send( trimLines(` ${args.search ? "Total roles found" : "Total roles"}: ${roles.length} \`\`\`py\n${roleLines.join("\n")}\`\`\` `), ); } else { - msg.channel.createMessage("```py\n" + roleLines.join("\n") + "```"); + msg.channel.send("```py\n" + roleLines.join("\n") + "```"); } } }, diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index 97a5d06a..aaf74c57 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -21,6 +21,6 @@ export const ServerInfoCmd = utilityCmd({ return; } - message.channel.createMessage({ embed: serverInfoEmbed }); + message.channel.send({ embed: serverInfoEmbed }); }, }); diff --git a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts index ee03044e..b2f5bb30 100644 --- a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts @@ -16,6 +16,6 @@ export const SnowflakeInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const embed = await getSnowflakeInfoEmbed(pluginData, args.id, false, message.author.id); - message.channel.createMessage({ embed }); + message.channel.send({ embed }); }, }); diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index 83e76e15..5a5d0c28 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -22,9 +22,7 @@ export const SourceCmd = utilityCmd({ return; } - const message = await pluginData.client - .getMessage(args.message.channel.id, args.message.messageId) - .catch(() => null); + const message = await args.message.channel.messages.fetch(args.message.messageId).catch(() => null); if (!message) { sendErrorMessage(pluginData, cmdMessage.channel, "Unknown message"); return; @@ -44,6 +42,6 @@ export const SourceCmd = utilityCmd({ const archiveId = await pluginData.state.archives.create(source, moment.utc().add(1, "hour")); const baseUrl = getBaseUrl(pluginData); const url = pluginData.state.archives.getUrl(baseUrl, archiveId); - cmdMessage.channel.createMessage(`Message source: ${url}`); + cmdMessage.channel.send(`Message source: ${url}`); }, }); diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index dca35e24..b7ceba39 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -23,6 +23,6 @@ export const UserInfoCmd = utilityCmd({ return; } - message.channel.createMessage({ embed }); + message.channel.send({ embed }); }, }); diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index c0e0cf63..d69c0fad 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -10,7 +10,7 @@ import { import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { LogType } from "../../../data/LogType"; -import { resolveChannel } from "knub/dist/helpers"; +import { VoiceChannel } from "discord.js"; export const VcdisconnectCmd = utilityCmd({ trigger: ["vcdisconnect", "vcdisc", "vcdc", "vckick", "vck"], @@ -28,16 +28,14 @@ export const VcdisconnectCmd = utilityCmd({ return; } - if (!args.member.voiceState || !args.member.voiceState.channelID) { + if (!args.member.voice || !args.member.voice.channelID) { sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); return; } - const channel = (await resolveChannel(pluginData.guild, args.member.voiceState.channelID)) as VoiceChannel; + const channel = pluginData.guild.channels.cache.get(args.member.voice.channelID) as VoiceChannel; try { - await args.member.edit({ - channelID: null, - }); + await args.member.voice.kick(); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to disconnect member"); return; diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index ae28f873..87c2ef74 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -11,6 +11,7 @@ import { import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { LogType } from "../../../data/LogType"; +import { VoiceChannel } from "discord.js"; export const VcmoveCmd = utilityCmd({ trigger: "vcmove", @@ -47,7 +48,7 @@ export const VcmoveCmd = utilityCmd({ channel = potentialChannel; } else { // Search string -> find closest matching voice channel name - const voiceChannels = pluginData.guild.channels.filter(theChannel => { + const voiceChannels = pluginData.guild.channels.cache.array().filter(theChannel => { return theChannel instanceof VoiceChannel; }) as VoiceChannel[]; const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, ch => ch.name); @@ -59,21 +60,21 @@ export const VcmoveCmd = utilityCmd({ channel = closestMatch; } - if (!args.member.voiceState || !args.member.voiceState.channelID) { + if (!args.member.voice || !args.member.voice.channelID) { sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); return; } - if (args.member.voiceState.channelID === channel.id) { + if (args.member.voice.channelID === channel.id) { sendErrorMessage(pluginData, msg.channel, "Member is already on that channel!"); return; } - const oldVoiceChannel = pluginData.guild.channels.cache.get(args.member.voiceState.channelID); + const oldVoiceChannel = pluginData.guild.channels.cache.get(args.member.voice.channelID); try { await args.member.edit({ - channelID: channel.id, + channel: channel.id, }); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to move member"); @@ -130,7 +131,7 @@ export const VcmoveAllCmd = utilityCmd({ channel = potentialChannel; } else { // Search string -> find closest matching voice channel name - const voiceChannels = pluginData.guild.channels.filter(theChannel => { + const voiceChannels = pluginData.guild.channels.cache.array().filter(theChannel => { return theChannel instanceof VoiceChannel; }) as VoiceChannel[]; const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, ch => ch.name); @@ -142,7 +143,7 @@ export const VcmoveAllCmd = utilityCmd({ channel = closestMatch; } - if (args.oldChannel.voiceMembers.size === 0) { + if (args.oldChannel.members.size === 0) { sendErrorMessage(pluginData, msg.channel, "Voice channel is empty"); return; } @@ -154,9 +155,9 @@ export const VcmoveAllCmd = utilityCmd({ // Cant leave null, otherwise we get an assignment error in the catch let currMember = msg.member; - const moveAmt = args.oldChannel.voiceMembers.size; + const moveAmt = args.oldChannel.members.size; let errAmt = 0; - for (const memberWithId of args.oldChannel.voiceMembers) { + for (const memberWithId of args.oldChannel.members) { currMember = memberWithId[1]; // Check for permissions but allow self-moves @@ -164,7 +165,7 @@ export const VcmoveAllCmd = utilityCmd({ sendErrorMessage( pluginData, msg.channel, - `Failed to move ${currMember.username}#${currMember.discriminator} (${currMember.id}): You cannot act on this member`, + `Failed to move ${currMember.user.username}#${currMember.user.discriminator} (${currMember.id}): You cannot act on this member`, ); errAmt++; continue; @@ -172,7 +173,7 @@ export const VcmoveAllCmd = utilityCmd({ try { currMember.edit({ - channelID: channel.id, + channel: channel.id, }); } catch { if (msg.member.id === currMember.id) { @@ -182,7 +183,7 @@ export const VcmoveAllCmd = utilityCmd({ sendErrorMessage( pluginData, msg.channel, - `Failed to move ${currMember.username}#${currMember.discriminator} (${currMember.id})`, + `Failed to move ${currMember.user.username}#${currMember.user.discriminator} (${currMember.id})`, ); errAmt++; continue; diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index 45756642..69b3d10c 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -5,6 +5,8 @@ import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; import { EmbedWith, formatNumber, preEmbedPadding, trimLines } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageEmbedOptions, Constants, VoiceChannel, StageChannel } from "discord.js"; +import { ChannelTypeStrings } from "src/types"; const TEXT_CHANNEL_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740656843545772062/text-channel.png"; @@ -19,7 +21,7 @@ export async function getChannelInfoEmbed( pluginData: GuildPluginData, channelId: string, requestMemberId?: string, -): Promise { +): Promise { const channel = pluginData.guild.channels.cache.get(channelId); if (!channel) { return null; @@ -30,22 +32,22 @@ export async function getChannelInfoEmbed( }; let icon = TEXT_CHANNEL_ICON; - if (channel.type === Constants.ChannelTypes.GUILD_VOICE) { + if (channel.type === ChannelTypeStrings.VOICE) { icon = VOICE_CHANNEL_ICON; - } else if (channel.type === Constants.ChannelTypes.GUILD_NEWS) { + } else if (channel.type === ChannelTypeStrings.NEWS) { icon = ANNOUNCEMENT_CHANNEL_ICON; - } else if (channel.type === Constants.ChannelTypes.GUILD_STAGE) { + } else if (channel.type === ChannelTypeStrings.STAGE) { icon = STAGE_CHANNEL_ICON; } const channelType = { - [Constants.ChannelTypes.GUILD_TEXT]: "Text channel", - [Constants.ChannelTypes.GUILD_VOICE]: "Voice channel", - [Constants.ChannelTypes.GUILD_CATEGORY]: "Category", - [Constants.ChannelTypes.GUILD_NEWS]: "Announcement channel", - [Constants.ChannelTypes.GUILD_STORE]: "Store channel", - [Constants.ChannelTypes.GUILD_STAGE]: "Stage channel", + [ChannelTypeStrings.TEXT]: "Text channel", + [ChannelTypeStrings.VOICE]: "Voice channel", + [ChannelTypeStrings.CATEGORY]: "Category", + [ChannelTypeStrings.NEWS]: "Announcement channel", + [ChannelTypeStrings.STORE]: "Store channel", + [ChannelTypeStrings.STAGE]: "Stage channel", }[channel.type] || "Channel"; embed.author = { @@ -55,9 +57,9 @@ export async function getChannelInfoEmbed( let channelName = `#${channel.name}`; if ( - channel.type === Constants.ChannelTypes.GUILD_VOICE || - channel.type === Constants.ChannelTypes.GUILD_CATEGORY || - channel.type === Constants.ChannelTypes.GUILD_STAGE + channel.type === ChannelTypeStrings.VOICE || + channel.type === ChannelTypeStrings.CATEGORY || + channel.type === ChannelTypeStrings.STAGE ) { channelName = channel.name; } @@ -68,12 +70,12 @@ export async function getChannelInfoEmbed( ? await timeAndDate.inMemberTz(requestMemberId, createdAt) : timeAndDate.inGuildTz(createdAt); const prettyCreatedAt = tzCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime")); - const channelAge = humanizeDuration(Date.now() - channel.createdAt, { + const channelAge = humanizeDuration(Date.now() - channel.createdTimestamp, { largest: 2, round: true, }); - const showMention = channel.type !== Constants.ChannelTypes.GUILD_CATEGORY; + const showMention = channel.type !== ChannelTypeStrings.CATEGORY; embed.fields.push({ name: preEmbedPadding + "Channel information", @@ -86,11 +88,11 @@ export async function getChannelInfoEmbed( `), }); - if (channel.type === Constants.ChannelTypes.GUILD_VOICE || channel.type === Constants.ChannelTypes.GUILD_STAGE) { - const voiceMembers = Array.from(channel.voiceMembers.values()); - const muted = voiceMembers.filter(vm => vm.voiceState.mute || vm.voiceState.selfMute); - const deafened = voiceMembers.filter(vm => vm.voiceState.deaf || vm.voiceState.selfDeaf); - const voiceOrStage = channel.type === Constants.ChannelTypes.GUILD_VOICE ? "Voice" : "Stage"; + if (channel.type === ChannelTypeStrings.VOICE || channel.type === ChannelTypeStrings.STAGE) { + const voiceMembers = Array.from((channel as VoiceChannel | StageChannel).members.values()); + const muted = voiceMembers.filter(vm => vm.voice.mute || vm.voice.selfMute); + const deafened = voiceMembers.filter(vm => vm.voice.deaf || vm.voice.selfDeaf); + const voiceOrStage = channel.type === ChannelTypeStrings.VOICE ? "Voice" : "Stage"; embed.fields.push({ name: preEmbedPadding + `${voiceOrStage} information`, @@ -102,21 +104,20 @@ export async function getChannelInfoEmbed( }); } - if (channel.type === Constants.ChannelTypes.GUILD_CATEGORY) { - const textChannels = pluginData.guild.channels.filter( - ch => ch.parentID === channel.id && ch.type !== Constants.ChannelTypes.GUILD_VOICE, + if (channel.type === ChannelTypeStrings.CATEGORY) { + const textChannels = pluginData.guild.channels.cache.filter( + ch => ch.parentID === channel.id && ch.type !== ChannelTypeStrings.VOICE, ); - const voiceChannels = pluginData.guild.channels.filter( + const voiceChannels = pluginData.guild.channels.cache.filter( ch => - ch.parentID === channel.id && - (ch.type === Constants.ChannelTypes.GUILD_VOICE || ch.type === Constants.ChannelTypes.GUILD_STAGE), + ch.parentID === channel.id && (ch.type === ChannelTypeStrings.VOICE || ch.type === ChannelTypeStrings.STAGE), ); embed.fields.push({ name: preEmbedPadding + "Category information", value: trimLines(` - Text channels: **${textChannels.length}** - Voice channels: **${voiceChannels.length}** + Text channels: **${textChannels.size}** + Voice channels: **${voiceChannels.size}** `), }); } diff --git a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts index b1e8297e..46ce8ab7 100644 --- a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts @@ -1,12 +1,13 @@ import { GuildPluginData } from "knub"; import { UtilityPluginType } from "../types"; import { trimLines, preEmbedPadding, EmbedWith } from "../../../utils"; +import { MessageEmbedOptions } from "discord.js"; export async function getEmojiInfoEmbed( pluginData: GuildPluginData, emojiId: string, -): Promise { - const emoji = pluginData.guild.emojis.find(e => e.id === emojiId); +): Promise { + const emoji = pluginData.guild.emojis.cache.find(e => e.id === emojiId); if (!emoji) { return null; } diff --git a/backend/src/plugins/Utility/functions/getGuildPreview.ts b/backend/src/plugins/Utility/functions/getGuildPreview.ts index 34d7f73c..3da2c823 100644 --- a/backend/src/plugins/Utility/functions/getGuildPreview.ts +++ b/backend/src/plugins/Utility/functions/getGuildPreview.ts @@ -1,8 +1,9 @@ +import { Client, GuildPreview } from "discord.js"; import { memoize, MINUTES } from "../../../utils"; /** * Memoized getGuildPreview */ export function getGuildPreview(client: Client, guildId: string): Promise { - return memoize(() => client.getGuildPreview(guildId).catch(() => null), `getGuildPreview_${guildId}`, 10 * MINUTES); + return memoize(() => client.fetchGuildPreview(guildId).catch(() => null), `getGuildPreview_${guildId}`, 10 * MINUTES); } diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index dff670b5..78be9002 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -9,6 +9,7 @@ import { EmbedWith, emptyEmbedValue, formatNumber, + GroupDMInvite, inviteHasCounts, isGroupDMInvite, isGuildInvite, @@ -16,12 +17,14 @@ import { resolveInvite, trimLines, } from "../../../utils"; +import { MessageEmbedOptions, Constants, Invite } from "discord.js"; +import { ChannelTypeStrings } from "src/types"; export async function getInviteInfoEmbed( pluginData: GuildPluginData, inviteCode: string, -): Promise { - const invite = await resolveInvite(pluginData.client, inviteCode, true); +): Promise { + let invite = await resolveInvite(pluginData.client, inviteCode, true); if (!invite) { return null; } @@ -67,9 +70,7 @@ export async function getInviteInfoEmbed( }); const channelName = - invite.channel.type === Constants.ChannelTypes.GUILD_VOICE - ? `🔉 ${invite.channel.name}` - : `#${invite.channel.name}`; + invite.channel.type === ChannelTypeStrings.VOICE ? `🔉 ${invite.channel.name}` : `#${invite.channel.name}`; const channelCreatedAtTimestamp = snowflakeToTimestamp(invite.channel.id); const channelCreatedAt = moment.utc(channelCreatedAtTimestamp, "x"); @@ -84,7 +85,7 @@ export async function getInviteInfoEmbed( Created: **${channelAge} ago** `); - if (invite.channel.type !== Constants.ChannelTypes.GUILD_VOICE) { + if (invite.channel.type !== ChannelTypeStrings.VOICE) { channelInfo += `\nMention: <#${invite.channel.id}>`; } @@ -113,16 +114,17 @@ export async function getInviteInfoEmbed( fields: [], }; + invite = invite as GroupDMInvite; embed.author = { name: invite.channel.name ? `Group DM invite: ${invite.channel.name}` : `Group DM invite`, url: `https://discord.gg/${invite.code}`, - }; + }; // FIXME pending invite re-think - if (invite.channel.icon) { + /*if (invite.channel.icon) { embed.author.icon_url = `https://cdn.discordapp.com/channel-icons/${invite.channel.id}/${invite.channel.icon}.png?size=256`; - } - - const channelCreatedAtTimestamp = snowflakeToTimestamp(invite.channel.id); + }*/ const channelCreatedAtTimestamp = snowflakeToTimestamp( + invite.channel.id, + ); const channelCreatedAt = moment.utc(channelCreatedAtTimestamp, "x"); const channelAge = humanizeDuration(Date.now() - channelCreatedAtTimestamp, { largest: 2, diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 798ec63a..2b3ad188 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -6,6 +6,8 @@ import humanizeDuration from "humanize-duration"; import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils"; import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageEmbedOptions, Constants, TextChannel } from "discord.js"; +import { MessageTypeStrings } from "src/types"; const MESSAGE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740685652152025088/message.png"; @@ -14,8 +16,10 @@ export async function getMessageInfoEmbed( channelId: string, messageId: string, requestMemberId?: string, -): Promise { - const message = await pluginData.client.getMessage(channelId, messageId).catch(() => null); +): Promise { + const message = await (pluginData.guild.channels.resolve(channelId) as TextChannel).messages + .fetch(messageId) + .catch(() => null); if (!message) { return null; } @@ -36,12 +40,12 @@ export async function getMessageInfoEmbed( ? await timeAndDate.inMemberTz(requestMemberId, createdAt) : timeAndDate.inGuildTz(createdAt); const prettyCreatedAt = tzCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime")); - const messageAge = humanizeDuration(Date.now() - message.createdAt, { + const messageAge = humanizeDuration(Date.now() - message.createdTimestamp, { largest: 2, round: true, }); - const editedAt = message.editedTimestamp && moment.utc(message.editedTimestamp, "x"); + const editedAt = message.editedTimestamp ? moment.utc(message.editedTimestamp!, "x") : undefined; const tzEditedAt = requestMemberId ? await timeAndDate.inMemberTz(requestMemberId, editedAt) : timeAndDate.inGuildTz(editedAt); @@ -55,16 +59,16 @@ export async function getMessageInfoEmbed( const type = { - [Constants.MessageTypes.DEFAULT]: "Regular message", - [Constants.MessageTypes.CHANNEL_PINNED_MESSAGE]: "System message", - [Constants.MessageTypes.GUILD_MEMBER_JOIN]: "System message", - [Constants.MessageTypes.USER_PREMIUM_GUILD_SUBSCRIPTION]: "System message", - [Constants.MessageTypes.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1]: "System message", - [Constants.MessageTypes.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2]: "System message", - [Constants.MessageTypes.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3]: "System message", - [Constants.MessageTypes.CHANNEL_FOLLOW_ADD]: "System message", - [Constants.MessageTypes.GUILD_DISCOVERY_DISQUALIFIED]: "System message", - [Constants.MessageTypes.GUILD_DISCOVERY_REQUALIFIED]: "System message", + [MessageTypeStrings.DEFAULT]: "Regular message", + [MessageTypeStrings.PINS_ADD]: "System message", + [MessageTypeStrings.GUILD_MEMBER_JOIN]: "System message", + [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION]: "System message", + [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1]: "System message", + [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2]: "System message", + [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3]: "System message", + [MessageTypeStrings.CHANNEL_FOLLOW_ADD]: "System message", + [MessageTypeStrings.GUILD_DISCOVERY_DISQUALIFIED]: "System message", + [MessageTypeStrings.GUILD_DISCOVERY_REQUALIFIED]: "System message", }[message.type] || "Unknown"; embed.fields.push({ @@ -87,12 +91,12 @@ export async function getMessageInfoEmbed( ? await timeAndDate.inMemberTz(requestMemberId, authorCreatedAt) : timeAndDate.inGuildTz(authorCreatedAt); const prettyAuthorCreatedAt = tzAuthorCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime")); - const authorAccountAge = humanizeDuration(Date.now() - message.author.createdAt, { + const authorAccountAge = humanizeDuration(Date.now() - message.author.createdTimestamp, { largest: 2, round: true, }); - const authorJoinedAt = message.member && moment.utc(message.member.joinedAt, "x"); + const authorJoinedAt = message.member && moment.utc(message.member.joinedTimestamp!, "x"); const tzAuthorJoinedAt = authorJoinedAt ? requestMemberId ? await timeAndDate.inMemberTz(requestMemberId, authorJoinedAt) @@ -101,7 +105,7 @@ export async function getMessageInfoEmbed( const prettyAuthorJoinedAt = tzAuthorJoinedAt?.format(timeAndDate.getDateFormat("pretty_datetime")); const authorServerAge = message.member && - humanizeDuration(Date.now() - message.member.joinedAt, { + humanizeDuration(Date.now() - message.member.joinedTimestamp!, { largest: 2, round: true, }); @@ -126,7 +130,7 @@ export async function getMessageInfoEmbed( }); } - if (message.attachments.length) { + if (message.attachments.size) { embed.fields.push({ name: preEmbedPadding + "Attachments", value: message.attachments[0].url, diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts index e5dff015..6bf58c3e 100644 --- a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -4,6 +4,7 @@ import { trimLines, preEmbedPadding, EmbedWith } from "../../../utils"; import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { Role, MessageEmbedOptions } from "discord.js"; const MENTION_ICON = "https://cdn.discordapp.com/attachments/705009450855039042/839284872152481792/mention.png"; @@ -11,7 +12,7 @@ export async function getRoleInfoEmbed( pluginData: GuildPluginData, role: Role, requestMemberId?: string, -): Promise { +): Promise { const embed: EmbedWith<"fields"> = { fields: [], }; @@ -29,12 +30,12 @@ export async function getRoleInfoEmbed( ? await timeAndDate.inMemberTz(requestMemberId, createdAt) : timeAndDate.inGuildTz(createdAt); const prettyCreatedAt = tzCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime")); - const roleAge = humanizeDuration(Date.now() - role.createdAt, { + const roleAge = humanizeDuration(Date.now() - role.createdTimestamp, { largest: 2, round: true, }); - const rolePerms = Object.keys(role.permissions.json).map(p => + const rolePerms = Object.keys(role.permissions.toJSON()).map(p => p // Voice channel related permission names start with 'voice' .replace(/^voice/i, "") @@ -44,7 +45,7 @@ export async function getRoleInfoEmbed( ); // -1 because of the @everyone role - const totalGuildRoles = pluginData.guild.roles.size - 1; + const totalGuildRoles = pluginData.guild.roles.cache.size - 1; embed.fields.push({ name: preEmbedPadding + "Role information", diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index a49deea6..fdbd3d66 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -17,16 +17,17 @@ import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; import { getGuildPreview } from "./getGuildPreview"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageEmbedOptions, CategoryChannel, TextChannel, VoiceChannel } from "discord.js"; export async function getServerInfoEmbed( pluginData: GuildPluginData, serverId: string, requestMemberId?: string, -): Promise { +): Promise { const thisServer = serverId === pluginData.guild.id ? pluginData.guild : null; const [restGuild, guildPreview] = await Promise.all([ thisServer - ? memoize(() => pluginData.client.getRESTGuild(serverId), `getRESTGuild_${serverId}`, 10 * MINUTES) + ? memoize(() => pluginData.client.guilds.fetch(serverId), `getRESTGuild_${serverId}`, 10 * MINUTES) : null, getGuildPreview(pluginData.client, serverId), ]); @@ -46,12 +47,12 @@ export async function getServerInfoEmbed( embed.author = { name: `Server: ${(guildPreview || restGuild)!.name}`, - icon_url: (guildPreview || restGuild)!.iconURL ?? undefined, + iconURL: (guildPreview || restGuild)!.iconURL() ?? undefined, }; // BASIC INFORMATION const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - const createdAt = moment.utc((guildPreview || restGuild)!.createdAt, "x"); + const createdAt = moment.utc((guildPreview || restGuild)!.id, "x"); // FIXME ID -> Timestamp const tzCreatedAt = requestMemberId ? await timeAndDate.inMemberTz(requestMemberId, createdAt) : timeAndDate.inGuildTz(createdAt); @@ -86,7 +87,7 @@ export async function getServerInfoEmbed( const bannerUrl = restGuild?.bannerURL ? `[Link](${restGuild.bannerURL})` : "None"; const splashUrl = (restGuild || guildPreview)!.splashURL != null - ? `[Link](${(restGuild || guildPreview)!.splashURL?.replace("size=128", "size=2048")})` + ? `[Link](${(restGuild || guildPreview)!.splashURL()?.replace("size=128", "size=2048")})` : "None"; embed.fields.push( @@ -113,33 +114,33 @@ export async function getServerInfoEmbed( restGuild?.approximateMemberCount || restGuild?.memberCount || thisServer?.memberCount || - thisServer?.members.size || + thisServer?.members.cache.size || 0; let onlineMemberCount = (guildPreview?.approximatePresenceCount || restGuild?.approximatePresenceCount)!; - if (onlineMemberCount == null && restGuild?.vanityURL) { + if (onlineMemberCount == null && restGuild?.vanityURLCode) { // For servers with a vanity URL, we can also use the numbers from the invite for online count - const invite = await resolveInvite(pluginData.client, restGuild.vanityURL!, true); + const invite = await resolveInvite(pluginData.client, restGuild.vanityURLCode!, true); if (invite && inviteHasCounts(invite)) { onlineMemberCount = invite.presenceCount; } } if (!onlineMemberCount && thisServer) { - onlineMemberCount = thisServer.members.filter(m => m.status !== "offline").length; // Extremely inaccurate fallback + onlineMemberCount = thisServer.members.cache.filter(m => m.presence.status !== "offline").size; // Extremely inaccurate fallback } const offlineMemberCount = totalMembers - onlineMemberCount; let memberCountTotalLines = `Total: **${formatNumber(totalMembers)}**`; - if (restGuild?.maxMembers) { - memberCountTotalLines += `\nMax: **${formatNumber(restGuild.maxMembers)}**`; + if (restGuild?.maximumMembers) { + memberCountTotalLines += `\nMax: **${formatNumber(restGuild.maximumMembers)}**`; } let memberCountOnlineLines = `Online: **${formatNumber(onlineMemberCount)}**`; - if (restGuild?.maxPresences) { - memberCountOnlineLines += `\nMax online: **${formatNumber(restGuild.maxPresences)}**`; + if (restGuild?.maximumPresences) { + memberCountOnlineLines += `\nMax online: **${formatNumber(restGuild.maximumPresences)}**`; } embed.fields.push({ @@ -154,19 +155,19 @@ export async function getServerInfoEmbed( // CHANNEL COUNTS if (thisServer) { - const totalChannels = thisServer.channels.size; - const categories = thisServer.channels.filter(channel => channel instanceof CategoryChannel); - const textChannels = thisServer.channels.filter(channel => channel instanceof TextChannel); - const voiceChannels = thisServer.channels.filter(channel => channel instanceof VoiceChannel); + const totalChannels = thisServer.channels.cache.size; + const categories = thisServer.channels.cache.filter(channel => channel instanceof CategoryChannel); + const textChannels = thisServer.channels.cache.filter(channel => channel instanceof TextChannel); + const voiceChannels = thisServer.channels.cache.filter(channel => channel instanceof VoiceChannel); embed.fields.push({ name: preEmbedPadding + "Channels", inline: true, value: trimLines(` Total: **${totalChannels}** / 500 - Categories: **${categories.length}** - Text: **${textChannels.length}** - Voice: **${voiceChannels.length}** + Categories: **${categories.size}** + Text: **${textChannels.size}** + Voice: **${voiceChannels.size}** `), }); } @@ -175,7 +176,7 @@ export async function getServerInfoEmbed( const otherStats: string[] = []; if (thisServer) { - otherStats.push(`Roles: **${thisServer.roles.size}** / 250`); + otherStats.push(`Roles: **${thisServer.roles.cache.size}** / 250`); } if (restGuild) { @@ -186,9 +187,9 @@ export async function getServerInfoEmbed( 2: 150, 3: 250, }[restGuild.premiumTier] || 50; - otherStats.push(`Emojis: **${restGuild.emojis.length}** / ${maxEmojis * 2}`); + otherStats.push(`Emojis: **${restGuild.emojis.cache.size}** / ${maxEmojis * 2}`); } else { - otherStats.push(`Emojis: **${guildPreview!.emojis.length}**`); + otherStats.push(`Emojis: **${guildPreview!.emojis.size}**`); } if (thisServer) { diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index bd0e39fc..0cec52bd 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -14,6 +14,7 @@ import { CaseTypes } from "../../../data/CaseTypes"; import humanizeDuration from "humanize-duration"; import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageEmbedOptions } from "discord.js"; const SNOWFLAKE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/742020790471491668/snowflake.png"; @@ -22,7 +23,7 @@ export async function getSnowflakeInfoEmbed( snowflake: string, showUnknownWarning = false, requestMemberId?: string, -): Promise { +): Promise { const embed: EmbedWith<"fields"> = { fields: [], }; diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index d6c2a0be..09c2fc59 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -15,13 +15,14 @@ import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; import humanizeDuration from "humanize-duration"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { MessageEmbedOptions, Role } from "discord.js"; export async function getUserInfoEmbed( pluginData: GuildPluginData, userId: string, compact = false, requestMemberId?: string, -): Promise { +): Promise { const user = await resolveUser(pluginData.client, userId); if (!user || user instanceof UnknownUser) { return null; @@ -39,7 +40,7 @@ export async function getUserInfoEmbed( name: `User: ${user.username}#${user.discriminator}`, }; - const avatarURL = user.avatarURL || user.defaultAvatarURL; + const avatarURL = user.avatarURL() || user.defaultAvatarURL; embed.author.icon_url = avatarURL; const createdAt = moment.utc(user.createdAt, "x"); @@ -47,7 +48,7 @@ export async function getUserInfoEmbed( ? await timeAndDate.inMemberTz(requestMemberId, createdAt) : timeAndDate.inGuildTz(createdAt); const prettyCreatedAt = tzCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime")); - const accountAge = humanizeDuration(moment.utc().valueOf() - user.createdAt, { + const accountAge = humanizeDuration(moment.utc().valueOf() - user.createdTimestamp, { largest: 2, round: true, }); @@ -61,12 +62,12 @@ export async function getUserInfoEmbed( `), }); if (member) { - const joinedAt = moment.utc(member.joinedAt, "x"); + const joinedAt = moment.utc(member.joinedTimestamp!, "x"); const tzJoinedAt = requestMemberId ? await timeAndDate.inMemberTz(requestMemberId, joinedAt) : timeAndDate.inGuildTz(joinedAt); const prettyJoinedAt = tzJoinedAt.format(timeAndDate.getDateFormat("pretty_datetime")); - const joinAge = humanizeDuration(moment.utc().valueOf() - member.joinedAt, { + const joinAge = humanizeDuration(moment.utc().valueOf() - member.joinedTimestamp!, { largest: 2, round: true, }); @@ -92,16 +93,18 @@ export async function getUserInfoEmbed( }); if (member) { - const joinedAt = moment.utc(member.joinedAt, "x"); + const joinedAt = moment.utc(member.joinedTimestamp!, "x"); const tzJoinedAt = requestMemberId ? await timeAndDate.inMemberTz(requestMemberId, joinedAt) : timeAndDate.inGuildTz(joinedAt); const prettyJoinedAt = tzJoinedAt.format(timeAndDate.getDateFormat("pretty_datetime")); - const joinAge = humanizeDuration(moment.utc().valueOf() - member.joinedAt, { + const joinAge = humanizeDuration(moment.utc().valueOf() - member.joinedTimestamp!, { largest: 2, round: true, }); - const roles = member.roles.map(id => pluginData.guild.roles.cache.get(id)).filter(r => r != null) as Role[]; + const roles = member.roles.cache + .map(role => pluginData.guild.roles.cache.get(role.id)) + .filter(r => r != null) as Role[]; roles.sort(sorter("position", "DESC")); embed.fields.push({ @@ -112,16 +115,14 @@ export async function getUserInfoEmbed( `), }); - const voiceChannel = member.voiceState.channelID - ? pluginData.guild.channels.cache.get(member.voiceState.channelID) - : null; - if (voiceChannel || member.voiceState.mute || member.voiceState.deaf) { + const voiceChannel = member.voice.channelID ? pluginData.guild.channels.cache.get(member.voice.channelID) : null; + if (voiceChannel || member.voice.mute || member.voice.deaf) { embed.fields.push({ name: preEmbedPadding + "Voice information", value: trimLines(` ${voiceChannel ? `Current voice channel: **${voiceChannel ? voiceChannel.name : "None"}**` : ""} - ${member.voiceState.mute ? "Server voice muted: **Yes**" : ""} - ${member.voiceState.deaf ? "Server voice deafened: **Yes**" : ""} + ${member.voice.mute ? "Server voice muted: **Yes**" : ""} + ${member.voice.deaf ? "Server voice deafened: **Yes**" : ""} `), }); } diff --git a/backend/src/plugins/Utility/guildReloads.ts b/backend/src/plugins/Utility/guildReloads.ts index a44b514d..b5cb292b 100644 --- a/backend/src/plugins/Utility/guildReloads.ts +++ b/backend/src/plugins/Utility/guildReloads.ts @@ -1 +1,3 @@ +import { TextChannel } from "discord.js"; + export const activeReloads: Map = new Map(); diff --git a/backend/src/plugins/Utility/refreshMembers.ts b/backend/src/plugins/Utility/refreshMembers.ts index a0ffc09f..aa4920d6 100644 --- a/backend/src/plugins/Utility/refreshMembers.ts +++ b/backend/src/plugins/Utility/refreshMembers.ts @@ -1,3 +1,4 @@ +import { Guild } from "discord.js"; import { HOURS, noop } from "../../utils"; const MEMBER_REFRESH_FREQUENCY = 1 * HOURS; // How often to do a full member refresh when using commands that need it @@ -9,7 +10,7 @@ export async function refreshMembersIfNeeded(guild: Guild) { return lastRefresh.promise; } - const loadPromise = guild.fetchAllMembers().then(noop); + const loadPromise = guild.members.fetch().then(noop); memberRefreshLog.set(guild.id, { time: Date.now(), promise: loadPromise, diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 4900d0ce..75c8dbce 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -14,6 +14,7 @@ import { inputPatternToRegExp, InvalidRegexError } from "../../validatorUtils"; import { asyncFilter } from "../../utils/async"; import Timeout = NodeJS.Timeout; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; +import { Message, User, Constants, TextChannel, GuildMember, Permissions } from "discord.js"; const SEARCH_RESULTS_PER_PAGE = 15; const SEARCH_ID_RESULTS_PER_PAGE = 50; @@ -90,7 +91,7 @@ export async function displaySearch( if (originalSearchMsg) { searchMsgPromise = originalSearchMsg.edit("Searching..."); } else { - searchMsgPromise = msg.channel.createMessage("Searching..."); + searchMsgPromise = msg.channel.send("Searching..."); searchMsgPromise.then(m => (originalSearchMsg = m)); } @@ -106,12 +107,12 @@ export async function displaySearch( } } catch (e) { if (e instanceof SearchError) { - sendErrorMessage(pluginData, msg.channel, e.message); + sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); return; } if (e instanceof InvalidRegexError) { - sendErrorMessage(pluginData, msg.channel, e.message); + sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); return; } @@ -119,7 +120,7 @@ export async function displaySearch( } if (searchResult.totalResults === 0) { - sendErrorMessage(pluginData, msg.channel, "No results found"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "No results found"); return; } @@ -149,7 +150,7 @@ export async function displaySearch( const embed = await getUserInfoEmbed(pluginData, searchResult.results[0].id, false); if (embed) { searchMsg.edit("Only one result:"); - msg.channel.createMessage({ embed }); + msg.channel.send({ embed }); return; } } @@ -160,30 +161,32 @@ export async function displaySearch( if (searchResult.totalResults > perPage) { if (!hasReactions) { hasReactions = true; - searchMsg.addReaction("⬅"); - searchMsg.addReaction("➡"); - searchMsg.addReaction("🔄"); + searchMsg.react("⬅"); + searchMsg.react("➡"); + searchMsg.react("🔄"); - const listenerFn = pluginData.events.on("messageReactionAdd", ({ args: { message: rMsg, emoji, member } }) => { + const listenerFn = pluginData.events.on("messageReactionAdd", async ({ args: { reaction, user } }) => { + const rMsg = reaction.message; + const member = await pluginData.guild.members.fetch(user.id); if (rMsg.id !== searchMsg.id) return; - if (member.id !== msg.author.id) return; - if (!["⬅", "➡", "🔄"].includes(emoji.name)) return; + if (member.user.id !== msg.author.id) return; + if (!["⬅", "➡", "🔄"].includes(reaction.emoji.name!)) return; - if (emoji.name === "⬅" && currentPage > 1) { + if (reaction.emoji.name === "⬅" && currentPage > 1) { loadSearchPage(currentPage - 1); - } else if (emoji.name === "➡" && currentPage < searchResult.lastPage) { + } else if (reaction.emoji.name === "➡" && currentPage < searchResult.lastPage) { loadSearchPage(currentPage + 1); - } else if (emoji.name === "🔄") { + } else if (reaction.emoji.name === "🔄") { loadSearchPage(currentPage); } if (isFullMessage(rMsg)) { - rMsg.removeReaction(emoji.name, member.id); + reaction.remove(); } }); clearReactionsFn = async () => { - searchMsg.removeReactions().catch(noop); + searchMsg.reactions.removeAll().catch(noop); pluginData.events.off("messageReactionAdd", listenerFn); }; } @@ -229,12 +232,12 @@ export async function archiveSearch( } } catch (e) { if (e instanceof SearchError) { - sendErrorMessage(pluginData, msg.channel, e.message); + sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); return; } if (e instanceof InvalidRegexError) { - sendErrorMessage(pluginData, msg.channel, e.message); + sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); return; } @@ -242,7 +245,7 @@ export async function archiveSearch( } if (results.totalResults === 0) { - sendErrorMessage(pluginData, msg.channel, "No results found"); + sendErrorMessage(pluginData, msg.channel as TextChannel, "No results found"); return; } @@ -260,7 +263,7 @@ export async function archiveSearch( const baseUrl = getBaseUrl(pluginData); const url = await pluginData.state.archives.getUrl(baseUrl, archiveId); - await msg.channel.createMessage(`Exported search results: ${url}`); + await msg.channel.send(`Exported search results: ${url}`); } async function performMemberSearch( @@ -268,16 +271,16 @@ async function performMemberSearch( args: MemberSearchParams, page = 1, perPage = SEARCH_RESULTS_PER_PAGE, -): Promise<{ results: Member[]; totalResults: number; page: number; lastPage: number; from: number; to: number }> { +): Promise<{ results: GuildMember[]; totalResults: number; page: number; lastPage: number; from: number; to: number }> { await refreshMembersIfNeeded(pluginData.guild); - let matchingMembers = Array.from(pluginData.guild.members.values()); + let matchingMembers = Array.from(pluginData.guild.members.cache.values()); if (args.role) { const roleIds = args.role.split(","); matchingMembers = matchingMembers.filter(member => { for (const role of roleIds) { - if (!member.roles.includes(role)) return false; + if (!member.roles.cache.has(role)) return false; } return true; @@ -285,11 +288,11 @@ async function performMemberSearch( } if (args.voice) { - matchingMembers = matchingMembers.filter(m => m.voiceState.channelID != null); + matchingMembers = matchingMembers.filter(m => m.voice.channelID != null); } if (args.bot) { - matchingMembers = matchingMembers.filter(m => m.bot); + matchingMembers = matchingMembers.filter(m => m.user.bot); } if (args.query) { @@ -306,6 +309,7 @@ async function performMemberSearch( const execRegExp = getOptimizedRegExpRunner(pluginData, isSafeRegex); + /** FIXME if we ever get the intent for this again if (args["status-search"]) { matchingMembers = await asyncFilter(matchingMembers, async member => { if (member.game) { @@ -344,17 +348,18 @@ async function performMemberSearch( return false; }); } else { - matchingMembers = await asyncFilter(matchingMembers, async member => { - if (member.nick && (await execRegExp(queryRegex, member.nick).catch(allowTimeout))) { - return true; - } + */ + matchingMembers = await asyncFilter(matchingMembers, async member => { + if (member.nickname && (await execRegExp(queryRegex, member.nickname).catch(allowTimeout))) { + return true; + } - const fullUsername = `${member.user.username}#${member.user.discriminator}`; - if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; + const fullUsername = `${member.user.username}#${member.user.discriminator}`; + if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; - return false; - }); - } + return false; + }); + // } FIXME in conjunction with above comment } const [, sortDir, sortBy] = (args.sort && args.sort.match(/^(-?)(.*)$/)) ?? [null, "ASC", "name"]; @@ -396,11 +401,11 @@ async function performBanSearch( perPage = SEARCH_RESULTS_PER_PAGE, ): Promise<{ results: User[]; totalResults: number; page: number; lastPage: number; from: number; to: number }> { const member = pluginData.guild.members.cache.get(pluginData.client.user!.id); - if (member && !hasDiscordPermissions(member.permissions, Constants.Permissions.banMembers)) { + if (member && !hasDiscordPermissions(member.permissions, Permissions.FLAGS.BAN_MEMBERS)) { throw new SearchError(`Unable to search bans: missing "Ban Members" permission`); } - let matchingBans = (await pluginData.guild.getBans()).map(x => x.user); + let matchingBans = (await pluginData.guild.bans.fetch({ cache: false })).map(x => x.user); if (args.query) { let isSafeRegex = true; @@ -454,14 +459,14 @@ async function performBanSearch( }; } -function formatSearchResultList(members: Array): string { +function formatSearchResultList(members: Array): string { const longestId = members.reduce((longest, member) => Math.max(longest, member.id.length), 0); const lines = members.map(member => { const paddedId = member.id.padEnd(longestId, " "); let line; - if (member instanceof Member) { + if (member instanceof GuildMember) { line = `${paddedId} ${member.user.username}#${member.user.discriminator}`; - if (member.nick) line += ` (${member.nick})`; + if (member.nickname) line += ` (${member.nickname})`; } else { line = `${paddedId} ${member.username}#${member.discriminator}`; } @@ -470,6 +475,6 @@ function formatSearchResultList(members: Array): string { return lines.join("\n"); } -function formatSearchResultIdList(members: Array): string { +function formatSearchResultIdList(members: Array): string { return members.map(m => m.id).join(" "); } diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index 7317aaac..50d54b94 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -4,6 +4,7 @@ import { createChunkedMessage, stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { sendDM } from "../../../utils/sendDM"; +import { TextChannel } from "discord.js"; export const SendWelcomeMessageEvt = welcomeMessageEvt({ event: "guildMemberAdd", @@ -55,7 +56,7 @@ export const SendWelcomeMessageEvt = welcomeMessageEvt({ } if (config.send_to_channel) { - const channel = meta.args.guild.channels.cache.get(config.send_to_channel); + const channel = meta.args.member.guild.channels.cache.get(config.send_to_channel); if (!channel || !(channel instanceof TextChannel)) return; try { diff --git a/backend/src/types.ts b/backend/src/types.ts index 6378ad27..add1d061 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -75,3 +75,25 @@ export enum ChannelTypeStrings { STAGE = "stage", UNKNOWN = "unknown", } + +export enum MessageTypeStrings { + "DEFAULT", + "RECIPIENT_ADD", + "RECIPIENT_REMOVE", + "CALL", + "CHANNEL_NAME_CHANGE", + "CHANNEL_ICON_CHANGE", + "PINS_ADD", + "GUILD_MEMBER_JOIN", + "USER_PREMIUM_GUILD_SUBSCRIPTION", + "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1", + "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2", + "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3", + "CHANNEL_FOLLOW_ADD", + "GUILD_DISCOVERY_DISQUALIFIED", + "GUILD_DISCOVERY_REQUALIFIED", + "GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING", + "GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING", + "REPLY", + "APPLICATION_COMMAND", +} diff --git a/backend/src/utils.test.ts b/backend/src/utils.test.ts index 9d72ce0f..ba1da55e 100644 --- a/backend/src/utils.test.ts +++ b/backend/src/utils.test.ts @@ -2,7 +2,7 @@ import * as ioTs from "io-ts"; import { convertDelayStringToMS, convertMSToDelayString, getUrlsInString, tAllowedMentions } from "./utils"; import test from "ava"; -import { AllowedMentions as ErisAllowedMentions } from "eris"; +import { erisAllowedMentionFormat } from "./utils/erisAllowedMentionsToDjsMentionOptions"; type AssertEquals = TActual extends TExpected ? true : false; @@ -52,6 +52,6 @@ test("delay strings: reverse conversion (conservative)", t => { test("tAllowedMentions matches Eris's AllowedMentions", t => { type TAllowedMentions = ioTs.TypeOf; - const typeTest: AssertEquals = true; + const typeTest: AssertEquals = true; t.pass(); }); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 549ebdd1..cfd33bf3 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -34,6 +34,8 @@ import { MessageEmbedOptions, MessageMentionOptions, MessageOptions, + PartialChannelData, + PartialMessage, StringResolvable, TextChannel, User, @@ -200,9 +202,9 @@ export function nonNullish(v: V): v is NonNullable { } export type InviteOpts = "withMetadata" | "withCount" | "withoutCount"; -export type GuildInvite = Invite & { guild: Guild }; -export type GroupDMInvite = Invite & { - channel: InvitePartialChannel; +export type GuildInvite = Invite & { guild: Guild }; +export type GroupDMInvite = Invite & { + channel: PartialChannelData; type: typeof Constants.ChannelTypes.GROUP; }; @@ -486,7 +488,7 @@ export async function findRelevantAuditLogEntry( } } - const entries = auditLogs ? auditLogs.entries : []; + const entries = auditLogs ? auditLogs.entries.array() : []; entries.sort((a, b) => { if (a.createdAt > b.createdAt) return -1; @@ -497,7 +499,7 @@ export async function findRelevantAuditLogEntry( const cutoffTS = Date.now() - 1000 * 60 * 2; const relevantEntry = entries.find(entry => { - return entry.targetID === userId && entry.createdAt >= cutoffTS; + return (entry.target as { id }).id === userId && entry.createdTimestamp >= cutoffTS; }); if (relevantEntry) { @@ -1119,7 +1121,7 @@ export function resolveUserId(bot: Client, value: string) { // A non-mention, full username? const usernameMatch = value.match(/^@?([^#]+)#(\d{4})$/); if (usernameMatch) { - const user = bot.users.find(u => u.username === usernameMatch[1] && u.discriminator === usernameMatch[2]); + const user = bot.users.cache.find(u => u.username === usernameMatch[1] && u.discriminator === usernameMatch[2]); if (user) return user.id; } @@ -1250,9 +1252,7 @@ export async function resolveRoleId(bot: Client, guildId: string, value: string) const inviteCache = new SimpleCache>(10 * MINUTES, 200); -type ResolveInviteReturnType = Promise< - (T extends true ? Invite<"withCount" | "withMetadata"> : Invite<"withMetadata">) | null ->; +type ResolveInviteReturnType = Promise; export async function resolveInvite( client: Client, code: string, @@ -1278,7 +1278,7 @@ export async function confirm( content: StringResolvable | MessageOptions, ) { const msg = await channel.send(content); - const reply = await helpers.waitForReaction(bot, msg, ["✅", "❌"], userId); + const reply: any = {}; // await helpers.waitForReaction(bot, msg, ["✅", "❌"], userId); FIXME waiting on waitForButton msg.delete().catch(noop); return reply && reply.name === "✅"; } @@ -1436,19 +1436,19 @@ export function trimMultilineString(str) { } export const trimPluginDescription = trimMultilineString; -export function isFullMessage(msg: PossiblyUncachedMessage): msg is Message { +export function isFullMessage(msg: Message | PartialMessage): msg is Message { return (msg as Message).createdAt != null; } -export function isGuildInvite(invite: Invite): invite is GuildInvite { +export function isGuildInvite(invite: Invite): invite is GuildInvite { return invite.guild != null; } -export function isGroupDMInvite(invite: Invite): invite is GroupDMInvite { +export function isGroupDMInvite(invite: Invite): invite is GroupDMInvite { return invite.guild == null && invite.channel?.type === "group"; } -export function inviteHasCounts(invite: Invite): invite is Invite<"withCount"> { +export function inviteHasCounts(invite: Invite): invite is Invite { return invite.memberCount != null; } diff --git a/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts index 776871d4..c12cec79 100644 --- a/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts +++ b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts @@ -36,8 +36,8 @@ export function erisAllowedMentionsToDjsMentionOptions( } export interface erisAllowedMentionFormat { - everyone: boolean | undefined; - users: boolean | string[] | undefined; - roles: boolean | string[] | undefined; - repliedUser: boolean | undefined; + everyone?: boolean | undefined; + users?: boolean | string[] | undefined; + roles?: boolean | string[] | undefined; + repliedUser?: boolean | undefined; } From edcfd2333f21d27ae6cb4ba72c8bed834ddca677 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 2 Jun 2021 19:35:44 +0200 Subject: [PATCH 06/79] Bot now connects, lint fixes --- backend/src/data/GuildSavedMessages.ts | 5 +++-- backend/src/index.ts | 4 +++- backend/src/plugins/Automod/actions/setSlowmode.ts | 5 +++-- .../plugins/Cases/functions/postToCaseLogChannel.ts | 2 +- backend/src/plugins/Censor/util/censorMessage.ts | 4 ++-- .../src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts | 2 +- backend/src/plugins/ModActions/commands/UnmuteCmd.ts | 2 +- backend/src/plugins/ModActions/commands/WarnCmd.ts | 2 +- backend/src/plugins/ModActions/functions/warnMember.ts | 2 +- backend/src/plugins/Persist/events/LoadDataEvt.ts | 2 +- backend/src/plugins/Utility/commands/AboutCmd.ts | 2 +- backend/src/plugins/Utility/search.ts | 2 +- backend/src/utils.test.ts | 4 ++-- backend/src/utils.ts | 2 +- .../utils/erisAllowedMentionsToDjsMentionOptions.ts | 10 +++++----- backend/src/validatorUtils.ts | 3 ++- 16 files changed, 29 insertions(+), 24 deletions(-) diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index b5759fde..423767ae 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -211,8 +211,9 @@ export class GuildSavedMessages extends BaseGuildRepository { const newMessage = { ...oldMessage, data: newData }; - //@ts-ignore - await this.messages.update( // FIXME? + // @ts-ignore + await this.messages.update( + // FIXME? { id }, { data: newData, diff --git a/backend/src/index.ts b/backend/src/index.ts index ad40ab22..fe3a07da 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -267,6 +267,8 @@ connect().then(async () => { startUptimeCounter(); }); - logger.info("Starting the bot"); + logger.info("Logging in..."); + await client.login(process.env.token); + logger.info("Initializing the bot"); bot.initialize(); }); diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index a2bacc38..7acfdd28 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -26,12 +26,13 @@ export const SetSlowmodeAction = automodAction({ continue; } - let channelsToSlowmode: TextChannel[] = []; + const channelsToSlowmode: TextChannel[] = []; if (channel.type === ChannelTypeStrings.CATEGORY) { // Find all text channels within the category for (const ch of pluginData.guild.channels.cache.values()) { - if (ch.parentID === channel.id && ch.type === ChannelTypeStrings.TEXT) + if (ch.parentID === channel.id && ch.type === ChannelTypeStrings.TEXT) { channelsToSlowmode.push(ch as TextChannel); + } } } else { channelsToSlowmode.push(channel as TextChannel); diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index 6d80698f..feacede1 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -21,7 +21,7 @@ export async function postToCaseLogChannel( let result; try { - if (file != undefined) { + if (file != null) { content.files = file; } result = await caseLogChannel.send({ ...content, split: false }); diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index ad4c32ba..69ed2859 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -14,8 +14,8 @@ export async function censorMessage( pluginData.state.serverLogs.ignoreLog(LogType.MESSAGE_DELETE, savedMessage.id); try { - const channel = pluginData.guild.channels.resolve(savedMessage.channel_id) as TextChannel; - await channel.messages.delete(savedMessage.id); + const resolvedChannel = pluginData.guild.channels.resolve(savedMessage.channel_id) as TextChannel; + await resolvedChannel.messages.delete(savedMessage.id); } catch { return; } diff --git a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts index e2d51c6f..45858330 100644 --- a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts +++ b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts @@ -29,7 +29,7 @@ function updateGuildInfo(pluginData: GuildPluginData) pluginData.state.allowedGuilds.updateInfo( pluginData.guild.id, pluginData.guild.name, - pluginData.guild.iconURL, + pluginData.guild.iconURL(), pluginData.guild.ownerID, ); } diff --git a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts index 53cc6728..0c3d09ac 100644 --- a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts @@ -61,7 +61,7 @@ export const UnmuteCmd = modActionsCmd({ } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server const notOnServerMsg = await msg.channel.send("User not found on the server, forceunmute instead?"); - const reply = false; //await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton + const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton notOnServerMsg.delete().catch(noop); if (!reply /*|| reply.name === "❌"*/) { diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index 9f347c97..b50caa35 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -73,7 +73,7 @@ export const WarnCmd = modActionsCmd({ config.warn_notify_message.replace("{priorWarnings}", `${priorWarnAmount}`), ); - const reply = false; //await waitForReaction(pluginData.client, tooManyWarningsMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton + const reply = false; // await waitForReaction(pluginData.client, tooManyWarningsMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton tooManyWarningsMsg.delete(); if (!reply /*|| reply.name === "❌"*/) { msg.channel.send(errorMessage("Warn cancelled by moderator")); diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index 1ffcf0d7..cf4e8eee 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -46,7 +46,7 @@ export async function warnMember( const failedMsg = await warnOptions.retryPromptChannel.send( "Failed to message the user. Log the warning anyway?", ); - const reply = false; //await waitForReaction(pluginData.client, failedMsg, ["✅", "❌"]); FIXME waiting on waitForButton + const reply = false; // await waitForReaction(pluginData.client, failedMsg, ["✅", "❌"]); FIXME waiting on waitForButton failedMsg.delete(); if (!reply /*|| reply.name === "❌"*/) { return { diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 96c63027..091c8fac 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -27,7 +27,7 @@ export const LoadDataEvt = persistEvt({ return; } - let toRestore: GuildMemberEditData = {}; + const toRestore: GuildMemberEditData = {}; const config = await pluginData.config.getForMember(member); const restoredData: string[] = []; diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index ad1d2bbf..1b60fa3c 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -41,7 +41,7 @@ export const AboutCmd = utilityCmd({ version = "?"; } - //const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; FIXME Sharding stuff + // const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; FIXME Sharding stuff const lastReload = humanizeDuration(Date.now() - pluginData.state.lastReload, { largest: 2, diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 75c8dbce..a42bd150 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -309,7 +309,7 @@ async function performMemberSearch( const execRegExp = getOptimizedRegExpRunner(pluginData, isSafeRegex); - /** FIXME if we ever get the intent for this again + /* FIXME if we ever get the intent for this again if (args["status-search"]) { matchingMembers = await asyncFilter(matchingMembers, async member => { if (member.game) { diff --git a/backend/src/utils.test.ts b/backend/src/utils.test.ts index ba1da55e..08baba41 100644 --- a/backend/src/utils.test.ts +++ b/backend/src/utils.test.ts @@ -2,7 +2,7 @@ import * as ioTs from "io-ts"; import { convertDelayStringToMS, convertMSToDelayString, getUrlsInString, tAllowedMentions } from "./utils"; import test from "ava"; -import { erisAllowedMentionFormat } from "./utils/erisAllowedMentionsToDjsMentionOptions"; +import { ErisAllowedMentionFormat } from "./utils/erisAllowedMentionsToDjsMentionOptions"; type AssertEquals = TActual extends TExpected ? true : false; @@ -52,6 +52,6 @@ test("delay strings: reverse conversion (conservative)", t => { test("tAllowedMentions matches Eris's AllowedMentions", t => { type TAllowedMentions = ioTs.TypeOf; - const typeTest: AssertEquals = true; + const typeTest: AssertEquals = true; t.pass(); }); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index cfd33bf3..91dab927 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1159,7 +1159,7 @@ export async function resolveUser(bot, value) { } // If we have the user cached, return that directly - if (bot.users.has(userId)) { + if (bot.users.cache.has(userId)) { return bot.users.get(userId); } diff --git a/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts index c12cec79..324ea826 100644 --- a/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts +++ b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts @@ -1,13 +1,13 @@ import { MessageMentionOptions, MessageMentionTypes } from "discord.js"; export function erisAllowedMentionsToDjsMentionOptions( - allowedMentions: erisAllowedMentionFormat | undefined, + allowedMentions: ErisAllowedMentionFormat | undefined, ): MessageMentionOptions | undefined { if (allowedMentions === undefined) return undefined; - let parse: MessageMentionTypes[] = []; - let users: string[] | undefined = undefined; - let roles: string[] | undefined = undefined; + const parse: MessageMentionTypes[] = []; + let users: string[] | undefined; + let roles: string[] | undefined; if (Array.isArray(allowedMentions.users)) { users = allowedMentions.users; @@ -35,7 +35,7 @@ export function erisAllowedMentionsToDjsMentionOptions( return mentions; } -export interface erisAllowedMentionFormat { +export interface ErisAllowedMentionFormat { everyone?: boolean | undefined; users?: boolean | string[] | undefined; roles?: boolean | string[] | undefined; diff --git a/backend/src/validatorUtils.ts b/backend/src/validatorUtils.ts index afc1297f..fad5ba94 100644 --- a/backend/src/validatorUtils.ts +++ b/backend/src/validatorUtils.ts @@ -123,7 +123,7 @@ export function decodeAndValidateStrict( err => report(validationResult), result => { // Make sure there are no extra properties - if (debug) + if (debug) { console.log( "JSON.stringify() check:", JSON.stringify(value) === JSON.stringify(result) @@ -131,6 +131,7 @@ export function decodeAndValidateStrict( : "they are not the same, might have excess", result, ); + } if (JSON.stringify(value) !== JSON.stringify(result)) { const diff = deepDiff(result, value); const errors = diff.filter(d => d.kind === "N").map(d => `Unknown property <${d.path.join(".")}>`); From d0c6e6f411d33cb7909972d172e5e7d4aa50f127 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 2 Jun 2021 23:41:05 +0200 Subject: [PATCH 07/79] More fixes, waitForInteraction (replacement for waitForReaction) --- backend/src/pluginUtils.ts | 8 ++- .../commands/ArchiveChannelCmd.ts | 1 - .../commands/ResetAllCounterValuesCmd.ts | 1 - backend/src/plugins/Logs/util/log.ts | 2 +- .../src/plugins/ModActions/commands/BanCmd.ts | 23 +++--- .../plugins/ModActions/commands/MuteCmd.ts | 11 +-- .../plugins/ModActions/commands/UnmuteCmd.ts | 11 +-- .../plugins/ModActions/commands/WarnCmd.ts | 14 ++-- .../plugins/ModActions/functions/isBanned.ts | 5 +- .../ModActions/functions/warnMember.ts | 16 +++-- .../applyReactionRoleReactionsToMessage.ts | 4 +- backend/src/utils.ts | 17 +++-- backend/src/utils/waitForInteraction.ts | 72 +++++++++++++++++++ 13 files changed, 135 insertions(+), 50 deletions(-) create mode 100644 backend/src/utils/waitForInteraction.ts diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 23b21d0f..f0912677 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -183,7 +183,7 @@ export function getPluginConfigPreprocessor( }; } -export function sendSuccessMessage( +export async function sendSuccessMessage( pluginData: AnyPluginData, channel: TextChannel, body: string, @@ -194,8 +194,9 @@ export function sendSuccessMessage( const content: MessageOptions = allowedMentions ? { content: formattedBody, allowedMentions } : { content: formattedBody }; + return channel - .send({ content }) // Force line break + .send({ ...content, split: false }) // Force line break .catch(err => { const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : `${channel.id}`; logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); @@ -203,7 +204,7 @@ export function sendSuccessMessage( }); } -export function sendErrorMessage( +export async function sendErrorMessage( pluginData: AnyPluginData, channel: TextChannel, body: string, @@ -214,6 +215,7 @@ export function sendErrorMessage( const content: MessageOptions = allowedMentions ? { content: formattedBody, allowedMentions } : { content: formattedBody }; + return channel .send({ ...content, split: false }) // Force line break .catch(err => { diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index faa67c18..87b61934 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -32,7 +32,6 @@ export const ArchiveChannelCmd = channelArchiverCmd({ async run({ message: msg, args, pluginData }) { if (!args["attachment-channel"]) { const confirmed = await confirm( - pluginData.client, msg.channel, msg.author.id, "No `-attachment-channel` specified. Continue? Attachments will not be available in the log if their message is deleted.", diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 6b632f95..2b16f10b 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -31,7 +31,6 @@ export const ResetAllCounterValuesCmd = typedGuildCommand()( const counterName = counter.name || args.counterName; const confirmed = await confirm( - pluginData.client, message.channel, message.author.id, trimMultilineString(` diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index ea65690d..0bb8c616 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -137,7 +137,7 @@ export async function log(pluginData: GuildPluginData, type: Log const batched = opts.batched ?? true; const batchTime = opts.batch_time ?? 1000; const cfg = pluginData.config.get(); - const parse: MessageMentionTypes[] | undefined = cfg.allow_user_mentions ? ["users"] : undefined; + const parse: MessageMentionTypes[] = cfg.allow_user_mentions ? ["users"] : []; if (batched) { // If we're batching log messages, gather all log messages within the set batch_time into a single message diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index f8cb4ff9..1d113168 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -12,6 +12,7 @@ import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { banLock } from "../../../utils/lockNameHelpers"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; const opts = { mod: ct.member({ option: true }), @@ -76,11 +77,12 @@ export const BanCmd = modActionsCmd({ } // Ask the mod if we should update the existing ban - const alreadyBannedMsg = await msg.channel.send("User is already banned, update ban?"); - const reply = false; // await waitForReaction(pluginData.client, alreadyBannedMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton - - alreadyBannedMsg.delete().catch(noop); - if (!reply /* || reply.name === "❌"*/) { + const reply = await waitForButtonConfirm( + msg.channel, + { content: "Failed to message the user. Log the warning anyway?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, + ); + if (!reply) { sendErrorMessage(pluginData, msg.channel, "User already banned, update cancelled by moderator"); lock.unlock(); return; @@ -124,11 +126,12 @@ export const BanCmd = modActionsCmd({ } } else { // Ask the mod if we should upgrade to a forceban as the user is not on the server - const notOnServerMsg = await msg.channel.send("User not found on the server, forceban instead?"); - const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); Waiting for waitForButton - - notOnServerMsg.delete().catch(noop); - if (!reply /*|| reply.name === "❌"*/) { + const reply = await waitForButtonConfirm( + msg.channel, + { content: "User not on server, forceban instead?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, + ); + if (!reply) { sendErrorMessage(pluginData, msg.channel, "User not on server, ban cancelled by moderator"); lock.unlock(); return; diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/MuteCmd.ts index 67f5ce71..4229bd6f 100644 --- a/backend/src/plugins/ModActions/commands/MuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MuteCmd.ts @@ -5,6 +5,7 @@ import { noop, resolveMember, resolveUser } from "../../../utils"; import { isBanned } from "../functions/isBanned"; import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; const opts = { mod: ct.member({ option: true }), @@ -54,11 +55,13 @@ export const MuteCmd = modActionsCmd({ return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server - const notOnServerMsg = await msg.channel.send("User not found on the server, forcemute instead?"); - const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton + const reply = await waitForButtonConfirm( + msg.channel, + { content: "User not found on the server, forcemute instead?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, + ); - notOnServerMsg.delete().catch(noop); - if (!reply /*|| reply.name === "❌"*/) { + if (!reply) { sendErrorMessage(pluginData, msg.channel, "User not on server, mute cancelled by moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts index 0c3d09ac..dae00bea 100644 --- a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts @@ -5,6 +5,7 @@ import { resolveUser, resolveMember, noop } from "../../../utils"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; import { isBanned } from "../functions/isBanned"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; const opts = { mod: ct.member({ option: true }), @@ -60,11 +61,13 @@ export const UnmuteCmd = modActionsCmd({ return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server - const notOnServerMsg = await msg.channel.send("User not found on the server, forceunmute instead?"); - const reply = false; // await waitForReaction(pluginData.client, notOnServerMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton + const reply = await waitForButtonConfirm( + msg.channel, + { content: "User not on server, forceunmute instead?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, + ); - notOnServerMsg.delete().catch(noop); - if (!reply /*|| reply.name === "❌"*/) { + if (!reply) { sendErrorMessage(pluginData, msg.channel, "User not on server, unmute cancelled by moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index b50caa35..37f8d814 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -6,11 +6,12 @@ import { formatReasonWithAttachments } from "../functions/formatReasonWithAttach import { CasesPlugin } from "../../Cases/CasesPlugin"; import { LogType } from "../../../data/LogType"; import { CaseTypes } from "../../../data/CaseTypes"; -import { errorMessage, resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { errorMessage, resolveMember, resolveUser } from "../../../utils"; import { isBanned } from "../functions/isBanned"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; import { warnMember } from "../functions/warnMember"; import { TextChannel } from "discord.js"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; export const WarnCmd = modActionsCmd({ trigger: "warn", @@ -69,13 +70,12 @@ export const WarnCmd = modActionsCmd({ const casesPlugin = pluginData.getPlugin(CasesPlugin); const priorWarnAmount = await casesPlugin.getCaseTypeAmountForUserId(memberToWarn.id, CaseTypes.Warn); if (config.warn_notify_enabled && priorWarnAmount >= config.warn_notify_threshold) { - const tooManyWarningsMsg = await msg.channel.send( - config.warn_notify_message.replace("{priorWarnings}", `${priorWarnAmount}`), + const reply = await waitForButtonConfirm( + msg.channel, + { content: config.warn_notify_message.replace("{priorWarnings}", `${priorWarnAmount}`) }, + { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, ); - - const reply = false; // await waitForReaction(pluginData.client, tooManyWarningsMsg, ["✅", "❌"], msg.author.id); FIXME waiting on waitForButton - tooManyWarningsMsg.delete(); - if (!reply /*|| reply.name === "❌"*/) { + if (!reply) { msg.channel.send(errorMessage("Warn cancelled by moderator")); return; } diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index 4496fe1a..1be820fa 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -20,7 +20,10 @@ export async function isBanned( } try { - const potentialBan = await Promise.race([pluginData.guild.bans.fetch({ user: userId }), sleep(timeout)]); + const potentialBan = await Promise.race([ + pluginData.guild.bans.fetch({ user: userId }).catch(() => null), + sleep(timeout), + ]); return potentialBan != null; } catch (e) { if (isDiscordRESTError(e) && e.code === 10026) { diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index cf4e8eee..af6e267e 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -14,7 +14,8 @@ import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; -import { GuildMember } from "discord.js"; +import { GuildMember, MessageOptions } from "discord.js"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; export async function warnMember( pluginData: GuildPluginData, @@ -43,12 +44,13 @@ export async function warnMember( if (!notifyResult.success) { if (warnOptions.retryPromptChannel && pluginData.guild.channels.resolve(warnOptions.retryPromptChannel.id)) { - const failedMsg = await warnOptions.retryPromptChannel.send( - "Failed to message the user. Log the warning anyway?", + const reply = await waitForButtonConfirm( + warnOptions.retryPromptChannel, + { content: "Failed to message the user. Log the warning anyway?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: warnOptions.caseArgs?.modId }, ); - const reply = false; // await waitForReaction(pluginData.client, failedMsg, ["✅", "❌"]); FIXME waiting on waitForButton - failedMsg.delete(); - if (!reply /*|| reply.name === "❌"*/) { + + if (!reply) { return { status: "failed", error: "Failed to message user", @@ -74,7 +76,7 @@ export async function warnMember( noteDetails: notifyResult.text ? [ucfirst(notifyResult.text)] : [], }); - const mod = await resolveUser(pluginData.client, modId); + const mod = await pluginData.guild.members.fetch(modId); pluginData.state.serverLogs.log(LogType.MEMBER_WARN, { mod: stripObjectToScalars(mod), member: stripObjectToScalars(member, ["user", "roles"]), diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index ea143838..e8280a8f 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -51,7 +51,7 @@ export async function applyReactionRoleReactionsToMessage( // Remove old reactions, if any try { - await targetMessage.removeReactions(); + await targetMessage.reactions.removeAll(); } catch (e) { if (isDiscordRESTError(e)) { errors.push(`Error ${e.code} while removing old reactions: ${e.message}`); @@ -74,7 +74,7 @@ export async function applyReactionRoleReactionsToMessage( const emoji = isSnowflake(rawEmoji) ? `foo:${rawEmoji}` : rawEmoji; try { - await targetMessage.addReaction(emoji); + await targetMessage.reactions.add(emoji); await sleep(1250); // Make sure we don't hit rate limits } catch (e) { if (isDiscordRESTError(e)) { diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 91dab927..30a411ab 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -27,9 +27,12 @@ import { GuildAuditLogsEntry, GuildChannel, GuildMember, + Interaction, Invite, Message, + MessageActionRow, MessageAttachment, + MessageComponent, MessageEmbed, MessageEmbedOptions, MessageMentionOptions, @@ -41,6 +44,7 @@ import { User, } from "discord.js"; import { ChannelTypeStrings } from "./types"; +import { waitForButtonConfirm } from "./utils/waitForInteraction"; const fsp = fs.promises; @@ -1160,7 +1164,7 @@ export async function resolveUser(bot, value) { // If we have the user cached, return that directly if (bot.users.cache.has(userId)) { - return bot.users.get(userId); + return bot.users.fetch(userId); } // We don't want to spam the API by trying to fetch unknown users again and again, @@ -1169,9 +1173,8 @@ export async function resolveUser(bot, value) { return new UnknownUser({ id: userId }); } - const freshUser = await bot.getRESTUser(userId).catch(noop); + const freshUser = await bot.users.fetch(userId, true, true).catch(noop); if (freshUser) { - bot.users.add(freshUser, bot); return freshUser; } @@ -1272,15 +1275,11 @@ export async function resolveInvite( } export async function confirm( - bot: Client, channel: TextChannel, userId: string, content: StringResolvable | MessageOptions, -) { - const msg = await channel.send(content); - const reply: any = {}; // await helpers.waitForReaction(bot, msg, ["✅", "❌"], userId); FIXME waiting on waitForButton - msg.delete().catch(noop); - return reply && reply.name === "✅"; +): Promise { + return waitForButtonConfirm(channel, { content }, { restrictToId: userId }); } export function messageSummary(msg: SavedMessage) { diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts new file mode 100644 index 00000000..2ee91e84 --- /dev/null +++ b/backend/src/utils/waitForInteraction.ts @@ -0,0 +1,72 @@ +import { + TextChannel, + MessageActionRow, + MessageOptions, + MessageButton, + Client, + Interaction, + MessageComponentInteraction, +} from "discord.js"; +import { PluginError } from "knub"; +import { noop } from "knub/dist/utils"; +import moment from "moment"; + +export async function waitForComponent( + channel: TextChannel, + toPost: MessageOptions, + components: MessageActionRow[], + options?: WaitForOptions, +) { + throw new PluginError("Unimplemented method waitForComponent called."); +} + +export async function waitForButtonConfirm( + channel: TextChannel, + toPost: MessageOptions, + options?: WaitForOptions, +): Promise { + return new Promise(async resolve => { + const idMod = `${channel.guild.id}-${moment.utc().valueOf()}`; + const row = new MessageActionRow().addComponents([ + new MessageButton() + .setStyle("SUCCESS") + .setLabel(options?.confirmText || "Confirm") + .setType("BUTTON") + .setCustomID(`confirmButton:${idMod}`), + + new MessageButton() + .setStyle("DANGER") + .setLabel(options?.cancelText || "Cancel") + .setType("BUTTON") + .setCustomID(`cancelButton:${idMod}`), + ]); + const message = await channel.send({ ...toPost, components: [row], split: false }); + + const filter = (iac: MessageComponentInteraction) => iac.message.id === message.id; + const collector = message.createMessageComponentInteractionCollector(filter, { time: 10000 }); + + collector.on("collect", (interaction: MessageComponentInteraction) => { + if (options?.restrictToId && options.restrictToId !== interaction.user.id) { + interaction.reply(`You are not permitted to use these buttons.`, { ephemeral: true }); + } else { + if (interaction.customID === `confirmButton:${idMod}`) { + message.delete(); + resolve(true); + } else if (interaction.customID === `cancelButton:${idMod}`) { + message.delete(); + resolve(false); + } + } + }); + collector.on("end", () => { + if (!message.deleted) message.delete().catch(noop); + resolve(false); + }); + }); +} + +export interface WaitForOptions { + restrictToId?: string; + confirmText?: string; + cancelText?: string; +} From 7124898568073e2d3b3a422b859a89da0b062c0a Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 3 Jun 2021 02:34:06 +0200 Subject: [PATCH 08/79] Remove erroneous lock Lock was acquired here and in the actual method, causing the actual method to wait 10 minutes for the timeout --- .../src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 2b16f10b..021c93c3 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -48,9 +48,7 @@ export const ResetAllCounterValuesCmd = typedGuildCommand()( .send(`Resetting counter **${counterName}**. This might take a while. Please don't reload the config.`) .catch(() => null); - const lock = await pluginData.locks.acquire(counterIdLock(counterId), 10 * MINUTES); await resetAllCounterValues(pluginData, args.counterName); - lock.interrupt(); loadingMessage?.delete().catch(noop); sendSuccessMessage(pluginData, message.channel, `All counter values for **${counterName}** have been reset`); From 43c23263f0c8d4858d0511889ed4ca3e0e0ef99c Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 6 Jun 2021 02:41:06 +0200 Subject: [PATCH 09/79] Properly order reaction roles --- backend/src/data/GuildReactionRoles.ts | 13 ++++++++++++- backend/src/data/entities/ReactionRole.ts | 2 ++ backend/src/index.ts | 2 +- .../1622939525343-OrderReactionRoles.ts | 18 ++++++++++++++++++ .../commands/InitReactionRolesCmd.ts | 3 +++ .../ReactionRoles/events/AddReactionRoleEvt.ts | 2 +- .../applyReactionRoleReactionsToMessage.ts | 10 ++++------ 7 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 backend/src/migrations/1622939525343-OrderReactionRoles.ts diff --git a/backend/src/data/GuildReactionRoles.ts b/backend/src/data/GuildReactionRoles.ts index 9b309f03..d724493f 100644 --- a/backend/src/data/GuildReactionRoles.ts +++ b/backend/src/data/GuildReactionRoles.ts @@ -24,6 +24,9 @@ export class GuildReactionRoles extends BaseGuildRepository { guild_id: this.guildId, message_id: messageId, }, + order: { + order: "ASC", + }, }); } @@ -50,7 +53,14 @@ export class GuildReactionRoles extends BaseGuildRepository { await this.reactionRoles.delete(criteria); } - async add(channelId: string, messageId: string, emoji: string, roleId: string, exclusive?: boolean) { + async add( + channelId: string, + messageId: string, + emoji: string, + roleId: string, + exclusive?: boolean, + position?: number, + ) { await this.reactionRoles.insert({ guild_id: this.guildId, channel_id: channelId, @@ -58,6 +68,7 @@ export class GuildReactionRoles extends BaseGuildRepository { emoji, role_id: roleId, is_exclusive: Boolean(exclusive), + order: position, }); } } diff --git a/backend/src/data/entities/ReactionRole.ts b/backend/src/data/entities/ReactionRole.ts index 532d3895..198fe0f5 100644 --- a/backend/src/data/entities/ReactionRole.ts +++ b/backend/src/data/entities/ReactionRole.ts @@ -21,4 +21,6 @@ export class ReactionRole { @Column() role_id: string; @Column() is_exclusive: boolean; + + @Column() order: number; } diff --git a/backend/src/index.ts b/backend/src/index.ts index fe3a07da..6cb6fbea 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -164,7 +164,7 @@ connect().then(async () => { intents: [ // Privileged Intents.FLAGS.GUILD_MEMBERS, - // "guildPresences", + // Intents.FLAGS.GUILD_PRESENCES, Intents.FLAGS.GUILD_MESSAGE_TYPING, // Regular diff --git a/backend/src/migrations/1622939525343-OrderReactionRoles.ts b/backend/src/migrations/1622939525343-OrderReactionRoles.ts new file mode 100644 index 00000000..2c94b118 --- /dev/null +++ b/backend/src/migrations/1622939525343-OrderReactionRoles.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; + +export class OrderReactionRoles1622939525343 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumn( + "reaction_roles", + new TableColumn({ + name: "order", + type: "int", + isNullable: true, + }), + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn("reaction_roles", "order"); + } +} diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 2434dde5..44ede36e 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -103,6 +103,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ const progressMessage = msg.channel.send("Adding reaction roles..."); // Save the new reaction roles to the database + let pos = 0; for (const pair of emojiRolePairs) { await pluginData.state.reactionRoles.add( args.message.channel.id, @@ -110,7 +111,9 @@ export const InitReactionRolesCmd = reactionRolesCmd({ pair[0], pair[1], args.exclusive, + pos, ); + pos++; } // Apply the reactions themselves diff --git a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts index b8331cf5..b996f68d 100644 --- a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts @@ -61,7 +61,7 @@ export const AddReactionRoleEvt = reactionRolesEvt({ setTimeout(() => { pluginData.state.reactionRemoveQueue.add(async () => { const wait = sleep(1500); - await meta.args.reaction.remove().catch(noop); + await meta.args.reaction.users.remove(userId).catch(noop); await wait; }); }, 1500); diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index e8280a8f..b2d39707 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -71,18 +71,16 @@ export async function applyReactionRoleReactionsToMessage( emojisToAdd.push(CLEAR_ROLES_EMOJI); for (const rawEmoji of emojisToAdd) { - const emoji = isSnowflake(rawEmoji) ? `foo:${rawEmoji}` : rawEmoji; - try { - await targetMessage.reactions.add(emoji); - await sleep(1250); // Make sure we don't hit rate limits + await targetMessage.react(rawEmoji); + await sleep(750); // Make sure we don't hit rate limits } catch (e) { if (isDiscordRESTError(e)) { if (e.code === 10014) { pluginData.state.reactionRoles.removeFromMessage(messageId, rawEmoji); - errors.push(`Unknown emoji: ${emoji}`); + errors.push(`Unknown emoji: ${rawEmoji}`); logs.log(LogType.BOT_ALERT, { - body: `Could not add unknown reaction role emoji ${emoji} to message ${channelId}/${messageId}`, + body: `Could not add unknown reaction role emoji ${rawEmoji} to message ${channelId}/${messageId}`, }); continue; } else if (e.code === 50013) { From 7c757d4b96ebcd4dec908d266193278143bdb1be Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 6 Jun 2021 04:57:05 +0200 Subject: [PATCH 10/79] WIP: Button Reactions This still needs some cleanup and some functionality straight up doesn't work or is only a POC --- .../ReactionRoles/ReactionRolesPlugin.ts | 5 ++ .../commands/PostButtonRolesCmd.ts | 65 +++++++++++++++ .../events/ButtonInteractionEvt.ts | 80 +++++++++++++++++++ backend/src/plugins/ReactionRoles/types.ts | 23 ++++++ .../ReactionRoles/util/buttonMenuActions.ts | 4 + 5 files changed, 177 insertions(+) create mode 100644 backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts create mode 100644 backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts create mode 100644 backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index ff8d6330..7b7b55de 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -10,11 +10,14 @@ import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; import { ClearReactionRolesCmd } from "./commands/ClearReactionRolesCmd"; import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; import { LogsPlugin } from "../Logs/LogsPlugin"; +import { PostButtonRolesCmd } from "./commands/PostButtonRolesCmd"; +import { ButtonInteractionEvt } from "./events/ButtonInteractionEvt"; const MIN_AUTO_REFRESH = 1000 * 60 * 15; // 15min minimum, let's not abuse the API const defaultOptions: PluginOptions = { config: { + button_groups: {}, auto_refresh_interval: MIN_AUTO_REFRESH, remove_user_reactions: true, @@ -47,11 +50,13 @@ export const ReactionRolesPlugin = zeppelinGuildPlugin( RefreshReactionRolesCmd, ClearReactionRolesCmd, InitReactionRolesCmd, + PostButtonRolesCmd, ], // prettier-ignore events: [ AddReactionRoleEvt, + ButtonInteractionEvt, ], beforeLoad(pluginData) { diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts new file mode 100644 index 00000000..6dc4f2fd --- /dev/null +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -0,0 +1,65 @@ +import { reactionRolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { MessageActionRow, MessageButton, MessageComponentInteraction, TextChannel } from "discord.js"; +import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils"; +import moment from "moment"; +import { ButtonMenuActions } from "../util/buttonMenuActions"; + +export const PostButtonRolesCmd = reactionRolesCmd({ + trigger: "reaction_roles post", + permission: "can_manage", + + signature: { + button_group: ct.string(), + }, + + async run({ message: msg, args, pluginData }) { + const cfg = pluginData.config.get(); + const group = cfg.button_groups[args.button_group]; + + if (!group) { + sendErrorMessage(pluginData, msg.channel, `No button group matches the name **${args.button_group}**`); + } + + const channel = pluginData.guild.channels.resolve(group.channel_id); + if (!channel) { + await sendErrorMessage( + pluginData, + msg.channel, + `The ID ${group.channel_id} does not match a channel on the server`, + ); + return; + } + + const buttons: MessageButton[] = []; + for (const button of Object.values(group.default_buttons)) { + let customId = ""; + if ((await pluginData.guild.roles.fetch(button.role_or_menu)) != null) { + // TODO: Make universal, currently can only handle custom emoji and not default ones + customId = `${args.button_group}::${ButtonMenuActions.GRANT_ROLE}::${button.role_or_menu}`; + } else { + customId = `${args.button_group}::${ButtonMenuActions.OPEN_MENU}::${button.role_or_menu}`; + } + + const btn = new MessageButton() + .setLabel(button.label) + .setStyle("PRIMARY") + .setType("BUTTON") + .setCustomID(customId); + + const emo = pluginData.client.emojis.resolve(button.emoji); + if (emo) btn.setEmoji(emo); + + buttons.push(btn); + } + const row = new MessageActionRow().addComponents(buttons); + + try { + await (channel as TextChannel).send({ content: group.message, components: [row], split: false }); + } catch (e) { + sendErrorMessage(pluginData, msg.channel, `Error trying to post message: ${e}`); + return; + } + await sendSuccessMessage(pluginData, msg.channel, `Successfully posted message in <#${channel.id}>`); + }, +}); diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts new file mode 100644 index 00000000..b37b89d8 --- /dev/null +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -0,0 +1,80 @@ +import { Interaction, MessageComponentInteraction, MessageComponentInteractionCollector } from "discord.js"; +import { LogType } from "src/data/LogType"; +import { pluginInfo } from "src/plugins/Automod/info"; +import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; +import { reactionRolesEvt } from "../types"; +import { ButtonMenuActions } from "../util/buttonMenuActions"; + +export const ButtonInteractionEvt = reactionRolesEvt({ + event: "interaction", + + async listener(meta) { + const int = meta.args.interaction.isMessageComponent() + ? (meta.args.interaction as MessageComponentInteraction) + : null; + if (!int) return; + const cfg = meta.pluginData.config.get(); + const split = int.customID.split("::"); + const [groupName, action, roleOrMenu] = [split[0], split[1], split[2]]; + + const group = cfg.button_groups[groupName]; + if (!group) { + await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`); + meta.pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A configuration error occured** on buttons for message ${int.message.id}, group **${groupName}** not found in config`, + ); + return; + } + + // Verify that detected action is known by us + if (!(Object).values(ButtonMenuActions).includes(action)) { + await sendEphemeralReply(int, `A internal error was encountered, please contact the Administrators!`); + meta.pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A internal error occured** on buttons for message ${int.message.id}, action **${action}** is not known`, + ); + return; + } + + if (action === ButtonMenuActions.GRANT_ROLE) { + const role = await meta.pluginData.guild.roles.fetch(roleOrMenu); + if (!role) { + await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`); + meta.pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A configuration error occured** on buttons for message ${int.message.id}, group **${groupName}** not found in config`, + ); + return; + } + + const member = await meta.pluginData.guild.members.fetch(int.user.id); + if (member.roles.cache.has(role.id)) { + await member.roles.remove(role, `Button Roles on message ${int.message.id}`); + await sendEphemeralReply(int, `You have removed the role <@&${role.id}>`); + } else { + await member.roles.add(role, `Button Roles on message ${int.message.id}`); + await sendEphemeralReply(int, `You have added the role <@&${role.id}>`); + } + + return; + } + + // TODO: Send ephemeral reply with buttons that are part of the selected menu + if (action === ButtonMenuActions.OPEN_MENU) { + console.log("Disable TSLint error"); + } + + await sendEphemeralReply(int, split.join("\n")); // TODO: Remove debug output + }, +}); + +async function sendEphemeralReply(interaction: MessageComponentInteraction, message: string) { + await interaction.reply(message, { ephemeral: true }); +} diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index 36fed600..d0b2e5d9 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -4,7 +4,30 @@ import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { Queue } from "../../Queue"; +const ButtonOpts = t.type({ + label: t.string, + emoji: t.string, + role_or_menu: t.string, +}); +export type TButtonOpts = t.TypeOf; + +const MenuButtonOpts = t.type({ + label: t.string, + emoji: t.string, + role: t.string, +}); +export type TMenuButtonOpts = t.TypeOf; + +const ButtonPairOpts = t.type({ + channel_id: t.string, + message: t.string, + default_buttons: t.record(t.string, ButtonOpts), + button_menus: t.record(t.string, t.record(t.string, MenuButtonOpts)), +}); +export type TButtonPairOpts = t.TypeOf; + export const ConfigSchema = t.type({ + button_groups: t.record(t.string, ButtonPairOpts), auto_refresh_interval: t.number, remove_user_reactions: t.boolean, can_manage: t.boolean, diff --git a/backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts b/backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts new file mode 100644 index 00000000..3edcca0d --- /dev/null +++ b/backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts @@ -0,0 +1,4 @@ +export enum ButtonMenuActions { + OPEN_MENU = "goto", + GRANT_ROLE = "grant", +} From a94e7593ec91cab2df14e114fe7142939b92f567 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 6 Jun 2021 23:02:24 +0200 Subject: [PATCH 11/79] Expand button reactions functionality --- .../commands/PostButtonRolesCmd.ts | 10 ++-- .../events/ButtonInteractionEvt.ts | 53 ++++++++++++++++--- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index 6dc4f2fd..6bd19017 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -1,8 +1,7 @@ import { reactionRolesCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { MessageActionRow, MessageButton, MessageComponentInteraction, TextChannel } from "discord.js"; +import { MessageActionRow, MessageButton, TextChannel } from "discord.js"; import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils"; -import moment from "moment"; import { ButtonMenuActions } from "../util/buttonMenuActions"; export const PostButtonRolesCmd = reactionRolesCmd({ @@ -35,7 +34,6 @@ export const PostButtonRolesCmd = reactionRolesCmd({ for (const button of Object.values(group.default_buttons)) { let customId = ""; if ((await pluginData.guild.roles.fetch(button.role_or_menu)) != null) { - // TODO: Make universal, currently can only handle custom emoji and not default ones customId = `${args.button_group}::${ButtonMenuActions.GRANT_ROLE}::${button.role_or_menu}`; } else { customId = `${args.button_group}::${ButtonMenuActions.OPEN_MENU}::${button.role_or_menu}`; @@ -47,8 +45,10 @@ export const PostButtonRolesCmd = reactionRolesCmd({ .setType("BUTTON") .setCustomID(customId); - const emo = pluginData.client.emojis.resolve(button.emoji); - if (emo) btn.setEmoji(emo); + if (button.emoji) { + const emo = pluginData.client.emojis.resolve(button.emoji) ?? button.emoji; + btn.setEmoji(emo); + } buttons.push(btn); } diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index b37b89d8..51694c1f 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -1,5 +1,13 @@ -import { Interaction, MessageComponentInteraction, MessageComponentInteractionCollector } from "discord.js"; +import { + Interaction, + MessageActionRow, + MessageButton, + MessageComponentInteraction, + MessageComponentInteractionCollector, + TextChannel, +} from "discord.js"; import { LogType } from "src/data/LogType"; +import { logger } from "src/logger"; import { pluginInfo } from "src/plugins/Automod/info"; import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; import { reactionRolesEvt } from "../types"; @@ -57,21 +65,54 @@ export const ButtonInteractionEvt = reactionRolesEvt({ const member = await meta.pluginData.guild.members.fetch(int.user.id); if (member.roles.cache.has(role.id)) { await member.roles.remove(role, `Button Roles on message ${int.message.id}`); - await sendEphemeralReply(int, `You have removed the role <@&${role.id}>`); + await sendEphemeralReply(int, `Role **${role.name}** removed`); } else { await member.roles.add(role, `Button Roles on message ${int.message.id}`); - await sendEphemeralReply(int, `You have added the role <@&${role.id}>`); + await sendEphemeralReply(int, `Role **${role.name}** added`); } return; } - // TODO: Send ephemeral reply with buttons that are part of the selected menu if (action === ButtonMenuActions.OPEN_MENU) { - console.log("Disable TSLint error"); + const menuButtons: MessageButton[] = []; + for (const menuButton of Object.values(group.button_menus[roleOrMenu])) { + let customId = ""; + customId = `${groupName}::${ButtonMenuActions.GRANT_ROLE}::${menuButton.role}`; + + const btn = new MessageButton() + .setLabel(menuButton.label) + .setStyle("PRIMARY") + .setType("BUTTON") + .setCustomID(customId); + + if (menuButton.emoji) { + const emo = meta.pluginData.client.emojis.resolve(menuButton.emoji) ?? menuButton.emoji; + btn.setEmoji(emo); + } + menuButtons.push(btn); + } + + if (menuButtons.length === 0) { + await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`); + meta.pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A configuration error occured** on buttons for message ${int.message.id}, menu **${roleOrMenu}** not found in config`, + ); + return; + } + const row = new MessageActionRow().addComponents(menuButtons); + + int.reply({ content: `Click to add/remove a role`, components: [row], ephemeral: true, split: false }); + return; } - await sendEphemeralReply(int, split.join("\n")); // TODO: Remove debug output + logger.warn( + `Action ${action} on button ${int.customID} (Guild: ${int.guildID}, Channel: ${int.channelID}) is unknown!`, + ); + await sendEphemeralReply(int, `A internal error was encountered, please contact the Administrators!`); }, }); From 6ac9d2f2a24ab502925f885621a712ec3c7644b2 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 6 Jun 2021 23:51:32 +0200 Subject: [PATCH 12/79] Organise all imports, make Mutes depend on Logs --- backend/src/RegExpRunner.ts | 6 +- backend/src/api/archives.ts | 2 +- backend/src/api/auth.ts | 12 +-- backend/src/api/docs.ts | 2 +- backend/src/api/guilds.ts | 16 ++-- backend/src/api/index.ts | 5 +- backend/src/api/permissions.ts | 4 +- backend/src/api/staff.ts | 2 +- backend/src/api/start.ts | 12 +-- backend/src/commandTypes.ts | 30 +++---- backend/src/configValidator.ts | 9 +- backend/src/data/AllowedGuilds.ts | 4 +- backend/src/data/ApiLogins.ts | 6 +- backend/src/data/ApiPermissionAssignments.ts | 6 +- backend/src/data/ApiUserInfo.ts | 6 +- backend/src/data/Configs.ts | 6 +- backend/src/data/GuildAntiraidLevels.ts | 2 +- backend/src/data/GuildArchives.ts | 14 +-- backend/src/data/GuildAutoReactions.ts | 2 +- backend/src/data/GuildCases.ts | 9 +- backend/src/data/GuildCounters.ts | 20 ++--- backend/src/data/GuildEvents.ts | 2 +- backend/src/data/GuildMemberTimezones.ts | 4 +- backend/src/data/GuildMutes.ts | 4 +- backend/src/data/GuildNicknameHistory.ts | 6 +- backend/src/data/GuildPersistedData.ts | 4 +- backend/src/data/GuildPingableRoles.ts | 2 +- backend/src/data/GuildReactionRoles.ts | 4 +- backend/src/data/GuildReminders.ts | 2 +- backend/src/data/GuildSavedMessages.ts | 16 ++-- backend/src/data/GuildScheduledPosts.ts | 2 +- backend/src/data/GuildSlowmodes.ts | 4 +- backend/src/data/GuildStarboardMessages.ts | 2 +- backend/src/data/GuildStarboardReactions.ts | 2 +- backend/src/data/GuildStats.ts | 2 +- backend/src/data/GuildTags.ts | 2 +- backend/src/data/GuildTempbans.ts | 3 +- backend/src/data/GuildVCAlerts.ts | 2 +- backend/src/data/Supporters.ts | 2 +- backend/src/data/UsernameHistory.ts | 4 +- backend/src/data/cleanup/configs.ts | 6 +- backend/src/data/cleanup/messages.ts | 6 +- backend/src/data/cleanup/nicknames.ts | 4 +- backend/src/data/cleanup/usernames.ts | 4 +- backend/src/data/db.ts | 2 +- backend/src/data/encryptedJsonTransformer.ts | 2 +- backend/src/data/encryptedTextTransformer.ts | 2 +- backend/src/data/getChannelIdFromMessageId.ts | 2 +- backend/src/index.ts | 33 ++++--- backend/src/migrateConfigsToDB.ts | 6 +- ...8692857722-FixStarboardReactionsIndices.ts | 2 +- backend/src/pluginUtils.ts | 16 ++-- .../plugins/AutoDelete/AutoDeletePlugin.ts | 10 +-- backend/src/plugins/AutoDelete/types.ts | 6 +- .../util/addMessageToDeletionQueue.ts | 4 +- .../plugins/AutoDelete/util/deleteNextItem.ts | 10 +-- .../AutoDelete/util/onMessageCreate.ts | 4 +- .../AutoDelete/util/onMessageDelete.ts | 2 +- .../AutoDelete/util/onMessageDeleteBulk.ts | 2 +- .../AutoReactions/AutoReactionsPlugin.ts | 12 +-- .../commands/DisableAutoReactionsCmd.ts | 2 +- .../commands/NewAutoReactionsCmd.ts | 16 ++-- .../AutoReactions/events/AddReactionsEvt.ts | 16 ++-- backend/src/plugins/AutoReactions/types.ts | 2 +- backend/src/plugins/Automod/AutomodPlugin.ts | 43 +++++----- .../plugins/Automod/actions/addToCounter.ts | 4 +- backend/src/plugins/Automod/actions/alert.ts | 26 +++--- .../Automod/actions/availableActions.ts | 22 ++--- backend/src/plugins/Automod/actions/ban.ts | 20 ++--- .../plugins/Automod/actions/changeNickname.ts | 4 +- backend/src/plugins/Automod/actions/clean.ts | 4 +- backend/src/plugins/Automod/actions/kick.ts | 7 +- backend/src/plugins/Automod/actions/log.ts | 4 +- backend/src/plugins/Automod/actions/mute.ts | 26 +++--- .../plugins/Automod/actions/removeRoles.ts | 24 +++--- backend/src/plugins/Automod/actions/reply.ts | 36 ++++---- .../Automod/actions/setAntiraidLevel.ts | 4 +- .../src/plugins/Automod/actions/setCounter.ts | 4 +- .../plugins/Automod/actions/setSlowmode.ts | 8 +- backend/src/plugins/Automod/actions/warn.ts | 7 +- .../Automod/commands/AntiraidClearCmd.ts | 6 +- .../Automod/commands/SetAntiraidCmd.ts | 8 +- .../Automod/commands/ViewAntiraidCmd.ts | 5 +- .../Automod/events/RunAutomodOnJoinEvt.ts | 4 +- .../events/RunAutomodOnMemberUpdate.ts | 7 +- .../events/runAutomodOnAntiraidLevel.ts | 6 +- .../events/runAutomodOnCounterTrigger.ts | 4 +- .../Automod/events/runAutomodOnMessage.ts | 8 +- .../Automod/events/runAutomodOnModAction.ts | 4 +- .../functions/addRecentActionsFromMessage.ts | 4 +- .../functions/checkAndUpdateCooldown.ts | 3 +- .../functions/clearOldNicknameChanges.ts | 2 +- .../functions/clearOldRecentActions.ts | 2 +- .../Automod/functions/clearOldRecentSpam.ts | 2 +- .../functions/clearRecentActionsForMessage.ts | 4 +- .../functions/createMessageSpamTrigger.ts | 10 +-- .../Automod/functions/findRecentSpam.ts | 2 +- .../getMatchingMessageRecentActions.ts | 6 +- .../functions/getMatchingRecentActions.ts | 2 +- .../functions/getTextMatchPartialSummary.ts | 6 +- .../Automod/functions/ignoredRoleChanges.ts | 2 +- .../matchMultipleTextTypesOnMessage.ts | 4 +- .../functions/resolveActionContactMethods.ts | 10 +-- .../plugins/Automod/functions/runAutomod.ts | 14 +-- .../Automod/functions/setAntiraidLevel.ts | 6 +- backend/src/plugins/Automod/helpers.ts | 2 +- backend/src/plugins/Automod/info.ts | 2 +- .../plugins/Automod/triggers/antiraidLevel.ts | 2 +- .../plugins/Automod/triggers/anyMessage.ts | 2 +- .../Automod/triggers/availableTriggers.ts | 36 ++++---- .../Automod/triggers/counterTrigger.ts | 4 +- .../Automod/triggers/matchAttachmentType.ts | 12 +-- .../plugins/Automod/triggers/matchInvites.ts | 17 ++-- .../plugins/Automod/triggers/matchLinks.ts | 17 ++-- .../plugins/Automod/triggers/matchRegex.ts | 10 +-- .../plugins/Automod/triggers/matchWords.ts | 10 +-- .../plugins/Automod/triggers/memberJoin.ts | 2 +- .../Automod/triggers/memberJoinSpam.ts | 6 +- .../src/plugins/Automod/triggers/roleAdded.ts | 2 +- .../plugins/Automod/triggers/roleRemoved.ts | 2 +- backend/src/plugins/Automod/types.ts | 20 ++--- .../plugins/BotControl/BotControlPlugin.ts | 34 ++++---- .../commands/AddDashboardUserCmd.ts | 6 +- .../BotControl/commands/AllowServerCmd.ts | 8 +- .../BotControl/commands/DisallowServerCmd.ts | 8 +- .../BotControl/commands/EligibleCmd.ts | 8 +- .../BotControl/commands/LeaveServerCmd.ts | 6 +- .../commands/ListDashboardPermsCmd.ts | 8 +- .../commands/ListDashboardUsersCmd.ts | 9 +- .../commands/ReloadGlobalPluginsCmd.ts | 4 +- .../BotControl/commands/ReloadServerCmd.ts | 6 +- .../commands/RemoveDashboardUserCmd.ts | 7 +- .../plugins/BotControl/commands/ServersCmd.ts | 10 +-- backend/src/plugins/BotControl/types.ts | 4 +- backend/src/plugins/Cases/CasesPlugin.ts | 28 +++--- .../src/plugins/Cases/functions/createCase.ts | 6 +- .../plugins/Cases/functions/createCaseNote.ts | 6 +- .../plugins/Cases/functions/getCaseColor.ts | 2 +- .../plugins/Cases/functions/getCaseEmbed.ts | 16 ++-- .../plugins/Cases/functions/getCaseIcon.ts | 2 +- .../plugins/Cases/functions/getCaseSummary.ts | 27 +++--- .../functions/getCaseTypeAmountForUserId.ts | 2 +- .../Cases/functions/getRecentCasesByMod.ts | 2 +- .../Cases/functions/postToCaseLogChannel.ts | 10 +-- backend/src/plugins/Cases/types.ts | 8 +- backend/src/plugins/Censor/CensorPlugin.ts | 10 +-- backend/src/plugins/Censor/types.ts | 4 +- .../plugins/Censor/util/applyFiltersToMsg.ts | 19 ++-- .../src/plugins/Censor/util/censorMessage.ts | 8 +- .../plugins/Censor/util/onMessageCreate.ts | 4 +- .../plugins/Censor/util/onMessageUpdate.ts | 4 +- .../ChannelArchiver/ChannelArchiverPlugin.ts | 6 +- .../commands/ArchiveChannelCmd.ts | 10 +-- .../ChannelArchiver/rehostAttachment.ts | 4 +- .../CompanionChannelsPlugin.ts | 6 +- .../events/VoiceStateUpdateEvt.ts | 2 +- .../functions/handleCompanionPermissions.ts | 10 +-- .../src/plugins/CompanionChannels/types.ts | 4 +- .../src/plugins/Counters/CountersPlugin.ts | 45 +++++----- .../Counters/commands/AddCounterCmd.ts | 8 +- .../Counters/commands/CountersListCmd.ts | 2 +- .../commands/ResetAllCounterValuesCmd.ts | 7 +- .../Counters/commands/ResetCounterCmd.ts | 8 +- .../Counters/commands/SetCounterCmd.ts | 8 +- .../Counters/commands/ViewCounterCmd.ts | 8 +- .../checkAllValuesForReverseTrigger.ts | 2 +- .../functions/checkAllValuesForTrigger.ts | 2 +- .../Counters/functions/checkCounterTrigger.ts | 2 +- .../functions/checkReverseCounterTrigger.ts | 2 +- .../Counters/functions/decayCounter.ts | 6 +- .../Counters/functions/emitCounterEvent.ts | 2 +- .../functions/getPrettyNameForCounter.ts | 2 +- .../getPrettyNameForCounterTrigger.ts | 2 +- .../Counters/functions/offCounterEvent.ts | 2 +- .../Counters/functions/onCounterEvent.ts | 2 +- backend/src/plugins/Counters/types.ts | 4 +- .../CustomEvents/CustomEventsPlugin.ts | 6 +- .../CustomEvents/actions/addRoleAction.ts | 6 +- .../CustomEvents/actions/createCaseAction.ts | 8 +- .../actions/makeRoleMentionableAction.ts | 4 +- .../actions/makeRoleUnmentionableAction.ts | 4 +- .../CustomEvents/actions/messageAction.ts | 6 +- .../actions/moveToVoiceChannelAction.ts | 8 +- .../actions/setChannelPermissionOverrides.ts | 4 +- .../CustomEvents/functions/runEvent.ts | 10 +-- backend/src/plugins/CustomEvents/types.ts | 4 +- .../GuildAccessMonitorPlugin.ts | 8 +- .../GuildConfigReloaderPlugin.ts | 8 +- .../functions/reloadChangedGuilds.ts | 2 +- .../src/plugins/GuildConfigReloader/types.ts | 2 +- .../GuildInfoSaver/GuildInfoSaverPlugin.ts | 6 +- .../plugins/LocateUser/LocateUserPlugin.ts | 14 +-- .../plugins/LocateUser/commands/FollowCmd.ts | 8 +- .../LocateUser/commands/ListFollowCmd.ts | 4 +- .../plugins/LocateUser/commands/WhereCmd.ts | 3 +- .../plugins/LocateUser/utils/moveMember.ts | 6 +- .../plugins/LocateUser/utils/outdatedLoop.ts | 4 +- .../plugins/LocateUser/utils/sendAlerts.ts | 6 +- .../src/plugins/LocateUser/utils/sendWhere.ts | 10 +-- backend/src/plugins/Logs/LogsPlugin.ts | 36 ++++---- .../Logs/events/LogsChannelModifyEvts.ts | 4 +- .../plugins/Logs/events/LogsGuildBanEvts.ts | 10 +-- .../Logs/events/LogsGuildMemberAddEvt.ts | 8 +- .../Logs/events/LogsGuildMemberRemoveEvt.ts | 4 +- .../plugins/Logs/events/LogsRoleModifyEvts.ts | 4 +- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 14 +-- .../Logs/events/LogsVoiceChannelEvts.ts | 4 +- backend/src/plugins/Logs/types.ts | 8 +- .../src/plugins/Logs/util/getLogMessage.ts | 28 +++--- backend/src/plugins/Logs/util/log.ts | 16 ++-- .../src/plugins/Logs/util/onMessageDelete.ts | 16 ++-- .../plugins/Logs/util/onMessageDeleteBulk.ts | 2 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 14 +-- .../MessageSaver/MessageSaverPlugin.ts | 8 +- .../MessageSaver/commands/SaveMessagesToDB.ts | 4 +- .../MessageSaver/commands/SavePinsToDB.ts | 4 +- .../plugins/MessageSaver/saveMessagesToDB.ts | 4 +- .../plugins/ModActions/ModActionsPlugin.ts | 86 +++++++++---------- .../plugins/ModActions/commands/AddCaseCmd.ts | 10 +-- .../src/plugins/ModActions/commands/BanCmd.ts | 20 ++--- .../plugins/ModActions/commands/CaseCmd.ts | 4 +- .../ModActions/commands/CasesModCmd.ts | 15 ++-- .../ModActions/commands/CasesUserCmd.ts | 30 +++---- .../ModActions/commands/DeleteCaseCmd.ts | 23 +++-- .../ModActions/commands/ForcebanCmd.ts | 16 ++-- .../ModActions/commands/ForcemuteCmd.ts | 2 +- .../ModActions/commands/ForceunmuteCmd.ts | 4 +- .../ModActions/commands/HideCaseCmd.ts | 2 +- .../plugins/ModActions/commands/KickCmd.ts | 7 +- .../plugins/ModActions/commands/MassBanCmd.ts | 30 +++---- .../ModActions/commands/MassUnbanCmd.ts | 18 ++-- .../ModActions/commands/MassmuteCmd.ts | 14 +-- .../plugins/ModActions/commands/MuteCmd.ts | 10 +-- .../plugins/ModActions/commands/NoteCmd.ts | 11 ++- .../ModActions/commands/SoftbanCommand.ts | 2 +- .../plugins/ModActions/commands/UnbanCmd.ts | 10 +-- .../ModActions/commands/UnhideCaseCmd.ts | 2 +- .../plugins/ModActions/commands/UnmuteCmd.ts | 8 +- .../plugins/ModActions/commands/UpdateCmd.ts | 2 +- .../plugins/ModActions/commands/WarnCmd.ts | 14 ++- .../events/CreateBanCaseOnManualBanEvt.ts | 20 ++--- .../events/CreateKickCaseOnManualKickEvt.ts | 16 ++-- .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 20 ++--- .../events/PostAlertOnMemberJoinEvt.ts | 8 +- .../functions/actualKickMemberCmd.ts | 14 +-- .../ModActions/functions/actualMuteUserCmd.ts | 20 ++--- .../functions/actualUnmuteUserCmd.ts | 16 ++-- .../plugins/ModActions/functions/banUserId.ts | 38 ++++---- .../functions/getDefaultContactMethods.ts | 6 +- .../ModActions/functions/ignoreEvent.ts | 2 +- .../plugins/ModActions/functions/isBanned.ts | 12 +-- .../ModActions/functions/kickMember.ts | 34 ++++---- .../functions/outdatedTempbansLoop.ts | 14 +-- .../ModActions/functions/warnMember.ts | 26 +++--- backend/src/plugins/ModActions/types.ts | 14 +-- backend/src/plugins/Mutes/MutesPlugin.ts | 41 ++++----- .../Mutes/commands/ClearBannedMutesCmd.ts | 4 +- .../plugins/Mutes/commands/ClearMutesCmd.ts | 4 +- .../commands/ClearMutesWithoutRoleCmd.ts | 2 +- .../src/plugins/Mutes/commands/MutesCmd.ts | 8 +- .../events/ClearActiveMuteOnRoleRemovalEvt.ts | 2 +- .../events/ReapplyActiveMuteOnJoinEvt.ts | 2 +- .../Mutes/functions/clearExpiredMutes.ts | 4 +- .../src/plugins/Mutes/functions/muteUser.ts | 46 +++++----- .../src/plugins/Mutes/functions/unmuteUser.ts | 14 +-- backend/src/plugins/Mutes/types.ts | 26 +++--- .../plugins/NameHistory/NameHistoryPlugin.ts | 4 +- .../plugins/NameHistory/commands/NamesCmd.ts | 6 +- backend/src/plugins/Persist/PersistPlugin.ts | 10 +-- .../src/plugins/Persist/events/LoadDataEvt.ts | 12 +-- .../plugins/Persist/events/StoreDataEvt.ts | 8 +- backend/src/plugins/Persist/types.ts | 2 +- .../PingableRoles/PingableRolesPlugin.ts | 6 +- .../commands/PingableRoleDisableCmd.ts | 2 +- .../commands/PingableRoleEnableCmd.ts | 2 +- .../events/ChangePingableEvts.ts | 4 +- backend/src/plugins/PingableRoles/types.ts | 2 +- .../utils/disablePingableRoles.ts | 2 +- .../utils/enablePingableRoles.ts | 2 +- .../utils/getPingableRolesForChannel.ts | 2 +- backend/src/plugins/Post/PostPlugin.ts | 16 ++-- backend/src/plugins/Post/commands/EditCmd.ts | 4 +- .../src/plugins/Post/commands/EditEmbedCmd.ts | 8 +- backend/src/plugins/Post/commands/PostCmd.ts | 2 +- .../src/plugins/Post/commands/PostEmbedCmd.ts | 10 +-- .../Post/commands/SchedluedPostsDeleteCmd.ts | 6 +- .../Post/commands/ScheduledPostsListCmd.ts | 14 ++- .../Post/commands/ScheduledPostsShowCmd.ts | 10 +-- backend/src/plugins/Post/types.ts | 2 +- .../src/plugins/Post/util/actualPostCmd.ts | 10 +-- .../plugins/Post/util/parseScheduleTime.ts | 2 +- backend/src/plugins/Post/util/postMessage.ts | 10 +-- .../plugins/Post/util/scheduledPostLoop.ts | 16 ++-- .../ReactionRoles/ReactionRolesPlugin.ts | 14 +-- .../commands/ClearReactionRolesCmd.ts | 6 +- .../commands/InitReactionRolesCmd.ts | 4 +- .../commands/PostButtonRolesCmd.ts | 4 +- .../commands/RefreshReactionRolesCmd.ts | 2 +- .../events/AddReactionRoleEvt.ts | 6 +- .../events/ButtonInteractionEvt.ts | 6 +- backend/src/plugins/ReactionRoles/types.ts | 4 +- .../util/addMemberPendingRoleChange.ts | 4 +- .../applyReactionRoleReactionsToMessage.ts | 15 ++-- .../util/refreshReactionRoles.ts | 2 +- .../src/plugins/Reminders/RemindersPlugin.ts | 8 +- .../plugins/Reminders/commands/RemindCmd.ts | 8 +- .../Reminders/commands/RemindersCmd.ts | 6 +- .../Reminders/commands/RemindersDeleteCmd.ts | 4 +- .../Reminders/utils/postDueRemindersLoop.ts | 12 +-- backend/src/plugins/Roles/RolesPlugin.ts | 8 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 10 +-- .../plugins/Roles/commands/MassAddRoleCmd.ts | 8 +- .../Roles/commands/MassRemoveRoleCmd.ts | 8 +- .../plugins/Roles/commands/RemoveRoleCmd.ts | 8 +- .../SelfGrantableRolesPlugin.ts | 6 +- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 18 ++-- .../commands/RoleHelpCmd.ts | 2 +- .../commands/RoleRemoveCmd.ts | 10 +-- .../src/plugins/SelfGrantableRoles/types.ts | 2 +- .../util/getApplyingEntries.ts | 2 +- .../src/plugins/Slowmode/SlowmodePlugin.ts | 22 ++--- .../Slowmode/commands/SlowmodeClearCmd.ts | 6 +- .../Slowmode/commands/SlowmodeGetCmd.ts | 4 +- .../Slowmode/commands/SlowmodeListCmd.ts | 8 +- .../Slowmode/commands/SlowmodeSetCmd.ts | 12 +-- backend/src/plugins/Slowmode/types.ts | 4 +- .../Slowmode/util/actualDisableSlowmodeCmd.ts | 6 +- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 8 +- .../Slowmode/util/clearExpiredSlowmodes.ts | 6 +- .../plugins/Slowmode/util/onMessageCreate.ts | 26 +++--- backend/src/plugins/Spam/SpamPlugin.ts | 14 +-- .../src/plugins/Spam/events/SpamVoiceEvt.ts | 2 +- backend/src/plugins/Spam/types.ts | 6 +- .../src/plugins/Spam/util/addRecentAction.ts | 2 +- .../Spam/util/clearRecentUserActions.ts | 2 +- .../plugins/Spam/util/getRecentActionCount.ts | 2 +- .../src/plugins/Spam/util/getRecentActions.ts | 2 +- .../Spam/util/logAndDetectMessageSpam.ts | 40 ++++----- .../Spam/util/logAndDetectOtherSpam.ts | 14 +-- backend/src/plugins/Spam/util/logCensor.ts | 2 +- .../src/plugins/Spam/util/onMessageCreate.ts | 4 +- .../src/plugins/Spam/util/saveSpamArchives.ts | 6 +- .../src/plugins/Starboard/StarboardPlugin.ts | 10 +-- .../Starboard/commands/MigratePinsCmd.ts | 10 +-- .../events/StarboardReactionAddEvt.ts | 8 +- backend/src/plugins/Starboard/types.ts | 2 +- .../util/createStarboardEmbedFromMessage.ts | 6 +- .../createStarboardPseudoFooterForMessage.ts | 2 +- .../plugins/Starboard/util/onMessageDelete.ts | 2 +- .../Starboard/util/preprocessStaticConfig.ts | 2 +- .../Starboard/util/saveMessageToStarboard.ts | 7 +- .../util/updateStarboardMessageStarCount.ts | 7 +- backend/src/plugins/Tags/TagsPlugin.ts | 26 +++--- .../src/plugins/Tags/commands/TagCreateCmd.ts | 4 +- .../src/plugins/Tags/commands/TagDeleteCmd.ts | 2 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 8 +- .../src/plugins/Tags/commands/TagListCmd.ts | 2 +- .../src/plugins/Tags/commands/TagSourceCmd.ts | 6 +- backend/src/plugins/Tags/types.ts | 6 +- .../src/plugins/Tags/util/findTagByName.ts | 6 +- .../Tags/util/matchAndRenderTagFromString.ts | 8 +- .../src/plugins/Tags/util/onMessageCreate.ts | 18 ++-- .../src/plugins/Tags/util/onMessageDelete.ts | 6 +- .../src/plugins/Tags/util/renderTagBody.ts | 10 +-- .../plugins/Tags/util/renderTagFromString.ts | 21 +++-- .../plugins/TimeAndDate/TimeAndDatePlugin.ts | 17 ++-- .../TimeAndDate/commands/ResetTimezoneCmd.ts | 3 +- .../TimeAndDate/commands/SetTimezoneCmd.ts | 3 +- .../TimeAndDate/commands/ViewTimezoneCmd.ts | 5 +- .../TimeAndDate/functions/getGuildTz.ts | 1 - .../TimeAndDate/functions/inGuildTz.ts | 2 +- .../TimeAndDate/functions/inMemberTz.ts | 3 +- backend/src/plugins/TimeAndDate/types.ts | 2 +- .../UsernameSaver/UsernameSaverPlugin.ts | 6 +- backend/src/plugins/Utility/UtilityPlugin.ts | 70 +++++++-------- .../src/plugins/Utility/commands/AboutCmd.ts | 11 ++- .../src/plugins/Utility/commands/AvatarCmd.ts | 8 +- .../plugins/Utility/commands/BanSearchCmd.ts | 2 +- .../Utility/commands/ChannelInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/CleanCmd.ts | 16 ++-- .../plugins/Utility/commands/ContextCmd.ts | 12 +-- .../plugins/Utility/commands/EmojiInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/HelpCmd.ts | 6 +- .../src/plugins/Utility/commands/InfoCmd.ts | 20 ++--- .../plugins/Utility/commands/InviteInfoCmd.ts | 4 +- .../src/plugins/Utility/commands/JumboCmd.ts | 6 +- .../src/plugins/Utility/commands/LevelCmd.ts | 4 +- .../Utility/commands/MessageInfoCmd.ts | 4 +- .../plugins/Utility/commands/NicknameCmd.ts | 4 +- .../Utility/commands/NicknameResetCmd.ts | 4 +- .../src/plugins/Utility/commands/PingCmd.ts | 4 +- .../Utility/commands/ReloadGuildCmd.ts | 4 +- .../plugins/Utility/commands/RoleInfoCmd.ts | 3 +- .../src/plugins/Utility/commands/RolesCmd.ts | 8 +- .../src/plugins/Utility/commands/SearchCmd.ts | 2 +- .../plugins/Utility/commands/ServerInfoCmd.ts | 2 +- .../Utility/commands/SnowflakeInfoCmd.ts | 4 +- .../src/plugins/Utility/commands/SourceCmd.ts | 9 +- .../plugins/Utility/commands/UserInfoCmd.ts | 4 +- .../Utility/commands/VcdisconnectCmd.ts | 20 ++--- .../src/plugins/Utility/commands/VcmoveCmd.ts | 26 +++--- .../Utility/functions/getChannelInfoEmbed.ts | 12 +-- .../Utility/functions/getEmojiInfoEmbed.ts | 6 +- .../Utility/functions/getInviteInfoEmbed.ts | 35 ++++---- .../Utility/functions/getMessageInfoEmbed.ts | 14 +-- .../Utility/functions/getRoleInfoEmbed.ts | 10 +-- .../Utility/functions/getServerInfoEmbed.ts | 35 ++++---- .../functions/getSnowflakeInfoEmbed.ts | 21 ++--- .../Utility/functions/getUserInfoEmbed.ts | 23 ++--- backend/src/plugins/Utility/search.ts | 22 ++--- backend/src/plugins/Utility/types.ts | 6 +- .../WelcomeMessage/WelcomeMessagePlugin.ts | 4 +- .../events/SendWelcomeMessageEvt.ts | 8 +- backend/src/plugins/WelcomeMessage/types.ts | 2 +- .../src/plugins/ZeppelinPluginBlueprint.ts | 25 +++--- backend/src/plugins/availablePlugins.ts | 62 ++++++------- backend/src/templateFormatter.test.ts | 2 +- backend/src/templateFormatter.ts | 2 +- backend/src/types.ts | 2 +- backend/src/utils.test.ts | 4 +- backend/src/utils.ts | 74 ++++++++-------- backend/src/utils/canReadChannel.ts | 4 +- backend/src/utils/createPaginatedMessage.ts | 15 ++-- backend/src/utils/crypt.test.ts | 2 +- backend/src/utils/crypt.ts | 2 +- .../src/utils/getMissingChannelPermissions.ts | 2 +- backend/src/utils/getMissingPermissions.ts | 2 +- backend/src/utils/parseFuzzyTimezone.ts | 2 +- backend/src/utils/resolveMessageTarget.ts | 6 +- .../utils/safeFindRelevantAuditLogEntry.ts | 2 +- backend/src/utils/sendDM.ts | 6 +- backend/src/utils/tColor.ts | 5 +- backend/src/utils/tValidTimezone.ts | 2 +- backend/src/utils/waitForInteraction.ts | 13 ++- backend/src/validation.test.ts | 6 +- backend/src/validatorUtils.ts | 9 +- backend/src/yamlParseTest.ts | 2 +- 437 files changed, 1912 insertions(+), 2027 deletions(-) diff --git a/backend/src/RegExpRunner.ts b/backend/src/RegExpRunner.ts index d66df414..96d39be3 100644 --- a/backend/src/RegExpRunner.ts +++ b/backend/src/RegExpRunner.ts @@ -1,7 +1,7 @@ -import { RegExpWorker, TimeoutError } from "regexp-worker"; -import { CooldownManager } from "knub"; -import { MINUTES, SECONDS } from "./utils"; import { EventEmitter } from "events"; +import { CooldownManager } from "knub"; +import { RegExpWorker, TimeoutError } from "regexp-worker"; +import { MINUTES, SECONDS } from "./utils"; import Timeout = NodeJS.Timeout; const isTimeoutError = (a): a is TimeoutError => { diff --git a/backend/src/api/archives.ts b/backend/src/api/archives.ts index b1330a98..3c1ae702 100644 --- a/backend/src/api/archives.ts +++ b/backend/src/api/archives.ts @@ -1,7 +1,7 @@ import express, { Request, Response } from "express"; +import moment from "moment-timezone"; import { GuildArchives } from "../data/GuildArchives"; import { notFound } from "./responses"; -import moment from "moment-timezone"; export function initArchives(app: express.Express) { const archives = new GuildArchives(null); diff --git a/backend/src/api/auth.ts b/backend/src/api/auth.ts index 2a5d3445..c891ac63 100644 --- a/backend/src/api/auth.ts +++ b/backend/src/api/auth.ts @@ -1,13 +1,13 @@ import express, { Request, Response } from "express"; -import passport from "passport"; -import OAuth2Strategy from "passport-oauth2"; -import { Strategy as CustomStrategy } from "passport-custom"; -import { ApiLogins } from "../data/ApiLogins"; -import pick from "lodash.pick"; import https from "https"; +import pick from "lodash.pick"; +import passport from "passport"; +import { Strategy as CustomStrategy } from "passport-custom"; +import OAuth2Strategy from "passport-oauth2"; +import { ApiLogins } from "../data/ApiLogins"; +import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; import { ApiUserInfo } from "../data/ApiUserInfo"; import { ApiUserInfoData } from "../data/entities/ApiUserInfo"; -import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; import { ok } from "./responses"; interface IPassportApiUser { diff --git a/backend/src/api/docs.ts b/backend/src/api/docs.ts index 22a70fa0..3009a4e1 100644 --- a/backend/src/api/docs.ts +++ b/backend/src/api/docs.ts @@ -1,7 +1,7 @@ import express from "express"; import { guildPlugins } from "../plugins/availablePlugins"; -import { notFound } from "./responses"; import { indentLines } from "../utils"; +import { notFound } from "./responses"; function formatConfigSchema(schema) { if (schema._tag === "InterfaceType" || schema._tag === "PartialType") { diff --git a/backend/src/api/guilds.ts b/backend/src/api/guilds.ts index 213dcb44..8969b29c 100644 --- a/backend/src/api/guilds.ts +++ b/backend/src/api/guilds.ts @@ -1,13 +1,13 @@ -import express, { Request, Response } from "express"; -import { AllowedGuilds } from "../data/AllowedGuilds"; -import { clientError, ok, serverError, unauthorized } from "./responses"; -import { Configs } from "../data/Configs"; -import { validateGuildConfig } from "../configValidator"; -import yaml, { YAMLException } from "js-yaml"; -import { apiTokenAuthHandlers } from "./auth"; import { ApiPermissions } from "@shared/apiPermissions"; -import { hasGuildPermission, requireGuildPermission } from "./permissions"; +import express, { Request, Response } from "express"; +import yaml, { YAMLException } from "js-yaml"; +import { validateGuildConfig } from "../configValidator"; +import { AllowedGuilds } from "../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; +import { Configs } from "../data/Configs"; +import { apiTokenAuthHandlers } from "./auth"; +import { hasGuildPermission, requireGuildPermission } from "./permissions"; +import { clientError, ok, serverError, unauthorized } from "./responses"; const apiPermissionAssignments = new ApiPermissionAssignments(); diff --git a/backend/src/api/index.ts b/backend/src/api/index.ts index 7579c34e..671f6c8b 100644 --- a/backend/src/api/index.ts +++ b/backend/src/api/index.ts @@ -1,8 +1,7 @@ +import { connect } from "../data/db"; +import { setIsAPI } from "../globals"; import "./loadEnv"; -import { connect } from "../data/db"; -import path from "path"; -import { setIsAPI } from "../globals"; if (!process.env.KEY) { // tslint:disable-next-line:no-console diff --git a/backend/src/api/permissions.ts b/backend/src/api/permissions.ts index 7433734a..9552aaf4 100644 --- a/backend/src/api/permissions.ts +++ b/backend/src/api/permissions.ts @@ -1,7 +1,7 @@ import { ApiPermissions, hasPermission, permissionArrToSet } from "@shared/apiPermissions"; -import { isStaff } from "../staff"; -import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; import { Request, Response } from "express"; +import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; +import { isStaff } from "../staff"; import { unauthorized } from "./responses"; const apiPermissionAssignments = new ApiPermissionAssignments(); diff --git a/backend/src/api/staff.ts b/backend/src/api/staff.ts index 82109735..08f0dc09 100644 --- a/backend/src/api/staff.ts +++ b/backend/src/api/staff.ts @@ -1,6 +1,6 @@ import express, { Request, Response } from "express"; -import { apiTokenAuthHandlers } from "./auth"; import { isStaff } from "../staff"; +import { apiTokenAuthHandlers } from "./auth"; export function initStaff(app: express.Express) { const staffRouter = express.Router(); diff --git a/backend/src/api/start.ts b/backend/src/api/start.ts index 0932edd4..2e3e2c7d 100644 --- a/backend/src/api/start.ts +++ b/backend/src/api/start.ts @@ -1,11 +1,11 @@ -import { clientError, error, notFound } from "./responses"; -import express from "express"; import cors from "cors"; -import { initAuth } from "./auth"; -import { initGuildsAPI } from "./guilds"; -import { initArchives } from "./archives"; -import { initDocs } from "./docs"; +import express from "express"; import { TokenError } from "passport-oauth2"; +import { initArchives } from "./archives"; +import { initAuth } from "./auth"; +import { initDocs } from "./docs"; +import { initGuildsAPI } from "./guilds"; +import { clientError, error, notFound } from "./responses"; const app = express(); diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index 647dde5c..4790dc68 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -1,21 +1,21 @@ -import { - channelMentionRegex, - convertDelayStringToMS, - disableCodeBlocks, - disableInlineCode, - isValidSnowflake, - resolveMember, - resolveUser, - resolveUserId, - roleMentionRegex, - UnknownUser, -} from "./utils"; -import { baseTypeConverters, baseCommandParameterTypeHelpers, CommandContext, TypeConversionError } from "knub"; +import { GuildChannel, GuildMember, User } from "discord.js"; +import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub"; import { createTypeHelper } from "knub-command-manager"; +import { + channelMentionRegex, + convertDelayStringToMS, + disableCodeBlocks, + disableInlineCode, + isValidSnowflake, + resolveMember, + resolveUser, + resolveUserId, + roleMentionRegex, + UnknownUser +} from "./utils"; +import { isValidTimezone } from "./utils/isValidTimezone"; import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget"; import { inputPatternToRegExp } from "./validatorUtils"; -import { isValidTimezone } from "./utils/isValidTimezone"; -import { GuildChannel, GuildMember, User } from "discord.js"; export const commandTypes = { ...baseTypeConverters, diff --git a/backend/src/configValidator.ts b/backend/src/configValidator.ts index 9ea4e804..0c45c611 100644 --- a/backend/src/configValidator.ts +++ b/backend/src/configValidator.ts @@ -1,10 +1,9 @@ -import * as t from "io-ts"; -import { guildPlugins } from "./plugins/availablePlugins"; -import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; -import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; -import { PartialZeppelinGuildConfigSchema, ZeppelinGuildConfig } from "./types"; import { configUtils, ConfigValidationError, PluginOptions } from "knub"; import moment from "moment-timezone"; +import { guildPlugins } from "./plugins/availablePlugins"; +import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; +import { PartialZeppelinGuildConfigSchema, ZeppelinGuildConfig } from "./types"; +import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; const pluginNameToPlugin = new Map(); for (const plugin of guildPlugins) { diff --git a/backend/src/data/AllowedGuilds.ts b/backend/src/data/AllowedGuilds.ts index 0efe9770..e3399fea 100644 --- a/backend/src/data/AllowedGuilds.ts +++ b/backend/src/data/AllowedGuilds.ts @@ -1,7 +1,7 @@ -import { AllowedGuild } from "./entities/AllowedGuild"; import { getRepository, Repository } from "typeorm"; -import { BaseRepository } from "./BaseRepository"; import { ApiPermissionTypes } from "./ApiPermissionAssignments"; +import { BaseRepository } from "./BaseRepository"; +import { AllowedGuild } from "./entities/AllowedGuild"; export class AllowedGuilds extends BaseRepository { private allowedGuilds: Repository; diff --git a/backend/src/data/ApiLogins.ts b/backend/src/data/ApiLogins.ts index 645fcd47..23bb7e49 100644 --- a/backend/src/data/ApiLogins.ts +++ b/backend/src/data/ApiLogins.ts @@ -1,11 +1,11 @@ -import { getRepository, Repository } from "typeorm"; -import { ApiLogin } from "./entities/ApiLogin"; -import { BaseRepository } from "./BaseRepository"; import crypto from "crypto"; import moment from "moment-timezone"; +import { getRepository, Repository } from "typeorm"; // tslint:disable-next-line:no-submodule-imports import uuidv4 from "uuid/v4"; import { DAYS, DBDateFormat } from "../utils"; +import { BaseRepository } from "./BaseRepository"; +import { ApiLogin } from "./entities/ApiLogin"; const LOGIN_EXPIRY_TIME = 1 * DAYS; diff --git a/backend/src/data/ApiPermissionAssignments.ts b/backend/src/data/ApiPermissionAssignments.ts index dbcc0e26..29686adc 100644 --- a/backend/src/data/ApiPermissionAssignments.ts +++ b/backend/src/data/ApiPermissionAssignments.ts @@ -1,7 +1,7 @@ -import { getRepository, Repository } from "typeorm"; -import { ApiPermissionAssignment } from "./entities/ApiPermissionAssignment"; -import { BaseRepository } from "./BaseRepository"; import { ApiPermissions } from "@shared/apiPermissions"; +import { getRepository, Repository } from "typeorm"; +import { BaseRepository } from "./BaseRepository"; +import { ApiPermissionAssignment } from "./entities/ApiPermissionAssignment"; export enum ApiPermissionTypes { User = "USER", diff --git a/backend/src/data/ApiUserInfo.ts b/backend/src/data/ApiUserInfo.ts index 09d9df75..73633d01 100644 --- a/backend/src/data/ApiUserInfo.ts +++ b/backend/src/data/ApiUserInfo.ts @@ -1,9 +1,9 @@ +import moment from "moment-timezone"; import { getRepository, Repository } from "typeorm"; -import { ApiUserInfo as ApiUserInfoEntity, ApiUserInfoData } from "./entities/ApiUserInfo"; +import { DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; import { connection } from "./db"; -import moment from "moment-timezone"; -import { DBDateFormat } from "../utils"; +import { ApiUserInfo as ApiUserInfoEntity, ApiUserInfoData } from "./entities/ApiUserInfo"; export class ApiUserInfo extends BaseRepository { private apiUserInfo: Repository; diff --git a/backend/src/data/Configs.ts b/backend/src/data/Configs.ts index 054ce255..3e0882f0 100644 --- a/backend/src/data/Configs.ts +++ b/backend/src/data/Configs.ts @@ -1,10 +1,10 @@ -import { Config } from "./entities/Config"; import { getRepository, Repository } from "typeorm"; -import { connection } from "./db"; -import { BaseRepository } from "./BaseRepository"; import { isAPI } from "../globals"; import { HOURS, SECONDS } from "../utils"; +import { BaseRepository } from "./BaseRepository"; import { cleanupConfigs } from "./cleanup/configs"; +import { connection } from "./db"; +import { Config } from "./entities/Config"; if (isAPI()) { const CLEANUP_INTERVAL = 1 * HOURS; diff --git a/backend/src/data/GuildAntiraidLevels.ts b/backend/src/data/GuildAntiraidLevels.ts index 7f1321c1..5775bc91 100644 --- a/backend/src/data/GuildAntiraidLevels.ts +++ b/backend/src/data/GuildAntiraidLevels.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { AntiraidLevel } from "./entities/AntiraidLevel"; export class GuildAntiraidLevels extends BaseGuildRepository { diff --git a/backend/src/data/GuildArchives.ts b/backend/src/data/GuildArchives.ts index 9c1ea69c..e99d8835 100644 --- a/backend/src/data/GuildArchives.ts +++ b/backend/src/data/GuildArchives.ts @@ -1,11 +1,11 @@ -import moment from "moment-timezone"; -import { ArchiveEntry } from "./entities/ArchiveEntry"; -import { getRepository, Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { trimLines } from "../utils"; -import { SavedMessage } from "./entities/SavedMessage"; -import { renderTemplate } from "../templateFormatter"; import { Guild } from "discord.js"; +import moment from "moment-timezone"; +import { getRepository, Repository } from "typeorm"; +import { renderTemplate } from "../templateFormatter"; +import { trimLines } from "../utils"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { ArchiveEntry } from "./entities/ArchiveEntry"; +import { SavedMessage } from "./entities/SavedMessage"; const DEFAULT_EXPIRY_DAYS = 30; diff --git a/backend/src/data/GuildAutoReactions.ts b/backend/src/data/GuildAutoReactions.ts index 094a1a4a..27fd737d 100644 --- a/backend/src/data/GuildAutoReactions.ts +++ b/backend/src/data/GuildAutoReactions.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { AutoReaction } from "./entities/AutoReaction"; export class GuildAutoReactions extends BaseGuildRepository { diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index 67a1ad41..349b1ce1 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -1,11 +1,10 @@ +import { getRepository, In, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { CaseTypes } from "./CaseTypes"; +import { connection } from "./db"; import { Case } from "./entities/Case"; import { CaseNote } from "./entities/CaseNote"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { getRepository, In, Repository } from "typeorm"; -import { DBDateFormat, disableLinkPreviews } from "../utils"; -import { CaseTypes } from "./CaseTypes"; import moment = require("moment-timezone"); -import { connection } from "./db"; const CASE_SUMMARY_REASON_MAX_LENGTH = 300; diff --git a/backend/src/data/GuildCounters.ts b/backend/src/data/GuildCounters.ts index 4a64aaea..8daf0b7c 100644 --- a/backend/src/data/GuildCounters.ts +++ b/backend/src/data/GuildCounters.ts @@ -1,18 +1,18 @@ +import moment from "moment-timezone"; +import { FindConditions, getRepository, In, IsNull, Not, Repository } from "typeorm"; +import { Queue } from "../Queue"; +import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; -import { FindConditions, getRepository, In, IsNull, LessThan, Not, Repository } from "typeorm"; +import { connection } from "./db"; import { Counter } from "./entities/Counter"; -import { CounterValue } from "./entities/CounterValue"; import { - CounterTrigger, - isValidCounterComparisonOp, - TRIGGER_COMPARISON_OPS, - TriggerComparisonOp, + CounterTrigger, + isValidCounterComparisonOp, + + TriggerComparisonOp } from "./entities/CounterTrigger"; import { CounterTriggerState } from "./entities/CounterTriggerState"; -import moment from "moment-timezone"; -import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils"; -import { connection } from "./db"; -import { Queue } from "../Queue"; +import { CounterValue } from "./entities/CounterValue"; const DELETE_UNUSED_COUNTERS_AFTER = 1 * DAYS; const DELETE_UNUSED_COUNTER_TRIGGERS_AFTER = 1 * DAYS; diff --git a/backend/src/data/GuildEvents.ts b/backend/src/data/GuildEvents.ts index 3a2b6489..ead809ab 100644 --- a/backend/src/data/GuildEvents.ts +++ b/backend/src/data/GuildEvents.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { QueuedEventEmitter } from "../QueuedEventEmitter"; +import { BaseGuildRepository } from "./BaseGuildRepository"; export class GuildEvents extends BaseGuildRepository { private queuedEventEmitter: QueuedEventEmitter; diff --git a/backend/src/data/GuildMemberTimezones.ts b/backend/src/data/GuildMemberTimezones.ts index 9e1a1b68..6c4ef82b 100644 --- a/backend/src/data/GuildMemberTimezones.ts +++ b/backend/src/data/GuildMemberTimezones.ts @@ -1,7 +1,7 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { MemberTimezone } from "./entities/MemberTimezone"; import { getRepository, Repository } from "typeorm/index"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { connection } from "./db"; +import { MemberTimezone } from "./entities/MemberTimezone"; export class GuildMemberTimezones extends BaseGuildRepository { protected memberTimezones: Repository; diff --git a/backend/src/data/GuildMutes.ts b/backend/src/data/GuildMutes.ts index 93fcfdc5..35f86fc0 100644 --- a/backend/src/data/GuildMutes.ts +++ b/backend/src/data/GuildMutes.ts @@ -1,7 +1,7 @@ import moment from "moment-timezone"; -import { Mute } from "./entities/Mute"; -import { BaseGuildRepository } from "./BaseGuildRepository"; import { Brackets, getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { Mute } from "./entities/Mute"; export class GuildMutes extends BaseGuildRepository { private mutes: Repository; diff --git a/backend/src/data/GuildNicknameHistory.ts b/backend/src/data/GuildNicknameHistory.ts index 60f8f419..51ed863c 100644 --- a/backend/src/data/GuildNicknameHistory.ts +++ b/backend/src/data/GuildNicknameHistory.ts @@ -1,9 +1,9 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, In, Repository } from "typeorm"; -import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry"; -import { MINUTES, SECONDS } from "../utils"; import { isAPI } from "../globals"; +import { MINUTES, SECONDS } from "../utils"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { cleanupNicknames } from "./cleanup/nicknames"; +import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry"; if (!isAPI()) { const CLEANUP_INTERVAL = 5 * MINUTES; diff --git a/backend/src/data/GuildPersistedData.ts b/backend/src/data/GuildPersistedData.ts index 2120916b..4dd8cffd 100644 --- a/backend/src/data/GuildPersistedData.ts +++ b/backend/src/data/GuildPersistedData.ts @@ -1,6 +1,6 @@ -import { PersistedData } from "./entities/PersistedData"; -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { PersistedData } from "./entities/PersistedData"; export interface IPartialPersistData { roles?: string[]; diff --git a/backend/src/data/GuildPingableRoles.ts b/backend/src/data/GuildPingableRoles.ts index fa3eda28..c8fd6f05 100644 --- a/backend/src/data/GuildPingableRoles.ts +++ b/backend/src/data/GuildPingableRoles.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { PingableRole } from "./entities/PingableRole"; export class GuildPingableRoles extends BaseGuildRepository { diff --git a/backend/src/data/GuildReactionRoles.ts b/backend/src/data/GuildReactionRoles.ts index d724493f..a3d7e30b 100644 --- a/backend/src/data/GuildReactionRoles.ts +++ b/backend/src/data/GuildReactionRoles.ts @@ -1,6 +1,6 @@ -import { ReactionRole } from "./entities/ReactionRole"; -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { ReactionRole } from "./entities/ReactionRole"; export class GuildReactionRoles extends BaseGuildRepository { private reactionRoles: Repository; diff --git a/backend/src/data/GuildReminders.ts b/backend/src/data/GuildReminders.ts index b370b465..b665569f 100644 --- a/backend/src/data/GuildReminders.ts +++ b/backend/src/data/GuildReminders.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { Reminder } from "./entities/Reminder"; export class GuildReminders extends BaseGuildRepository { diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index 423767ae..b80fae0f 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -1,12 +1,12 @@ -import { getRepository, Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage"; -import { QueuedEventEmitter } from "../QueuedEventEmitter"; -import moment from "moment-timezone"; -import { MINUTES, SECONDS } from "../utils"; -import { isAPI } from "../globals"; -import { cleanupMessages } from "./cleanup/messages"; import { GuildChannel, Message } from "discord.js"; +import moment from "moment-timezone"; +import { getRepository, Repository } from "typeorm"; +import { isAPI } from "../globals"; +import { QueuedEventEmitter } from "../QueuedEventEmitter"; +import { MINUTES, SECONDS } from "../utils"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { cleanupMessages } from "./cleanup/messages"; +import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage"; if (!isAPI()) { const CLEANUP_INTERVAL = 5 * MINUTES; diff --git a/backend/src/data/GuildScheduledPosts.ts b/backend/src/data/GuildScheduledPosts.ts index af621434..c302b81e 100644 --- a/backend/src/data/GuildScheduledPosts.ts +++ b/backend/src/data/GuildScheduledPosts.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { ScheduledPost } from "./entities/ScheduledPost"; export class GuildScheduledPosts extends BaseGuildRepository { diff --git a/backend/src/data/GuildSlowmodes.ts b/backend/src/data/GuildSlowmodes.ts index 9e4281db..b6452490 100644 --- a/backend/src/data/GuildSlowmodes.ts +++ b/backend/src/data/GuildSlowmodes.ts @@ -1,8 +1,8 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; +import moment from "moment-timezone"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { SlowmodeChannel } from "./entities/SlowmodeChannel"; import { SlowmodeUser } from "./entities/SlowmodeUser"; -import moment from "moment-timezone"; export class GuildSlowmodes extends BaseGuildRepository { private slowmodeChannels: Repository; diff --git a/backend/src/data/GuildStarboardMessages.ts b/backend/src/data/GuildStarboardMessages.ts index c01bb8dc..0e932928 100644 --- a/backend/src/data/GuildStarboardMessages.ts +++ b/backend/src/data/GuildStarboardMessages.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { StarboardMessage } from "./entities/StarboardMessage"; export class GuildStarboardMessages extends BaseGuildRepository { diff --git a/backend/src/data/GuildStarboardReactions.ts b/backend/src/data/GuildStarboardReactions.ts index 5094491e..413b7120 100644 --- a/backend/src/data/GuildStarboardReactions.ts +++ b/backend/src/data/GuildStarboardReactions.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { StarboardReaction } from "./entities/StarboardReaction"; export class GuildStarboardReactions extends BaseGuildRepository { diff --git a/backend/src/data/GuildStats.ts b/backend/src/data/GuildStats.ts index a0ca75a6..d70623dd 100644 --- a/backend/src/data/GuildStats.ts +++ b/backend/src/data/GuildStats.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { StatValue } from "./entities/StatValue"; export class GuildStats extends BaseGuildRepository { diff --git a/backend/src/data/GuildTags.ts b/backend/src/data/GuildTags.ts index 385bfd80..76206164 100644 --- a/backend/src/data/GuildTags.ts +++ b/backend/src/data/GuildTags.ts @@ -1,6 +1,6 @@ -import { Tag } from "./entities/Tag"; import { getRepository, Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { Tag } from "./entities/Tag"; import { TagResponse } from "./entities/TagResponse"; export class GuildTags extends BaseGuildRepository { diff --git a/backend/src/data/GuildTempbans.ts b/backend/src/data/GuildTempbans.ts index 76e126c5..f5f52143 100644 --- a/backend/src/data/GuildTempbans.ts +++ b/backend/src/data/GuildTempbans.ts @@ -1,7 +1,6 @@ import moment from "moment-timezone"; -import { Mute } from "./entities/Mute"; +import { getRepository, Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; -import { Brackets, getRepository, Repository } from "typeorm"; import { Tempban } from "./entities/Tempban"; export class GuildTempbans extends BaseGuildRepository { diff --git a/backend/src/data/GuildVCAlerts.ts b/backend/src/data/GuildVCAlerts.ts index 6acc35e9..4c64c197 100644 --- a/backend/src/data/GuildVCAlerts.ts +++ b/backend/src/data/GuildVCAlerts.ts @@ -1,5 +1,5 @@ -import { BaseGuildRepository } from "./BaseGuildRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; import { VCAlert } from "./entities/VCAlert"; export class GuildVCAlerts extends BaseGuildRepository { diff --git a/backend/src/data/Supporters.ts b/backend/src/data/Supporters.ts index 26c294c7..58b1b2d3 100644 --- a/backend/src/data/Supporters.ts +++ b/backend/src/data/Supporters.ts @@ -1,5 +1,5 @@ -import { BaseRepository } from "./BaseRepository"; import { getRepository, Repository } from "typeorm"; +import { BaseRepository } from "./BaseRepository"; import { Supporter } from "./entities/Supporter"; export class Supporters extends BaseRepository { diff --git a/backend/src/data/UsernameHistory.ts b/backend/src/data/UsernameHistory.ts index bcc5647a..c17a747c 100644 --- a/backend/src/data/UsernameHistory.ts +++ b/backend/src/data/UsernameHistory.ts @@ -1,9 +1,9 @@ import { getRepository, In, Repository } from "typeorm"; -import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry"; +import { isAPI } from "../globals"; import { MINUTES, SECONDS } from "../utils"; import { BaseRepository } from "./BaseRepository"; -import { isAPI } from "../globals"; import { cleanupUsernames } from "./cleanup/usernames"; +import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry"; if (!isAPI()) { const CLEANUP_INTERVAL = 5 * MINUTES; diff --git a/backend/src/data/cleanup/configs.ts b/backend/src/data/cleanup/configs.ts index 04c76044..252b6c6d 100644 --- a/backend/src/data/cleanup/configs.ts +++ b/backend/src/data/cleanup/configs.ts @@ -1,8 +1,8 @@ -import { connection } from "../db"; -import { getRepository, In } from "typeorm"; -import { Config } from "../entities/Config"; import moment from "moment-timezone"; +import { getRepository, In } from "typeorm"; import { DBDateFormat } from "../../utils"; +import { connection } from "../db"; +import { Config } from "../entities/Config"; const CLEAN_PER_LOOP = 50; diff --git a/backend/src/data/cleanup/messages.ts b/backend/src/data/cleanup/messages.ts index 1b9f8427..06d55c99 100644 --- a/backend/src/data/cleanup/messages.ts +++ b/backend/src/data/cleanup/messages.ts @@ -1,8 +1,8 @@ -import { DAYS, DBDateFormat, MINUTES } from "../../utils"; -import { getRepository, In } from "typeorm"; -import { SavedMessage } from "../entities/SavedMessage"; import moment from "moment-timezone"; +import { getRepository, In } from "typeorm"; +import { DAYS, DBDateFormat, MINUTES } from "../../utils"; import { connection } from "../db"; +import { SavedMessage } from "../entities/SavedMessage"; /** * How long message edits, deletions, etc. will include the original message content. diff --git a/backend/src/data/cleanup/nicknames.ts b/backend/src/data/cleanup/nicknames.ts index e48b2670..4907e004 100644 --- a/backend/src/data/cleanup/nicknames.ts +++ b/backend/src/data/cleanup/nicknames.ts @@ -1,8 +1,8 @@ -import { getRepository, In } from "typeorm"; import moment from "moment-timezone"; -import { NicknameHistoryEntry } from "../entities/NicknameHistoryEntry"; +import { getRepository, In } from "typeorm"; import { DAYS, DBDateFormat } from "../../utils"; import { connection } from "../db"; +import { NicknameHistoryEntry } from "../entities/NicknameHistoryEntry"; export const NICKNAME_RETENTION_PERIOD = 30 * DAYS; const CLEAN_PER_LOOP = 500; diff --git a/backend/src/data/cleanup/usernames.ts b/backend/src/data/cleanup/usernames.ts index 6bcca3d2..eea441d5 100644 --- a/backend/src/data/cleanup/usernames.ts +++ b/backend/src/data/cleanup/usernames.ts @@ -1,8 +1,8 @@ -import { getRepository, In } from "typeorm"; import moment from "moment-timezone"; -import { UsernameHistoryEntry } from "../entities/UsernameHistoryEntry"; +import { getRepository, In } from "typeorm"; import { DAYS, DBDateFormat } from "../../utils"; import { connection } from "../db"; +import { UsernameHistoryEntry } from "../entities/UsernameHistoryEntry"; export const USERNAME_RETENTION_PERIOD = 30 * DAYS; const CLEAN_PER_LOOP = 500; diff --git a/backend/src/data/db.ts b/backend/src/data/db.ts index 30383b14..9888d0b5 100644 --- a/backend/src/data/db.ts +++ b/backend/src/data/db.ts @@ -1,5 +1,5 @@ -import { SimpleError } from "../SimpleError"; import { Connection, createConnection } from "typeorm"; +import { SimpleError } from "../SimpleError"; let connectionPromise: Promise; diff --git a/backend/src/data/encryptedJsonTransformer.ts b/backend/src/data/encryptedJsonTransformer.ts index 01b6080c..38272ebc 100644 --- a/backend/src/data/encryptedJsonTransformer.ts +++ b/backend/src/data/encryptedJsonTransformer.ts @@ -1,5 +1,5 @@ -import { decrypt, encrypt } from "../utils/crypt"; import { ValueTransformer } from "typeorm"; +import { decrypt, encrypt } from "../utils/crypt"; interface EncryptedJsonTransformer extends ValueTransformer { from(dbValue: any): T; diff --git a/backend/src/data/encryptedTextTransformer.ts b/backend/src/data/encryptedTextTransformer.ts index 353c5d72..7d0432ae 100644 --- a/backend/src/data/encryptedTextTransformer.ts +++ b/backend/src/data/encryptedTextTransformer.ts @@ -1,5 +1,5 @@ -import { decrypt, encrypt } from "../utils/crypt"; import { ValueTransformer } from "typeorm"; +import { decrypt, encrypt } from "../utils/crypt"; interface EncryptedTextTransformer extends ValueTransformer { from(dbValue: any): string; diff --git a/backend/src/data/getChannelIdFromMessageId.ts b/backend/src/data/getChannelIdFromMessageId.ts index 64fc3b85..0558ee69 100644 --- a/backend/src/data/getChannelIdFromMessageId.ts +++ b/backend/src/data/getChannelIdFromMessageId.ts @@ -1,5 +1,5 @@ +import { getRepository, Repository } from "typeorm"; import { SavedMessage } from "./entities/SavedMessage"; -import { Repository, getRepository } from "typeorm"; let repository: Repository; diff --git a/backend/src/index.ts b/backend/src/index.ts index 6cb6fbea..42ee9343 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,29 +1,28 @@ -import "./loadEnv"; - -import path from "path"; -import yaml from "js-yaml"; - +import { Client, Intents, TextChannel } from "discord.js"; import fs from "fs"; +import yaml from "js-yaml"; import { Knub, PluginError } from "knub"; -import { SimpleError } from "./SimpleError"; - -import { Configs } from "./data/Configs"; +import { PluginLoadError } from "knub/dist/plugins/PluginLoadError"; // Always use UTC internally // This is also enforced for the database in data/db.ts import moment from "moment-timezone"; -import { connect } from "./data/db"; -import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availablePlugins"; -import { errorMessage, isDiscordHTTPError, isDiscordRESTError, MINUTES, successMessage } from "./utils"; -import { startUptimeCounter } from "./uptime"; import { AllowedGuilds } from "./data/AllowedGuilds"; -import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; -import { RecoverablePluginError } from "./RecoverablePluginError"; +import { Configs } from "./data/Configs"; +import { connect } from "./data/db"; import { GuildLogs } from "./data/GuildLogs"; import { LogType } from "./data/LogType"; -import { logger } from "./logger"; -import { PluginLoadError } from "knub/dist/plugins/PluginLoadError"; import { ErisError } from "./ErisError"; -import { Client, Intents, TextChannel } from "discord.js"; +import "./loadEnv"; +import { logger } from "./logger"; +import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availablePlugins"; +import { RecoverablePluginError } from "./RecoverablePluginError"; +import { SimpleError } from "./SimpleError"; +import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; +import { startUptimeCounter } from "./uptime"; +import { errorMessage, isDiscordHTTPError, isDiscordRESTError, successMessage } from "./utils"; + + + const fsp = fs.promises; diff --git a/backend/src/migrateConfigsToDB.ts b/backend/src/migrateConfigsToDB.ts index a814a63d..67423c41 100644 --- a/backend/src/migrateConfigsToDB.ts +++ b/backend/src/migrateConfigsToDB.ts @@ -1,8 +1,8 @@ // tslint:disable:no-console -import { connect } from "./data/db"; -import { Configs } from "./data/Configs"; -import path from "path"; import * as _fs from "fs"; +import path from "path"; +import { Configs } from "./data/Configs"; +import { connect } from "./data/db"; const fs = _fs.promises; diff --git a/backend/src/migrations/1608692857722-FixStarboardReactionsIndices.ts b/backend/src/migrations/1608692857722-FixStarboardReactionsIndices.ts index dcde8a09..d74a8749 100644 --- a/backend/src/migrations/1608692857722-FixStarboardReactionsIndices.ts +++ b/backend/src/migrations/1608692857722-FixStarboardReactionsIndices.ts @@ -1,4 +1,4 @@ -import { MigrationInterface, QueryRunner, TableIndex, TableUnique } from "typeorm"; +import { MigrationInterface, QueryRunner, TableIndex } from "typeorm"; export class FixStarboardReactionsIndices1608692857722 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index f0912677..bb0f607e 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -2,18 +2,18 @@ * @file Utility functions that are plugin-instance-specific (i.e. use PluginData) */ -import { CommandContext, configUtils, ConfigValidationError, GuildPluginData, helpers, PluginOptions } from "knub"; -import { decodeAndValidateStrict, StrictValidationError, validate } from "./validatorUtils"; -import { deepKeyIntersect, errorMessage, successMessage, tDeepPartial, tNullable } from "./utils"; -import { TZeppelinKnub } from "./types"; -import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; // TODO: Export from Knub index +import { GuildMember, Message, MessageMentionOptions, MessageOptions, TextChannel } from "discord.js"; import * as t from "io-ts"; +import { CommandContext, configUtils, ConfigValidationError, GuildPluginData, helpers, PluginOptions } from "knub"; import { PluginOverrideCriteria } from "knub/dist/config/configTypes"; -import { Tail } from "./utils/typeUtils"; +import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; // TODO: Export from Knub index import { AnyPluginData } from "knub/dist/plugins/PluginData"; -import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; import { logger } from "./logger"; -import { APIMessage, GuildMember, Message, MessageMentionOptions, MessageOptions, TextChannel, User } from "discord.js"; +import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; +import { TZeppelinKnub } from "./types"; +import { deepKeyIntersect, errorMessage, successMessage, tDeepPartial, tNullable } from "./utils"; +import { Tail } from "./utils/typeUtils"; +import { decodeAndValidateStrict, StrictValidationError, validate } from "./validatorUtils"; const { getMemberLevel } = helpers; diff --git a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts index 80973641..aa7ffd50 100644 --- a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts +++ b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts @@ -1,13 +1,13 @@ import { PluginOptions } from "knub"; -import { AutoDeletePluginType, ConfigSchema } from "./types"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { LogsPlugin } from "../Logs/LogsPlugin"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { AutoDeletePluginType, ConfigSchema } from "./types"; import { onMessageCreate } from "./util/onMessageCreate"; import { onMessageDelete } from "./util/onMessageDelete"; import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/AutoDelete/types.ts b/backend/src/plugins/AutoDelete/types.ts index 9cee0d3b..2294f222 100644 --- a/backend/src/plugins/AutoDelete/types.ts +++ b/backend/src/plugins/AutoDelete/types.ts @@ -1,9 +1,9 @@ import * as t from "io-ts"; -import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { tDelayString, MINUTES } from "../../utils"; +import { BasePluginType } from "knub"; +import { SavedMessage } from "../../data/entities/SavedMessage"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { SavedMessage } from "../../data/entities/SavedMessage"; +import { MINUTES, tDelayString } from "../../utils"; import Timeout = NodeJS.Timeout; export const MAX_DELAY = 5 * MINUTES; diff --git a/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts b/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts index 21788d58..7d37c003 100644 --- a/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts +++ b/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { AutoDeletePluginType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { scheduleNextDeletion } from "./scheduleNextDeletion"; import { sorter } from "../../../utils"; +import { AutoDeletePluginType } from "../types"; +import { scheduleNextDeletion } from "./scheduleNextDeletion"; export function addMessageToDeletionQueue( pluginData: GuildPluginData, diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts index 2ec8b598..553f828f 100644 --- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts +++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts @@ -1,14 +1,14 @@ +import { Permissions, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { AutoDeletePluginType } from "../types"; import moment from "moment-timezone"; import { LogType } from "../../../data/LogType"; -import { resolveUser, stripObjectToScalars, verboseChannelMention } from "../../../utils"; import { logger } from "../../../logger"; -import { scheduleNextDeletion } from "./scheduleNextDeletion"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { resolveUser, stripObjectToScalars, verboseChannelMention } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { Permissions, TextChannel } from "discord.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { AutoDeletePluginType } from "../types"; +import { scheduleNextDeletion } from "./scheduleNextDeletion"; export async function deleteNextItem(pluginData: GuildPluginData) { const [itemToDelete] = pluginData.state.deletionQueue.splice(0, 1); diff --git a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts index e6ee40e5..0a7bfc73 100644 --- a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts +++ b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts @@ -1,8 +1,8 @@ -import { AutoDeletePluginType, MAX_DELAY } from "../types"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { convertDelayStringToMS, resolveMember } from "../../../utils"; import { LogType } from "../../../data/LogType"; +import { convertDelayStringToMS, resolveMember } from "../../../utils"; +import { AutoDeletePluginType, MAX_DELAY } from "../types"; import { addMessageToDeletionQueue } from "./addMessageToDeletionQueue"; export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { diff --git a/backend/src/plugins/AutoDelete/util/onMessageDelete.ts b/backend/src/plugins/AutoDelete/util/onMessageDelete.ts index 98eb2816..48b7bb72 100644 --- a/backend/src/plugins/AutoDelete/util/onMessageDelete.ts +++ b/backend/src/plugins/AutoDelete/util/onMessageDelete.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { AutoDeletePluginType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { AutoDeletePluginType } from "../types"; import { scheduleNextDeletion } from "./scheduleNextDeletion"; export function onMessageDelete(pluginData: GuildPluginData, msg: SavedMessage) { diff --git a/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts b/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts index b48f8f89..6c39a667 100644 --- a/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts @@ -1,6 +1,6 @@ -import { AutoDeletePluginType } from "../types"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { AutoDeletePluginType } from "../types"; import { onMessageDelete } from "./onMessageDelete"; export function onMessageDeleteBulk(pluginData: GuildPluginData, messages: SavedMessage[]) { diff --git a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts index 2192a774..886a9922 100644 --- a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts +++ b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts @@ -1,13 +1,13 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { AutoReactionsPluginType, ConfigSchema } from "./types"; import { PluginOptions } from "knub"; -import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd"; -import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildAutoReactions } from "../../data/GuildAutoReactions"; -import { AddReactionsEvt } from "./events/AddReactionsEvt"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd"; +import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd"; +import { AddReactionsEvt } from "./events/AddReactionsEvt"; +import { AutoReactionsPluginType, ConfigSchema } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts index 5f2d82cf..56193797 100644 --- a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts @@ -1,6 +1,6 @@ -import { autoReactionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { autoReactionsCmd } from "../types"; export const DisableAutoReactionsCmd = autoReactionsCmd({ trigger: "auto_reactions disable", diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index f1fb64ff..8bb4dfe9 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -1,12 +1,12 @@ -import { autoReactionsCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; - -import { readChannelPermissions } from "../../../utils/readChannelPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; import { GuildChannel, Permissions } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; +import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { readChannelPermissions } from "../../../utils/readChannelPermissions"; +import { autoReactionsCmd } from "../types"; + const requiredPermissions = readChannelPermissions | Permissions.FLAGS.ADD_REACTIONS; diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index 06ca2bb2..330714fe 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -1,12 +1,12 @@ -import { autoReactionsEvt } from "../types"; -import { isDiscordRESTError } from "../../../utils"; -import { LogType } from "../../../data/LogType"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; - -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { readChannelPermissions } from "../../../utils/readChannelPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; import { GuildChannel, Permissions } from "discord.js"; +import { LogType } from "../../../data/LogType"; +import { isDiscordRESTError } from "../../../utils"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; +import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { readChannelPermissions } from "../../../utils/readChannelPermissions"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { autoReactionsEvt } from "../types"; + const p = Permissions.FLAGS; diff --git a/backend/src/plugins/AutoReactions/types.ts b/backend/src/plugins/AutoReactions/types.ts index 6a1fb285..a5c269c2 100644 --- a/backend/src/plugins/AutoReactions/types.ts +++ b/backend/src/plugins/AutoReactions/types.ts @@ -1,8 +1,8 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; +import { GuildAutoReactions } from "../../data/GuildAutoReactions"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildAutoReactions } from "../../data/GuildAutoReactions"; export const ConfigSchema = t.type({ can_manage: t.boolean, diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index fabdc806..d57df9ed 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -1,38 +1,35 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { AutomodPluginType, ConfigSchema } from "./types"; -import { RunAutomodOnJoinEvt } from "./events/RunAutomodOnJoinEvt"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { runAutomodOnMessage } from "./events/runAutomodOnMessage"; -import { Queue } from "../../Queue"; import { configUtils, CooldownManager } from "knub"; -import { availableTriggers } from "./triggers/availableTriggers"; -import { StrictValidationError } from "../../validatorUtils"; import { ConfigPreprocessorFn } from "knub/dist/config/configTypes"; -import { availableActions } from "./actions/availableActions"; -import { clearOldRecentActions } from "./functions/clearOldRecentActions"; -import { disableCodeBlocks, MINUTES, SECONDS } from "../../utils"; -import { clearOldRecentSpam } from "./functions/clearOldRecentSpam"; import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels"; import { GuildArchives } from "../../data/GuildArchives"; -import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChanges"; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { Queue } from "../../Queue"; +import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; +import { MINUTES, SECONDS } from "../../utils"; +import { registerEventListenersFromMap } from "../../utils/registerEventListenersFromMap"; +import { unregisterEventListenersFromMap } from "../../utils/unregisterEventListenersFromMap"; +import { StrictValidationError } from "../../validatorUtils"; +import { CountersPlugin } from "../Counters/CountersPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; import { MutesPlugin } from "../Mutes/MutesPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { availableActions } from "./actions/availableActions"; import { AntiraidClearCmd } from "./commands/AntiraidClearCmd"; import { SetAntiraidCmd } from "./commands/SetAntiraidCmd"; import { ViewAntiraidCmd } from "./commands/ViewAntiraidCmd"; -import { pluginInfo } from "./info"; -import { RegExpRunner } from "../../RegExpRunner"; -import { LogType } from "../../data/LogType"; -import { logger } from "../../logger"; -import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { RunAutomodOnMemberUpdate } from "./events/RunAutomodOnMemberUpdate"; -import { CountersPlugin } from "../Counters/CountersPlugin"; import { runAutomodOnCounterTrigger } from "./events/runAutomodOnCounterTrigger"; +import { RunAutomodOnJoinEvt } from "./events/RunAutomodOnJoinEvt"; +import { RunAutomodOnMemberUpdate } from "./events/RunAutomodOnMemberUpdate"; +import { runAutomodOnMessage } from "./events/runAutomodOnMessage"; import { runAutomodOnModAction } from "./events/runAutomodOnModAction"; -import { registerEventListenersFromMap } from "../../utils/registerEventListenersFromMap"; -import { unregisterEventListenersFromMap } from "../../utils/unregisterEventListenersFromMap"; +import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChanges"; +import { clearOldRecentActions } from "./functions/clearOldRecentActions"; +import { clearOldRecentSpam } from "./functions/clearOldRecentSpam"; +import { pluginInfo } from "./info"; +import { availableTriggers } from "./triggers/availableTriggers"; +import { AutomodPluginType, ConfigSchema } from "./types"; const defaultOptions = { config: { diff --git a/backend/src/plugins/Automod/actions/addToCounter.ts b/backend/src/plugins/Automod/actions/addToCounter.ts index 7606f91d..74e1ddc5 100644 --- a/backend/src/plugins/Automod/actions/addToCounter.ts +++ b/backend/src/plugins/Automod/actions/addToCounter.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { CountersPlugin } from "../../Counters/CountersPlugin"; import { LogType } from "../../../data/LogType"; +import { CountersPlugin } from "../../Counters/CountersPlugin"; +import { automodAction } from "../helpers"; export const AddToCounterAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/actions/alert.ts b/backend/src/plugins/Automod/actions/alert.ts index 7b932639..b7c4a000 100644 --- a/backend/src/plugins/Automod/actions/alert.ts +++ b/backend/src/plugins/Automod/actions/alert.ts @@ -1,18 +1,18 @@ -import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { LogType } from "../../../data/LogType"; -import { - createChunkedMessage, - messageLink, - stripObjectToScalars, - tAllowedMentions, - tNormalizedNullOptional, - verboseChannelMention, -} from "../../../utils"; -import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TextChannel } from "discord.js"; +import * as t from "io-ts"; import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; +import { LogType } from "../../../data/LogType"; +import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; +import { + createChunkedMessage, + messageLink, + stripObjectToScalars, + tAllowedMentions, + tNormalizedNullOptional, + verboseChannelMention +} from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { automodAction } from "../helpers"; export const AlertAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/actions/availableActions.ts b/backend/src/plugins/Automod/actions/availableActions.ts index 54146de3..fbdcf8f9 100644 --- a/backend/src/plugins/Automod/actions/availableActions.ts +++ b/backend/src/plugins/Automod/actions/availableActions.ts @@ -1,20 +1,20 @@ import * as t from "io-ts"; -import { CleanAction } from "./clean"; import { AutomodActionBlueprint } from "../helpers"; -import { WarnAction } from "./warn"; -import { MuteAction } from "./mute"; -import { KickAction } from "./kick"; -import { BanAction } from "./ban"; -import { AlertAction } from "./alert"; -import { ChangeNicknameAction } from "./changeNickname"; -import { LogAction } from "./log"; import { AddRolesAction } from "./addRoles"; -import { RemoveRolesAction } from "./removeRoles"; -import { SetAntiraidLevelAction } from "./setAntiraidLevel"; -import { ReplyAction } from "./reply"; import { AddToCounterAction } from "./addToCounter"; +import { AlertAction } from "./alert"; +import { BanAction } from "./ban"; +import { ChangeNicknameAction } from "./changeNickname"; +import { CleanAction } from "./clean"; +import { KickAction } from "./kick"; +import { LogAction } from "./log"; +import { MuteAction } from "./mute"; +import { RemoveRolesAction } from "./removeRoles"; +import { ReplyAction } from "./reply"; +import { SetAntiraidLevelAction } from "./setAntiraidLevel"; import { SetCounterAction } from "./setCounter"; import { SetSlowmodeAction } from "./setSlowmode"; +import { WarnAction } from "./warn"; export const availableActions: Record> = { clean: CleanAction, diff --git a/backend/src/plugins/Automod/actions/ban.ts b/backend/src/plugins/Automod/actions/ban.ts index 9ca09086..ebec5516 100644 --- a/backend/src/plugins/Automod/actions/ban.ts +++ b/backend/src/plugins/Automod/actions/ban.ts @@ -1,18 +1,16 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { LogType } from "../../../data/LogType"; import { - asyncMap, - convertDelayStringToMS, - nonNullish, - resolveMember, - tDelayString, - tNullable, - unique, + convertDelayStringToMS, + nonNullish, + + tDelayString, + tNullable, + unique } from "../../../utils"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { CaseArgs } from "../../Cases/types"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; +import { automodAction } from "../helpers"; export const BanAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/actions/changeNickname.ts b/backend/src/plugins/Automod/actions/changeNickname.ts index 7225f794..d6dee527 100644 --- a/backend/src/plugins/Automod/actions/changeNickname.ts +++ b/backend/src/plugins/Automod/actions/changeNickname.ts @@ -1,8 +1,8 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; import { nonNullish, unique } from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { automodAction } from "../helpers"; export const ChangeNicknameAction = automodAction({ configType: t.union([ diff --git a/backend/src/plugins/Automod/actions/clean.ts b/backend/src/plugins/Automod/actions/clean.ts index 4f505cfb..a326cc3b 100644 --- a/backend/src/plugins/Automod/actions/clean.ts +++ b/backend/src/plugins/Automod/actions/clean.ts @@ -1,8 +1,8 @@ +import { TextChannel } from "discord.js"; import * as t from "io-ts"; -import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; import { noop } from "../../../utils"; -import { TextChannel } from "discord.js"; +import { automodAction } from "../helpers"; export const CleanAction = automodAction({ configType: t.boolean, diff --git a/backend/src/plugins/Automod/actions/kick.ts b/backend/src/plugins/Automod/actions/kick.ts index 0b0fafa5..98408da3 100644 --- a/backend/src/plugins/Automod/actions/kick.ts +++ b/backend/src/plugins/Automod/actions/kick.ts @@ -1,10 +1,9 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { LogType } from "../../../data/LogType"; import { asyncMap, nonNullish, resolveMember, tNullable, unique } from "../../../utils"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { CaseArgs } from "../../Cases/types"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; +import { automodAction } from "../helpers"; export const KickAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/actions/log.ts b/backend/src/plugins/Automod/actions/log.ts index 5390fe12..7218ce5f 100644 --- a/backend/src/plugins/Automod/actions/log.ts +++ b/backend/src/plugins/Automod/actions/log.ts @@ -1,8 +1,8 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars, unique } from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { automodAction } from "../helpers"; export const LogAction = automodAction({ configType: t.boolean, diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index 3bc7a90b..2ee0b9ba 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -1,21 +1,19 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { - asyncMap, - convertDelayStringToMS, - nonNullish, - resolveMember, - tDelayString, - tNullable, - unique, -} from "../../../utils"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { MutesPlugin } from "../../Mutes/MutesPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { + convertDelayStringToMS, + nonNullish, + + tDelayString, + tNullable, + unique +} from "../../../utils"; import { CaseArgs } from "../../Cases/types"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { MutesPlugin } from "../../Mutes/MutesPlugin"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; +import { automodAction } from "../helpers"; export const MuteAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index 79e22fae..35071c02 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -1,17 +1,15 @@ -import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { LogType } from "../../../data/LogType"; -import { asyncMap, nonNullish, resolveMember, tNullable, unique } from "../../../utils"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { getMissingPermissions } from "../../../utils/getMissingPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { canAssignRole } from "../../../utils/canAssignRole"; - -import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; -import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { Permissions } from "discord.js"; +import * as t from "io-ts"; +import { LogType } from "../../../data/LogType"; +import { nonNullish, unique } from "../../../utils"; +import { canAssignRole } from "../../../utils/canAssignRole"; +import { getMissingPermissions } from "../../../utils/getMissingPermissions"; +import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; +import { automodAction } from "../helpers"; + const p = Permissions.FLAGS; diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index 8357edb9..dafb9dfb 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -1,23 +1,23 @@ +import { MessageOptions, Permissions, TextChannel, User } from "discord.js"; import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { - convertDelayStringToMS, - noop, - renderRecursively, - StrictMessageContent, - stripObjectToScalars, - tDelayString, - tMessageContent, - tNullable, - unique, - verboseChannelMention, -} from "../../../utils"; - -import { AutomodContext } from "../types"; -import { renderTemplate } from "../../../templateFormatter"; -import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogType } from "../../../data/LogType"; -import { TextChannel, User, Constants, MessageOptions, Permissions } from "discord.js"; +import { renderTemplate } from "../../../templateFormatter"; +import { + convertDelayStringToMS, + noop, + renderRecursively, + + stripObjectToScalars, + tDelayString, + tMessageContent, + tNullable, + unique, + verboseChannelMention +} from "../../../utils"; +import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; +import { automodAction } from "../helpers"; +import { AutomodContext } from "../types"; + export const ReplyAction = automodAction({ configType: t.union([ diff --git a/backend/src/plugins/Automod/actions/setAntiraidLevel.ts b/backend/src/plugins/Automod/actions/setAntiraidLevel.ts index 8d15a35f..a1722aae 100644 --- a/backend/src/plugins/Automod/actions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/actions/setAntiraidLevel.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { setAntiraidLevel } from "../functions/setAntiraidLevel"; import { tNullable } from "../../../utils"; +import { setAntiraidLevel } from "../functions/setAntiraidLevel"; +import { automodAction } from "../helpers"; export const SetAntiraidLevelAction = automodAction({ configType: tNullable(t.string), diff --git a/backend/src/plugins/Automod/actions/setCounter.ts b/backend/src/plugins/Automod/actions/setCounter.ts index eb63d80d..150d77f7 100644 --- a/backend/src/plugins/Automod/actions/setCounter.ts +++ b/backend/src/plugins/Automod/actions/setCounter.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { CountersPlugin } from "../../Counters/CountersPlugin"; import { LogType } from "../../../data/LogType"; +import { CountersPlugin } from "../../Counters/CountersPlugin"; +import { automodAction } from "../helpers"; export const SetCounterAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index 7acfdd28..05222df3 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -1,9 +1,9 @@ +import { TextChannel } from "discord.js"; import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { convertDelayStringToMS, isDiscordRESTError, tDelayString, tNullable } from "../../../utils"; -import { LogType } from "../../../data/LogType"; -import { Constants, TextChannel } from "discord.js"; import { ChannelTypeStrings } from "src/types"; +import { LogType } from "../../../data/LogType"; +import { convertDelayStringToMS, isDiscordRESTError, tDelayString, tNullable } from "../../../utils"; +import { automodAction } from "../helpers"; export const SetSlowmodeAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/actions/warn.ts b/backend/src/plugins/Automod/actions/warn.ts index 38f131b8..29dd4955 100644 --- a/backend/src/plugins/Automod/actions/warn.ts +++ b/backend/src/plugins/Automod/actions/warn.ts @@ -1,10 +1,9 @@ import * as t from "io-ts"; -import { automodAction } from "../helpers"; -import { LogType } from "../../../data/LogType"; import { asyncMap, nonNullish, resolveMember, tNullable, unique } from "../../../utils"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { CaseArgs } from "../../Cases/types"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; +import { automodAction } from "../helpers"; export const WarnAction = automodAction({ configType: t.type({ diff --git a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts index 8aa210ee..3f119b6b 100644 --- a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts +++ b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts @@ -1,7 +1,7 @@ -import { typedGuildCommand, GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; -import { setAntiraidLevel } from "../functions/setAntiraidLevel"; +import { typedGuildCommand } from "knub"; import { sendSuccessMessage } from "../../../pluginUtils"; +import { setAntiraidLevel } from "../functions/setAntiraidLevel"; +import { AutomodPluginType } from "../types"; export const AntiraidClearCmd = typedGuildCommand()({ trigger: ["antiraid clear", "antiraid reset", "antiraid none", "antiraid off"], diff --git a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts index 0f98ac8a..3ec0f2f9 100644 --- a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts @@ -1,8 +1,8 @@ -import { typedGuildCommand, GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; -import { setAntiraidLevel } from "../functions/setAntiraidLevel"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { typedGuildCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { setAntiraidLevel } from "../functions/setAntiraidLevel"; +import { AutomodPluginType } from "../types"; export const SetAntiraidCmd = typedGuildCommand()({ trigger: "antiraid", diff --git a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts index 397e60e1..5c208497 100644 --- a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts @@ -1,8 +1,5 @@ -import { typedGuildCommand, GuildPluginData } from "knub"; +import { typedGuildCommand } from "knub"; import { AutomodPluginType } from "../types"; -import { setAntiraidLevel } from "../functions/setAntiraidLevel"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; export const ViewAntiraidCmd = typedGuildCommand()({ trigger: "antiraid", diff --git a/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts b/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts index 504a014e..17e98ba0 100644 --- a/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts +++ b/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts @@ -1,7 +1,7 @@ import { typedGuildEventListener } from "knub"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { runAutomod } from "../functions/runAutomod"; import { RecentActionType } from "../constants"; +import { runAutomod } from "../functions/runAutomod"; +import { AutomodContext, AutomodPluginType } from "../types"; export const RunAutomodOnJoinEvt = typedGuildEventListener()({ event: "guildMemberAdd", diff --git a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts index 8ef0b461..611aadde 100644 --- a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts +++ b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts @@ -1,9 +1,8 @@ import { typedGuildEventListener } from "knub"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { RecentActionType } from "../constants"; -import { runAutomod } from "../functions/runAutomod"; -import isEqual from "lodash.isequal"; import diff from "lodash.difference"; +import isEqual from "lodash.isequal"; +import { runAutomod } from "../functions/runAutomod"; +import { AutomodContext, AutomodPluginType } from "../types"; export const RunAutomodOnMemberUpdate = typedGuildEventListener()({ event: "guildMemberUpdate", diff --git a/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts b/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts index 4145cb19..2dfc4bac 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { runAutomod } from "../functions/runAutomod"; import { User } from "discord.js"; +import { GuildPluginData } from "knub"; +import { runAutomod } from "../functions/runAutomod"; +import { AutomodContext, AutomodPluginType } from "../types"; export async function runAutomodOnAntiraidLevel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts b/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts index 2b1b974d..01f75116 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { runAutomod } from "../functions/runAutomod"; import { resolveMember, resolveUser, UnknownUser } from "../../../utils"; import { CountersPlugin } from "../../Counters/CountersPlugin"; +import { runAutomod } from "../functions/runAutomod"; +import { AutomodContext, AutomodPluginType } from "../types"; export async function runAutomodOnCounterTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts index a3db2cf4..1945be37 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts @@ -1,10 +1,10 @@ -import { SavedMessage } from "../../../data/entities/SavedMessage"; import { GuildPluginData } from "knub"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { runAutomod } from "../functions/runAutomod"; -import { addRecentActionsFromMessage } from "../functions/addRecentActionsFromMessage"; import moment from "moment-timezone"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { addRecentActionsFromMessage } from "../functions/addRecentActionsFromMessage"; import { clearRecentActionsForMessage } from "../functions/clearRecentActionsForMessage"; +import { runAutomod } from "../functions/runAutomod"; +import { AutomodContext, AutomodPluginType } from "../types"; export function runAutomodOnMessage( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts index 5f9437c1..79c8dbea 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { runAutomod } from "../functions/runAutomod"; import { resolveMember, resolveUser, UnknownUser } from "../../../utils"; import { ModActionType } from "../../ModActions/types"; +import { runAutomod } from "../functions/runAutomod"; +import { AutomodContext, AutomodPluginType } from "../types"; export async function runAutomodOnModAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts index 90b8dba6..4f533182 100644 --- a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts +++ b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts @@ -1,7 +1,7 @@ -import { AutomodContext, AutomodPluginType } from "../types"; import { GuildPluginData } from "knub"; -import { RECENT_ACTION_EXPIRY_TIME, RecentActionType } from "../constants"; import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils"; +import { RecentActionType, RECENT_ACTION_EXPIRY_TIME } from "../constants"; +import { AutomodContext, AutomodPluginType } from "../types"; export function addRecentActionsFromMessage(pluginData: GuildPluginData, context: AutomodContext) { const message = context.message!; diff --git a/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts b/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts index 887d18f0..6338d698 100644 --- a/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts +++ b/backend/src/plugins/Automod/functions/checkAndUpdateCooldown.ts @@ -1,7 +1,6 @@ -import { AutomodContext, AutomodPluginType, TRule } from "../types"; import { GuildPluginData } from "knub"; -import { AutomodTriggerMatchResult } from "../helpers"; import { convertDelayStringToMS } from "../../../utils"; +import { AutomodContext, AutomodPluginType, TRule } from "../types"; export function checkAndUpdateCooldown( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts b/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts index 8d668ba7..0d720c2d 100644 --- a/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts +++ b/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; +import { RECENT_NICKNAME_CHANGE_EXPIRY_TIME } from "../constants"; import { AutomodPluginType } from "../types"; -import { RECENT_NICKNAME_CHANGE_EXPIRY_TIME, RECENT_SPAM_EXPIRY_TIME } from "../constants"; export function clearOldRecentNicknameChanges(pluginData: GuildPluginData) { const now = Date.now(); diff --git a/backend/src/plugins/Automod/functions/clearOldRecentActions.ts b/backend/src/plugins/Automod/functions/clearOldRecentActions.ts index e1ee2fe5..67a79718 100644 --- a/backend/src/plugins/Automod/functions/clearOldRecentActions.ts +++ b/backend/src/plugins/Automod/functions/clearOldRecentActions.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; import { RECENT_ACTION_EXPIRY_TIME } from "../constants"; +import { AutomodPluginType } from "../types"; export function clearOldRecentActions(pluginData: GuildPluginData) { const now = Date.now(); diff --git a/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts b/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts index 7fcec63e..a0f34c8b 100644 --- a/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts +++ b/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; import { RECENT_SPAM_EXPIRY_TIME } from "../constants"; +import { AutomodPluginType } from "../types"; export function clearOldRecentSpam(pluginData: GuildPluginData) { const now = Date.now(); diff --git a/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts b/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts index 03af6c9d..7aa9750a 100644 --- a/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts +++ b/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts @@ -1,7 +1,5 @@ -import { AutomodContext, AutomodPluginType } from "../types"; import { GuildPluginData } from "knub"; -import { RECENT_ACTION_EXPIRY_TIME, RecentActionType } from "../constants"; -import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils"; +import { AutomodContext, AutomodPluginType } from "../types"; export function clearRecentActionsForMessage(pluginData: GuildPluginData, context: AutomodContext) { const message = context.message!; diff --git a/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts b/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts index 09f4af78..009a1f52 100644 --- a/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts +++ b/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts @@ -1,13 +1,13 @@ -import { RecentActionType } from "../constants"; -import { automodTrigger } from "../helpers"; +import * as t from "io-ts"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { getBaseUrl } from "../../../pluginUtils"; import { convertDelayStringToMS, sorter, tDelayString, tNullable } from "../../../utils"; -import { humanizeDurationShort } from "../../../humanizeDurationShort"; +import { RecentActionType } from "../constants"; +import { automodTrigger } from "../helpers"; import { findRecentSpam } from "./findRecentSpam"; import { getMatchingMessageRecentActions } from "./getMatchingMessageRecentActions"; -import * as t from "io-ts"; import { getMessageSpamIdentifier } from "./getSpamIdentifier"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; const MessageSpamTriggerConfig = t.type({ amount: t.number, diff --git a/backend/src/plugins/Automod/functions/findRecentSpam.ts b/backend/src/plugins/Automod/functions/findRecentSpam.ts index 6ec8a59f..0e042ed5 100644 --- a/backend/src/plugins/Automod/functions/findRecentSpam.ts +++ b/backend/src/plugins/Automod/functions/findRecentSpam.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; import { RecentActionType } from "../constants"; +import { AutomodPluginType } from "../types"; export function findRecentSpam( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts b/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts index 7e7299bc..8318ea1e 100644 --- a/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts +++ b/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts @@ -1,9 +1,9 @@ import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; import moment from "moment-timezone"; -import { getMatchingRecentActions } from "./getMatchingRecentActions"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; import { RecentActionType } from "../constants"; +import { AutomodPluginType } from "../types"; +import { getMatchingRecentActions } from "./getMatchingRecentActions"; export function getMatchingMessageRecentActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts b/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts index 56d251c2..416c050b 100644 --- a/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts +++ b/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; import { RecentActionType } from "../constants"; +import { AutomodPluginType } from "../types"; export function getMatchingRecentActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts index 99442b1e..7ce964d5 100644 --- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts +++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts @@ -1,7 +1,7 @@ -import { MatchableTextType } from "./matchMultipleTextTypesOnMessage"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { messageSummary, verboseChannelMention } from "../../../utils"; import { GuildPluginData } from "knub"; +import { messageSummary, verboseChannelMention } from "../../../utils"; +import { AutomodContext, AutomodPluginType } from "../types"; +import { MatchableTextType } from "./matchMultipleTextTypesOnMessage"; export function getTextMatchPartialSummary( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts b/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts index a3c881a6..a8314a85 100644 --- a/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts +++ b/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; import { MINUTES } from "../../../utils"; +import { AutomodPluginType } from "../types"; const IGNORED_ROLE_CHANGE_LIFETIME = 5 * MINUTES; diff --git a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts index 2638d677..6b2e1038 100644 --- a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts +++ b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts @@ -1,8 +1,8 @@ +import { Constants } from "discord.js"; +import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { resolveMember } from "../../../utils"; -import { GuildPluginData } from "knub"; import { AutomodPluginType } from "../types"; -import { Activity, Constants } from "discord.js"; type TextTriggerWithMultipleMatchTypes = { match_messages: boolean; diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts index 83753a02..a7c465fc 100644 --- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts +++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts @@ -1,9 +1,9 @@ -import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; - -import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; +import { AutomodPluginType } from "../types"; + export function resolveActionContactMethods( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts index f95a9abf..3af968da 100644 --- a/backend/src/plugins/Automod/functions/runAutomod.ts +++ b/backend/src/plugins/Automod/functions/runAutomod.ts @@ -1,11 +1,11 @@ -import { GuildPluginData } from "knub"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { availableTriggers } from "../triggers/availableTriggers"; -import { availableActions } from "../actions/availableActions"; -import { AutomodTriggerMatchResult } from "../helpers"; -import { CleanAction } from "../actions/clean"; -import { checkAndUpdateCooldown } from "./checkAndUpdateCooldown"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { availableActions } from "../actions/availableActions"; +import { CleanAction } from "../actions/clean"; +import { AutomodTriggerMatchResult } from "../helpers"; +import { availableTriggers } from "../triggers/availableTriggers"; +import { AutomodContext, AutomodPluginType } from "../types"; +import { checkAndUpdateCooldown } from "./checkAndUpdateCooldown"; export async function runAutomod(pluginData: GuildPluginData, context: AutomodContext) { const userId = context.user?.id || context.member?.id || context.message?.user_id; diff --git a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts index 8d926525..328a8772 100644 --- a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts @@ -1,10 +1,10 @@ +import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { AutomodPluginType } from "../types"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars } from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; import { runAutomodOnAntiraidLevel } from "../events/runAutomodOnAntiraidLevel"; -import { User } from "discord.js"; +import { AutomodPluginType } from "../types"; export async function setAntiraidLevel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/helpers.ts b/backend/src/plugins/Automod/helpers.ts index f14e0331..20bafe7e 100644 --- a/backend/src/plugins/Automod/helpers.ts +++ b/backend/src/plugins/Automod/helpers.ts @@ -1,6 +1,6 @@ +import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { Awaitable } from "knub/dist/utils"; -import * as t from "io-ts"; import { AutomodContext, AutomodPluginType } from "./types"; interface BaseAutomodTriggerMatchResult { diff --git a/backend/src/plugins/Automod/info.ts b/backend/src/plugins/Automod/info.ts index 9fcdced0..6a053757 100644 --- a/backend/src/plugins/Automod/info.ts +++ b/backend/src/plugins/Automod/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinGuildPluginBlueprint } from "../ZeppelinPluginBlueprint"; import { trimPluginDescription } from "../../utils"; +import { ZeppelinGuildPluginBlueprint } from "../ZeppelinPluginBlueprint"; export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = { prettyName: "Automod", diff --git a/backend/src/plugins/Automod/triggers/antiraidLevel.ts b/backend/src/plugins/Automod/triggers/antiraidLevel.ts index 98398811..24959c66 100644 --- a/backend/src/plugins/Automod/triggers/antiraidLevel.ts +++ b/backend/src/plugins/Automod/triggers/antiraidLevel.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { tNullable } from "../../../utils"; +import { automodTrigger } from "../helpers"; // tslint:disable-next-line interface AntiraidLevelTriggerResult {} diff --git a/backend/src/plugins/Automod/triggers/anyMessage.ts b/backend/src/plugins/Automod/triggers/anyMessage.ts index 4f15c3cb..59c120ad 100644 --- a/backend/src/plugins/Automod/triggers/anyMessage.ts +++ b/backend/src/plugins/Automod/triggers/anyMessage.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { verboseChannelMention } from "../../../utils"; +import { automodTrigger } from "../helpers"; // tslint:disable-next-line:no-empty-interface interface AnyMessageResultType {} diff --git a/backend/src/plugins/Automod/triggers/availableTriggers.ts b/backend/src/plugins/Automod/triggers/availableTriggers.ts index cbb5b7d2..dbd02cc8 100644 --- a/backend/src/plugins/Automod/triggers/availableTriggers.ts +++ b/backend/src/plugins/Automod/triggers/availableTriggers.ts @@ -1,32 +1,32 @@ import * as t from "io-ts"; -import { MatchWordsTrigger } from "./matchWords"; import { AutomodTriggerBlueprint } from "../helpers"; -import { MessageSpamTrigger } from "./messageSpam"; -import { MentionSpamTrigger } from "./mentionSpam"; -import { LinkSpamTrigger } from "./linkSpam"; +import { AntiraidLevelTrigger } from "./antiraidLevel"; +import { AnyMessageTrigger } from "./anyMessage"; import { AttachmentSpamTrigger } from "./attachmentSpam"; -import { EmojiSpamTrigger } from "./emojiSpam"; -import { LineSpamTrigger } from "./lineSpam"; +import { BanTrigger } from "./ban"; import { CharacterSpamTrigger } from "./characterSpam"; -import { MatchRegexTrigger } from "./matchRegex"; +import { CounterTrigger } from "./counterTrigger"; +import { EmojiSpamTrigger } from "./emojiSpam"; +import { KickTrigger } from "./kick"; +import { LineSpamTrigger } from "./lineSpam"; +import { LinkSpamTrigger } from "./linkSpam"; +import { MatchAttachmentTypeTrigger } from "./matchAttachmentType"; import { MatchInvitesTrigger } from "./matchInvites"; import { MatchLinksTrigger } from "./matchLinks"; -import { MatchAttachmentTypeTrigger } from "./matchAttachmentType"; -import { MemberJoinSpamTrigger } from "./memberJoinSpam"; +import { MatchRegexTrigger } from "./matchRegex"; +import { MatchWordsTrigger } from "./matchWords"; import { MemberJoinTrigger } from "./memberJoin"; +import { MemberJoinSpamTrigger } from "./memberJoinSpam"; +import { MentionSpamTrigger } from "./mentionSpam"; +import { MessageSpamTrigger } from "./messageSpam"; +import { MuteTrigger } from "./mute"; +import { NoteTrigger } from "./note"; import { RoleAddedTrigger } from "./roleAdded"; import { RoleRemovedTrigger } from "./roleRemoved"; import { StickerSpamTrigger } from "./stickerSpam"; -import { CounterTrigger } from "./counterTrigger"; -import { NoteTrigger } from "./note"; -import { WarnTrigger } from "./warn"; -import { MuteTrigger } from "./mute"; -import { UnmuteTrigger } from "./unmute"; -import { KickTrigger } from "./kick"; -import { BanTrigger } from "./ban"; import { UnbanTrigger } from "./unban"; -import { AnyMessageTrigger } from "./anyMessage"; -import { AntiraidLevelTrigger } from "./antiraidLevel"; +import { UnmuteTrigger } from "./unmute"; +import { WarnTrigger } from "./warn"; export const availableTriggers: Record> = { any_message: AnyMessageTrigger, diff --git a/backend/src/plugins/Automod/triggers/counterTrigger.ts b/backend/src/plugins/Automod/triggers/counterTrigger.ts index ddfda013..a446164b 100644 --- a/backend/src/plugins/Automod/triggers/counterTrigger.ts +++ b/backend/src/plugins/Automod/triggers/counterTrigger.ts @@ -1,8 +1,6 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; -import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges"; -import { CountersPlugin } from "../../Counters/CountersPlugin"; import { tNullable } from "../../../utils"; +import { automodTrigger } from "../helpers"; // tslint:disable-next-line interface CounterTriggerResult {} diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 39163095..7541b577 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -1,12 +1,12 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { - asSingleLine, - disableCodeBlocks, - disableInlineCode, - messageSummary, - verboseChannelMention, + asSingleLine, + + disableInlineCode, + messageSummary, + verboseChannelMention } from "../../../utils"; +import { automodTrigger } from "../helpers"; interface MatchResultType { matchedType: string; diff --git a/backend/src/plugins/Automod/triggers/matchInvites.ts b/backend/src/plugins/Automod/triggers/matchInvites.ts index 1e254711..6b238841 100644 --- a/backend/src/plugins/Automod/triggers/matchInvites.ts +++ b/backend/src/plugins/Automod/triggers/matchInvites.ts @@ -1,17 +1,14 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { - disableCodeBlocks, - disableInlineCode, - getInviteCodesInString, - GuildInvite, - isGuildInvite, - resolveInvite, - tNullable, - verboseChannelMention, + getInviteCodesInString, + GuildInvite, + isGuildInvite, + resolveInvite, + tNullable } from "../../../utils"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; +import { automodTrigger } from "../helpers"; interface MatchResultType { type: MatchableTextType; diff --git a/backend/src/plugins/Automod/triggers/matchLinks.ts b/backend/src/plugins/Automod/triggers/matchLinks.ts index 50d953d6..29c05190 100644 --- a/backend/src/plugins/Automod/triggers/matchLinks.ts +++ b/backend/src/plugins/Automod/triggers/matchLinks.ts @@ -1,18 +1,15 @@ -import * as t from "io-ts"; import escapeStringRegexp from "escape-string-regexp"; -import { automodTrigger } from "../helpers"; +import * as t from "io-ts"; +import { allowTimeout } from "../../../RegExpRunner"; import { - asSingleLine, - disableCodeBlocks, - disableInlineCode, - getUrlsInString, - tNullable, - verboseChannelMention, + disableInlineCode, + getUrlsInString, + tNullable } from "../../../utils"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; import { TRegex } from "../../../validatorUtils"; import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; -import { allowTimeout } from "../../../RegExpRunner"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; +import { automodTrigger } from "../helpers"; interface MatchResultType { type: MatchableTextType; diff --git a/backend/src/plugins/Automod/triggers/matchRegex.ts b/backend/src/plugins/Automod/triggers/matchRegex.ts index 95dc3241..5d585f08 100644 --- a/backend/src/plugins/Automod/triggers/matchRegex.ts +++ b/backend/src/plugins/Automod/triggers/matchRegex.ts @@ -1,12 +1,12 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; -import { disableInlineCode, verboseChannelMention } from "../../../utils"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; -import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; import { allowTimeout } from "../../../RegExpRunner"; -import { TRegex } from "../../../validatorUtils"; +import { disableInlineCode } from "../../../utils"; import { normalizeText } from "../../../utils/normalizeText"; import { stripMarkdown } from "../../../utils/stripMarkdown"; +import { TRegex } from "../../../validatorUtils"; +import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; +import { automodTrigger } from "../helpers"; interface MatchResultType { pattern: string; diff --git a/backend/src/plugins/Automod/triggers/matchWords.ts b/backend/src/plugins/Automod/triggers/matchWords.ts index b5a2da97..2a011546 100644 --- a/backend/src/plugins/Automod/triggers/matchWords.ts +++ b/backend/src/plugins/Automod/triggers/matchWords.ts @@ -1,11 +1,11 @@ -import * as t from "io-ts"; import escapeStringRegexp from "escape-string-regexp"; -import { automodTrigger } from "../helpers"; -import { disableInlineCode, verboseChannelMention } from "../../../utils"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; -import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; +import * as t from "io-ts"; +import { disableInlineCode } from "../../../utils"; import { normalizeText } from "../../../utils/normalizeText"; import { stripMarkdown } from "../../../utils/stripMarkdown"; +import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; +import { automodTrigger } from "../helpers"; interface MatchResultType { word: string; diff --git a/backend/src/plugins/Automod/triggers/memberJoin.ts b/backend/src/plugins/Automod/triggers/memberJoin.ts index a94b6b52..014c992b 100644 --- a/backend/src/plugins/Automod/triggers/memberJoin.ts +++ b/backend/src/plugins/Automod/triggers/memberJoin.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { convertDelayStringToMS, tDelayString } from "../../../utils"; +import { automodTrigger } from "../helpers"; export const MemberJoinTrigger = automodTrigger()({ configType: t.type({ diff --git a/backend/src/plugins/Automod/triggers/memberJoinSpam.ts b/backend/src/plugins/Automod/triggers/memberJoinSpam.ts index f0f9b704..7ab1964a 100644 --- a/backend/src/plugins/Automod/triggers/memberJoinSpam.ts +++ b/backend/src/plugins/Automod/triggers/memberJoinSpam.ts @@ -1,10 +1,10 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { convertDelayStringToMS, tDelayString } from "../../../utils"; -import { getMatchingRecentActions } from "../functions/getMatchingRecentActions"; import { RecentActionType } from "../constants"; -import { sumRecentActionCounts } from "../functions/sumRecentActionCounts"; import { findRecentSpam } from "../functions/findRecentSpam"; +import { getMatchingRecentActions } from "../functions/getMatchingRecentActions"; +import { sumRecentActionCounts } from "../functions/sumRecentActionCounts"; +import { automodTrigger } from "../helpers"; export const MemberJoinSpamTrigger = automodTrigger()({ configType: t.type({ diff --git a/backend/src/plugins/Automod/triggers/roleAdded.ts b/backend/src/plugins/Automod/triggers/roleAdded.ts index f3a4d7cb..ad0e6bfd 100644 --- a/backend/src/plugins/Automod/triggers/roleAdded.ts +++ b/backend/src/plugins/Automod/triggers/roleAdded.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges"; +import { automodTrigger } from "../helpers"; interface RoleAddedMatchResult { matchedRoleId: string; diff --git a/backend/src/plugins/Automod/triggers/roleRemoved.ts b/backend/src/plugins/Automod/triggers/roleRemoved.ts index 430ec746..b0af1166 100644 --- a/backend/src/plugins/Automod/triggers/roleRemoved.ts +++ b/backend/src/plugins/Automod/triggers/roleRemoved.ts @@ -1,6 +1,6 @@ import * as t from "io-ts"; -import { automodTrigger } from "../helpers"; import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges"; +import { automodTrigger } from "../helpers"; interface RoleAddedMatchResult { matchedRoleId: string; diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 08b49ee4..100899bd 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -1,22 +1,22 @@ +import { GuildMember, User } from "discord.js"; import * as t from "io-ts"; -import { tNullable, UnknownUser } from "../../utils"; import { BasePluginType, CooldownManager } from "knub"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildLogs } from "../../data/GuildLogs"; import { SavedMessage } from "../../data/entities/SavedMessage"; - -import { AvailableTriggers } from "./triggers/availableTriggers"; -import { AvailableActions } from "./actions/availableActions"; -import { Queue } from "../../Queue"; import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels"; import { GuildArchives } from "../../data/GuildArchives"; -import { RecentActionType } from "./constants"; -import Timeout = NodeJS.Timeout; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { Queue } from "../../Queue"; import { RegExpRunner } from "../../RegExpRunner"; +import { tNullable } from "../../utils"; import { CounterEvents } from "../Counters/types"; import { ModActionsEvents, ModActionType } from "../ModActions/types"; import { MutesEvents } from "../Mutes/types"; -import { GuildMember, User } from "discord.js"; +import { AvailableActions } from "./actions/availableActions"; +import { RecentActionType } from "./constants"; +import { AvailableTriggers } from "./triggers/availableTriggers"; + +import Timeout = NodeJS.Timeout; export const Rule = t.type({ enabled: t.boolean, diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index 6c5cffc3..8bce0acb 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -1,24 +1,24 @@ -import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; -import { BotControlPluginType, ConfigSchema } from "./types"; -import { GuildArchives } from "../../data/GuildArchives"; - -import { sendSuccessMessage } from "../../pluginUtils"; -import { getActiveReload, resetActiveReload } from "./activeReload"; -import { ReloadGlobalPluginsCmd } from "./commands/ReloadGlobalPluginsCmd"; -import { ServersCmd } from "./commands/ServersCmd"; -import { LeaveServerCmd } from "./commands/LeaveServerCmd"; -import { ReloadServerCmd } from "./commands/ReloadServerCmd"; +import { TextChannel } from "discord.js"; import { AllowedGuilds } from "../../data/AllowedGuilds"; +import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; +import { Configs } from "../../data/Configs"; +import { GuildArchives } from "../../data/GuildArchives"; +import { sendSuccessMessage } from "../../pluginUtils"; +import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; +import { getActiveReload, resetActiveReload } from "./activeReload"; +import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd"; import { AllowServerCmd } from "./commands/AllowServerCmd"; import { DisallowServerCmd } from "./commands/DisallowServerCmd"; -import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd"; -import { RemoveDashboardUserCmd } from "./commands/RemoveDashboardUserCmd"; -import { Configs } from "../../data/Configs"; -import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; -import { ListDashboardUsersCmd } from "./commands/ListDashboardUsersCmd"; -import { ListDashboardPermsCmd } from "./commands/ListDashboardPermsCmd"; import { EligibleCmd } from "./commands/EligibleCmd"; -import { TextChannel } from "discord.js"; +import { LeaveServerCmd } from "./commands/LeaveServerCmd"; +import { ListDashboardPermsCmd } from "./commands/ListDashboardPermsCmd"; +import { ListDashboardUsersCmd } from "./commands/ListDashboardUsersCmd"; +import { ReloadGlobalPluginsCmd } from "./commands/ReloadGlobalPluginsCmd"; +import { ReloadServerCmd } from "./commands/ReloadServerCmd"; +import { RemoveDashboardUserCmd } from "./commands/RemoveDashboardUserCmd"; +import { ServersCmd } from "./commands/ServersCmd"; +import { BotControlPluginType, ConfigSchema } from "./types"; + const defaultOptions = { config: { diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index 3e207b1e..156606da 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -1,8 +1,8 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; import { ApiPermissions } from "@shared/apiPermissions"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { botControlCmd } from "../types"; export const AddDashboardUserCmd = botControlCmd({ trigger: ["add_dashboard_user"], diff --git a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts index 751fdfcc..2ff34f6d 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -1,9 +1,9 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isSnowflake } from "../../../utils"; import { ApiPermissions } from "@shared/apiPermissions"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { isSnowflake } from "../../../utils"; +import { botControlCmd } from "../types"; export const AllowServerCmd = botControlCmd({ trigger: ["allow_server", "allowserver", "add_server", "addserver"], diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index 1fc4916e..9dfd9599 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -1,8 +1,8 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { noop } from "../../../utils"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { noop } from "../../../utils"; +import { botControlCmd } from "../types"; export const DisallowServerCmd = botControlCmd({ trigger: ["disallow_server", "disallowserver", "remove_server", "removeserver"], diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index ff68d1d8..522cf3a0 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -1,8 +1,8 @@ -import { botControlCmd } from "../types"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { resolveInvite, verboseUserMention } from "../../../utils"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveInvite, verboseUserMention } from "../../../utils"; +import { botControlCmd } from "../types"; const REQUIRED_MEMBER_COUNT = 5000; diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 1d96eb96..8352548a 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -1,7 +1,7 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { botControlCmd } from "../types"; export const LeaveServerCmd = botControlCmd({ trigger: ["leave_server", "leave_guild"], diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index 2933cf32..d9310906 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -1,10 +1,10 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { createChunkedMessage, resolveUser } from "../../../utils"; import { AllowedGuild } from "../../../data/entities/AllowedGuild"; import { ApiPermissionAssignment } from "../../../data/entities/ApiPermissionAssignment"; -import { TextChannel } from "discord.js"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveUser } from "../../../utils"; +import { botControlCmd } from "../types"; export const ListDashboardPermsCmd = botControlCmd({ trigger: ["list_dashboard_permissions", "list_dashboard_perms", "list_dash_permissionss", "list_dash_perms"], diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index 107579b2..81e58fb7 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -1,9 +1,8 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { ApiPermissions } from "@shared/apiPermissions"; -import { resolveUser, UnknownUser } from "../../../utils"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveUser } from "../../../utils"; +import { botControlCmd } from "../types"; export const ListDashboardUsersCmd = botControlCmd({ trigger: ["list_dashboard_users"], diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index 8be32a5e..1b3629ce 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -1,7 +1,7 @@ -import { botControlCmd } from "../types"; +import { TextChannel } from "discord.js"; import { isOwnerPreFilter } from "../../../pluginUtils"; import { getActiveReload, setActiveReload } from "../activeReload"; -import { TextChannel } from "discord.js"; +import { botControlCmd } from "../types"; export const ReloadGlobalPluginsCmd = botControlCmd({ trigger: "bot_reload_global_plugins", diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 892ef744..0166cba1 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -1,7 +1,7 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { botControlCmd } from "../types"; export const ReloadServerCmd = botControlCmd({ trigger: ["reload_server", "reload_guild"], diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 186e02a2..75085491 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -1,8 +1,7 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { ApiPermissions } from "@shared/apiPermissions"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { botControlCmd } from "../types"; export const RemoveDashboardUserCmd = botControlCmd({ trigger: ["remove_dashboard_user"], diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index 1d99230b..53950f53 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -1,9 +1,9 @@ -import { botControlCmd } from "../types"; -import { isOwnerPreFilter } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import escapeStringRegexp from "escape-string-regexp"; -import { createChunkedMessage, getUser, sorter } from "../../../utils"; import { TextChannel } from "discord.js"; +import escapeStringRegexp from "escape-string-regexp"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwnerPreFilter } from "../../../pluginUtils"; +import { createChunkedMessage, getUser, sorter } from "../../../utils"; +import { botControlCmd } from "../types"; export const ServersCmd = botControlCmd({ trigger: ["servers", "guilds"], diff --git a/backend/src/plugins/BotControl/types.ts b/backend/src/plugins/BotControl/types.ts index d84a526d..1acac3a4 100644 --- a/backend/src/plugins/BotControl/types.ts +++ b/backend/src/plugins/BotControl/types.ts @@ -1,10 +1,10 @@ import * as t from "io-ts"; -import { tNullable } from "../../utils"; import { BasePluginType, typedGlobalCommand, typedGlobalEventListener } from "knub"; -import { GuildArchives } from "../../data/GuildArchives"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; import { Configs } from "../../data/Configs"; +import { GuildArchives } from "../../data/GuildArchives"; +import { tNullable } from "../../utils"; export const ConfigSchema = t.type({ can_use: t.boolean, diff --git a/backend/src/plugins/Cases/CasesPlugin.ts b/backend/src/plugins/Cases/CasesPlugin.ts index 2bc0d861..6f870fc6 100644 --- a/backend/src/plugins/Cases/CasesPlugin.ts +++ b/backend/src/plugins/Cases/CasesPlugin.ts @@ -1,21 +1,21 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { CaseArgs, CaseNoteArgs, CasesPluginType, ConfigSchema } from "./types"; -import { createCase } from "./functions/createCase"; -import { GuildLogs } from "../../data/GuildLogs"; +import { CaseTypes } from "../../data/CaseTypes"; +import { Case } from "../../data/entities/Case"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; -import { createCaseNote } from "./functions/createCaseNote"; -import { Case } from "../../data/entities/Case"; -import { postCaseToCaseLogChannel } from "./functions/postToCaseLogChannel"; -import { CaseTypes } from "../../data/CaseTypes"; -import { getCaseTypeAmountForUserId } from "./functions/getCaseTypeAmountForUserId"; -import { getCaseEmbed } from "./functions/getCaseEmbed"; -import { trimPluginDescription } from "../../utils"; -import { getCaseSummary } from "./functions/getCaseSummary"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { GuildLogs } from "../../data/GuildLogs"; import { mapToPublicFn } from "../../pluginUtils"; -import { getTotalCasesByMod } from "./functions/getTotalCasesByMod"; +import { trimPluginDescription } from "../../utils"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { createCase } from "./functions/createCase"; +import { createCaseNote } from "./functions/createCaseNote"; +import { getCaseEmbed } from "./functions/getCaseEmbed"; +import { getCaseSummary } from "./functions/getCaseSummary"; +import { getCaseTypeAmountForUserId } from "./functions/getCaseTypeAmountForUserId"; import { getRecentCasesByMod } from "./functions/getRecentCasesByMod"; +import { getTotalCasesByMod } from "./functions/getTotalCasesByMod"; +import { postCaseToCaseLogChannel } from "./functions/postToCaseLogChannel"; +import { CaseArgs, CaseNoteArgs, CasesPluginType, ConfigSchema } from "./types"; const defaultOptions = { config: { diff --git a/backend/src/plugins/Cases/functions/createCase.ts b/backend/src/plugins/Cases/functions/createCase.ts index fd3caa04..0d66c71e 100644 --- a/backend/src/plugins/Cases/functions/createCase.ts +++ b/backend/src/plugins/Cases/functions/createCase.ts @@ -1,9 +1,9 @@ -import { CaseArgs, CasesPluginType } from "../types"; -import { resolveUser } from "../../../utils"; import { GuildPluginData } from "knub"; +import { logger } from "../../../logger"; +import { resolveUser } from "../../../utils"; +import { CaseArgs, CasesPluginType } from "../types"; import { createCaseNote } from "./createCaseNote"; import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; -import { logger } from "../../../logger"; export async function createCase(pluginData: GuildPluginData, args: CaseArgs) { const user = await resolveUser(pluginData.client, args.userId); diff --git a/backend/src/plugins/Cases/functions/createCaseNote.ts b/backend/src/plugins/Cases/functions/createCaseNote.ts index cd3ae649..ed95e7a7 100644 --- a/backend/src/plugins/Cases/functions/createCaseNote.ts +++ b/backend/src/plugins/Cases/functions/createCaseNote.ts @@ -1,9 +1,9 @@ -import { CaseNoteArgs, CasesPluginType } from "../types"; import { GuildPluginData } from "knub"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { resolveCaseId } from "./resolveCaseId"; -import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; import { resolveUser, UnknownUser } from "../../../utils"; +import { CaseNoteArgs, CasesPluginType } from "../types"; +import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; +import { resolveCaseId } from "./resolveCaseId"; export async function createCaseNote(pluginData: GuildPluginData, args: CaseNoteArgs): Promise { const theCase = await pluginData.state.cases.find(resolveCaseId(args.caseId)); diff --git a/backend/src/plugins/Cases/functions/getCaseColor.ts b/backend/src/plugins/Cases/functions/getCaseColor.ts index 1cf6ce77..379b171d 100644 --- a/backend/src/plugins/Cases/functions/getCaseColor.ts +++ b/backend/src/plugins/Cases/functions/getCaseColor.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CasesPluginType } from "../types"; import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes"; import { caseColors } from "../caseColors"; +import { CasesPluginType } from "../types"; export function getCaseColor(pluginData: GuildPluginData, caseType: CaseTypes) { return pluginData.config.get().case_colors?.[CaseTypeToName[caseType]] ?? caseColors[caseType]; diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index a73c5e15..5a3562c8 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -1,14 +1,14 @@ -import { Case } from "../../../data/entities/Case"; - +import { MessageOptions } from "discord.js"; +import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; -import { GuildPluginData, helpers } from "knub"; -import { CasesPluginType } from "../types"; -import { resolveCaseId } from "./resolveCaseId"; -import { chunkLines, chunkMessageLines, emptyEmbedValue, messageLink } from "../../../utils"; -import { getCaseColor } from "./getCaseColor"; +import { Case } from "../../../data/entities/Case"; +import { chunkMessageLines, emptyEmbedValue, messageLink } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { MessageOptions } from "discord.js"; +import { CasesPluginType } from "../types"; +import { getCaseColor } from "./getCaseColor"; +import { resolveCaseId } from "./resolveCaseId"; + export async function getCaseEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/getCaseIcon.ts b/backend/src/plugins/Cases/functions/getCaseIcon.ts index eb8fc3d5..6748a7ef 100644 --- a/backend/src/plugins/Cases/functions/getCaseIcon.ts +++ b/backend/src/plugins/Cases/functions/getCaseIcon.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CasesPluginType } from "../types"; import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes"; import { caseIcons } from "../caseIcons"; +import { CasesPluginType } from "../types"; export function getCaseIcon(pluginData: GuildPluginData, caseType: CaseTypes) { return pluginData.config.get().case_icons?.[CaseTypeToName[caseType]] ?? caseIcons[caseType]; diff --git a/backend/src/plugins/Cases/functions/getCaseSummary.ts b/backend/src/plugins/Cases/functions/getCaseSummary.ts index d948fdac..5f2f388e 100644 --- a/backend/src/plugins/Cases/functions/getCaseSummary.ts +++ b/backend/src/plugins/Cases/functions/getCaseSummary.ts @@ -1,22 +1,19 @@ import { GuildPluginData } from "knub"; -import { CasesPluginType } from "../types"; -import { - convertDelayStringToMS, - DAYS, - DBDateFormat, - disableLinkPreviews, - emptyEmbedValue, - messageLink, -} from "../../../utils"; -import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes"; +import { splitMessageIntoChunks } from "knub/dist/helpers"; import moment from "moment-timezone"; import { Case } from "../../../data/entities/Case"; -import humanizeDuration from "humanize-duration"; -import { humanizeDurationShort } from "../../../humanizeDurationShort"; -import { caseAbbreviations } from "../caseAbbreviations"; -import { getCaseIcon } from "./getCaseIcon"; +import { + convertDelayStringToMS, + DAYS, + DBDateFormat, + disableLinkPreviews, + + messageLink +} from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { splitIntoCleanChunks, splitMessageIntoChunks } from "knub/dist/helpers"; +import { caseAbbreviations } from "../caseAbbreviations"; +import { CasesPluginType } from "../types"; +import { getCaseIcon } from "./getCaseIcon"; const CASE_SUMMARY_REASON_MAX_LENGTH = 300; const INCLUDE_MORE_NOTES_THRESHOLD = 20; diff --git a/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts b/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts index 60752242..94f35d7f 100644 --- a/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts +++ b/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { CasesPluginType } from "../types"; import { CaseTypes } from "../../../data/CaseTypes"; +import { CasesPluginType } from "../types"; export async function getCaseTypeAmountForUserId( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts index 89ec703c..b9988078 100644 --- a/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts +++ b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { CasesPluginType } from "../types"; import { Case } from "../../../data/entities/Case"; +import { CasesPluginType } from "../types"; export function getRecentCasesByMod( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index feacede1..f16895b3 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -1,12 +1,12 @@ +import { FileOptions, Message, MessageOptions, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { CasesPluginType } from "../types"; - -import { isDiscordRESTError } from "../../../utils"; -import { LogType } from "../../../data/LogType"; import { Case } from "../../../data/entities/Case"; +import { LogType } from "../../../data/LogType"; +import { isDiscordRESTError } from "../../../utils"; +import { CasesPluginType } from "../types"; import { getCaseEmbed } from "./getCaseEmbed"; import { resolveCaseId } from "./resolveCaseId"; -import { FileOptions, Message, MessageOptions, TextChannel } from "discord.js"; + export async function postToCaseLogChannel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/types.ts b/backend/src/plugins/Cases/types.ts index 94fe1920..9ec1a371 100644 --- a/backend/src/plugins/Cases/types.ts +++ b/backend/src/plugins/Cases/types.ts @@ -1,10 +1,10 @@ import * as t from "io-ts"; -import { tDelayString, tPartialDictionary, tNullable } from "../../utils"; +import { BasePluginType } from "knub"; import { CaseNameToType, CaseTypes } from "../../data/CaseTypes"; -import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildCases } from "../../data/GuildCases"; import { GuildArchives } from "../../data/GuildArchives"; +import { GuildCases } from "../../data/GuildCases"; +import { GuildLogs } from "../../data/GuildLogs"; +import { tDelayString, tNullable, tPartialDictionary } from "../../utils"; import { tColor } from "../../utils/tColor"; export const ConfigSchema = t.type({ diff --git a/backend/src/plugins/Censor/CensorPlugin.ts b/backend/src/plugins/Censor/CensorPlugin.ts index 4dc103ec..f8401f54 100644 --- a/backend/src/plugins/Censor/CensorPlugin.ts +++ b/backend/src/plugins/Censor/CensorPlugin.ts @@ -1,13 +1,13 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, CensorPluginType } from "./types"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; +import { trimPluginDescription } from "../../utils"; +import { LogsPlugin } from "../Logs/LogsPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { CensorPluginType, ConfigSchema } from "./types"; import { onMessageCreate } from "./util/onMessageCreate"; import { onMessageUpdate } from "./util/onMessageUpdate"; -import { trimPluginDescription } from "../../utils"; -import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { LogsPlugin } from "../Logs/LogsPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Censor/types.ts b/backend/src/plugins/Censor/types.ts index 5cc64f5d..1363baef 100644 --- a/backend/src/plugins/Censor/types.ts +++ b/backend/src/plugins/Censor/types.ts @@ -1,10 +1,10 @@ import * as t from "io-ts"; import { BasePluginType } from "knub"; -import { tNullable } from "../../utils"; -import { TRegex } from "../../validatorUtils"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { RegExpRunner } from "../../RegExpRunner"; +import { tNullable } from "../../utils"; +import { TRegex } from "../../validatorUtils"; export const ConfigSchema = t.type({ filter_zalgo: t.boolean, diff --git a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts index 045276f2..f0ea8c40 100644 --- a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts +++ b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts @@ -1,15 +1,14 @@ -import { GuildPluginData } from "knub"; -import { CensorPluginType } from "../types"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; - -import { ZalgoRegex } from "../../../data/Zalgo"; -import { getInviteCodesInString, getUrlsInString, resolveMember, resolveInvite, isGuildInvite } from "../../../utils"; -import cloneDeep from "lodash.clonedeep"; -import { censorMessage } from "./censorMessage"; +import { Invite, MessageEmbed } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; -import { logger } from "../../../logger"; +import { GuildPluginData } from "knub"; +import cloneDeep from "lodash.clonedeep"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { ZalgoRegex } from "../../../data/Zalgo"; import { allowTimeout } from "../../../RegExpRunner"; -import { MessageEmbed, Invite } from "discord.js"; +import { getInviteCodesInString, getUrlsInString, isGuildInvite, resolveInvite, resolveMember } from "../../../utils"; +import { CensorPluginType } from "../types"; +import { censorMessage } from "./censorMessage"; + export async function applyFiltersToMsg( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index 69ed2859..62249446 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -1,10 +1,10 @@ +import { TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { CensorPluginType } from "../types"; +import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars, resolveUser } from "../../../utils"; -import { disableCodeBlocks, deactivateMentions } from "knub/dist/helpers"; -import { TextChannel } from "discord.js"; +import { resolveUser, stripObjectToScalars } from "../../../utils"; +import { CensorPluginType } from "../types"; export async function censorMessage( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Censor/util/onMessageCreate.ts b/backend/src/plugins/Censor/util/onMessageCreate.ts index fb9cfaeb..482e9cff 100644 --- a/backend/src/plugins/Censor/util/onMessageCreate.ts +++ b/backend/src/plugins/Censor/util/onMessageCreate.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { CensorPluginType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { applyFiltersToMsg } from "./applyFiltersToMsg"; import { messageLock } from "../../../utils/lockNameHelpers"; +import { CensorPluginType } from "../types"; +import { applyFiltersToMsg } from "./applyFiltersToMsg"; export async function onMessageCreate(pluginData: GuildPluginData, savedMessage: SavedMessage) { if (savedMessage.is_bot) return; diff --git a/backend/src/plugins/Censor/util/onMessageUpdate.ts b/backend/src/plugins/Censor/util/onMessageUpdate.ts index 7afd4c17..d17bf6b0 100644 --- a/backend/src/plugins/Censor/util/onMessageUpdate.ts +++ b/backend/src/plugins/Censor/util/onMessageUpdate.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { CensorPluginType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { applyFiltersToMsg } from "./applyFiltersToMsg"; import { messageLock } from "../../../utils/lockNameHelpers"; +import { CensorPluginType } from "../types"; +import { applyFiltersToMsg } from "./applyFiltersToMsg"; export async function onMessageUpdate(pluginData: GuildPluginData, savedMessage: SavedMessage) { if (savedMessage.is_bot) return; diff --git a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts index 249a5ef0..3349c242 100644 --- a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts +++ b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts @@ -1,8 +1,8 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ChannelArchiverPluginType } from "./types"; -import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd"; import * as t from "io-ts"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd"; +import { ChannelArchiverPluginType } from "./types"; export const ChannelArchiverPlugin = zeppelinGuildPlugin()({ name: "channel_archiver", diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 87b61934..3d4112a9 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -1,10 +1,10 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { channelArchiverCmd } from "../types"; -import { isOwner, sendErrorMessage } from "../../../pluginUtils"; -import { confirm, SECONDS, noop } from "../../../utils"; import moment from "moment-timezone"; -import { rehostAttachment } from "../rehostAttachment"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { isOwner, sendErrorMessage } from "../../../pluginUtils"; +import { confirm, noop, SECONDS } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { rehostAttachment } from "../rehostAttachment"; +import { channelArchiverCmd } from "../types"; const MAX_ARCHIVED_MESSAGES = 5000; const MAX_MESSAGES_PER_FETCH = 100; diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index bf05d122..f51c6173 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -1,6 +1,6 @@ -import { downloadFile } from "../../utils"; -import fs from "fs"; import { MessageAttachment, MessageOptions, TextChannel } from "discord.js"; +import fs from "fs"; +import { downloadFile } from "../../utils"; const fsp = fs.promises; const MAX_ATTACHMENT_REHOST_SIZE = 1024 * 1024 * 8; diff --git a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts index d3a89865..64bda1c1 100644 --- a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts +++ b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts @@ -1,9 +1,9 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { CompanionChannelsPluginType, ConfigSchema } from "./types"; +import { CooldownManager } from "knub"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; -import { CooldownManager } from "knub"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { VoiceStateUpdateEvt } from "./events/VoiceStateUpdateEvt"; +import { CompanionChannelsPluginType, ConfigSchema } from "./types"; const defaultOptions = { config: { diff --git a/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts b/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts index 142e9b17..07251fdb 100644 --- a/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts +++ b/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts @@ -1,5 +1,5 @@ -import { companionChannelsEvt } from "../types"; import { handleCompanionPermissions } from "../functions/handleCompanionPermissions"; +import { companionChannelsEvt } from "../types"; export const VoiceStateUpdateEvt = companionChannelsEvt({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index 1a338251..3ea79867 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -1,11 +1,11 @@ -import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; -import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId"; +import { Permissions, StageChannel, TextChannel, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; - +import { LogType } from "../../../data/LogType"; import { isDiscordRESTError, MINUTES } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { LogType } from "../../../data/LogType"; -import { VoiceChannel, TextChannel, Permissions, StageChannel } from "discord.js"; +import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; +import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId"; + const ERROR_COOLDOWN_KEY = "errorCooldown"; const ERROR_COOLDOWN = 5 * MINUTES; diff --git a/backend/src/plugins/CompanionChannels/types.ts b/backend/src/plugins/CompanionChannels/types.ts index 1a91800d..1168b4f8 100644 --- a/backend/src/plugins/CompanionChannels/types.ts +++ b/backend/src/plugins/CompanionChannels/types.ts @@ -1,8 +1,6 @@ import * as t from "io-ts"; -import { tNullable } from "../../utils"; import { BasePluginType, CooldownManager, typedGuildEventListener } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { tNullable } from "../../utils"; // Permissions using these numbers: https://abal.moe/Eris/docs/reference (add all allowed/denied ones up) export const CompanionChannelOpts = t.type({ diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index 028c6a0d..fe23cd6d 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -1,33 +1,32 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, CountersPluginType, TTrigger } from "./types"; +import { EventEmitter } from "events"; +import { PluginOptions } from "knub"; +import { ConfigPreprocessorFn } from "knub/dist/config/configTypes"; +import { + buildCounterConditionString, + CounterTrigger, + getReverseCounterComparisonOp, + parseCounterConditionString +} from "../../data/entities/CounterTrigger"; import { GuildCounters } from "../../data/GuildCounters"; import { mapToPublicFn } from "../../pluginUtils"; -import { changeCounterValue } from "./functions/changeCounterValue"; -import { setCounterValue } from "./functions/setCounterValue"; -import { convertDelayStringToMS, MINUTES, SECONDS } from "../../utils"; -import { EventEmitter } from "events"; -import { onCounterEvent } from "./functions/onCounterEvent"; -import { offCounterEvent } from "./functions/offCounterEvent"; -import { emitCounterEvent } from "./functions/emitCounterEvent"; -import { ConfigPreprocessorFn } from "knub/dist/config/configTypes"; -import { decayCounter } from "./functions/decayCounter"; +import { convertDelayStringToMS, MINUTES } from "../../utils"; import { StrictValidationError } from "../../validatorUtils"; -import { PluginOptions } from "knub"; -import { ViewCounterCmd } from "./commands/ViewCounterCmd"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { AddCounterCmd } from "./commands/AddCounterCmd"; +import { CountersListCmd } from "./commands/CountersListCmd"; +import { ResetAllCounterValuesCmd } from "./commands/ResetAllCounterValuesCmd"; +import { ResetCounterCmd } from "./commands/ResetCounterCmd"; import { SetCounterCmd } from "./commands/SetCounterCmd"; -import { - buildCounterConditionString, - CounterTrigger, - getReverseCounterComparisonOp, - parseCounterConditionString, -} from "../../data/entities/CounterTrigger"; +import { ViewCounterCmd } from "./commands/ViewCounterCmd"; +import { changeCounterValue } from "./functions/changeCounterValue"; +import { counterExists } from "./functions/counterExists"; +import { decayCounter } from "./functions/decayCounter"; import { getPrettyNameForCounter } from "./functions/getPrettyNameForCounter"; import { getPrettyNameForCounterTrigger } from "./functions/getPrettyNameForCounterTrigger"; -import { counterExists } from "./functions/counterExists"; -import { ResetAllCounterValuesCmd } from "./commands/ResetAllCounterValuesCmd"; -import { CountersListCmd } from "./commands/CountersListCmd"; -import { ResetCounterCmd } from "./commands/ResetCounterCmd"; +import { offCounterEvent } from "./functions/offCounterEvent"; +import { onCounterEvent } from "./functions/onCounterEvent"; +import { setCounterValue } from "./functions/setCounterValue"; +import { ConfigSchema, CountersPluginType, TTrigger } from "./types"; const MAX_COUNTERS = 5; const MAX_TRIGGERS_PER_COUNTER = 5; diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 779c83f0..455c4549 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -1,12 +1,12 @@ +import { TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; -import { CountersPluginType } from "../types"; +import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { waitForReply } from "knub/dist/helpers"; - import { resolveUser, UnknownUser } from "../../../utils"; import { changeCounterValue } from "../functions/changeCounterValue"; -import { TextChannel } from "discord.js"; +import { CountersPluginType } from "../types"; + export const AddCounterCmd = typedGuildCommand()({ trigger: ["counters add", "counter add", "addcounter"], diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index 5e35a28a..c92a2fe4 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -1,8 +1,8 @@ import { typedGuildCommand } from "knub"; -import { CountersPluginType } from "../types"; import { sendErrorMessage } from "../../../pluginUtils"; import { trimMultilineString, ucfirst } from "../../../utils"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; +import { CountersPluginType } from "../types"; export const CountersListCmd = typedGuildCommand()({ trigger: ["counters list", "counter list", "counters"], diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 021c93c3..a4cc3587 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -1,11 +1,10 @@ import { typedGuildCommand } from "knub"; -import { CountersPluginType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; - -import { confirm, MINUTES, noop, trimMultilineString } from "../../../utils"; +import { confirm, noop, trimMultilineString } from "../../../utils"; import { resetAllCounterValues } from "../functions/resetAllCounterValues"; -import { counterIdLock } from "../../../utils/lockNameHelpers"; +import { CountersPluginType } from "../types"; + export const ResetAllCounterValuesCmd = typedGuildCommand()({ trigger: ["counters reset_all"], diff --git a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts index 736f66f8..c684fa7b 100644 --- a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts @@ -1,12 +1,12 @@ +import { TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; -import { CountersPluginType } from "../types"; +import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { waitForReply } from "knub/dist/helpers"; - import { resolveUser, UnknownUser } from "../../../utils"; import { setCounterValue } from "../functions/setCounterValue"; -import { TextChannel } from "discord.js"; +import { CountersPluginType } from "../types"; + export const ResetCounterCmd = typedGuildCommand()({ trigger: ["counters reset", "counter reset", "resetcounter"], diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 1158b5a6..02ced104 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -1,12 +1,12 @@ +import { TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; -import { CountersPluginType } from "../types"; +import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { waitForReply } from "knub/dist/helpers"; - import { resolveUser, UnknownUser } from "../../../utils"; import { setCounterValue } from "../functions/setCounterValue"; -import { TextChannel } from "discord.js"; +import { CountersPluginType } from "../types"; + export const SetCounterCmd = typedGuildCommand()({ trigger: ["counters set", "counter set", "setcounter"], diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index bafbcb76..73ce6287 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -1,11 +1,11 @@ +import { TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; -import { CountersPluginType } from "../types"; +import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { waitForReply } from "knub/dist/helpers"; - import { resolveUser, UnknownUser } from "../../../utils"; -import { TextChannel } from "discord.js"; +import { CountersPluginType } from "../types"; + export const ViewCounterCmd = typedGuildCommand()({ trigger: ["counters view", "counter view", "viewcounter", "counter"], diff --git a/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts b/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts index 19998225..263855dc 100644 --- a/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; import { CounterTrigger } from "../../../data/entities/CounterTrigger"; +import { CountersPluginType } from "../types"; import { emitCounterEvent } from "./emitCounterEvent"; export async function checkAllValuesForReverseTrigger( diff --git a/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts b/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts index 02b02e5f..0a42673f 100644 --- a/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; import { CounterTrigger } from "../../../data/entities/CounterTrigger"; +import { CountersPluginType } from "../types"; import { emitCounterEvent } from "./emitCounterEvent"; export async function checkAllValuesForTrigger( diff --git a/backend/src/plugins/Counters/functions/checkCounterTrigger.ts b/backend/src/plugins/Counters/functions/checkCounterTrigger.ts index 5bdd1b05..8923abf5 100644 --- a/backend/src/plugins/Counters/functions/checkCounterTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkCounterTrigger.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; import { CounterTrigger } from "../../../data/entities/CounterTrigger"; +import { CountersPluginType } from "../types"; import { emitCounterEvent } from "./emitCounterEvent"; export async function checkCounterTrigger( diff --git a/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts b/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts index e601dd9d..544d4066 100644 --- a/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; import { CounterTrigger } from "../../../data/entities/CounterTrigger"; +import { CountersPluginType } from "../types"; import { emitCounterEvent } from "./emitCounterEvent"; export async function checkReverseCounterTrigger( diff --git a/backend/src/plugins/Counters/functions/decayCounter.ts b/backend/src/plugins/Counters/functions/decayCounter.ts index 7db4cef3..c7b813ea 100644 --- a/backend/src/plugins/Counters/functions/decayCounter.ts +++ b/backend/src/plugins/Counters/functions/decayCounter.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; -import { checkAllValuesForTrigger } from "./checkAllValuesForTrigger"; -import { checkAllValuesForReverseTrigger } from "./checkAllValuesForReverseTrigger"; import { counterIdLock } from "../../../utils/lockNameHelpers"; +import { CountersPluginType } from "../types"; +import { checkAllValuesForReverseTrigger } from "./checkAllValuesForReverseTrigger"; +import { checkAllValuesForTrigger } from "./checkAllValuesForTrigger"; export async function decayCounter( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/emitCounterEvent.ts b/backend/src/plugins/Counters/functions/emitCounterEvent.ts index ad131e54..30e4bfea 100644 --- a/backend/src/plugins/Counters/functions/emitCounterEvent.ts +++ b/backend/src/plugins/Counters/functions/emitCounterEvent.ts @@ -1,5 +1,5 @@ -import { CounterEvents, CountersPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { CounterEvents, CountersPluginType } from "../types"; export function emitCounterEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts b/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts index 766b4ef3..c9fd0342 100644 --- a/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts +++ b/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts @@ -1,5 +1,5 @@ -import { CountersPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { CountersPluginType } from "../types"; export function getPrettyNameForCounter(pluginData: GuildPluginData, counterName: string) { const config = pluginData.config.get(); diff --git a/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts b/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts index d7a2b923..1445bdd8 100644 --- a/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts +++ b/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts @@ -1,5 +1,5 @@ -import { CountersPluginType, TTrigger } from "../types"; import { GuildPluginData } from "knub"; +import { CountersPluginType, TTrigger } from "../types"; export function getPrettyNameForCounterTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/offCounterEvent.ts b/backend/src/plugins/Counters/functions/offCounterEvent.ts index 66ee9624..08c28cff 100644 --- a/backend/src/plugins/Counters/functions/offCounterEvent.ts +++ b/backend/src/plugins/Counters/functions/offCounterEvent.ts @@ -1,5 +1,5 @@ -import { CounterEventEmitter, CountersPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { CounterEventEmitter, CountersPluginType } from "../types"; export function offCounterEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/onCounterEvent.ts b/backend/src/plugins/Counters/functions/onCounterEvent.ts index 1a3aa6fd..1789571b 100644 --- a/backend/src/plugins/Counters/functions/onCounterEvent.ts +++ b/backend/src/plugins/Counters/functions/onCounterEvent.ts @@ -1,5 +1,5 @@ -import { CounterEvents, CountersPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { CounterEvents, CountersPluginType } from "../types"; export function onCounterEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/types.ts b/backend/src/plugins/Counters/types.ts index 1efdc474..57bc69d6 100644 --- a/backend/src/plugins/Counters/types.ts +++ b/backend/src/plugins/Counters/types.ts @@ -1,9 +1,9 @@ +import { EventEmitter } from "events"; import * as t from "io-ts"; import { BasePluginType } from "knub"; +import { CounterTrigger } from "../../data/entities/CounterTrigger"; import { GuildCounters } from "../../data/GuildCounters"; import { tDelayString, tNullable } from "../../utils"; -import { EventEmitter } from "events"; -import { CounterTrigger } from "../../data/entities/CounterTrigger"; import Timeout = NodeJS.Timeout; export const Trigger = t.type({ diff --git a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts index 43d25250..c1c183eb 100644 --- a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts +++ b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts @@ -1,9 +1,9 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, CustomEventsPluginType } from "./types"; -import { typedGuildCommand, parseSignature } from "knub"; +import { parseSignature, typedGuildCommand } from "knub"; import { commandTypes } from "../../commandTypes"; import { stripObjectToScalars } from "../../utils"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { runEvent } from "./functions/runEvent"; +import { ConfigSchema, CustomEventsPluginType } from "./types"; const defaultOptions = { config: { diff --git a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts index f356e6f9..b5549bce 100644 --- a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts +++ b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts @@ -1,10 +1,10 @@ -import { GuildPluginData } from "knub"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; import * as t from "io-ts"; +import { GuildPluginData } from "knub"; +import { canActOn } from "../../../pluginUtils"; import { renderTemplate } from "../../../templateFormatter"; import { resolveMember } from "../../../utils"; import { ActionError } from "../ActionError"; -import { canActOn } from "../../../pluginUtils"; +import { CustomEventsPluginType, TCustomEvent } from "../types"; export const AddRoleAction = t.type({ type: t.literal("add_role"), diff --git a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts index 985ff14c..e9e4fac1 100644 --- a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts +++ b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts @@ -1,10 +1,10 @@ -import { GuildPluginData } from "knub"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; import * as t from "io-ts"; -import { renderTemplate } from "../../../templateFormatter"; +import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; -import { ActionError } from "../ActionError"; +import { renderTemplate } from "../../../templateFormatter"; import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { ActionError } from "../ActionError"; +import { CustomEventsPluginType, TCustomEvent } from "../types"; export const CreateCaseAction = t.type({ type: t.literal("create_case"), diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts index d08abfcb..63c381cc 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts @@ -1,8 +1,8 @@ -import { GuildPluginData } from "knub"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; import * as t from "io-ts"; +import { GuildPluginData } from "knub"; import { convertDelayStringToMS, noop, tDelayString } from "../../../utils"; import { ActionError } from "../ActionError"; +import { CustomEventsPluginType, TCustomEvent } from "../types"; export const MakeRoleMentionableAction = t.type({ type: t.literal("make_role_mentionable"), diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts index ea75ff12..de0a413c 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; import * as t from "io-ts"; +import { GuildPluginData } from "knub"; import { ActionError } from "../ActionError"; +import { CustomEventsPluginType, TCustomEvent } from "../types"; export const MakeRoleUnmentionableAction = t.type({ type: t.literal("make_role_unmentionable"), diff --git a/backend/src/plugins/CustomEvents/actions/messageAction.ts b/backend/src/plugins/CustomEvents/actions/messageAction.ts index fe03eda0..9fa91ba0 100644 --- a/backend/src/plugins/CustomEvents/actions/messageAction.ts +++ b/backend/src/plugins/CustomEvents/actions/messageAction.ts @@ -1,9 +1,9 @@ -import { GuildPluginData } from "knub"; -import { CustomEventsPluginType } from "../types"; +import { TextChannel } from "discord.js"; import * as t from "io-ts"; +import { GuildPluginData } from "knub"; import { renderTemplate } from "../../../templateFormatter"; import { ActionError } from "../ActionError"; -import { TextChannel } from "discord.js"; +import { CustomEventsPluginType } from "../types"; export const MessageAction = t.type({ type: t.literal("message"), diff --git a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts index 6d8f0731..176a768e 100644 --- a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts +++ b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts @@ -1,11 +1,11 @@ -import { GuildPluginData } from "knub"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { VoiceChannel } from "discord.js"; import * as t from "io-ts"; +import { GuildPluginData } from "knub"; +import { canActOn } from "../../../pluginUtils"; import { renderTemplate } from "../../../templateFormatter"; import { resolveMember } from "../../../utils"; import { ActionError } from "../ActionError"; -import { canActOn } from "../../../pluginUtils"; -import { VoiceChannel } from "discord.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types"; export const MoveToVoiceChannelAction = t.type({ type: t.literal("move_to_vc"), diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index 24555c2e..4203d2a8 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; import * as t from "io-ts"; +import { GuildPluginData } from "knub"; import { ActionError } from "../ActionError"; +import { CustomEventsPluginType, TCustomEvent } from "../types"; export const SetChannelPermissionOverridesAction = t.type({ type: t.literal("set_channel_permission_overrides"), diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 5a4121ac..11ae8aaf 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -1,16 +1,16 @@ +import { Message, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; import { sendErrorMessage } from "../../../pluginUtils"; import { ActionError } from "../ActionError"; - import { addRoleAction } from "../actions/addRoleAction"; import { createCaseAction } from "../actions/createCaseAction"; -import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction"; -import { messageAction } from "../actions/messageAction"; import { makeRoleMentionableAction } from "../actions/makeRoleMentionableAction"; import { makeRoleUnmentionableAction } from "../actions/makeRoleUnmentionableAction"; +import { messageAction } from "../actions/messageAction"; +import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction"; import { setChannelPermissionOverridesAction } from "../actions/setChannelPermissionOverrides"; -import { Message, TextChannel } from "discord.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types"; + export async function runEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/CustomEvents/types.ts b/backend/src/plugins/CustomEvents/types.ts index 44058777..48628376 100644 --- a/backend/src/plugins/CustomEvents/types.ts +++ b/backend/src/plugins/CustomEvents/types.ts @@ -2,10 +2,10 @@ import * as t from "io-ts"; import { BasePluginType } from "knub"; import { AddRoleAction } from "./actions/addRoleAction"; import { CreateCaseAction } from "./actions/createCaseAction"; -import { MoveToVoiceChannelAction } from "./actions/moveToVoiceChannelAction"; -import { MessageAction } from "./actions/messageAction"; import { MakeRoleMentionableAction } from "./actions/makeRoleMentionableAction"; import { MakeRoleUnmentionableAction } from "./actions/makeRoleUnmentionableAction"; +import { MessageAction } from "./actions/messageAction"; +import { MoveToVoiceChannelAction } from "./actions/moveToVoiceChannelAction"; import { SetChannelPermissionOverridesAction } from "./actions/setChannelPermissionOverrides"; // Triggers diff --git a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts index ca322168..a8fc7432 100644 --- a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts +++ b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts @@ -1,8 +1,8 @@ -import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; -import { BasePluginType, typedGlobalEventListener, GlobalPluginData } from "knub"; -import * as t from "io-ts"; -import { AllowedGuilds } from "../../data/AllowedGuilds"; import { Guild } from "discord.js"; +import * as t from "io-ts"; +import { BasePluginType, GlobalPluginData, typedGlobalEventListener } from "knub"; +import { AllowedGuilds } from "../../data/AllowedGuilds"; +import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; interface GuildAccessMonitorPluginType extends BasePluginType { config: {}; diff --git a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts index 5316232f..c48745e1 100644 --- a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts +++ b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts @@ -1,8 +1,8 @@ -import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; -import { GuildConfigReloaderPluginType } from "./types"; -import { Configs } from "../../data/Configs"; -import { reloadChangedGuilds } from "./functions/reloadChangedGuilds"; import * as t from "io-ts"; +import { Configs } from "../../data/Configs"; +import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; +import { reloadChangedGuilds } from "./functions/reloadChangedGuilds"; +import { GuildConfigReloaderPluginType } from "./types"; export const GuildConfigReloaderPlugin = zeppelinGlobalPlugin()({ name: "guild_config_reloader", diff --git a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts index 10cd97c0..65571b46 100644 --- a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts +++ b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts @@ -1,6 +1,6 @@ import { GlobalPluginData } from "knub"; -import { GuildConfigReloaderPluginType } from "../types"; import { SECONDS } from "../../../utils"; +import { GuildConfigReloaderPluginType } from "../types"; const CHECK_INTERVAL = 1 * SECONDS; diff --git a/backend/src/plugins/GuildConfigReloader/types.ts b/backend/src/plugins/GuildConfigReloader/types.ts index ded863ee..94ada5cf 100644 --- a/backend/src/plugins/GuildConfigReloader/types.ts +++ b/backend/src/plugins/GuildConfigReloader/types.ts @@ -1,6 +1,6 @@ import { BasePluginType } from "knub"; -import { TConfigSchema } from "../Mutes/types"; import { Configs } from "../../data/Configs"; +import { TConfigSchema } from "../Mutes/types"; import Timeout = NodeJS.Timeout; export interface GuildConfigReloaderPluginType extends BasePluginType { diff --git a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts index 45858330..4591b228 100644 --- a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts +++ b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts @@ -1,9 +1,9 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { AllowedGuilds } from "../../data/AllowedGuilds"; -import { GuildInfoSaverPluginType } from "./types"; import { MINUTES } from "../../utils"; -import * as t from "io-ts"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { GuildInfoSaverPluginType } from "./types"; export const GuildInfoSaverPlugin = zeppelinGuildPlugin()({ name: "guild_info_saver", diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index b6bf2538..fc77d99a 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -1,15 +1,15 @@ import { PluginOptions } from "knub"; -import { ConfigSchema, LocateUserPluginType } from "./types"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { GuildVCAlerts } from "../../data/GuildVCAlerts"; -import { outdatedAlertsLoop } from "./utils/outdatedLoop"; -import { fillActiveAlertsList } from "./utils/fillAlertsList"; -import { WhereCmd } from "./commands/WhereCmd"; +import { trimPluginDescription } from "../../utils"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { FollowCmd } from "./commands/FollowCmd"; import { DeleteFollowCmd, ListFollowCmd } from "./commands/ListFollowCmd"; -import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts"; +import { WhereCmd } from "./commands/WhereCmd"; import { GuildBanRemoveAlertsEvt } from "./events/BanRemoveAlertsEvt"; -import { trimPluginDescription } from "../../utils"; +import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts"; +import { ConfigSchema, LocateUserPluginType } from "./types"; +import { fillActiveAlertsList } from "./utils/fillAlertsList"; +import { outdatedAlertsLoop } from "./utils/outdatedLoop"; import Timeout = NodeJS.Timeout; const defaultOptions: PluginOptions = { diff --git a/backend/src/plugins/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts index 74838673..5a8d7e5d 100644 --- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts @@ -1,9 +1,9 @@ -import { locateUserCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; -import { MINUTES, SECONDS } from "../../../utils"; +import moment from "moment-timezone"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { MINUTES, SECONDS } from "../../../utils"; +import { locateUserCmd } from "../types"; export const FollowCmd = locateUserCmd({ trigger: ["follow", "f"], diff --git a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts index 67ad383d..f8e669bc 100644 --- a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts @@ -1,7 +1,7 @@ -import { locateUserCmd } from "../types"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { createChunkedMessage, sorter } from "../../../utils"; +import { locateUserCmd } from "../types"; export const ListFollowCmd = locateUserCmd({ trigger: ["follows", "fs"], diff --git a/backend/src/plugins/LocateUser/commands/WhereCmd.ts b/backend/src/plugins/LocateUser/commands/WhereCmd.ts index 5cbdac4a..0ff00d91 100644 --- a/backend/src/plugins/LocateUser/commands/WhereCmd.ts +++ b/backend/src/plugins/LocateUser/commands/WhereCmd.ts @@ -1,6 +1,5 @@ -import { locateUserCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { resolveMember } from "../../../utils"; +import { locateUserCmd } from "../types"; import { sendWhere } from "../utils/sendWhere"; export const WhereCmd = locateUserCmd({ diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index 6e74ae4b..7912d7b8 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { LocateUserPluginType } from "../types"; -import { sendErrorMessage } from "../../../pluginUtils"; import { GuildMember, TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { LocateUserPluginType } from "../types"; export async function moveMember( pluginData: GuildPluginData, diff --git a/backend/src/plugins/LocateUser/utils/outdatedLoop.ts b/backend/src/plugins/LocateUser/utils/outdatedLoop.ts index 0e3f29cd..4236342d 100644 --- a/backend/src/plugins/LocateUser/utils/outdatedLoop.ts +++ b/backend/src/plugins/LocateUser/utils/outdatedLoop.ts @@ -1,7 +1,7 @@ -import { SECONDS } from "../../../utils"; -import { removeUserIdFromActiveAlerts } from "./removeUserIdFromActiveAlerts"; import { GuildPluginData } from "knub"; +import { SECONDS } from "../../../utils"; import { LocateUserPluginType } from "../types"; +import { removeUserIdFromActiveAlerts } from "./removeUserIdFromActiveAlerts"; const ALERT_LOOP_TIME = 30 * SECONDS; diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts index 882e4344..e88dcec9 100644 --- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts @@ -1,10 +1,10 @@ +import { TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LocateUserPluginType } from "../types"; import { resolveMember } from "../../../utils"; +import { LocateUserPluginType } from "../types"; +import { moveMember } from "./moveMember"; import { sendWhere } from "./sendWhere"; -import { moveMember } from "./moveMember"; -import { TextChannel } from "discord.js"; export async function sendAlerts(pluginData: GuildPluginData, userId: string) { const triggeredAlerts = await pluginData.state.alerts.getAlertsByUserId(userId); diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 4fb151b6..b9cc9cb8 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -1,9 +1,9 @@ -import { getInviteLink } from "knub/dist/helpers"; -import { createOrReuseInvite } from "./createOrReuseInvite"; -import { GuildPluginData } from "knub"; -import { LocateUserPluginType } from "../types"; -import { sendErrorMessage } from "../../../pluginUtils"; import { GuildMember, Invite, TextChannel, VoiceChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { getInviteLink } from "knub/dist/helpers"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { LocateUserPluginType } from "../types"; +import { createOrReuseInvite } from "./createOrReuseInvite"; export async function sendWhere( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 2d2be7b2..6de27037 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -1,28 +1,28 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, FORMAT_NO_TIMESTAMP, LogsPluginType } from "./types"; import DefaultLogMessages from "../../data/DefaultLogMessages.json"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { LogType } from "../../data/LogType"; +import { logger } from "../../logger"; +import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; +import { disableCodeBlocks } from "../../utils"; +import { CasesPlugin } from "../Cases/CasesPlugin"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { LogsChannelCreateEvt, LogsChannelDeleteEvt } from "./events/LogsChannelModifyEvts"; +import { LogsGuildMemberAddEvt } from "./events/LogsGuildMemberAddEvt"; +import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt"; +import { LogsRoleCreateEvt, LogsRoleDeleteEvt } from "./events/LogsRoleModifyEvts"; +import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts"; +import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts"; +import { ConfigSchema, FORMAT_NO_TIMESTAMP, LogsPluginType } from "./types"; +import { getLogMessage } from "./util/getLogMessage"; +import { log } from "./util/log"; import { onMessageDelete } from "./util/onMessageDelete"; import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk"; import { onMessageUpdate } from "./util/onMessageUpdate"; -import { LogsGuildMemberAddEvt } from "./events/LogsGuildMemberAddEvt"; -import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt"; -import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts"; -import { LogsChannelCreateEvt, LogsChannelDeleteEvt } from "./events/LogsChannelModifyEvts"; -import { LogsRoleCreateEvt, LogsRoleDeleteEvt } from "./events/LogsRoleModifyEvts"; -import { log } from "./util/log"; -import { LogType } from "../../data/LogType"; -import { getLogMessage } from "./util/getLogMessage"; -import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { disableCodeBlocks } from "../../utils"; -import { logger } from "../../logger"; -import { CasesPlugin } from "../Cases/CasesPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts index dad30a6a..fb7b9e74 100644 --- a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts @@ -1,6 +1,6 @@ -import { logsEvt } from "../types"; -import { stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars } from "../../../utils"; +import { logsEvt } from "../types"; export const LogsChannelCreateEvt = logsEvt({ event: "channelCreate", diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index ab7d7498..220543ac 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -1,9 +1,9 @@ -import { logsEvt } from "../types"; -import { stripObjectToScalars, UnknownUser } from "../../../utils"; -import { LogType } from "../../../data/LogType"; - -import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { GuildAuditLogs } from "discord.js"; +import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars, UnknownUser } from "../../../utils"; +import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; +import { logsEvt } from "../types"; + export const LogsGuildBanAddEvt = logsEvt({ event: "guildBanAdd", diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts index 71448dbb..e206b99a 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts @@ -1,9 +1,9 @@ -import { logsEvt } from "../types"; -import { stripObjectToScalars } from "../../../utils"; -import { LogType } from "../../../data/LogType"; -import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; +import moment from "moment-timezone"; +import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { logsEvt } from "../types"; export const LogsGuildMemberAddEvt = logsEvt({ event: "guildMemberAdd", diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts index cde1fbd8..69be59d3 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts @@ -1,6 +1,6 @@ -import { logsEvt } from "../types"; -import { stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars } from "../../../utils"; +import { logsEvt } from "../types"; export const LogsGuildMemberRemoveEvt = logsEvt({ event: "guildMemberRemove", diff --git a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts index 48a85448..7c5f2108 100644 --- a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts @@ -1,6 +1,6 @@ -import { logsEvt } from "../types"; -import { stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars } from "../../../utils"; +import { logsEvt } from "../types"; export const LogsRoleCreateEvt = logsEvt({ event: "roleCreate", diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index 170e8543..ba4b5d08 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -1,11 +1,11 @@ -import { logsEvt } from "../types"; -import { stripObjectToScalars, UnknownUser } from "../../../utils"; - -import { LogType } from "../../../data/LogType"; -import isEqual from "lodash.isequal"; -import diff from "lodash.difference"; -import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { GuildAuditLogs } from "discord.js"; +import diff from "lodash.difference"; +import isEqual from "lodash.isequal"; +import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars, UnknownUser } from "../../../utils"; +import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; +import { logsEvt } from "../types"; + export const LogsGuildMemberUpdateEvt = logsEvt({ event: "guildMemberUpdate", diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index 61ce1593..50d31bfa 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -1,6 +1,6 @@ -import { logsEvt } from "../types"; -import { stripObjectToScalars } from "../../../utils"; import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars } from "../../../utils"; +import { logsEvt } from "../types"; export const LogsVoiceStateUpdateEvt = logsEvt({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/Logs/types.ts b/backend/src/plugins/Logs/types.ts index bdb96a4d..56178d6b 100644 --- a/backend/src/plugins/Logs/types.ts +++ b/backend/src/plugins/Logs/types.ts @@ -1,12 +1,12 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildEventListener } from "knub"; -import { TRegex } from "../../validatorUtils"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; -import { tMessageContent, tNullable } from "../../utils"; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { RegExpRunner } from "../../RegExpRunner"; +import { tMessageContent, tNullable } from "../../utils"; +import { TRegex } from "../../validatorUtils"; export const tLogFormats = t.record(t.string, t.union([t.string, tMessageContent])); export type TLogFormats = t.TypeOf; diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts index 06baebc5..435264e3 100644 --- a/backend/src/plugins/Logs/util/getLogMessage.ts +++ b/backend/src/plugins/Logs/util/getLogMessage.ts @@ -1,19 +1,17 @@ -import { GuildPluginData } from "knub"; -import { FORMAT_NO_TIMESTAMP, LogsPluginType, TLogChannel, TLogFormats } from "../types"; -import { LogType } from "../../../data/LogType"; -import { - verboseUserMention, - verboseUserName, - verboseChannelMention, - messageSummary, - resolveMember, - renderRecursively, -} from "../../../utils"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; -import { logger } from "../../../logger"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { MessageOptions } from "discord.js"; +import { GuildPluginData } from "knub"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { LogType } from "../../../data/LogType"; +import { logger } from "../../../logger"; +import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; +import { + messageSummary, + + renderRecursively, resolveMember, verboseChannelMention, verboseUserMention, + verboseUserName +} from "../../../utils"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { FORMAT_NO_TIMESTAMP, LogsPluginType, TLogChannel } from "../types"; export async function getLogMessage( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 0bb8c616..3d9d438c 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -1,12 +1,12 @@ -import { GuildPluginData } from "knub"; -import { LogsPluginType, TLogChannelMap } from "../types"; -import { LogType } from "../../../data/LogType"; - -import { createChunkedMessage, get, noop } from "../../../utils"; -import { getLogMessage } from "./getLogMessage"; -import { allowTimeout } from "../../../RegExpRunner"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; import { MessageMentionTypes, TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { LogType } from "../../../data/LogType"; +import { allowTimeout } from "../../../RegExpRunner"; +import { createChunkedMessage, get, noop } from "../../../utils"; +import { LogsPluginType, TLogChannelMap } from "../types"; +import { getLogMessage } from "./getLogMessage"; + const excludedUserProps = ["user", "member", "mod"]; const excludedRoleProps = ["message.member.roles", "member.roles"]; diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index a7437713..c64185d8 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -1,12 +1,12 @@ -import { SavedMessage } from "../../../data/entities/SavedMessage"; - -import { useMediaUrls, stripObjectToScalars, resolveUser } from "../../../utils"; -import { LogType } from "../../../data/LogType"; -import moment from "moment-timezone"; -import { GuildPluginData } from "knub"; -import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { MessageAttachment } from "discord.js"; +import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { LogType } from "../../../data/LogType"; +import { resolveUser, stripObjectToScalars, useMediaUrls } from "../../../utils"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; + export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); diff --git a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts index d0fac9c5..6e23315a 100644 --- a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { LogsPluginType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { getBaseUrl } from "../../../pluginUtils"; +import { LogsPluginType } from "../types"; export async function onMessageDeleteBulk(pluginData: GuildPluginData, savedMessages: SavedMessage[]) { const channel = pluginData.guild.channels.cache.get(savedMessages[0].channel_id); diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index 1075d63e..87631bbc 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -1,11 +1,11 @@ -import { GuildPluginData } from "knub"; -import { LogsPluginType } from "../types"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; - -import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars, resolveUser } from "../../../utils"; -import cloneDeep from "lodash.clonedeep"; import { MessageEmbed } from "discord.js"; +import { GuildPluginData } from "knub"; +import cloneDeep from "lodash.clonedeep"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { LogType } from "../../../data/LogType"; +import { resolveUser, stripObjectToScalars } from "../../../utils"; +import { LogsPluginType } from "../types"; + export async function onMessageUpdate( pluginData: GuildPluginData, diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts index 955663cb..eb529ffa 100644 --- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts +++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts @@ -1,10 +1,10 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, MessageSaverPluginType } from "./types"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { PluginOptions } from "knub"; -import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB"; import { SavePinsToDBCmd } from "./commands/SavePinsToDB"; +import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts"; +import { ConfigSchema, MessageSaverPluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts index 226a8a2b..3d2456e8 100644 --- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts @@ -1,7 +1,7 @@ -import { messageSaverCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { saveMessagesToDB } from "../saveMessagesToDB"; import { sendSuccessMessage } from "../../../pluginUtils"; +import { saveMessagesToDB } from "../saveMessagesToDB"; +import { messageSaverCmd } from "../types"; export const SaveMessagesToDBCmd = messageSaverCmd({ trigger: "save_messages_to_db", diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index a159a642..ede884d6 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -1,7 +1,7 @@ -import { messageSaverCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { saveMessagesToDB } from "../saveMessagesToDB"; import { sendSuccessMessage } from "../../../pluginUtils"; +import { saveMessagesToDB } from "../saveMessagesToDB"; +import { messageSaverCmd } from "../types"; export const SavePinsToDBCmd = messageSaverCmd({ trigger: "save_pins_to_db", diff --git a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts index dd0f3b80..1ce82aa9 100644 --- a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts @@ -1,6 +1,6 @@ -import { MessageSaverPluginType } from "./types"; +import { Message, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { TextChannel, Message } from "discord.js"; +import { MessageSaverPluginType } from "./types"; export async function saveMessagesToDB( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index f0a51c69..3be7332a 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -1,51 +1,51 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { CasesPlugin } from "../Cases/CasesPlugin"; -import { MutesPlugin } from "../Mutes/MutesPlugin"; -import { BanOptions, ConfigSchema, KickOptions, ModActionsPluginType, WarnOptions } from "./types"; -import { CreateBanCaseOnManualBanEvt } from "./events/CreateBanCaseOnManualBanEvt"; -import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManualUnbanEvt"; -import { CreateKickCaseOnManualKickEvt } from "./events/CreateKickCaseOnManualKickEvt"; -import { UpdateCmd } from "./commands/UpdateCmd"; -import { NoteCmd } from "./commands/NoteCmd"; -import { WarnCmd } from "./commands/WarnCmd"; -import { MuteCmd } from "./commands/MuteCmd"; -import { PostAlertOnMemberJoinEvt } from "./events/PostAlertOnMemberJoinEvt"; -import { ForcemuteCmd } from "./commands/ForcemuteCmd"; -import { UnmuteCmd } from "./commands/UnmuteCmd"; -import { KickCmd } from "./commands/KickCmd"; -import { SoftbanCmd } from "./commands/SoftbanCommand"; -import { BanCmd } from "./commands/BanCmd"; -import { UnbanCmd } from "./commands/UnbanCmd"; -import { ForcebanCmd } from "./commands/ForcebanCmd"; -import { MassunbanCmd } from "./commands/MassUnbanCmd"; -import { MassbanCmd } from "./commands/MassBanCmd"; -import { AddCaseCmd } from "./commands/AddCaseCmd"; -import { CaseCmd } from "./commands/CaseCmd"; -import { CasesUserCmd } from "./commands/CasesUserCmd"; -import { CasesModCmd } from "./commands/CasesModCmd"; -import { HideCaseCmd } from "./commands/HideCaseCmd"; -import { UnhideCaseCmd } from "./commands/UnhideCaseCmd"; -import { GuildMutes } from "../../data/GuildMutes"; +import { GuildMember, Message } from "discord.js"; +import { EventEmitter } from "events"; import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; -import { ForceUnmuteCmd } from "./commands/ForceunmuteCmd"; -import { warnMember } from "./functions/warnMember"; - -import { kickMember } from "./functions/kickMember"; -import { banUserId } from "./functions/banUserId"; -import { MassmuteCmd } from "./commands/MassmuteCmd"; -import { MINUTES, trimPluginDescription } from "../../utils"; -import { DeleteCaseCmd } from "./commands/DeleteCaseCmd"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { GuildMutes } from "../../data/GuildMutes"; import { GuildTempbans } from "../../data/GuildTempbans"; -import { outdatedTempbansLoop } from "./functions/outdatedTempbansLoop"; -import { EventEmitter } from "events"; import { mapToPublicFn } from "../../pluginUtils"; -import { onModActionsEvent } from "./functions/onModActionsEvent"; -import { offModActionsEvent } from "./functions/offModActionsEvent"; -import { updateCase } from "./functions/updateCase"; import { Queue } from "../../Queue"; -import { GuildMember, Message } from "discord.js"; +import { MINUTES, trimPluginDescription } from "../../utils"; +import { CasesPlugin } from "../Cases/CasesPlugin"; +import { MutesPlugin } from "../Mutes/MutesPlugin"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { AddCaseCmd } from "./commands/AddCaseCmd"; +import { BanCmd } from "./commands/BanCmd"; +import { CaseCmd } from "./commands/CaseCmd"; +import { CasesModCmd } from "./commands/CasesModCmd"; +import { CasesUserCmd } from "./commands/CasesUserCmd"; +import { DeleteCaseCmd } from "./commands/DeleteCaseCmd"; +import { ForcebanCmd } from "./commands/ForcebanCmd"; +import { ForcemuteCmd } from "./commands/ForcemuteCmd"; +import { ForceUnmuteCmd } from "./commands/ForceunmuteCmd"; +import { HideCaseCmd } from "./commands/HideCaseCmd"; +import { KickCmd } from "./commands/KickCmd"; +import { MassbanCmd } from "./commands/MassBanCmd"; +import { MassmuteCmd } from "./commands/MassmuteCmd"; +import { MassunbanCmd } from "./commands/MassUnbanCmd"; +import { MuteCmd } from "./commands/MuteCmd"; +import { NoteCmd } from "./commands/NoteCmd"; +import { SoftbanCmd } from "./commands/SoftbanCommand"; +import { UnbanCmd } from "./commands/UnbanCmd"; +import { UnhideCaseCmd } from "./commands/UnhideCaseCmd"; +import { UnmuteCmd } from "./commands/UnmuteCmd"; +import { UpdateCmd } from "./commands/UpdateCmd"; +import { WarnCmd } from "./commands/WarnCmd"; +import { CreateBanCaseOnManualBanEvt } from "./events/CreateBanCaseOnManualBanEvt"; +import { CreateKickCaseOnManualKickEvt } from "./events/CreateKickCaseOnManualKickEvt"; +import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManualUnbanEvt"; +import { PostAlertOnMemberJoinEvt } from "./events/PostAlertOnMemberJoinEvt"; +import { banUserId } from "./functions/banUserId"; +import { kickMember } from "./functions/kickMember"; +import { offModActionsEvent } from "./functions/offModActionsEvent"; +import { onModActionsEvent } from "./functions/onModActionsEvent"; +import { outdatedTempbansLoop } from "./functions/outdatedTempbansLoop"; +import { updateCase } from "./functions/updateCase"; +import { warnMember } from "./functions/warnMember"; +import { BanOptions, ConfigSchema, KickOptions, ModActionsPluginType, WarnOptions } from "./types"; + const defaultOptions = { config: { diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts index 7f2a551d..6dbfb67d 100644 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts @@ -1,12 +1,12 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveUser, resolveMember, stripObjectToScalars } from "../../../utils"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { CaseTypes } from "../../../data/CaseTypes"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; +import { modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index 1d113168..8ebc8e2a 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -1,18 +1,18 @@ -import { modActionsCmd, IgnoredEventType } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveUser, resolveMember, stripObjectToScalars, noop } from "../../../utils"; -import { isBanned } from "../functions/isBanned"; -import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { banUserId } from "../functions/banUserId"; -import { getMemberLevel } from "knub/dist/helpers"; import humanizeDuration from "humanize-duration"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { getMemberLevel } from "knub/dist/helpers"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; import { banLock } from "../../../utils/lockNameHelpers"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; +import { banUserId } from "../functions/banUserId"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; +import { isBanned } from "../functions/isBanned"; +import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; +import { modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/CaseCmd.ts b/backend/src/plugins/ModActions/commands/CaseCmd.ts index 6c50d4c8..d3d8ce95 100644 --- a/backend/src/plugins/ModActions/commands/CaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/CaseCmd.ts @@ -1,7 +1,7 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { modActionsCmd } from "../types"; export const CaseCmd = modActionsCmd({ trigger: "case", diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 49bbc937..7bc9d19f 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -1,15 +1,14 @@ -import { modActionsCmd } from "../types"; +import { MessageEmbedOptions, User } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { trimLines, createChunkedMessage, emptyEmbedValue, sorter, resolveUser } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { emptyEmbedValue, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; - -import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; -import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; -import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { createPaginatedMessage } from "../../../utils/createPaginatedMessage"; -import { MessageEmbedOptions, User } from "discord.js"; +import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; +import { getGuildPrefix } from "../../../utils/getGuildPrefix"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { modActionsCmd } from "../types"; + const opts = { mod: ct.userId({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index 7fa4f499..b4af16a4 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -1,22 +1,16 @@ -import { modActionsCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { - UnknownUser, - multiSorter, - trimLines, - createChunkedMessage, - resolveUser, - emptyEmbedValue, - chunkArray, -} from "../../../utils"; -import { getGuildPrefix } from "../../../utils/getGuildPrefix"; - -import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; -import { asyncMap } from "../../../utils/async"; -import { CaseTypes } from "../../../data/CaseTypes"; import { MessageEmbedOptions, User } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { + chunkArray, emptyEmbedValue, resolveUser, trimLines, UnknownUser +} from "../../../utils"; +import { asyncMap } from "../../../utils/async"; +import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; +import { getGuildPrefix } from "../../../utils/getGuildPrefix"; +import { modActionsCmd } from "../types"; + const opts = { expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index ecda9c25..6e99fb9f 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -1,16 +1,15 @@ -import { modActionsCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { helpers } from "knub"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; - -import { SECONDS, stripObjectToScalars, trimLines } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { LogType } from "../../../data/LogType"; -import moment from "moment-timezone"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { Case } from "../../../data/entities/Case"; import { TextChannel } from "discord.js"; +import { helpers } from "knub"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { Case } from "../../../data/entities/Case"; +import { LogType } from "../../../data/LogType"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { SECONDS, stripObjectToScalars, trimLines } from "../../../utils"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { modActionsCmd } from "../types"; + export const DeleteCaseCmd = modActionsCmd({ trigger: ["delete_case", "deletecase"], diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index 6ba06b74..a4ea8460 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -1,15 +1,13 @@ -import { modActionsCmd, IgnoredEventType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveUser, resolveMember, stripObjectToScalars } from "../../../utils"; -import { isBanned } from "../functions/isBanned"; -import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { banUserId } from "../functions/banUserId"; -import { ignoreEvent } from "../functions/ignoreEvent"; -import { LogType } from "../../../data/LogType"; import { CaseTypes } from "../../../data/CaseTypes"; +import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; +import { ignoreEvent } from "../functions/ignoreEvent"; +import { isBanned } from "../functions/isBanned"; +import { IgnoredEventType, modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts b/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts index af680374..18fe1228 100644 --- a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts @@ -1,8 +1,8 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn, sendErrorMessage } from "../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../utils"; import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; +import { modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts b/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts index e86a6408..8ce0ce14 100644 --- a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts @@ -1,8 +1,8 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveUser, resolveMember } from "../../../utils"; +import { resolveMember, resolveUser } from "../../../utils"; import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; +import { modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts b/backend/src/plugins/ModActions/commands/HideCaseCmd.ts index 0e12521f..38337d85 100644 --- a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/HideCaseCmd.ts @@ -1,6 +1,6 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { modActionsCmd } from "../types"; export const HideCaseCmd = modActionsCmd({ trigger: ["hide", "hidecase", "hide_case"], diff --git a/backend/src/plugins/ModActions/commands/KickCmd.ts b/backend/src/plugins/ModActions/commands/KickCmd.ts index d93e0369..080294d0 100644 --- a/backend/src/plugins/ModActions/commands/KickCmd.ts +++ b/backend/src/plugins/ModActions/commands/KickCmd.ts @@ -1,11 +1,6 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveUser, resolveMember } from "../../../utils"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; -import { isBanned } from "../functions/isBanned"; import { actualKickMemberCmd } from "../functions/actualKickMemberCmd"; +import { modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 758dd268..796caf19 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -1,21 +1,17 @@ -import { modActionsCmd, IgnoredEventType } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveUser, resolveMember, stripObjectToScalars, noop, MINUTES } from "../../../utils"; -import { isBanned } from "../functions/isBanned"; -import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { banUserId } from "../functions/banUserId"; -import { CaseTypes } from "../../../data/CaseTypes"; - -import { waitForReply } from "knub/dist/helpers"; -import { ignoreEvent } from "../functions/ignoreEvent"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { LogType } from "../../../data/LogType"; -import { performance } from "perf_hooks"; -import { humanizeDurationShort } from "../../../humanizeDurationShort"; -import { load } from "js-yaml"; import { TextChannel } from "discord.js"; +import { waitForReply } from "knub/dist/helpers"; +import { performance } from "perf_hooks"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { LogType } from "../../../data/LogType"; +import { humanizeDurationShort } from "../../../humanizeDurationShort"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { MINUTES, noop, stripObjectToScalars } from "../../../utils"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; +import { ignoreEvent } from "../functions/ignoreEvent"; +import { IgnoredEventType, modActionsCmd } from "../types"; + export const MassbanCmd = modActionsCmd({ trigger: "massban", diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index d4673dbf..758b7817 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -1,16 +1,16 @@ -import { modActionsCmd, IgnoredEventType } from "../types"; +import { TextChannel } from "discord.js"; +import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { LogType } from "../../../data/LogType"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { stripObjectToScalars } from "../../../utils"; -import { isBanned } from "../functions/isBanned"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { CaseTypes } from "../../../data/CaseTypes"; - -import { waitForReply } from "knub/dist/helpers"; -import { ignoreEvent } from "../functions/ignoreEvent"; import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogType } from "../../../data/LogType"; -import { TextChannel } from "discord.js"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; +import { ignoreEvent } from "../functions/ignoreEvent"; +import { isBanned } from "../functions/isBanned"; +import { IgnoredEventType, modActionsCmd } from "../types"; + export const MassunbanCmd = modActionsCmd({ trigger: "massunban", diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index 15c2e90f..46c8eeea 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -1,14 +1,14 @@ -import { modActionsCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { stripObjectToScalars } from "../../../utils"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; - +import { TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { TextChannel } from "discord.js"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { stripObjectToScalars } from "../../../utils"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; +import { modActionsCmd } from "../types"; + export const MassmuteCmd = modActionsCmd({ trigger: "massmute", diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/MuteCmd.ts index 4229bd6f..b51fbd1e 100644 --- a/backend/src/plugins/ModActions/commands/MuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MuteCmd.ts @@ -1,11 +1,11 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { noop, resolveMember, resolveUser } from "../../../utils"; -import { isBanned } from "../functions/isBanned"; - -import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; +import { resolveMember, resolveUser } from "../../../utils"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; +import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; +import { isBanned } from "../functions/isBanned"; +import { modActionsCmd } from "../types"; + const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index 4b31954d..c5cd7679 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -1,12 +1,11 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { Case } from "../../../data/entities/Case"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogType } from "../../../data/LogType"; import { CaseTypes } from "../../../data/CaseTypes"; +import { LogType } from "../../../data/LogType"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveUser, stripObjectToScalars } from "../../../utils"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; +import { modActionsCmd } from "../types"; export const NoteCmd = modActionsCmd({ trigger: "note", diff --git a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts index ea768f09..9bbb6415 100644 --- a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts +++ b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts @@ -1,7 +1,7 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { trimPluginDescription } from "../../../utils"; import { actualKickMemberCmd } from "../functions/actualKickMemberCmd"; +import { modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index ada9c975..c93933f0 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -1,12 +1,12 @@ -import { modActionsCmd, IgnoredEventType } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, hasPermission, sendSuccessMessage } from "../../../pluginUtils"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { LogType } from "../../../data/LogType"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveUser, stripObjectToScalars } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { LogType } from "../../../data/LogType"; import { ignoreEvent } from "../functions/ignoreEvent"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { IgnoredEventType, modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts index 5418b2a5..9fe9e208 100644 --- a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts @@ -1,6 +1,6 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { modActionsCmd } from "../types"; export const UnhideCaseCmd = modActionsCmd({ trigger: ["unhide", "unhidecase", "unhide_case"], diff --git a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts index dae00bea..f09c2e83 100644 --- a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts @@ -1,11 +1,11 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveUser, resolveMember, noop } from "../../../utils"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; +import { canActOn, sendErrorMessage } from "../../../pluginUtils"; +import { resolveMember, resolveUser } from "../../../utils"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; import { isBanned } from "../functions/isBanned"; -import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; +import { modActionsCmd } from "../types"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/UpdateCmd.ts b/backend/src/plugins/ModActions/commands/UpdateCmd.ts index 6c8d78ca..3310522e 100644 --- a/backend/src/plugins/ModActions/commands/UpdateCmd.ts +++ b/backend/src/plugins/ModActions/commands/UpdateCmd.ts @@ -1,6 +1,6 @@ -import { modActionsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { updateCase } from "../functions/updateCase"; +import { modActionsCmd } from "../types"; export const UpdateCmd = modActionsCmd({ trigger: ["update", "reason"], diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index 37f8d814..f85e1bdb 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -1,17 +1,15 @@ -import { modActionsCmd } from "../types"; +import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { Case } from "../../../data/entities/Case"; -import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogType } from "../../../data/LogType"; import { CaseTypes } from "../../../data/CaseTypes"; +import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { errorMessage, resolveMember, resolveUser } from "../../../utils"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { isBanned } from "../functions/isBanned"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; import { warnMember } from "../functions/warnMember"; -import { TextChannel } from "discord.js"; -import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; +import { modActionsCmd } from "../types"; export const WarnCmd = modActionsCmd({ trigger: "warn", diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index cc9b975c..997a05d7 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -1,14 +1,14 @@ -import { IgnoredEventType, modActionsEvt } from "../types"; -import { isEventIgnored } from "../functions/isEventIgnored"; -import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; - -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; -import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils"; -import { Case } from "../../../data/entities/Case"; import { GuildAuditLogs, User } from "discord.js"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { Case } from "../../../data/entities/Case"; +import { LogType } from "../../../data/LogType"; +import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; +import { isEventIgnored } from "../functions/isEventIgnored"; +import { IgnoredEventType, modActionsEvt } from "../types"; + /** * Create a BAN case automatically when a user is banned manually. diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index 3229058d..2a6af747 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -1,15 +1,15 @@ -import { IgnoredEventType, modActionsEvt } from "../types"; -import { isEventIgnored } from "../functions/isEventIgnored"; -import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; - -import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { GuildAuditLogs, User } from "discord.js"; import { CaseTypes } from "../../../data/CaseTypes"; -import { logger } from "../../../logger"; +import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; +import { logger } from "../../../logger"; import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; -import { Case } from "../../../data/entities/Case"; -import { GuildAuditLogs, User } from "discord.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; +import { isEventIgnored } from "../functions/isEventIgnored"; +import { IgnoredEventType, modActionsEvt } from "../types"; + /** * Create a KICK case automatically when a user is kicked manually. diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index 5d684e97..d0824fe1 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -1,14 +1,14 @@ -import { IgnoredEventType, modActionsEvt } from "../types"; -import { isEventIgnored } from "../functions/isEventIgnored"; -import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; - -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; -import { stripObjectToScalars, resolveUser, UnknownUser } from "../../../utils"; -import { LogType } from "../../../data/LogType"; -import { Case } from "../../../data/entities/Case"; import { GuildAuditLogs, User } from "discord.js"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { Case } from "../../../data/entities/Case"; +import { LogType } from "../../../data/LogType"; +import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; +import { isEventIgnored } from "../functions/isEventIgnored"; +import { IgnoredEventType, modActionsEvt } from "../types"; + /** * Create an UNBAN case automatically when a user is unbanned manually. diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index d13ecef4..c17a7ad1 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -1,10 +1,10 @@ -import { modActionsEvt } from "../types"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { Permissions, TextChannel } from "discord.js"; import { LogType } from "../../../data/LogType"; - import { resolveMember } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { TextChannel, Constants, Permissions } from "discord.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { modActionsEvt } from "../types"; + /** * Show an alert if a member with prior notes joins the server diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index 290996b0..06820890 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -1,15 +1,15 @@ -import { LogType } from "../../../data/LogType"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; -import { errorMessage, resolveUser, resolveMember } from "../../../utils"; +import { GuildMember, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { sendErrorMessage, canActOn, sendSuccessMessage } from "../../../pluginUtils"; import { hasPermission } from "knub/dist/helpers"; -import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs"; +import { LogType } from "../../../data/LogType"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { errorMessage, resolveMember, resolveUser } from "../../../utils"; +import { IgnoredEventType, ModActionsPluginType } from "../types"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; -import { kickMember } from "./kickMember"; import { ignoreEvent } from "./ignoreEvent"; import { isBanned } from "./isBanned"; -import { GuildMember, TextChannel } from "discord.js"; +import { kickMember } from "./kickMember"; +import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs"; export async function actualKickMemberCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index 203913b0..b5ff7ed1 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -1,15 +1,15 @@ -import { asSingleLine, isDiscordRESTError, UnknownUser } from "../../../utils"; -import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../types"; +import { GuildMember, Message, TextChannel, User } from "discord.js"; import humanizeDuration from "humanize-duration"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; -import { MuteResult } from "../../Mutes/types"; -import { MutesPlugin } from "../../Mutes/MutesPlugin"; -import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; -import { User, Message, TextChannel, GuildMember } from "discord.js"; +import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { asSingleLine, isDiscordRESTError, UnknownUser } from "../../../utils"; +import { MutesPlugin } from "../../Mutes/MutesPlugin"; +import { MuteResult } from "../../Mutes/types"; +import { ModActionsPluginType } from "../types"; +import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; +import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs"; /** * The actual function run by both !mute and !forcemute. diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts index 72950b82..6b6ddd91 100644 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts @@ -1,12 +1,12 @@ -import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../types"; - -import { UnknownUser, asSingleLine } from "../../../utils"; -import { sendErrorMessage, sendSuccessMessage, hasPermission } from "../../../pluginUtils"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; +import { GuildMember, Message, TextChannel, User } from "discord.js"; import humanizeDuration from "humanize-duration"; -import { User, Message, GuildMember, TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; +import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { asSingleLine, UnknownUser } from "../../../utils"; +import { ModActionsPluginType } from "../types"; +import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; + export async function actualUnmuteCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index e1da2e2d..b6bea1aa 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -1,23 +1,23 @@ -import { GuildPluginData } from "knub"; -import { BanOptions, BanResult, IgnoredEventType, ModActionsPluginType } from "../types"; -import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult, -} from "../../../utils"; - -import { renderTemplate } from "../../../templateFormatter"; -import { getDefaultContactMethods } from "./getDefaultContactMethods"; -import { LogType } from "../../../data/LogType"; -import { ignoreEvent } from "./ignoreEvent"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { logger } from "../../../logger"; -import humanizeDuration from "humanize-duration"; import { DiscordAPIError, User } from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { LogType } from "../../../data/LogType"; +import { logger } from "../../../logger"; +import { renderTemplate } from "../../../templateFormatter"; +import { + createUserNotificationError, + notifyUser, + resolveUser, + stripObjectToScalars, + ucfirst, + UserNotificationResult +} from "../../../utils"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { BanOptions, BanResult, IgnoredEventType, ModActionsPluginType } from "../types"; +import { getDefaultContactMethods } from "./getDefaultContactMethods"; +import { ignoreEvent } from "./ignoreEvent"; + /** * Ban the specified user id, whether or not they're actually on the server at the time. Generates a case. diff --git a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts index 68078a88..a4d9d75c 100644 --- a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts +++ b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../types"; -import { UserNotificationMethod } from "../../../utils"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { UserNotificationMethod } from "../../../utils"; +import { ModActionsPluginType } from "../types"; export function getDefaultContactMethods( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/ignoreEvent.ts b/backend/src/plugins/ModActions/functions/ignoreEvent.ts index 6f97e84f..71c25362 100644 --- a/backend/src/plugins/ModActions/functions/ignoreEvent.ts +++ b/backend/src/plugins/ModActions/functions/ignoreEvent.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; import { SECONDS } from "../../../utils"; +import { IgnoredEventType, ModActionsPluginType } from "../types"; import { clearIgnoredEvents } from "./clearIgnoredEvents"; const DEFAULT_TIMEOUT = 15 * SECONDS; diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index 1be820fa..de419db4 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -1,10 +1,10 @@ -import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../types"; -import { isDiscordHTTPError, isDiscordRESTError, SECONDS, sleep } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { LogType } from "../../../data/LogType"; -import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { Permissions } from "discord.js"; +import { GuildPluginData } from "knub"; +import { LogType } from "../../../data/LogType"; +import { isDiscordHTTPError, isDiscordRESTError, SECONDS, sleep } from "../../../utils"; +import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { ModActionsPluginType } from "../types"; export async function isBanned( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index 175a480e..09fbb9f5 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -1,21 +1,21 @@ -import { GuildPluginData } from "knub"; -import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types"; - -import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult, -} from "../../../utils"; -import { renderTemplate } from "../../../templateFormatter"; -import { getDefaultContactMethods } from "./getDefaultContactMethods"; -import { LogType } from "../../../data/LogType"; -import { ignoreEvent } from "./ignoreEvent"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; import { GuildMember } from "discord.js"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { LogType } from "../../../data/LogType"; +import { renderTemplate } from "../../../templateFormatter"; +import { + createUserNotificationError, + notifyUser, + resolveUser, + stripObjectToScalars, + ucfirst, + UserNotificationResult +} from "../../../utils"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types"; +import { getDefaultContactMethods } from "./getDefaultContactMethods"; +import { ignoreEvent } from "./ignoreEvent"; + /** * Kick the specified server member. Generates a case. diff --git a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts index bb7fe336..510c9625 100644 --- a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts +++ b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts @@ -1,15 +1,15 @@ -import { resolveUser, SECONDS, stripObjectToScalars } from "../../../utils"; +import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; +import moment from "moment-timezone"; import { LogType } from "src/data/LogType"; +import { logger } from "src/logger"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { resolveUser, SECONDS, stripObjectToScalars } from "../../../utils"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { IgnoredEventType, ModActionsPluginType } from "../types"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; import { ignoreEvent } from "./ignoreEvent"; import { isBanned } from "./isBanned"; -import { logger } from "src/logger"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CaseTypes } from "../../../data/CaseTypes"; -import moment from "moment-timezone"; -import humanizeDuration from "humanize-duration"; const TEMPBAN_LOOP_TIME = 60 * SECONDS; diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index af6e267e..1be237c4 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,21 +1,21 @@ +import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { ModActionsPluginType, WarnOptions, WarnResult } from "../types"; - -import { getDefaultContactMethods } from "./getDefaultContactMethods"; -import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult, -} from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; -import { GuildMember, MessageOptions } from "discord.js"; +import { + createUserNotificationError, + notifyUser, + resolveUser, + stripObjectToScalars, + ucfirst, + UserNotificationResult +} from "../../../utils"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { ModActionsPluginType, WarnOptions, WarnResult } from "../types"; +import { getDefaultContactMethods } from "./getDefaultContactMethods"; + export async function warnMember( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index 08c1314a..b8c07270 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,17 +1,17 @@ +import { TextChannel } from "discord.js"; +import { EventEmitter } from "events"; import * as t from "io-ts"; -import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { GuildMutes } from "../../data/GuildMutes"; +import { Case } from "../../data/entities/Case"; import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; -import { Case } from "../../data/entities/Case"; +import { GuildMutes } from "../../data/GuildMutes"; +import { GuildTempbans } from "../../data/GuildTempbans"; +import { Queue } from "../../Queue"; +import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils"; import { CaseArgs } from "../Cases/types"; -import { GuildTempbans } from "../../data/GuildTempbans"; import Timeout = NodeJS.Timeout; -import { EventEmitter } from "events"; -import { Queue } from "../../Queue"; -import { TextChannel } from "discord.js"; export const ConfigSchema = t.type({ dm_on_warn: t.boolean, diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index acb16e44..23205f10 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -1,26 +1,27 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, MuteOptions, MutesPluginType } from "./types"; -import { CasesPlugin } from "../Cases/CasesPlugin"; -import { GuildMutes } from "../../data/GuildMutes"; +import { GuildMember } from "discord.js"; +import { EventEmitter } from "events"; +import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; -import { GuildArchives } from "../../data/GuildArchives"; -import { clearExpiredMutes } from "./functions/clearExpiredMutes"; -import { MutesCmd } from "./commands/MutesCmd"; -import { ClearBannedMutesCmd } from "./commands/ClearBannedMutesCmd"; -import { ClearActiveMuteOnRoleRemovalEvt } from "./events/ClearActiveMuteOnRoleRemovalEvt"; -import { ClearMutesWithoutRoleCmd } from "./commands/ClearMutesWithoutRoleCmd"; -import { ClearMutesCmd } from "./commands/ClearMutesCmd"; -import { muteUser } from "./functions/muteUser"; -import { unmuteUser } from "./functions/unmuteUser"; - -import { ClearActiveMuteOnMemberBanEvt } from "./events/ClearActiveMuteOnMemberBanEvt"; -import { ReapplyActiveMuteOnJoinEvt } from "./events/ReapplyActiveMuteOnJoinEvt"; +import { GuildMutes } from "../../data/GuildMutes"; import { mapToPublicFn } from "../../pluginUtils"; -import { EventEmitter } from "events"; -import { onMutesEvent } from "./functions/onMutesEvent"; +import { CasesPlugin } from "../Cases/CasesPlugin"; +import { LogsPlugin } from "../Logs/LogsPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { ClearBannedMutesCmd } from "./commands/ClearBannedMutesCmd"; +import { ClearMutesCmd } from "./commands/ClearMutesCmd"; +import { ClearMutesWithoutRoleCmd } from "./commands/ClearMutesWithoutRoleCmd"; +import { MutesCmd } from "./commands/MutesCmd"; +import { ClearActiveMuteOnMemberBanEvt } from "./events/ClearActiveMuteOnMemberBanEvt"; +import { ClearActiveMuteOnRoleRemovalEvt } from "./events/ClearActiveMuteOnRoleRemovalEvt"; +import { ReapplyActiveMuteOnJoinEvt } from "./events/ReapplyActiveMuteOnJoinEvt"; +import { clearExpiredMutes } from "./functions/clearExpiredMutes"; +import { muteUser } from "./functions/muteUser"; import { offMutesEvent } from "./functions/offMutesEvent"; -import { GuildMember } from "discord.js"; +import { onMutesEvent } from "./functions/onMutesEvent"; +import { unmuteUser } from "./functions/unmuteUser"; +import { ConfigSchema, MutesPluginType } from "./types"; + const defaultOptions = { config: { @@ -72,7 +73,7 @@ export const MutesPlugin = zeppelinGuildPlugin()({ configSchema: ConfigSchema, defaultOptions, - dependencies: [CasesPlugin], + dependencies: [CasesPlugin, LogsPlugin], // prettier-ignore commands: [ diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index c2fbc844..537450a6 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,7 +1,7 @@ +import { User } from "discord.js"; +import { sendSuccessMessage } from "../../../pluginUtils"; import { mutesCmd } from "../types"; -import { sendSuccessMessage } from "../../../pluginUtils"; -import { User } from "discord.js"; export const ClearBannedMutesCmd = mutesCmd({ trigger: "clear_banned_mutes", diff --git a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts index 7a07efb7..3021a7a7 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts @@ -1,6 +1,6 @@ -import { mutesCmd } from "../types"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { mutesCmd } from "../types"; export const ClearMutesCmd = mutesCmd({ trigger: "clear_mutes", diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index 08aebe63..eec295c5 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -1,6 +1,6 @@ -import { mutesCmd } from "../types"; import { sendSuccessMessage } from "../../../pluginUtils"; import { resolveMember } from "../../../utils"; +import { mutesCmd } from "../types"; export const ClearMutesWithoutRoleCmd = mutesCmd({ trigger: "clear_mutes_without_role", diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 276a6227..10c2d2e3 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -1,10 +1,10 @@ -import { IMuteWithDetails, mutesCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { DBDateFormat, isFullMessage, MINUTES, noop, resolveMember } from "../../../utils"; +import { GuildMember } from "discord.js"; import moment from "moment-timezone"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { getBaseUrl } from "../../../pluginUtils"; -import { GuildMember } from "discord.js"; +import { DBDateFormat, isFullMessage, MINUTES, noop, resolveMember } from "../../../utils"; +import { IMuteWithDetails, mutesCmd } from "../types"; export const MutesCmd = mutesCmd({ trigger: "mutes", diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts index f3b4eeed..4b8aa784 100644 --- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts +++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts @@ -1,5 +1,5 @@ -import { mutesEvt } from "../types"; import { memberHasMutedRole } from "../functions/memberHasMutedRole"; +import { mutesEvt } from "../types"; /** * Clear active mute if the mute role is removed manually diff --git a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts index 729392b8..a1a942fa 100644 --- a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts +++ b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts @@ -1,7 +1,7 @@ -import { mutesEvt } from "../types"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars } from "../../../utils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { mutesEvt } from "../types"; /** * Reapply active mutes on join diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index 7db4e807..233906a2 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -1,9 +1,9 @@ import { GuildPluginData } from "knub"; -import { MutesPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { resolveMember, stripObjectToScalars, UnknownUser } from "../../../utils"; - import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { MutesPluginType } from "../types"; + export async function clearExpiredMutes(pluginData: GuildPluginData) { const expiredMutes = await pluginData.state.mutes.getExpiredMutes(); diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 15bef04f..6d26d661 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -1,25 +1,29 @@ -import { GuildPluginData } from "knub"; -import { MuteOptions, MutesPluginType } from "../types"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import humanizeDuration from "humanize-duration"; -import { - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult, - resolveMember, - UserNotificationMethod, -} from "../../../utils"; -import { renderTemplate } from "../../../templateFormatter"; - -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { Case } from "../../../data/entities/Case"; -import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; -import { muteLock } from "../../../utils/lockNameHelpers"; import { TextChannel, User } from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { Case } from "../../../data/entities/Case"; +import { LogType } from "../../../data/LogType"; +import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { renderTemplate } from "../../../templateFormatter"; +import { + notifyUser, + + + + + resolveMember, resolveUser, + stripObjectToScalars, + ucfirst, + + + UserNotificationMethod, UserNotificationResult +} from "../../../utils"; +import { muteLock } from "../../../utils/lockNameHelpers"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { MuteOptions, MutesPluginType } from "../types"; + export async function muteUser( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index 0fa81dcb..72201eae 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -1,14 +1,14 @@ -import { GuildPluginData } from "knub"; -import { MutesPluginType, UnmuteResult } from "../types"; -import { CaseArgs } from "../../Cases/types"; -import { resolveUser, stripObjectToScalars, resolveMember } from "../../../utils"; -import { memberHasMutedRole } from "./memberHasMutedRole"; import humanizeDuration from "humanize-duration"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; - +import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { CaseArgs } from "../../Cases/types"; +import { MutesPluginType, UnmuteResult } from "../types"; +import { memberHasMutedRole } from "./memberHasMutedRole"; + export async function unmuteUser( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index 9fc62f46..c0afcc18 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -1,17 +1,17 @@ -import * as t from "io-ts"; -import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils"; -import { Mute } from "../../data/entities/Mute"; - -import { Case } from "../../data/entities/Case"; -import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildMutes } from "../../data/GuildMutes"; -import { CaseArgs } from "../Cases/types"; -import Timeout = NodeJS.Timeout; -import { EventEmitter } from "events"; import { GuildMember } from "discord.js"; +import { EventEmitter } from "events"; +import * as t from "io-ts"; +import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; +import { Case } from "../../data/entities/Case"; +import { Mute } from "../../data/entities/Mute"; +import { GuildArchives } from "../../data/GuildArchives"; +import { GuildCases } from "../../data/GuildCases"; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildMutes } from "../../data/GuildMutes"; +import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils"; +import { CaseArgs } from "../Cases/types"; + +import Timeout = NodeJS.Timeout; export const ConfigSchema = t.type({ mute_role: tNullable(t.string), diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts index af95ea7a..250cace5 100644 --- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts +++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts @@ -1,11 +1,11 @@ import { PluginOptions } from "knub"; -import { ConfigSchema, NameHistoryPluginType } from "./types"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; import { UsernameHistory } from "../../data/UsernameHistory"; import { Queue } from "../../Queue"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { NamesCmd } from "./commands/NamesCmd"; import { ChannelJoinEvt, MessageCreateEvt } from "./events/UpdateNameEvts"; +import { ConfigSchema, NameHistoryPluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index 90cf80ee..a6f722c7 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -1,11 +1,11 @@ -import { nameHistoryCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; import { createChunkedMessage, disableCodeBlocks } from "knub/dist/helpers"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames"; -import { DAYS } from "../../../utils"; import { MAX_NICKNAME_ENTRIES_PER_USER } from "../../../data/GuildNicknameHistory"; import { MAX_USERNAME_ENTRIES_PER_USER } from "../../../data/UsernameHistory"; import { sendErrorMessage } from "../../../pluginUtils"; +import { DAYS } from "../../../utils"; +import { nameHistoryCmd } from "../types"; export const NamesCmd = nameHistoryCmd({ trigger: "names", diff --git a/backend/src/plugins/Persist/PersistPlugin.ts b/backend/src/plugins/Persist/PersistPlugin.ts index 25b74d11..ede40235 100644 --- a/backend/src/plugins/Persist/PersistPlugin.ts +++ b/backend/src/plugins/Persist/PersistPlugin.ts @@ -1,12 +1,12 @@ import { PluginOptions } from "knub"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, PersistPluginType } from "./types"; -import { GuildPersistedData } from "../../data/GuildPersistedData"; import { GuildLogs } from "../../data/GuildLogs"; -import { StoreDataEvt } from "./events/StoreDataEvt"; -import { LoadDataEvt } from "./events/LoadDataEvt"; +import { GuildPersistedData } from "../../data/GuildPersistedData"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { LoadDataEvt } from "./events/LoadDataEvt"; +import { StoreDataEvt } from "./events/StoreDataEvt"; +import { ConfigSchema, PersistPluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 091c8fac..251c8164 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -1,14 +1,14 @@ -import { persistEvt } from "../types"; - +import { GuildMemberEditData, Permissions } from "discord.js"; import intersection from "lodash.intersection"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars } from "../../../utils"; -import { getMissingPermissions } from "../../../utils/getMissingPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; import { canAssignRole } from "../../../utils/canAssignRole"; +import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { GuildMemberEditData, Permissions } from "discord.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { persistEvt } from "../types"; + const p = Permissions.FLAGS; diff --git a/backend/src/plugins/Persist/events/StoreDataEvt.ts b/backend/src/plugins/Persist/events/StoreDataEvt.ts index 0bc95404..2f43fac5 100644 --- a/backend/src/plugins/Persist/events/StoreDataEvt.ts +++ b/backend/src/plugins/Persist/events/StoreDataEvt.ts @@ -1,8 +1,8 @@ -import { persistEvt } from "../types"; -import { IPartialPersistData } from "../../../data/GuildPersistedData"; - -import intersection from "lodash.intersection"; import { GuildMember } from "discord.js"; +import intersection from "lodash.intersection"; +import { IPartialPersistData } from "../../../data/GuildPersistedData"; +import { persistEvt } from "../types"; + export const StoreDataEvt = persistEvt({ event: "guildMemberRemove", diff --git a/backend/src/plugins/Persist/types.ts b/backend/src/plugins/Persist/types.ts index 2c360daf..8475f4be 100644 --- a/backend/src/plugins/Persist/types.ts +++ b/backend/src/plugins/Persist/types.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildEventListener } from "knub"; -import { GuildPersistedData } from "../../data/GuildPersistedData"; import { GuildLogs } from "../../data/GuildLogs"; +import { GuildPersistedData } from "../../data/GuildPersistedData"; export const ConfigSchema = t.type({ persisted_roles: t.array(t.string), diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts index de1fa15c..8b4f8e61 100644 --- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts +++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts @@ -1,10 +1,10 @@ import { PluginOptions } from "knub"; -import { ConfigSchema, PingableRolesPluginType } from "./types"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { GuildPingableRoles } from "../../data/GuildPingableRoles"; -import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd"; +import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; import { MessageCreateDisablePingableEvt, TypingEnablePingableEvt } from "./events/ChangePingableEvts"; +import { ConfigSchema, PingableRolesPluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts index 02dc86cf..41709ffc 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { pingableRolesCmd } from "../types"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { pingableRolesCmd } from "../types"; export const PingableRoleDisableCmd = pingableRolesCmd({ trigger: ["pingable_role disable", "pingable_role d"], diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts index 6cf6ef8d..30077e09 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { pingableRolesCmd } from "../types"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { pingableRolesCmd } from "../types"; export const PingableRoleEnableCmd = pingableRolesCmd({ trigger: "pingable_role", diff --git a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts index 5efbba02..23c4627c 100644 --- a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts +++ b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts @@ -1,7 +1,7 @@ import { pingableRolesEvt } from "../types"; -import { getPingableRolesForChannel } from "../utils/getPingableRolesForChannel"; -import { enablePingableRoles } from "../utils/enablePingableRoles"; import { disablePingableRoles } from "../utils/disablePingableRoles"; +import { enablePingableRoles } from "../utils/enablePingableRoles"; +import { getPingableRolesForChannel } from "../utils/getPingableRolesForChannel"; const TIMEOUT = 10 * 1000; diff --git a/backend/src/plugins/PingableRoles/types.ts b/backend/src/plugins/PingableRoles/types.ts index 84030afd..cc479a99 100644 --- a/backend/src/plugins/PingableRoles/types.ts +++ b/backend/src/plugins/PingableRoles/types.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { GuildPingableRoles } from "../../data/GuildPingableRoles"; import { PingableRole } from "../../data/entities/PingableRole"; +import { GuildPingableRoles } from "../../data/GuildPingableRoles"; export const ConfigSchema = t.type({ can_manage: t.boolean, diff --git a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts index 21e96189..9d137828 100644 --- a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts @@ -1,5 +1,5 @@ -import { PingableRole } from "../../../data/entities/PingableRole"; import { GuildPluginData } from "knub"; +import { PingableRole } from "../../../data/entities/PingableRole"; import { PingableRolesPluginType } from "../types"; export function disablePingableRoles( diff --git a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts index 972495e3..65cc5eb6 100644 --- a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts @@ -1,5 +1,5 @@ -import { PingableRole } from "../../../data/entities/PingableRole"; import { GuildPluginData } from "knub"; +import { PingableRole } from "../../../data/entities/PingableRole"; import { PingableRolesPluginType } from "../types"; export function enablePingableRoles( diff --git a/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts b/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts index 9b3f5819..96b6b228 100644 --- a/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts +++ b/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts @@ -1,5 +1,5 @@ -import { PingableRole } from "../../../data/entities/PingableRole"; import { GuildPluginData } from "knub"; +import { PingableRole } from "../../../data/entities/PingableRole"; import { PingableRolesPluginType } from "../types"; export async function getPingableRolesForChannel( diff --git a/backend/src/plugins/Post/PostPlugin.ts b/backend/src/plugins/Post/PostPlugin.ts index 85ec4e12..493f8adb 100644 --- a/backend/src/plugins/Post/PostPlugin.ts +++ b/backend/src/plugins/Post/PostPlugin.ts @@ -1,18 +1,18 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, PostPluginType } from "./types"; +import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; -import { GuildLogs } from "../../data/GuildLogs"; -import { PostCmd } from "./commands/PostCmd"; -import { PostEmbedCmd } from "./commands/PostEmbedCmd"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { EditCmd } from "./commands/EditCmd"; import { EditEmbedCmd } from "./commands/EditEmbedCmd"; -import { ScheduledPostsShowCmd } from "./commands/ScheduledPostsShowCmd"; -import { ScheduledPostsListCmd } from "./commands/ScheduledPostsListCmd"; +import { PostCmd } from "./commands/PostCmd"; +import { PostEmbedCmd } from "./commands/PostEmbedCmd"; import { ScheduledPostsDeleteCmd } from "./commands/SchedluedPostsDeleteCmd"; +import { ScheduledPostsListCmd } from "./commands/ScheduledPostsListCmd"; +import { ScheduledPostsShowCmd } from "./commands/ScheduledPostsShowCmd"; +import { ConfigSchema, PostPluginType } from "./types"; import { scheduledPostLoop } from "./util/scheduledPostLoop"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index b0df9b4d..add44ec7 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -1,8 +1,8 @@ -import { postCmd } from "../types"; +import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { postCmd } from "../types"; import { formatContent } from "../util/formatContent"; -import { TextChannel } from "discord.js"; export const EditCmd = postCmd({ trigger: "edit", diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index d832e8aa..83713814 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -1,12 +1,12 @@ -import { postCmd } from "../types"; +import { MessageEmbed, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; - import { trimLines } from "../../../utils"; -import { formatContent } from "../util/formatContent"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; -import { MessageEmbed, TextChannel } from "discord.js"; +import { postCmd } from "../types"; +import { formatContent } from "../util/formatContent"; + const COLOR_MATCH_REGEX = /^#?([0-9a-f]{6})$/; diff --git a/backend/src/plugins/Post/commands/PostCmd.ts b/backend/src/plugins/Post/commands/PostCmd.ts index 25ae5a6b..4a1f3a4a 100644 --- a/backend/src/plugins/Post/commands/PostCmd.ts +++ b/backend/src/plugins/Post/commands/PostCmd.ts @@ -1,5 +1,5 @@ -import { postCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { postCmd } from "../types"; import { actualPostCmd } from "../util/actualPostCmd"; export const PostCmd = postCmd({ diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index 344b9e17..d9d5ef6a 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -1,13 +1,13 @@ -import { postCmd } from "../types"; +import { MessageEmbedOptions } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { actualPostCmd } from "../util/actualPostCmd"; import { sendErrorMessage } from "../../../pluginUtils"; - import { isValidEmbed, trimLines } from "../../../utils"; -import { formatContent } from "../util/formatContent"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; -import { MessageEmbed, MessageEmbedOptions } from "discord.js"; +import { postCmd } from "../types"; +import { actualPostCmd } from "../util/actualPostCmd"; +import { formatContent } from "../util/formatContent"; + export const PostEmbedCmd = postCmd({ trigger: "post_embed", diff --git a/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts b/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts index 98810fc1..0cda8a72 100644 --- a/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts +++ b/backend/src/plugins/Post/commands/SchedluedPostsDeleteCmd.ts @@ -1,7 +1,7 @@ -import { postCmd } from "../types"; -import { sorter } from "../../../utils"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { sorter } from "../../../utils"; +import { postCmd } from "../types"; export const ScheduledPostsDeleteCmd = postCmd({ trigger: ["scheduled_posts delete", "scheduled_posts d"], diff --git a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts index 3a3a3c8f..ea7a2b0f 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts @@ -1,15 +1,11 @@ -import { postCmd } from "../types"; -import { - trimLines, - sorter, - disableCodeBlocks, - deactivateMentions, - createChunkedMessage, - DBDateFormat, -} from "../../../utils"; import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; +import { + createChunkedMessage, + DBDateFormat, deactivateMentions, disableCodeBlocks, sorter, trimLines +} from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { postCmd } from "../types"; const SCHEDULED_POST_PREVIEW_TEXT_LENGTH = 50; diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index a94b8033..c1a92510 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -1,9 +1,9 @@ -import { postCmd } from "../types"; -import { sorter } from "../../../utils"; -import { sendErrorMessage } from "../../../pluginUtils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { postMessage } from "../util/postMessage"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { sorter } from "../../../utils"; +import { postCmd } from "../types"; +import { postMessage } from "../util/postMessage"; export const ScheduledPostsShowCmd = postCmd({ trigger: ["scheduled_posts", "scheduled_posts show"], diff --git a/backend/src/plugins/Post/types.ts b/backend/src/plugins/Post/types.ts index 12800a55..b54a23d2 100644 --- a/backend/src/plugins/Post/types.ts +++ b/backend/src/plugins/Post/types.ts @@ -1,8 +1,8 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand } from "knub"; +import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; -import { GuildLogs } from "../../data/GuildLogs"; export const ConfigSchema = t.type({ can_post: t.boolean, diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index c814ae0b..5c7d8f68 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -1,14 +1,14 @@ -import { StrictMessageContent, errorMessage, stripObjectToScalars, MINUTES, DBDateFormat } from "../../../utils"; +import { Channel, Message, TextChannel } from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { LogType } from "../../../data/LogType"; -import humanizeDuration from "humanize-duration"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { GuildPluginData } from "knub"; +import { DBDateFormat, errorMessage, MINUTES, StrictMessageContent, stripObjectToScalars } from "../../../utils"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { PostPluginType } from "../types"; import { parseScheduleTime } from "./parseScheduleTime"; import { postMessage } from "./postMessage"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { Message, Channel, TextChannel } from "discord.js"; const MIN_REPEAT_TIME = 5 * MINUTES; const MAX_REPEAT_TIME = Math.pow(2, 32); diff --git a/backend/src/plugins/Post/util/parseScheduleTime.ts b/backend/src/plugins/Post/util/parseScheduleTime.ts index 26d115f2..5f5325e5 100644 --- a/backend/src/plugins/Post/util/parseScheduleTime.ts +++ b/backend/src/plugins/Post/util/parseScheduleTime.ts @@ -1,6 +1,6 @@ +import { GuildPluginData } from "knub"; import moment, { Moment } from "moment-timezone"; import { convertDelayStringToMS } from "../../../utils"; -import { GuildPluginData } from "knub"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; // TODO: Extract out of the Post plugin, use everywhere with a date input diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index 292fc6b3..de7db105 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -1,10 +1,10 @@ -import { GuildPluginData } from "knub"; -import { PostPluginType } from "../types"; - -import { downloadFile } from "../../../utils"; +import { Message, MessageAttachment, MessageOptions, TextChannel } from "discord.js"; import fs from "fs"; +import { GuildPluginData } from "knub"; +import { downloadFile } from "../../../utils"; +import { PostPluginType } from "../types"; import { formatContent } from "./formatContent"; -import { TextChannel, Message, MessageOptions, MessageAttachment } from "discord.js"; + const fsp = fs.promises; diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts index d24f3ec6..fdaff973 100644 --- a/backend/src/plugins/Post/util/scheduledPostLoop.ts +++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts @@ -1,12 +1,12 @@ -import { GuildPluginData } from "knub"; -import { PostPluginType } from "../types"; -import { logger } from "../../../logger"; -import { stripObjectToScalars, SECONDS, DBDateFormat } from "../../../utils"; -import { LogType } from "../../../data/LogType"; -import moment from "moment-timezone"; - -import { postMessage } from "./postMessage"; import { TextChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { LogType } from "../../../data/LogType"; +import { logger } from "../../../logger"; +import { DBDateFormat, SECONDS, stripObjectToScalars } from "../../../utils"; +import { PostPluginType } from "../types"; +import { postMessage } from "./postMessage"; + const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS; diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 7b7b55de..51817f58 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -1,17 +1,17 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, ReactionRolesPluginType } from "./types"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; -import { autoRefreshLoop } from "./util/autoRefreshLoop"; -import { InitReactionRolesCmd } from "./commands/InitReactionRolesCmd"; -import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; -import { ClearReactionRolesCmd } from "./commands/ClearReactionRolesCmd"; -import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; import { LogsPlugin } from "../Logs/LogsPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { ClearReactionRolesCmd } from "./commands/ClearReactionRolesCmd"; +import { InitReactionRolesCmd } from "./commands/InitReactionRolesCmd"; import { PostButtonRolesCmd } from "./commands/PostButtonRolesCmd"; +import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; +import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; import { ButtonInteractionEvt } from "./events/ButtonInteractionEvt"; +import { ConfigSchema, ReactionRolesPluginType } from "./types"; +import { autoRefreshLoop } from "./util/autoRefreshLoop"; const MIN_AUTO_REFRESH = 1000 * 60 * 15; // 15min minimum, let's not abuse the API diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index 1b6bb197..a9ce7421 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -1,9 +1,9 @@ -import { reactionRolesCmd } from "../types"; +import { Message } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; - import { isDiscordRESTError } from "../../../utils"; -import { Message } from "discord.js"; +import { reactionRolesCmd } from "../types"; + export const ClearReactionRolesCmd = reactionRolesCmd({ trigger: "reaction_roles clear", diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 44ede36e..e233e7a9 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -1,9 +1,9 @@ -import { reactionRolesCmd, TReactionRolePair } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { canUseEmoji, isDiscordRESTError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; -import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { reactionRolesCmd, TReactionRolePair } from "../types"; +import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; const CLEAR_ROLES_EMOJI = "❌"; diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index 6bd19017..e5ccf683 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -1,7 +1,7 @@ -import { reactionRolesCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; import { MessageActionRow, MessageButton, TextChannel } from "discord.js"; import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { reactionRolesCmd } from "../types"; import { ButtonMenuActions } from "../util/buttonMenuActions"; export const PostButtonRolesCmd = reactionRolesCmd({ diff --git a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts index 7a93165b..3a55f6ba 100644 --- a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts @@ -1,6 +1,6 @@ -import { reactionRolesCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { reactionRolesCmd } from "../types"; import { refreshReactionRoles } from "../util/refreshReactionRoles"; export const RefreshReactionRolesCmd = reactionRolesCmd({ diff --git a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts index b996f68d..c4f125f0 100644 --- a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts @@ -1,10 +1,8 @@ -import { reactionRolesEvt } from "../types"; +import { Message } from "discord.js"; import { noop, resolveMember, sleep } from "../../../utils"; +import { reactionRolesEvt } from "../types"; import { addMemberPendingRoleChange } from "../util/addMemberPendingRoleChange"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { LogType } from "../../../data/LogType"; -import { Message } from "discord.js"; const CLEAR_ROLES_EMOJI = "❌"; diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 51694c1f..7a79cc99 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -1,14 +1,10 @@ import { - Interaction, MessageActionRow, MessageButton, - MessageComponentInteraction, - MessageComponentInteractionCollector, - TextChannel, + MessageComponentInteraction } from "discord.js"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; -import { pluginInfo } from "src/plugins/Automod/info"; import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; import { reactionRolesEvt } from "../types"; import { ButtonMenuActions } from "../util/buttonMenuActions"; diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index d0b2e5d9..9d80c81e 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; -import { BasePluginType, typedGuildEventListener, typedGuildCommand } from "knub"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; const ButtonOpts = t.type({ diff --git a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts index 1bc5bf73..1e2f88ff 100644 --- a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts +++ b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { ReactionRolesPluginType, RoleChangeMode, PendingMemberRoleChanges } from "../types"; -import { resolveMember } from "../../../utils"; import { logger } from "../../../logger"; +import { resolveMember } from "../../../utils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { PendingMemberRoleChanges, ReactionRolesPluginType, RoleChangeMode } from "../types"; const ROLE_CHANGE_BATCH_DEBOUNCE_TIME = 1500; diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index b2d39707..3059ba5c 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -1,12 +1,11 @@ -import { GuildPluginData } from "knub"; -import { ReactionRolesPluginType } from "../types"; -import { ReactionRole } from "../../../data/entities/ReactionRole"; - -import { isDiscordRESTError, sleep, isSnowflake } from "../../../utils"; -import { logger } from "../../../logger"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { LogType } from "../../../data/LogType"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { ReactionRole } from "../../../data/entities/ReactionRole"; +import { LogType } from "../../../data/LogType"; +import { isDiscordRESTError, sleep } from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { ReactionRolesPluginType } from "../types"; + const CLEAR_ROLES_EMOJI = "❌"; diff --git a/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts b/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts index 3d85ac52..1cb3ff80 100644 --- a/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts +++ b/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts @@ -1,5 +1,5 @@ -import { ReactionRolesPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { ReactionRolesPluginType } from "../types"; import { applyReactionRoleReactionsToMessage } from "./applyReactionRoleReactionsToMessage"; export async function refreshReactionRoles( diff --git a/backend/src/plugins/Reminders/RemindersPlugin.ts b/backend/src/plugins/Reminders/RemindersPlugin.ts index 928a013f..e1a39417 100644 --- a/backend/src/plugins/Reminders/RemindersPlugin.ts +++ b/backend/src/plugins/Reminders/RemindersPlugin.ts @@ -1,12 +1,12 @@ import { PluginOptions } from "knub"; -import { ConfigSchema, RemindersPluginType } from "./types"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { GuildReminders } from "../../data/GuildReminders"; -import { postDueRemindersLoop } from "./utils/postDueRemindersLoop"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { RemindCmd } from "./commands/RemindCmd"; import { RemindersCmd } from "./commands/RemindersCmd"; import { RemindersDeleteCmd } from "./commands/RemindersDeleteCmd"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { ConfigSchema, RemindersPluginType } from "./types"; +import { postDueRemindersLoop } from "./utils/postDueRemindersLoop"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts index ad9cd355..7cce547f 100644 --- a/backend/src/plugins/Reminders/commands/RemindCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts @@ -1,10 +1,10 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import moment from "moment-timezone"; -import { convertDelayStringToMS, messageLink } from "../../../utils"; import humanizeDuration from "humanize-duration"; +import moment from "moment-timezone"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { remindersCmd } from "../types"; +import { convertDelayStringToMS, messageLink } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { remindersCmd } from "../types"; export const RemindCmd = remindersCmd({ trigger: ["remind", "remindme", "reminder"], diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts index 1a32533e..ca61ceb8 100644 --- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts @@ -1,9 +1,9 @@ -import { remindersCmd } from "../types"; +import humanizeDuration from "humanize-duration"; +import moment from "moment-timezone"; import { sendErrorMessage } from "../../../pluginUtils"; import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils"; -import moment from "moment-timezone"; -import humanizeDuration from "humanize-duration"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { remindersCmd } from "../types"; export const RemindersCmd = remindersCmd({ trigger: "reminders", diff --git a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts index 7b9f33c6..e9f97a66 100644 --- a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts @@ -1,7 +1,7 @@ -import { remindersCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { sorter } from "../../../utils"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { remindersCmd } from "../types"; export const RemindersDeleteCmd = remindersCmd({ trigger: ["reminders delete", "reminders d"], diff --git a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts index 7a5d447a..9678ce3b 100644 --- a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts +++ b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts @@ -1,10 +1,10 @@ -import { GuildPluginData } from "knub"; -import { RemindersPluginType } from "../types"; -import moment from "moment-timezone"; -import humanizeDuration from "humanize-duration"; -import { disableLinkPreviews } from "knub/dist/helpers"; -import { SECONDS } from "../../../utils"; import { TextChannel } from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import { disableLinkPreviews } from "knub/dist/helpers"; +import moment from "moment-timezone"; +import { SECONDS } from "../../../utils"; +import { RemindersPluginType } from "../types"; const REMINDER_LOOP_TIME = 10 * SECONDS; const MAX_TRIES = 3; diff --git a/backend/src/plugins/Roles/RolesPlugin.ts b/backend/src/plugins/Roles/RolesPlugin.ts index bcb8fb60..1b7dcfff 100644 --- a/backend/src/plugins/Roles/RolesPlugin.ts +++ b/backend/src/plugins/Roles/RolesPlugin.ts @@ -1,12 +1,12 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, RolesPluginType } from "./types"; import { GuildLogs } from "../../data/GuildLogs"; +import { trimPluginDescription } from "../../utils"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { AddRoleCmd } from "./commands/AddRoleCmd"; -import { RemoveRoleCmd } from "./commands/RemoveRoleCmd"; import { MassAddRoleCmd } from "./commands/MassAddRoleCmd"; import { MassRemoveRoleCmd } from "./commands/MassRemoveRoleCmd"; -import { trimPluginDescription } from "../../utils"; +import { RemoveRoleCmd } from "./commands/RemoveRoleCmd"; +import { ConfigSchema, RolesPluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index cc093d3e..b5f6619d 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -1,9 +1,9 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage, canActOn } from "../../../pluginUtils"; -import { rolesCmd } from "../types"; -import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; -import { LogType } from "../../../data/LogType"; import { GuildChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { LogType } from "../../../data/LogType"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; +import { rolesCmd } from "../types"; export const AddRoleCmd = rolesCmd({ trigger: "addrole", diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index f2f0532d..0457d344 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -1,10 +1,10 @@ +import { GuildMember } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, canActOn } from "../../../pluginUtils"; -import { rolesCmd } from "../types"; -import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { GuildMember } from "discord.js"; +import { canActOn, sendErrorMessage } from "../../../pluginUtils"; +import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils"; +import { rolesCmd } from "../types"; export const MassAddRoleCmd = rolesCmd({ trigger: "massaddrole", diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index 42240164..ece59402 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -1,10 +1,10 @@ +import { GuildMember } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, canActOn } from "../../../pluginUtils"; -import { rolesCmd } from "../types"; -import { resolveMember, stripObjectToScalars, successMessage, resolveRoleId } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { GuildMember } from "discord.js"; +import { canActOn, sendErrorMessage } from "../../../pluginUtils"; +import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils"; +import { rolesCmd } from "../types"; export const MassRemoveRoleCmd = rolesCmd({ trigger: "massremoverole", diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index b160bff3..eb6bd714 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -1,10 +1,10 @@ +import { GuildChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage, canActOn } from "../../../pluginUtils"; +import { LogType } from "../../../data/LogType"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; import { rolesCmd } from "../types"; -import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars, verboseUserMention, resolveRoleId } from "../../../utils"; -import { GuildChannel } from "discord.js"; export const RemoveRoleCmd = rolesCmd({ trigger: "removerole", diff --git a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts index b73488fd..981776fc 100644 --- a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts +++ b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts @@ -1,10 +1,10 @@ import { CooldownManager, PluginOptions } from "knub"; -import { SelfGrantableRolesPluginType, ConfigSchema, defaultSelfGrantableRoleEntry } from "./types"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { trimPluginDescription } from "../../utils"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { RoleAddCmd } from "./commands/RoleAddCmd"; -import { RoleRemoveCmd } from "./commands/RoleRemoveCmd"; import { RoleHelpCmd } from "./commands/RoleHelpCmd"; +import { RoleRemoveCmd } from "./commands/RoleRemoveCmd"; +import { ConfigSchema, defaultSelfGrantableRoleEntry, SelfGrantableRolesPluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index cf3d9c84..d5f14b8a 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -1,13 +1,13 @@ -import { selfGrantableRolesCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getApplyingEntries } from "../util/getApplyingEntries"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { splitRoleNames } from "../util/splitRoleNames"; -import { normalizeRoleNames } from "../util/normalizeRoleNames"; -import { findMatchingRoles } from "../util/findMatchingRoles"; - -import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { Role } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { selfGrantableRolesCmd } from "../types"; +import { findMatchingRoles } from "../util/findMatchingRoles"; +import { getApplyingEntries } from "../util/getApplyingEntries"; +import { normalizeRoleNames } from "../util/normalizeRoleNames"; +import { splitRoleNames } from "../util/splitRoleNames"; + export const RoleAddCmd = selfGrantableRolesCmd({ trigger: ["role", "role add"], diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts index 2969ac0b..438abbd1 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts @@ -1,5 +1,5 @@ -import { selfGrantableRolesCmd } from "../types"; import { asSingleLine, trimLines } from "../../../utils"; +import { selfGrantableRolesCmd } from "../types"; import { getApplyingEntries } from "../util/getApplyingEntries"; export const RoleHelpCmd = selfGrantableRolesCmd({ diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index 5d41e639..b1413050 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -1,11 +1,11 @@ -import { selfGrantableRolesCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getApplyingEntries } from "../util/getApplyingEntries"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { splitRoleNames } from "../util/splitRoleNames"; -import { normalizeRoleNames } from "../util/normalizeRoleNames"; -import { findMatchingRoles } from "../util/findMatchingRoles"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { selfGrantableRolesCmd } from "../types"; +import { findMatchingRoles } from "../util/findMatchingRoles"; +import { getApplyingEntries } from "../util/getApplyingEntries"; +import { normalizeRoleNames } from "../util/normalizeRoleNames"; +import { splitRoleNames } from "../util/splitRoleNames"; export const RoleRemoveCmd = selfGrantableRolesCmd({ trigger: "role remove", diff --git a/backend/src/plugins/SelfGrantableRoles/types.ts b/backend/src/plugins/SelfGrantableRoles/types.ts index 8423acd4..dbebcf9f 100644 --- a/backend/src/plugins/SelfGrantableRoles/types.ts +++ b/backend/src/plugins/SelfGrantableRoles/types.ts @@ -1,5 +1,5 @@ import * as t from "io-ts"; -import { BasePluginType, typedGuildCommand, CooldownManager } from "knub"; +import { BasePluginType, CooldownManager, typedGuildCommand } from "knub"; const RoleMap = t.record(t.string, t.array(t.string)); diff --git a/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts b/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts index 41e8b87e..65495be4 100644 --- a/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts +++ b/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts @@ -1,5 +1,5 @@ -import { TSelfGrantableRoleEntry, SelfGrantableRolesPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { SelfGrantableRolesPluginType, TSelfGrantableRoleEntry } from "../types"; export async function getApplyingEntries( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index 79190820..5dda25c9 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -1,18 +1,18 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, SlowmodePluginType } from "./types"; -import { GuildSlowmodes } from "../../data/GuildSlowmodes"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { GuildSlowmodes } from "../../data/GuildSlowmodes"; import { SECONDS } from "../../utils"; -import { onMessageCreate } from "./util/onMessageCreate"; -import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes"; -import { SlowmodeDisableCmd } from "./commands/SlowmodeDisableCmd"; -import { SlowmodeClearCmd } from "./commands/SlowmodeClearCmd"; -import { SlowmodeListCmd } from "./commands/SlowmodeListCmd"; -import { SlowmodeGetCmd } from "./commands/SlowmodeGetCmd"; -import { SlowmodeSetCmd } from "./commands/SlowmodeSetCmd"; import { LogsPlugin } from "../Logs/LogsPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { SlowmodeClearCmd } from "./commands/SlowmodeClearCmd"; +import { SlowmodeDisableCmd } from "./commands/SlowmodeDisableCmd"; +import { SlowmodeGetCmd } from "./commands/SlowmodeGetCmd"; +import { SlowmodeListCmd } from "./commands/SlowmodeListCmd"; +import { SlowmodeSetCmd } from "./commands/SlowmodeSetCmd"; +import { ConfigSchema, SlowmodePluginType } from "./types"; +import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes"; +import { onMessageCreate } from "./util/onMessageCreate"; const BOT_SLOWMODE_CLEAR_INTERVAL = 60 * SECONDS; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index f8da441e..0047861b 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -1,11 +1,11 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { slowmodeCmd } from "../types"; -import { clearBotSlowmodeFromUserId } from "../util/clearBotSlowmodeFromUserId"; import { asSingleLine, disableInlineCode } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { BOT_SLOWMODE_CLEAR_PERMISSIONS } from "../requiredPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { BOT_SLOWMODE_CLEAR_PERMISSIONS } from "../requiredPermissions"; +import { slowmodeCmd } from "../types"; +import { clearBotSlowmodeFromUserId } from "../util/clearBotSlowmodeFromUserId"; export const SlowmodeClearCmd = slowmodeCmd({ trigger: ["slowmode clear", "slowmode c"], diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts index 276e28e9..e4d5b579 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts @@ -1,8 +1,8 @@ +import { TextChannel } from "discord.js"; +import humanizeDuration from "humanize-duration"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { slowmodeCmd } from "../types"; -import humanizeDuration from "humanize-duration"; -import { TextChannel } from "discord.js"; export const SlowmodeGetCmd = slowmodeCmd({ trigger: "slowmode", diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts index 0ea52e9f..9cad2a32 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts @@ -1,9 +1,9 @@ -import { slowmodeCmd } from "../types"; - +import { GuildChannel, TextChannel } from "discord.js"; +import humanizeDuration from "humanize-duration"; import { createChunkedMessage } from "knub/dist/helpers"; import { errorMessage } from "../../../utils"; -import humanizeDuration from "humanize-duration"; -import { GuildChannel, TextChannel } from "discord.js"; +import { slowmodeCmd } from "../types"; + export const SlowmodeListCmd = slowmodeCmd({ trigger: ["slowmode list", "slowmode l", "slowmodes"], diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 633e77c6..48005ab6 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,15 +1,15 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { slowmodeCmd } from "../types"; - +import { Permissions, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { asSingleLine, DAYS, disableInlineCode, HOURS, MINUTES } from "../../../utils"; -import { disableBotSlowmodeForChannel } from "../util/disableBotSlowmodeForChannel"; -import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { BOT_SLOWMODE_PERMISSIONS, NATIVE_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; -import { Permissions, TextChannel } from "discord.js"; +import { slowmodeCmd } from "../types"; +import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; +import { disableBotSlowmodeForChannel } from "../util/disableBotSlowmodeForChannel"; + const MAX_NATIVE_SLOWMODE = 6 * HOURS; // 6 hours const MAX_BOT_SLOWMODE = DAYS * 365 * 100; // 100 years diff --git a/backend/src/plugins/Slowmode/types.ts b/backend/src/plugins/Slowmode/types.ts index bfd71e4c..3c3824da 100644 --- a/backend/src/plugins/Slowmode/types.ts +++ b/backend/src/plugins/Slowmode/types.ts @@ -1,8 +1,8 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { GuildSlowmodes } from "../../data/GuildSlowmodes"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { GuildSlowmodes } from "../../data/GuildSlowmodes"; export const ConfigSchema = t.type({ use_native_slowmode: t.boolean, diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index 4d02cf09..09565bae 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -1,10 +1,10 @@ +import { Message, TextChannel } from "discord.js"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel"; import { noop } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { Message, TextChannel } from "discord.js"; +import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions"; +import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel"; export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const botSlowmode = await pluginData.state.slowmodes.getChannelSlowmode(args.channel.id); diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 02f465ec..0490be02 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -1,10 +1,10 @@ -import { SlowmodePluginType } from "../types"; +import { GuildChannel, Permissions, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; - -import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "../../../utils"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { GuildChannel, TextChannel, Permissions } from "discord.js"; +import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { SlowmodePluginType } from "../types"; + export async function applyBotSlowmodeToUserId( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index 66357446..a405b9b2 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -1,11 +1,11 @@ +import { GuildChannel, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { SlowmodePluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; - import { stripObjectToScalars, UnknownUser } from "../../../utils"; +import { SlowmodePluginType } from "../types"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; -import { GuildChannel, TextChannel } from "discord.js"; + export async function clearExpiredSlowmodes(pluginData: GuildPluginData) { const expiredSlowmodeUsers = await pluginData.state.slowmodes.getExpiredSlowmodeUsers(); diff --git a/backend/src/plugins/Slowmode/util/onMessageCreate.ts b/backend/src/plugins/Slowmode/util/onMessageCreate.ts index 035337f5..aa2a1db3 100644 --- a/backend/src/plugins/Slowmode/util/onMessageCreate.ts +++ b/backend/src/plugins/Slowmode/util/onMessageCreate.ts @@ -1,17 +1,17 @@ -import { SavedMessage } from "../../../data/entities/SavedMessage"; - -import { GuildPluginData } from "knub"; -import { SlowmodePluginType } from "../types"; -import { resolveMember } from "../../../utils"; -import { applyBotSlowmodeToUserId } from "./applyBotSlowmodeToUserId"; -import { hasPermission } from "../../../pluginUtils"; -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { BOT_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { LogType } from "../../../data/LogType"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { messageLock } from "../../../utils/lockNameHelpers"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { LogType } from "../../../data/LogType"; +import { hasPermission } from "../../../pluginUtils"; +import { resolveMember } from "../../../utils"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; +import { messageLock } from "../../../utils/lockNameHelpers"; +import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { BOT_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; +import { SlowmodePluginType } from "../types"; +import { applyBotSlowmodeToUserId } from "./applyBotSlowmodeToUserId"; + export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; diff --git a/backend/src/plugins/Spam/SpamPlugin.ts b/backend/src/plugins/Spam/SpamPlugin.ts index 5bad893d..ddf45a0b 100644 --- a/backend/src/plugins/Spam/SpamPlugin.ts +++ b/backend/src/plugins/Spam/SpamPlugin.ts @@ -1,15 +1,15 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, SpamPluginType } from "./types"; -import { GuildLogs } from "../../data/GuildLogs"; import { GuildArchives } from "../../data/GuildArchives"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { GuildLogs } from "../../data/GuildLogs"; import { GuildMutes } from "../../data/GuildMutes"; -import { onMessageCreate } from "./util/onMessageCreate"; -import { clearOldRecentActions } from "./util/clearOldRecentActions"; -import { SpamVoiceStateUpdateEvt } from "./events/SpamVoiceEvt"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { SpamVoiceStateUpdateEvt } from "./events/SpamVoiceEvt"; +import { ConfigSchema, SpamPluginType } from "./types"; +import { clearOldRecentActions } from "./util/clearOldRecentActions"; +import { onMessageCreate } from "./util/onMessageCreate"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts index 2b553e06..7e862325 100644 --- a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts +++ b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts @@ -1,4 +1,4 @@ -import { spamEvt, RecentActionType } from "../types"; +import { RecentActionType, spamEvt } from "../types"; import { logAndDetectOtherSpam } from "../util/logAndDetectOtherSpam"; export const SpamVoiceStateUpdateEvt = spamEvt({ diff --git a/backend/src/plugins/Spam/types.ts b/backend/src/plugins/Spam/types.ts index 9d4e0567..68697f02 100644 --- a/backend/src/plugins/Spam/types.ts +++ b/backend/src/plugins/Spam/types.ts @@ -1,10 +1,10 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildEventListener } from "knub"; -import { tNullable } from "../../utils"; -import { GuildLogs } from "../../data/GuildLogs"; import { GuildArchives } from "../../data/GuildArchives"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { GuildLogs } from "../../data/GuildLogs"; import { GuildMutes } from "../../data/GuildMutes"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { tNullable } from "../../utils"; const BaseSingleSpamConfig = t.type({ interval: t.number, diff --git a/backend/src/plugins/Spam/util/addRecentAction.ts b/backend/src/plugins/Spam/util/addRecentAction.ts index ec9e1261..418702a8 100644 --- a/backend/src/plugins/Spam/util/addRecentAction.ts +++ b/backend/src/plugins/Spam/util/addRecentAction.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { SpamPluginType, RecentActionType } from "../types"; +import { RecentActionType, SpamPluginType } from "../types"; export function addRecentAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/clearRecentUserActions.ts b/backend/src/plugins/Spam/util/clearRecentUserActions.ts index 839ac107..cfaf7b53 100644 --- a/backend/src/plugins/Spam/util/clearRecentUserActions.ts +++ b/backend/src/plugins/Spam/util/clearRecentUserActions.ts @@ -1,5 +1,5 @@ -import { RecentActionType, SpamPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { RecentActionType, SpamPluginType } from "../types"; export function clearRecentUserActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/getRecentActionCount.ts b/backend/src/plugins/Spam/util/getRecentActionCount.ts index c7ae5c55..5b0b0aef 100644 --- a/backend/src/plugins/Spam/util/getRecentActionCount.ts +++ b/backend/src/plugins/Spam/util/getRecentActionCount.ts @@ -1,5 +1,5 @@ -import { RecentActionType, SpamPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { RecentActionType, SpamPluginType } from "../types"; export function getRecentActionCount( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/getRecentActions.ts b/backend/src/plugins/Spam/util/getRecentActions.ts index 765a1300..ff3f31ac 100644 --- a/backend/src/plugins/Spam/util/getRecentActions.ts +++ b/backend/src/plugins/Spam/util/getRecentActions.ts @@ -1,5 +1,5 @@ -import { RecentActionType, SpamPluginType } from "../types"; import { GuildPluginData } from "knub"; +import { RecentActionType, SpamPluginType } from "../types"; export function getRecentActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index 0ce54e7f..a7846eb4 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -1,29 +1,29 @@ -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types"; -import moment from "moment-timezone"; -import { MuteResult } from "../../../plugins/Mutes/types"; -import { - convertDelayStringToMS, - DBDateFormat, - noop, - resolveMember, - stripObjectToScalars, - trimLines, -} from "../../../utils"; -import { LogType } from "../../../data/LogType"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { logger } from "../../../logger"; +import { TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; +import moment from "moment-timezone"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { LogType } from "../../../data/LogType"; +import { logger } from "../../../logger"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; +import { MuteResult } from "../../../plugins/Mutes/types"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { + convertDelayStringToMS, + DBDateFormat, + noop, + resolveMember, + stripObjectToScalars, + trimLines +} from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types"; import { addRecentAction } from "./addRecentAction"; +import { clearRecentUserActions } from "./clearRecentUserActions"; import { getRecentActionCount } from "./getRecentActionCount"; import { getRecentActions } from "./getRecentActions"; -import { clearRecentUserActions } from "./clearRecentUserActions"; import { saveSpamArchives } from "./saveSpamArchives"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { TextChannel } from "discord.js"; export async function logAndDetectMessageSpam( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts index b7cc82ec..7e1b3c60 100644 --- a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts @@ -1,15 +1,15 @@ import { GuildPluginData } from "knub"; -import { SpamPluginType, RecentActionType } from "../types"; -import { addRecentAction } from "./addRecentAction"; -import { getRecentActionCount } from "./getRecentActionCount"; -import { resolveMember, convertDelayStringToMS, stripObjectToScalars } from "../../../utils"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; -import { clearRecentUserActions } from "./clearRecentUserActions"; import { LogType } from "../../../data/LogType"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { convertDelayStringToMS, resolveMember, stripObjectToScalars } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { RecentActionType, SpamPluginType } from "../types"; +import { addRecentAction } from "./addRecentAction"; +import { clearRecentUserActions } from "./clearRecentUserActions"; +import { getRecentActionCount } from "./getRecentActionCount"; export async function logAndDetectOtherSpam( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/logCensor.ts b/backend/src/plugins/Spam/util/logCensor.ts index 318a0bae..cb503da4 100644 --- a/backend/src/plugins/Spam/util/logCensor.ts +++ b/backend/src/plugins/Spam/util/logCensor.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { SpamPluginType, RecentActionType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { RecentActionType, SpamPluginType } from "../types"; import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam"; export async function logCensor(pluginData: GuildPluginData, savedMessage: SavedMessage) { diff --git a/backend/src/plugins/Spam/util/onMessageCreate.ts b/backend/src/plugins/Spam/util/onMessageCreate.ts index cedb0616..17410a19 100644 --- a/backend/src/plugins/Spam/util/onMessageCreate.ts +++ b/backend/src/plugins/Spam/util/onMessageCreate.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { SpamPluginType, RecentActionType } from "../types"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { getUserMentions, getRoleMentions, getUrlsInString, getEmojiInString } from "../../../utils"; +import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils"; +import { RecentActionType, SpamPluginType } from "../types"; import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam"; export async function onMessageCreate(pluginData: GuildPluginData, savedMessage: SavedMessage) { diff --git a/backend/src/plugins/Spam/util/saveSpamArchives.ts b/backend/src/plugins/Spam/util/saveSpamArchives.ts index 9a3b3cac..d6d062a1 100644 --- a/backend/src/plugins/Spam/util/saveSpamArchives.ts +++ b/backend/src/plugins/Spam/util/saveSpamArchives.ts @@ -1,7 +1,7 @@ -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import moment from "moment-timezone"; -import { getBaseUrl } from "../../../pluginUtils"; import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { getBaseUrl } from "../../../pluginUtils"; import { SpamPluginType } from "../types"; const SPAM_ARCHIVE_EXPIRY_DAYS = 90; diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index 817828a1..a7ab3ff2 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -1,14 +1,14 @@ import { PluginOptions } from "knub"; -import { ConfigSchema, defaultStarboardOpts, StarboardPluginType } from "./types"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { trimPluginDescription } from "../../utils"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; -import { onMessageDelete } from "./util/onMessageDelete"; +import { trimPluginDescription } from "../../utils"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { MigratePinsCmd } from "./commands/MigratePinsCmd"; import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt"; -import { StarboardReactionRemoveEvt, StarboardReactionRemoveAllEvt } from "./events/StarboardReactionRemoveEvts"; +import { StarboardReactionRemoveAllEvt, StarboardReactionRemoveEvt } from "./events/StarboardReactionRemoveEvts"; +import { ConfigSchema, defaultStarboardOpts, StarboardPluginType } from "./types"; +import { onMessageDelete } from "./util/onMessageDelete"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index 27b08d4d..d88fa744 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -1,9 +1,9 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { starboardCmd } from "../types"; -import { sendSuccessMessage, sendErrorMessage } from "../../../pluginUtils"; - -import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { starboardCmd } from "../types"; +import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; + export const MigratePinsCmd = starboardCmd({ trigger: "starboard migrate_pins", diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts index ddcdb925..bedbddc5 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts @@ -1,10 +1,10 @@ +import { Message, TextChannel } from "discord.js"; +import { noop, resolveMember } from "../../../utils"; +import { allStarboardsLock } from "../../../utils/lockNameHelpers"; import { starboardEvt } from "../types"; - -import { UnknownUser, resolveMember, noop, resolveUser } from "../../../utils"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; import { updateStarboardMessageStarCount } from "../util/updateStarboardMessageStarCount"; -import { allStarboardsLock } from "../../../utils/lockNameHelpers"; -import { Message, TextChannel } from "discord.js"; + export const StarboardReactionAddEvt = starboardEvt({ event: "messageReactionAdd", diff --git a/backend/src/plugins/Starboard/types.ts b/backend/src/plugins/Starboard/types.ts index a8d160b4..de460e5b 100644 --- a/backend/src/plugins/Starboard/types.ts +++ b/backend/src/plugins/Starboard/types.ts @@ -1,9 +1,9 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { tNullable, tDeepPartial } from "../../utils"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; +import { tDeepPartial, tNullable } from "../../utils"; const StarboardOpts = t.type({ channel_id: t.string, diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 7c47e846..ffff5915 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -1,7 +1,7 @@ -import { EmbedWith, EMPTY_CHAR, messageLink } from "../../../utils"; - +import { GuildChannel, Message } from "discord.js"; import path from "path"; -import { Message, GuildChannel } from "discord.js"; +import { EmbedWith, EMPTY_CHAR } from "../../../utils"; + const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"]; const audioAttachmentExtensions = ["wav", "mp3", "m4a"]; diff --git a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts index 04f32806..49d2cdde 100644 --- a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts @@ -1,4 +1,4 @@ -import { Message, EmbedField } from "discord.js"; +import { EmbedField, Message } from "discord.js"; import { EMPTY_CHAR, messageLink } from "../../../utils"; import { TStarboardOpts } from "../types"; diff --git a/backend/src/plugins/Starboard/util/onMessageDelete.ts b/backend/src/plugins/Starboard/util/onMessageDelete.ts index 74477afe..fb6c7f2e 100644 --- a/backend/src/plugins/Starboard/util/onMessageDelete.ts +++ b/backend/src/plugins/Starboard/util/onMessageDelete.ts @@ -1,5 +1,5 @@ -import { SavedMessage } from "../../../data/entities/SavedMessage"; import { GuildPluginData } from "knub"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; import { StarboardPluginType } from "../types"; import { removeMessageFromStarboard } from "./removeMessageFromStarboard"; import { removeMessageFromStarboardMessages } from "./removeMessageFromStarboardMessages"; diff --git a/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts b/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts index b690fbf8..708b4a89 100644 --- a/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts +++ b/backend/src/plugins/Starboard/util/preprocessStaticConfig.ts @@ -1,5 +1,5 @@ -import { PartialConfigSchema, defaultStarboardOpts } from "../types"; import * as t from "io-ts"; +import { defaultStarboardOpts, PartialConfigSchema } from "../types"; export function preprocessStaticConfig(config: t.TypeOf) { if (config.boards) { diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index 88f6023b..ad2cd8b7 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -1,12 +1,9 @@ +import { Message, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { StarboardPluginType, TStarboardOpts } from "../types"; - -import moment from "moment-timezone"; -import { EmbedWith, EMPTY_CHAR, messageLink } from "../../../utils"; -import path from "path"; import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; -import { Message, TextChannel } from "discord.js"; + export async function saveMessageToStarboard( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts index 3cccbd37..b6375a28 100644 --- a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts +++ b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts @@ -1,8 +1,7 @@ -import { noop } from "../../../utils"; -import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; -import { TStarboardOpts } from "../types"; -import Timeout = NodeJS.Timeout; import { Message } from "discord.js"; +import { TStarboardOpts } from "../types"; +import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; +import Timeout = NodeJS.Timeout; const DEBOUNCE_DELAY = 1000; const debouncedUpdates: Record = {}; diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 889c92b2..2d6b83f9 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -1,25 +1,25 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, TagsPluginType } from "./types"; +import humanizeDuration from "humanize-duration"; import { PluginOptions } from "knub"; +import moment from "moment-timezone"; +import { StrictValidationError } from "src/validatorUtils"; import { GuildArchives } from "../../data/GuildArchives"; -import { GuildTags } from "../../data/GuildTags"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildLogs } from "../../data/GuildLogs"; -import { onMessageCreate } from "./util/onMessageCreate"; -import { onMessageDelete } from "./util/onMessageDelete"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { GuildTags } from "../../data/GuildTags"; +import { mapToPublicFn } from "../../pluginUtils"; +import { convertDelayStringToMS } from "../../utils"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { TagCreateCmd } from "./commands/TagCreateCmd"; import { TagDeleteCmd } from "./commands/TagDeleteCmd"; import { TagEvalCmd } from "./commands/TagEvalCmd"; import { TagListCmd } from "./commands/TagListCmd"; import { TagSourceCmd } from "./commands/TagSourceCmd"; -import moment from "moment-timezone"; -import humanizeDuration from "humanize-duration"; -import { convertDelayStringToMS } from "../../utils"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { mapToPublicFn } from "../../pluginUtils"; -import { renderTagBody } from "./util/renderTagBody"; +import { ConfigSchema, TagsPluginType } from "./types"; import { findTagByName } from "./util/findTagByName"; -import { StrictValidationError } from "src/validatorUtils"; +import { onMessageCreate } from "./util/onMessageCreate"; +import { onMessageDelete } from "./util/onMessageDelete"; +import { renderTagBody } from "./util/renderTagBody"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Tags/commands/TagCreateCmd.ts b/backend/src/plugins/Tags/commands/TagCreateCmd.ts index c55a5cab..0595e4bb 100644 --- a/backend/src/plugins/Tags/commands/TagCreateCmd.ts +++ b/backend/src/plugins/Tags/commands/TagCreateCmd.ts @@ -1,7 +1,7 @@ -import { tagsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { parseTemplate, TemplateParseError } from "../../../templateFormatter"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { parseTemplate, TemplateParseError } from "../../../templateFormatter"; +import { tagsCmd } from "../types"; export const TagCreateCmd = tagsCmd({ trigger: "tag", diff --git a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts index 40875d21..47cb623d 100644 --- a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts +++ b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts @@ -1,6 +1,6 @@ -import { tagsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { tagsCmd } from "../types"; export const TagDeleteCmd = tagsCmd({ trigger: "tag delete", diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 7d47b8be..61d8569c 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -1,10 +1,10 @@ -import { tagsCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; - -import { TemplateParseError } from "../../../templateFormatter"; import { sendErrorMessage } from "../../../pluginUtils"; -import { renderTagBody } from "../util/renderTagBody"; +import { TemplateParseError } from "../../../templateFormatter"; import { stripObjectToScalars } from "../../../utils"; +import { tagsCmd } from "../types"; +import { renderTagBody } from "../util/renderTagBody"; + export const TagEvalCmd = tagsCmd({ trigger: "tag eval", diff --git a/backend/src/plugins/Tags/commands/TagListCmd.ts b/backend/src/plugins/Tags/commands/TagListCmd.ts index 8ab8d8de..41febd5d 100644 --- a/backend/src/plugins/Tags/commands/TagListCmd.ts +++ b/backend/src/plugins/Tags/commands/TagListCmd.ts @@ -1,5 +1,5 @@ -import { tagsCmd } from "../types"; import { createChunkedMessage } from "../../../utils"; +import { tagsCmd } from "../types"; export const TagListCmd = tagsCmd({ trigger: ["tag list", "tags", "taglist"], diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts index 08847b00..9e0e5cef 100644 --- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts +++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts @@ -1,7 +1,7 @@ -import { tagsCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, getBaseUrl, sendSuccessMessage } from "../../../pluginUtils"; import moment from "moment-timezone"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { tagsCmd } from "../types"; export const TagSourceCmd = tagsCmd({ trigger: "tag", diff --git a/backend/src/plugins/Tags/types.ts b/backend/src/plugins/Tags/types.ts index 348e2982..17ad0fc8 100644 --- a/backend/src/plugins/Tags/types.ts +++ b/backend/src/plugins/Tags/types.ts @@ -1,10 +1,10 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { tNullable, tEmbed } from "../../utils"; import { GuildArchives } from "../../data/GuildArchives"; -import { GuildTags } from "../../data/GuildTags"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { GuildTags } from "../../data/GuildTags"; +import { tEmbed, tNullable } from "../../utils"; export const Tag = t.union([t.string, tEmbed]); diff --git a/backend/src/plugins/Tags/util/findTagByName.ts b/backend/src/plugins/Tags/util/findTagByName.ts index c8e3807a..4ec61ec5 100644 --- a/backend/src/plugins/Tags/util/findTagByName.ts +++ b/backend/src/plugins/Tags/util/findTagByName.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { Tag, TagsPluginType } from "../types"; -import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; import * as t from "io-ts"; +import { GuildPluginData } from "knub"; +import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; +import { Tag, TagsPluginType } from "../types"; export async function findTagByName( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts index 968fc1e7..db436067 100644 --- a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts +++ b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts @@ -1,10 +1,10 @@ -import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; +import { GuildMember } from "discord.js"; +import escapeStringRegexp from "escape-string-regexp"; import { GuildPluginData } from "knub"; +import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; +import { StrictMessageContent } from "../../../utils"; import { TagsPluginType, TTagCategory } from "../types"; import { renderTagFromString } from "./renderTagFromString"; -import { convertDelayStringToMS, StrictMessageContent } from "../../../utils"; -import escapeStringRegexp from "escape-string-regexp"; -import { GuildMember } from "discord.js"; interface BaseResult { renderedContent: StrictMessageContent; diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index e6169eb5..432b73ab 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -1,14 +1,14 @@ -import { TagsPluginType } from "../types"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { GuildPluginData } from "knub"; -import { convertDelayStringToMS, noop, resolveMember, tStrictMessageContent } from "../../../utils"; -import { validate } from "../../../validatorUtils"; -import { LogType } from "../../../data/LogType"; - -import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString"; -import { messageIsEmpty } from "../../../utils/messageIsEmpty"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { LogType } from "../../../data/LogType"; +import { convertDelayStringToMS, resolveMember, tStrictMessageContent } from "../../../utils"; +import { messageIsEmpty } from "../../../utils/messageIsEmpty"; +import { validate } from "../../../validatorUtils"; +import { TagsPluginType } from "../types"; +import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString"; + export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; diff --git a/backend/src/plugins/Tags/util/onMessageDelete.ts b/backend/src/plugins/Tags/util/onMessageDelete.ts index 7a418bb0..e8643e85 100644 --- a/backend/src/plugins/Tags/util/onMessageDelete.ts +++ b/backend/src/plugins/Tags/util/onMessageDelete.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { TagsPluginType } from "../types"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { TagsPluginType } from "../types"; export async function onMessageDelete(pluginData: GuildPluginData, msg: SavedMessage) { // Command message was deleted -> delete the response as well diff --git a/backend/src/plugins/Tags/util/renderTagBody.ts b/backend/src/plugins/Tags/util/renderTagBody.ts index 735455dc..725275f1 100644 --- a/backend/src/plugins/Tags/util/renderTagBody.ts +++ b/backend/src/plugins/Tags/util/renderTagBody.ts @@ -1,10 +1,10 @@ -import { renderTemplate } from "../../../templateFormatter"; -import { GuildPluginData } from "knub"; -import { Tag, TagsPluginType } from "../types"; -import { renderRecursively, StrictMessageContent } from "../../../utils"; import * as t from "io-ts"; -import { findTagByName } from "./findTagByName"; +import { GuildPluginData } from "knub"; import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager"; +import { renderTemplate } from "../../../templateFormatter"; +import { renderRecursively, StrictMessageContent } from "../../../utils"; +import { Tag, TagsPluginType } from "../types"; +import { findTagByName } from "./findTagByName"; export async function renderTagBody( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Tags/util/renderTagFromString.ts b/backend/src/plugins/Tags/util/renderTagFromString.ts index 5e5975a1..89b489b0 100644 --- a/backend/src/plugins/Tags/util/renderTagFromString.ts +++ b/backend/src/plugins/Tags/util/renderTagFromString.ts @@ -1,15 +1,14 @@ -import { Tag, TagsPluginType } from "../types"; - -import * as t from "io-ts"; -import { renderRecursively, StrictMessageContent, stripObjectToScalars } from "../../../utils"; -import { parseArguments } from "knub-command-manager"; -import { TemplateParseError } from "../../../templateFormatter"; -import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { LogType } from "../../../data/LogType"; -import { renderTagBody } from "./renderTagBody"; import { GuildMember } from "discord.js"; +import * as t from "io-ts"; +import { GuildPluginData } from "knub"; +import { parseArguments } from "knub-command-manager"; +import { LogType } from "../../../data/LogType"; +import { TemplateParseError } from "../../../templateFormatter"; +import { StrictMessageContent, stripObjectToScalars } from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { Tag, TagsPluginType } from "../types"; +import { renderTagBody } from "./renderTagBody"; + export async function renderTagFromString( pluginData: GuildPluginData, diff --git a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts index 7d079265..2f0d6cdf 100644 --- a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts +++ b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts @@ -1,19 +1,18 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, TimeAndDatePluginType } from "./types"; -import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; import { PluginOptions } from "knub"; +import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; +import { mapToPublicFn } from "../../pluginUtils"; +import { trimPluginDescription } from "../../utils"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { ResetTimezoneCmd } from "./commands/ResetTimezoneCmd"; import { SetTimezoneCmd } from "./commands/SetTimezoneCmd"; import { ViewTimezoneCmd } from "./commands/ViewTimezoneCmd"; import { defaultDateFormats } from "./defaultDateFormats"; -import { Tail } from "../../utils/typeUtils"; -import { inGuildTz } from "./functions/inGuildTz"; -import { mapToPublicFn } from "../../pluginUtils"; +import { getDateFormat } from "./functions/getDateFormat"; import { getGuildTz } from "./functions/getGuildTz"; import { getMemberTz } from "./functions/getMemberTz"; -import { getDateFormat } from "./functions/getDateFormat"; +import { inGuildTz } from "./functions/inGuildTz"; import { inMemberTz } from "./functions/inMemberTz"; -import { ResetTimezoneCmd } from "./commands/ResetTimezoneCmd"; -import { trimPluginDescription } from "../../utils"; +import { ConfigSchema, TimeAndDatePluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts index 56cd21b7..db59965a 100644 --- a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts @@ -1,7 +1,6 @@ -import { timeAndDateCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendSuccessMessage } from "../../../pluginUtils"; import { getGuildTz } from "../functions/getGuildTz"; +import { timeAndDateCmd } from "../types"; export const ResetTimezoneCmd = timeAndDateCmd({ trigger: "timezone reset", diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index 0d69f47c..1786bd34 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -1,9 +1,8 @@ -import { timeAndDateCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { isValidTimezone } from "../../../utils/isValidTimezone"; import { disableInlineCode, trimLines } from "../../../utils"; import { parseFuzzyTimezone } from "../../../utils/parseFuzzyTimezone"; +import { timeAndDateCmd } from "../types"; export const SetTimezoneCmd = timeAndDateCmd({ trigger: "timezone", diff --git a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts index d1d41694..0c72bc4e 100644 --- a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts @@ -1,8 +1,5 @@ -import { timeAndDateCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendSuccessMessage } from "../../../pluginUtils"; -import { getMemberTz } from "../functions/getMemberTz"; import { getGuildTz } from "../functions/getGuildTz"; +import { timeAndDateCmd } from "../types"; export const ViewTimezoneCmd = timeAndDateCmd({ trigger: "timezone", diff --git a/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts b/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts index ed30d67e..922c7c88 100644 --- a/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts +++ b/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts @@ -1,5 +1,4 @@ import { GuildPluginData } from "knub"; -import { ZeppelinGuildConfig } from "../../../types"; import { TimeAndDatePluginType } from "../types"; export function getGuildTz(pluginData: GuildPluginData) { diff --git a/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts b/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts index 118e5789..d19a6d68 100644 --- a/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts +++ b/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { TimeAndDatePluginType } from "../types"; import moment from "moment-timezone"; +import { TimeAndDatePluginType } from "../types"; import { getGuildTz } from "./getGuildTz"; export function inGuildTz(pluginData: GuildPluginData, input?: moment.Moment | number) { diff --git a/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts b/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts index f6adc85a..37ec7ca3 100644 --- a/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts +++ b/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts @@ -1,7 +1,6 @@ import { GuildPluginData } from "knub"; -import { TimeAndDatePluginType } from "../types"; import moment from "moment-timezone"; -import { getGuildTz } from "./getGuildTz"; +import { TimeAndDatePluginType } from "../types"; import { getMemberTz } from "./getMemberTz"; export async function inMemberTz( diff --git a/backend/src/plugins/TimeAndDate/types.ts b/backend/src/plugins/TimeAndDate/types.ts index 48fa5d3a..c0144bfd 100644 --- a/backend/src/plugins/TimeAndDate/types.ts +++ b/backend/src/plugins/TimeAndDate/types.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; -import { tNullable, tPartialDictionary } from "../../utils"; import { BasePluginType, typedGuildCommand } from "knub"; import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; +import { tNullable, tPartialDictionary } from "../../utils"; import { tValidTimezone } from "../../utils/tValidTimezone"; import { defaultDateFormats } from "./defaultDateFormats"; diff --git a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts index fbbe1e81..3014350c 100644 --- a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts +++ b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts @@ -1,9 +1,9 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import * as t from "io-ts"; import { UsernameHistory } from "../../data/UsernameHistory"; import { Queue } from "../../Queue"; -import { UsernameSaverPluginType } from "./types"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { MessageCreateUpdateUsernameEvt, VoiceChannelJoinUpdateUsernameEvt } from "./events/UpdateUsernameEvts"; -import * as t from "io-ts"; +import { UsernameSaverPluginType } from "./types"; export const UsernameSaverPlugin = zeppelinGuildPlugin()({ name: "username_saver", diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 2a22bc38..d2d32325 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -1,43 +1,43 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ConfigSchema, UtilityPluginType } from "./types"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildArchives } from "../../data/GuildArchives"; -import { Supporters } from "../../data/Supporters"; -import { ServerInfoCmd } from "./commands/ServerInfoCmd"; -import { RolesCmd } from "./commands/RolesCmd"; -import { LevelCmd } from "./commands/LevelCmd"; -import { SearchCmd } from "./commands/SearchCmd"; -import { BanSearchCmd } from "./commands/BanSearchCmd"; -import { UserInfoCmd } from "./commands/UserInfoCmd"; -import { NicknameResetCmd } from "./commands/NicknameResetCmd"; -import { NicknameCmd } from "./commands/NicknameCmd"; -import { PingCmd } from "./commands/PingCmd"; -import { SourceCmd } from "./commands/SourceCmd"; -import { ContextCmd } from "./commands/ContextCmd"; -import { VcmoveAllCmd, VcmoveCmd } from "./commands/VcmoveCmd"; -import { HelpCmd } from "./commands/HelpCmd"; -import { AboutCmd } from "./commands/AboutCmd"; import { PluginOptions } from "knub"; -import { activeReloads } from "./guildReloads"; +import { GuildArchives } from "../../data/GuildArchives"; +import { GuildCases } from "../../data/GuildCases"; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { Supporters } from "../../data/Supporters"; import { sendSuccessMessage } from "../../pluginUtils"; -import { ReloadGuildCmd } from "./commands/ReloadGuildCmd"; -import { JumboCmd } from "./commands/JumboCmd"; -import { AvatarCmd } from "./commands/AvatarCmd"; -import { CleanCmd } from "./commands/CleanCmd"; -import { InviteInfoCmd } from "./commands/InviteInfoCmd"; -import { ChannelInfoCmd } from "./commands/ChannelInfoCmd"; -import { MessageInfoCmd } from "./commands/MessageInfoCmd"; -import { InfoCmd } from "./commands/InfoCmd"; -import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd"; import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { VcdisconnectCmd } from "./commands/VcdisconnectCmd"; import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; -import { refreshMembersIfNeeded } from "./refreshMembers"; -import { RoleInfoCmd } from "./commands/RoleInfoCmd"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { AboutCmd } from "./commands/AboutCmd"; +import { AvatarCmd } from "./commands/AvatarCmd"; +import { BanSearchCmd } from "./commands/BanSearchCmd"; +import { ChannelInfoCmd } from "./commands/ChannelInfoCmd"; +import { CleanCmd } from "./commands/CleanCmd"; +import { ContextCmd } from "./commands/ContextCmd"; import { EmojiInfoCmd } from "./commands/EmojiInfoCmd"; +import { HelpCmd } from "./commands/HelpCmd"; +import { InfoCmd } from "./commands/InfoCmd"; +import { InviteInfoCmd } from "./commands/InviteInfoCmd"; +import { JumboCmd } from "./commands/JumboCmd"; +import { LevelCmd } from "./commands/LevelCmd"; +import { MessageInfoCmd } from "./commands/MessageInfoCmd"; +import { NicknameCmd } from "./commands/NicknameCmd"; +import { NicknameResetCmd } from "./commands/NicknameResetCmd"; +import { PingCmd } from "./commands/PingCmd"; +import { ReloadGuildCmd } from "./commands/ReloadGuildCmd"; +import { RoleInfoCmd } from "./commands/RoleInfoCmd"; +import { RolesCmd } from "./commands/RolesCmd"; +import { SearchCmd } from "./commands/SearchCmd"; +import { ServerInfoCmd } from "./commands/ServerInfoCmd"; +import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd"; +import { SourceCmd } from "./commands/SourceCmd"; +import { UserInfoCmd } from "./commands/UserInfoCmd"; +import { VcdisconnectCmd } from "./commands/VcdisconnectCmd"; +import { VcmoveAllCmd, VcmoveCmd } from "./commands/VcmoveCmd"; +import { activeReloads } from "./guildReloads"; +import { refreshMembersIfNeeded } from "./refreshMembers"; +import { ConfigSchema, UtilityPluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 1b60fa3c..79b0f1cf 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -1,14 +1,13 @@ -import { utilityCmd } from "../types"; -import { EmbedWith, multiSorter, resolveMember, sorter } from "../../../utils"; - -import { getCurrentUptime } from "../../../uptime"; +import { GuildChannel, MessageOptions } from "discord.js"; import humanizeDuration from "humanize-duration"; import LCL from "last-commit-log"; -import path from "path"; import moment from "moment-timezone"; import { rootDir } from "../../../paths"; +import { getCurrentUptime } from "../../../uptime"; +import { EmbedWith, multiSorter, resolveMember, sorter } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { GuildChannel, MessageOptions } from "discord.js"; +import { utilityCmd } from "../types"; + export const AboutCmd = utilityCmd({ trigger: "about", diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index c267afff..c7489c22 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -1,8 +1,8 @@ -import { utilityCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { UnknownUser } from "../../../utils"; -import { sendErrorMessage } from "../../../pluginUtils"; import { MessageEmbedOptions } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { UnknownUser } from "../../../utils"; +import { utilityCmd } from "../types"; export const AvatarCmd = utilityCmd({ trigger: ["avatar", "av"], diff --git a/backend/src/plugins/Utility/commands/BanSearchCmd.ts b/backend/src/plugins/Utility/commands/BanSearchCmd.ts index df599b67..40ff318b 100644 --- a/backend/src/plugins/Utility/commands/BanSearchCmd.ts +++ b/backend/src/plugins/Utility/commands/BanSearchCmd.ts @@ -1,6 +1,6 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { archiveSearch, displaySearch, SearchType } from "../search"; +import { utilityCmd } from "../types"; // Separate from BanSearchCmd to avoid a circular reference from ./search.ts export const banSearchSignature = { diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index dece87b7..3acfb4b1 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -1,7 +1,7 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; +import { utilityCmd } from "../types"; export const ChannelInfoCmd = utilityCmd({ trigger: ["channel", "channelinfo"], diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 44db25b6..ef307021 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -1,15 +1,15 @@ -import { utilityCmd, UtilityPluginType } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { DAYS, getInviteCodesInString, noop, SECONDS, stripObjectToScalars } from "../../../utils"; -import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; - -import moment from "moment-timezone"; +import { Message, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; -import { allowTimeout } from "../../../RegExpRunner"; import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; -import { TextChannel, User, Message } from "discord.js"; +import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { allowTimeout } from "../../../RegExpRunner"; +import { DAYS, getInviteCodesInString, noop, SECONDS, stripObjectToScalars } from "../../../utils"; +import { utilityCmd, UtilityPluginType } from "../types"; + const MAX_CLEAN_COUNT = 150; const MAX_CLEAN_TIME = 1 * DAYS; diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index 9a11df10..3d5429aa 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -1,10 +1,10 @@ -import { utilityCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { messageLink } from "../../../utils"; -import { sendErrorMessage } from "../../../pluginUtils"; - -import { canReadChannel } from "../../../utils/canReadChannel"; import { TextChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { messageLink } from "../../../utils"; +import { canReadChannel } from "../../../utils/canReadChannel"; +import { utilityCmd } from "../types"; + export const ContextCmd = utilityCmd({ trigger: "context", diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index 90d272d6..8cc7e784 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -1,8 +1,8 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { customEmojiRegex } from "../../../utils"; import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; +import { utilityCmd } from "../types"; export const EmojiInfoCmd = utilityCmd({ trigger: ["emoji", "emojiinfo"], diff --git a/backend/src/plugins/Utility/commands/HelpCmd.ts b/backend/src/plugins/Utility/commands/HelpCmd.ts index f677f7d2..d53f19b4 100644 --- a/backend/src/plugins/Utility/commands/HelpCmd.ts +++ b/backend/src/plugins/Utility/commands/HelpCmd.ts @@ -1,8 +1,8 @@ -import { utilityCmd } from "../types"; +import { LoadedGuildPlugin } from "knub"; +import { PluginCommandDefinition } from "knub/dist/commands/commandUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { createChunkedMessage } from "../../../utils"; -import { PluginCommandDefinition } from "knub/dist/commands/commandUtils"; -import { LoadedGuildPlugin } from "knub"; +import { utilityCmd } from "../types"; export const HelpCmd = utilityCmd({ trigger: "help", diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 5a13fbed..e2e033c2 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -1,19 +1,19 @@ -import { utilityCmd } from "../types"; +import { getChannelId, getRoleId } from "knub/dist/utils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; import { customEmojiRegex, isValidSnowflake, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils"; -import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; -import { resolveMessageTarget } from "../../../utils/resolveMessageTarget"; import { canReadChannel } from "../../../utils/canReadChannel"; -import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; +import { resolveMessageTarget } from "../../../utils/resolveMessageTarget"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; -import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; -import { getChannelId, getRoleId } from "knub/dist/utils"; -import { getGuildPreview } from "../functions/getGuildPreview"; -import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed"; -import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed"; import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; +import { getGuildPreview } from "../functions/getGuildPreview"; +import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; +import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; +import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed"; +import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; +import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed"; +import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; +import { utilityCmd } from "../types"; export const InfoCmd = utilityCmd({ trigger: "info", diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index a5c7fd9f..bceac2f3 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -1,8 +1,8 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; import { parseInviteCodeInput } from "../../../utils"; +import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; +import { utilityCmd } from "../types"; export const InviteInfoCmd = utilityCmd({ trigger: ["invite", "inviteinfo"], diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index 276fa257..b54be54d 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -1,10 +1,10 @@ -import { utilityCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { downloadFile, isEmoji, SECONDS } from "../../../utils"; import fs from "fs"; import sharp from "sharp"; import twemoji from "twemoji"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; +import { downloadFile, isEmoji, SECONDS } from "../../../utils"; +import { utilityCmd } from "../types"; const fsp = fs.promises; diff --git a/backend/src/plugins/Utility/commands/LevelCmd.ts b/backend/src/plugins/Utility/commands/LevelCmd.ts index 70b6ceae..404412b5 100644 --- a/backend/src/plugins/Utility/commands/LevelCmd.ts +++ b/backend/src/plugins/Utility/commands/LevelCmd.ts @@ -1,6 +1,6 @@ -import { utilityCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; import { helpers } from "knub"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { utilityCmd } from "../types"; const { getMemberLevel } = helpers; diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index e46dbc3a..04115cf6 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -1,8 +1,8 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; +import { utilityCmd } from "../types"; export const MessageInfoCmd = utilityCmd({ trigger: ["message", "messageinfo"], diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index b2da21cf..3dc803a2 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -1,7 +1,7 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { errorMessage } from "../../../utils"; import { canActOn, sendSuccessMessage } from "../../../pluginUtils"; +import { errorMessage } from "../../../utils"; +import { utilityCmd } from "../types"; export const NicknameCmd = utilityCmd({ trigger: ["nickname", "nick"], diff --git a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts index e2e5db00..91894a40 100644 --- a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts @@ -1,7 +1,7 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { errorMessage } from "../../../utils"; import { canActOn, sendSuccessMessage } from "../../../pluginUtils"; +import { errorMessage } from "../../../utils"; +import { utilityCmd } from "../types"; export const NicknameResetCmd = utilityCmd({ trigger: ["nickname reset", "nick reset"], diff --git a/backend/src/plugins/Utility/commands/PingCmd.ts b/backend/src/plugins/Utility/commands/PingCmd.ts index 08030f77..8739bfde 100644 --- a/backend/src/plugins/Utility/commands/PingCmd.ts +++ b/backend/src/plugins/Utility/commands/PingCmd.ts @@ -1,6 +1,6 @@ -import { utilityCmd } from "../types"; -import { noop, trimLines } from "../../../utils"; import { Message } from "discord.js"; +import { noop, trimLines } from "../../../utils"; +import { utilityCmd } from "../types"; const { performance } = require("perf_hooks"); diff --git a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts index 1fc824e6..53dd027c 100644 --- a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts +++ b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts @@ -1,7 +1,7 @@ +import { TextChannel } from "discord.js"; +import { activeReloads } from "../guildReloads"; import { utilityCmd } from "../types"; -import { activeReloads } from "../guildReloads"; -import { TextChannel } from "discord.js"; export const ReloadGuildCmd = utilityCmd({ trigger: "reload_guild", diff --git a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts index 48406cb3..38357054 100644 --- a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts @@ -1,7 +1,6 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed"; +import { utilityCmd } from "../types"; export const RoleInfoCmd = utilityCmd({ trigger: ["roleinfo"], diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index ea6ab800..b89285f3 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -1,10 +1,10 @@ -import { utilityCmd } from "../types"; +import { Role, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; - +import { sendErrorMessage } from "../../../pluginUtils"; import { chunkArray, sorter, trimLines } from "../../../utils"; import { refreshMembersIfNeeded } from "../refreshMembers"; -import { sendErrorMessage } from "../../../pluginUtils"; -import { Role, TextChannel } from "discord.js"; +import { utilityCmd } from "../types"; + export const RolesCmd = utilityCmd({ trigger: "roles", diff --git a/backend/src/plugins/Utility/commands/SearchCmd.ts b/backend/src/plugins/Utility/commands/SearchCmd.ts index 4b8038db..f187dba8 100644 --- a/backend/src/plugins/Utility/commands/SearchCmd.ts +++ b/backend/src/plugins/Utility/commands/SearchCmd.ts @@ -1,6 +1,6 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { archiveSearch, displaySearch, SearchType } from "../search"; +import { utilityCmd } from "../types"; // Separate from SearchCmd to avoid a circular reference from ./search.ts export const searchCmdSignature = { diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index aaf74c57..d39abc10 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -1,7 +1,7 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; +import { utilityCmd } from "../types"; export const ServerInfoCmd = utilityCmd({ trigger: ["server", "serverinfo"], diff --git a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts index b2f5bb30..1320323e 100644 --- a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts @@ -1,8 +1,6 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; -import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed"; +import { utilityCmd } from "../types"; export const SnowflakeInfoCmd = utilityCmd({ trigger: ["snowflake", "snowflakeinfo"], diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index 5a5d0c28..075c974e 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -1,10 +1,9 @@ -import { utilityCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { errorMessage } from "../../../utils"; -import { getBaseUrl, sendErrorMessage } from "../../../pluginUtils"; import moment from "moment-timezone"; - +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { getBaseUrl, sendErrorMessage } from "../../../pluginUtils"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { utilityCmd } from "../types"; + export const SourceCmd = utilityCmd({ trigger: "source", diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index b7ceba39..092692d3 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -1,7 +1,7 @@ -import { utilityCmd } from "../types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; import { sendErrorMessage } from "../../../pluginUtils"; +import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; +import { utilityCmd } from "../types"; export const UserInfoCmd = utilityCmd({ trigger: ["user", "userinfo", "whois"], diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index d69c0fad..a750fe02 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -1,16 +1,12 @@ -import { utilityCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { - channelMentionRegex, - errorMessage, - isSnowflake, - simpleClosestStringMatch, - stripObjectToScalars, -} from "../../../utils"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; - -import { LogType } from "../../../data/LogType"; import { VoiceChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { LogType } from "../../../data/LogType"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { + stripObjectToScalars +} from "../../../utils"; +import { utilityCmd } from "../types"; + export const VcdisconnectCmd = utilityCmd({ trigger: ["vcdisconnect", "vcdisc", "vcdc", "vckick", "vck"], diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 87c2ef74..8b5b0aa5 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -1,17 +1,17 @@ -import { utilityCmd } from "../types"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { - channelMentionRegex, - errorMessage, - isSnowflake, - resolveMember, - simpleClosestStringMatch, - stripObjectToScalars, -} from "../../../utils"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; - -import { LogType } from "../../../data/LogType"; import { VoiceChannel } from "discord.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { LogType } from "../../../data/LogType"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { + channelMentionRegex, + + isSnowflake, + + simpleClosestStringMatch, + stripObjectToScalars +} from "../../../utils"; +import { utilityCmd } from "../types"; + export const VcmoveCmd = utilityCmd({ trigger: "vcmove", diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index 69b3d10c..8dcfef3b 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -1,12 +1,12 @@ -import { GuildPluginData } from "knub"; -import { UtilityPluginType } from "../types"; - -import moment from "moment-timezone"; +import { MessageEmbedOptions, StageChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { ChannelTypeStrings } from "src/types"; import { EmbedWith, formatNumber, preEmbedPadding, trimLines } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { MessageEmbedOptions, Constants, VoiceChannel, StageChannel } from "discord.js"; -import { ChannelTypeStrings } from "src/types"; +import { UtilityPluginType } from "../types"; + const TEXT_CHANNEL_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740656843545772062/text-channel.png"; diff --git a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts index 46ce8ab7..02228924 100644 --- a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts @@ -1,7 +1,7 @@ -import { GuildPluginData } from "knub"; -import { UtilityPluginType } from "../types"; -import { trimLines, preEmbedPadding, EmbedWith } from "../../../utils"; import { MessageEmbedOptions } from "discord.js"; +import { GuildPluginData } from "knub"; +import { EmbedWith, preEmbedPadding, trimLines } from "../../../utils"; +import { UtilityPluginType } from "../types"; export async function getEmojiInfoEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index 78be9002..046c6035 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -1,24 +1,23 @@ +import { MessageEmbedOptions } from "discord.js"; +import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { ChannelTypeStrings } from "src/types"; +import { + EmbedWith, + + formatNumber, + GroupDMInvite, + inviteHasCounts, + isGroupDMInvite, + isGuildInvite, + preEmbedPadding, + resolveInvite, + trimLines +} from "../../../utils"; +import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; import { UtilityPluginType } from "../types"; -import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; -import moment from "moment-timezone"; -import humanizeDuration from "humanize-duration"; -import { - embedPadding, - EmbedWith, - emptyEmbedValue, - formatNumber, - GroupDMInvite, - inviteHasCounts, - isGroupDMInvite, - isGuildInvite, - preEmbedPadding, - resolveInvite, - trimLines, -} from "../../../utils"; -import { MessageEmbedOptions, Constants, Invite } from "discord.js"; -import { ChannelTypeStrings } from "src/types"; export async function getInviteInfoEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 2b3ad188..d411be4e 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -1,13 +1,13 @@ +import { MessageEmbedOptions, TextChannel } from "discord.js"; +import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; +import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; +import moment from "moment-timezone"; +import { MessageTypeStrings } from "src/types"; +import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; -import moment from "moment-timezone"; -import humanizeDuration from "humanize-duration"; -import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils"; -import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { MessageEmbedOptions, Constants, TextChannel } from "discord.js"; -import { MessageTypeStrings } from "src/types"; const MESSAGE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740685652152025088/message.png"; diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts index 6bf58c3e..4f16c31a 100644 --- a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -1,10 +1,10 @@ -import { GuildPluginData } from "knub"; -import { UtilityPluginType } from "../types"; -import { trimLines, preEmbedPadding, EmbedWith } from "../../../utils"; -import moment from "moment-timezone"; +import { MessageEmbedOptions, Role } from "discord.js"; import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { EmbedWith, preEmbedPadding, trimLines } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { Role, MessageEmbedOptions } from "discord.js"; +import { UtilityPluginType } from "../types"; const MENTION_ICON = "https://cdn.discordapp.com/attachments/705009450855039042/839284872152481792/mention.png"; diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index fdbd3d66..9e4f40b2 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -1,23 +1,22 @@ -import { GuildPluginData } from "knub"; -import { UtilityPluginType } from "../types"; -import { - embedPadding, - EmbedWith, - formatNumber, - inviteHasCounts, - memoize, - MINUTES, - preEmbedPadding, - resolveInvite, - resolveUser, - trimLines, -} from "../../../utils"; - -import moment from "moment-timezone"; +import { CategoryChannel, MessageEmbedOptions, TextChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; -import { getGuildPreview } from "./getGuildPreview"; +import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { + EmbedWith, + formatNumber, + inviteHasCounts, + memoize, + MINUTES, + preEmbedPadding, + resolveInvite, + resolveUser, + trimLines +} from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { MessageEmbedOptions, CategoryChannel, TextChannel, VoiceChannel } from "discord.js"; +import { UtilityPluginType } from "../types"; +import { getGuildPreview } from "./getGuildPreview"; + export async function getServerInfoEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index 0cec52bd..400f75b8 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -1,20 +1,13 @@ -import { GuildPluginData } from "knub"; -import { UtilityPluginType } from "../types"; -import { - UnknownUser, - trimLines, - embedPadding, - resolveMember, - resolveUser, - preEmbedPadding, - EmbedWith, -} from "../../../utils"; -import moment from "moment-timezone"; -import { CaseTypes } from "../../../data/CaseTypes"; +import { MessageEmbedOptions } from "discord.js"; import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import moment from "moment-timezone"; +import { + EmbedWith, preEmbedPadding +} from "../../../utils"; import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { MessageEmbedOptions } from "discord.js"; +import { UtilityPluginType } from "../types"; const SNOWFLAKE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/742020790471491668/snowflake.png"; diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 09c2fc59..7dc72d35 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -1,21 +1,16 @@ +import { MessageEmbedOptions, Role } from "discord.js"; +import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { UtilityPluginType } from "../types"; -import { - UnknownUser, - trimLines, - embedPadding, - resolveMember, - resolveUser, - preEmbedPadding, - sorter, - messageLink, - EmbedWith, -} from "../../../utils"; import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; -import humanizeDuration from "humanize-duration"; +import { + EmbedWith, messageLink, preEmbedPadding, resolveMember, + resolveUser, + + sorter, trimLines, UnknownUser +} from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { MessageEmbedOptions, Role } from "discord.js"; +import { UtilityPluginType } from "../types"; export async function getUserInfoEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index a42bd150..0a36ebd9 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -1,20 +1,20 @@ -import moment from "moment-timezone"; +import { GuildMember, Message, Permissions, TextChannel, User } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; -import { isFullMessage, MINUTES, multiSorter, noop, sorter, trimLines } from "../../utils"; -import { getBaseUrl, sendErrorMessage } from "../../pluginUtils"; import { GuildPluginData } from "knub"; import { ArgsFromSignatureOrArray } from "knub/dist/commands/commandUtils"; -import { searchCmdSignature } from "./commands/SearchCmd"; -import { banSearchSignature } from "./commands/BanSearchCmd"; -import { UtilityPluginType } from "./types"; -import { refreshMembersIfNeeded } from "./refreshMembers"; -import { getUserInfoEmbed } from "./functions/getUserInfoEmbed"; +import moment from "moment-timezone"; +import { getBaseUrl, sendErrorMessage } from "../../pluginUtils"; import { allowTimeout, RegExpRunner } from "../../RegExpRunner"; -import { inputPatternToRegExp, InvalidRegexError } from "../../validatorUtils"; +import { isFullMessage, MINUTES, multiSorter, noop, sorter, trimLines } from "../../utils"; import { asyncFilter } from "../../utils/async"; -import Timeout = NodeJS.Timeout; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; -import { Message, User, Constants, TextChannel, GuildMember, Permissions } from "discord.js"; +import { inputPatternToRegExp, InvalidRegexError } from "../../validatorUtils"; +import { banSearchSignature } from "./commands/BanSearchCmd"; +import { searchCmdSignature } from "./commands/SearchCmd"; +import { getUserInfoEmbed } from "./functions/getUserInfoEmbed"; +import { refreshMembersIfNeeded } from "./refreshMembers"; +import { UtilityPluginType } from "./types"; +import Timeout = NodeJS.Timeout; const SEARCH_RESULTS_PER_PAGE = 15; const SEARCH_ID_RESULTS_PER_PAGE = 50; diff --git a/backend/src/plugins/Utility/types.ts b/backend/src/plugins/Utility/types.ts index bea8f6c3..6d02be57 100644 --- a/backend/src/plugins/Utility/types.ts +++ b/backend/src/plugins/Utility/types.ts @@ -1,9 +1,9 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildArchives } from "../../data/GuildArchives"; +import { GuildCases } from "../../data/GuildCases"; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Supporters } from "../../data/Supporters"; import { RegExpRunner } from "../../RegExpRunner"; diff --git a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts index a5899a03..c311c794 100644 --- a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts +++ b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts @@ -1,8 +1,8 @@ -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PluginOptions } from "knub"; -import { ConfigSchema, WelcomeMessagePluginType } from "./types"; import { GuildLogs } from "../../data/GuildLogs"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { SendWelcomeMessageEvt } from "./events/SendWelcomeMessageEvt"; +import { ConfigSchema, WelcomeMessagePluginType } from "./types"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index 50d54b94..53f2a630 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -1,10 +1,10 @@ -import { welcomeMessageEvt } from "../types"; +import { TextChannel } from "discord.js"; +import { LogType } from "../../../data/LogType"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { createChunkedMessage, stripObjectToScalars } from "../../../utils"; -import { LogType } from "../../../data/LogType"; - import { sendDM } from "../../../utils/sendDM"; -import { TextChannel } from "discord.js"; +import { welcomeMessageEvt } from "../types"; + export const SendWelcomeMessageEvt = welcomeMessageEvt({ event: "guildMemberAdd", diff --git a/backend/src/plugins/WelcomeMessage/types.ts b/backend/src/plugins/WelcomeMessage/types.ts index 7f99b402..c4a995da 100644 --- a/backend/src/plugins/WelcomeMessage/types.ts +++ b/backend/src/plugins/WelcomeMessage/types.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildEventListener } from "knub"; -import { tNullable } from "../../utils"; import { GuildLogs } from "../../data/GuildLogs"; +import { tNullable } from "../../utils"; export const ConfigSchema = t.type({ send_dm: t.boolean, diff --git a/backend/src/plugins/ZeppelinPluginBlueprint.ts b/backend/src/plugins/ZeppelinPluginBlueprint.ts index f55bd0c6..76177e9c 100644 --- a/backend/src/plugins/ZeppelinPluginBlueprint.ts +++ b/backend/src/plugins/ZeppelinPluginBlueprint.ts @@ -1,17 +1,20 @@ -import { - BasePluginType, - typedGlobalPlugin, - GlobalPluginBlueprint, - GlobalPluginData, - typedGuildPlugin, - GuildPluginBlueprint, - GuildPluginData, -} from "knub"; import * as t from "io-ts"; +import { + BasePluginType, + + GlobalPluginBlueprint, + GlobalPluginData, + + GuildPluginBlueprint, + GuildPluginData, typedGlobalPlugin, + + + typedGuildPlugin +} from "knub"; +import { PluginOptions } from "knub/dist/config/configTypes"; +import { Awaitable } from "knub/dist/utils"; import { getPluginConfigPreprocessor } from "../pluginUtils"; import { TMarkdown } from "../types"; -import { Awaitable } from "knub/dist/utils"; -import { PluginOptions } from "knub/dist/config/configTypes"; /** * GUILD PLUGINS diff --git a/backend/src/plugins/availablePlugins.ts b/backend/src/plugins/availablePlugins.ts index e1e4e936..3f0568f6 100644 --- a/backend/src/plugins/availablePlugins.ts +++ b/backend/src/plugins/availablePlugins.ts @@ -1,38 +1,38 @@ -import { UtilityPlugin } from "./Utility/UtilityPlugin"; -import { LocateUserPlugin } from "./LocateUser/LocateUserPlugin"; -import { ZeppelinGlobalPluginBlueprint, ZeppelinGuildPluginBlueprint } from "./ZeppelinPluginBlueprint"; -import { PersistPlugin } from "./Persist/PersistPlugin"; -import { NameHistoryPlugin } from "./NameHistory/NameHistoryPlugin"; -import { MessageSaverPlugin } from "./MessageSaver/MessageSaverPlugin"; -import { AutoReactionsPlugin } from "./AutoReactions/AutoReactionsPlugin"; -import { RemindersPlugin } from "./Reminders/RemindersPlugin"; -import { UsernameSaverPlugin } from "./UsernameSaver/UsernameSaverPlugin"; -import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin"; -import { PingableRolesPlugin } from "./PingableRoles/PingableRolesPlugin"; -import { GuildConfigReloaderPlugin } from "./GuildConfigReloader/GuildConfigReloaderPlugin"; -import { CasesPlugin } from "./Cases/CasesPlugin"; -import { MutesPlugin } from "./Mutes/MutesPlugin"; -import { TagsPlugin } from "./Tags/TagsPlugin"; -import { ModActionsPlugin } from "./ModActions/ModActionsPlugin"; -import { PostPlugin } from "./Post/PostPlugin"; import { AutoDeletePlugin } from "./AutoDelete/AutoDeletePlugin"; -import { GuildInfoSaverPlugin } from "./GuildInfoSaver/GuildInfoSaverPlugin"; -import { CensorPlugin } from "./Censor/CensorPlugin"; -import { RolesPlugin } from "./Roles/RolesPlugin"; -import { SlowmodePlugin } from "./Slowmode/SlowmodePlugin"; -import { StarboardPlugin } from "./Starboard/StarboardPlugin"; -import { ChannelArchiverPlugin } from "./ChannelArchiver/ChannelArchiverPlugin"; -import { LogsPlugin } from "./Logs/LogsPlugin"; -import { SelfGrantableRolesPlugin } from "./SelfGrantableRoles/SelfGrantableRolesPlugin"; -import { SpamPlugin } from "./Spam/SpamPlugin"; -import { ReactionRolesPlugin } from "./ReactionRoles/ReactionRolesPlugin"; import { AutomodPlugin } from "./Automod/AutomodPlugin"; -import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin"; -import { CustomEventsPlugin } from "./CustomEvents/CustomEventsPlugin"; +import { AutoReactionsPlugin } from "./AutoReactions/AutoReactionsPlugin"; import { BotControlPlugin } from "./BotControl/BotControlPlugin"; -import { GuildAccessMonitorPlugin } from "./GuildAccessMonitor/GuildAccessMonitorPlugin"; -import { TimeAndDatePlugin } from "./TimeAndDate/TimeAndDatePlugin"; +import { CasesPlugin } from "./Cases/CasesPlugin"; +import { CensorPlugin } from "./Censor/CensorPlugin"; +import { ChannelArchiverPlugin } from "./ChannelArchiver/ChannelArchiverPlugin"; +import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin"; import { CountersPlugin } from "./Counters/CountersPlugin"; +import { CustomEventsPlugin } from "./CustomEvents/CustomEventsPlugin"; +import { GuildAccessMonitorPlugin } from "./GuildAccessMonitor/GuildAccessMonitorPlugin"; +import { GuildConfigReloaderPlugin } from "./GuildConfigReloader/GuildConfigReloaderPlugin"; +import { GuildInfoSaverPlugin } from "./GuildInfoSaver/GuildInfoSaverPlugin"; +import { LocateUserPlugin } from "./LocateUser/LocateUserPlugin"; +import { LogsPlugin } from "./Logs/LogsPlugin"; +import { MessageSaverPlugin } from "./MessageSaver/MessageSaverPlugin"; +import { ModActionsPlugin } from "./ModActions/ModActionsPlugin"; +import { MutesPlugin } from "./Mutes/MutesPlugin"; +import { NameHistoryPlugin } from "./NameHistory/NameHistoryPlugin"; +import { PersistPlugin } from "./Persist/PersistPlugin"; +import { PingableRolesPlugin } from "./PingableRoles/PingableRolesPlugin"; +import { PostPlugin } from "./Post/PostPlugin"; +import { ReactionRolesPlugin } from "./ReactionRoles/ReactionRolesPlugin"; +import { RemindersPlugin } from "./Reminders/RemindersPlugin"; +import { RolesPlugin } from "./Roles/RolesPlugin"; +import { SelfGrantableRolesPlugin } from "./SelfGrantableRoles/SelfGrantableRolesPlugin"; +import { SlowmodePlugin } from "./Slowmode/SlowmodePlugin"; +import { SpamPlugin } from "./Spam/SpamPlugin"; +import { StarboardPlugin } from "./Starboard/StarboardPlugin"; +import { TagsPlugin } from "./Tags/TagsPlugin"; +import { TimeAndDatePlugin } from "./TimeAndDate/TimeAndDatePlugin"; +import { UsernameSaverPlugin } from "./UsernameSaver/UsernameSaverPlugin"; +import { UtilityPlugin } from "./Utility/UtilityPlugin"; +import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin"; +import { ZeppelinGlobalPluginBlueprint, ZeppelinGuildPluginBlueprint } from "./ZeppelinPluginBlueprint"; // prettier-ignore export const guildPlugins: Array> = [ diff --git a/backend/src/templateFormatter.test.ts b/backend/src/templateFormatter.test.ts index 93a804b9..0d692e8b 100644 --- a/backend/src/templateFormatter.test.ts +++ b/backend/src/templateFormatter.test.ts @@ -1,5 +1,5 @@ -import { parseTemplate, renderParsedTemplate, renderTemplate } from "./templateFormatter"; import test from "ava"; +import { parseTemplate, renderParsedTemplate, renderTemplate } from "./templateFormatter"; test("Parses plain string templates correctly", t => { const result = parseTemplate("foo bar baz"); diff --git a/backend/src/templateFormatter.ts b/backend/src/templateFormatter.ts index 865da3d2..145d7f1d 100644 --- a/backend/src/templateFormatter.ts +++ b/backend/src/templateFormatter.ts @@ -1,5 +1,5 @@ -import { get, has } from "./utils"; import seedrandom from "seedrandom"; +import { get, has } from "./utils"; const TEMPLATE_CACHE_SIZE = 200; const templateCache: Map = new Map(); diff --git a/backend/src/types.ts b/backend/src/types.ts index add1d061..27286147 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -1,5 +1,5 @@ -import { BaseConfig, Knub } from "knub"; import * as t from "io-ts"; +import { BaseConfig, Knub } from "knub"; export interface ZeppelinGuildConfig extends BaseConfig { success_emoji?: string; diff --git a/backend/src/utils.test.ts b/backend/src/utils.test.ts index 08baba41..042f477d 100644 --- a/backend/src/utils.test.ts +++ b/backend/src/utils.test.ts @@ -1,9 +1,9 @@ +import test from "ava"; import * as ioTs from "io-ts"; import { convertDelayStringToMS, convertMSToDelayString, getUrlsInString, tAllowedMentions } from "./utils"; - -import test from "ava"; import { ErisAllowedMentionFormat } from "./utils/erisAllowedMentionsToDjsMentionOptions"; + type AssertEquals = TActual extends TExpected ? true : false; test("getUrlsInString(): detects full links", t => { diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 30a411ab..da467473 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1,50 +1,44 @@ -import { URL } from "url"; -import tlds from "tlds"; -import emojiRegex from "emoji-regex"; -import * as t from "io-ts"; +import { + Client, + Constants, + Emoji, + Guild, + GuildAuditLogs, + GuildAuditLogsEntry, + GuildChannel, + GuildMember, + Invite, + Message, + + MessageAttachment, + + MessageEmbed, + MessageEmbedOptions, + MessageMentionOptions, + MessageOptions, + PartialChannelData, + PartialMessage, + StringResolvable, + TextChannel, + User +} from "discord.js"; +import emojiRegex from "emoji-regex"; +import { either } from "fp-ts/lib/Either"; +import { unsafeCoerce } from "fp-ts/lib/function"; import fs from "fs"; import https from "https"; -import tmp from "tmp"; -import { helpers } from "knub"; -import { SavedMessage } from "./data/entities/SavedMessage"; -import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; -import { either } from "fp-ts/lib/Either"; +import * as t from "io-ts"; import moment from "moment-timezone"; +import tlds from "tlds"; +import tmp from "tmp"; +import { URL } from "url"; +import { SavedMessage } from "./data/entities/SavedMessage"; import { SimpleCache } from "./SimpleCache"; -import { logger } from "./logger"; -import { unsafeCoerce } from "fp-ts/lib/function"; import { sendDM } from "./utils/sendDM"; -import { LogType } from "./data/LogType"; -import { - APIMessage, - Channel, - Client, - Constants, - Emoji, - Guild, - GuildAuditLogs, - GuildAuditLogsEntry, - GuildChannel, - GuildMember, - Interaction, - Invite, - Message, - MessageActionRow, - MessageAttachment, - MessageComponent, - MessageEmbed, - MessageEmbedOptions, - MessageMentionOptions, - MessageOptions, - PartialChannelData, - PartialMessage, - StringResolvable, - TextChannel, - User, -} from "discord.js"; -import { ChannelTypeStrings } from "./types"; import { waitForButtonConfirm } from "./utils/waitForInteraction"; +import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; + const fsp = fs.promises; diff --git a/backend/src/utils/canReadChannel.ts b/backend/src/utils/canReadChannel.ts index 6f1b3fe2..94268c4b 100644 --- a/backend/src/utils/canReadChannel.ts +++ b/backend/src/utils/canReadChannel.ts @@ -1,6 +1,6 @@ -import { readChannelPermissions } from "./readChannelPermissions"; -import { getMissingChannelPermissions } from "./getMissingChannelPermissions"; import { GuildChannel, GuildMember } from "discord.js"; +import { getMissingChannelPermissions } from "./getMissingChannelPermissions"; +import { readChannelPermissions } from "./readChannelPermissions"; export function canReadChannel(channel: GuildChannel, member: GuildMember) { // Not missing permissions required to read the channel = can read channel diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index a398c8da..8d6249c5 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,12 +1,11 @@ import { - APIMessage, - Client, - Message, - MessageOptions, - MessageReaction, - PartialUser, - TextChannel, - User, + Client, + Message, + MessageOptions, + MessageReaction, + PartialUser, + TextChannel, + User } from "discord.js"; import { Awaitable } from "knub/dist/utils"; import { MINUTES, noop } from "../utils"; diff --git a/backend/src/utils/crypt.test.ts b/backend/src/utils/crypt.test.ts index 00619645..7034205f 100644 --- a/backend/src/utils/crypt.test.ts +++ b/backend/src/utils/crypt.test.ts @@ -1,6 +1,6 @@ import test from "ava"; +import { decrypt, encrypt } from "./crypt"; -import { encrypt, decrypt } from "./crypt"; test("encrypt() followed by decrypt()", t => { const original = "banana 123 👀 💕"; // Includes emojis to verify utf8 stuff works diff --git a/backend/src/utils/crypt.ts b/backend/src/utils/crypt.ts index 3184f328..9af9c3ce 100644 --- a/backend/src/utils/crypt.ts +++ b/backend/src/utils/crypt.ts @@ -1,6 +1,6 @@ +import crypto from "crypto"; import "../loadEnv"; -import crypto, { DecipherGCM } from "crypto"; if (!process.env.KEY) { // tslint:disable-next-line:no-console diff --git a/backend/src/utils/getMissingChannelPermissions.ts b/backend/src/utils/getMissingChannelPermissions.ts index f7e99cb6..0d224887 100644 --- a/backend/src/utils/getMissingChannelPermissions.ts +++ b/backend/src/utils/getMissingChannelPermissions.ts @@ -1,4 +1,4 @@ -import { GuildMember, GuildChannel } from "discord.js"; +import { GuildChannel, GuildMember } from "discord.js"; import { getMissingPermissions } from "./getMissingPermissions"; /** diff --git a/backend/src/utils/getMissingPermissions.ts b/backend/src/utils/getMissingPermissions.ts index d9863c24..8e14ac63 100644 --- a/backend/src/utils/getMissingPermissions.ts +++ b/backend/src/utils/getMissingPermissions.ts @@ -1,4 +1,4 @@ -import { PermissionOverwrites, Permissions } from "discord.js"; +import { Permissions } from "discord.js"; /** * @param resolvedPermissions A Permission object from e.g. GuildChannel#permissionsFor() or Member#permission diff --git a/backend/src/utils/parseFuzzyTimezone.ts b/backend/src/utils/parseFuzzyTimezone.ts index 05d3b1c7..ef570e26 100644 --- a/backend/src/utils/parseFuzzyTimezone.ts +++ b/backend/src/utils/parseFuzzyTimezone.ts @@ -1,5 +1,5 @@ -import moment from "moment-timezone"; import escapeStringRegexp from "escape-string-regexp"; +import moment from "moment-timezone"; const normalizeTzName = str => str.replace(/[^a-zA-Z0-9+\-]/g, "").toLowerCase(); diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts index 4d2a6a62..00df7010 100644 --- a/backend/src/utils/resolveMessageTarget.ts +++ b/backend/src/utils/resolveMessageTarget.ts @@ -1,7 +1,7 @@ -import { disableInlineCode, isSnowflake } from "../utils"; -import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; -import { GuildPluginData, TypeConversionError } from "knub"; import { TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; +import { isSnowflake } from "../utils"; const channelAndMessageIdRegex = /^(\d+)[\-\/](\d+)$/; const messageLinkRegex = /^https:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/\d+\/(\d+)\/(\d+)$/i; diff --git a/backend/src/utils/safeFindRelevantAuditLogEntry.ts b/backend/src/utils/safeFindRelevantAuditLogEntry.ts index ab196cf0..4b83510b 100644 --- a/backend/src/utils/safeFindRelevantAuditLogEntry.ts +++ b/backend/src/utils/safeFindRelevantAuditLogEntry.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; +import { LogType } from "../data/LogType"; import { LogsPlugin } from "../plugins/Logs/LogsPlugin"; import { findRelevantAuditLogEntry, isDiscordRESTError } from "../utils"; -import { LogType } from "../data/LogType"; /** * Wrapper for findRelevantAuditLogEntry() that handles permission errors gracefully. diff --git a/backend/src/utils/sendDM.ts b/backend/src/utils/sendDM.ts index 3679dbc5..c2dbdb93 100644 --- a/backend/src/utils/sendDM.ts +++ b/backend/src/utils/sendDM.ts @@ -1,7 +1,7 @@ -import { createChunkedMessage, HOURS, isDiscordRESTError } from "../utils"; -import { logger } from "../logger"; -import Timeout = NodeJS.Timeout; import { APIMessage, User } from "discord.js"; +import { logger } from "../logger"; +import { createChunkedMessage, HOURS, isDiscordRESTError } from "../utils"; +import Timeout = NodeJS.Timeout; let dmsDisabled = false; let dmsDisabledTimeout: Timeout; diff --git a/backend/src/utils/tColor.ts b/backend/src/utils/tColor.ts index df61f579..ccc4f6a3 100644 --- a/backend/src/utils/tColor.ts +++ b/backend/src/utils/tColor.ts @@ -1,9 +1,8 @@ -import * as t from "io-ts"; import { either } from "fp-ts/lib/Either"; -import { convertDelayStringToMS } from "../utils"; +import * as t from "io-ts"; +import { intToRgb } from "./intToRgb"; import { parseColor } from "./parseColor"; import { rgbToInt } from "./rgbToInt"; -import { intToRgb } from "./intToRgb"; export const tColor = new t.Type( "tColor", diff --git a/backend/src/utils/tValidTimezone.ts b/backend/src/utils/tValidTimezone.ts index 9922bd96..43c61c3e 100644 --- a/backend/src/utils/tValidTimezone.ts +++ b/backend/src/utils/tValidTimezone.ts @@ -1,5 +1,5 @@ -import * as t from "io-ts"; import { either } from "fp-ts/lib/Either"; +import * as t from "io-ts"; import { isValidTimezone } from "./isValidTimezone"; export const tValidTimezone = new t.Type( diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 2ee91e84..76310557 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -1,11 +1,10 @@ import { - TextChannel, - MessageActionRow, - MessageOptions, - MessageButton, - Client, - Interaction, - MessageComponentInteraction, + MessageActionRow, + + MessageButton, + + + MessageComponentInteraction, MessageOptions, TextChannel } from "discord.js"; import { PluginError } from "knub"; import { noop } from "knub/dist/utils"; diff --git a/backend/src/validation.test.ts b/backend/src/validation.test.ts index e1019a85..795e67ff 100644 --- a/backend/src/validation.test.ts +++ b/backend/src/validation.test.ts @@ -1,7 +1,7 @@ -import { tDeepPartial } from "./utils"; -import * as t from "io-ts"; -import * as validatorUtils from "./validatorUtils"; import test from "ava"; +import * as t from "io-ts"; +import { tDeepPartial } from "./utils"; +import * as validatorUtils from "./validatorUtils"; test("tDeepPartial works", ava => { const originalSchema = t.type({ diff --git a/backend/src/validatorUtils.ts b/backend/src/validatorUtils.ts index fad5ba94..8a6863f9 100644 --- a/backend/src/validatorUtils.ts +++ b/backend/src/validatorUtils.ts @@ -1,9 +1,8 @@ -import * as t from "io-ts"; -import { pipe } from "fp-ts/lib/pipeable"; -import { either, fold } from "fp-ts/lib/Either"; -import { noop } from "./utils"; import deepDiff from "deep-diff"; -import safeRegex from "safe-regex"; +import { either, fold } from "fp-ts/lib/Either"; +import { pipe } from "fp-ts/lib/pipeable"; +import * as t from "io-ts"; +import { noop } from "./utils"; const regexWithFlags = /^\/(.*?)\/([i]*)$/; diff --git a/backend/src/yamlParseTest.ts b/backend/src/yamlParseTest.ts index dabb3727..2838591c 100644 --- a/backend/src/yamlParseTest.ts +++ b/backend/src/yamlParseTest.ts @@ -1,5 +1,5 @@ -import YAML from "yawn-yaml/cjs"; import { load } from "js-yaml"; +import YAML from "yawn-yaml/cjs"; const src = ` prefix: '!' From 5efdf5ce953352b2c83bffd0765eca86d2c4f301 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 8 Jun 2021 02:23:30 +0200 Subject: [PATCH 13/79] Formatting and initial ButtonRoles DB work --- backend/src/api/index.ts | 1 - backend/src/commandTypes.ts | 20 ++++---- backend/src/data/GuildButtonRoles.ts | 50 +++++++++++++++++++ backend/src/data/GuildCounters.ts | 7 +-- backend/src/data/entities/ButtonRole.ts | 20 ++++++++ backend/src/index.ts | 3 -- .../1623018101018-CreateButtonRolesTable.ts | 44 ++++++++++++++++ .../commands/NewAutoReactionsCmd.ts | 1 - .../AutoReactions/events/AddReactionsEvt.ts | 1 - backend/src/plugins/Automod/actions/alert.ts | 12 ++--- backend/src/plugins/Automod/actions/ban.ts | 9 +--- backend/src/plugins/Automod/actions/mute.ts | 9 +--- .../plugins/Automod/actions/removeRoles.ts | 1 - backend/src/plugins/Automod/actions/reply.ts | 20 ++++---- .../functions/resolveActionContactMethods.ts | 1 - .../Automod/triggers/matchAttachmentType.ts | 8 +-- .../plugins/Automod/triggers/matchInvites.ts | 8 +-- .../plugins/Automod/triggers/matchLinks.ts | 6 +-- .../plugins/BotControl/BotControlPlugin.ts | 1 - .../plugins/Cases/functions/getCaseEmbed.ts | 1 - .../plugins/Cases/functions/getCaseSummary.ts | 9 +--- .../Cases/functions/postToCaseLogChannel.ts | 1 - .../plugins/Censor/util/applyFiltersToMsg.ts | 1 - .../functions/handleCompanionPermissions.ts | 1 - .../src/plugins/Counters/CountersPlugin.ts | 8 +-- .../Counters/commands/AddCounterCmd.ts | 1 - .../commands/ResetAllCounterValuesCmd.ts | 1 - .../Counters/commands/ResetCounterCmd.ts | 1 - .../Counters/commands/SetCounterCmd.ts | 1 - .../Counters/commands/ViewCounterCmd.ts | 1 - .../CustomEvents/functions/runEvent.ts | 1 - .../plugins/LocateUser/utils/sendAlerts.ts | 1 - .../plugins/Logs/events/LogsGuildBanEvts.ts | 1 - .../plugins/Logs/events/LogsUserUpdateEvts.ts | 1 - .../src/plugins/Logs/util/getLogMessage.ts | 10 ++-- backend/src/plugins/Logs/util/log.ts | 1 - .../src/plugins/Logs/util/onMessageDelete.ts | 1 - .../src/plugins/Logs/util/onMessageUpdate.ts | 1 - .../plugins/ModActions/ModActionsPlugin.ts | 1 - .../ModActions/commands/CasesModCmd.ts | 1 - .../ModActions/commands/CasesUserCmd.ts | 5 +- .../ModActions/commands/DeleteCaseCmd.ts | 1 - .../plugins/ModActions/commands/MassBanCmd.ts | 1 - .../ModActions/commands/MassUnbanCmd.ts | 1 - .../ModActions/commands/MassmuteCmd.ts | 1 - .../plugins/ModActions/commands/MuteCmd.ts | 1 - .../events/CreateBanCaseOnManualBanEvt.ts | 1 - .../events/CreateKickCaseOnManualKickEvt.ts | 1 - .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 1 - .../events/PostAlertOnMemberJoinEvt.ts | 1 - .../functions/actualUnmuteUserCmd.ts | 1 - .../plugins/ModActions/functions/banUserId.ts | 13 +++-- .../ModActions/functions/kickMember.ts | 13 +++-- .../ModActions/functions/warnMember.ts | 13 +++-- backend/src/plugins/Mutes/MutesPlugin.ts | 1 - .../Mutes/commands/ClearBannedMutesCmd.ts | 1 - .../Mutes/functions/clearExpiredMutes.ts | 1 - .../src/plugins/Mutes/functions/muteUser.ts | 19 +++---- .../src/plugins/Mutes/functions/unmuteUser.ts | 1 - .../src/plugins/Persist/events/LoadDataEvt.ts | 1 - .../plugins/Persist/events/StoreDataEvt.ts | 1 - .../src/plugins/Post/commands/EditEmbedCmd.ts | 1 - .../src/plugins/Post/commands/PostEmbedCmd.ts | 1 - .../Post/commands/ScheduledPostsListCmd.ts | 8 ++- backend/src/plugins/Post/util/postMessage.ts | 1 - .../plugins/Post/util/scheduledPostLoop.ts | 1 - .../commands/ClearReactionRolesCmd.ts | 1 - .../events/AddReactionRoleEvt.ts | 1 - .../events/ButtonInteractionEvt.ts | 6 +-- .../applyReactionRoleReactionsToMessage.ts | 1 - .../plugins/Roles/commands/RemoveRoleCmd.ts | 1 - .../SelfGrantableRoles/commands/RoleAddCmd.ts | 1 - .../Slowmode/commands/SlowmodeGetCmd.ts | 1 - .../Slowmode/commands/SlowmodeListCmd.ts | 1 - .../Slowmode/commands/SlowmodeSetCmd.ts | 1 - .../Slowmode/util/applyBotSlowmodeToUserId.ts | 1 - .../Slowmode/util/clearExpiredSlowmodes.ts | 1 - .../plugins/Slowmode/util/onMessageCreate.ts | 1 - .../Spam/util/logAndDetectMessageSpam.ts | 12 ++--- .../Starboard/commands/MigratePinsCmd.ts | 1 - .../events/StarboardReactionAddEvt.ts | 1 - .../util/createStarboardEmbedFromMessage.ts | 1 - .../Starboard/util/saveMessageToStarboard.ts | 1 - .../src/plugins/Tags/commands/TagEvalCmd.ts | 1 - .../src/plugins/Tags/util/onMessageCreate.ts | 1 - .../plugins/Tags/util/renderTagFromString.ts | 1 - .../src/plugins/Utility/commands/AboutCmd.ts | 1 - .../src/plugins/Utility/commands/CleanCmd.ts | 1 - .../plugins/Utility/commands/ContextCmd.ts | 1 - .../Utility/commands/ReloadGuildCmd.ts | 1 - .../src/plugins/Utility/commands/RolesCmd.ts | 1 - .../src/plugins/Utility/commands/SourceCmd.ts | 1 - .../Utility/commands/VcdisconnectCmd.ts | 5 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 10 +--- .../Utility/functions/getChannelInfoEmbed.ts | 1 - .../Utility/functions/getInviteInfoEmbed.ts | 20 ++++---- .../Utility/functions/getMessageInfoEmbed.ts | 1 - .../Utility/functions/getServerInfoEmbed.ts | 19 ++++--- .../functions/getSnowflakeInfoEmbed.ts | 4 +- .../Utility/functions/getUserInfoEmbed.ts | 12 +++-- .../events/SendWelcomeMessageEvt.ts | 1 - .../src/plugins/ZeppelinPluginBlueprint.ts | 17 +++---- backend/src/utils.test.ts | 1 - backend/src/utils.ts | 44 ++++++++-------- backend/src/utils/createPaginatedMessage.ts | 10 +--- backend/src/utils/crypt.test.ts | 1 - backend/src/utils/crypt.ts | 1 - backend/src/utils/waitForInteraction.ts | 9 +--- 108 files changed, 253 insertions(+), 303 deletions(-) create mode 100644 backend/src/data/GuildButtonRoles.ts create mode 100644 backend/src/data/entities/ButtonRole.ts create mode 100644 backend/src/migrations/1623018101018-CreateButtonRolesTable.ts diff --git a/backend/src/api/index.ts b/backend/src/api/index.ts index 671f6c8b..cd2ae878 100644 --- a/backend/src/api/index.ts +++ b/backend/src/api/index.ts @@ -2,7 +2,6 @@ import { connect } from "../data/db"; import { setIsAPI } from "../globals"; import "./loadEnv"; - if (!process.env.KEY) { // tslint:disable-next-line:no-console console.error("Project root .env with KEY is required!"); diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index 4790dc68..04ca71fa 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -2,16 +2,16 @@ import { GuildChannel, GuildMember, User } from "discord.js"; import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub"; import { createTypeHelper } from "knub-command-manager"; import { - channelMentionRegex, - convertDelayStringToMS, - disableCodeBlocks, - disableInlineCode, - isValidSnowflake, - resolveMember, - resolveUser, - resolveUserId, - roleMentionRegex, - UnknownUser + channelMentionRegex, + convertDelayStringToMS, + disableCodeBlocks, + disableInlineCode, + isValidSnowflake, + resolveMember, + resolveUser, + resolveUserId, + roleMentionRegex, + UnknownUser, } from "./utils"; import { isValidTimezone } from "./utils/isValidTimezone"; import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget"; diff --git a/backend/src/data/GuildButtonRoles.ts b/backend/src/data/GuildButtonRoles.ts new file mode 100644 index 00000000..56bf7bb1 --- /dev/null +++ b/backend/src/data/GuildButtonRoles.ts @@ -0,0 +1,50 @@ +import { getRepository, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { ButtonRole } from "./entities/ButtonRole"; + +export class GuildButtonRoles extends BaseGuildRepository { + private buttonRoles: Repository; + + constructor(guildId) { + super(guildId); + this.buttonRoles = getRepository(ButtonRole); + } + + async getForButtonId(buttonId: string) { + return this.buttonRoles.findOne({ + guild_id: this.guildId, + button_id: buttonId, + }); + } + + async getAllForMessageId(messageId: string) { + return this.buttonRoles.find({ + guild_id: this.guildId, + message_id: messageId, + }); + } + + async removeForButtonId(buttonId: string) { + return this.buttonRoles.delete({ + guild_id: this.guildId, + button_id: buttonId, + }); + } + + async removeAllForMessageId(messageId: string) { + return this.buttonRoles.delete({ + guild_id: this.guildId, + message_id: messageId, + }); + } + + async add(messageId: string, buttonId: string, buttonGroup: string, buttonName: string) { + await this.buttonRoles.insert({ + guild_id: this.guildId, + message_id: messageId, + button_id: buttonId, + button_group: buttonGroup, + button_name: buttonName, + }); + } +} diff --git a/backend/src/data/GuildCounters.ts b/backend/src/data/GuildCounters.ts index 8daf0b7c..0a1ff57e 100644 --- a/backend/src/data/GuildCounters.ts +++ b/backend/src/data/GuildCounters.ts @@ -5,12 +5,7 @@ import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { connection } from "./db"; import { Counter } from "./entities/Counter"; -import { - CounterTrigger, - isValidCounterComparisonOp, - - TriggerComparisonOp -} from "./entities/CounterTrigger"; +import { CounterTrigger, isValidCounterComparisonOp, TriggerComparisonOp } from "./entities/CounterTrigger"; import { CounterTriggerState } from "./entities/CounterTriggerState"; import { CounterValue } from "./entities/CounterValue"; diff --git a/backend/src/data/entities/ButtonRole.ts b/backend/src/data/entities/ButtonRole.ts new file mode 100644 index 00000000..9dc52b2c --- /dev/null +++ b/backend/src/data/entities/ButtonRole.ts @@ -0,0 +1,20 @@ +import { Column, Entity, PrimaryColumn, Unique } from "typeorm"; + +@Entity("button_roles") +export class ButtonRole { + @Column() + @PrimaryColumn() + guild_id: string; + + @Column() + @PrimaryColumn() + message_id: string; + + @Column() + @PrimaryColumn() + button_id: string; + + @Column() button_group: string; + + @Column() button_name: string; +} diff --git a/backend/src/index.ts b/backend/src/index.ts index 42ee9343..a830042b 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -21,9 +21,6 @@ import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; import { startUptimeCounter } from "./uptime"; import { errorMessage, isDiscordHTTPError, isDiscordRESTError, successMessage } from "./utils"; - - - const fsp = fs.promises; if (!process.env.KEY) { diff --git a/backend/src/migrations/1623018101018-CreateButtonRolesTable.ts b/backend/src/migrations/1623018101018-CreateButtonRolesTable.ts new file mode 100644 index 00000000..ef5c6e8a --- /dev/null +++ b/backend/src/migrations/1623018101018-CreateButtonRolesTable.ts @@ -0,0 +1,44 @@ +import { MigrationInterface, QueryRunner, Table } from "typeorm"; + +export class CreateButtonRolesTable1623018101018 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: "button_roles", + columns: [ + { + name: "guild_id", + type: "bigint", + isPrimary: true, + }, + { + name: "message_id", + type: "bigint", + isPrimary: true, + }, + { + name: "button_id", + type: "varchar", + length: "100", + isPrimary: true, + isUnique: true, + }, + { + name: "button_group", + type: "varchar", + length: "100", + }, + { + name: "button_name", + type: "varchar", + length: "100", + }, + ], + }), + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable("button_roles"); + } +} diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 8bb4dfe9..2b6c8579 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -7,7 +7,6 @@ import { missingPermissionError } from "../../../utils/missingPermissionError"; import { readChannelPermissions } from "../../../utils/readChannelPermissions"; import { autoReactionsCmd } from "../types"; - const requiredPermissions = readChannelPermissions | Permissions.FLAGS.ADD_REACTIONS; export const NewAutoReactionsCmd = autoReactionsCmd({ diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index 330714fe..e8a0fc29 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -7,7 +7,6 @@ import { readChannelPermissions } from "../../../utils/readChannelPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { autoReactionsEvt } from "../types"; - const p = Permissions.FLAGS; export const AddReactionsEvt = autoReactionsEvt({ diff --git a/backend/src/plugins/Automod/actions/alert.ts b/backend/src/plugins/Automod/actions/alert.ts index b7c4a000..bb0593e2 100644 --- a/backend/src/plugins/Automod/actions/alert.ts +++ b/backend/src/plugins/Automod/actions/alert.ts @@ -4,12 +4,12 @@ import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMen import { LogType } from "../../../data/LogType"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { - createChunkedMessage, - messageLink, - stripObjectToScalars, - tAllowedMentions, - tNormalizedNullOptional, - verboseChannelMention + createChunkedMessage, + messageLink, + stripObjectToScalars, + tAllowedMentions, + tNormalizedNullOptional, + verboseChannelMention, } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { automodAction } from "../helpers"; diff --git a/backend/src/plugins/Automod/actions/ban.ts b/backend/src/plugins/Automod/actions/ban.ts index ebec5516..ff92be3a 100644 --- a/backend/src/plugins/Automod/actions/ban.ts +++ b/backend/src/plugins/Automod/actions/ban.ts @@ -1,12 +1,5 @@ import * as t from "io-ts"; -import { - convertDelayStringToMS, - nonNullish, - - tDelayString, - tNullable, - unique -} from "../../../utils"; +import { convertDelayStringToMS, nonNullish, tDelayString, tNullable, unique } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index 2ee0b9ba..564f65a8 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -1,14 +1,7 @@ import * as t from "io-ts"; import { LogType } from "../../../data/LogType"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { - convertDelayStringToMS, - nonNullish, - - tDelayString, - tNullable, - unique -} from "../../../utils"; +import { convertDelayStringToMS, nonNullish, tDelayString, tNullable, unique } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index 35071c02..09e881f4 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -10,7 +10,6 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; import { automodAction } from "../helpers"; - const p = Permissions.FLAGS; export const RemoveRolesAction = automodAction({ diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index dafb9dfb..0a1c9ba1 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -3,22 +3,20 @@ import * as t from "io-ts"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; import { - convertDelayStringToMS, - noop, - renderRecursively, - - stripObjectToScalars, - tDelayString, - tMessageContent, - tNullable, - unique, - verboseChannelMention + convertDelayStringToMS, + noop, + renderRecursively, + stripObjectToScalars, + tDelayString, + tMessageContent, + tNullable, + unique, + verboseChannelMention, } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { automodAction } from "../helpers"; import { AutomodContext } from "../types"; - export const ReplyAction = automodAction({ configType: t.union([ t.string, diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts index a7c465fc..cbb5709d 100644 --- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts +++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts @@ -4,7 +4,6 @@ import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError" import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; import { AutomodPluginType } from "../types"; - export function resolveActionContactMethods( pluginData: GuildPluginData, actionConfig: { diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 7541b577..11a25d05 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -1,11 +1,5 @@ import * as t from "io-ts"; -import { - asSingleLine, - - disableInlineCode, - messageSummary, - verboseChannelMention -} from "../../../utils"; +import { asSingleLine, disableInlineCode, messageSummary, verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; interface MatchResultType { diff --git a/backend/src/plugins/Automod/triggers/matchInvites.ts b/backend/src/plugins/Automod/triggers/matchInvites.ts index 6b238841..9e0b0c4e 100644 --- a/backend/src/plugins/Automod/triggers/matchInvites.ts +++ b/backend/src/plugins/Automod/triggers/matchInvites.ts @@ -1,11 +1,5 @@ import * as t from "io-ts"; -import { - getInviteCodesInString, - GuildInvite, - isGuildInvite, - resolveInvite, - tNullable -} from "../../../utils"; +import { getInviteCodesInString, GuildInvite, isGuildInvite, resolveInvite, tNullable } from "../../../utils"; import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; import { automodTrigger } from "../helpers"; diff --git a/backend/src/plugins/Automod/triggers/matchLinks.ts b/backend/src/plugins/Automod/triggers/matchLinks.ts index 29c05190..193a184c 100644 --- a/backend/src/plugins/Automod/triggers/matchLinks.ts +++ b/backend/src/plugins/Automod/triggers/matchLinks.ts @@ -1,11 +1,7 @@ import escapeStringRegexp from "escape-string-regexp"; import * as t from "io-ts"; import { allowTimeout } from "../../../RegExpRunner"; -import { - disableInlineCode, - getUrlsInString, - tNullable -} from "../../../utils"; +import { disableInlineCode, getUrlsInString, tNullable } from "../../../utils"; import { TRegex } from "../../../validatorUtils"; import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index 8bce0acb..3e559af0 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -19,7 +19,6 @@ import { RemoveDashboardUserCmd } from "./commands/RemoveDashboardUserCmd"; import { ServersCmd } from "./commands/ServersCmd"; import { BotControlPluginType, ConfigSchema } from "./types"; - const defaultOptions = { config: { can_use: false, diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index 5a3562c8..5d52c662 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -9,7 +9,6 @@ import { CasesPluginType } from "../types"; import { getCaseColor } from "./getCaseColor"; import { resolveCaseId } from "./resolveCaseId"; - export async function getCaseEmbed( pluginData: GuildPluginData, caseOrCaseId: Case | number, diff --git a/backend/src/plugins/Cases/functions/getCaseSummary.ts b/backend/src/plugins/Cases/functions/getCaseSummary.ts index 5f2f388e..98841451 100644 --- a/backend/src/plugins/Cases/functions/getCaseSummary.ts +++ b/backend/src/plugins/Cases/functions/getCaseSummary.ts @@ -2,14 +2,7 @@ import { GuildPluginData } from "knub"; import { splitMessageIntoChunks } from "knub/dist/helpers"; import moment from "moment-timezone"; import { Case } from "../../../data/entities/Case"; -import { - convertDelayStringToMS, - DAYS, - DBDateFormat, - disableLinkPreviews, - - messageLink -} from "../../../utils"; +import { convertDelayStringToMS, DAYS, DBDateFormat, disableLinkPreviews, messageLink } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { caseAbbreviations } from "../caseAbbreviations"; import { CasesPluginType } from "../types"; diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index f16895b3..ddd250e3 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -7,7 +7,6 @@ import { CasesPluginType } from "../types"; import { getCaseEmbed } from "./getCaseEmbed"; import { resolveCaseId } from "./resolveCaseId"; - export async function postToCaseLogChannel( pluginData: GuildPluginData, content: MessageOptions, diff --git a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts index f0ea8c40..ffadcc67 100644 --- a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts +++ b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts @@ -9,7 +9,6 @@ import { getInviteCodesInString, getUrlsInString, isGuildInvite, resolveInvite, import { CensorPluginType } from "../types"; import { censorMessage } from "./censorMessage"; - export async function applyFiltersToMsg( pluginData: GuildPluginData, savedMessage: SavedMessage, diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index 3ea79867..a2155dc1 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -6,7 +6,6 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId"; - const ERROR_COOLDOWN_KEY = "errorCooldown"; const ERROR_COOLDOWN = 5 * MINUTES; diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index fe23cd6d..d2566515 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -2,10 +2,10 @@ import { EventEmitter } from "events"; import { PluginOptions } from "knub"; import { ConfigPreprocessorFn } from "knub/dist/config/configTypes"; import { - buildCounterConditionString, - CounterTrigger, - getReverseCounterComparisonOp, - parseCounterConditionString + buildCounterConditionString, + CounterTrigger, + getReverseCounterComparisonOp, + parseCounterConditionString, } from "../../data/entities/CounterTrigger"; import { GuildCounters } from "../../data/GuildCounters"; import { mapToPublicFn } from "../../pluginUtils"; diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 455c4549..83057133 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -7,7 +7,6 @@ import { resolveUser, UnknownUser } from "../../../utils"; import { changeCounterValue } from "../functions/changeCounterValue"; import { CountersPluginType } from "../types"; - export const AddCounterCmd = typedGuildCommand()({ trigger: ["counters add", "counter add", "addcounter"], permission: "can_edit", diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index a4cc3587..2f4d8def 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -5,7 +5,6 @@ import { confirm, noop, trimMultilineString } from "../../../utils"; import { resetAllCounterValues } from "../functions/resetAllCounterValues"; import { CountersPluginType } from "../types"; - export const ResetAllCounterValuesCmd = typedGuildCommand()({ trigger: ["counters reset_all"], permission: "can_reset_all", diff --git a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts index c684fa7b..56050683 100644 --- a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts @@ -7,7 +7,6 @@ import { resolveUser, UnknownUser } from "../../../utils"; import { setCounterValue } from "../functions/setCounterValue"; import { CountersPluginType } from "../types"; - export const ResetCounterCmd = typedGuildCommand()({ trigger: ["counters reset", "counter reset", "resetcounter"], permission: "can_edit", diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 02ced104..0e78a4bc 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -7,7 +7,6 @@ import { resolveUser, UnknownUser } from "../../../utils"; import { setCounterValue } from "../functions/setCounterValue"; import { CountersPluginType } from "../types"; - export const SetCounterCmd = typedGuildCommand()({ trigger: ["counters set", "counter set", "setcounter"], permission: "can_edit", diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index 73ce6287..ff14c339 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -6,7 +6,6 @@ import { sendErrorMessage } from "../../../pluginUtils"; import { resolveUser, UnknownUser } from "../../../utils"; import { CountersPluginType } from "../types"; - export const ViewCounterCmd = typedGuildCommand()({ trigger: ["counters view", "counter view", "viewcounter", "counter"], permission: "can_view", diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 11ae8aaf..1322d41b 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -11,7 +11,6 @@ import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction"; import { setChannelPermissionOverridesAction } from "../actions/setChannelPermissionOverrides"; import { CustomEventsPluginType, TCustomEvent } from "../types"; - export async function runEvent( pluginData: GuildPluginData, event: TCustomEvent, diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts index e88dcec9..44edd232 100644 --- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts @@ -5,7 +5,6 @@ import { LocateUserPluginType } from "../types"; import { moveMember } from "./moveMember"; import { sendWhere } from "./sendWhere"; - export async function sendAlerts(pluginData: GuildPluginData, userId: string) { const triggeredAlerts = await pluginData.state.alerts.getAlertsByUserId(userId); const member = await resolveMember(pluginData.client, pluginData.guild, userId); diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index 220543ac..60167082 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -4,7 +4,6 @@ import { stripObjectToScalars, UnknownUser } from "../../../utils"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { logsEvt } from "../types"; - export const LogsGuildBanAddEvt = logsEvt({ event: "guildBanAdd", diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index ba4b5d08..245f25ae 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -6,7 +6,6 @@ import { stripObjectToScalars, UnknownUser } from "../../../utils"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { logsEvt } from "../types"; - export const LogsGuildMemberUpdateEvt = logsEvt({ event: "guildMemberUpdate", diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts index 435264e3..7ffd0a17 100644 --- a/backend/src/plugins/Logs/util/getLogMessage.ts +++ b/backend/src/plugins/Logs/util/getLogMessage.ts @@ -5,10 +5,12 @@ import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { - messageSummary, - - renderRecursively, resolveMember, verboseChannelMention, verboseUserMention, - verboseUserName + messageSummary, + renderRecursively, + resolveMember, + verboseChannelMention, + verboseUserMention, + verboseUserName, } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { FORMAT_NO_TIMESTAMP, LogsPluginType, TLogChannel } from "../types"; diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 3d9d438c..4c6c7252 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -7,7 +7,6 @@ import { createChunkedMessage, get, noop } from "../../../utils"; import { LogsPluginType, TLogChannelMap } from "../types"; import { getLogMessage } from "./getLogMessage"; - const excludedUserProps = ["user", "member", "mod"]; const excludedRoleProps = ["message.member.roles", "member.roles"]; diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index c64185d8..3c3fb922 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -7,7 +7,6 @@ import { resolveUser, stripObjectToScalars, useMediaUrls } from "../../../utils" import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; - export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index 87631bbc..f83fe54a 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -6,7 +6,6 @@ import { LogType } from "../../../data/LogType"; import { resolveUser, stripObjectToScalars } from "../../../utils"; import { LogsPluginType } from "../types"; - export async function onMessageUpdate( pluginData: GuildPluginData, savedMessage: SavedMessage, diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 3be7332a..d6c19a5a 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -46,7 +46,6 @@ import { updateCase } from "./functions/updateCase"; import { warnMember } from "./functions/warnMember"; import { BanOptions, ConfigSchema, KickOptions, ModActionsPluginType, WarnOptions } from "./types"; - const defaultOptions = { config: { dm_on_warn: true, diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 7bc9d19f..12ce028d 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -9,7 +9,6 @@ import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { modActionsCmd } from "../types"; - const opts = { mod: ct.userId({ option: true }), }; diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index b4af16a4..2b96257e 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -3,15 +3,12 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { sendErrorMessage } from "../../../pluginUtils"; -import { - chunkArray, emptyEmbedValue, resolveUser, trimLines, UnknownUser -} from "../../../utils"; +import { chunkArray, emptyEmbedValue, resolveUser, trimLines, UnknownUser } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { modActionsCmd } from "../types"; - const opts = { expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), hidden: ct.bool({ option: true, isSwitch: true, shortcut: "h" }), diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 6e99fb9f..64b2e7d0 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -10,7 +10,6 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { modActionsCmd } from "../types"; - export const DeleteCaseCmd = modActionsCmd({ trigger: ["delete_case", "deletecase"], permission: "can_deletecase", diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 796caf19..8fb84b73 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -12,7 +12,6 @@ import { formatReasonWithAttachments } from "../functions/formatReasonWithAttach import { ignoreEvent } from "../functions/ignoreEvent"; import { IgnoredEventType, modActionsCmd } from "../types"; - export const MassbanCmd = modActionsCmd({ trigger: "massban", permission: "can_massban", diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index 758b7817..6b41e3f4 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -11,7 +11,6 @@ import { ignoreEvent } from "../functions/ignoreEvent"; import { isBanned } from "../functions/isBanned"; import { IgnoredEventType, modActionsCmd } from "../types"; - export const MassunbanCmd = modActionsCmd({ trigger: "massunban", permission: "can_massunban", diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index 46c8eeea..171270da 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -9,7 +9,6 @@ import { stripObjectToScalars } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { modActionsCmd } from "../types"; - export const MassmuteCmd = modActionsCmd({ trigger: "massmute", permission: "can_massmute", diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/MuteCmd.ts index b51fbd1e..f824fca3 100644 --- a/backend/src/plugins/ModActions/commands/MuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MuteCmd.ts @@ -6,7 +6,6 @@ import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; import { isBanned } from "../functions/isBanned"; import { modActionsCmd } from "../types"; - const opts = { mod: ct.member({ option: true }), notify: ct.string({ option: true }), diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index 997a05d7..850ed2c0 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -9,7 +9,6 @@ import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; import { isEventIgnored } from "../functions/isEventIgnored"; import { IgnoredEventType, modActionsEvt } from "../types"; - /** * Create a BAN case automatically when a user is banned manually. * Attempts to find the ban's details in the audit log. diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index 2a6af747..9bc6baf5 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -10,7 +10,6 @@ import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; import { isEventIgnored } from "../functions/isEventIgnored"; import { IgnoredEventType, modActionsEvt } from "../types"; - /** * Create a KICK case automatically when a user is kicked manually. * Attempts to find the kick's details in the audit log. diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index d0824fe1..7bec3cb7 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -9,7 +9,6 @@ import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; import { isEventIgnored } from "../functions/isEventIgnored"; import { IgnoredEventType, modActionsEvt } from "../types"; - /** * Create an UNBAN case automatically when a user is unbanned manually. * Attempts to find the unban's details in the audit log. diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index c17a7ad1..fc9cd29e 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -5,7 +5,6 @@ import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { modActionsEvt } from "../types"; - /** * Show an alert if a member with prior notes joins the server */ diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts index 6b6ddd91..9f95b417 100644 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts @@ -7,7 +7,6 @@ import { asSingleLine, UnknownUser } from "../../../utils"; import { ModActionsPluginType } from "../types"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; - export async function actualUnmuteCmd( pluginData: GuildPluginData, user: User | UnknownUser, diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index b6bea1aa..9c44be59 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -6,19 +6,18 @@ import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { renderTemplate } from "../../../templateFormatter"; import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult + createUserNotificationError, + notifyUser, + resolveUser, + stripObjectToScalars, + ucfirst, + UserNotificationResult, } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { BanOptions, BanResult, IgnoredEventType, ModActionsPluginType } from "../types"; import { getDefaultContactMethods } from "./getDefaultContactMethods"; import { ignoreEvent } from "./ignoreEvent"; - /** * Ban the specified user id, whether or not they're actually on the server at the time. Generates a case. */ diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index 09fbb9f5..d676e9aa 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -4,19 +4,18 @@ import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult + createUserNotificationError, + notifyUser, + resolveUser, + stripObjectToScalars, + ucfirst, + UserNotificationResult, } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types"; import { getDefaultContactMethods } from "./getDefaultContactMethods"; import { ignoreEvent } from "./ignoreEvent"; - /** * Kick the specified server member. Generates a case. */ diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index 1be237c4..9a8d7aff 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -4,19 +4,18 @@ import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult + createUserNotificationError, + notifyUser, + resolveUser, + stripObjectToScalars, + ucfirst, + UserNotificationResult, } from "../../../utils"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { ModActionsPluginType, WarnOptions, WarnResult } from "../types"; import { getDefaultContactMethods } from "./getDefaultContactMethods"; - export async function warnMember( pluginData: GuildPluginData, member: GuildMember, diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index 23205f10..cd9f6739 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -22,7 +22,6 @@ import { onMutesEvent } from "./functions/onMutesEvent"; import { unmuteUser } from "./functions/unmuteUser"; import { ConfigSchema, MutesPluginType } from "./types"; - const defaultOptions = { config: { mute_role: null, diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 537450a6..6eb24da0 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -2,7 +2,6 @@ import { User } from "discord.js"; import { sendSuccessMessage } from "../../../pluginUtils"; import { mutesCmd } from "../types"; - export const ClearBannedMutesCmd = mutesCmd({ trigger: "clear_banned_mutes", permission: "can_cleanup", diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index 233906a2..b818bdfb 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -4,7 +4,6 @@ import { resolveMember, stripObjectToScalars, UnknownUser } from "../../../utils import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { MutesPluginType } from "../types"; - export async function clearExpiredMutes(pluginData: GuildPluginData) { const expiredMutes = await pluginData.state.mutes.getExpiredMutes(); for (const mute of expiredMutes) { diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 6d26d661..d944cfe0 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -8,23 +8,18 @@ import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { renderTemplate } from "../../../templateFormatter"; import { - notifyUser, - - - - - resolveMember, resolveUser, - stripObjectToScalars, - ucfirst, - - - UserNotificationMethod, UserNotificationResult + notifyUser, + resolveMember, + resolveUser, + stripObjectToScalars, + ucfirst, + UserNotificationMethod, + UserNotificationResult, } from "../../../utils"; import { muteLock } from "../../../utils/lockNameHelpers"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { MuteOptions, MutesPluginType } from "../types"; - export async function muteUser( pluginData: GuildPluginData, userId: string, diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index 72201eae..aa896b43 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -9,7 +9,6 @@ import { CaseArgs } from "../../Cases/types"; import { MutesPluginType, UnmuteResult } from "../types"; import { memberHasMutedRole } from "./memberHasMutedRole"; - export async function unmuteUser( pluginData: GuildPluginData, userId: string, diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 251c8164..ee6fbf00 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -9,7 +9,6 @@ import { missingPermissionError } from "../../../utils/missingPermissionError"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { persistEvt } from "../types"; - const p = Permissions.FLAGS; export const LoadDataEvt = persistEvt({ diff --git a/backend/src/plugins/Persist/events/StoreDataEvt.ts b/backend/src/plugins/Persist/events/StoreDataEvt.ts index 2f43fac5..aad0c48e 100644 --- a/backend/src/plugins/Persist/events/StoreDataEvt.ts +++ b/backend/src/plugins/Persist/events/StoreDataEvt.ts @@ -3,7 +3,6 @@ import intersection from "lodash.intersection"; import { IPartialPersistData } from "../../../data/GuildPersistedData"; import { persistEvt } from "../types"; - export const StoreDataEvt = persistEvt({ event: "guildMemberRemove", diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 83713814..992f0596 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -7,7 +7,6 @@ import { rgbToInt } from "../../../utils/rgbToInt"; import { postCmd } from "../types"; import { formatContent } from "../util/formatContent"; - const COLOR_MATCH_REGEX = /^#?([0-9a-f]{6})$/; export const EditEmbedCmd = postCmd({ diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index d9d5ef6a..6db7d1cc 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -8,7 +8,6 @@ import { postCmd } from "../types"; import { actualPostCmd } from "../util/actualPostCmd"; import { formatContent } from "../util/formatContent"; - export const PostEmbedCmd = postCmd({ trigger: "post_embed", permission: "can_post", diff --git a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts index ea7a2b0f..65e76041 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts @@ -1,8 +1,12 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; import { - createChunkedMessage, - DBDateFormat, deactivateMentions, disableCodeBlocks, sorter, trimLines + createChunkedMessage, + DBDateFormat, + deactivateMentions, + disableCodeBlocks, + sorter, + trimLines, } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { postCmd } from "../types"; diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index de7db105..4066880a 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -5,7 +5,6 @@ import { downloadFile } from "../../../utils"; import { PostPluginType } from "../types"; import { formatContent } from "./formatContent"; - const fsp = fs.promises; export async function postMessage( diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts index fdaff973..37f8e553 100644 --- a/backend/src/plugins/Post/util/scheduledPostLoop.ts +++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts @@ -7,7 +7,6 @@ import { DBDateFormat, SECONDS, stripObjectToScalars } from "../../../utils"; import { PostPluginType } from "../types"; import { postMessage } from "./postMessage"; - const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS; export async function scheduledPostLoop(pluginData: GuildPluginData) { diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index a9ce7421..6653c010 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -4,7 +4,6 @@ import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { isDiscordRESTError } from "../../../utils"; import { reactionRolesCmd } from "../types"; - export const ClearReactionRolesCmd = reactionRolesCmd({ trigger: "reaction_roles clear", permission: "can_manage", diff --git a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts index c4f125f0..1d7a116f 100644 --- a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts @@ -3,7 +3,6 @@ import { noop, resolveMember, sleep } from "../../../utils"; import { reactionRolesEvt } from "../types"; import { addMemberPendingRoleChange } from "../util/addMemberPendingRoleChange"; - const CLEAR_ROLES_EMOJI = "❌"; export const AddReactionRoleEvt = reactionRolesEvt({ diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 7a79cc99..05638f2f 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -1,8 +1,4 @@ -import { - MessageActionRow, - MessageButton, - MessageComponentInteraction -} from "discord.js"; +import { MessageActionRow, MessageButton, MessageComponentInteraction } from "discord.js"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index 3059ba5c..f3f6c9c5 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -6,7 +6,6 @@ import { isDiscordRESTError, sleep } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ReactionRolesPluginType } from "../types"; - const CLEAR_ROLES_EMOJI = "❌"; /** diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index eb6bd714..fccf0fdd 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -5,7 +5,6 @@ import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginU import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; import { rolesCmd } from "../types"; - export const RemoveRoleCmd = rolesCmd({ trigger: "removerole", permission: "can_assign", diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index d5f14b8a..67f75d13 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -8,7 +8,6 @@ import { getApplyingEntries } from "../util/getApplyingEntries"; import { normalizeRoleNames } from "../util/normalizeRoleNames"; import { splitRoleNames } from "../util/splitRoleNames"; - export const RoleAddCmd = selfGrantableRolesCmd({ trigger: ["role", "role add"], permission: null, diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts index e4d5b579..d3f743d0 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts @@ -3,7 +3,6 @@ import humanizeDuration from "humanize-duration"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { slowmodeCmd } from "../types"; - export const SlowmodeGetCmd = slowmodeCmd({ trigger: "slowmode", permission: "can_manage", diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts index 9cad2a32..0ef7733c 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts @@ -4,7 +4,6 @@ import { createChunkedMessage } from "knub/dist/helpers"; import { errorMessage } from "../../../utils"; import { slowmodeCmd } from "../types"; - export const SlowmodeListCmd = slowmodeCmd({ trigger: ["slowmode list", "slowmode l", "slowmodes"], permission: "can_manage", diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 48005ab6..5f9ec9a4 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -10,7 +10,6 @@ import { slowmodeCmd } from "../types"; import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; import { disableBotSlowmodeForChannel } from "../util/disableBotSlowmodeForChannel"; - const MAX_NATIVE_SLOWMODE = 6 * HOURS; // 6 hours const MAX_BOT_SLOWMODE = DAYS * 365 * 100; // 100 years const MIN_BOT_SLOWMODE = 15 * MINUTES; diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 0490be02..9ca3d0c3 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -5,7 +5,6 @@ import { logger } from "../../../logger"; import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "../../../utils"; import { SlowmodePluginType } from "../types"; - export async function applyBotSlowmodeToUserId( pluginData: GuildPluginData, channel: GuildChannel & TextChannel, diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index a405b9b2..83439358 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -6,7 +6,6 @@ import { stripObjectToScalars, UnknownUser } from "../../../utils"; import { SlowmodePluginType } from "../types"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; - export async function clearExpiredSlowmodes(pluginData: GuildPluginData) { const expiredSlowmodeUsers = await pluginData.state.slowmodes.getExpiredSlowmodeUsers(); for (const user of expiredSlowmodeUsers) { diff --git a/backend/src/plugins/Slowmode/util/onMessageCreate.ts b/backend/src/plugins/Slowmode/util/onMessageCreate.ts index aa2a1db3..8147447b 100644 --- a/backend/src/plugins/Slowmode/util/onMessageCreate.ts +++ b/backend/src/plugins/Slowmode/util/onMessageCreate.ts @@ -12,7 +12,6 @@ import { BOT_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; import { SlowmodePluginType } from "../types"; import { applyBotSlowmodeToUserId } from "./applyBotSlowmodeToUserId"; - export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index a7846eb4..66a98fb6 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -10,12 +10,12 @@ import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { MuteResult } from "../../../plugins/Mutes/types"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { - convertDelayStringToMS, - DBDateFormat, - noop, - resolveMember, - stripObjectToScalars, - trimLines + convertDelayStringToMS, + DBDateFormat, + noop, + resolveMember, + stripObjectToScalars, + trimLines, } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types"; diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index d88fa744..5f79a3bb 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -4,7 +4,6 @@ import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { starboardCmd } from "../types"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; - export const MigratePinsCmd = starboardCmd({ trigger: "starboard migrate_pins", permission: "can_migrate", diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts index bedbddc5..0a8dc025 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts @@ -5,7 +5,6 @@ import { starboardEvt } from "../types"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; import { updateStarboardMessageStarCount } from "../util/updateStarboardMessageStarCount"; - export const StarboardReactionAddEvt = starboardEvt({ event: "messageReactionAdd", diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index ffff5915..a66f09f8 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -2,7 +2,6 @@ import { GuildChannel, Message } from "discord.js"; import path from "path"; import { EmbedWith, EMPTY_CHAR } from "../../../utils"; - const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"]; const audioAttachmentExtensions = ["wav", "mp3", "m4a"]; const videoAttachmentExtensions = ["mp4", "mkv", "mov"]; diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index ad2cd8b7..068ed424 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -4,7 +4,6 @@ import { StarboardPluginType, TStarboardOpts } from "../types"; import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; - export async function saveMessageToStarboard( pluginData: GuildPluginData, msg: Message, diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 61d8569c..e117983b 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -5,7 +5,6 @@ import { stripObjectToScalars } from "../../../utils"; import { tagsCmd } from "../types"; import { renderTagBody } from "../util/renderTagBody"; - export const TagEvalCmd = tagsCmd({ trigger: "tag eval", permission: "can_create", diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index 432b73ab..1dcbdb65 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -9,7 +9,6 @@ import { validate } from "../../../validatorUtils"; import { TagsPluginType } from "../types"; import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString"; - export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; if (!msg.data.content) return; diff --git a/backend/src/plugins/Tags/util/renderTagFromString.ts b/backend/src/plugins/Tags/util/renderTagFromString.ts index 89b489b0..930a70a5 100644 --- a/backend/src/plugins/Tags/util/renderTagFromString.ts +++ b/backend/src/plugins/Tags/util/renderTagFromString.ts @@ -9,7 +9,6 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { Tag, TagsPluginType } from "../types"; import { renderTagBody } from "./renderTagBody"; - export async function renderTagFromString( pluginData: GuildPluginData, str: string, diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 79b0f1cf..546d51dc 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -8,7 +8,6 @@ import { EmbedWith, multiSorter, resolveMember, sorter } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { utilityCmd } from "../types"; - export const AboutCmd = utilityCmd({ trigger: "about", description: "Show information about Zeppelin's status on the server", diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index ef307021..2e067e01 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -10,7 +10,6 @@ import { allowTimeout } from "../../../RegExpRunner"; import { DAYS, getInviteCodesInString, noop, SECONDS, stripObjectToScalars } from "../../../utils"; import { utilityCmd, UtilityPluginType } from "../types"; - const MAX_CLEAN_COUNT = 150; const MAX_CLEAN_TIME = 1 * DAYS; const CLEAN_COMMAND_DELETE_DELAY = 5 * SECONDS; diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index 3d5429aa..e51ceeab 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -5,7 +5,6 @@ import { messageLink } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; import { utilityCmd } from "../types"; - export const ContextCmd = utilityCmd({ trigger: "context", description: "Get a link to the context of the specified message", diff --git a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts index 53dd027c..48734fe0 100644 --- a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts +++ b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts @@ -2,7 +2,6 @@ import { TextChannel } from "discord.js"; import { activeReloads } from "../guildReloads"; import { utilityCmd } from "../types"; - export const ReloadGuildCmd = utilityCmd({ trigger: "reload_guild", description: "Reload the Zeppelin configuration and all plugins for the server. This can sometimes fix issues.", diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index b89285f3..8aa7e85a 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -5,7 +5,6 @@ import { chunkArray, sorter, trimLines } from "../../../utils"; import { refreshMembersIfNeeded } from "../refreshMembers"; import { utilityCmd } from "../types"; - export const RolesCmd = utilityCmd({ trigger: "roles", description: "List all roles or roles matching a search", diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index 075c974e..bacaedf6 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -4,7 +4,6 @@ import { getBaseUrl, sendErrorMessage } from "../../../pluginUtils"; import { canReadChannel } from "../../../utils/canReadChannel"; import { utilityCmd } from "../types"; - export const SourceCmd = utilityCmd({ trigger: "source", description: "View the message source of the specified message id", diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index a750fe02..b0a44755 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -2,12 +2,9 @@ import { VoiceChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { - stripObjectToScalars -} from "../../../utils"; +import { stripObjectToScalars } from "../../../utils"; import { utilityCmd } from "../types"; - export const VcdisconnectCmd = utilityCmd({ trigger: ["vcdisconnect", "vcdisc", "vcdc", "vckick", "vck"], description: "Disconnect a member from their voice channel", diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 8b5b0aa5..967db1f0 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -2,17 +2,9 @@ import { VoiceChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { - channelMentionRegex, - - isSnowflake, - - simpleClosestStringMatch, - stripObjectToScalars -} from "../../../utils"; +import { channelMentionRegex, isSnowflake, simpleClosestStringMatch, stripObjectToScalars } from "../../../utils"; import { utilityCmd } from "../types"; - export const VcmoveCmd = utilityCmd({ trigger: "vcmove", description: "Move a member to another voice channel", diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index 8dcfef3b..b34da288 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -7,7 +7,6 @@ import { EmbedWith, formatNumber, preEmbedPadding, trimLines } from "../../../ut import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; - const TEXT_CHANNEL_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740656843545772062/text-channel.png"; const VOICE_CHANNEL_ICON = diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index 046c6035..c8ddfad8 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -4,21 +4,19 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { ChannelTypeStrings } from "src/types"; import { - EmbedWith, - - formatNumber, - GroupDMInvite, - inviteHasCounts, - isGroupDMInvite, - isGuildInvite, - preEmbedPadding, - resolveInvite, - trimLines + EmbedWith, + formatNumber, + GroupDMInvite, + inviteHasCounts, + isGroupDMInvite, + isGuildInvite, + preEmbedPadding, + resolveInvite, + trimLines, } from "../../../utils"; import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; import { UtilityPluginType } from "../types"; - export async function getInviteInfoEmbed( pluginData: GuildPluginData, inviteCode: string, diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index d411be4e..27faf36a 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -8,7 +8,6 @@ import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLi import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; - const MESSAGE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740685652152025088/message.png"; export async function getMessageInfoEmbed( diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 9e4f40b2..e47410f5 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -3,21 +3,20 @@ import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { - EmbedWith, - formatNumber, - inviteHasCounts, - memoize, - MINUTES, - preEmbedPadding, - resolveInvite, - resolveUser, - trimLines + EmbedWith, + formatNumber, + inviteHasCounts, + memoize, + MINUTES, + preEmbedPadding, + resolveInvite, + resolveUser, + trimLines, } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; import { getGuildPreview } from "./getGuildPreview"; - export async function getServerInfoEmbed( pluginData: GuildPluginData, serverId: string, diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index 400f75b8..3ef1777f 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -2,9 +2,7 @@ import { MessageEmbedOptions } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { - EmbedWith, preEmbedPadding -} from "../../../utils"; +import { EmbedWith, preEmbedPadding } from "../../../utils"; import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 7dc72d35..96ed072a 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -4,10 +4,14 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; import { - EmbedWith, messageLink, preEmbedPadding, resolveMember, - resolveUser, - - sorter, trimLines, UnknownUser + EmbedWith, + messageLink, + preEmbedPadding, + resolveMember, + resolveUser, + sorter, + trimLines, + UnknownUser, } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index 53f2a630..c6ebe5b6 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -5,7 +5,6 @@ import { createChunkedMessage, stripObjectToScalars } from "../../../utils"; import { sendDM } from "../../../utils/sendDM"; import { welcomeMessageEvt } from "../types"; - export const SendWelcomeMessageEvt = welcomeMessageEvt({ event: "guildMemberAdd", diff --git a/backend/src/plugins/ZeppelinPluginBlueprint.ts b/backend/src/plugins/ZeppelinPluginBlueprint.ts index 76177e9c..7a1dd44a 100644 --- a/backend/src/plugins/ZeppelinPluginBlueprint.ts +++ b/backend/src/plugins/ZeppelinPluginBlueprint.ts @@ -1,15 +1,12 @@ import * as t from "io-ts"; import { - BasePluginType, - - GlobalPluginBlueprint, - GlobalPluginData, - - GuildPluginBlueprint, - GuildPluginData, typedGlobalPlugin, - - - typedGuildPlugin + BasePluginType, + GlobalPluginBlueprint, + GlobalPluginData, + GuildPluginBlueprint, + GuildPluginData, + typedGlobalPlugin, + typedGuildPlugin, } from "knub"; import { PluginOptions } from "knub/dist/config/configTypes"; import { Awaitable } from "knub/dist/utils"; diff --git a/backend/src/utils.test.ts b/backend/src/utils.test.ts index 042f477d..abd89774 100644 --- a/backend/src/utils.test.ts +++ b/backend/src/utils.test.ts @@ -3,7 +3,6 @@ import * as ioTs from "io-ts"; import { convertDelayStringToMS, convertMSToDelayString, getUrlsInString, tAllowedMentions } from "./utils"; import { ErisAllowedMentionFormat } from "./utils/erisAllowedMentionsToDjsMentionOptions"; - type AssertEquals = TActual extends TExpected ? true : false; test("getUrlsInString(): detects full links", t => { diff --git a/backend/src/utils.ts b/backend/src/utils.ts index da467473..edfe1ad2 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1,27 +1,24 @@ import { - Client, - Constants, - Emoji, - Guild, - GuildAuditLogs, - GuildAuditLogsEntry, - GuildChannel, - GuildMember, - - Invite, - Message, - - MessageAttachment, - - MessageEmbed, - MessageEmbedOptions, - MessageMentionOptions, - MessageOptions, - PartialChannelData, - PartialMessage, - StringResolvable, - TextChannel, - User + Client, + Constants, + Emoji, + Guild, + GuildAuditLogs, + GuildAuditLogsEntry, + GuildChannel, + GuildMember, + Invite, + Message, + MessageAttachment, + MessageEmbed, + MessageEmbedOptions, + MessageMentionOptions, + MessageOptions, + PartialChannelData, + PartialMessage, + StringResolvable, + TextChannel, + User, } from "discord.js"; import emojiRegex from "emoji-regex"; import { either } from "fp-ts/lib/Either"; @@ -39,7 +36,6 @@ import { sendDM } from "./utils/sendDM"; import { waitForButtonConfirm } from "./utils/waitForInteraction"; import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; - const fsp = fs.promises; const delayStringMultipliers = { diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index 8d6249c5..8eeacc97 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,12 +1,4 @@ -import { - Client, - Message, - MessageOptions, - MessageReaction, - PartialUser, - TextChannel, - User -} from "discord.js"; +import { Client, Message, MessageOptions, MessageReaction, PartialUser, TextChannel, User } from "discord.js"; import { Awaitable } from "knub/dist/utils"; import { MINUTES, noop } from "../utils"; import Timeout = NodeJS.Timeout; diff --git a/backend/src/utils/crypt.test.ts b/backend/src/utils/crypt.test.ts index 7034205f..38b381ca 100644 --- a/backend/src/utils/crypt.test.ts +++ b/backend/src/utils/crypt.test.ts @@ -1,7 +1,6 @@ import test from "ava"; import { decrypt, encrypt } from "./crypt"; - test("encrypt() followed by decrypt()", t => { const original = "banana 123 👀 💕"; // Includes emojis to verify utf8 stuff works const encrypted = encrypt(original); diff --git a/backend/src/utils/crypt.ts b/backend/src/utils/crypt.ts index 9af9c3ce..fdf81109 100644 --- a/backend/src/utils/crypt.ts +++ b/backend/src/utils/crypt.ts @@ -1,7 +1,6 @@ import crypto from "crypto"; import "../loadEnv"; - if (!process.env.KEY) { // tslint:disable-next-line:no-console console.error("Environment value KEY required for encryption"); diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 76310557..497c882d 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -1,11 +1,4 @@ -import { - MessageActionRow, - - MessageButton, - - - MessageComponentInteraction, MessageOptions, TextChannel -} from "discord.js"; +import { MessageActionRow, MessageButton, MessageComponentInteraction, MessageOptions, TextChannel } from "discord.js"; import { PluginError } from "knub"; import { noop } from "knub/dist/utils"; import moment from "moment"; From 5c7c3c8cba641e80ecdc839fd973aa7986135566 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 8 Jun 2021 04:34:32 +0200 Subject: [PATCH 14/79] Make message with default buttons stateful --- backend/src/data/GuildButtonRoles.ts | 10 +++- backend/src/data/entities/ButtonRole.ts | 4 ++ .../1623018101018-CreateButtonRolesTable.ts | 5 ++ .../ReactionRoles/ReactionRolesPlugin.ts | 4 ++ .../commands/PostButtonRolesCmd.ts | 47 ++++++++------- .../events/ButtonInteractionEvt.ts | 58 ++++++++++++++----- .../ReactionRoles/events/MessageDeletedEvt.ts | 14 +++++ backend/src/plugins/ReactionRoles/types.ts | 12 +--- .../util/buttonCustomIdFunctions.ts | 41 +++++++++++++ backend/src/utils/idToTimestamp.ts | 10 ++++ 10 files changed, 158 insertions(+), 47 deletions(-) create mode 100644 backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts create mode 100644 backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts create mode 100644 backend/src/utils/idToTimestamp.ts diff --git a/backend/src/data/GuildButtonRoles.ts b/backend/src/data/GuildButtonRoles.ts index 56bf7bb1..24ee2e59 100644 --- a/backend/src/data/GuildButtonRoles.ts +++ b/backend/src/data/GuildButtonRoles.ts @@ -38,9 +38,17 @@ export class GuildButtonRoles extends BaseGuildRepository { }); } - async add(messageId: string, buttonId: string, buttonGroup: string, buttonName: string) { + async getForButtonGroup(buttonGroup: string) { + return this.buttonRoles.find({ + guild_id: this.guildId, + button_group: buttonGroup, + }); + } + + async add(channelId: string, messageId: string, buttonId: string, buttonGroup: string, buttonName: string) { await this.buttonRoles.insert({ guild_id: this.guildId, + channel_id: channelId, message_id: messageId, button_id: buttonId, button_group: buttonGroup, diff --git a/backend/src/data/entities/ButtonRole.ts b/backend/src/data/entities/ButtonRole.ts index 9dc52b2c..affcce07 100644 --- a/backend/src/data/entities/ButtonRole.ts +++ b/backend/src/data/entities/ButtonRole.ts @@ -6,6 +6,10 @@ export class ButtonRole { @PrimaryColumn() guild_id: string; + @Column() + @PrimaryColumn() + channel_id: string; + @Column() @PrimaryColumn() message_id: string; diff --git a/backend/src/migrations/1623018101018-CreateButtonRolesTable.ts b/backend/src/migrations/1623018101018-CreateButtonRolesTable.ts index ef5c6e8a..4d6b47e1 100644 --- a/backend/src/migrations/1623018101018-CreateButtonRolesTable.ts +++ b/backend/src/migrations/1623018101018-CreateButtonRolesTable.ts @@ -11,6 +11,11 @@ export class CreateButtonRolesTable1623018101018 implements MigrationInterface { type: "bigint", isPrimary: true, }, + { + name: "channel_id", + type: "bigint", + isPrimary: true, + }, { name: "message_id", type: "bigint", diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 51817f58..d0452703 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -1,4 +1,5 @@ import { PluginOptions } from "knub"; +import { GuildButtonRoles } from "src/data/GuildButtonRoles"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; @@ -10,6 +11,7 @@ import { PostButtonRolesCmd } from "./commands/PostButtonRolesCmd"; import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; import { ButtonInteractionEvt } from "./events/ButtonInteractionEvt"; +import { MessageDeletedEvt } from "./events/MessageDeletedEvt"; import { ConfigSchema, ReactionRolesPluginType } from "./types"; import { autoRefreshLoop } from "./util/autoRefreshLoop"; @@ -57,6 +59,7 @@ export const ReactionRolesPlugin = zeppelinGuildPlugin( events: [ AddReactionRoleEvt, ButtonInteractionEvt, + MessageDeletedEvt, ], beforeLoad(pluginData) { @@ -64,6 +67,7 @@ export const ReactionRolesPlugin = zeppelinGuildPlugin( state.reactionRoles = GuildReactionRoles.getGuildInstance(guild.id); state.savedMessages = GuildSavedMessages.getGuildInstance(guild.id); + state.buttonRoles = GuildButtonRoles.getGuildInstance(guild.id); state.reactionRemoveQueue = new Queue(); state.roleChangeQueue = new Queue(); state.pendingRoleChanges = new Map(); diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index e5ccf683..3b162fa3 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -2,42 +2,33 @@ import { MessageActionRow, MessageButton, TextChannel } from "discord.js"; import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { reactionRolesCmd } from "../types"; -import { ButtonMenuActions } from "../util/buttonMenuActions"; +import { createHash } from "crypto"; +import moment from "moment"; export const PostButtonRolesCmd = reactionRolesCmd({ trigger: "reaction_roles post", permission: "can_manage", signature: { - button_group: ct.string(), + channel: ct.textChannel(), + buttonGroup: ct.string(), }, async run({ message: msg, args, pluginData }) { const cfg = pluginData.config.get(); - const group = cfg.button_groups[args.button_group]; + const group = cfg.button_groups[args.buttonGroup]; if (!group) { - sendErrorMessage(pluginData, msg.channel, `No button group matches the name **${args.button_group}**`); - } - - const channel = pluginData.guild.channels.resolve(group.channel_id); - if (!channel) { - await sendErrorMessage( - pluginData, - msg.channel, - `The ID ${group.channel_id} does not match a channel on the server`, - ); + sendErrorMessage(pluginData, msg.channel, `No button group matches the name **${args.buttonGroup}**`); return; } const buttons: MessageButton[] = []; - for (const button of Object.values(group.default_buttons)) { - let customId = ""; - if ((await pluginData.guild.roles.fetch(button.role_or_menu)) != null) { - customId = `${args.button_group}::${ButtonMenuActions.GRANT_ROLE}::${button.role_or_menu}`; - } else { - customId = `${args.button_group}::${ButtonMenuActions.OPEN_MENU}::${button.role_or_menu}`; - } + const toInsert: Array<{ customId; buttonGroup; buttonName }> = []; + for (const [buttonName, button] of Object.entries(group.default_buttons)) { + const customId = createHash("md5") + .update(`${buttonName}${moment.utc().valueOf()}`) + .digest("hex"); const btn = new MessageButton() .setLabel(button.label) @@ -51,15 +42,27 @@ export const PostButtonRolesCmd = reactionRolesCmd({ } buttons.push(btn); + toInsert.push({ customId, buttonGroup: args.buttonGroup, buttonName }); } const row = new MessageActionRow().addComponents(buttons); try { - await (channel as TextChannel).send({ content: group.message, components: [row], split: false }); + const newMsg = await args.channel.send({ content: group.message, components: [row], split: false }); + + for (const btn of toInsert) { + await pluginData.state.buttonRoles.add( + args.channel.id, + newMsg.id, + btn.customId, + btn.buttonGroup, + btn.buttonName, + ); + } } catch (e) { sendErrorMessage(pluginData, msg.channel, `Error trying to post message: ${e}`); return; } - await sendSuccessMessage(pluginData, msg.channel, `Successfully posted message in <#${channel.id}>`); + + await sendSuccessMessage(pluginData, msg.channel, `Successfully posted message in <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 05638f2f..29cef85b 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -1,9 +1,20 @@ import { MessageActionRow, MessageButton, MessageComponentInteraction } from "discord.js"; +import moment from "moment"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; +import { MINUTES } from "src/utils"; +import { idToTimestamp } from "src/utils/idToTimestamp"; import { reactionRolesEvt } from "../types"; +import { + generateStatelessCustomId, + resolveStatefulCustomId, + BUTTON_CONTEXT_SEPARATOR, +} from "../util/buttonCustomIdFunctions"; import { ButtonMenuActions } from "../util/buttonMenuActions"; +import humanizeDuration from "humanize-duration"; + +const BUTTON_INVALIDATION_TIME = 15 * MINUTES; export const ButtonInteractionEvt = reactionRolesEvt({ event: "interaction", @@ -14,42 +25,60 @@ export const ButtonInteractionEvt = reactionRolesEvt({ : null; if (!int) return; const cfg = meta.pluginData.config.get(); - const split = int.customID.split("::"); - const [groupName, action, roleOrMenu] = [split[0], split[1], split[2]]; + const split = int.customID.split(BUTTON_CONTEXT_SEPARATOR); + const context = (await resolveStatefulCustomId(meta.pluginData, int.customID)) ?? { + groupName: split[0], + action: split[1], + roleOrMenu: split[2], + stateless: true, + }; - const group = cfg.button_groups[groupName]; + if (context.stateless) { + const timeSinceCreation = moment.utc().valueOf() - idToTimestamp(int.message.id)!; + if (timeSinceCreation >= BUTTON_INVALIDATION_TIME) { + sendEphemeralReply( + int, + `Sorry, but these buttons are invalid because they are older than ${humanizeDuration( + BUTTON_INVALIDATION_TIME, + )}.\nIf the menu is still available, open it again to assign yourself roles!`, + ); + return; + } + } + + const group = cfg.button_groups[context.groupName]; if (!group) { await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`); meta.pluginData .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, group **${groupName}** not found in config`, + `**A configuration error occured** on buttons for message ${int.message.id}, group **${context.groupName}** not found in config`, ); return; } // Verify that detected action is known by us - if (!(Object).values(ButtonMenuActions).includes(action)) { + if (!(Object).values(ButtonMenuActions).includes(context.action)) { await sendEphemeralReply(int, `A internal error was encountered, please contact the Administrators!`); meta.pluginData .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A internal error occured** on buttons for message ${int.message.id}, action **${action}** is not known`, + `**A internal error occured** on buttons for message ${int.message.id}, action **${context.action}** is not known`, ); return; } - if (action === ButtonMenuActions.GRANT_ROLE) { - const role = await meta.pluginData.guild.roles.fetch(roleOrMenu); + if (context.action === ButtonMenuActions.GRANT_ROLE) { + const role = await meta.pluginData.guild.roles.fetch(context.roleOrMenu); if (!role) { await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`); meta.pluginData .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, group **${groupName}** not found in config`, + `**A configuration error occured** on buttons for message ${int.message.id}, group **${context.groupName}** not found in config`, ); return; } @@ -66,11 +95,10 @@ export const ButtonInteractionEvt = reactionRolesEvt({ return; } - if (action === ButtonMenuActions.OPEN_MENU) { + if (context.action === ButtonMenuActions.OPEN_MENU) { const menuButtons: MessageButton[] = []; - for (const menuButton of Object.values(group.button_menus[roleOrMenu])) { - let customId = ""; - customId = `${groupName}::${ButtonMenuActions.GRANT_ROLE}::${menuButton.role}`; + for (const menuButton of Object.values(group.button_menus[context.roleOrMenu])) { + const customId = await generateStatelessCustomId(meta.pluginData, context.groupName, menuButton.role_or_menu); const btn = new MessageButton() .setLabel(menuButton.label) @@ -91,7 +119,7 @@ export const ButtonInteractionEvt = reactionRolesEvt({ .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, menu **${roleOrMenu}** not found in config`, + `**A configuration error occured** on buttons for message ${int.message.id}, menu **${context.roleOrMenu}** not found in config`, ); return; } @@ -102,7 +130,7 @@ export const ButtonInteractionEvt = reactionRolesEvt({ } logger.warn( - `Action ${action} on button ${int.customID} (Guild: ${int.guildID}, Channel: ${int.channelID}) is unknown!`, + `Action ${context.action} on button ${int.customID} (Guild: ${int.guildID}, Channel: ${int.channelID}) is unknown!`, ); await sendEphemeralReply(int, `A internal error was encountered, please contact the Administrators!`); }, diff --git a/backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts b/backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts new file mode 100644 index 00000000..323da037 --- /dev/null +++ b/backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts @@ -0,0 +1,14 @@ +import { reactionRolesEvt } from "../types"; + +export const MessageDeletedEvt = reactionRolesEvt({ + event: "messageDelete", + allowBots: true, + allowSelf: true, + + async listener(meta) { + const pluginData = meta.pluginData; + + await pluginData.state.buttonRoles.removeAllForMessageId(meta.args.message.id); + await pluginData.state.reactionRoles.removeFromMessage(meta.args.message.id); + }, +}); diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index 9d80c81e..940af482 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -1,5 +1,6 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; +import { GuildButtonRoles } from "src/data/GuildButtonRoles"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; @@ -11,18 +12,10 @@ const ButtonOpts = t.type({ }); export type TButtonOpts = t.TypeOf; -const MenuButtonOpts = t.type({ - label: t.string, - emoji: t.string, - role: t.string, -}); -export type TMenuButtonOpts = t.TypeOf; - const ButtonPairOpts = t.type({ - channel_id: t.string, message: t.string, default_buttons: t.record(t.string, ButtonOpts), - button_menus: t.record(t.string, t.record(t.string, MenuButtonOpts)), + button_menus: t.record(t.string, t.record(t.string, ButtonOpts)), }); export type TButtonPairOpts = t.TypeOf; @@ -54,6 +47,7 @@ export interface ReactionRolesPluginType extends BasePluginType { state: { reactionRoles: GuildReactionRoles; savedMessages: GuildSavedMessages; + buttonRoles: GuildButtonRoles; reactionRemoveQueue: Queue; roleChangeQueue: Queue; diff --git a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts new file mode 100644 index 00000000..cde61646 --- /dev/null +++ b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts @@ -0,0 +1,41 @@ +import { GuildPluginData } from "knub"; +import { ReactionRolesPluginType } from "../types"; +import { ButtonMenuActions } from "./buttonMenuActions"; + +export const BUTTON_CONTEXT_SEPARATOR = "::"; + +export async function getButtonAction(pluginData: GuildPluginData, roleOrMenu: string) { + if (await pluginData.guild.roles.fetch(roleOrMenu)) { + return ButtonMenuActions.GRANT_ROLE; + } else { + return ButtonMenuActions.OPEN_MENU; + } +} + +export async function generateStatelessCustomId( + pluginData: GuildPluginData, + groupName: string, + roleOrMenu: string, +) { + let id = groupName + BUTTON_CONTEXT_SEPARATOR; + + id += `${await getButtonAction(pluginData, roleOrMenu)}${BUTTON_CONTEXT_SEPARATOR}${roleOrMenu}`; + + return id; +} + +export async function resolveStatefulCustomId(pluginData: GuildPluginData, id: string) { + const button = await pluginData.state.buttonRoles.getForButtonId(id); + + if (button) { + const group = pluginData.config.get().button_groups[button.button_group]; + const cfgButton = group.default_buttons[button.button_name]; + + return { + groupName: button.button_group, + action: await getButtonAction(pluginData, cfgButton.role_or_menu), + roleOrMenu: cfgButton.role_or_menu, + stateless: false, + }; + } +} diff --git a/backend/src/utils/idToTimestamp.ts b/backend/src/utils/idToTimestamp.ts new file mode 100644 index 00000000..62dd4743 --- /dev/null +++ b/backend/src/utils/idToTimestamp.ts @@ -0,0 +1,10 @@ +import moment from "moment"; + +const EPOCH = 1420070400000; + +export function idToTimestamp(id: string) { + if (typeof id === "number") return null; + return moment(+id / 4194304 + EPOCH) + .utc() + .valueOf(); +} From b0329dca054e2f0a2fc500b1b9aa1eca47a4be44 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 8 Jun 2021 04:47:36 +0200 Subject: [PATCH 15/79] Move action handlers to util file --- .../events/ButtonInteractionEvt.ts | 64 ++------------- .../util/buttonActionHandlers.ts | 81 +++++++++++++++++++ .../util/buttonCustomIdFunctions.ts | 2 +- .../ReactionRoles/util/buttonMenuActions.ts | 2 +- 4 files changed, 89 insertions(+), 60 deletions(-) create mode 100644 backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 29cef85b..6dd3f793 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -1,4 +1,4 @@ -import { MessageActionRow, MessageButton, MessageComponentInteraction } from "discord.js"; +import { MessageComponentInteraction } from "discord.js"; import moment from "moment"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; @@ -6,13 +6,10 @@ import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; import { MINUTES } from "src/utils"; import { idToTimestamp } from "src/utils/idToTimestamp"; import { reactionRolesEvt } from "../types"; -import { - generateStatelessCustomId, - resolveStatefulCustomId, - BUTTON_CONTEXT_SEPARATOR, -} from "../util/buttonCustomIdFunctions"; +import { resolveStatefulCustomId, BUTTON_CONTEXT_SEPARATOR } from "../util/buttonCustomIdFunctions"; import { ButtonMenuActions } from "../util/buttonMenuActions"; import humanizeDuration from "humanize-duration"; +import { handleModifyRole, handleOpenMenu } from "../util/buttonActionHandlers"; const BUTTON_INVALIDATION_TIME = 15 * MINUTES; @@ -70,62 +67,13 @@ export const ButtonInteractionEvt = reactionRolesEvt({ return; } - if (context.action === ButtonMenuActions.GRANT_ROLE) { - const role = await meta.pluginData.guild.roles.fetch(context.roleOrMenu); - if (!role) { - await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`); - meta.pluginData - .getPlugin(LogsPlugin) - .log( - LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, group **${context.groupName}** not found in config`, - ); - return; - } - - const member = await meta.pluginData.guild.members.fetch(int.user.id); - if (member.roles.cache.has(role.id)) { - await member.roles.remove(role, `Button Roles on message ${int.message.id}`); - await sendEphemeralReply(int, `Role **${role.name}** removed`); - } else { - await member.roles.add(role, `Button Roles on message ${int.message.id}`); - await sendEphemeralReply(int, `Role **${role.name}** added`); - } - + if (context.action === ButtonMenuActions.MODIFY_ROLE) { + await handleModifyRole(meta.pluginData, int, group, context); return; } if (context.action === ButtonMenuActions.OPEN_MENU) { - const menuButtons: MessageButton[] = []; - for (const menuButton of Object.values(group.button_menus[context.roleOrMenu])) { - const customId = await generateStatelessCustomId(meta.pluginData, context.groupName, menuButton.role_or_menu); - - const btn = new MessageButton() - .setLabel(menuButton.label) - .setStyle("PRIMARY") - .setType("BUTTON") - .setCustomID(customId); - - if (menuButton.emoji) { - const emo = meta.pluginData.client.emojis.resolve(menuButton.emoji) ?? menuButton.emoji; - btn.setEmoji(emo); - } - menuButtons.push(btn); - } - - if (menuButtons.length === 0) { - await sendEphemeralReply(int, `A configuration error was encountered, please contact the Administrators!`); - meta.pluginData - .getPlugin(LogsPlugin) - .log( - LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, menu **${context.roleOrMenu}** not found in config`, - ); - return; - } - const row = new MessageActionRow().addComponents(menuButtons); - - int.reply({ content: `Click to add/remove a role`, components: [row], ephemeral: true, split: false }); + await handleOpenMenu(meta.pluginData, int, group, context); return; } diff --git a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts new file mode 100644 index 00000000..8a098476 --- /dev/null +++ b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts @@ -0,0 +1,81 @@ +import { MessageButton, MessageActionRow, MessageComponentInteraction } from "discord.js"; +import { GuildPluginData } from "knub"; +import { LogType } from "../../../data/LogType"; +import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; +import { ReactionRolesPluginType, TButtonPairOpts } from "../types"; +import { generateStatelessCustomId } from "./buttonCustomIdFunctions"; + +export async function handleOpenMenu( + pluginData: GuildPluginData, + int: MessageComponentInteraction, + group: TButtonPairOpts, + context, +) { + const menuButtons: MessageButton[] = []; + for (const menuButton of Object.values(group.button_menus[context.roleOrMenu])) { + const customId = await generateStatelessCustomId(pluginData, context.groupName, menuButton.role_or_menu); + + const btn = new MessageButton() + .setLabel(menuButton.label) + .setStyle("PRIMARY") + .setType("BUTTON") + .setCustomID(customId); + + if (menuButton.emoji) { + const emo = pluginData.client.emojis.resolve(menuButton.emoji) ?? menuButton.emoji; + btn.setEmoji(emo); + } + menuButtons.push(btn); + } + + if (menuButtons.length === 0) { + await int.reply({ + content: `A configuration error was encountered, please contact the Administrators!`, + ephemeral: true, + }); + pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A configuration error occured** on buttons for message ${int.message.id}, menu **${context.roleOrMenu}** not found in config`, + ); + return; + } + const row = new MessageActionRow().addComponents(menuButtons); + + int.reply({ content: `Click to add/remove a role`, components: [row], ephemeral: true }); + return; +} + +export async function handleModifyRole( + pluginData: GuildPluginData, + int: MessageComponentInteraction, + group: TButtonPairOpts, + context, +) { + const role = await pluginData.guild.roles.fetch(context.roleOrMenu); + if (!role) { + await int.reply({ + content: `A configuration error was encountered, please contact the Administrators!`, + ephemeral: true, + }); + pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A configuration error occured** on buttons for message ${int.message.id}, role **${context.roleOrMenu}** not found on server`, + ); + return; + } + + const member = await pluginData.guild.members.fetch(int.user.id); + if (member.roles.cache.has(role.id)) { + await member.roles.remove(role, `Button Roles on message ${int.message.id}`); + await int.reply({ content: `Role **${role.name}** removed`, ephemeral: true }); + } else { + await member.roles.add(role, `Button Roles on message ${int.message.id}`); + await int.reply({ content: `Role **${role.name}** added`, ephemeral: true }); + } + + return; +} diff --git a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts index cde61646..26eae6f2 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts @@ -6,7 +6,7 @@ export const BUTTON_CONTEXT_SEPARATOR = "::"; export async function getButtonAction(pluginData: GuildPluginData, roleOrMenu: string) { if (await pluginData.guild.roles.fetch(roleOrMenu)) { - return ButtonMenuActions.GRANT_ROLE; + return ButtonMenuActions.MODIFY_ROLE; } else { return ButtonMenuActions.OPEN_MENU; } diff --git a/backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts b/backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts index 3edcca0d..89c77ff7 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonMenuActions.ts @@ -1,4 +1,4 @@ export enum ButtonMenuActions { OPEN_MENU = "goto", - GRANT_ROLE = "grant", + MODIFY_ROLE = "grant", } From 421f6defaaf8da8f9314e92e27694e3961dc8c98 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 17 Jun 2021 01:32:38 +0200 Subject: [PATCH 16/79] Remove unnecessary cache lookup --- backend/src/plugins/Utility/commands/CleanCmd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 2e067e01..8e27c286 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -32,7 +32,7 @@ async function cleanMessages( pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE_BULK, idsToDelete[0]); // Actually delete the messages - (pluginData.guild.channels.cache.get(channel.id) as TextChannel).bulkDelete(idsToDelete); + channel.bulkDelete(idsToDelete); await pluginData.state.savedMessages.markBulkAsDeleted(idsToDelete); // Create an archive From 2700f4e38990dc269918f859cabc5bd1802c125f Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 17 Jun 2021 02:10:23 +0200 Subject: [PATCH 17/79] Allow !clean to delete messages not already saved If a message is found that is not stored, we save it and then bulk delete --- backend/src/data/GuildSavedMessages.ts | 6 +++++ .../src/plugins/Utility/commands/CleanCmd.ts | 26 ++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index b80fae0f..0ede8e83 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -159,6 +159,12 @@ export class GuildSavedMessages extends BaseGuildRepository { return this.create({ ...data, ...overrides }); } + async createFromMessages(messages: Message[], overrides = {}) { + for (const msg of messages) { + await this.createFromMsg(msg, overrides); + } + } + async markAsDeleted(id) { await this.messages .createQueryBuilder("messages") diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 8e27c286..416b6d10 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -121,11 +121,20 @@ export const CleanCmd = utilityCmd({ } while (messagesToClean.length < args.count) { - const potentialMessagesToClean = await pluginData.state.savedMessages.getLatestByChannelBeforeId( - targetChannel.id, - beforeId, - args.count, - ); + const potentialMessages = await targetChannel.messages.fetch({ + before: beforeId, + limit: args.count, + }); + if (potentialMessages.size === 0) break; + + const existingStored = await pluginData.state.savedMessages.getMultiple(potentialMessages.keyArray()); + const alreadyStored = existingStored.map(stored => stored.id); + const messagesToStore = potentialMessages + .array() + .filter(potentialMsg => !alreadyStored.includes(potentialMsg.id)); + await pluginData.state.savedMessages.createFromMessages(messagesToStore); + + const potentialMessagesToClean = await pluginData.state.savedMessages.getMultiple(potentialMessages.keyArray()); if (potentialMessagesToClean.length === 0) break; const filtered: SavedMessage[] = []; @@ -150,12 +159,9 @@ export const CleanCmd = utilityCmd({ const withoutOverflow = filtered.slice(0, remaining); messagesToClean.push(...withoutOverflow); - beforeId = potentialMessagesToClean[potentialMessagesToClean.length - 1].id; + beforeId = potentialMessages.lastKey()!; - if ( - foundId || - moment.utc(potentialMessagesToClean[potentialMessagesToClean.length - 1].posted_at).valueOf() < timeCutoff - ) { + if (foundId || moment.utc(potentialMessages.last()!.createdTimestamp).valueOf() < timeCutoff) { break; } } From f9dd82f2018ff50ad69e45b17cf64ca42fa1ac53 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 17 Jun 2021 02:30:12 +0200 Subject: [PATCH 18/79] Add member_leave automod trigger At least i think so - cant test it until knub changes are done --- backend/src/plugins/Automod/AutomodPlugin.ts | 3 ++- backend/src/plugins/Automod/constants.ts | 1 + ...JoinEvt.ts => RunAutomodOnJoinLeaveEvt.ts} | 22 +++++++++++++++++++ .../Automod/triggers/availableTriggers.ts | 2 ++ .../plugins/Automod/triggers/memberLeave.ts | 20 +++++++++++++++++ backend/src/plugins/Automod/types.ts | 3 ++- 6 files changed, 49 insertions(+), 2 deletions(-) rename backend/src/plugins/Automod/events/{RunAutomodOnJoinEvt.ts => RunAutomodOnJoinLeaveEvt.ts} (58%) create mode 100644 backend/src/plugins/Automod/triggers/memberLeave.ts diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index d57df9ed..eb2484dd 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -20,7 +20,7 @@ import { AntiraidClearCmd } from "./commands/AntiraidClearCmd"; import { SetAntiraidCmd } from "./commands/SetAntiraidCmd"; import { ViewAntiraidCmd } from "./commands/ViewAntiraidCmd"; import { runAutomodOnCounterTrigger } from "./events/runAutomodOnCounterTrigger"; -import { RunAutomodOnJoinEvt } from "./events/RunAutomodOnJoinEvt"; +import { RunAutomodOnJoinEvt, RunAutomodOnLeaveEvt } from "./events/RunAutomodOnJoinLeaveEvt"; import { RunAutomodOnMemberUpdate } from "./events/RunAutomodOnMemberUpdate"; import { runAutomodOnMessage } from "./events/runAutomodOnMessage"; import { runAutomodOnModAction } from "./events/runAutomodOnModAction"; @@ -176,6 +176,7 @@ export const AutomodPlugin = zeppelinGuildPlugin()({ events: [ RunAutomodOnJoinEvt, RunAutomodOnMemberUpdate, + RunAutomodOnLeaveEvt, // Messages use message events from SavedMessages, see onLoad below ], diff --git a/backend/src/plugins/Automod/constants.ts b/backend/src/plugins/Automod/constants.ts index d6f30b86..1f46f2e3 100644 --- a/backend/src/plugins/Automod/constants.ts +++ b/backend/src/plugins/Automod/constants.ts @@ -15,4 +15,5 @@ export enum RecentActionType { VoiceChannelMove, MemberJoin, Sticker, + MemberLeave, } diff --git a/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts b/backend/src/plugins/Automod/events/RunAutomodOnJoinLeaveEvt.ts similarity index 58% rename from backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts rename to backend/src/plugins/Automod/events/RunAutomodOnJoinLeaveEvt.ts index 17e98ba0..faaff383 100644 --- a/backend/src/plugins/Automod/events/RunAutomodOnJoinEvt.ts +++ b/backend/src/plugins/Automod/events/RunAutomodOnJoinLeaveEvt.ts @@ -25,3 +25,25 @@ export const RunAutomodOnJoinEvt = typedGuildEventListener()( }); }, }); + +export const RunAutomodOnLeaveEvt = typedGuildEventListener()({ + event: "guildMemberRemove", + listener({ pluginData, args: { member } }) { + const context: AutomodContext = { + timestamp: Date.now(), + partialMember: member, + joined: true, + }; + + pluginData.state.queue.add(() => { + pluginData.state.recentActions.push({ + type: RecentActionType.MemberLeave, + context, + count: 1, + identifier: null, + }); + + runAutomod(pluginData, context); + }); + }, +}); diff --git a/backend/src/plugins/Automod/triggers/availableTriggers.ts b/backend/src/plugins/Automod/triggers/availableTriggers.ts index dbd02cc8..e62e811d 100644 --- a/backend/src/plugins/Automod/triggers/availableTriggers.ts +++ b/backend/src/plugins/Automod/triggers/availableTriggers.ts @@ -17,6 +17,7 @@ import { MatchRegexTrigger } from "./matchRegex"; import { MatchWordsTrigger } from "./matchWords"; import { MemberJoinTrigger } from "./memberJoin"; import { MemberJoinSpamTrigger } from "./memberJoinSpam"; +import { MemberLeaveTrigger } from "./memberLeave"; import { MentionSpamTrigger } from "./mentionSpam"; import { MessageSpamTrigger } from "./messageSpam"; import { MuteTrigger } from "./mute"; @@ -72,6 +73,7 @@ export const AvailableTriggers = t.type({ match_links: MatchLinksTrigger.configType, match_attachment_type: MatchAttachmentTypeTrigger.configType, member_join: MemberJoinTrigger.configType, + member_leave: MemberLeaveTrigger.configType, role_added: RoleAddedTrigger.configType, role_removed: RoleRemovedTrigger.configType, diff --git a/backend/src/plugins/Automod/triggers/memberLeave.ts b/backend/src/plugins/Automod/triggers/memberLeave.ts new file mode 100644 index 00000000..9af9bc4f --- /dev/null +++ b/backend/src/plugins/Automod/triggers/memberLeave.ts @@ -0,0 +1,20 @@ +import * as t from "io-ts"; +import { automodTrigger } from "../helpers"; + +export const MemberLeaveTrigger = automodTrigger()({ + configType: t.type({}), + + defaultConfig: {}, + + async match({ pluginData, context, triggerConfig }) { + if (!context.joined || !context.member) { + return; + } + + return {}; + }, + + renderMatchInformation({ pluginData, contexts, triggerConfig }) { + return ""; + }, +}); diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 100899bd..3981860d 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -1,4 +1,4 @@ -import { GuildMember, User } from "discord.js"; +import { GuildMember, PartialGuildMember, User } from "discord.js"; import * as t from "io-ts"; import { BasePluginType, CooldownManager } from "knub"; import { SavedMessage } from "../../data/entities/SavedMessage"; @@ -115,6 +115,7 @@ export interface AutomodContext { user?: User; message?: SavedMessage; member?: GuildMember; + partialMember?: GuildMember | PartialGuildMember; joined?: boolean; rolesChanged?: { added?: string[]; From 6e22687bf64b6e9a63ae1756519ac2c208fb6677 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Mon, 21 Jun 2021 01:36:35 +0200 Subject: [PATCH 19/79] Switch pagination to buttons --- .../src/plugins/Mutes/commands/MutesCmd.ts | 88 ++++++++------ .../events/ButtonInteractionEvt.ts | 2 + backend/src/plugins/Utility/search.ts | 113 ++++++++++++------ backend/src/utils/waitForInteraction.ts | 10 -- 4 files changed, 131 insertions(+), 82 deletions(-) diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 10c2d2e3..47e4a4fd 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -1,4 +1,4 @@ -import { GuildMember } from "discord.js"; +import { GuildMember, MessageActionRow, MessageButton, MessageComponentInteraction } from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; @@ -27,10 +27,9 @@ export const MutesCmd = mutesCmd({ let totalMutes = 0; let hasFilters = false; - let hasReactions = false; - let clearReactionsFn; - let clearReactionsTimeout; - const clearReactionsDebounce = 5 * MINUTES; + let stopCollectionFn; + let stopCollectionTimeout; + const stopCollectionDebounce = 5 * MINUTES; let lines: string[] = []; @@ -167,13 +166,12 @@ export const MutesCmd = mutesCmd({ message += "\n\n" + pageLines.join("\n"); listMessage.edit(message); - bumpClearReactionsTimeout(); + bumpCollectionTimeout(); }; - const bumpClearReactionsTimeout = () => { - if (!hasReactions) return; - clearTimeout(clearReactionsTimeout); - clearReactionsTimeout = setTimeout(clearReactionsFn, clearReactionsDebounce); + const bumpCollectionTimeout = () => { + clearTimeout(stopCollectionTimeout); + stopCollectionTimeout = setTimeout(stopCollectionFn, stopCollectionDebounce); }; if (totalMutes === 0) { @@ -194,35 +192,55 @@ export const MutesCmd = mutesCmd({ drawListPage(1); if (totalPages > 1) { - hasReactions = true; - listMessage.react("⬅"); - listMessage.react("➡"); + const idMod = `${listMessage.id}:muteList`; + const buttons: MessageButton[] = []; - const paginationReactionListener = pluginData.events.on( - "messageReactionAdd", - async ({ args: { reaction, user } }) => { - const rMsg = reaction.message; - const member = await pluginData.guild.members.fetch(user.id); - if (!isFullMessage(rMsg)) return; - if (rMsg.id !== listMessage.id) return; - if (member.id !== msg.author.id) return; - if (!["⬅", "➡"].includes(reaction.emoji.name!)) return; - - if (reaction.emoji.name === "⬅" && currentPage > 1) { - drawListPage(currentPage - 1); - } else if (reaction.emoji.name === "➡" && currentPage < totalPages) { - drawListPage(currentPage + 1); - } - - reaction.remove().catch(noop); - }, + buttons.push( + new MessageButton() + .setStyle("SECONDARY") + .setEmoji("⬅") + .setType("BUTTON") + .setCustomID(`previousButton:${idMod}`), ); - clearReactionsFn = () => { - listMessage.reactions.removeAll().catch(noop); - pluginData.events.off("messageReactionAdd", paginationReactionListener); + buttons.push( + new MessageButton() + .setStyle("SECONDARY") + .setEmoji("➡") + .setType("BUTTON") + .setCustomID(`nextButton:${idMod}`), + ); + + const row = new MessageActionRow().addComponents(buttons); + await listMessage.edit({ components: [row] }); + + const filter = (iac: MessageComponentInteraction) => iac.message.id === listMessage.id; + const collector = listMessage.createMessageComponentInteractionCollector(filter, { + time: stopCollectionDebounce, + }); + + collector.on("collect", async (interaction: MessageComponentInteraction) => { + if (msg.author.id !== interaction.user.id) { + interaction.reply(`You are not permitted to use these buttons.`, { ephemeral: true }); + } else { + collector.resetTimer(); + if (interaction.customID === `previousButton:${idMod}` && currentPage > 1) { + await interaction.deferUpdate(); + await drawListPage(currentPage - 1); + } else if (interaction.customID === `nextButton:${idMod}` && currentPage < totalPages) { + await interaction.deferUpdate(); + await drawListPage(currentPage + 1); + } else { + await interaction.deferUpdate(); + } + } + }); + + stopCollectionFn = async () => { + collector.stop(); + await listMessage.edit({ content: listMessage.content, components: [] }); }; - bumpClearReactionsTimeout(); + bumpCollectionTimeout(); } } }, diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 6dd3f793..a5feb154 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -21,6 +21,8 @@ export const ButtonInteractionEvt = reactionRolesEvt({ ? (meta.args.interaction as MessageComponentInteraction) : null; if (!int) return; + const allOnMessage = await meta.pluginData.state.buttonRoles.getAllForMessageId(int.message.id); + if (allOnMessage.length === 0) return; const cfg = meta.pluginData.config.get(); const split = int.customID.split(BUTTON_CONTEXT_SEPARATOR); const context = (await resolveStatefulCustomId(meta.pluginData, int.customID)) ?? { diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 0a36ebd9..04289dac 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -1,11 +1,20 @@ -import { GuildMember, Message, Permissions, TextChannel, User } from "discord.js"; +import { + GuildMember, + Message, + MessageActionRow, + MessageButton, + MessageComponentInteraction, + Permissions, + TextChannel, + User, +} from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import { GuildPluginData } from "knub"; import { ArgsFromSignatureOrArray } from "knub/dist/commands/commandUtils"; import moment from "moment-timezone"; import { getBaseUrl, sendErrorMessage } from "../../pluginUtils"; import { allowTimeout, RegExpRunner } from "../../RegExpRunner"; -import { isFullMessage, MINUTES, multiSorter, noop, sorter, trimLines } from "../../utils"; +import { MINUTES, multiSorter, sorter, trimLines } from "../../utils"; import { asyncFilter } from "../../utils/async"; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; import { inputPatternToRegExp, InvalidRegexError } from "../../validatorUtils"; @@ -75,9 +84,8 @@ export async function displaySearch( let originalSearchMsg: Message; let searching = false; let currentPage = args.page || 1; - let hasReactions = false; - let clearReactionsFn: () => void; - let clearReactionsTimeout: Timeout; + let stopCollectionFn: () => void; + let stopCollectionTimeout: Timeout; const perPage = args.ids ? SEARCH_ID_RESULTS_PER_PAGE : SEARCH_RESULTS_PER_PAGE; @@ -155,47 +163,78 @@ export async function displaySearch( } } - searchMsg.edit(result); + currentPage = searchResult.page; // Set up pagination reactions if needed. The reactions are cleared after a timeout. if (searchResult.totalResults > perPage) { - if (!hasReactions) { - hasReactions = true; - searchMsg.react("⬅"); - searchMsg.react("➡"); - searchMsg.react("🔄"); + const idMod = `${searchMsg.id}:${moment.utc().valueOf()}`; + const buttons: MessageButton[] = []; - const listenerFn = pluginData.events.on("messageReactionAdd", async ({ args: { reaction, user } }) => { - const rMsg = reaction.message; - const member = await pluginData.guild.members.fetch(user.id); - if (rMsg.id !== searchMsg.id) return; - if (member.user.id !== msg.author.id) return; - if (!["⬅", "➡", "🔄"].includes(reaction.emoji.name!)) return; + buttons.push( + new MessageButton() + .setStyle("SECONDARY") + .setEmoji("⬅") + .setType("BUTTON") + .setCustomID(`previousButton:${idMod}`) + .setDisabled(currentPage === 1), + ); - if (reaction.emoji.name === "⬅" && currentPage > 1) { - loadSearchPage(currentPage - 1); - } else if (reaction.emoji.name === "➡" && currentPage < searchResult.lastPage) { - loadSearchPage(currentPage + 1); - } else if (reaction.emoji.name === "🔄") { - loadSearchPage(currentPage); + buttons.push( + new MessageButton() + .setStyle("SECONDARY") + .setEmoji("➡") + .setType("BUTTON") + .setCustomID(`nextButton:${idMod}`) + .setDisabled(currentPage === searchResult.lastPage), + ); + + buttons.push( + new MessageButton() + .setStyle("SECONDARY") + .setEmoji("🔄") + .setType("BUTTON") + .setCustomID(`reloadButton:${idMod}`), + ); + + const row = new MessageActionRow().addComponents(buttons); + await searchMsg.edit({ content: result, components: [row] }); + + const filter = (iac: MessageComponentInteraction) => iac.message.id === searchMsg.id; + const collector = searchMsg.createMessageComponentInteractionCollector(filter, { time: 2 * MINUTES }); + + collector.on("collect", async (interaction: MessageComponentInteraction) => { + if (msg.author.id !== interaction.user.id) { + interaction.reply(`You are not permitted to use these buttons.`, { ephemeral: true }); + } else { + if (interaction.customID === `previousButton:${idMod}` && currentPage > 1) { + collector.stop(); + await interaction.deferUpdate(); + await loadSearchPage(currentPage - 1); + } else if (interaction.customID === `nextButton:${idMod}` && currentPage < searchResult.lastPage) { + collector.stop(); + await interaction.deferUpdate(); + await loadSearchPage(currentPage + 1); + } else if (interaction.customID === `reloadButton:${idMod}`) { + collector.stop(); + await interaction.deferUpdate(); + await loadSearchPage(currentPage); + } else { + await interaction.deferUpdate(); } + } + }); - if (isFullMessage(rMsg)) { - reaction.remove(); - } - }); + stopCollectionFn = async () => { + collector.stop(); + await searchMsg.edit({ content: searchMsg.content, components: [] }); + }; - clearReactionsFn = async () => { - searchMsg.reactions.removeAll().catch(noop); - pluginData.events.off("messageReactionAdd", listenerFn); - }; - } - - clearTimeout(clearReactionsTimeout); - clearReactionsTimeout = setTimeout(clearReactionsFn, 5 * MINUTES); + clearTimeout(stopCollectionTimeout); + stopCollectionTimeout = setTimeout(stopCollectionFn, 2 * MINUTES); + } else { + searchMsg.edit(result); } - currentPage = searchResult.page; searching = false; }; @@ -370,7 +409,7 @@ async function performMemberSearch( } else { matchingMembers.sort( multiSorter([ - [m => m.username.toLowerCase(), realSortDir], + [m => m.user.username.toLowerCase(), realSortDir], [m => m.discriminator, realSortDir], ]), ); diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 497c882d..dd36f3fd 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -1,17 +1,7 @@ import { MessageActionRow, MessageButton, MessageComponentInteraction, MessageOptions, TextChannel } from "discord.js"; -import { PluginError } from "knub"; import { noop } from "knub/dist/utils"; import moment from "moment"; -export async function waitForComponent( - channel: TextChannel, - toPost: MessageOptions, - components: MessageActionRow[], - options?: WaitForOptions, -) { - throw new PluginError("Unimplemented method waitForComponent called."); -} - export async function waitForButtonConfirm( channel: TextChannel, toPost: MessageOptions, From 7bf5e1f3c6ed87182cb82adbab2fd7a573fc69ef Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Mon, 21 Jun 2021 01:36:53 +0200 Subject: [PATCH 20/79] misc. bugfixes --- backend/src/plugins/Utility/commands/InfoCmd.ts | 13 ++++++++++--- backend/src/utils.ts | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index e2e033c2..f69aaa4b 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -1,7 +1,14 @@ import { getChannelId, getRoleId } from "knub/dist/utils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; -import { customEmojiRegex, isValidSnowflake, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils"; +import { + customEmojiRegex, + isValidSnowflake, + noop, + parseInviteCodeInput, + resolveInvite, + resolveUser, +} from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; import { resolveMessageTarget } from "../../../utils/resolveMessageTarget"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; @@ -50,7 +57,7 @@ export const InfoCmd = utilityCmd({ // 2. Server if (userCfg.can_server) { - const guild = pluginData.client.guilds.fetch(value); + const guild = await pluginData.client.guilds.fetch(value).catch(noop); if (guild) { const embed = await getServerInfoEmbed(pluginData, value, message.author.id); if (embed) { @@ -108,7 +115,7 @@ export const InfoCmd = utilityCmd({ // 6. Server again (fallback for discovery servers) if (userCfg.can_server) { - const serverPreview = getGuildPreview(pluginData.client, value).catch(() => null); + const serverPreview = await getGuildPreview(pluginData.client, value).catch(() => null); if (serverPreview) { const embed = await getServerInfoEmbed(pluginData, value, message.author.id); if (embed) { diff --git a/backend/src/utils.ts b/backend/src/utils.ts index edfe1ad2..f72eebe9 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1258,7 +1258,7 @@ export async function resolveInvite( } // @ts-ignore: the getInvite() withCounts typings are blergh - const promise = client.getInvite(code, withCounts).catch(() => null); + const promise = client.fetchInvite(code).catch(() => null); inviteCache.set(key, promise); return promise as ResolveInviteReturnType; From 653d6c1dc20e9aa000ab539e1a552b7ec0619188 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 22 Jun 2021 02:49:31 +0200 Subject: [PATCH 21/79] Button role improvements, proper validation --- .../ReactionRoles/ReactionRolesPlugin.ts | 58 ++++++++++++++++++- .../commands/PostButtonRolesCmd.ts | 16 +++-- backend/src/plugins/ReactionRoles/types.ts | 20 ++++++- .../util/buttonActionHandlers.ts | 50 ++++++++++++---- .../util/splitButtonsIntoRows.ts | 41 +++++++++++++ 5 files changed, 166 insertions(+), 19 deletions(-) create mode 100644 backend/src/plugins/ReactionRoles/util/splitButtonsIntoRows.ts diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index d0452703..47aa4c64 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -1,5 +1,8 @@ import { PluginOptions } from "knub"; -import { GuildButtonRoles } from "src/data/GuildButtonRoles"; +import { ConfigPreprocessorFn } from "knub/dist/config/configTypes"; +import { GuildButtonRoles } from "../../data/GuildButtonRoles"; +import { isValidSnowflake } from "../../utils"; +import { StrictValidationError } from "../../validatorUtils"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; @@ -14,6 +17,7 @@ import { ButtonInteractionEvt } from "./events/ButtonInteractionEvt"; import { MessageDeletedEvt } from "./events/MessageDeletedEvt"; import { ConfigSchema, ReactionRolesPluginType } from "./types"; import { autoRefreshLoop } from "./util/autoRefreshLoop"; +import { getRowCount } from "./util/splitButtonsIntoRows"; const MIN_AUTO_REFRESH = 1000 * 60 * 15; // 15min minimum, let's not abuse the API @@ -36,6 +40,57 @@ const defaultOptions: PluginOptions = { ], }; +const MAXIMUM_COMPONENT_ROWS = 5; + +const configPreprocessor: ConfigPreprocessorFn = options => { + if (options.config.button_groups) { + for (const [groupName, group] of Object.entries(options.config.button_groups)) { + const defaultButtonNames = Object.keys(group.default_buttons); + const defaultButtons = Object.values(group.default_buttons); + const menuNames = Object.keys(group.button_menus ?? []); + + const defaultBtnRowCount = getRowCount(defaultButtons); + if (defaultBtnRowCount > MAXIMUM_COMPONENT_ROWS || defaultBtnRowCount === 0) { + throw new StrictValidationError([ + `Invalid row count for default_buttons: You currently have ${defaultBtnRowCount}, the maximum is 5. A new row is started automatically each 5 consecutive buttons.`, + ]); + } + + for (let i = 0; i < defaultButtons.length; i++) { + const defBtn = defaultButtons[i]; + if (!menuNames.includes(defBtn.role_or_menu) && !isValidSnowflake(defBtn.role_or_menu)) { + throw new StrictValidationError([ + `Invalid value for default_buttons/${defaultButtonNames[i]}/role_or_menu: ${defBtn.role_or_menu} is neither an existing menu nor a valid snowflake.`, + ]); + } + } + + for (const [menuName, menuButtonEntries] of Object.entries(group.button_menus ?? [])) { + const menuButtonNames = Object.keys(menuButtonEntries); + const menuButtons = Object.values(menuButtonEntries); + + const menuButtonRowCount = getRowCount(menuButtons); + if (menuButtonRowCount > MAXIMUM_COMPONENT_ROWS || menuButtonRowCount === 0) { + throw new StrictValidationError([ + `Invalid row count for button_menus/${menuName}: You currently have ${menuButtonRowCount}, the maximum is 5. A new row is started automatically each 5 consecutive buttons.`, + ]); + } + + for (let i = 0; i < menuButtons.length; i++) { + const menuBtn = menuButtons[i]; + if (!menuNames.includes(menuBtn.role_or_menu) && !isValidSnowflake(menuBtn.role_or_menu)) { + throw new StrictValidationError([ + `Invalid value for button_menus/${menuButtonNames[i]}/role_or_menu: ${menuBtn.role_or_menu} is neither an existing menu nor a valid snowflake.`, + ]); + } + } + } + } + } + + return options; +}; + export const ReactionRolesPlugin = zeppelinGuildPlugin()({ name: "reaction_roles", showInDocs: true, @@ -61,6 +116,7 @@ export const ReactionRolesPlugin = zeppelinGuildPlugin( ButtonInteractionEvt, MessageDeletedEvt, ], + configPreprocessor, beforeLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index 3b162fa3..5f602921 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -4,6 +4,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { reactionRolesCmd } from "../types"; import { createHash } from "crypto"; import moment from "moment"; +import { splitButtonsIntoRows } from "../util/splitButtonsIntoRows"; export const PostButtonRolesCmd = reactionRolesCmd({ trigger: "reaction_roles post", @@ -16,6 +17,10 @@ export const PostButtonRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { const cfg = pluginData.config.get(); + if (!cfg.button_groups) { + sendErrorMessage(pluginData, msg.channel, "No button groups defined in config"); + return; + } const group = cfg.button_groups[args.buttonGroup]; if (!group) { @@ -31,10 +36,11 @@ export const PostButtonRolesCmd = reactionRolesCmd({ .digest("hex"); const btn = new MessageButton() - .setLabel(button.label) - .setStyle("PRIMARY") + .setLabel(button.label ?? "") + .setStyle(button.style ?? "PRIMARY") .setType("BUTTON") - .setCustomID(customId); + .setCustomID(customId) + .setDisabled(button.disabled ?? false); if (button.emoji) { const emo = pluginData.client.emojis.resolve(button.emoji) ?? button.emoji; @@ -44,10 +50,10 @@ export const PostButtonRolesCmd = reactionRolesCmd({ buttons.push(btn); toInsert.push({ customId, buttonGroup: args.buttonGroup, buttonName }); } - const row = new MessageActionRow().addComponents(buttons); + const rows = splitButtonsIntoRows(buttons, Object.values(group.default_buttons)); // new MessageActionRow().addComponents(buttons); try { - const newMsg = await args.channel.send({ content: group.message, components: [row], split: false }); + const newMsg = await args.channel.send({ content: group.message, components: rows, split: false }); for (const btn of toInsert) { await pluginData.state.buttonRoles.add( diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index 940af482..203a4327 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -1,21 +1,35 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; import { GuildButtonRoles } from "src/data/GuildButtonRoles"; +import { tNullable } from "../../utils"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; +// These need to be updated every time discord adds/removes a style, +// but i cant figure out how to import MessageButtonStyles at runtime +enum ButtonStyles { + PRIMARY = 1, + SECONDARY = 2, + SUCCESS = 3, + DANGER = 4, + // LINK = 5, We do not want users to create link buttons, but it would be style 5 +} + const ButtonOpts = t.type({ - label: t.string, - emoji: t.string, + label: tNullable(t.string), + emoji: tNullable(t.string), role_or_menu: t.string, + style: tNullable(t.keyof(ButtonStyles)), // https://discord.js.org/#/docs/main/master/typedef/MessageButtonStyle + disabled: tNullable(t.boolean), + end_row: tNullable(t.boolean), }); export type TButtonOpts = t.TypeOf; const ButtonPairOpts = t.type({ message: t.string, default_buttons: t.record(t.string, ButtonOpts), - button_menus: t.record(t.string, t.record(t.string, ButtonOpts)), + button_menus: tNullable(t.record(t.string, t.record(t.string, ButtonOpts))), }); export type TButtonPairOpts = t.TypeOf; diff --git a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts index 8a098476..c59ae400 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts @@ -4,6 +4,7 @@ import { LogType } from "../../../data/LogType"; import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; import { ReactionRolesPluginType, TButtonPairOpts } from "../types"; import { generateStatelessCustomId } from "./buttonCustomIdFunctions"; +import { splitButtonsIntoRows } from "./splitButtonsIntoRows"; export async function handleOpenMenu( pluginData: GuildPluginData, @@ -12,14 +13,29 @@ export async function handleOpenMenu( context, ) { const menuButtons: MessageButton[] = []; + if (group.button_menus == null) { + await int.reply({ + content: `A configuration error was encountered, please contact the Administrators!`, + ephemeral: true, + }); + pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A configuration error occured** on buttons for message ${int.message.id}, no menus found in config`, + ); + return; + } + for (const menuButton of Object.values(group.button_menus[context.roleOrMenu])) { const customId = await generateStatelessCustomId(pluginData, context.groupName, menuButton.role_or_menu); const btn = new MessageButton() - .setLabel(menuButton.label) + .setLabel(menuButton.label ?? "") .setStyle("PRIMARY") .setType("BUTTON") - .setCustomID(customId); + .setCustomID(customId) + .setDisabled(menuButton.disabled ?? false); if (menuButton.emoji) { const emo = pluginData.client.emojis.resolve(menuButton.emoji) ?? menuButton.emoji; @@ -41,9 +57,9 @@ export async function handleOpenMenu( ); return; } - const row = new MessageActionRow().addComponents(menuButtons); + const rows = splitButtonsIntoRows(menuButtons, Object.values(group.button_menus[context.roleOrMenu])); // new MessageActionRow().addComponents(menuButtons); - int.reply({ content: `Click to add/remove a role`, components: [row], ephemeral: true }); + int.reply({ content: `Click to add/remove a role`, components: rows, ephemeral: true }); return; } @@ -69,12 +85,26 @@ export async function handleModifyRole( } const member = await pluginData.guild.members.fetch(int.user.id); - if (member.roles.cache.has(role.id)) { - await member.roles.remove(role, `Button Roles on message ${int.message.id}`); - await int.reply({ content: `Role **${role.name}** removed`, ephemeral: true }); - } else { - await member.roles.add(role, `Button Roles on message ${int.message.id}`); - await int.reply({ content: `Role **${role.name}** added`, ephemeral: true }); + try { + if (member.roles.cache.has(role.id)) { + await member.roles.remove(role, `Button Roles on message ${int.message.id}`); + await int.reply({ content: `Role **${role.name}** removed`, ephemeral: true }); + } else { + await member.roles.add(role, `Button Roles on message ${int.message.id}`); + await int.reply({ content: `Role **${role.name}** added`, ephemeral: true }); + } + } catch (e) { + await int.reply({ + content: "A configuration error was encountered, please contact the Administrators!", + ephemeral: true, + }); + pluginData + .getPlugin(LogsPlugin) + .log( + LogType.BOT_ALERT, + `**A configuration error occured** on buttons for message ${int.message.id}, error: ${e}. We might be missing permissions!`, + ); + return; } return; diff --git a/backend/src/plugins/ReactionRoles/util/splitButtonsIntoRows.ts b/backend/src/plugins/ReactionRoles/util/splitButtonsIntoRows.ts new file mode 100644 index 00000000..d357b7e1 --- /dev/null +++ b/backend/src/plugins/ReactionRoles/util/splitButtonsIntoRows.ts @@ -0,0 +1,41 @@ +import { MessageActionRow, MessageButton } from "discord.js"; +import { TButtonOpts } from "../types"; + +export function splitButtonsIntoRows(actualButtons: MessageButton[], configButtons: TButtonOpts[]): MessageActionRow[] { + const rows: MessageActionRow[] = []; + let curRow = new MessageActionRow(); + let consecutive = 0; + + for (let i = 0; i < actualButtons.length; i++) { + const aBtn = actualButtons[i]; + const cBtn = configButtons[i]; + + curRow.addComponents(aBtn); + if (((consecutive + 1) % 5 === 0 || cBtn.end_row) && i + 1 < actualButtons.length) { + rows.push(curRow); + curRow = new MessageActionRow(); + consecutive = 0; + } else { + consecutive++; + } + } + + return rows; +} + +export function getRowCount(configButtons: TButtonOpts[]): number { + let count = 1; + let consecutive = 0; + for (let i = 0; i < configButtons.length; i++) { + const cBtn = configButtons[i]; + + if (((consecutive + 1) % 5 === 0 || cBtn.end_row) && i + 1 < configButtons.length) { + count++; + consecutive = 0; + } else { + consecutive++; + } + } + + return count; +} From 0822fc15e55abaf8b6ae8032cd56b5349133e1be Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 30 Jun 2021 04:56:56 +0200 Subject: [PATCH 22/79] Type fixes for djs --- backend/package-lock.json | 6509 ++++++++++++++++- backend/package.json | 8 +- backend/src/data/GuildArchives.ts | 4 +- backend/src/pluginUtils.ts | 4 +- .../plugins/AutoDelete/util/deleteNextItem.ts | 6 +- .../src/plugins/Automod/actions/addRoles.ts | 6 +- backend/src/plugins/Automod/actions/alert.ts | 4 +- backend/src/plugins/Automod/actions/clean.ts | 6 +- .../plugins/Automod/actions/removeRoles.ts | 6 +- backend/src/plugins/Automod/actions/reply.ts | 7 +- .../plugins/Automod/actions/setSlowmode.ts | 4 +- .../Automod/events/runAutomodOnMessage.ts | 5 +- .../functions/getTextMatchPartialSummary.ts | 7 +- .../functions/resolveActionContactMethods.ts | 4 +- .../plugins/Automod/functions/runAutomod.ts | 8 +- .../plugins/Automod/triggers/anyMessage.ts | 3 +- .../Automod/triggers/matchAttachmentType.ts | 3 +- .../src/plugins/Automod/triggers/roleAdded.ts | 3 +- .../plugins/Automod/triggers/roleRemoved.ts | 3 +- .../plugins/BotControl/BotControlPlugin.ts | 6 +- .../plugins/BotControl/commands/ServersCmd.ts | 6 +- .../plugins/Cases/functions/getCaseEmbed.ts | 2 +- .../Cases/functions/postToCaseLogChannel.ts | 10 +- .../src/plugins/Censor/util/censorMessage.ts | 8 +- .../commands/ArchiveChannelCmd.ts | 16 +- .../ChannelArchiver/rehostAttachment.ts | 2 +- .../functions/handleCompanionPermissions.ts | 10 +- .../Counters/commands/AddCounterCmd.ts | 4 +- .../commands/ResetAllCounterValuesCmd.ts | 8 +- .../Counters/commands/ResetCounterCmd.ts | 4 +- .../Counters/commands/SetCounterCmd.ts | 4 +- .../Counters/commands/ViewCounterCmd.ts | 4 +- .../actions/makeRoleMentionableAction.ts | 3 +- .../actions/makeRoleUnmentionableAction.ts | 3 +- .../CustomEvents/actions/messageAction.ts | 4 +- .../actions/moveToVoiceChannelAction.ts | 4 +- .../actions/setChannelPermissionOverrides.ts | 3 +- .../LocateUser/events/SendAlertsEvts.ts | 4 +- .../plugins/LocateUser/utils/moveMember.ts | 4 +- .../plugins/LocateUser/utils/sendAlerts.ts | 4 +- .../src/plugins/LocateUser/utils/sendWhere.ts | 1 - backend/src/plugins/Logs/util/log.ts | 6 +- .../src/plugins/Logs/util/onMessageDelete.ts | 4 +- .../plugins/Logs/util/onMessageDeleteBulk.ts | 3 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 4 +- .../plugins/MessageSaver/saveMessagesToDB.ts | 4 +- .../ModActions/commands/CasesModCmd.ts | 2 +- .../ModActions/commands/CasesUserCmd.ts | 16 +- .../ModActions/commands/DeleteCaseCmd.ts | 4 +- .../ModActions/commands/ForcebanCmd.ts | 3 +- .../plugins/ModActions/commands/UnbanCmd.ts | 3 +- .../events/PostAlertOnMemberJoinEvt.ts | 4 +- .../plugins/ModActions/functions/banUserId.ts | 4 +- .../functions/getDefaultContactMethods.ts | 4 +- .../plugins/ModActions/functions/isBanned.ts | 4 +- .../functions/outdatedTempbansLoop.ts | 6 +- .../ModActions/functions/warnMember.ts | 4 +- backend/src/plugins/Mutes/MutesPlugin.ts | 4 +- .../Mutes/commands/ClearBannedMutesCmd.ts | 4 +- .../commands/ClearMutesWithoutRoleCmd.ts | 3 +- .../src/plugins/Mutes/commands/MutesCmd.ts | 19 +- .../Mutes/functions/clearExpiredMutes.ts | 3 +- .../Mutes/functions/memberHasMutedRole.ts | 4 +- .../src/plugins/Mutes/functions/muteUser.ts | 9 +- .../src/plugins/Mutes/functions/unmuteUser.ts | 7 +- .../utils/disablePingableRoles.ts | 3 +- .../utils/enablePingableRoles.ts | 3 +- backend/src/plugins/Post/commands/EditCmd.ts | 11 +- .../src/plugins/Post/commands/EditEmbedCmd.ts | 11 +- backend/src/plugins/Post/util/postMessage.ts | 2 +- .../plugins/Post/util/scheduledPostLoop.ts | 6 +- .../commands/ClearReactionRolesCmd.ts | 4 +- .../commands/InitReactionRolesCmd.ts | 5 +- .../commands/PostButtonRolesCmd.ts | 5 +- .../events/ButtonInteractionEvt.ts | 2 +- .../util/addMemberPendingRoleChange.ts | 5 +- .../applyReactionRoleReactionsToMessage.ts | 6 +- .../util/buttonActionHandlers.ts | 5 +- .../util/buttonCustomIdFunctions.ts | 3 +- .../Reminders/utils/postDueRemindersLoop.ts | 8 +- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 10 +- .../commands/RoleHelpCmd.ts | 2 +- .../commands/RoleRemoveCmd.ts | 5 +- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 6 +- .../util/clearBotSlowmodeFromUserId.ts | 4 +- .../Slowmode/util/clearExpiredSlowmodes.ts | 7 +- .../plugins/Slowmode/util/onMessageCreate.ts | 6 +- .../Spam/util/logAndDetectMessageSpam.ts | 8 +- backend/src/plugins/Spam/util/logCensor.ts | 3 +- .../src/plugins/Spam/util/onMessageCreate.ts | 3 +- .../Starboard/commands/MigratePinsCmd.ts | 4 +- .../events/StarboardReactionAddEvt.ts | 10 +- .../Starboard/util/saveMessageToStarboard.ts | 6 +- .../util/updateStarboardMessageStarCount.ts | 2 +- backend/src/plugins/Tags/TagsPlugin.ts | 8 +- .../src/plugins/Tags/util/onMessageCreate.ts | 8 +- .../src/plugins/Tags/util/onMessageDelete.ts | 10 +- .../src/plugins/Utility/commands/AvatarCmd.ts | 2 +- .../plugins/Utility/commands/BanSearchCmd.ts | 6 +- .../Utility/commands/ChannelInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/CleanCmd.ts | 12 +- .../plugins/Utility/commands/EmojiInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/InfoCmd.ts | 25 +- .../plugins/Utility/commands/InviteInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/JumboCmd.ts | 2 +- .../Utility/commands/MessageInfoCmd.ts | 2 +- .../plugins/Utility/commands/RoleInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/SearchCmd.ts | 12 +- .../plugins/Utility/commands/ServerInfoCmd.ts | 2 +- .../Utility/commands/SnowflakeInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/SourceCmd.ts | 3 +- .../plugins/Utility/commands/UserInfoCmd.ts | 4 +- .../Utility/functions/getChannelInfoEmbed.ts | 4 +- .../Utility/functions/getGuildPreview.ts | 8 +- .../Utility/functions/getMessageInfoEmbed.ts | 6 +- .../Utility/functions/getServerInfoEmbed.ts | 6 +- backend/src/plugins/Utility/search.ts | 9 +- .../events/SendWelcomeMessageEvt.ts | 4 +- backend/src/utils.ts | 20 +- backend/src/utils/canAssignRole.ts | 4 +- backend/src/utils/createPaginatedMessage.ts | 2 +- .../erisAllowedMentionsToDjsMentionOptions.ts | 10 +- backend/src/utils/getMissingPermissions.ts | 8 +- backend/src/utils/hasDiscordPermissions.ts | 8 +- backend/src/utils/messageHasContent.ts | 8 +- backend/src/utils/resolveMessageTarget.ts | 4 +- backend/src/utils/sendDM.ts | 4 +- backend/src/utils/waitForInteraction.ts | 8 +- package-lock.json | 2071 +++++- package.json | 1 - 130 files changed, 8877 insertions(+), 411 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index ca572ce5..4809cb21 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,8 +1,6361 @@ { "name": "@zeppelin/backend", "version": "0.0.1", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@zeppelin/backend", + "version": "0.0.1", + "dependencies": { + "@types/sharp": "^0.23.1", + "@types/twemoji": "^12.1.0", + "bufferutil": "^4.0.3", + "cors": "^2.8.5", + "cross-env": "^5.2.0", + "deep-diff": "^1.0.2", + "discord.js": "^13.0.0-dev.edab5af.1624996138", + "dotenv": "^4.0.0", + "emoji-regex": "^8.0.0", + "erlpack": "github:discord/erlpack", + "escape-string-regexp": "^1.0.5", + "express": "^4.17.0", + "fp-ts": "^2.0.1", + "humanize-duration": "^3.15.0", + "io-ts": "^2.0.0", + "js-yaml": "^3.13.1", + "knub": "file:../../Knub", + "knub-command-manager": "^9.1.0", + "last-commit-log": "^2.1.0", + "lodash.chunk": "^4.2.0", + "lodash.clonedeep": "^4.5.0", + "lodash.difference": "^4.5.0", + "lodash.intersection": "^4.4.0", + "lodash.isequal": "^4.5.0", + "lodash.pick": "^4.4.0", + "moment-timezone": "^0.5.21", + "mysql": "^2.16.0", + "parse-color": "^1.0.0", + "passport": "^0.4.0", + "passport-custom": "^1.0.5", + "passport-oauth2": "^1.5.0", + "pkg-up": "^3.1.0", + "reflect-metadata": "^0.1.12", + "regexp-worker": "^1.1.0", + "safe-regex": "^2.0.2", + "seedrandom": "^3.0.1", + "sharp": "^0.23.4", + "strip-combining-marks": "^1.0.0", + "tlds": "^1.203.1", + "tmp": "0.0.33", + "tsconfig-paths": "^3.9.0", + "twemoji": "^12.1.4", + "typeorm": "^0.2.31", + "utf-8-validate": "^5.0.5", + "uuid": "^3.3.2", + "yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build", + "zlib-sync": "^0.1.7" + }, + "devDependencies": { + "@types/cors": "^2.8.5", + "@types/express": "^4.16.1", + "@types/jest": "^24.0.15", + "@types/js-yaml": "^3.12.1", + "@types/lodash.at": "^4.6.3", + "@types/moment-timezone": "^0.5.6", + "@types/node": "^14.0.14", + "@types/passport": "^1.0.0", + "@types/passport-oauth2": "^1.4.8", + "@types/passport-strategy": "^0.2.35", + "@types/safe-regex": "^1.1.2", + "@types/tmp": "0.0.33", + "ava": "^3.10.0", + "rimraf": "^2.6.2", + "source-map-support": "^0.5.16", + "tsc-watch": "^4.0.0", + "typescript": "^4.4.0-dev.20210629" + } + }, + "../../Knub": { + "name": "knub", + "version": "30.0.0-beta.38", + "license": "MIT", + "dependencies": { + "@discordjs/voice": "^0.5.1", + "discord-api-types": "^0.18.1", + "discord.js": "^13.0.0-dev.edab5af.1624996138", + "knub-command-manager": "^9.1.0", + "ts-essentials": "^6.0.7" + }, + "devDependencies": { + "@types/chai": "^4.2.18", + "@types/mocha": "^7.0.2", + "@types/node": "^14.14.45", + "@typescript-eslint/eslint-plugin": "^4.23.0", + "@typescript-eslint/parser": "^4.23.0", + "chai": "^4.3.4", + "eslint": "^7.2.0", + "husky": "^4.3.8", + "lint-staged": "^10.5.4", + "mocha": "^8.4.0", + "prettier": "^2.3.0", + "shx": "^0.3.3", + "ts-node": "^8.10.2", + "typescript": "^4.2.4" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.4.tgz", + "integrity": "sha512-BFlgP2SoLO9HJX9WBwN67gHWMBhDX/eDz64Jajd6mR/UAUzqrNMm99d4qHnVaKscAElZoFiPv+JpR/Siud5lXw==", + "dev": true, + "dependencies": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/@concordance/react": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", + "integrity": "sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1" + }, + "engines": { + "node": ">=6.12.3 <7 || >=8.9.4 <9 || >=10.0.0" + } + }, + "node_modules/@concordance/react/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@discordjs/collection": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", + "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" + }, + "node_modules/@discordjs/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sapphire/async-queue": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.4.tgz", + "integrity": "sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA==", + "engines": { + "node": ">=14", + "npm": ">=6" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sqltools/formatter": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.2.tgz", + "integrity": "sha512-/5O7Fq6Vnv8L6ucmPjaWbVG1XkP4FO+w5glqfkIsq3Xw4oyNAdJddbnYodNDAfjVUvo/rrSCTom4kAND7T1o5Q==" + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/body-parser": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", + "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "node_modules/@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-invOmosX0DqbpA+cE2yoHGUlF/blyf7nB0OGYBBiH27crcVm5NmFaZkLP4Ta1hGaesckCi5lVLlydNJCxkTOSg==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz", + "integrity": "sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.16.11", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.11.tgz", + "integrity": "sha512-K8d2M5t3tBQimkyaYTXxtHYyoJPUEhy2/omVRnTAKw5FEdT+Ft6lTaTOpoJdHeG+mIwQXXtqiTcYZ6IR8LTzjQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/jest": { + "version": "24.0.21", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.21.tgz", + "integrity": "sha512-uyqFvx78Tuy0h5iLCPWRCvi5HhWwEqhIj30doitp191oYLqlCxUyAJHdWVm5+Nr271/vPnkyt6rWeEIjGowBTg==", + "dev": true, + "dependencies": { + "@types/jest-diff": "*" + } + }, + "node_modules/@types/jest-diff": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", + "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", + "dev": true + }, + "node_modules/@types/js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" + }, + "node_modules/@types/lodash": { + "version": "4.14.144", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.144.tgz", + "integrity": "sha512-ogI4g9W5qIQQUhXAclq6zhqgqNUr7UlFaqDHbch7WLSLeeM/7d3CRaw7GLajxvyFvhJqw4Rpcz5bhoaYtIx6Tg==", + "dev": true + }, + "node_modules/@types/lodash.at": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.at/-/lodash.at-4.6.6.tgz", + "integrity": "sha512-OAfIqBWv0HjWVxKF8y6ZFTEwLM1wgpvsrMOb/fEKp8/HM2JO2V555Au5JZkiTnXOF453rqCooGKYFzNrR/kaAA==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/mime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/moment-timezone": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/@types/moment-timezone/-/moment-timezone-0.5.12.tgz", + "integrity": "sha512-hnHH2+Efg2vExr/dSz+IX860nSiyk9Sk4pJF2EmS11lRpMcNXeB4KBW5xcgw2QPsb9amTXdsVNEe5IoJXiT0uw==", + "dev": true, + "dependencies": { + "moment": ">=2.14.0" + } + }, + "node_modules/@types/node": { + "version": "14.0.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.14.tgz", + "integrity": "sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/oauth": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz", + "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/passport": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.1.tgz", + "integrity": "sha512-oK87JjN8i8kmqb0RN0sCUB/ZjrWf3b8U45eAzZVy1ssYYgBrMOuALmvoqp7MglsilXAjxum+LS29VQqeQx6ddA==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/passport-oauth2": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.8.tgz", + "integrity": "sha512-tlX16wyFE5YJR2pHpZ308dgB1MV9/Ra2wfQh71eWk+/umPoD1Rca2D4N5M27W7nZm1wqUNGTk1I864nHvEgiFA==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/oauth": "*", + "@types/passport": "*" + } + }, + "node_modules/@types/passport-strategy": { + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz", + "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==", + "dev": true, + "dependencies": { + "@types/express": "*", + "@types/passport": "*" + } + }, + "node_modules/@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "node_modules/@types/safe-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/safe-regex/-/safe-regex-1.1.2.tgz", + "integrity": "sha512-wuS9LVpgIiTYaGKd+s6Dj0kRXBkttaXjVxzaXmviCACi8RO+INPayND+VNjAcall/l1Jkyhh9lyPfKW/aP/Yug==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", + "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, + "node_modules/@types/sharp": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz", + "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0=", + "dev": true + }, + "node_modules/@types/twemoji": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.0.tgz", + "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==" + }, + "node_modules/@types/ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "dependencies": { + "string-width": "^3.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "node_modules/anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrgv": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", + "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/ava": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-3.10.0.tgz", + "integrity": "sha512-CxcYQYeE39pcLWrN2/TASMpnqH/SoaX+W61+4m3saETU041PIDcoP9LLNWPAE/yJZXjp0M1RWTohSkmGqJZKww==", + "dev": true, + "dependencies": { + "@concordance/react": "^2.0.0", + "acorn": "^7.3.1", + "acorn-walk": "^7.2.0", + "ansi-styles": "^4.2.1", + "arrgv": "^1.0.2", + "arrify": "^2.0.1", + "callsites": "^3.1.0", + "chalk": "^4.1.0", + "chokidar": "^3.4.0", + "chunkd": "^2.0.1", + "ci-info": "^2.0.0", + "ci-parallel-vars": "^1.0.1", + "clean-yaml-object": "^0.1.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "common-path-prefix": "^3.0.0", + "concordance": "^5.0.0", + "convert-source-map": "^1.7.0", + "currently-unhandled": "^0.4.1", + "debug": "^4.1.1", + "del": "^5.1.0", + "emittery": "^0.7.0", + "equal-length": "^1.0.0", + "figures": "^3.2.0", + "globby": "^11.0.1", + "ignore-by-default": "^2.0.0", + "import-local": "^3.0.2", + "indent-string": "^4.0.0", + "is-error": "^2.2.2", + "is-plain-object": "^3.0.1", + "is-promise": "^4.0.0", + "lodash": "^4.17.15", + "matcher": "^3.0.0", + "md5-hex": "^3.0.1", + "mem": "^6.1.0", + "ms": "^2.1.2", + "ora": "^4.0.4", + "p-map": "^4.0.0", + "picomatch": "^2.2.2", + "pkg-conf": "^3.1.0", + "plur": "^4.0.0", + "pretty-ms": "^7.0.0", + "read-pkg": "^5.2.0", + "resolve-cwd": "^3.0.0", + "slash": "^3.0.0", + "source-map-support": "^0.5.19", + "stack-utils": "^2.0.2", + "strip-ansi": "^6.0.0", + "supertap": "^1.0.0", + "temp-dir": "^2.0.0", + "trim-off-newlines": "^1.0.1", + "update-notifier": "^4.1.0", + "write-file-atomic": "^3.0.3", + "yargs": "^15.4.0" + }, + "bin": { + "ava": "cli.js" + }, + "engines": { + "node": ">=10.18.0 <11 || >=12.14.0 <12.17.0 || >=12.17.0 <13 || >=14.0.0" + } + }, + "node_modules/ava/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ava/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ava/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/ava/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ava/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ava/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/ava/node_modules/decamelize": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-3.2.0.tgz", + "integrity": "sha512-4TgkVUsmmu7oCSyGBm5FvfMoACuoh9EOidm7V5/J2X2djAwwt57qb3F2KMP2ITqODTCSwb+YRV+0Zqrv18k/hw==", + "dev": true, + "dependencies": { + "xregexp": "^4.2.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ava/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/ava/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ava/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/yargs": { + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.0.tgz", + "integrity": "sha512-D3fRFnZwLWp8jVAAhPZBsmeIHY8tTsb8ItV9KaAaopmC6wde2u6Yw29JBIZHXw14kgkRnYmDgmQU4FVMDlIsWw==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^3.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ava/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ava/node_modules/yargs-parser/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ava/node_modules/yargs/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/bl/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/blueimp-md5": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.16.0.tgz", + "integrity": "sha512-j4nzWIqEFpLSbdhUApHRGDwfXbV8ALhqOn+FY5L6XBdKPAXU9BpGgFSbDsgqogfqPPR9R2WooseWCsfhfEC6uQ==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/bufferutil": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", + "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/chownr": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" + }, + "node_modules/chunkd": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", + "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/ci-parallel-vars": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", + "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", + "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-highlight": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.10.tgz", + "integrity": "sha512-CcPFD3JwdQ2oSzy+AMG6j3LRTkNjM82kzcSKzoVw6cLanDCJNlsLjeqVTOTfOfucnWv5F0rmBemVf1m9JiIasw==", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.0.0", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-highlight/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cli-highlight/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cli-highlight/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/cli-highlight/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-highlight/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", + "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/code-excerpt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", + "dev": true, + "dependencies": { + "convert-to-spaces": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "dependencies": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concordance": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.0.tgz", + "integrity": "sha512-stOCz9ffg0+rytwTaL2njUOIyMfANwfwmqc9Dr4vTUS/x/KkVFlWx9Zlzu6tHYtjKxxaCF/cEAZgPDac+n35sg==", + "dev": true, + "dependencies": { + "date-time": "^3.1.0", + "esutils": "^2.0.3", + "fast-diff": "^1.2.0", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.15", + "md5-hex": "^3.0.1", + "semver": "^7.3.2", + "well-known-symbols": "^2.0.0" + }, + "engines": { + "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=13.5.0" + } + }, + "node_modules/concordance/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cross-env": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz", + "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==", + "dependencies": { + "cross-spawn": "^6.0.5" + }, + "bin": { + "cross-env": "dist/bin/cross-env.js", + "cross-env-shell": "dist/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/date-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", + "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", + "dev": true, + "dependencies": { + "time-zone": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/deep-diff": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-1.0.2.tgz", + "integrity": "sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==" + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "dev": true + }, + "node_modules/del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "dependencies": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/del/node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/del/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/discord.js": { + "version": "13.0.0-dev.edab5af.1624996138", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.edab5af.1624996138.tgz", + "integrity": "sha512-WGbizyvt23aorgHH4dP4vDB/v7NT2szQOdLaeypzjiP89e3yvtVOPDpoFdm03PPzG65n4K005/qfN4yBVVbysw==", + "dependencies": { + "@discordjs/collection": "^0.1.6", + "@discordjs/form-data": "^3.0.1", + "@sapphire/async-queue": "^1.1.4", + "@types/ws": "^7.4.5", + "abort-controller": "^3.0.0", + "discord-api-types": "^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", + "node-fetch": "^2.6.1", + "ws": "^7.5.0" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/discord.js/node_modules/discord-api-types": { + "version": "0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e.tgz", + "integrity": "sha512-ttRA/8e/WKHDbGFfED5WlS7gID+kalmNr6iMiWBCvkphQ7kFHiTOVbnj/zX9ksaRaYXp/I38SCQ+qZvLu8DJZg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/dot-prop": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=", + "engines": { + "node": ">=4.6.0" + } + }, + "node_modules/dotgitconfig": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dotgitconfig/-/dotgitconfig-1.0.1.tgz", + "integrity": "sha512-a6RPc5Cco7ogiKLVExcGBMEEP6jHkzJFYbS/HYGFvQSZrm3EkC876YIqqrj92N8SZYGLqPz6pU522/LlNAaedQ==", + "dependencies": { + "ini": "^1.3.5" + } + }, + "node_modules/duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "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/emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/equal-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", + "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/erlpack": { + "version": "0.1.3", + "resolved": "git+ssh://git@github.com/discord/erlpack.git#e27db8f82892bdb9b28a0547cc394d68b5d2242d", + "integrity": "sha512-uDE+ma9xOMfF4ncJHoymBWA084DqoO8q/hBDvGx4WUxmvFQfHoCsk3BYk1D1Lei/lhNCZXLf1vkeNYVBSqrSgw==", + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.14.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true, + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/figlet": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.0.tgz", + "integrity": "sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fp-ts": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.1.1.tgz", + "integrity": "sha512-YcWhMdDCFCja0MmaDroTgNu+NWWrrnUEn92nvDgrtVy9Z71YFnhNVIghoHPt8gs82ijoMzFGeWKvArbyICiJgw==" + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-extra/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/fs-minipass": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz", + "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "node_modules/glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-dirs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", + "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "dev": true, + "dependencies": { + "ini": "^1.3.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/highlight.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.6.0.tgz", + "integrity": "sha512-8mlRcn5vk/r4+QcqerapwBYTe+iPL5ih6xrNylxrnBdHQiijDETfXX7VIxC3UiCRiINBJfANBAsPzAvRQj8RpQ==", + "engines": { + "node": "*" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/humanize-duration": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.21.0.tgz", + "integrity": "sha512-7BLsrQZ2nMGeakmGDUl1pDne6/7iAdvwf1RtDLCOPHNFIHjkOVW7lcu7xHkIM9HhZAlSSO5crhC1dHvtl4dIQw==" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.0.0.tgz", + "integrity": "sha512-+mQSgMRiFD3L3AOxLYOCxjIq4OnAmo5CIuC+lj5ehCJcPtV++QacEV7FdpzvYxH6DaOySWzQU6RR0lPLy37ckA==", + "dev": true, + "engines": { + "node": ">=10 <11 || >=12 <13 || >=14" + } + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/io-ts": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-2.0.1.tgz", + "integrity": "sha512-RezD+WcCfW4VkMkEcQWL/Nmy/nqsWTvTYg7oUmTGzglvSSV2P9h2z1PVeREPFf0GWNzruYleAt1XCMQZSg1xxQ==", + "peerDependencies": { + "fp-ts": "^2.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/irregular-plurals": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.2.0.tgz", + "integrity": "sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-error": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dev": true, + "dependencies": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-5.0.0.tgz", + "integrity": "sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==", + "dependencies": { + "universalify": "^0.1.2" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/knub": { + "resolved": "../../Knub", + "link": true + }, + "node_modules/knub-command-manager": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-9.1.0.tgz", + "integrity": "sha512-pEtpWElbBoTRSL8kWSPRrTIuTIdvYGkP/wzOn77cieumC02adfwEt1Cc09HFvVT4ib35nf1y31oul36csaG7Vg==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + } + }, + "node_modules/knub-command-manager/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/last-commit-log": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/last-commit-log/-/last-commit-log-2.1.0.tgz", + "integrity": "sha512-vvZNAaiPSQ/PtyfDP2UrIRwKx0xttliGSwEfd/4tU1B/2iD/g4e3nWbttYb6YLarpULpM6s5OW5JWl97ogB6jA==", + "dependencies": { + "dotgitconfig": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.chunk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", + "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, + "node_modules/lodash.intersection": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.intersection/-/lodash.intersection-4.4.0.tgz", + "integrity": "sha1-ChG6Yx0OlcI8fy9Mu5ppLtF45wU=" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "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/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/matcher/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/md5-hex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", + "dev": true, + "dependencies": { + "blueimp-md5": "^2.10.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.0.tgz", + "integrity": "sha512-RlbnLQgRHk5lwqTtpEkBTQ2ll/CG/iB+J4Hy2Wh97PjgZgXgWJWrFF+XXujh3UUVLvR4OOTgZzcWMMwnehlEUg==", + "dev": true, + "dependencies": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mem/node_modules/mimic-fn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.0.0.tgz", + "integrity": "sha512-PiVO95TKvhiwgSwg1IdLYlCTdul38yZxZMIcnDSFIBUm4BNZha2qpQ4GpJ++15bHoKDtrW2D69lMfFwdFYtNZQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dependencies": { + "mime-db": "1.40.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/minizlib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", + "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.27", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.27.tgz", + "integrity": "sha512-EIKQs7h5sAsjhPCqN6ggx6cEbs94GK050254TIJySD1bzoM5JTYDwAU1IoVOeTOL6Gm27kYJ51/uuvq1kIlrbw==", + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/mysql": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz", + "integrity": "sha512-7vMqHQ673SAk5C8fOzTG2LpPcf3bNt0oL3sFpxPEEFp1mdlDcrLK0On7z8ZYKaaHrHwNcQ/MTUz7/oobZ2OyyA==", + "dependencies": { + "bignumber.js": "7.2.1", + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node_modules/node-abi": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.0.tgz", + "integrity": "sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg==", + "dependencies": { + "semver": "^5.4.1" + } + }, + "node_modules/node-cleanup": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", + "integrity": "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "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", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.4.tgz", + "integrity": "sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/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/parent-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", + "integrity": "sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/parse-color": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", + "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=", + "dependencies": { + "color-convert": "~0.5.0" + } + }, + "node_modules/parse-color/node_modules/color-convert": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", + "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/passport": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", + "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-custom": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/passport-custom/-/passport-custom-1.1.0.tgz", + "integrity": "sha512-wWlewQHKQfiQPY7SwQj1w+/MioiVRc/rBuNEgLaBKinKoFkiTDOFVzJ03wYK5e0i9h9Rk6AOf1k6lIpVNYGQiA==", + "dependencies": { + "passport-strategy": "1.x.x" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/passport-oauth2": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", + "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", + "dependencies": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true, + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prebuild-install": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", + "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", + "dependencies": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pretty-ms": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.0.tgz", + "integrity": "sha512-J3aPWiC5e9ZeZFuSeBraGxSkGMOvulSWsxDByOcbD1Pr75YL3LSNIKIb52WXbCLE1sS5s4inBBbryjF4Y05Ceg==", + "dev": true, + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ps-tree": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", + "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", + "dev": true, + "dependencies": { + "event-stream": "=3.3.4" + }, + "bin": { + "ps-tree": "bin/ps-tree.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pupa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", + "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "dev": true, + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "node_modules/regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, + "node_modules/regexp-tree": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.14.tgz", + "integrity": "sha512-59v5A90TAh4cAMyDQEOzcnsu4q7Wb10RsyTjngEnJIZsWYM4siVGu+JmLT1WsxHvOWhiu4YS20XiTuxWMeVoHQ==", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexp-worker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexp-worker/-/regexp-worker-1.1.0.tgz", + "integrity": "sha512-IDDOhDlI972T7bexYwyw+JKdqFsBtJvX8RA+ChVwjhgcK/gv4eG3oZu8Rbidnamh2U2b0ZWdawKksjzY2dmVFw==", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/registry-auth-token": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", + "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "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/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/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/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "node_modules/serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sharp": { + "version": "0.23.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.4.tgz", + "integrity": "sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q==", + "hasInstallScript": true, + "dependencies": { + "color": "^3.1.2", + "detect-libc": "^1.0.3", + "nan": "^2.14.0", + "npmlog": "^4.1.2", + "prebuild-install": "^5.3.3", + "semver": "^6.3.0", + "simple-get": "^3.1.0", + "tar": "^5.0.5", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=8.5.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/sharp/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/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "node_modules/simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "node_modules/simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-get/node_modules/mimic-response": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz", + "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "node_modules/split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true, + "dependencies": { + "duplexer": "~0.1.1" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-argv": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz", + "integrity": "sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-combining-marks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-combining-marks/-/strip-combining-marks-1.0.0.tgz", + "integrity": "sha1-gpXK/RGDN+u+Rt3Fgizb2flb6nE=" + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supertap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-1.0.0.tgz", + "integrity": "sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "indent-string": "^3.2.0", + "js-yaml": "^3.10.0", + "serialize-error": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supertap/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/supertap/node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supertap/node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/supertap/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tar": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz", + "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==", + "dependencies": { + "chownr": "^1.1.3", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^0.5.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/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/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/term-size": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", + "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tlds": { + "version": "1.203.1", + "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.203.1.tgz", + "integrity": "sha512-7MUlYyGJ6rSitEZ3r1Q1QNV8uSIzapS8SmmhSusBuIc7uIxPPwsKllEP0GRp1NS6Ik6F+fRZvnjDWm3ecv2hDw==", + "bin": { + "tlds": "bin.js" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tsc-watch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-4.0.0.tgz", + "integrity": "sha512-I+1cE7WN9YhDknNRAO5NRI7jzeiIZCxUZ0dFEM/Gf+3KTlHasusDEftwezJ+PSFkECSn3RQmf28RdovjTptkRA==", + "dev": true, + "dependencies": { + "cross-spawn": "^5.1.0", + "node-cleanup": "^2.1.2", + "ps-tree": "^1.2.0", + "string-argv": "^0.1.1", + "strip-ansi": "^4.0.0" + }, + "bin": { + "tsc-watch": "index.js" + }, + "engines": { + "node": ">=6.4.0" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/tsc-watch/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tsc-watch/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/tsc-watch/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/twemoji": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/twemoji/-/twemoji-12.1.4.tgz", + "integrity": "sha512-e37lUlVijmABF7wPCc09s1kKj3hcpzU8KL5zw2bBDIXOtOr4luLF+ODJaEqca8dZPmLR5ezrJYI93nhPovKBiQ==", + "dependencies": { + "fs-extra": "^8.0.1", + "jsonfile": "^5.0.0", + "twemoji-parser": "12.1.1", + "universalify": "^0.1.2" + } + }, + "node_modules/twemoji-parser": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/twemoji-parser/-/twemoji-parser-12.1.1.tgz", + "integrity": "sha512-XFUB4ReEvPbNPtiuyo/+crM4RldYbRRAhyE7Hw6EnfBdXECGydw7a49EGADayRvaeierP/m4DSv/OZQObh0LGA==" + }, + "node_modules/type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typeorm": { + "version": "0.2.31", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.31.tgz", + "integrity": "sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==", + "dependencies": { + "@sqltools/formatter": "1.2.2", + "app-root-path": "^3.0.0", + "buffer": "^5.5.0", + "chalk": "^4.1.0", + "cli-highlight": "^2.1.10", + "debug": "^4.1.1", + "dotenv": "^8.2.0", + "glob": "^7.1.6", + "js-yaml": "^3.14.0", + "mkdirp": "^1.0.4", + "reflect-metadata": "^0.1.13", + "sha.js": "^2.4.11", + "tslib": "^1.13.0", + "xml2js": "^0.4.23", + "yargonaut": "^1.1.2", + "yargs": "^16.0.3" + }, + "bin": { + "typeorm": "cli.js" + }, + "funding": { + "url": "https://opencollective.com/typeorm" + } + }, + "node_modules/typeorm/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/typeorm/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/typeorm/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/typeorm/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/typeorm/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/typeorm/node_modules/dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/typeorm/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typeorm/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/typeorm/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/typeorm/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typeorm/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/typeorm/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "4.4.0-dev.20210629", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.0-dev.20210629.tgz", + "integrity": "sha512-kqDceSuAA0qQ6z5mrQc3LcD6IcwrKOZZ2YO7oBgwfGM0zzraUKhpdJSZovwN0pF3MdI211HccvrHf8JX7UJD7A==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dev": true, + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-notifier": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", + "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", + "dev": true, + "dependencies": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/update-notifier/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/update-notifier/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.5.tgz", + "integrity": "sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ==", + "hasInstallScript": true, + "dependencies": { + "node-gyp-build": "^4.2.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", + "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "dev": true, + "dependencies": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/yaml-js": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/yaml-js/-/yaml-js-0.2.3.tgz", + "integrity": "sha512-6xUQtVKl1qcd0EXtTEzUDVJy9Ji1fYa47LtkDtYKlIjhibPE9knNPmoRyf6SGREFHlOAUyDe9OdYqRP4DuSi5Q==" + }, + "node_modules/yargonaut": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", + "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", + "dependencies": { + "chalk": "^1.1.1", + "figlet": "^1.1.1", + "parent-require": "^1.0.0" + } + }, + "node_modules/yargonaut/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.5", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.5.tgz", + "integrity": "sha512-jYRGS3zWy20NtDtK2kBgo/TlAoy5YUuhD9/LZ7z7W4j1Fdw2cqD0xEEclf8fxc8xjD6X5Qr+qQQwCEsP8iRiYg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yawn-yaml": { + "version": "1.5.0", + "resolved": "git+ssh://git@github.com/dragory/yawn-yaml.git#77ab3870ca53c4693002c4a41336e7476e7934ed", + "integrity": "sha512-22gZa51NZQgBnoQzTqoNAXqNn8l7vonJhU+MEiqDXz6sA0GszMk0Un2xyN1p+8uhdq6ndFKz5qXeDC0eAyaMtQ==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.4.2", + "lodash": "^4.17.11", + "yaml-js": "^0.2.3" + } + }, + "node_modules/zlib-sync": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/zlib-sync/-/zlib-sync-0.1.7.tgz", + "integrity": "sha512-UmciU6ZrIwtwPC8noMzq+kGMdiWwNRZ3wC0SbED4Ew5Ikqx14MqDPRs/Pbk+3rZPh5SzsOgUBs1WRE0iieddpg==", + "hasInstallScript": true, + "dependencies": { + "nan": "^2.14.0" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.10.4", @@ -99,9 +6452,9 @@ } }, "@sapphire/async-queue": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.2.tgz", - "integrity": "sha512-NkR7AzC9uyb++tMIZgG4X0ci8JM1rnvNmKbLwY42RgotRV8JGUntZ7ZpR7MN7p5zPlVdKo/YmOqcCCsBJ6LNuw==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.4.tgz", + "integrity": "sha512-fFrlF/uWpGOX5djw5Mu2Hnnrunao75WGey0sP0J3jnhmrJ5TAPzHYOmytD5iN/+pMxS+f+u/gezqHa9tPhRHEA==" }, "@sindresorhus/is": { "version": "0.14.0", @@ -341,6 +6694,14 @@ "resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.0.tgz", "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==" }, + "@types/ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA==", + "requires": { + "@types/node": "*" + } + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -1625,23 +7986,26 @@ "path-type": "^4.0.0" } }, - "discord-api-types": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.18.1.tgz", - "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" - }, "discord.js": { - "version": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", - "from": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", + "version": "13.0.0-dev.edab5af.1624996138", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.edab5af.1624996138.tgz", + "integrity": "sha512-WGbizyvt23aorgHH4dP4vDB/v7NT2szQOdLaeypzjiP89e3yvtVOPDpoFdm03PPzG65n4K005/qfN4yBVVbysw==", "requires": { "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", - "@sapphire/async-queue": "^1.1.2", + "@sapphire/async-queue": "^1.1.4", + "@types/ws": "^7.4.5", "abort-controller": "^3.0.0", + "discord-api-types": "^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", "node-fetch": "^2.6.1", - "prism-media": "^1.2.9", - "tweetnacl": "^1.0.3", - "ws": "^7.4.5" + "ws": "^7.5.0" + }, + "dependencies": { + "discord-api-types": { + "version": "0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e.tgz", + "integrity": "sha512-ttRA/8e/WKHDbGFfED5WlS7gID+kalmNr6iMiWBCvkphQ7kFHiTOVbnj/zX9ksaRaYXp/I38SCQ+qZvLu8DJZg==" + } } }, "dot-prop": { @@ -1714,8 +8078,9 @@ "dev": true }, "erlpack": { - "version": "github:discord/erlpack#e27db8f82892bdb9b28a0547cc394d68b5d2242d", - "from": "github:discord/erlpack", + "version": "git+ssh://git@github.com/discord/erlpack.git#e27db8f82892bdb9b28a0547cc394d68b5d2242d", + "integrity": "sha512-uDE+ma9xOMfF4ncJHoymBWA084DqoO8q/hBDvGx4WUxmvFQfHoCsk3BYk1D1Lei/lhNCZXLf1vkeNYVBSqrSgw==", + "from": "erlpack@github:discord/erlpack", "requires": { "bindings": "^1.5.0", "nan": "^2.14.0" @@ -2056,9 +8421,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2252,7 +8617,8 @@ "io-ts": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-2.0.1.tgz", - "integrity": "sha512-RezD+WcCfW4VkMkEcQWL/Nmy/nqsWTvTYg7oUmTGzglvSSV2P9h2z1PVeREPFf0GWNzruYleAt1XCMQZSg1xxQ==" + "integrity": "sha512-RezD+WcCfW4VkMkEcQWL/Nmy/nqsWTvTYg7oUmTGzglvSSV2P9h2z1PVeREPFf0GWNzruYleAt1XCMQZSg1xxQ==", + "requires": {} }, "ipaddr.js": { "version": "1.9.0", @@ -2455,35 +8821,33 @@ } }, "knub": { - "version": "30.0.0-beta.38", - "resolved": "https://registry.npmjs.org/knub/-/knub-30.0.0-beta.38.tgz", - "integrity": "sha512-/c1JgFoI/ezzVSC9fXxdeqv3EE5b4w/WC15UcJY2+EjJHlzuFAePK6pZynNRM7y8c/O35/jslkpSwnDrPMrhRg==", + "version": "file:../../Knub", "requires": { + "@discordjs/voice": "^0.5.1", + "@types/chai": "^4.2.18", + "@types/mocha": "^7.0.2", + "@types/node": "^14.14.45", + "@typescript-eslint/eslint-plugin": "^4.23.0", + "@typescript-eslint/parser": "^4.23.0", + "chai": "^4.3.4", "discord-api-types": "^0.18.1", - "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", + "discord.js": "^13.0.0-dev.edab5af.1624996138", + "eslint": "^7.2.0", + "husky": "^4.3.8", "knub-command-manager": "^9.1.0", - "ts-essentials": "^6.0.7" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" - }, - "knub-command-manager": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-9.1.0.tgz", - "integrity": "sha512-pEtpWElbBoTRSL8kWSPRrTIuTIdvYGkP/wzOn77cieumC02adfwEt1Cc09HFvVT4ib35nf1y31oul36csaG7Vg==", - "requires": { - "escape-string-regexp": "^2.0.0" - } - } + "lint-staged": "^10.5.4", + "mocha": "^8.4.0", + "prettier": "^2.3.0", + "shx": "^0.3.3", + "ts-essentials": "^6.0.7", + "ts-node": "^8.10.2", + "typescript": "^4.2.4" } }, "knub-command-manager": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-8.1.2.tgz", - "integrity": "sha512-/ooWzol2uxKRSi8INDaexXeRfLRJyboQUbwFFljkE3aYHihnf4ZNuKNgQImq2aUhSdLl9Jy/A1fCSjuooNsbtw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/knub-command-manager/-/knub-command-manager-9.1.0.tgz", + "integrity": "sha512-pEtpWElbBoTRSL8kWSPRrTIuTIdvYGkP/wzOn77cieumC02adfwEt1Cc09HFvVT4ib35nf1y31oul36csaG7Vg==", "requires": { "escape-string-regexp": "^2.0.0" }, @@ -2907,9 +9271,9 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "npmlog": { @@ -3375,11 +9739,6 @@ "parse-ms": "^2.1.0" } }, - "prism-media": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.9.tgz", - "integrity": "sha512-UHCYuqHipbTR1ZsXr5eg4JUmHER8Ss4YEb9Azn+9zzJ7/jlTtD1h0lc4g6tNx3eMlB8Mp6bfll0LPMAV4R6r3Q==" - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -3975,6 +10334,14 @@ "duplexer": "~0.1.1" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-argv": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz", @@ -4000,14 +10367,6 @@ } } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -4217,11 +10576,6 @@ "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, - "ts-essentials": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-6.0.7.tgz", - "integrity": "sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==" - }, "tsc-watch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-4.0.0.tgz", @@ -4287,11 +10641,6 @@ "safe-buffer": "^5.0.1" } }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, "twemoji": { "version": "12.1.4", "resolved": "https://registry.npmjs.org/twemoji/-/twemoji-12.1.4.tgz", @@ -4446,9 +10795,9 @@ } }, "typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "4.4.0-dev.20210629", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.0-dev.20210629.tgz", + "integrity": "sha512-kqDceSuAA0qQ6z5mrQc3LcD6IcwrKOZZ2YO7oBgwfGM0zzraUKhpdJSZovwN0pF3MdI211HccvrHf8JX7UJD7A==", "dev": true }, "uid2": { @@ -4576,9 +10925,9 @@ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -4783,9 +11132,10 @@ } }, "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", + "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", + "requires": {} }, "xdg-basedir": { "version": "4.0.0", @@ -4930,6 +11280,7 @@ }, "yawn-yaml": { "version": "git+ssh://git@github.com/dragory/yawn-yaml.git#77ab3870ca53c4693002c4a41336e7476e7934ed", + "integrity": "sha512-22gZa51NZQgBnoQzTqoNAXqNn8l7vonJhU+MEiqDXz6sA0GszMk0Un2xyN1p+8uhdq6ndFKz5qXeDC0eAyaMtQ==", "from": "yawn-yaml@github:dragory/yawn-yaml#string-number-fix-build", "requires": { "js-yaml": "^3.4.2", diff --git a/backend/package.json b/backend/package.json index b92b0ff1..73213034 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", + "discord.js": "^13.0.0-dev.edab5af.1624996138", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -39,8 +39,8 @@ "humanize-duration": "^3.15.0", "io-ts": "^2.0.0", "js-yaml": "^3.13.1", - "knub": "^30.0.0-beta.38", - "knub-command-manager": "^8.1.2", + "knub": "file:../../Knub", + "knub-command-manager": "^9.1.0", "last-commit-log": "^2.1.0", "lodash.chunk": "^4.2.0", "lodash.clonedeep": "^4.5.0", @@ -88,7 +88,7 @@ "rimraf": "^2.6.2", "source-map-support": "^0.5.16", "tsc-watch": "^4.0.0", - "typescript": "^4.1.3" + "typescript": "^4.4.0-dev.20210629" }, "ava": { "files": [ diff --git a/backend/src/data/GuildArchives.ts b/backend/src/data/GuildArchives.ts index e99d8835..df69e6c1 100644 --- a/backend/src/data/GuildArchives.ts +++ b/backend/src/data/GuildArchives.ts @@ -1,4 +1,4 @@ -import { Guild } from "discord.js"; +import { Guild, Snowflake } from "discord.js"; import moment from "moment-timezone"; import { getRepository, Repository } from "typeorm"; import { renderTemplate } from "../templateFormatter"; @@ -73,7 +73,7 @@ export class GuildArchives extends BaseGuildRepository { protected async renderLinesFromSavedMessages(savedMessages: SavedMessage[], guild: Guild) { const msgLines: string[] = []; for (const msg of savedMessages) { - const channel = guild.channels.cache.get(msg.channel_id); + const channel = guild.channels.cache.get(msg.channel_id as Snowflake); const user = { ...msg.data.author, id: msg.user_id }; const line = await renderTemplate(MESSAGE_ARCHIVE_MESSAGE_FORMAT, { diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index bb0f607e..733ba59a 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -196,7 +196,7 @@ export async function sendSuccessMessage( : { content: formattedBody }; return channel - .send({ ...content, split: false }) // Force line break + .send({ ...content }) // Force line break .catch(err => { const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : `${channel.id}`; logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); @@ -217,7 +217,7 @@ export async function sendErrorMessage( : { content: formattedBody }; return channel - .send({ ...content, split: false }) // Force line break + .send({ ...content }) // Force line break .catch(err => { const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : `${channel.id}`; logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts index 553f828f..e18b8feb 100644 --- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts +++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts @@ -1,4 +1,4 @@ -import { Permissions, TextChannel } from "discord.js"; +import { Permissions, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { LogType } from "../../../data/LogType"; @@ -16,7 +16,7 @@ export async function deleteNextItem(pluginData: GuildPluginData { + (channel as TextChannel).messages.delete(itemToDelete.message.id as Snowflake).catch(err => { if (err.code === 10008) { // "Unknown Message", probably already deleted by automod or another bot, ignore return; diff --git a/backend/src/plugins/Automod/actions/addRoles.ts b/backend/src/plugins/Automod/actions/addRoles.ts index ea467446..e87a2cc2 100644 --- a/backend/src/plugins/Automod/actions/addRoles.ts +++ b/backend/src/plugins/Automod/actions/addRoles.ts @@ -1,4 +1,4 @@ -import { Permissions } from "discord.js"; +import { Permissions, Snowflake } from "discord.js"; import * as t from "io-ts"; import { LogType } from "../../../data/LogType"; import { nonNullish, unique } from "../../../utils"; @@ -41,7 +41,7 @@ export const AddRolesAction = automodAction({ if (rolesWeCannotAssign.length) { const roleNamesWeCannotAssign = rolesWeCannotAssign.map( - roleId => pluginData.guild.roles.cache.get(roleId)?.name || roleId, + roleId => pluginData.guild.roles.cache.get(roleId as Snowflake)?.name || roleId, ); const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { @@ -55,7 +55,7 @@ export const AddRolesAction = automodAction({ members.map(async member => { const memberRoles = new Set(member.roles.cache.keyArray()); for (const roleId of rolesToAssign) { - memberRoles.add(roleId); + memberRoles.add(roleId as Snowflake); ignoreRoleChange(pluginData, member.id, roleId); } diff --git a/backend/src/plugins/Automod/actions/alert.ts b/backend/src/plugins/Automod/actions/alert.ts index bb0593e2..206c215c 100644 --- a/backend/src/plugins/Automod/actions/alert.ts +++ b/backend/src/plugins/Automod/actions/alert.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; import { LogType } from "../../../data/LogType"; @@ -24,7 +24,7 @@ export const AlertAction = automodAction({ defaultConfig: {}, async apply({ pluginData, contexts, actionConfig, ruleName, matchResult }) { - const channel = pluginData.guild.channels.cache.get(actionConfig.channel); + const channel = pluginData.guild.channels.cache.get(actionConfig.channel as Snowflake); const logs = pluginData.getPlugin(LogsPlugin); if (channel && channel instanceof TextChannel) { diff --git a/backend/src/plugins/Automod/actions/clean.ts b/backend/src/plugins/Automod/actions/clean.ts index a326cc3b..56d5be64 100644 --- a/backend/src/plugins/Automod/actions/clean.ts +++ b/backend/src/plugins/Automod/actions/clean.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { LogType } from "../../../data/LogType"; import { noop } from "../../../utils"; @@ -30,8 +30,8 @@ export const CleanAction = automodAction({ pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE, id); } - const channel = pluginData.guild.channels.cache.get(channelId) as TextChannel; - await channel.bulkDelete(messageIds).catch(noop); + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake) as TextChannel; + await channel.bulkDelete(messageIds as Snowflake[]).catch(noop); } }, }); diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index 09e881f4..54ce11f1 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -1,4 +1,4 @@ -import { Permissions } from "discord.js"; +import { Permissions, Snowflake } from "discord.js"; import * as t from "io-ts"; import { LogType } from "../../../data/LogType"; import { nonNullish, unique } from "../../../utils"; @@ -42,7 +42,7 @@ export const RemoveRolesAction = automodAction({ if (rolesWeCannotRemove.length) { const roleNamesWeCannotRemove = rolesWeCannotRemove.map( - roleId => pluginData.guild.roles.cache.get(roleId)?.name || roleId, + roleId => pluginData.guild.roles.cache.get(roleId as Snowflake)?.name || roleId, ); const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { @@ -56,7 +56,7 @@ export const RemoveRolesAction = automodAction({ members.map(async member => { const memberRoles = new Set(member.roles.cache.keyArray()); for (const roleId of rolesToRemove) { - memberRoles.delete(roleId); + memberRoles.delete(roleId as Snowflake); ignoreRoleChange(pluginData, member.id, roleId); } diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index 0a1c9ba1..07164ee6 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -1,4 +1,4 @@ -import { MessageOptions, Permissions, TextChannel, User } from "discord.js"; +import { MessageOptions, Permissions, Snowflake, TextChannel, User } from "discord.js"; import * as t from "io-ts"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; @@ -31,7 +31,7 @@ export const ReplyAction = automodAction({ async apply({ pluginData, contexts, actionConfig, ruleName }) { const contextsWithTextChannels = contexts .filter(c => c.message?.channel_id) - .filter(c => pluginData.guild.channels.cache.get(c.message!.channel_id) instanceof TextChannel); + .filter(c => pluginData.guild.channels.cache.get(c.message!.channel_id as Snowflake) instanceof TextChannel); const contextsByChannelId = contextsWithTextChannels.reduce((map: Map, context) => { if (!map.has(context.message!.channel_id)) { @@ -56,7 +56,7 @@ export const ReplyAction = automodAction({ : ((await renderRecursively(actionConfig.text, renderReplyText)) as MessageOptions); if (formatted) { - const channel = pluginData.guild.channels.cache.get(channelId) as TextChannel; + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake) as TextChannel; // Check for basic Send Messages and View Channel permissions if ( @@ -90,7 +90,6 @@ export const ReplyAction = automodAction({ allowedMentions: { users: [user.id], }, - split: false, }); if (typeof actionConfig === "object" && actionConfig.auto_delete) { diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index 05222df3..c303de3a 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { ChannelTypeStrings } from "src/types"; import { LogType } from "../../../data/LogType"; @@ -19,7 +19,7 @@ export const SetSlowmodeAction = automodAction({ const slowmodeMs = Math.max(actionConfig.duration ? convertDelayStringToMS(actionConfig.duration)! : 0, 0); for (const channelId of actionConfig.channels) { - const channel = pluginData.guild.channels.cache.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); // Only text channels and text channels within categories support slowmodes if (!channel || !(channel.type === ChannelTypeStrings.TEXT || ChannelTypeStrings.CATEGORY)) { diff --git a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts index 1945be37..34d14a74 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { SavedMessage } from "../../../data/entities/SavedMessage"; @@ -11,8 +12,8 @@ export function runAutomodOnMessage( message: SavedMessage, isEdit: boolean, ) { - const user = pluginData.client.users.cache!.get(message.user_id); - const member = pluginData.guild.members.cache.get(message.user_id); + const user = pluginData.client.users.cache!.get(message.user_id as Snowflake); + const member = pluginData.guild.members.cache.get(message.user_id as Snowflake); const context: AutomodContext = { timestamp: moment.utc(message.posted_at).valueOf(), diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts index 7ce964d5..f88f9b69 100644 --- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts +++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts @@ -1,3 +1,4 @@ +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { messageSummary, verboseChannelMention } from "../../../utils"; import { AutomodContext, AutomodPluginType } from "../types"; @@ -10,13 +11,13 @@ export function getTextMatchPartialSummary( ) { if (type === "message") { const message = context.message!; - const channel = pluginData.guild.channels.cache.get(message.channel_id); + const channel = pluginData.guild.channels.cache.get(message.channel_id as Snowflake) as TextChannel; const channelMention = channel ? verboseChannelMention(channel) : `\`#${message.channel_id}\``; return `message in ${channelMention}:\n${messageSummary(message)}`; } else if (type === "embed") { const message = context.message!; - const channel = pluginData.guild.channels.cache.get(message.channel_id); + const channel = pluginData.guild.channels.cache.get(message.channel_id as Snowflake) as TextChannel; const channelMention = channel ? verboseChannelMention(channel) : `\`#${message.channel_id}\``; return `message embed in ${channelMention}:\n${messageSummary(message)}`; @@ -28,6 +29,6 @@ export function getTextMatchPartialSummary( const visibleName = context.member?.nickname || context.user!.username; return `visible name: ${visibleName}`; } else if (type === "customstatus") { - return `custom status: ${context.member!.presence.activities.find(a => a.type === "CUSTOM_STATUS")?.name}`; + return `custom status: ${context.member!.presence.activities.find(a => a.type === "CUSTOM")?.name}`; } } diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts index cbb5709d..8dca9ee4 100644 --- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts +++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; @@ -18,7 +18,7 @@ export function resolveActionContactMethods( throw new RecoverablePluginError(ERRORS.NO_USER_NOTIFICATION_CHANNEL); } - const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel); + const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel as Snowflake); if (!(channel instanceof TextChannel)) { throw new RecoverablePluginError(ERRORS.INVALID_USER_NOTIFICATION_CHANNEL); } diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts index 3af968da..d3520402 100644 --- a/backend/src/plugins/Automod/functions/runAutomod.ts +++ b/backend/src/plugins/Automod/functions/runAutomod.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { availableActions } from "../actions/availableActions"; import { CleanAction } from "../actions/clean"; @@ -9,10 +9,10 @@ import { checkAndUpdateCooldown } from "./checkAndUpdateCooldown"; export async function runAutomod(pluginData: GuildPluginData, context: AutomodContext) { const userId = context.user?.id || context.member?.id || context.message?.user_id; - const user = context.user || (userId && pluginData.client.users!.cache.get(userId)); - const member = context.member || (userId && pluginData.guild.members.cache.get(userId)) || null; + const user = context.user || (userId && pluginData.client.users!.cache.get(userId as Snowflake)); + const member = context.member || (userId && pluginData.guild.members.cache.get(userId as Snowflake)) || null; const channelId = context.message?.channel_id; - const channel = channelId ? (pluginData.guild.channels.cache.get(channelId) as TextChannel) : null; + const channel = channelId ? (pluginData.guild.channels.cache.get(channelId as Snowflake) as TextChannel) : null; const categoryId = channel?.parentID; const config = await pluginData.config.getMatchingConfig({ diff --git a/backend/src/plugins/Automod/triggers/anyMessage.ts b/backend/src/plugins/Automod/triggers/anyMessage.ts index 59c120ad..9422f4f5 100644 --- a/backend/src/plugins/Automod/triggers/anyMessage.ts +++ b/backend/src/plugins/Automod/triggers/anyMessage.ts @@ -1,3 +1,4 @@ +import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; @@ -21,7 +22,7 @@ export const AnyMessageTrigger = automodTrigger()({ }, renderMatchInformation({ pluginData, contexts, matchResult }) { - const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id); + const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id as Snowflake) as TextChannel; return `Matched message (\`${contexts[0].message!.id}\`) in ${ channel ? verboseChannelMention(channel) : "Unknown Channel" }`; diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 11a25d05..d69cc9a8 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -1,3 +1,4 @@ +import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { asSingleLine, disableInlineCode, messageSummary, verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; @@ -67,7 +68,7 @@ export const MatchAttachmentTypeTrigger = automodTrigger()({ }, renderMatchInformation({ pluginData, contexts, matchResult }) { - const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id)!; + const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id as Snowflake) as TextChannel; const prettyChannel = verboseChannelMention(channel); return ( diff --git a/backend/src/plugins/Automod/triggers/roleAdded.ts b/backend/src/plugins/Automod/triggers/roleAdded.ts index ad0e6bfd..d3fd0cf9 100644 --- a/backend/src/plugins/Automod/triggers/roleAdded.ts +++ b/backend/src/plugins/Automod/triggers/roleAdded.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import * as t from "io-ts"; import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges"; import { automodTrigger } from "../helpers"; @@ -33,7 +34,7 @@ export const RoleAddedTrigger = automodTrigger()({ }, renderMatchInformation({ matchResult, pluginData, contexts }) { - const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId); + const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId as Snowflake); const roleName = role?.name || "Unknown"; const member = contexts[0].member!; const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; diff --git a/backend/src/plugins/Automod/triggers/roleRemoved.ts b/backend/src/plugins/Automod/triggers/roleRemoved.ts index b0af1166..45360086 100644 --- a/backend/src/plugins/Automod/triggers/roleRemoved.ts +++ b/backend/src/plugins/Automod/triggers/roleRemoved.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import * as t from "io-ts"; import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges"; import { automodTrigger } from "../helpers"; @@ -33,7 +34,7 @@ export const RoleRemovedTrigger = automodTrigger()({ }, renderMatchInformation({ matchResult, pluginData, contexts }) { - const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId); + const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId as Snowflake); const roleName = role?.name || "Unknown"; const member = contexts[0].member!; const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index 3e559af0..dd53d72c 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; import { Configs } from "../../data/Configs"; @@ -58,9 +58,9 @@ export const BotControlPlugin = zeppelinGlobalPlugin()({ const [guildId, channelId] = activeReload; resetActiveReload(); - const guild = await pluginData.client.guilds.fetch(guildId); + const guild = await pluginData.client.guilds.fetch(guildId as Snowflake); if (guild) { - const channel = guild.channels.cache.get(channelId); + const channel = guild.channels.cache.get(channelId as Snowflake); if (channel instanceof TextChannel) { sendSuccessMessage(pluginData, channel, "Global plugins reloaded!"); } diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index 53950f53..e9bbf694 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -15,9 +15,9 @@ export const ServersCmd = botControlCmd({ signature: { search: ct.string({ catchAll: true, required: false }), - all: ct.switchOption({ shortcut: "a" }), - initialized: ct.switchOption({ shortcut: "i" }), - uninitialized: ct.switchOption({ shortcut: "u" }), + all: ct.switchOption({ def: false, shortcut: "a" }), + initialized: ct.switchOption({ def: false, shortcut: "i" }), + uninitialized: ct.switchOption({ def: false, shortcut: "u" }), }, async run({ pluginData, message: msg, args }) { diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index 5d52c662..90c051c5 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -108,5 +108,5 @@ export async function getCaseEmbed( }); } - return { embed }; + return { embeds: [embed] }; } diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index ddd250e3..33a6e97d 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -1,4 +1,4 @@ -import { FileOptions, Message, MessageOptions, TextChannel } from "discord.js"; +import { FileOptions, Message, MessageOptions, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; @@ -15,7 +15,7 @@ export async function postToCaseLogChannel( const caseLogChannelId = pluginData.config.get().case_log_channel; if (!caseLogChannelId) return null; - const caseLogChannel = pluginData.guild.channels.cache.get(caseLogChannelId); + const caseLogChannel = pluginData.guild.channels.cache.get(caseLogChannelId as Snowflake); if (!caseLogChannel || !(caseLogChannel instanceof TextChannel)) return null; let result; @@ -23,7 +23,7 @@ export async function postToCaseLogChannel( if (file != null) { content.files = file; } - result = await caseLogChannel.send({ ...content, split: false }); + result = await caseLogChannel.send({ ...content }); } catch (e) { if (isDiscordRESTError(e) && (e.code === 50013 || e.code === 50001)) { pluginData.state.logs.log(LogType.BOT_ALERT, { @@ -52,8 +52,8 @@ export async function postCaseToCaseLogChannel( const [channelId, messageId] = theCase.log_message_id.split("-"); try { - const channel = pluginData.guild.channels.resolve(channelId) as TextChannel; - await channel.messages.edit(messageId, caseEmbed); + const channel = pluginData.guild.channels.resolve(channelId as Snowflake) as TextChannel; + await channel.messages.edit(messageId as Snowflake, caseEmbed); return null; } catch {} // tslint:disable-line:no-empty } diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index 62249446..29704425 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers"; import { SavedMessage } from "../../../data/entities/SavedMessage"; @@ -14,14 +14,14 @@ export async function censorMessage( pluginData.state.serverLogs.ignoreLog(LogType.MESSAGE_DELETE, savedMessage.id); try { - const resolvedChannel = pluginData.guild.channels.resolve(savedMessage.channel_id) as TextChannel; - await resolvedChannel.messages.delete(savedMessage.id); + const resolvedChannel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake) as TextChannel; + await resolvedChannel.messages.delete(savedMessage.id as Snowflake); } catch { return; } const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake); pluginData.state.serverLogs.log(LogType.CENSOR, { user: stripObjectToScalars(user), diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 3d4112a9..5d84be22 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -1,3 +1,4 @@ +import { Collection, Message, Snowflake } from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isOwner, sendErrorMessage } from "../../../pluginUtils"; @@ -31,11 +32,10 @@ export const ArchiveChannelCmd = channelArchiverCmd({ async run({ message: msg, args, pluginData }) { if (!args["attachment-channel"]) { - const confirmed = await confirm( - msg.channel, - msg.author.id, - "No `-attachment-channel` specified. Continue? Attachments will not be available in the log if their message is deleted.", - ); + const confirmed = await confirm(msg.channel, msg.author.id, { + content: + "No `-attachment-channel` specified. Continue? Attachments will not be available in the log if their message is deleted.", + }); if (!confirmed) { sendErrorMessage(pluginData, msg.channel, "Canceled"); return; @@ -60,7 +60,10 @@ export const ArchiveChannelCmd = channelArchiverCmd({ while (archivedMessages < maxMessagesToArchive) { const messagesToFetch = Math.min(MAX_MESSAGES_PER_FETCH, maxMessagesToArchive - archivedMessages); - const messages = await args.channel.messages.fetch({ limit: messagesToFetch, before: previousId }); + const messages = (await args.channel.messages.fetch({ + limit: messagesToFetch, + before: previousId, + })) as Collection; if (messages.size === 0) break; for (const message of messages.values()) { @@ -111,7 +114,6 @@ export const ArchiveChannelCmd = channelArchiverCmd({ name: `archive-${args.channel.name}-${moment.utc().format("YYYY-MM-DD-HH-mm-ss")}.txt`, }, ], - split: false, }); }, }); diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index f51c6173..13b65cfc 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -22,7 +22,7 @@ export async function rehostAttachment(attachment: MessageAttachment, targetChan content: `Rehost of attachment ${attachment.id}`, files: [{ name: attachment.name ? attachment.name : undefined, attachment: await fsp.readFile(downloaded.path) }], }; - const rehostMessage = await targetChannel.send({ content, split: false }); + const rehostMessage = await targetChannel.send(content); return rehostMessage.attachments.values()[0].url; } catch { return "Failed to rehost attachment"; diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index a2155dc1..ddbfc266 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -1,4 +1,4 @@ -import { Permissions, StageChannel, TextChannel, VoiceChannel } from "discord.js"; +import { Permissions, Snowflake, StageChannel, TextChannel, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { isDiscordRESTError, MINUTES } from "../../../utils"; @@ -51,13 +51,15 @@ export async function handleCompanionPermissions( try { for (const channelId of permsToDelete) { - const channel = pluginData.guild.channels.cache.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel || !(channel instanceof TextChannel)) continue; - await channel.permissionOverwrites.get(userId)?.delete(`Companion Channel for ${oldChannel!.id} | User Left`); + await channel.permissionOverwrites + .get(userId as Snowflake) + ?.delete(`Companion Channel for ${oldChannel!.id} | User Left`); } for (const [channelId, permissions] of permsToSet) { - const channel = pluginData.guild.channels.cache.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel || !(channel instanceof TextChannel)) continue; await channel.updateOverwrite(userId, new Permissions(BigInt(permissions)).serialize(), { reason: `Companion Channel for ${voiceChannel!.id} | User Joined`, diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 83057133..c045469f 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; @@ -73,7 +73,7 @@ export const AddCounterCmd = typedGuildCommand()({ return; } - const potentialChannel = pluginData.guild.channels.resolve(reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 2f4d8def..af8dc9ad 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -28,15 +28,13 @@ export const ResetAllCounterValuesCmd = typedGuildCommand()( } const counterName = counter.name || args.counterName; - const confirmed = await confirm( - message.channel, - message.author.id, - trimMultilineString(` + const confirmed = await confirm(message.channel, message.author.id, { + content: trimMultilineString(` Do you want to reset **ALL** values for counter **${counterName}**? This will reset the counter for **all** users and channels. **Note:** This will *not* trigger any triggers or counter triggers. `), - ); + }); if (!confirmed) { sendErrorMessage(pluginData, message.channel, "Cancelled"); return; diff --git a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts index 56050683..2c92d329 100644 --- a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; @@ -68,7 +68,7 @@ export const ResetCounterCmd = typedGuildCommand()({ return; } - const potentialChannel = pluginData.guild.channels.resolve(reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 0e78a4bc..5052c23c 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; @@ -73,7 +73,7 @@ export const SetCounterCmd = typedGuildCommand()({ return; } - const potentialChannel = pluginData.guild.channels.resolve(reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index ff14c339..26a2fe7c 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { typedGuildCommand } from "knub"; import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; @@ -67,7 +67,7 @@ export const ViewCounterCmd = typedGuildCommand()({ return; } - const potentialChannel = pluginData.guild.channels.resolve(reply.content); + const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); return; diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts index 63c381cc..11974a7a 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { convertDelayStringToMS, noop, tDelayString } from "../../../utils"; @@ -18,7 +19,7 @@ export async function makeRoleMentionableAction( event: TCustomEvent, eventData: any, ) { - const role = pluginData.guild.roles.cache.get(action.role); + const role = pluginData.guild.roles.cache.get(action.role as Snowflake); if (!role) { throw new ActionError(`Unknown role: ${role}`); } diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts index de0a413c..505cb3f7 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { ActionError } from "../ActionError"; @@ -16,7 +17,7 @@ export async function makeRoleUnmentionableAction( event: TCustomEvent, eventData: any, ) { - const role = pluginData.guild.roles.cache.get(action.role); + const role = pluginData.guild.roles.cache.get(action.role as Snowflake); if (!role) { throw new ActionError(`Unknown role: ${role}`); } diff --git a/backend/src/plugins/CustomEvents/actions/messageAction.ts b/backend/src/plugins/CustomEvents/actions/messageAction.ts index 9fa91ba0..90630f1f 100644 --- a/backend/src/plugins/CustomEvents/actions/messageAction.ts +++ b/backend/src/plugins/CustomEvents/actions/messageAction.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { renderTemplate } from "../../../templateFormatter"; @@ -18,7 +18,7 @@ export async function messageAction( values: any, ) { const targetChannelId = await renderTemplate(action.channel, values, false); - const targetChannel = pluginData.guild.channels.cache.get(targetChannelId); + const targetChannel = pluginData.guild.channels.cache.get(targetChannelId as Snowflake); if (!targetChannel) throw new ActionError("Unknown target channel"); if (!(targetChannel instanceof TextChannel)) throw new ActionError("Target channel is not a text channel"); diff --git a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts index 176a768e..fd4d756c 100644 --- a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts +++ b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts @@ -1,4 +1,4 @@ -import { VoiceChannel } from "discord.js"; +import { Snowflake, VoiceChannel } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { canActOn } from "../../../pluginUtils"; @@ -30,7 +30,7 @@ export async function moveToVoiceChannelAction( } const targetChannelId = await renderTemplate(action.channel, values, false); - const targetChannel = pluginData.guild.channels.cache.get(targetChannelId); + const targetChannel = pluginData.guild.channels.cache.get(targetChannelId as Snowflake); if (!targetChannel) throw new ActionError("Unknown target channel"); if (!(targetChannel instanceof VoiceChannel)) throw new ActionError("Target channel is not a voice channel"); diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index 4203d2a8..e9497ed1 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -1,3 +1,4 @@ +import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { ActionError } from "../ActionError"; @@ -24,7 +25,7 @@ export async function setChannelPermissionOverridesAction( event: TCustomEvent, eventData: any, ) { - const channel = pluginData.guild.channels.cache.get(action.channel); + const channel = pluginData.guild.channels.cache.get(action.channel as Snowflake) as TextChannel; if (!channel) { throw new ActionError(`Unknown channel: ${action.channel}`); } diff --git a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts index d1f5e18c..55b86bdc 100644 --- a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts +++ b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { locateUserEvt } from "../types"; import { sendAlerts } from "../utils/sendAlerts"; @@ -17,7 +17,7 @@ export const VoiceStateUpdateAlertEvt = locateUserEvt({ const voiceChannel = meta.args.oldState.channel!; triggeredAlerts.forEach(alert => { - const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id) as TextChannel; + const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel; txtChannel.send( `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`<#!${voiceChannel.id}>\``, ); diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index 7912d7b8..312adda2 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,4 +1,4 @@ -import { GuildMember, TextChannel } from "discord.js"; +import { GuildMember, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { sendErrorMessage } from "../../../pluginUtils"; import { LocateUserPluginType } from "../types"; @@ -9,7 +9,7 @@ export async function moveMember( target: GuildMember, errorChannel: TextChannel, ) { - const modMember: GuildMember = await pluginData.guild.members.fetch(toMoveID); + const modMember: GuildMember = await pluginData.guild.members.fetch(toMoveID as Snowflake); if (modMember.voice.channelID != null) { try { await modMember.edit({ diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts index 44edd232..67f865bf 100644 --- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { resolveMember } from "../../../utils"; import { LocateUserPluginType } from "../types"; @@ -12,7 +12,7 @@ export async function sendAlerts(pluginData: GuildPluginData { const prepend = `<@!${alert.requestor_id}>, an alert requested by you has triggered!\nReminder: \`${alert.body}\`\n`; - const txtChannel = pluginData.guild.channels.resolve(alert.channel_id) as TextChannel; + const txtChannel = pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel; sendWhere(pluginData, member, txtChannel, prepend); if (alert.active) { moveMember(pluginData, alert.requestor_id, member, txtChannel); diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index b9cc9cb8..77b7dd56 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -28,7 +28,6 @@ export async function sendWhere( channel.send({ content: prepend + `<@${member.id}> is in the following channel: \`${voice.name}\` ${getInviteLink(invite)}`, allowedMentions: { parse: ["users"] }, - split: false, }); } } diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 4c6c7252..0fdce60e 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -1,4 +1,4 @@ -import { MessageMentionTypes, TextChannel } from "discord.js"; +import { MessageMentionTypes, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -19,7 +19,7 @@ export async function log(pluginData: GuildPluginData, type: Log const typeStr = LogType[type]; logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) { - const channel = pluginData.guild.channels.cache.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel || !(channel instanceof TextChannel)) continue; if ((opts.include && opts.include.includes(typeStr)) || (opts.exclude && !opts.exclude.includes(typeStr))) { @@ -45,7 +45,7 @@ export async function log(pluginData: GuildPluginData, type: Log if (opts.excluded_roles) { for (const value of Object.values(data || {})) { if (value instanceof SavedMessage) { - const member = pluginData.guild.members.cache.get(value.user_id); + const member = pluginData.guild.members.cache.get(value.user_id as Snowflake); for (const role of member?.roles.cache || []) { if (opts.excluded_roles.includes(role[0])) { continue logChannelLoop; diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index 3c3fb922..637e6cd3 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -1,4 +1,4 @@ -import { MessageAttachment } from "discord.js"; +import { MessageAttachment, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { SavedMessage } from "../../../data/entities/SavedMessage"; @@ -9,7 +9,7 @@ import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake); if (user) { // Replace attachment URLs with media URLs diff --git a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts index 6e23315a..500b5cb7 100644 --- a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -5,7 +6,7 @@ import { getBaseUrl } from "../../../pluginUtils"; import { LogsPluginType } from "../types"; export async function onMessageDeleteBulk(pluginData: GuildPluginData, savedMessages: SavedMessage[]) { - const channel = pluginData.guild.channels.cache.get(savedMessages[0].channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessages[0].channel_id as Snowflake); const archiveId = await pluginData.state.archives.createFromSavedMessages(savedMessages, pluginData.guild); const archiveUrl = pluginData.state.archives.getUrl(getBaseUrl(pluginData), archiveId); const authorIds = Array.from(new Set(savedMessages.map(item => `\`${item.user_id}\``))).join(", "); diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index f83fe54a..2b03d53a 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -1,4 +1,4 @@ -import { MessageEmbed } from "discord.js"; +import { MessageEmbed, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import cloneDeep from "lodash.clonedeep"; import { SavedMessage } from "../../../data/entities/SavedMessage"; @@ -47,7 +47,7 @@ export async function onMessageUpdate( } const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake); pluginData.state.guildLogs.log(LogType.MESSAGE_EDIT, { user: stripObjectToScalars(user), diff --git a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts index 1ce82aa9..85b2d637 100644 --- a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel } from "discord.js"; +import { Message, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { MessageSaverPluginType } from "./types"; @@ -15,7 +15,7 @@ export async function saveMessagesToDB( let thisMsg: Message; try { - thisMsg = await channel.messages.fetch(id); + thisMsg = await channel.messages.fetch(id as Snowflake); if (!thisMsg) { failed.push(id); diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 12ce028d..6b06c56c 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -71,7 +71,7 @@ export const CasesModCmd = modActionsCmd({ ], }; - return { embed }; + return { embeds: [embed] }; }, { limitToUserId: msg.author.id, diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index 2b96257e..ac1d2eb5 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -12,13 +12,13 @@ import { modActionsCmd } from "../types"; const opts = { expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), hidden: ct.bool({ option: true, isSwitch: true, shortcut: "h" }), - reverseFilters: ct.switchOption({ shortcut: "r" }), - notes: ct.switchOption({ shortcut: "n" }), - warns: ct.switchOption({ shortcut: "w" }), - mutes: ct.switchOption({ shortcut: "m" }), - unmutes: ct.switchOption({ shortcut: "um" }), - bans: ct.switchOption({ shortcut: "b" }), - unbans: ct.switchOption({ shortcut: "ub" }), + reverseFilters: ct.switchOption({ def: false, shortcut: "r" }), + notes: ct.switchOption({ def: false, shortcut: "n" }), + warns: ct.switchOption({ def: false, shortcut: "w" }), + mutes: ct.switchOption({ def: false, shortcut: "m" }), + unmutes: ct.switchOption({ def: false, shortcut: "um" }), + bans: ct.switchOption({ def: false, shortcut: "b" }), + unbans: ct.switchOption({ def: false, shortcut: "ub" }), }; export const CasesUserCmd = modActionsCmd({ @@ -127,7 +127,7 @@ export const CasesUserCmd = modActionsCmd({ ], }; - msg.channel.send({ embed }); + msg.channel.send({ embeds: [embed] }); } } } diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 64b2e7d0..931ce82c 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -21,7 +21,7 @@ export const DeleteCaseCmd = modActionsCmd({ signature: { caseNumber: ct.number({ rest: true }), - force: ct.switchOption({ shortcut: "f" }), + force: ct.switchOption({ def: false, shortcut: "f" }), }, async run({ pluginData, message, args }) { @@ -49,8 +49,8 @@ export const DeleteCaseCmd = modActionsCmd({ const cases = pluginData.getPlugin(CasesPlugin); const embedContent = await cases.getCaseEmbed(theCase); message.channel.send({ + ...embedContent, content: "Delete the following case? Answer 'Yes' to continue, 'No' to cancel.", - embed: embedContent.embed, }); const reply = await helpers.waitForReply( diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index a4ea8460..b84c2283 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; @@ -66,7 +67,7 @@ export const ForcebanCmd = modActionsCmd({ try { // FIXME: Use banUserId()? - await pluginData.guild.bans.create(user.id, { + await pluginData.guild.bans.create(user.id as Snowflake, { days: 1, reason: reason != null ? encodeURIComponent(reason) : undefined, }); diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index c93933f0..5a9be476 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; @@ -49,7 +50,7 @@ export const UnbanCmd = modActionsCmd({ try { ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); - await pluginData.guild.bans.remove(user.id, reason != null ? encodeURIComponent(reason) : undefined); + await pluginData.guild.bans.remove(user.id as Snowflake, reason != null ? encodeURIComponent(reason) : undefined); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to unban member; are you sure they're banned?"); return; diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index fc9cd29e..b8925aa1 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -1,4 +1,4 @@ -import { Permissions, TextChannel } from "discord.js"; +import { Permissions, Snowflake, TextChannel } from "discord.js"; import { LogType } from "../../../data/LogType"; import { resolveMember } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; @@ -22,7 +22,7 @@ export const PostAlertOnMemberJoinEvt = modActionsEvt({ const logs = pluginData.getPlugin(LogsPlugin); if (actions.length) { - const alertChannel = pluginData.guild.channels.cache.get(alertChannelId); + const alertChannel = pluginData.guild.channels.cache.get(alertChannelId as Snowflake); if (!alertChannel) { logs.log(LogType.BOT_ALERT, { body: `Unknown \`alert_channel\` configured for \`mod_actions\`: \`${alertChannelId}\``, diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index 9c44be59..101014b9 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -1,4 +1,4 @@ -import { DiscordAPIError, User } from "discord.js"; +import { DiscordAPIError, Snowflake, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -77,7 +77,7 @@ export async function banUserId( ignoreEvent(pluginData, IgnoredEventType.Ban, userId); try { const deleteMessageDays = Math.min(30, Math.max(0, banOptions.deleteMessageDays ?? 1)); - await pluginData.guild.bans.create(userId, { + await pluginData.guild.bans.create(userId as Snowflake, { days: deleteMessageDays, reason: reason != null ? encodeURIComponent(reason) : undefined, }); diff --git a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts index a4d9d75c..a94a848a 100644 --- a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts +++ b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { UserNotificationMethod } from "../../../utils"; import { ModActionsPluginType } from "../types"; @@ -15,7 +15,7 @@ export function getDefaultContactMethods( } if (config[`message_on_${type}`] && config.message_channel) { - const channel = pluginData.guild.channels.cache.get(config.message_channel); + const channel = pluginData.guild.channels.cache.get(config.message_channel as Snowflake); if (channel instanceof TextChannel) { methods.push({ type: "channel", diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index de419db4..60fe37e3 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -1,4 +1,4 @@ -import { Permissions } from "discord.js"; +import { Permissions, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { isDiscordHTTPError, isDiscordRESTError, SECONDS, sleep } from "../../../utils"; @@ -21,7 +21,7 @@ export async function isBanned( try { const potentialBan = await Promise.race([ - pluginData.guild.bans.fetch({ user: userId }).catch(() => null), + pluginData.guild.bans.fetch({ user: userId as Snowflake }).catch(() => null), sleep(timeout), ]); return potentialBan != null; diff --git a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts index 510c9625..f983dd3b 100644 --- a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts +++ b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -30,7 +31,10 @@ export async function outdatedTempbansLoop(pluginData: GuildPluginData()({ hasMutedRole(pluginData) { return (member: GuildMember) => { const muteRole = pluginData.config.get().mute_role; - return muteRole ? member.roles.cache.has(muteRole) : false; + return muteRole ? member.roles.cache.has(muteRole as Snowflake) : false; }; }, diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 6eb24da0..77fc0f85 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,4 +1,4 @@ -import { User } from "discord.js"; +import { Snowflake, User } from "discord.js"; import { sendSuccessMessage } from "../../../pluginUtils"; import { mutesCmd } from "../types"; @@ -19,7 +19,7 @@ export const ClearBannedMutesCmd = mutesCmd({ let cleared = 0; for (const mute of activeMutes) { - if (bannedIds.includes(mute.user_id)) { + if (bannedIds.includes(mute.user_id as Snowflake)) { await pluginData.state.mutes.clear(mute.user_id); cleared++; } diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index eec295c5..0dbef291 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { sendSuccessMessage } from "../../../pluginUtils"; import { resolveMember } from "../../../utils"; import { mutesCmd } from "../types"; @@ -19,7 +20,7 @@ export const ClearMutesWithoutRoleCmd = mutesCmd({ const member = await resolveMember(pluginData.client, pluginData.guild, mute.user_id); if (!member) continue; - if (!member.roles.cache.has(muteRole)) { + if (!member.roles.cache.has(muteRole as Snowflake)) { await pluginData.state.mutes.clear(mute.user_id); cleared++; } diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 47e4a4fd..666d6c94 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -1,4 +1,4 @@ -import { GuildMember, MessageActionRow, MessageButton, MessageComponentInteraction } from "discord.js"; +import { GuildMember, MessageActionRow, MessageButton, MessageComponentInteraction, Snowflake } from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; @@ -16,9 +16,9 @@ export const MutesCmd = mutesCmd({ shortcut: "a", }), - left: ct.switchOption({ shortcut: "l" }), - manual: ct.switchOption({ shortcut: "m" }), - export: ct.switchOption({ shortcut: "e" }), + left: ct.switchOption({ def: false, shortcut: "l" }), + manual: ct.switchOption({ def: false, shortcut: "m" }), + export: ct.switchOption({ def: false, shortcut: "e" }), }, async run({ pluginData, message: msg, args }) { @@ -53,7 +53,7 @@ export const MutesCmd = mutesCmd({ if (muteRole) { pluginData.guild.members.cache.forEach(member => { if (muteUserIds.has(member.id)) return; - if (member.roles.cache.has(muteRole)) manuallyMutedMembers.push(member); + if (member.roles.cache.has(muteRole as Snowflake)) manuallyMutedMembers.push(member); }); } @@ -111,7 +111,7 @@ export const MutesCmd = mutesCmd({ const muteCasesById = muteCases.reduce((map, c) => map.set(c.id, c), new Map()); lines = filteredMutes.map(mute => { - const user = pluginData.client.users.resolve(mute.user_id); + const user = pluginData.client.users.resolve(mute.user_id as Snowflake); const username = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; const theCase = muteCasesById.get(mute.case_id); const caseName = theCase ? `Case #${theCase.case_number}` : "No case"; @@ -199,7 +199,6 @@ export const MutesCmd = mutesCmd({ new MessageButton() .setStyle("SECONDARY") .setEmoji("⬅") - .setType("BUTTON") .setCustomID(`previousButton:${idMod}`), ); @@ -207,7 +206,6 @@ export const MutesCmd = mutesCmd({ new MessageButton() .setStyle("SECONDARY") .setEmoji("➡") - .setType("BUTTON") .setCustomID(`nextButton:${idMod}`), ); @@ -215,13 +213,14 @@ export const MutesCmd = mutesCmd({ await listMessage.edit({ components: [row] }); const filter = (iac: MessageComponentInteraction) => iac.message.id === listMessage.id; - const collector = listMessage.createMessageComponentInteractionCollector(filter, { + const collector = listMessage.createMessageComponentInteractionCollector({ + filter, time: stopCollectionDebounce, }); collector.on("collect", async (interaction: MessageComponentInteraction) => { if (msg.author.id !== interaction.user.id) { - interaction.reply(`You are not permitted to use these buttons.`, { ephemeral: true }); + interaction.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }); } else { collector.resetTimer(); if (interaction.customID === `previousButton:${idMod}` && currentPage > 1) { diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index b818bdfb..9217e1a2 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { resolveMember, stripObjectToScalars, UnknownUser } from "../../../utils"; @@ -23,7 +24,7 @@ export async function clearExpiredMutes(pluginData: GuildPluginData, member: GuildMember): boolean { const muteRole = pluginData.config.get().mute_role; - return muteRole ? member.roles.cache.has(muteRole) : false; + return muteRole ? member.roles.cache.has(muteRole as Snowflake) : false; } diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index d944cfe0..3aa9fc95 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -1,4 +1,4 @@ -import { TextChannel, User } from "discord.js"; +import { Snowflake, TextChannel, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -86,7 +86,7 @@ export async function muteUser( } // Apply mute role if it's missing - if (!currentUserRoles.includes(muteRole)) { + if (!currentUserRoles.includes(muteRole as Snowflake)) { try { await member.roles.add(muteRole); } catch (e) { @@ -125,7 +125,7 @@ export async function muteUser( if (moveToVoiceChannel || cfg.kick_from_voice_channel) { // TODO: Add back the voiceState check once we figure out how to get voice state for guild members that are loaded on-demand try { - await member.edit({ channel: moveToVoiceChannel }); + await member.edit({ channel: moveToVoiceChannel as Snowflake }); } catch {} // tslint:disable-line } } @@ -172,7 +172,8 @@ export async function muteUser( } const useChannel = existingMute ? config.message_on_update : config.message_on_mute; - const channel = config.message_channel && pluginData.guild.channels.cache.get(config.message_channel); + const channel = + config.message_channel && pluginData.guild.channels.cache.get(config.message_channel as Snowflake); if (useChannel && channel instanceof TextChannel) { contactMethods.push({ type: "channel", channel }); } diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index aa896b43..437baf31 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -35,7 +36,7 @@ export async function unmuteUser( const lock = await pluginData.locks.acquire(memberRolesLock(member)); const muteRole = pluginData.config.get().mute_role; - if (muteRole && member.roles.cache.has(muteRole)) { + if (muteRole && member.roles.cache.has(muteRole as Snowflake)) { await member.roles.remove(muteRole); } if (existingMute?.roles_to_restore) { @@ -43,7 +44,7 @@ export async function unmuteUser( let newRoles: string[] = member.roles.cache.keyArray(); newRoles = muteRole && newRoles.includes(muteRole) ? newRoles.splice(newRoles.indexOf(muteRole), 1) : newRoles; for (const toRestore of existingMute.roles_to_restore) { - if (guildRoles.has(toRestore) && toRestore !== muteRole) newRoles.push(toRestore); + if (guildRoles.has(toRestore as Snowflake) && toRestore !== muteRole) newRoles.push(toRestore); } await member.roles.set(newRoles); } @@ -83,7 +84,7 @@ export async function unmuteUser( }); // Log the action - const mod = pluginData.client.users.fetch(modId); + const mod = pluginData.client.users.fetch(modId as Snowflake); if (unmuteTime) { pluginData.state.serverLogs.log(LogType.MEMBER_TIMED_UNMUTE, { mod: stripObjectToScalars(mod), diff --git a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts index 9d137828..8730b588 100644 --- a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { PingableRole } from "../../../data/entities/PingableRole"; import { PingableRolesPluginType } from "../types"; @@ -7,7 +8,7 @@ export function disablePingableRoles( pingableRoles: PingableRole[], ) { for (const pingableRole of pingableRoles) { - const role = pluginData.guild.roles.cache.get(pingableRole.role_id); + const role = pluginData.guild.roles.cache.get(pingableRole.role_id as Snowflake); if (!role) continue; role.edit( diff --git a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts index 65cc5eb6..a7c40e78 100644 --- a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { PingableRole } from "../../../data/entities/PingableRole"; import { PingableRolesPluginType } from "../types"; @@ -7,7 +8,7 @@ export function enablePingableRoles( pingableRoles: PingableRole[], ) { for (const pingableRole of pingableRoles) { - const role = pluginData.guild.roles.cache.get(pingableRole.role_id); + const role = pluginData.guild.roles.cache.get(pingableRole.role_id as Snowflake); if (!role) continue; role.edit( diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index add44ec7..1835abca 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { postCmd } from "../types"; @@ -25,9 +25,12 @@ export const EditCmd = postCmd({ return; } - (pluginData.guild.channels.cache.get(savedMessage.channel_id) as TextChannel).messages.edit(savedMessage.id, { - content: formatContent(args.content), - }); + (pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake) as TextChannel).messages.edit( + savedMessage.id as Snowflake, + { + content: formatContent(args.content), + }, + ); sendSuccessMessage(pluginData, msg.channel, "Message edited"); }, }); diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 992f0596..a8155d98 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -1,4 +1,4 @@ -import { MessageEmbed, TextChannel } from "discord.js"; +import { MessageEmbed, Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { trimLines } from "../../../utils"; @@ -47,9 +47,12 @@ export const EditEmbedCmd = postCmd({ if (content) embed.description = formatContent(content); if (color) embed.color = color; - (pluginData.guild.channels.cache.get(savedMessage.channel_id) as TextChannel).messages.edit(savedMessage.id, { - embed, - }); + (pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake) as TextChannel).messages.edit( + savedMessage.id as Snowflake, + { + embeds: [embed], + }, + ); await sendSuccessMessage(pluginData, msg.channel, "Embed edited"); if (args.content) { diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index 4066880a..9d4b67f4 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -38,7 +38,7 @@ export async function postMessage( }; } - const createdMsg = await channel.send(content, file); + const createdMsg = await channel.send({ ...content, files: [file] }); pluginData.state.savedMessages.setPermanent(createdMsg.id); if (downloadedAttachment) { diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts index 37f8e553..85155f5b 100644 --- a/backend/src/plugins/Post/util/scheduledPostLoop.ts +++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts @@ -1,4 +1,4 @@ -import { TextChannel, User } from "discord.js"; +import { Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { LogType } from "../../../data/LogType"; @@ -12,10 +12,10 @@ const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS; export async function scheduledPostLoop(pluginData: GuildPluginData) { const duePosts = await pluginData.state.scheduledPosts.getDueScheduledPosts(); for (const post of duePosts) { - const channel = pluginData.guild.channels.cache.get(post.channel_id); + const channel = pluginData.guild.channels.cache.get(post.channel_id as Snowflake); if (channel instanceof TextChannel) { const [username, discriminator] = post.author_name.split("#"); - const author: User = (await pluginData.client.users.fetch(post.author_id)) || { + const author: User = (await pluginData.client.users.fetch(post.author_id as Snowflake)) || { id: post.author_id, username, discriminator, diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index 6653c010..dc68a245 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -1,4 +1,4 @@ -import { Message } from "discord.js"; +import { Message, Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { isDiscordRESTError } from "../../../utils"; @@ -23,7 +23,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ let targetMessage: Message; try { - targetMessage = await args.message.channel.messages.fetch(args.message.messageId); + targetMessage = await args.message.channel.messages.fetch(args.message.messageId as Snowflake); } catch (err) { if (isDiscordRESTError(err) && err.code === 50001) { sendErrorMessage(pluginData, msg.channel, "Missing access to the specified message"); diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index e233e7a9..c118b973 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { canUseEmoji, isDiscordRESTError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; @@ -39,7 +40,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ let targetMessage; try { - targetMessage = await args.message.channel.messages.fetch(args.message.messageId).catch(noop); + targetMessage = await args.message.channel.messages.fetch(args.message.messageId as Snowflake).catch(noop); } catch (e) { if (isDiscordRESTError(e)) { sendErrorMessage(pluginData, msg.channel, `Error ${e.code} while getting message: ${e.message}`); @@ -94,7 +95,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ return; } - if (!pluginData.guild.roles.cache.has(pair[1])) { + if (!pluginData.guild.roles.cache.has(pair[1] as Snowflake)) { sendErrorMessage(pluginData, msg.channel, `Unknown role ${pair[1]}`); return; } diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index 5f602921..84f809d8 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -1,4 +1,4 @@ -import { MessageActionRow, MessageButton, TextChannel } from "discord.js"; +import { MessageActionRow, MessageButton, Snowflake, TextChannel } from "discord.js"; import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { reactionRolesCmd } from "../types"; @@ -38,12 +38,11 @@ export const PostButtonRolesCmd = reactionRolesCmd({ const btn = new MessageButton() .setLabel(button.label ?? "") .setStyle(button.style ?? "PRIMARY") - .setType("BUTTON") .setCustomID(customId) .setDisabled(button.disabled ?? false); if (button.emoji) { - const emo = pluginData.client.emojis.resolve(button.emoji) ?? button.emoji; + const emo = pluginData.client.emojis.resolve(button.emoji as Snowflake) ?? button.emoji; btn.setEmoji(emo); } diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index a5feb154..47266478 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -87,5 +87,5 @@ export const ButtonInteractionEvt = reactionRolesEvt({ }); async function sendEphemeralReply(interaction: MessageComponentInteraction, message: string) { - await interaction.reply(message, { ephemeral: true }); + await interaction.reply({ content: message, ephemeral: true }); } diff --git a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts index 1e2f88ff..41ec5710 100644 --- a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts +++ b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; import { resolveMember } from "../../../utils"; @@ -25,8 +26,8 @@ export async function addMemberPendingRoleChange( if (member) { const newRoleIds = new Set(member.roles.cache.keyArray()); for (const change of newPendingRoleChangeObj.changes) { - if (change.mode === "+") newRoleIds.add(change.roleId); - else newRoleIds.delete(change.roleId); + if (change.mode === "+") newRoleIds.add(change.roleId as Snowflake); + else newRoleIds.delete(change.roleId as Snowflake); } try { diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index f3f6c9c5..c9e1e0f7 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { ReactionRole } from "../../../data/entities/ReactionRole"; import { LogType } from "../../../data/LogType"; @@ -17,7 +17,7 @@ export async function applyReactionRoleReactionsToMessage( messageId: string, reactionRoles: ReactionRole[], ): Promise { - const channel = pluginData.guild.channels.cache.get(channelId) as TextChannel; + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake) as TextChannel; if (!channel) return; const errors: string[] = []; @@ -25,7 +25,7 @@ export async function applyReactionRoleReactionsToMessage( let targetMessage; try { - targetMessage = await channel.messages.fetch(messageId); + targetMessage = await channel.messages.fetch(messageId as Snowflake); } catch (e) { if (isDiscordRESTError(e)) { if (e.code === 10008) { diff --git a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts index c59ae400..45205035 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts @@ -1,4 +1,4 @@ -import { MessageButton, MessageActionRow, MessageComponentInteraction } from "discord.js"; +import { MessageButton, MessageActionRow, MessageComponentInteraction, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; @@ -33,12 +33,11 @@ export async function handleOpenMenu( const btn = new MessageButton() .setLabel(menuButton.label ?? "") .setStyle("PRIMARY") - .setType("BUTTON") .setCustomID(customId) .setDisabled(menuButton.disabled ?? false); if (menuButton.emoji) { - const emo = pluginData.client.emojis.resolve(menuButton.emoji) ?? menuButton.emoji; + const emo = pluginData.client.emojis.resolve(menuButton.emoji as Snowflake) ?? menuButton.emoji; btn.setEmoji(emo); } menuButtons.push(btn); diff --git a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts index 26eae6f2..9a758d0a 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { ReactionRolesPluginType } from "../types"; import { ButtonMenuActions } from "./buttonMenuActions"; @@ -5,7 +6,7 @@ import { ButtonMenuActions } from "./buttonMenuActions"; export const BUTTON_CONTEXT_SEPARATOR = "::"; export async function getButtonAction(pluginData: GuildPluginData, roleOrMenu: string) { - if (await pluginData.guild.roles.fetch(roleOrMenu)) { + if (await pluginData.guild.roles.fetch(roleOrMenu as Snowflake).catch(() => false)) { return ButtonMenuActions.MODIFY_ROLE; } else { return ButtonMenuActions.OPEN_MENU; diff --git a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts index 9678ce3b..b5fc6257 100644 --- a/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts +++ b/backend/src/plugins/Reminders/utils/postDueRemindersLoop.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { disableLinkPreviews } from "knub/dist/helpers"; @@ -12,7 +12,7 @@ const MAX_TRIES = 3; export async function postDueRemindersLoop(pluginData: GuildPluginData) { const pendingReminders = await pluginData.state.reminders.getDueReminders(); for (const reminder of pendingReminders) { - const channel = pluginData.guild.channels.cache.get(reminder.channel_id); + const channel = pluginData.guild.channels.cache.get(reminder.channel_id as Snowflake); if (channel && channel instanceof TextChannel) { try { // Only show created at date if one exists @@ -25,14 +25,14 @@ export async function postDueRemindersLoop(pluginData: GuildPluginData: ${reminder.body} \n\`Set at ${reminder.created_at} (${result} ago)\``, ), allowedMentions: { - users: [reminder.user_id], + users: [reminder.user_id as Snowflake], }, }); } else { await channel.send({ content: disableLinkPreviews(`Reminder for <@!${reminder.user_id}>: ${reminder.body}`), allowedMentions: { - users: [reminder.user_id], + users: [reminder.user_id as Snowflake], }, }); } diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index 67f75d13..9943a9bb 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -1,4 +1,4 @@ -import { Role } from "discord.js"; +import { Role, Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; @@ -31,7 +31,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ const hasUnknownRoles = matchedRoleIds.length !== roleNames.length; const rolesToAdd: Map = Array.from(matchedRoleIds.values()) - .map(id => pluginData.guild.roles.cache.get(id)!) + .map(id => pluginData.guild.roles.cache.get(id as Snowflake)!) .filter(Boolean) .reduce((map, role) => { map.set(role.id, role); @@ -68,10 +68,10 @@ export const RoleAddCmd = selfGrantableRolesCmd({ newRoleIds.delete(roleId); rolesToAdd.delete(roleId); - if (msg.member.roles.cache.has(roleId)) { - removed.add(pluginData.guild.roles.cache.get(roleId)!); + if (msg.member.roles.cache.has(roleId as Snowflake)) { + removed.add(pluginData.guild.roles.cache.get(roleId as Snowflake)!); } else { - skipped.add(pluginData.guild.roles.cache.get(roleId)!); + skipped.add(pluginData.guild.roles.cache.get(roleId as Snowflake)!); } } } diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts index 438abbd1..b1bf6899 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts @@ -47,6 +47,6 @@ export const RoleHelpCmd = selfGrantableRolesCmd({ color: parseInt("42bff4", 16), }; - msg.channel.send({ embed: helpEmbed }); + msg.channel.send({ embeds: [helpEmbed] }); }, }); diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index b1413050..0ba51766 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; @@ -27,7 +28,9 @@ export const RoleRemoveCmd = selfGrantableRolesCmd({ const roleNames = normalizeRoleNames(splitRoleNames(args.roleNames)); const matchedRoleIds = findMatchingRoles(roleNames, applyingEntries); - const rolesToRemove = Array.from(matchedRoleIds.values()).map(id => pluginData.guild.roles.cache.get(id)!); + const rolesToRemove = Array.from(matchedRoleIds.values()).map( + id => pluginData.guild.roles.cache.get(id as Snowflake)!, + ); const roleIdsToRemove = rolesToRemove.map(r => r.id); // Remove the roles diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 9ca3d0c3..94ec6dc3 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -1,4 +1,4 @@ -import { GuildChannel, Permissions, TextChannel } from "discord.js"; +import { GuildChannel, Permissions, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; @@ -11,7 +11,7 @@ export async function applyBotSlowmodeToUserId( userId: string, ) { // Deny sendMessage permission from the user. If there are existing permission overwrites, take those into account. - const existingOverride = channel.permissionOverwrites.get(userId); + const existingOverride = channel.permissionOverwrites.get(userId as Snowflake); const newDeniedPermissions = (existingOverride ? existingOverride.deny.bitfield : 0n) | Permissions.FLAGS.SEND_MESSAGES; const newAllowedPermissions = @@ -22,7 +22,7 @@ export async function applyBotSlowmodeToUserId( { id: userId, allow: newAllowedPermissions, deny: newDeniedPermissions, type: "member" }, ]); } catch (e) { - const user = pluginData.client.users.fetch(userId) || new UnknownUser({ id: userId }); + const user = pluginData.client.users.fetch(userId as Snowflake) || new UnknownUser({ id: userId }); if (isDiscordRESTError(e) && e.code === 50013) { logger.warn( diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index 4f7cb4c6..c0943900 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,4 +1,4 @@ -import { GuildChannel, TextChannel } from "discord.js"; +import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { SlowmodePluginType } from "../types"; @@ -13,7 +13,7 @@ export async function clearBotSlowmodeFromUserId( // Previously we diffed the overrides so we could clear the "send messages" override without touching other // overrides. Unfortunately, it seems that was a bit buggy - we didn't always receive the event for the changed // overrides and then we also couldn't diff against them. For consistency's sake, we just delete the override now. - await channel.permissionOverwrites.get(userId)?.delete(); + await channel.permissionOverwrites.get(userId as Snowflake)?.delete(); } catch (e) { if (!force) { throw e; diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index 83439358..dd7ced57 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -1,4 +1,4 @@ -import { GuildChannel, TextChannel } from "discord.js"; +import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; @@ -9,7 +9,7 @@ import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; export async function clearExpiredSlowmodes(pluginData: GuildPluginData) { const expiredSlowmodeUsers = await pluginData.state.slowmodes.getExpiredSlowmodeUsers(); for (const user of expiredSlowmodeUsers) { - const channel = pluginData.guild.channels.cache.get(user.channel_id); + const channel = pluginData.guild.channels.cache.get(user.channel_id as Snowflake); if (!channel) { await pluginData.state.slowmodes.clearSlowmodeUser(user.channel_id, user.user_id); continue; @@ -20,7 +20,8 @@ export async function clearExpiredSlowmodes(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; - const channel = pluginData.guild.channels.cache.get(msg.channel_id) as TextChannel; + const channel = pluginData.guild.channels.cache.get(msg.channel_id as Snowflake) as TextChannel; if (!channel) return; // Don't apply slowmode if the lock was interrupted earlier (e.g. the message was caught by word filters) @@ -49,7 +49,7 @@ export async function onMessageCreate(pluginData: GuildPluginData pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE, id)); - (pluginData.guild.channels.cache.get(savedMessage.channel_id)! as TextChannel).bulkDelete(msgIds).catch(noop); + (pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake)! as TextChannel) + .bulkDelete(msgIds as Snowflake[]) + .catch(noop); } // Store the ID of the last handled message @@ -146,7 +148,7 @@ export async function logAndDetectMessageSpam( clearRecentUserActions(pluginData, type, savedMessage.user_id, savedMessage.channel_id); // Generate a log from the detected messages - const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id); + const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake); const archiveUrl = await saveSpamArchives(pluginData, uniqueMessages); // Create a case diff --git a/backend/src/plugins/Spam/util/logCensor.ts b/backend/src/plugins/Spam/util/logCensor.ts index cb503da4..1b09c16e 100644 --- a/backend/src/plugins/Spam/util/logCensor.ts +++ b/backend/src/plugins/Spam/util/logCensor.ts @@ -1,10 +1,11 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { RecentActionType, SpamPluginType } from "../types"; import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam"; export async function logCensor(pluginData: GuildPluginData, savedMessage: SavedMessage) { - const member = pluginData.guild.members.cache.get(savedMessage.user_id); + const member = pluginData.guild.members.cache.get(savedMessage.user_id as Snowflake); const config = await pluginData.config.getMatchingConfig({ userId: savedMessage.user_id, channelId: savedMessage.channel_id, diff --git a/backend/src/plugins/Spam/util/onMessageCreate.ts b/backend/src/plugins/Spam/util/onMessageCreate.ts index 17410a19..769fe50d 100644 --- a/backend/src/plugins/Spam/util/onMessageCreate.ts +++ b/backend/src/plugins/Spam/util/onMessageCreate.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils"; @@ -7,7 +8,7 @@ import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam"; export async function onMessageCreate(pluginData: GuildPluginData, savedMessage: SavedMessage) { if (savedMessage.is_bot) return; - const member = pluginData.guild.members.cache.get(savedMessage.user_id); + const member = pluginData.guild.members.cache.get(savedMessage.user_id as Snowflake); const config = await pluginData.config.getMatchingConfig({ userId: savedMessage.user_id, channelId: savedMessage.channel_id, diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index 5f79a3bb..98c5c698 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { starboardCmd } from "../types"; @@ -23,7 +23,7 @@ export const MigratePinsCmd = starboardCmd({ return; } - const starboardChannel = pluginData.guild.channels.cache.get(starboard.channel_id); + const starboardChannel = pluginData.guild.channels.cache.get(starboard.channel_id as Snowflake); if (!starboardChannel || !(starboardChannel instanceof TextChannel)) { sendErrorMessage(pluginData, msg.channel, "Starboard has an unknown/invalid channel id"); return; diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts index 0a8dc025..b0f485ce 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel } from "discord.js"; +import { Message, Snowflake, TextChannel } from "discord.js"; import { noop, resolveMember } from "../../../utils"; import { allStarboardsLock } from "../../../utils/lockNameHelpers"; import { starboardEvt } from "../types"; @@ -76,8 +76,12 @@ export const StarboardReactionAddEvt = starboardEvt({ // If the message has already been posted to this starboard, update star counts if (starboard.show_star_count) { for (const starboardMessage of starboardMessages) { - const channel = pluginData.guild.channels.cache.get(starboardMessage.starboard_channel_id) as TextChannel; - const realStarboardMessage = await channel.messages.fetch(starboardMessage.starboard_message_id); + const channel = pluginData.guild.channels.cache.get( + starboardMessage.starboard_channel_id as Snowflake, + ) as TextChannel; + const realStarboardMessage = await channel.messages.fetch( + starboardMessage.starboard_message_id as Snowflake, + ); await updateStarboardMessageStarCount( starboard, msg, diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index 068ed424..12e2785a 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel } from "discord.js"; +import { Message, MessageEmbed, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { StarboardPluginType, TStarboardOpts } from "../types"; import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; @@ -9,13 +9,13 @@ export async function saveMessageToStarboard( msg: Message, starboard: TStarboardOpts, ) { - const channel = pluginData.guild.channels.cache.get(starboard.channel_id); + const channel = pluginData.guild.channels.cache.get(starboard.channel_id as Snowflake); if (!channel) return; const starCount = (await pluginData.state.starboardReactions.getAllReactionsForMessageId(msg.id)).length; const embed = createStarboardEmbedFromMessage(msg, Boolean(starboard.copy_full_embed), starboard.color); embed.fields!.push(createStarboardPseudoFooterForMessage(starboard, msg, starboard.star_emoji![0], starCount)); - const starboardMessage = await (channel as TextChannel).send(embed); + const starboardMessage = await (channel as TextChannel).send({ embeds: [embed as MessageEmbed] }); await pluginData.state.starboardMessages.createStarboardMessage(channel.id, msg.id, starboardMessage.id); } diff --git a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts index b6375a28..04f6002c 100644 --- a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts +++ b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts @@ -23,6 +23,6 @@ export async function updateStarboardMessageStarCount( const embed = starboardMessage.embeds[0]!; embed.fields!.pop(); // Remove pseudo footer embed.fields!.push(createStarboardPseudoFooterForMessage(starboard, originalMessage, starEmoji, starCount)); // Create new pseudo footer - starboardMessage.edit({ embed }); + starboardMessage.edit({ embeds: [embed] }); }, DEBOUNCE_DELAY); } diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 2d6b83f9..220b896a 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { PluginOptions } from "knub"; import moment from "moment-timezone"; @@ -214,11 +215,14 @@ export const TagsPlugin = zeppelinGuildPlugin()({ return input; } - if (pluginData.guild.members.cache.has(input) || pluginData.client.users.resolve(input)) { + if ( + pluginData.guild.members.cache.has(input as Snowflake) || + pluginData.client.users.resolve(input as Snowflake) + ) { return `<@!${input}>`; } - if (pluginData.guild.channels.cache.has(input)) { + if (pluginData.guild.channels.cache.has(input as Snowflake)) { return `<#${input}>`; } diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index 1dcbdb65..a32ea6bc 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; import { SavedMessage } from "../../../data/entities/SavedMessage"; @@ -16,7 +16,7 @@ export async function onMessageCreate(pluginData: GuildPluginData delete the response as well const commandMsgResponse = await pluginData.state.tags.findResponseByCommandMessageId(msg.id); if (commandMsgResponse) { - const channel = pluginData.guild.channels.cache.get(msg.channel_id) as TextChannel; + const channel = pluginData.guild.channels.cache.get(msg.channel_id as Snowflake) as TextChannel; if (!channel) return; const responseMsg = await pluginData.state.savedMessages.find(commandMsgResponse.response_message_id); if (!responseMsg || responseMsg.deleted_at != null) return; - await channel.messages.delete(commandMsgResponse.response_message_id); + await channel.messages.delete(commandMsgResponse.response_message_id as Snowflake); return; } // Response was deleted -> delete the command message as well const responseMsgResponse = await pluginData.state.tags.findResponseByResponseMessageId(msg.id); if (responseMsgResponse) { - const channel = pluginData.guild.channels.cache.get(msg.channel_id) as TextChannel; + const channel = pluginData.guild.channels.cache.get(msg.channel_id as Snowflake) as TextChannel; if (!channel) return; const commandMsg = await pluginData.state.savedMessages.find(responseMsgResponse.command_message_id); if (!commandMsg || commandMsg.deleted_at != null) return; - await channel.messages.delete(responseMsgResponse.command_message_id); + await channel.messages.delete(responseMsgResponse.command_message_id as Snowflake); return; } } diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index c7489c22..c8c80620 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -25,7 +25,7 @@ export const AvatarCmd = utilityCmd({ image: { url: avatarUrl + `${extension}?size=2048` }, }; embed.title = `Avatar of ${user.username}#${user.discriminator}:`; - msg.channel.send({ embed }); + msg.channel.send({ embeds: [embed] }); } else { sendErrorMessage(pluginData, msg.channel, "Invalid user ID"); } diff --git a/backend/src/plugins/Utility/commands/BanSearchCmd.ts b/backend/src/plugins/Utility/commands/BanSearchCmd.ts index 40ff318b..25d60fb4 100644 --- a/backend/src/plugins/Utility/commands/BanSearchCmd.ts +++ b/backend/src/plugins/Utility/commands/BanSearchCmd.ts @@ -8,10 +8,10 @@ export const banSearchSignature = { page: ct.number({ option: true, shortcut: "p" }), sort: ct.string({ option: true }), - "case-sensitive": ct.switchOption({ shortcut: "cs" }), - export: ct.switchOption({ shortcut: "e" }), + "case-sensitive": ct.switchOption({ def: false, shortcut: "cs" }), + export: ct.switchOption({ def: false, shortcut: "e" }), ids: ct.switchOption(), - regex: ct.switchOption({ shortcut: "re" }), + regex: ct.switchOption({ def: false, shortcut: "re" }), }; export const BanSearchCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index 3acfb4b1..bbef9bcf 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -20,6 +20,6 @@ export const ChannelInfoCmd = utilityCmd({ return; } - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 416b6d10..e953b7f2 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel, User } from "discord.js"; +import { Message, Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; @@ -25,7 +25,7 @@ async function cleanMessages( // Delete & archive in ID order savedMessages = Array.from(savedMessages).sort((a, b) => (a.id > b.id ? 1 : -1)); - const idsToDelete = savedMessages.map(m => m.id); + const idsToDelete = savedMessages.map(m => m.id) as Snowflake[]; // Make sure the deletions aren't double logged idsToDelete.forEach(id => pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE, id)); @@ -53,9 +53,9 @@ async function cleanMessages( const opts = { user: ct.userId({ option: true, shortcut: "u" }), channel: ct.channelId({ option: true, shortcut: "c" }), - bots: ct.switchOption({ shortcut: "b" }), - "delete-pins": ct.switchOption({ shortcut: "p" }), - "has-invites": ct.switchOption({ shortcut: "i" }), + bots: ct.switchOption({ def: false, shortcut: "b" }), + "delete-pins": ct.switchOption({ def: false, shortcut: "p" }), + "has-invites": ct.switchOption({ def: false, shortcut: "i" }), match: ct.regex({ option: true, shortcut: "m" }), "to-id": ct.anyId({ option: true, shortcut: "id" }), }; @@ -75,7 +75,7 @@ export const CleanCmd = utilityCmd({ }, { count: ct.number(), - update: ct.switchOption({ shortcut: "up" }), + update: ct.switchOption({ def: false, shortcut: "up" }), ...opts, }, diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index 8cc7e784..3f7d094b 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -27,6 +27,6 @@ export const EmojiInfoCmd = utilityCmd({ return; } - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index f69aaa4b..8ca414a5 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { getChannelId, getRoleId } from "knub/dist/utils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; @@ -31,7 +32,7 @@ export const InfoCmd = utilityCmd({ signature: { value: ct.string({ required: false }), - compact: ct.switchOption({ shortcut: "c" }), + compact: ct.switchOption({ def: false, shortcut: "c" }), }, async run({ message, args, pluginData }) { @@ -45,11 +46,11 @@ export const InfoCmd = utilityCmd({ // 1. Channel if (userCfg.can_channelinfo) { const channelId = getChannelId(value); - const channel = channelId && pluginData.guild.channels.cache.get(channelId); + const channel = channelId && pluginData.guild.channels.cache.get(channelId as Snowflake); if (channel) { const embed = await getChannelInfoEmbed(pluginData, channelId!, message.author.id); if (embed) { - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -61,7 +62,7 @@ export const InfoCmd = utilityCmd({ if (guild) { const embed = await getServerInfoEmbed(pluginData, value, message.author.id); if (embed) { - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -73,7 +74,7 @@ export const InfoCmd = utilityCmd({ if (user && userCfg.can_userinfo) { const embed = await getUserInfoEmbed(pluginData, user.id, Boolean(args.compact), message.author.id); if (embed) { - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -91,7 +92,7 @@ export const InfoCmd = utilityCmd({ message.author.id, ); if (embed) { - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -106,7 +107,7 @@ export const InfoCmd = utilityCmd({ if (invite) { const embed = await getInviteInfoEmbed(pluginData, inviteCode); if (embed) { - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -119,7 +120,7 @@ export const InfoCmd = utilityCmd({ if (serverPreview) { const embed = await getServerInfoEmbed(pluginData, value, message.author.id); if (embed) { - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -128,10 +129,10 @@ export const InfoCmd = utilityCmd({ // 7. Role if (userCfg.can_roleinfo) { const roleId = getRoleId(value); - const role = roleId && pluginData.guild.roles.cache.get(roleId); + const role = roleId && pluginData.guild.roles.cache.get(roleId as Snowflake); if (role) { const embed = await getRoleInfoEmbed(pluginData, role, message.author.id); - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -142,7 +143,7 @@ export const InfoCmd = utilityCmd({ if (emojiIdMatch?.[2]) { const embed = await getEmojiInfoEmbed(pluginData, emojiIdMatch[2]); if (embed) { - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } } @@ -151,7 +152,7 @@ export const InfoCmd = utilityCmd({ // 9. Arbitrary ID if (isValidSnowflake(value) && userCfg.can_snowflake) { const embed = await getSnowflakeInfoEmbed(pluginData, value, true, message.author.id); - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); return; } diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index bceac2f3..df34123a 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -22,6 +22,6 @@ export const InviteInfoCmd = utilityCmd({ return; } - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index b54be54d..4e2e99a7 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -83,6 +83,6 @@ export const JumboCmd = utilityCmd({ }; } - msg.channel.send("", file); + msg.channel.send({ content: "", files: [file] }); }, }); diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index 04115cf6..82096250 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -31,6 +31,6 @@ export const MessageInfoCmd = utilityCmd({ return; } - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts index 38357054..b04b49a7 100644 --- a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts @@ -14,6 +14,6 @@ export const RoleInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const embed = await getRoleInfoEmbed(pluginData, args.role, message.author.id); - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/SearchCmd.ts b/backend/src/plugins/Utility/commands/SearchCmd.ts index f187dba8..777bb890 100644 --- a/backend/src/plugins/Utility/commands/SearchCmd.ts +++ b/backend/src/plugins/Utility/commands/SearchCmd.ts @@ -8,14 +8,14 @@ export const searchCmdSignature = { page: ct.number({ option: true, shortcut: "p" }), role: ct.string({ option: true, shortcut: "r" }), - voice: ct.switchOption({ shortcut: "v" }), - bot: ct.switchOption({ shortcut: "b" }), + voice: ct.switchOption({ def: false, shortcut: "v" }), + bot: ct.switchOption({ def: false, shortcut: "b" }), sort: ct.string({ option: true }), - "case-sensitive": ct.switchOption({ shortcut: "cs" }), - export: ct.switchOption({ shortcut: "e" }), + "case-sensitive": ct.switchOption({ def: false, shortcut: "cs" }), + export: ct.switchOption({ def: false, shortcut: "e" }), ids: ct.switchOption(), - regex: ct.switchOption({ shortcut: "re" }), - "status-search": ct.switchOption({ shortcut: "ss" }), + regex: ct.switchOption({ def: false, shortcut: "re" }), + "status-search": ct.switchOption({ def: false, shortcut: "ss" }), }; export const SearchCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index d39abc10..30fb7efe 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -21,6 +21,6 @@ export const ServerInfoCmd = utilityCmd({ return; } - message.channel.send({ embed: serverInfoEmbed }); + message.channel.send({ embeds: [serverInfoEmbed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts index 1320323e..59f43893 100644 --- a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts @@ -14,6 +14,6 @@ export const SnowflakeInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const embed = await getSnowflakeInfoEmbed(pluginData, args.id, false, message.author.id); - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index bacaedf6..ada75479 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { getBaseUrl, sendErrorMessage } from "../../../pluginUtils"; @@ -20,7 +21,7 @@ export const SourceCmd = utilityCmd({ return; } - const message = await args.message.channel.messages.fetch(args.message.messageId).catch(() => null); + const message = await args.message.channel.messages.fetch(args.message.messageId as Snowflake).catch(() => null); if (!message) { sendErrorMessage(pluginData, cmdMessage.channel, "Unknown message"); return; diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index 092692d3..c7ce8b48 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -12,7 +12,7 @@ export const UserInfoCmd = utilityCmd({ signature: { user: ct.resolvedUserLoose({ required: false }), - compact: ct.switchOption({ shortcut: "c" }), + compact: ct.switchOption({ def: false, shortcut: "c" }), }, async run({ message, args, pluginData }) { @@ -23,6 +23,6 @@ export const UserInfoCmd = utilityCmd({ return; } - message.channel.send({ embed }); + message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index b34da288..356ba4bd 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions, StageChannel, VoiceChannel } from "discord.js"; +import { MessageEmbedOptions, Snowflake, StageChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -21,7 +21,7 @@ export async function getChannelInfoEmbed( channelId: string, requestMemberId?: string, ): Promise { - const channel = pluginData.guild.channels.cache.get(channelId); + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel) { return null; } diff --git a/backend/src/plugins/Utility/functions/getGuildPreview.ts b/backend/src/plugins/Utility/functions/getGuildPreview.ts index 3da2c823..fc1d00db 100644 --- a/backend/src/plugins/Utility/functions/getGuildPreview.ts +++ b/backend/src/plugins/Utility/functions/getGuildPreview.ts @@ -1,9 +1,13 @@ -import { Client, GuildPreview } from "discord.js"; +import { Client, GuildPreview, Snowflake } from "discord.js"; import { memoize, MINUTES } from "../../../utils"; /** * Memoized getGuildPreview */ export function getGuildPreview(client: Client, guildId: string): Promise { - return memoize(() => client.fetchGuildPreview(guildId).catch(() => null), `getGuildPreview_${guildId}`, 10 * MINUTES); + return memoize( + () => client.fetchGuildPreview(guildId as Snowflake).catch(() => null), + `getGuildPreview_${guildId}`, + 10 * MINUTES, + ); } diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 27faf36a..5b8fc4bc 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions, TextChannel } from "discord.js"; +import { MessageEmbedOptions, Snowflake, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; @@ -16,8 +16,8 @@ export async function getMessageInfoEmbed( messageId: string, requestMemberId?: string, ): Promise { - const message = await (pluginData.guild.channels.resolve(channelId) as TextChannel).messages - .fetch(messageId) + const message = await (pluginData.guild.channels.resolve(channelId as Snowflake) as TextChannel).messages + .fetch(messageId as Snowflake) .catch(() => null); if (!message) { return null; diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index e47410f5..960a3d0c 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -1,4 +1,4 @@ -import { CategoryChannel, MessageEmbedOptions, TextChannel, VoiceChannel } from "discord.js"; +import { CategoryChannel, MessageEmbedOptions, Snowflake, TextChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -25,7 +25,7 @@ export async function getServerInfoEmbed( const thisServer = serverId === pluginData.guild.id ? pluginData.guild : null; const [restGuild, guildPreview] = await Promise.all([ thisServer - ? memoize(() => pluginData.client.guilds.fetch(serverId), `getRESTGuild_${serverId}`, 10 * MINUTES) + ? memoize(() => pluginData.client.guilds.fetch(serverId as Snowflake), `getRESTGuild_${serverId}`, 10 * MINUTES) : null, getGuildPreview(pluginData.client, serverId), ]); @@ -68,7 +68,7 @@ export async function getServerInfoEmbed( const ownerName = `${owner.username}#${owner.discriminator}`; basicInformation.push(`Owner: **${ownerName}** (\`${thisServer.ownerID}\`)`); - basicInformation.push(`Voice region: **${thisServer.region}**`); + // basicInformation.push(`Voice region: **${thisServer.region}**`); Outdated, as automatic voice regions are fully live } if (features.length > 0) { diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 04289dac..d53c21ab 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -158,7 +158,7 @@ export async function displaySearch( const embed = await getUserInfoEmbed(pluginData, searchResult.results[0].id, false); if (embed) { searchMsg.edit("Only one result:"); - msg.channel.send({ embed }); + msg.channel.send({ embeds: [embed] }); return; } } @@ -174,7 +174,6 @@ export async function displaySearch( new MessageButton() .setStyle("SECONDARY") .setEmoji("⬅") - .setType("BUTTON") .setCustomID(`previousButton:${idMod}`) .setDisabled(currentPage === 1), ); @@ -183,7 +182,6 @@ export async function displaySearch( new MessageButton() .setStyle("SECONDARY") .setEmoji("➡") - .setType("BUTTON") .setCustomID(`nextButton:${idMod}`) .setDisabled(currentPage === searchResult.lastPage), ); @@ -192,7 +190,6 @@ export async function displaySearch( new MessageButton() .setStyle("SECONDARY") .setEmoji("🔄") - .setType("BUTTON") .setCustomID(`reloadButton:${idMod}`), ); @@ -200,11 +197,11 @@ export async function displaySearch( await searchMsg.edit({ content: result, components: [row] }); const filter = (iac: MessageComponentInteraction) => iac.message.id === searchMsg.id; - const collector = searchMsg.createMessageComponentInteractionCollector(filter, { time: 2 * MINUTES }); + const collector = searchMsg.createMessageComponentInteractionCollector({ filter, time: 2 * MINUTES }); collector.on("collect", async (interaction: MessageComponentInteraction) => { if (msg.author.id !== interaction.user.id) { - interaction.reply(`You are not permitted to use these buttons.`, { ephemeral: true }); + interaction.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }); } else { if (interaction.customID === `previousButton:${idMod}` && currentPage > 1) { collector.stop(); diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index c6ebe5b6..2cfa6e53 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { LogType } from "../../../data/LogType"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { createChunkedMessage, stripObjectToScalars } from "../../../utils"; @@ -55,7 +55,7 @@ export const SendWelcomeMessageEvt = welcomeMessageEvt({ } if (config.send_to_channel) { - const channel = meta.args.member.guild.channels.cache.get(config.send_to_channel); + const channel = meta.args.member.guild.channels.cache.get(config.send_to_channel as Snowflake); if (!channel || !(channel instanceof TextChannel)) return; try { diff --git a/backend/src/utils.ts b/backend/src/utils.ts index f72eebe9..b05af8cf 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -16,7 +16,7 @@ import { MessageOptions, PartialChannelData, PartialMessage, - StringResolvable, + Snowflake, TextChannel, User, } from "discord.js"; @@ -1133,7 +1133,7 @@ export function resolveUserId(bot: Client, value: string) { */ export function getUser(client: Client, userResolvable: string): User | UnknownUser { const id = resolveUserId(client, userResolvable); - return id ? client.users.resolve(id) || new UnknownUser({ id }) : new UnknownUser(); + return id ? client.users.resolve(id as Snowflake) || new UnknownUser({ id }) : new UnknownUser(); } /** @@ -1188,8 +1188,8 @@ export async function resolveMember( if (!userId) return null; // If we have the member cached, return that directly - if (guild.members.cache.has(userId) && !fresh) { - return guild.members.cache.get(userId) || null; + if (guild.members.cache.has(userId as Snowflake) && !fresh) { + return guild.members.cache.get(userId as Snowflake) || null; } // We don't want to spam the API by trying to fetch unknown members again and again, @@ -1199,7 +1199,7 @@ export async function resolveMember( return null; } - const freshMember = await guild.members.fetch({ user: userId, force: true }).catch(noop); + const freshMember = await guild.members.fetch({ user: userId as Snowflake, force: true }).catch(noop); if (freshMember) { // freshMember.id = userId; // I dont even know why this is here -Dark return freshMember; @@ -1229,7 +1229,7 @@ export async function resolveRoleId(bot: Client, guildId: string, value: string) } // Role name - const roleList = await (await bot.guilds.fetch(guildId)).roles.cache; + const roleList = await (await bot.guilds.fetch(guildId as Snowflake)).roles.cache; const role = roleList.filter(x => x.name.toLocaleLowerCase() === value.toLocaleLowerCase()); if (role[0]) { return role[0].id; @@ -1264,12 +1264,8 @@ export async function resolveInvite( return promise as ResolveInviteReturnType; } -export async function confirm( - channel: TextChannel, - userId: string, - content: StringResolvable | MessageOptions, -): Promise { - return waitForButtonConfirm(channel, { content }, { restrictToId: userId }); +export async function confirm(channel: TextChannel, userId: string, content: MessageOptions): Promise { + return waitForButtonConfirm(channel, content, { restrictToId: userId }); } export function messageSummary(msg: SavedMessage) { diff --git a/backend/src/utils/canAssignRole.ts b/backend/src/utils/canAssignRole.ts index 17de0e45..a88a61e9 100644 --- a/backend/src/utils/canAssignRole.ts +++ b/backend/src/utils/canAssignRole.ts @@ -1,4 +1,4 @@ -import { Guild, GuildMember, Permissions, Role } from "discord.js"; +import { Guild, GuildMember, Permissions, Role, Snowflake } from "discord.js"; import { getMissingPermissions } from "./getMissingPermissions"; import { hasDiscordPermissions } from "./hasDiscordPermissions"; @@ -11,7 +11,7 @@ export function canAssignRole(guild: Guild, member: GuildMember, roleId: string) return false; } - const targetRole = guild.roles.cache.get(roleId); + const targetRole = guild.roles.cache.get(roleId as Snowflake); if (!targetRole) { return false; } diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index 8eeacc97..66da9f0b 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -24,7 +24,7 @@ export async function createPaginatedMessage( ): Promise { const fullOpts = { ...defaultOpts, ...opts } as PaginateMessageOpts; const firstPageContent = await loadPageFn(1); - const message = await channel.send({ content: firstPageContent }); + const message = await channel.send(firstPageContent); let page = 1; let pageLoadId = 0; // Used to avoid race conditions when rapidly switching pages diff --git a/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts index 324ea826..54f9649b 100644 --- a/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts +++ b/backend/src/utils/erisAllowedMentionsToDjsMentionOptions.ts @@ -1,4 +1,4 @@ -import { MessageMentionOptions, MessageMentionTypes } from "discord.js"; +import { MessageMentionOptions, MessageMentionTypes, Snowflake } from "discord.js"; export function erisAllowedMentionsToDjsMentionOptions( allowedMentions: ErisAllowedMentionFormat | undefined, @@ -6,17 +6,17 @@ export function erisAllowedMentionsToDjsMentionOptions( if (allowedMentions === undefined) return undefined; const parse: MessageMentionTypes[] = []; - let users: string[] | undefined; - let roles: string[] | undefined; + let users: Snowflake[] | undefined; + let roles: Snowflake[] | undefined; if (Array.isArray(allowedMentions.users)) { - users = allowedMentions.users; + users = allowedMentions.users as Snowflake[]; } else if (allowedMentions.users === true) { parse.push("users"); } if (Array.isArray(allowedMentions.roles)) { - roles = allowedMentions.roles; + roles = allowedMentions.roles as Snowflake[]; } else if (allowedMentions.roles === true) { parse.push("roles"); } diff --git a/backend/src/utils/getMissingPermissions.ts b/backend/src/utils/getMissingPermissions.ts index 8e14ac63..3b1adf45 100644 --- a/backend/src/utils/getMissingPermissions.ts +++ b/backend/src/utils/getMissingPermissions.ts @@ -9,12 +9,12 @@ export function getMissingPermissions( resolvedPermissions: Permissions | Readonly, requiredPermissions: number | bigint, ): bigint { - const allowedPermissions = BigInt(resolvedPermissions); - const nRequiredPermissions = BigInt(requiredPermissions); + const allowedPermissions = resolvedPermissions; + const nRequiredPermissions = requiredPermissions; - if (Boolean(allowedPermissions & BigInt(Permissions.FLAGS.ADMINISTRATOR))) { + if (Boolean(allowedPermissions.bitfield & Permissions.FLAGS.ADMINISTRATOR)) { return BigInt(0); } - return nRequiredPermissions & ~allowedPermissions; + return BigInt(nRequiredPermissions) & ~allowedPermissions.bitfield; } diff --git a/backend/src/utils/hasDiscordPermissions.ts b/backend/src/utils/hasDiscordPermissions.ts index 7cbe8750..c8f4823a 100644 --- a/backend/src/utils/hasDiscordPermissions.ts +++ b/backend/src/utils/hasDiscordPermissions.ts @@ -8,12 +8,12 @@ export function hasDiscordPermissions( resolvedPermissions: Permissions | Readonly | null, requiredPermissions: number | bigint, ) { - const allowedPermissions = BigInt(resolvedPermissions); - const nRequiredPermissions = BigInt(requiredPermissions); + const allowedPermissions = resolvedPermissions; + const nRequiredPermissions = requiredPermissions; - if (Boolean(allowedPermissions & BigInt(Permissions.FLAGS.ADMINISTRATOR))) { + if (Boolean(allowedPermissions?.bitfield! & Permissions.FLAGS.ADMINISTRATOR)) { return true; } - return Boolean((allowedPermissions & nRequiredPermissions) === nRequiredPermissions); + return Boolean((allowedPermissions?.bitfield! & BigInt(nRequiredPermissions)) === nRequiredPermissions); } diff --git a/backend/src/utils/messageHasContent.ts b/backend/src/utils/messageHasContent.ts index e333f5c9..b70918be 100644 --- a/backend/src/utils/messageHasContent.ts +++ b/backend/src/utils/messageHasContent.ts @@ -27,8 +27,12 @@ export function messageHasContent(content: string | MessageOptions): boolean { return true; } - if (content.embed && embedHasContent(content.embed)) { - return true; + if (content.embeds) { + for (const embed of content.embeds) { + if (embed && embedHasContent(embed)) { + return true; + } + } } return false; diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts index 00df7010..a7c3043c 100644 --- a/backend/src/utils/resolveMessageTarget.ts +++ b/backend/src/utils/resolveMessageTarget.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; import { isSnowflake } from "../utils"; @@ -46,7 +46,7 @@ export async function resolveMessageTarget(pluginData: GuildPluginData, val return null; } - const channel = pluginData.guild.channels.resolve(result.channelId); + const channel = pluginData.guild.channels.resolve(result.channelId as Snowflake); if (!channel || !(channel instanceof TextChannel)) { return null; } diff --git a/backend/src/utils/sendDM.ts b/backend/src/utils/sendDM.ts index c2dbdb93..851efcb5 100644 --- a/backend/src/utils/sendDM.ts +++ b/backend/src/utils/sendDM.ts @@ -1,4 +1,4 @@ -import { APIMessage, User } from "discord.js"; +import { MessagePayload, User } from "discord.js"; import { logger } from "../logger"; import { createChunkedMessage, HOURS, isDiscordRESTError } from "../utils"; import Timeout = NodeJS.Timeout; @@ -16,7 +16,7 @@ export class DMError extends Error {} const error20026 = "The bot cannot currently send DMs"; -export async function sendDM(user: User, content: string | APIMessage, source: string) { +export async function sendDM(user: User, content: string | MessagePayload, source: string) { if (dmsDisabled) { throw new DMError(error20026); } diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index dd36f3fd..7e790436 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -13,23 +13,21 @@ export async function waitForButtonConfirm( new MessageButton() .setStyle("SUCCESS") .setLabel(options?.confirmText || "Confirm") - .setType("BUTTON") .setCustomID(`confirmButton:${idMod}`), new MessageButton() .setStyle("DANGER") .setLabel(options?.cancelText || "Cancel") - .setType("BUTTON") .setCustomID(`cancelButton:${idMod}`), ]); - const message = await channel.send({ ...toPost, components: [row], split: false }); + const message = await channel.send({ ...toPost, components: [row] }); const filter = (iac: MessageComponentInteraction) => iac.message.id === message.id; - const collector = message.createMessageComponentInteractionCollector(filter, { time: 10000 }); + const collector = message.createMessageComponentInteractionCollector({ filter, time: 10000 }); collector.on("collect", (interaction: MessageComponentInteraction) => { if (options?.restrictToId && options.restrictToId !== interaction.user.id) { - interaction.reply(`You are not permitted to use these buttons.`, { ephemeral: true }); + interaction.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }); } else { if (interaction.customID === `confirmButton:${idMod}`) { message.delete(); diff --git a/package-lock.json b/package-lock.json index b6991f05..308ef9b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,2077 @@ { "name": "@zeppelin/zeppelin", "version": "0.0.1", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@zeppelin/zeppelin", + "version": "0.0.1", + "devDependencies": { + "husky": "^3.0.9", + "lint-staged": "^9.4.2", + "prettier": "^1.19.1", + "tslint": "^5.13.1", + "tslint-config-prettier": "^1.18.0", + "typescript": "^4.1.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.0.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "dependencies": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "dependencies": { + "any-observable": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "node_modules/@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "dependencies": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "12.12.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz", + "integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "dependencies": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "dependencies": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", + "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.0" + } + }, + "node_modules/figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz", + "integrity": "sha512-09/VS4iek66Dh2bctjRkowueRJbY1JDGR1L/zRxO1Qk8Uxs6PnqaNSqalpizPT+CDjre3hnEsuzvhgomz9qYrA==", + "dev": true + }, + "node_modules/get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true + }, + "node_modules/husky": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/husky/-/husky-3.0.9.tgz", + "integrity": "sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "chalk": "^2.4.2", + "ci-info": "^2.0.0", + "cosmiconfig": "^5.2.1", + "execa": "^1.0.0", + "get-stdin": "^7.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "read-pkg": "^5.2.0", + "run-node": "^1.0.0", + "slash": "^3.0.0" + }, + "bin": { + "husky-run": "run.js", + "husky-upgrade": "lib/upgrader/bin.js" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "dependencies": { + "symbol-observable": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/lint-staged": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.4.2.tgz", + "integrity": "sha512-OFyGokJSWTn2M6vngnlLXjaHhi8n83VIZZ5/1Z26SULRUWgR3ITWpAEQC9Pnm3MC/EpCxlwts/mQWDHNji2+zA==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "commander": "^2.20.0", + "cosmiconfig": "^5.2.1", + "debug": "^4.1.1", + "dedent": "^0.7.0", + "del": "^5.0.0", + "execa": "^2.0.3", + "listr": "^0.14.3", + "log-symbols": "^3.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.1.1", + "string-argv": "^0.3.0", + "stringify-object": "^3.3.0" + }, + "bin": { + "lint-staged": "bin/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", + "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^3.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": "^8.12.0 || >=9.7.0" + } + }, + "node_modules/lint-staged/node_modules/get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", + "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz", + "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lint-staged/node_modules/which": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz", + "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "dependencies": { + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "listr": "^0.14.2" + } + }, + "node_modules/listr-update-renderer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-update-renderer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-update-renderer/node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-update-renderer/node_modules/log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "dependencies": { + "chalk": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-update-renderer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-verbose-renderer/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "dependencies": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp/node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true, + "bin": { + "opencollective-postinstall": "index.js" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.0.tgz", + "integrity": "sha512-uhnEDzAbrcJ8R3g2fANnSuXZMBtkpSjxTTgn2LeSiQlfmq72enQJWdQllXW24MBLYnA1SBD2vfvx2o0Zw3Ielw==", + "dev": true, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true, + "bin": { + "run-node": "run-node" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "node_modules/rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "node_modules/tslint": { + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.0.tgz", + "integrity": "sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true, + "bin": { + "tslint-config-prettier-check": "bin/check.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "dependencies": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + }, "dependencies": { "@babel/code-frame": { "version": "7.5.5", diff --git a/package.json b/package.json index d5fc559d..1c3f821c 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "lint": "tslint \"./{backend,dashboard}/{,!(node_modules)/**/}/*.ts\"", "codestyle-check": "prettier --check \"./{backend,dashboard}/{,!(node_modules)/**/}/*.ts\"" }, - "dependencies": {}, "devDependencies": { "husky": "^3.0.9", "lint-staged": "^9.4.2", From be71357ff98d36923ac38f9f0ccd434bf5efedf6 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:43:42 +0200 Subject: [PATCH 23/79] Upgrade DJS, fix bugs --- backend/package-lock.json | 79 +++++++++++++++---- backend/package.json | 2 +- .../BotControl/commands/DisallowServerCmd.ts | 4 +- .../BotControl/commands/LeaveServerCmd.ts | 8 +- .../BotControl/commands/ReloadServerCmd.ts | 6 +- .../commands/ArchiveChannelCmd.ts | 2 +- .../plugins/ModActions/commands/MassBanCmd.ts | 6 +- .../ModActions/commands/MassUnbanCmd.ts | 7 +- .../ModActions/commands/MassmuteCmd.ts | 4 +- .../plugins/NameHistory/commands/NamesCmd.ts | 3 +- .../commands/PostButtonRolesCmd.ts | 2 +- .../src/plugins/Utility/commands/AboutCmd.ts | 45 ++++++----- .../src/plugins/Utility/commands/CleanCmd.ts | 2 +- .../plugins/Utility/commands/ContextCmd.ts | 4 +- .../src/plugins/Utility/commands/InfoCmd.ts | 2 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 10 +-- backend/src/plugins/Utility/search.ts | 3 +- 17 files changed, 123 insertions(+), 66 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 4809cb21..6a2cfff2 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.edab5af.1624996138", + "discord.js": "^13.0.0-dev.64f093f.1625054868", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -161,6 +161,24 @@ "node": ">=0.10.0" } }, + "node_modules/@discordjs/builders": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.1.1.tgz", + "integrity": "sha512-9eBC22bX2HBsob5ixMwZ6quy/vewU5GHuSJhpmSZ3cDGg8XPnrYdzbwI54U+V9kQBTa7M+aMu1lYVqMEPojj8A==", + "dependencies": { + "discord-api-types": "^0.18.1", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@discordjs/builders/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, "node_modules/@discordjs/collection": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", @@ -2133,11 +2151,20 @@ "node": ">=8" } }, + "node_modules/discord-api-types": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.18.1.tgz", + "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/discord.js": { - "version": "13.0.0-dev.edab5af.1624996138", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.edab5af.1624996138.tgz", - "integrity": "sha512-WGbizyvt23aorgHH4dP4vDB/v7NT2szQOdLaeypzjiP89e3yvtVOPDpoFdm03PPzG65n4K005/qfN4yBVVbysw==", + "version": "13.0.0-dev.64f093f.1625054868", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.64f093f.1625054868.tgz", + "integrity": "sha512-CgpgvpcALYmEhgGETAxFHMqt+XmuTbcSYIN+kLyzualzHNQ2RageW3tslgLgSnBdID60AMvXN/nzMuEn/J6rAA==", "dependencies": { + "@discordjs/builders": "^0.1.1", "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", @@ -2145,7 +2172,7 @@ "abort-controller": "^3.0.0", "discord-api-types": "^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", "node-fetch": "^2.6.1", - "ws": "^7.5.0" + "ws": "^7.5.1" }, "engines": { "node": ">=14.0.0", @@ -6134,9 +6161,9 @@ } }, "node_modules/ws": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", - "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.1.tgz", + "integrity": "sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==", "engines": { "node": ">=8.3.0" }, @@ -6410,6 +6437,22 @@ } } }, + "@discordjs/builders": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.1.1.tgz", + "integrity": "sha512-9eBC22bX2HBsob5ixMwZ6quy/vewU5GHuSJhpmSZ3cDGg8XPnrYdzbwI54U+V9kQBTa7M+aMu1lYVqMEPojj8A==", + "requires": { + "discord-api-types": "^0.18.1", + "tslib": "^2.3.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, "@discordjs/collection": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", @@ -7986,11 +8029,17 @@ "path-type": "^4.0.0" } }, + "discord-api-types": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.18.1.tgz", + "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" + }, "discord.js": { - "version": "13.0.0-dev.edab5af.1624996138", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.edab5af.1624996138.tgz", - "integrity": "sha512-WGbizyvt23aorgHH4dP4vDB/v7NT2szQOdLaeypzjiP89e3yvtVOPDpoFdm03PPzG65n4K005/qfN4yBVVbysw==", + "version": "13.0.0-dev.64f093f.1625054868", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.64f093f.1625054868.tgz", + "integrity": "sha512-CgpgvpcALYmEhgGETAxFHMqt+XmuTbcSYIN+kLyzualzHNQ2RageW3tslgLgSnBdID60AMvXN/nzMuEn/J6rAA==", "requires": { + "@discordjs/builders": "^0.1.1", "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", @@ -7998,7 +8047,7 @@ "abort-controller": "^3.0.0", "discord-api-types": "^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", "node-fetch": "^2.6.1", - "ws": "^7.5.0" + "ws": "^7.5.1" }, "dependencies": { "discord-api-types": { @@ -11132,9 +11181,9 @@ } }, "ws": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", - "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.1.tgz", + "integrity": "sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==", "requires": {} }, "xdg-basedir": { diff --git a/backend/package.json b/backend/package.json index 73213034..9cf5f4b3 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.edab5af.1624996138", + "discord.js": "^13.0.0-dev.64f093f.1625054868", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index 9dfd9599..1a9cf64a 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { noop } from "../../../utils"; @@ -24,7 +24,7 @@ export const DisallowServerCmd = botControlCmd({ await pluginData.state.allowedGuilds.remove(args.guildId); await pluginData.client.guilds.cache - .get(args.guildId) + .get(args.guildId as Snowflake) ?.leave() .catch(noop); sendSuccessMessage(pluginData, msg.channel as TextChannel, "Server removed!"); diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 8352548a..b502c08f 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { botControlCmd } from "../types"; @@ -15,16 +15,16 @@ export const LeaveServerCmd = botControlCmd({ }, async run({ pluginData, message: msg, args }) { - if (!pluginData.client.guilds.cache.has(args.guildId)) { + if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { sendErrorMessage(pluginData, msg.channel as TextChannel, "I am not in that guild"); return; } - const guildToLeave = await pluginData.client.guilds.fetch(args.guildId)!; + const guildToLeave = await pluginData.client.guilds.fetch(args.guildId as Snowflake)!; const guildName = guildToLeave.name; try { - await pluginData.client.guilds.cache.get(args.guildId)?.leave(); + await pluginData.client.guilds.cache.get(args.guildId as Snowflake)?.leave(); } catch (e) { sendErrorMessage(pluginData, msg.channel as TextChannel, `Failed to leave guild: ${e.message}`); return; diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 0166cba1..fb652b65 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isOwnerPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { botControlCmd } from "../types"; @@ -15,7 +15,7 @@ export const ReloadServerCmd = botControlCmd({ }, async run({ pluginData, message: msg, args }) { - if (!pluginData.client.guilds.cache.has(args.guildId)) { + if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { sendErrorMessage(pluginData, msg.channel as TextChannel, "I am not in that guild"); return; } @@ -27,7 +27,7 @@ export const ReloadServerCmd = botControlCmd({ return; } - const guild = await pluginData.client.guilds.fetch(args.guildId); + const guild = await pluginData.client.guilds.fetch(args.guildId as Snowflake); sendSuccessMessage(pluginData, msg.channel as TextChannel, `Reloaded guild **${guild?.name || "???"}**`); }, }); diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 5d84be22..84e26317 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -62,7 +62,7 @@ export const ArchiveChannelCmd = channelArchiverCmd({ const messagesToFetch = Math.min(MAX_MESSAGES_PER_FETCH, maxMessagesToArchive - archivedMessages); const messages = (await args.channel.messages.fetch({ limit: messagesToFetch, - before: previousId, + before: previousId as Snowflake, })) as Collection; if (messages.size === 0) break; diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 8fb84b73..dc1e0855 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; import { performance } from "perf_hooks"; import { commandTypeHelpers as ct } from "../../../commandTypes"; @@ -42,7 +42,7 @@ export const MassbanCmd = modActionsCmd({ // Verify we can act on each of the users specified for (const userId of args.userIds) { - const member = pluginData.guild.members.cache.get(userId); // TODO: Get members on demand? + const member = pluginData.guild.members.cache.get(userId as Snowflake); // TODO: Get members on demand? if (member && !canActOn(pluginData, msg.member, member)) { sendErrorMessage(pluginData, msg.channel, "Cannot massban one or more users: insufficient permissions"); return; @@ -91,7 +91,7 @@ export const MassbanCmd = modActionsCmd({ ignoreEvent(pluginData, IgnoredEventType.Ban, userId, 120 * 1000); pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId, 120 * 1000); - await pluginData.guild.bans.create(userId, { + await pluginData.guild.bans.create(userId as Snowflake, { days: 1, reason: banReason != null ? encodeURIComponent(banReason) : undefined, }); diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index 6b41e3f4..1d6ec0c7 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -60,7 +60,10 @@ export const MassunbanCmd = modActionsCmd({ } try { - await pluginData.guild.bans.remove(userId, unbanReason != null ? encodeURIComponent(unbanReason) : undefined); + await pluginData.guild.bans.remove( + userId as Snowflake, + unbanReason != null ? encodeURIComponent(unbanReason) : undefined, + ); await casesPlugin.createCase({ userId, diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index 171270da..a2c1faf2 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; @@ -43,7 +43,7 @@ export const MassmuteCmd = modActionsCmd({ // Verify we can act upon all users for (const userId of args.userIds) { - const member = pluginData.guild.members.cache.get(userId); + const member = pluginData.guild.members.cache.get(userId as Snowflake); if (member && !canActOn(pluginData, msg.member, member)) { sendErrorMessage(pluginData, msg.channel, "Cannot massmute one or more users: insufficient permissions"); return; diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index a6f722c7..f2a7348a 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { createChunkedMessage, disableCodeBlocks } from "knub/dist/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames"; @@ -29,7 +30,7 @@ export const NamesCmd = nameHistoryCmd({ ); const usernameRows = usernames.map(r => `\`[${r.timestamp}]\` **${disableCodeBlocks(r.username)}**`); - const user = await pluginData.client.users.fetch(args.userId); + const user = await pluginData.client.users.fetch(args.userId as Snowflake); const currentUsername = user ? `${user.username}#${user.discriminator}` : args.userId; const nicknameDays = Math.round(NICKNAME_RETENTION_PERIOD / DAYS); diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index 84f809d8..aa74c553 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -52,7 +52,7 @@ export const PostButtonRolesCmd = reactionRolesCmd({ const rows = splitButtonsIntoRows(buttons, Object.values(group.default_buttons)); // new MessageActionRow().addComponents(buttons); try { - const newMsg = await args.channel.send({ content: group.message, components: rows, split: false }); + const newMsg = await args.channel.send({ content: group.message, components: rows }); for (const btn of toInsert) { await pluginData.state.buttonRoles.add( diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 546d51dc..dd788816 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -63,24 +63,26 @@ export const AboutCmd = utilityCmd({ ); loadedPlugins.sort(); - const aboutContent: MessageOptions & { embed: EmbedWith<"title" | "fields"> } = { - embed: { - title: `About ${pluginData.client.user!.username}`, - fields: [ - { - name: "Status", - value: basicInfoRows - .map(([label, value]) => { - return `${label}: **${value}**`; - }) - .join("\n"), - }, - { - name: `Loaded plugins on this server (${loadedPlugins.length})`, - value: loadedPlugins.join(", "), - }, - ], - }, + const aboutContent: MessageOptions = { + embeds: [ + { + title: `About ${pluginData.client.user!.username}`, + fields: [ + { + name: "Status", + value: basicInfoRows + .map(([label, value]) => { + return `${label}: **${value}**`; + }) + .join("\n"), + }, + { + name: `Loaded plugins on this server (${loadedPlugins.length})`, + value: loadedPlugins.join(", "), + }, + ], + }, + ], }; const supporters = await pluginData.state.supporters.getAll(); @@ -92,9 +94,10 @@ export const AboutCmd = utilityCmd({ ); if (supporters.length) { - aboutContent.embed.fields.push({ + aboutContent.embeds![0].fields!.push({ name: "Zeppelin supporters 🎉", value: supporters.map(s => `**${s.name}** ${s.amount ? `${s.amount}€/mo` : ""}`.trim()).join("\n"), + inline: false, }); } @@ -105,12 +108,12 @@ export const AboutCmd = utilityCmd({ botRoles = botRoles.filter(r => r.color); // Filter to those with a color botRoles.sort(sorter("position", "DESC")); // Sort by position (highest first) if (botRoles.length) { - aboutContent.embed.color = botRoles[0].color; + aboutContent.embeds![0].color = botRoles[0].color; } // Use the bot avatar as the embed image if (pluginData.client.user!.avatarURL()) { - aboutContent.embed.thumbnail = { url: pluginData.client.user!.avatarURL()! }; + aboutContent.embeds![0].thumbnail = { url: pluginData.client.user!.avatarURL()! }; } msg.channel.send(aboutContent); diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index e953b7f2..e7024866 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -87,7 +87,7 @@ export const CleanCmd = utilityCmd({ return; } - const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel) : msg.channel; + const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; if (!targetChannel || !(targetChannel instanceof TextChannel)) { sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`); return; diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index e51ceeab..ceec4407 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { messageLink } from "../../../utils"; @@ -38,7 +38,7 @@ export const ContextCmd = utilityCmd({ const previousMessage = ( await (pluginData.guild.channels.cache.get(channel.id) as TextChannel).messages.fetch({ limit: 1, - before: messageId, + before: messageId as Snowflake, }) )[0]; if (!previousMessage) { diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 8ca414a5..9c4b55d3 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -58,7 +58,7 @@ export const InfoCmd = utilityCmd({ // 2. Server if (userCfg.can_server) { - const guild = await pluginData.client.guilds.fetch(value).catch(noop); + const guild = await pluginData.client.guilds.fetch(value as Snowflake).catch(noop); if (guild) { const embed = await getServerInfoEmbed(pluginData, value, message.author.id); if (embed) { diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 967db1f0..c7d68008 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -1,4 +1,4 @@ -import { VoiceChannel } from "discord.js"; +import { Snowflake, VoiceChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; @@ -21,7 +21,7 @@ export const VcmoveCmd = utilityCmd({ if (isSnowflake(args.channel)) { // Snowflake -> resolve channel directly - const potentialChannel = pluginData.guild.channels.cache.get(args.channel); + const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; @@ -31,7 +31,7 @@ export const VcmoveCmd = utilityCmd({ } else if (channelMentionRegex.test(args.channel)) { // Channel mention -> parse channel id and resolve channel from that const channelId = args.channel.match(channelMentionRegex)![1]; - const potentialChannel = pluginData.guild.channels.cache.get(channelId); + const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; @@ -104,7 +104,7 @@ export const VcmoveAllCmd = utilityCmd({ if (isSnowflake(args.channel)) { // Snowflake -> resolve channel directly - const potentialChannel = pluginData.guild.channels.cache.get(args.channel); + const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; @@ -114,7 +114,7 @@ export const VcmoveAllCmd = utilityCmd({ } else if (channelMentionRegex.test(args.channel)) { // Channel mention -> parse channel id and resolve channel from that const channelId = args.channel.match(channelMentionRegex)![1]; - const potentialChannel = pluginData.guild.channels.cache.get(channelId); + const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); return; diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index d53c21ab..f535539d 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -5,6 +5,7 @@ import { MessageButton, MessageComponentInteraction, Permissions, + Snowflake, TextChannel, User, } from "discord.js"; @@ -316,7 +317,7 @@ async function performMemberSearch( const roleIds = args.role.split(","); matchingMembers = matchingMembers.filter(member => { for (const role of roleIds) { - if (!member.roles.cache.has(role)) return false; + if (!member.roles.cache.has(role as Snowflake)) return false; } return true; From 1ad70ffe1a9ea60cc6977428424d1411dfbeab0a Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 30 Jun 2021 23:06:02 +0200 Subject: [PATCH 24/79] Change DiscordRESTError to DiscordAPIError --- backend/package-lock.json | 18 +++++++++--------- backend/package.json | 2 +- backend/src/index.ts | 4 ++-- .../AutoReactions/events/AddReactionsEvt.ts | 4 ++-- .../src/plugins/Automod/actions/setSlowmode.ts | 4 ++-- .../Cases/functions/postToCaseLogChannel.ts | 4 ++-- .../functions/handleCompanionPermissions.ts | 4 ++-- .../ModActions/functions/actualMuteUserCmd.ts | 4 ++-- .../plugins/ModActions/functions/isBanned.ts | 6 +++--- .../commands/ClearReactionRolesCmd.ts | 4 ++-- .../commands/InitReactionRolesCmd.ts | 4 ++-- .../applyReactionRoleReactionsToMessage.ts | 8 ++++---- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 4 ++-- backend/src/utils.ts | 6 +++--- .../src/utils/safeFindRelevantAuditLogEntry.ts | 4 ++-- backend/src/utils/sendDM.ts | 4 ++-- package-lock.json | 14 +++++++------- package.json | 2 +- 18 files changed, 50 insertions(+), 50 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 6a2cfff2..60a8e66b 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -73,7 +73,7 @@ "rimraf": "^2.6.2", "source-map-support": "^0.5.16", "tsc-watch": "^4.0.0", - "typescript": "^4.4.0-dev.20210629" + "typescript": "^4.3.4" } }, "../../Knub": { @@ -83,7 +83,7 @@ "dependencies": { "@discordjs/voice": "^0.5.1", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.edab5af.1624996138", + "discord.js": "^13.0.0-dev.64f093f.1625054868", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -5721,9 +5721,9 @@ } }, "node_modules/typescript": { - "version": "4.4.0-dev.20210629", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.0-dev.20210629.tgz", - "integrity": "sha512-kqDceSuAA0qQ6z5mrQc3LcD6IcwrKOZZ2YO7oBgwfGM0zzraUKhpdJSZovwN0pF3MdI211HccvrHf8JX7UJD7A==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", + "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8880,7 +8880,7 @@ "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.edab5af.1624996138", + "discord.js": "^13.0.0-dev.64f093f.1625054868", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", @@ -10844,9 +10844,9 @@ } }, "typescript": { - "version": "4.4.0-dev.20210629", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.0-dev.20210629.tgz", - "integrity": "sha512-kqDceSuAA0qQ6z5mrQc3LcD6IcwrKOZZ2YO7oBgwfGM0zzraUKhpdJSZovwN0pF3MdI211HccvrHf8JX7UJD7A==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", + "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==", "dev": true }, "uid2": { diff --git a/backend/package.json b/backend/package.json index 9cf5f4b3..88c84cb7 100644 --- a/backend/package.json +++ b/backend/package.json @@ -88,7 +88,7 @@ "rimraf": "^2.6.2", "source-map-support": "^0.5.16", "tsc-watch": "^4.0.0", - "typescript": "^4.4.0-dev.20210629" + "typescript": "^4.3.4" }, "ava": { "files": [ diff --git a/backend/src/index.ts b/backend/src/index.ts index a830042b..560e5f45 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -19,7 +19,7 @@ import { RecoverablePluginError } from "./RecoverablePluginError"; import { SimpleError } from "./SimpleError"; import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; import { startUptimeCounter } from "./uptime"; -import { errorMessage, isDiscordHTTPError, isDiscordRESTError, successMessage } from "./utils"; +import { errorMessage, isDiscordHTTPError, isDiscordAPIError, successMessage } from "./utils"; const fsp = fs.promises; @@ -113,7 +113,7 @@ function errorHandler(err) { console.error(`Exiting after ${RECENT_PLUGIN_ERROR_EXIT_THRESHOLD} plugin errors`); process.exit(1); } - } else if (isDiscordRESTError(err) || isDiscordHTTPError(err)) { + } else if (isDiscordAPIError(err) || isDiscordHTTPError(err)) { // Discord API errors, usually safe to just log instead of crash // We still bail if we get a ton of them in a short amount of time if (++recentDiscordErrors >= RECENT_DISCORD_ERROR_EXIT_THRESHOLD) { diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index e8a0fc29..fc96efc6 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -1,6 +1,6 @@ import { GuildChannel, Permissions } from "discord.js"; import { LogType } from "../../../data/LogType"; -import { isDiscordRESTError } from "../../../utils"; +import { isDiscordAPIError } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { readChannelPermissions } from "../../../utils/readChannelPermissions"; @@ -36,7 +36,7 @@ export const AddReactionsEvt = autoReactionsEvt({ try { await message.react(reaction); } catch (e) { - if (isDiscordRESTError(e)) { + if (isDiscordAPIError(e)) { const logs = pluginData.getPlugin(LogsPlugin); if (e.code === 10008) { logs.log(LogType.BOT_ALERT, { diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index c303de3a..f2b9aeac 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -2,7 +2,7 @@ import { Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { ChannelTypeStrings } from "src/types"; import { LogType } from "../../../data/LogType"; -import { convertDelayStringToMS, isDiscordRESTError, tDelayString, tNullable } from "../../../utils"; +import { convertDelayStringToMS, isDiscordAPIError, tDelayString, tNullable } from "../../../utils"; import { automodAction } from "../helpers"; export const SetSlowmodeAction = automodAction({ @@ -49,7 +49,7 @@ export const SetSlowmodeAction = automodAction({ } catch (e) { // Check for invalid form body -> indicates duration was too large const errorMessage = - isDiscordRESTError(e) && e.code === 50035 + isDiscordAPIError(e) && e.code === 50035 ? `Duration is greater than maximum native slowmode duration` : e.message; diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index 33a6e97d..7f3f04d5 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -2,7 +2,7 @@ import { FileOptions, Message, MessageOptions, Snowflake, TextChannel } from "di import { GuildPluginData } from "knub"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; -import { isDiscordRESTError } from "../../../utils"; +import { isDiscordAPIError } from "../../../utils"; import { CasesPluginType } from "../types"; import { getCaseEmbed } from "./getCaseEmbed"; import { resolveCaseId } from "./resolveCaseId"; @@ -25,7 +25,7 @@ export async function postToCaseLogChannel( } result = await caseLogChannel.send({ ...content }); } catch (e) { - if (isDiscordRESTError(e) && (e.code === 50013 || e.code === 50001)) { + if (isDiscordAPIError(e) && (e.code === 50013 || e.code === 50001)) { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Missing permissions to post mod cases in <#${caseLogChannel.id}>`, }); diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index ddbfc266..de83899b 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -1,7 +1,7 @@ import { Permissions, Snowflake, StageChannel, TextChannel, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; -import { isDiscordRESTError, MINUTES } from "../../../utils"; +import { isDiscordAPIError, MINUTES } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId"; @@ -66,7 +66,7 @@ export async function handleCompanionPermissions( }); } } catch (e) { - if (isDiscordRESTError(e) && e.code === 50001) { + if (isDiscordAPIError(e) && e.code === 50001) { const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { body: `Missing permissions to handle companion channels. Pausing companion channels for 5 minutes or until the bot is reloaded on this server.`, diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index b5ff7ed1..57b0f249 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -4,7 +4,7 @@ import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { asSingleLine, isDiscordRESTError, UnknownUser } from "../../../utils"; +import { asSingleLine, isDiscordAPIError, UnknownUser } from "../../../utils"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; import { MuteResult } from "../../Mutes/types"; import { ModActionsPluginType } from "../types"; @@ -60,7 +60,7 @@ export async function actualMuteUserCmd( } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: no mute role set in config"); - } else if (isDiscordRESTError(e) && e.code === 10007) { + } else if (isDiscordAPIError(e) && e.code === 10007) { sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: unknown member"); } else { logger.error(`Failed to mute user ${user.id}: ${e.stack}`); diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index 60fe37e3..dc476e63 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -1,7 +1,7 @@ import { Permissions, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; -import { isDiscordHTTPError, isDiscordRESTError, SECONDS, sleep } from "../../../utils"; +import { isDiscordHTTPError, isDiscordAPIError, SECONDS, sleep } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../types"; @@ -26,7 +26,7 @@ export async function isBanned( ]); return potentialBan != null; } catch (e) { - if (isDiscordRESTError(e) && e.code === 10026) { + if (isDiscordAPIError(e) && e.code === 10026) { // [10026]: Unknown Ban return false; } @@ -36,7 +36,7 @@ export async function isBanned( return false; } - if (isDiscordRESTError(e) && e.code === 50013) { + if (isDiscordAPIError(e) && e.code === 50013) { pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, { body: `Missing "Ban Members" permission to check for existing bans`, }); diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index dc68a245..229b8fbe 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -1,7 +1,7 @@ import { Message, Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { isDiscordRESTError } from "../../../utils"; +import { isDiscordAPIError } from "../../../utils"; import { reactionRolesCmd } from "../types"; export const ClearReactionRolesCmd = reactionRolesCmd({ @@ -25,7 +25,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ try { targetMessage = await args.message.channel.messages.fetch(args.message.messageId as Snowflake); } catch (err) { - if (isDiscordRESTError(err) && err.code === 50001) { + if (isDiscordAPIError(err) && err.code === 50001) { sendErrorMessage(pluginData, msg.channel, "Missing access to the specified message"); return; } diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index c118b973..dba3db59 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { canUseEmoji, isDiscordRESTError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; +import { canUseEmoji, isDiscordAPIError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; import { reactionRolesCmd, TReactionRolePair } from "../types"; import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; @@ -42,7 +42,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ try { targetMessage = await args.message.channel.messages.fetch(args.message.messageId as Snowflake).catch(noop); } catch (e) { - if (isDiscordRESTError(e)) { + if (isDiscordAPIError(e)) { sendErrorMessage(pluginData, msg.channel, `Error ${e.code} while getting message: ${e.message}`); return; } diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index c9e1e0f7..8dafc9fe 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -2,7 +2,7 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { ReactionRole } from "../../../data/entities/ReactionRole"; import { LogType } from "../../../data/LogType"; -import { isDiscordRESTError, sleep } from "../../../utils"; +import { isDiscordAPIError, sleep } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ReactionRolesPluginType } from "../types"; @@ -27,7 +27,7 @@ export async function applyReactionRoleReactionsToMessage( try { targetMessage = await channel.messages.fetch(messageId as Snowflake); } catch (e) { - if (isDiscordRESTError(e)) { + if (isDiscordAPIError(e)) { if (e.code === 10008) { // Unknown message, remove reaction roles from the message logs.log(LogType.BOT_ALERT, { @@ -51,7 +51,7 @@ export async function applyReactionRoleReactionsToMessage( try { await targetMessage.reactions.removeAll(); } catch (e) { - if (isDiscordRESTError(e)) { + if (isDiscordAPIError(e)) { errors.push(`Error ${e.code} while removing old reactions: ${e.message}`); logs.log(LogType.BOT_ALERT, { body: `Error ${e.code} while removing old reaction role reactions from message ${channelId}/${messageId}: ${e.message}`, @@ -73,7 +73,7 @@ export async function applyReactionRoleReactionsToMessage( await targetMessage.react(rawEmoji); await sleep(750); // Make sure we don't hit rate limits } catch (e) { - if (isDiscordRESTError(e)) { + if (isDiscordAPIError(e)) { if (e.code === 10014) { pluginData.state.reactionRoles.removeFromMessage(messageId, rawEmoji); errors.push(`Unknown emoji: ${rawEmoji}`); diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 94ec6dc3..45f35d58 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -2,7 +2,7 @@ import { GuildChannel, Permissions, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { isDiscordRESTError, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { isDiscordAPIError, stripObjectToScalars, UnknownUser } from "../../../utils"; import { SlowmodePluginType } from "../types"; export async function applyBotSlowmodeToUserId( @@ -24,7 +24,7 @@ export async function applyBotSlowmodeToUserId( } catch (e) { const user = pluginData.client.users.fetch(userId as Snowflake) || new UnknownUser({ id: userId }); - if (isDiscordRESTError(e) && e.code === 50013) { + if (isDiscordAPIError(e) && e.code === 50013) { logger.warn( `Missing permissions to apply bot slowmode to user ${userId} on channel ${channel.name} (${channel.id}) on server ${pluginData.guild.name} (${pluginData.guild.id})`, ); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index b05af8cf..9f549db7 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -70,13 +70,13 @@ export function isValidSnowflake(str: string) { } export const DISCORD_HTTP_ERROR_NAME = "DiscordHTTPError"; -export const DISCORD_REST_ERROR_NAME = "DiscordRESTError"; +export const DISCORD_REST_ERROR_NAME = "DiscordAPIError"; export function isDiscordHTTPError(err: Error | string) { return typeof err === "object" && err.constructor?.name === DISCORD_HTTP_ERROR_NAME; } -export function isDiscordRESTError(err: Error | string) { +export function isDiscordAPIError(err: Error | string) { return typeof err === "object" && err.constructor?.name === DISCORD_REST_ERROR_NAME; } @@ -470,7 +470,7 @@ export async function findRelevantAuditLogEntry( try { auditLogs = await guild.fetchAuditLogs({ limit: 5, type: actionType }); } catch (e) { - if (isDiscordRESTError(e) && e.code === 50013) { + if (isDiscordAPIError(e) && e.code === 50013) { // If we don't have permission to read audit log, set audit log requests on cooldown auditLogNextAttemptAfterFail.set(guild.id, Date.now() + AUDIT_LOG_FAIL_COOLDOWN); } else if (isDiscordHTTPError(e) && e.code === 500) { diff --git a/backend/src/utils/safeFindRelevantAuditLogEntry.ts b/backend/src/utils/safeFindRelevantAuditLogEntry.ts index 4b83510b..8845e52e 100644 --- a/backend/src/utils/safeFindRelevantAuditLogEntry.ts +++ b/backend/src/utils/safeFindRelevantAuditLogEntry.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { LogType } from "../data/LogType"; import { LogsPlugin } from "../plugins/Logs/LogsPlugin"; -import { findRelevantAuditLogEntry, isDiscordRESTError } from "../utils"; +import { findRelevantAuditLogEntry, isDiscordAPIError } from "../utils"; /** * Wrapper for findRelevantAuditLogEntry() that handles permission errors gracefully. @@ -17,7 +17,7 @@ export async function safeFindRelevantAuditLogEntry( try { return await findRelevantAuditLogEntry(pluginData.guild, actionType, userId, attempts, attemptDelay); } catch (e) { - if (isDiscordRESTError(e) && e.code === 50013) { + if (isDiscordAPIError(e) && e.code === 50013) { const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.BOT_ALERT, { body: "Missing permissions to read audit log", diff --git a/backend/src/utils/sendDM.ts b/backend/src/utils/sendDM.ts index 851efcb5..7cfc3f87 100644 --- a/backend/src/utils/sendDM.ts +++ b/backend/src/utils/sendDM.ts @@ -1,6 +1,6 @@ import { MessagePayload, User } from "discord.js"; import { logger } from "../logger"; -import { createChunkedMessage, HOURS, isDiscordRESTError } from "../utils"; +import { createChunkedMessage, HOURS, isDiscordAPIError } from "../utils"; import Timeout = NodeJS.Timeout; let dmsDisabled = false; @@ -30,7 +30,7 @@ export async function sendDM(user: User, content: string | MessagePayload, sourc await user.send(content); } } catch (e) { - if (isDiscordRESTError(e) && e.code === 20026) { + if (isDiscordAPIError(e) && e.code === 20026) { logger.warn(`Received error code 20026: ${e.message}`); logger.warn("Disabling attempts to send DMs for 1 hour"); disableDMs(1 * HOURS); diff --git a/package-lock.json b/package-lock.json index 308ef9b3..21898d07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "prettier": "^1.19.1", "tslint": "^5.13.1", "tslint-config-prettier": "^1.18.0", - "typescript": "^4.1.3" + "typescript": "^4.3.4" } }, "node_modules/@babel/code-frame": { @@ -1975,9 +1975,9 @@ } }, "node_modules/typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", + "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -3611,9 +3611,9 @@ "dev": true }, "typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", + "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==", "dev": true }, "validate-npm-package-license": { diff --git a/package.json b/package.json index 1c3f821c..0c1f6d68 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "prettier": "^1.19.1", "tslint": "^5.13.1", "tslint-config-prettier": "^1.18.0", - "typescript": "^4.1.3" + "typescript": "^4.3.4" }, "husky": { "hooks": { From bb9b8cfe06437cc1b977f2e7f410ebaef4c65f5f Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 1 Jul 2021 00:30:48 +0200 Subject: [PATCH 25/79] Proper button validation, bugfix for voice move spam --- .../src/plugins/ReactionRoles/ReactionRolesPlugin.ts | 10 ++++++++++ backend/src/plugins/Spam/events/SpamVoiceEvt.ts | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 47aa4c64..1c841457 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -63,6 +63,11 @@ const configPreprocessor: ConfigPreprocessorFn = option `Invalid value for default_buttons/${defaultButtonNames[i]}/role_or_menu: ${defBtn.role_or_menu} is neither an existing menu nor a valid snowflake.`, ]); } + if (!defBtn.label && !defBtn.emoji) { + throw new StrictValidationError([ + `Invalid values for default_buttons/${defaultButtonNames[i]}/(label|emoji): Must have label, emoji or both set for the button to be valid.`, + ]); + } } for (const [menuName, menuButtonEntries] of Object.entries(group.button_menus ?? [])) { @@ -83,6 +88,11 @@ const configPreprocessor: ConfigPreprocessorFn = option `Invalid value for button_menus/${menuButtonNames[i]}/role_or_menu: ${menuBtn.role_or_menu} is neither an existing menu nor a valid snowflake.`, ]); } + if (!menuBtn.label && !menuBtn.emoji) { + throw new StrictValidationError([ + `Invalid values for default_buttons/${defaultButtonNames[i]}/(label|emoji): Must have label, emoji or both set for the button to be valid.`, + ]); + } } } } diff --git a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts index 7e862325..36aba638 100644 --- a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts +++ b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts @@ -7,7 +7,8 @@ export const SpamVoiceStateUpdateEvt = spamEvt({ async listener(meta) { const member = meta.args.newState.member; if (!member) return; - const channel = meta.args.newState.channel!; + const channel = meta.args.newState.channel; + if (!channel) return; const config = await meta.pluginData.config.getMatchingConfig({ member, channelId: channel.id }); const maxVoiceMoves = config.max_voice_moves; From 144c9c43e0ca6fb827e63027dd7e613f1f1c73f4 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 1 Jul 2021 02:21:16 +0200 Subject: [PATCH 26/79] Add logging for threads and stages --- backend/src/data/DefaultLogMessages.json | 8 ++++ backend/src/data/LogType.ts | 8 ++++ backend/src/plugins/Logs/LogsPlugin.ts | 12 +++++ .../events/LogsStageInstanceModifyEvts.ts | 46 +++++++++++++++++++ .../Logs/events/LogsThreadModifyEvts.ts | 34 ++++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts create mode 100644 backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts diff --git a/backend/src/data/DefaultLogMessages.json b/backend/src/data/DefaultLogMessages.json index 0c6c010e..2f00d39c 100644 --- a/backend/src/data/DefaultLogMessages.json +++ b/backend/src/data/DefaultLogMessages.json @@ -26,6 +26,10 @@ "CHANNEL_DELETE": "🗑 Channel {channelMention(channel)} was deleted", "CHANNEL_EDIT": "✏ Channel {channelMention(channel)} was edited", + "THREAD_CREATE": "🖊 Thread {channelMention(thread)} was created in channel <#{thread.parentID}>", + "THREAD_DELETE": "🗑 Thread {channelMention(thread)} was deleted/archived from channel <#{thread.parentID}>", + "THREAD_UPDATE": "✏ Thread {channelMention(newThread)} was edited. Previous name: `{oldThread.name}`", + "ROLE_CREATE": "🖊 Role **{role.name}** (`{role.id}`) was created", "ROLE_DELETE": "🖊 Role **{role.name}** (`{role.id}`) was deleted", "ROLE_EDIT": "🖊 Role **{role.name}** (`{role.id}`) was edited", @@ -42,6 +46,10 @@ "VOICE_CHANNEL_FORCE_MOVE": "\uD83C\uDF99 ✍ {userMention(member)} was moved from **{oldChannel.name}** to **{newChannel.name}** by {userMention(mod)}", "VOICE_CHANNEL_FORCE_DISCONNECT": "\uD83C\uDF99 🚫 {userMention(member)} was forcefully disconnected from **{oldChannel.name}** by {userMention(mod)}", + "STAGE_INSTANCE_CREATE": "📣 Stage Instance `{stageInstance.topic}` was created in Stage Channel <#{stageChannel.id}>", + "STAGE_INSTANCE_DELETE": "📣 Stage Instance `{stageInstance.topic}` was deleted in Stage Channel <#{stageChannel.id}>", + "STAGE_INSTANCE_UPDATE": "📣 Stage Instance `{newStageInstance.topic}` was edited in Stage Channel <#{stageChannel.id}>. Previous topic: `{oldStageInstance.topic}`", + "COMMAND": "🤖 {userMention(member)} used command in {channelMention(channel)}:\n`{command}`", "MESSAGE_SPAM_DETECTED": "🛑 {userMention(member)} spam detected in {channelMention(channel)}: {description} (more than {limit} in {interval}s)\n{archiveUrl}", diff --git a/backend/src/data/LogType.ts b/backend/src/data/LogType.ts index bc62cd02..c01610e2 100644 --- a/backend/src/data/LogType.ts +++ b/backend/src/data/LogType.ts @@ -19,6 +19,10 @@ export enum LogType { CHANNEL_CREATE, CHANNEL_DELETE, + THREAD_CREATE, + THREAD_DELETE, + THREAD_UPDATE, + ROLE_CREATE, ROLE_DELETE, @@ -31,6 +35,10 @@ export enum LogType { VOICE_CHANNEL_LEAVE, VOICE_CHANNEL_MOVE, + STAGE_INSTANCE_CREATE, + STAGE_INSTANCE_DELETE, + STAGE_INSTANCE_UPDATE, + COMMAND, MESSAGE_SPAM_DETECTED, diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 6de27037..8c8520be 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -15,6 +15,12 @@ import { LogsChannelCreateEvt, LogsChannelDeleteEvt } from "./events/LogsChannel import { LogsGuildMemberAddEvt } from "./events/LogsGuildMemberAddEvt"; import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt"; import { LogsRoleCreateEvt, LogsRoleDeleteEvt } from "./events/LogsRoleModifyEvts"; +import { + LogsStageInstanceCreateEvt, + LogsStageInstanceDeleteEvt, + LogsStageInstanceUpdateEvt, +} from "./events/LogsStageInstanceModifyEvts"; +import { LogsThreadCreateEvt, LogsThreadDeleteEvt, LogsThreadUpdateEvt } from "./events/LogsThreadModifyEvts"; import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts"; import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts"; import { ConfigSchema, FORMAT_NO_TIMESTAMP, LogsPluginType } from "./types"; @@ -67,6 +73,12 @@ export const LogsPlugin = zeppelinGuildPlugin()({ LogsRoleCreateEvt, LogsRoleDeleteEvt, LogsVoiceStateUpdateEvt, + LogsStageInstanceCreateEvt, + LogsStageInstanceDeleteEvt, + LogsStageInstanceUpdateEvt, + LogsThreadCreateEvt, + LogsThreadDeleteEvt, + LogsThreadUpdateEvt, ], public: { diff --git a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts new file mode 100644 index 00000000..25b68a53 --- /dev/null +++ b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts @@ -0,0 +1,46 @@ +import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars } from "../../../utils"; +import { logsEvt } from "../types"; + +export const LogsStageInstanceCreateEvt = logsEvt({ + event: "stageInstanceCreate", + + async listener(meta) { + const stageChannel = + meta.args.stageInstance.channel ?? + (await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelID)); + meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_CREATE, { + stageInstance: stripObjectToScalars(meta.args.stageInstance), + stageChannel: stripObjectToScalars(stageChannel), + }); + }, +}); + +export const LogsStageInstanceDeleteEvt = logsEvt({ + event: "stageInstanceDelete", + + async listener(meta) { + const stageChannel = + meta.args.stageInstance.channel ?? + (await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelID)); + meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_DELETE, { + stageInstance: stripObjectToScalars(meta.args.stageInstance), + stageChannel: stripObjectToScalars(stageChannel), + }); + }, +}); + +export const LogsStageInstanceUpdateEvt = logsEvt({ + event: "stageInstanceUpdate", + + async listener(meta) { + const stageChannel = + meta.args.newStageInstance.channel ?? + (await meta.pluginData.guild.channels.fetch(meta.args.newStageInstance.channelID)); + meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_UPDATE, { + oldStageInstance: stripObjectToScalars(meta.args.oldStageInstance), + newStageInstance: stripObjectToScalars(meta.args.newStageInstance), + stageChannel: stripObjectToScalars(stageChannel), + }); + }, +}); diff --git a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts new file mode 100644 index 00000000..bb5c4b5d --- /dev/null +++ b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts @@ -0,0 +1,34 @@ +import { LogType } from "../../../data/LogType"; +import { stripObjectToScalars } from "../../../utils"; +import { logsEvt } from "../types"; + +export const LogsThreadCreateEvt = logsEvt({ + event: "threadCreate", + + async listener(meta) { + meta.pluginData.state.guildLogs.log(LogType.THREAD_CREATE, { + thread: stripObjectToScalars(meta.args.thread), + }); + }, +}); + +export const LogsThreadDeleteEvt = logsEvt({ + event: "threadDelete", + + async listener(meta) { + meta.pluginData.state.guildLogs.log(LogType.THREAD_DELETE, { + thread: stripObjectToScalars(meta.args.thread), + }); + }, +}); + +export const LogsThreadUpdateEvt = logsEvt({ + event: "threadUpdate", + + async listener(meta) { + meta.pluginData.state.guildLogs.log(LogType.THREAD_UPDATE, { + oldThread: stripObjectToScalars(meta.args.oldThread), + newThread: stripObjectToScalars(meta.args.newThread), + }); + }, +}); From 968889e529b9d7809c696f29caaafc563f22f962 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 1 Jul 2021 04:40:39 +0200 Subject: [PATCH 27/79] Add missing logtypes, add change visualization --- backend/src/data/DefaultLogMessages.json | 8 +++--- backend/src/data/LogType.ts | 2 ++ backend/src/plugins/Logs/LogsPlugin.ts | 6 +++-- .../Logs/events/LogsChannelModifyEvts.ts | 17 +++++++++++- .../plugins/Logs/events/LogsRoleModifyEvts.ts | 17 +++++++++++- .../events/LogsStageInstanceModifyEvts.ts | 7 ++++- .../Logs/events/LogsThreadModifyEvts.ts | 6 ++++- backend/src/utils.ts | 27 +++++++++++++++++++ 8 files changed, 80 insertions(+), 10 deletions(-) diff --git a/backend/src/data/DefaultLogMessages.json b/backend/src/data/DefaultLogMessages.json index 2f00d39c..fccdb1ed 100644 --- a/backend/src/data/DefaultLogMessages.json +++ b/backend/src/data/DefaultLogMessages.json @@ -24,15 +24,15 @@ "CHANNEL_CREATE": "🖊 Channel {channelMention(channel)} was created", "CHANNEL_DELETE": "🗑 Channel {channelMention(channel)} was deleted", - "CHANNEL_EDIT": "✏ Channel {channelMention(channel)} was edited", + "CHANNEL_UPDATE": "✏ Channel {channelMention(newChannel)} was edited. Changes:\n{differenceString}", "THREAD_CREATE": "🖊 Thread {channelMention(thread)} was created in channel <#{thread.parentID}>", "THREAD_DELETE": "🗑 Thread {channelMention(thread)} was deleted/archived from channel <#{thread.parentID}>", - "THREAD_UPDATE": "✏ Thread {channelMention(newThread)} was edited. Previous name: `{oldThread.name}`", + "THREAD_UPDATE": "✏ Thread {channelMention(newThread)} was edited. Changes:\n{differenceString}", "ROLE_CREATE": "🖊 Role **{role.name}** (`{role.id}`) was created", "ROLE_DELETE": "🖊 Role **{role.name}** (`{role.id}`) was deleted", - "ROLE_EDIT": "🖊 Role **{role.name}** (`{role.id}`) was edited", + "ROLE_UPDATE": "🖊 Role **{newRole.name}** (`{newRole.id}`) was edited. Changes:\n{differenceString}", "MESSAGE_EDIT": "✏ {userMention(user)} edited their message (`{after.id}`) in {channelMention(channel)}:\n**Before:**{messageSummary(before)}**After:**{messageSummary(after)}", "MESSAGE_DELETE": "🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}", @@ -48,7 +48,7 @@ "STAGE_INSTANCE_CREATE": "📣 Stage Instance `{stageInstance.topic}` was created in Stage Channel <#{stageChannel.id}>", "STAGE_INSTANCE_DELETE": "📣 Stage Instance `{stageInstance.topic}` was deleted in Stage Channel <#{stageChannel.id}>", - "STAGE_INSTANCE_UPDATE": "📣 Stage Instance `{newStageInstance.topic}` was edited in Stage Channel <#{stageChannel.id}>. Previous topic: `{oldStageInstance.topic}`", + "STAGE_INSTANCE_UPDATE": "📣 Stage Instance `{newStageInstance.topic}` was edited in Stage Channel <#{stageChannel.id}>. Changes:\n{differenceString}", "COMMAND": "🤖 {userMention(member)} used command in {channelMention(channel)}:\n`{command}`", diff --git a/backend/src/data/LogType.ts b/backend/src/data/LogType.ts index c01610e2..eb6e66e5 100644 --- a/backend/src/data/LogType.ts +++ b/backend/src/data/LogType.ts @@ -18,6 +18,7 @@ export enum LogType { CHANNEL_CREATE, CHANNEL_DELETE, + CHANNEL_UPDATE, THREAD_CREATE, THREAD_DELETE, @@ -25,6 +26,7 @@ export enum LogType { ROLE_CREATE, ROLE_DELETE, + ROLE_UPDATE, MESSAGE_EDIT, MESSAGE_DELETE, diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 8c8520be..64c62444 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -11,10 +11,10 @@ import { disableCodeBlocks } from "../../utils"; import { CasesPlugin } from "../Cases/CasesPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { LogsChannelCreateEvt, LogsChannelDeleteEvt } from "./events/LogsChannelModifyEvts"; +import { LogsChannelCreateEvt, LogsChannelDeleteEvt, LogsChannelUpdateEvt } from "./events/LogsChannelModifyEvts"; import { LogsGuildMemberAddEvt } from "./events/LogsGuildMemberAddEvt"; import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt"; -import { LogsRoleCreateEvt, LogsRoleDeleteEvt } from "./events/LogsRoleModifyEvts"; +import { LogsRoleCreateEvt, LogsRoleDeleteEvt, LogsRoleUpdateEvt } from "./events/LogsRoleModifyEvts"; import { LogsStageInstanceCreateEvt, LogsStageInstanceDeleteEvt, @@ -70,8 +70,10 @@ export const LogsPlugin = zeppelinGuildPlugin()({ LogsGuildMemberUpdateEvt, LogsChannelCreateEvt, LogsChannelDeleteEvt, + LogsChannelUpdateEvt, LogsRoleCreateEvt, LogsRoleDeleteEvt, + LogsRoleUpdateEvt, LogsVoiceStateUpdateEvt, LogsStageInstanceCreateEvt, LogsStageInstanceDeleteEvt, diff --git a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts index fb7b9e74..8c5f7c0a 100644 --- a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts @@ -1,5 +1,5 @@ import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; +import { differenceToString, getScalarDifference, stripObjectToScalars } from "../../../utils"; import { logsEvt } from "../types"; export const LogsChannelCreateEvt = logsEvt({ @@ -21,3 +21,18 @@ export const LogsChannelDeleteEvt = logsEvt({ }); }, }); + +export const LogsChannelUpdateEvt = logsEvt({ + event: "channelUpdate", + + async listener(meta) { + const diff = getScalarDifference(meta.args.oldChannel, meta.args.newChannel); + const differenceString = differenceToString(diff); + + meta.pluginData.state.guildLogs.log(LogType.CHANNEL_UPDATE, { + oldChannel: stripObjectToScalars(meta.args.oldChannel), + newChannel: stripObjectToScalars(meta.args.newChannel), + differenceString, + }); + }, +}); diff --git a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts index 7c5f2108..729deaab 100644 --- a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts @@ -1,5 +1,5 @@ import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; +import { differenceToString, getScalarDifference, stripObjectToScalars } from "../../../utils"; import { logsEvt } from "../types"; export const LogsRoleCreateEvt = logsEvt({ @@ -21,3 +21,18 @@ export const LogsRoleDeleteEvt = logsEvt({ }); }, }); + +export const LogsRoleUpdateEvt = logsEvt({ + event: "roleUpdate", + + async listener(meta) { + const diff = getScalarDifference(meta.args.oldRole, meta.args.newRole); + const differenceString = differenceToString(diff); + + meta.pluginData.state.guildLogs.log(LogType.ROLE_UPDATE, { + newRole: stripObjectToScalars(meta.args.newRole), + oldRole: stripObjectToScalars(meta.args.oldRole), + differenceString, + }); + }, +}); diff --git a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts index 25b68a53..6ce0b98a 100644 --- a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts @@ -1,5 +1,5 @@ import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; +import { differenceToString, getScalarDifference, stripObjectToScalars } from "../../../utils"; import { logsEvt } from "../types"; export const LogsStageInstanceCreateEvt = logsEvt({ @@ -37,10 +37,15 @@ export const LogsStageInstanceUpdateEvt = logsEvt({ const stageChannel = meta.args.newStageInstance.channel ?? (await meta.pluginData.guild.channels.fetch(meta.args.newStageInstance.channelID)); + + const diff = getScalarDifference(meta.args.oldStageInstance, meta.args.newStageInstance); + const differenceString = differenceToString(diff); + meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_UPDATE, { oldStageInstance: stripObjectToScalars(meta.args.oldStageInstance), newStageInstance: stripObjectToScalars(meta.args.newStageInstance), stageChannel: stripObjectToScalars(stageChannel), + differenceString, }); }, }); diff --git a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts index bb5c4b5d..0ed7af00 100644 --- a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts @@ -1,5 +1,5 @@ import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; +import { stripObjectToScalars, getScalarDifference, differenceToString } from "../../../utils"; import { logsEvt } from "../types"; export const LogsThreadCreateEvt = logsEvt({ @@ -26,9 +26,13 @@ export const LogsThreadUpdateEvt = logsEvt({ event: "threadUpdate", async listener(meta) { + const diff = getScalarDifference(meta.args.oldThread, meta.args.newThread, ["messageCount", "archiveTimestamp"]); + const differenceString = differenceToString(diff); + meta.pluginData.state.guildLogs.log(LogType.THREAD_UPDATE, { oldThread: stripObjectToScalars(meta.args.oldThread), newThread: stripObjectToScalars(meta.args.newThread), + differenceString, }); }, }); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 9f549db7..f9d9094a 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -35,6 +35,7 @@ import { SimpleCache } from "./SimpleCache"; import { sendDM } from "./utils/sendDM"; import { waitForButtonConfirm } from "./utils/waitForInteraction"; import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; +import { isEqual } from "lodash"; const fsp = fs.promises; @@ -165,6 +166,32 @@ function tDeepPartialProp(prop: any) { } } +export function getScalarDifference( + base: T, + object: T, + ignoreKeys: string[] = [], +): Map { + base = stripObjectToScalars(base) as T; + object = stripObjectToScalars(object) as T; + const diff = new Map(); + + for (const [key, value] of Object.entries(object)) { + if (!isEqual(value, base[key]) && !ignoreKeys.includes(key)) { + diff.set(key, { was: base[key], is: value }); + } + } + + return diff; +} + +export function differenceToString(diff: Map): string { + let toReturn = ""; + for (const [key, difference] of diff) { + toReturn += `${key[0].toUpperCase() + key.slice(1)}: \`${difference.was}\` ➜ \`${difference.is}\`\n`; + } + return toReturn; +} + // https://stackoverflow.com/a/49262929/316944 export type Not = T & Exclude; From ac619ec00fbe4bd8bab9d8c70b81d41c7ade2904 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 1 Jul 2021 04:42:44 +0200 Subject: [PATCH 28/79] Update DJS --- backend/package-lock.json | 18 +++++++++--------- backend/package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 60a8e66b..fe1ac44e 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.64f093f.1625054868", + "discord.js": "^13.0.0-dev.a08ce7d.1625097834", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -83,7 +83,7 @@ "dependencies": { "@discordjs/voice": "^0.5.1", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.64f093f.1625054868", + "discord.js": "^13.0.0-dev.a08ce7d.1625097834", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -2160,9 +2160,9 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.64f093f.1625054868", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.64f093f.1625054868.tgz", - "integrity": "sha512-CgpgvpcALYmEhgGETAxFHMqt+XmuTbcSYIN+kLyzualzHNQ2RageW3tslgLgSnBdID60AMvXN/nzMuEn/J6rAA==", + "version": "13.0.0-dev.a08ce7d.1625097834", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a08ce7d.1625097834.tgz", + "integrity": "sha512-JqtGLMxXWKebpV8t4WV/kfCnTdkH4XCQceWcaYH3kZatXHiUNDzypv/Qgi5e8ioSeVKWMQzAaxg5Epm8bpOfZw==", "dependencies": { "@discordjs/builders": "^0.1.1", "@discordjs/collection": "^0.1.6", @@ -8035,9 +8035,9 @@ "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" }, "discord.js": { - "version": "13.0.0-dev.64f093f.1625054868", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.64f093f.1625054868.tgz", - "integrity": "sha512-CgpgvpcALYmEhgGETAxFHMqt+XmuTbcSYIN+kLyzualzHNQ2RageW3tslgLgSnBdID60AMvXN/nzMuEn/J6rAA==", + "version": "13.0.0-dev.a08ce7d.1625097834", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a08ce7d.1625097834.tgz", + "integrity": "sha512-JqtGLMxXWKebpV8t4WV/kfCnTdkH4XCQceWcaYH3kZatXHiUNDzypv/Qgi5e8ioSeVKWMQzAaxg5Epm8bpOfZw==", "requires": { "@discordjs/builders": "^0.1.1", "@discordjs/collection": "^0.1.6", @@ -8880,7 +8880,7 @@ "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.64f093f.1625054868", + "discord.js": "^13.0.0-dev.a08ce7d.1625097834", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", diff --git a/backend/package.json b/backend/package.json index 88c84cb7..68a57222 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.64f093f.1625054868", + "discord.js": "^13.0.0-dev.a08ce7d.1625097834", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", From 5e73d380c5a9b1a9a4f0caf5d247eb759bc77e7c Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 4 Jul 2021 17:41:44 +0200 Subject: [PATCH 29/79] Update DJS --- backend/package-lock.json | 34 +++++++++---------- backend/package.json | 2 +- backend/src/index.ts | 4 +-- .../AutoReactions/events/AddReactionsEvt.ts | 2 +- .../plugins/Cases/functions/getCaseEmbed.ts | 4 +-- .../functions/handleCompanionPermissions.ts | 4 +-- .../CustomEvents/actions/addRoleAction.ts | 3 +- .../actions/setChannelPermissionOverrides.ts | 11 ++++-- .../MessageSaver/events/SaveMessagesEvts.ts | 2 +- .../src/plugins/Mutes/commands/MutesCmd.ts | 2 +- .../events/ReapplyActiveMuteOnJoinEvt.ts | 3 +- .../Mutes/functions/clearExpiredMutes.ts | 4 +-- .../src/plugins/Mutes/functions/muteUser.ts | 6 ++-- .../src/plugins/Mutes/functions/unmuteUser.ts | 4 +-- .../NameHistory/events/UpdateNameEvts.ts | 2 +- .../events/ChangePingableEvts.ts | 2 +- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 2 +- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 15 ++++---- .../util/clearBotSlowmodeFromUserId.ts | 2 +- .../events/UpdateUsernameEvts.ts | 2 +- backend/src/plugins/Utility/search.ts | 2 +- backend/src/utils/createPaginatedMessage.ts | 13 +++++-- backend/src/utils/waitForInteraction.ts | 2 +- 23 files changed, 71 insertions(+), 56 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index fe1ac44e..3c496965 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.a08ce7d.1625097834", + "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -83,7 +83,7 @@ "dependencies": { "@discordjs/voice": "^0.5.1", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.a08ce7d.1625097834", + "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -162,9 +162,9 @@ } }, "node_modules/@discordjs/builders": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.1.1.tgz", - "integrity": "sha512-9eBC22bX2HBsob5ixMwZ6quy/vewU5GHuSJhpmSZ3cDGg8XPnrYdzbwI54U+V9kQBTa7M+aMu1lYVqMEPojj8A==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.2.0.tgz", + "integrity": "sha512-TVq7NZBCJrrTRc3CfxOr3IdgY5nrtqVxZ7qDUF1mN6LgxIiOldmFxsSwMrQBzLFVmOwqFyNLKCeblley8UpEuw==", "dependencies": { "discord-api-types": "^0.18.1", "tslib": "^2.3.0" @@ -2160,11 +2160,11 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.a08ce7d.1625097834", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a08ce7d.1625097834.tgz", - "integrity": "sha512-JqtGLMxXWKebpV8t4WV/kfCnTdkH4XCQceWcaYH3kZatXHiUNDzypv/Qgi5e8ioSeVKWMQzAaxg5Epm8bpOfZw==", + "version": "13.0.0-dev.ab0b3b9.1625400166", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.ab0b3b9.1625400166.tgz", + "integrity": "sha512-nTdUyPEvy1OxCoSXVJrJDFMxEIEUr/NIpuf8x0gz0XTdrghDrGR756hX4KuqGT12fm9PpqciyT+52f7fkzIxCQ==", "dependencies": { - "@discordjs/builders": "^0.1.1", + "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", @@ -6438,9 +6438,9 @@ } }, "@discordjs/builders": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.1.1.tgz", - "integrity": "sha512-9eBC22bX2HBsob5ixMwZ6quy/vewU5GHuSJhpmSZ3cDGg8XPnrYdzbwI54U+V9kQBTa7M+aMu1lYVqMEPojj8A==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.2.0.tgz", + "integrity": "sha512-TVq7NZBCJrrTRc3CfxOr3IdgY5nrtqVxZ7qDUF1mN6LgxIiOldmFxsSwMrQBzLFVmOwqFyNLKCeblley8UpEuw==", "requires": { "discord-api-types": "^0.18.1", "tslib": "^2.3.0" @@ -8035,11 +8035,11 @@ "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" }, "discord.js": { - "version": "13.0.0-dev.a08ce7d.1625097834", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a08ce7d.1625097834.tgz", - "integrity": "sha512-JqtGLMxXWKebpV8t4WV/kfCnTdkH4XCQceWcaYH3kZatXHiUNDzypv/Qgi5e8ioSeVKWMQzAaxg5Epm8bpOfZw==", + "version": "13.0.0-dev.ab0b3b9.1625400166", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.ab0b3b9.1625400166.tgz", + "integrity": "sha512-nTdUyPEvy1OxCoSXVJrJDFMxEIEUr/NIpuf8x0gz0XTdrghDrGR756hX4KuqGT12fm9PpqciyT+52f7fkzIxCQ==", "requires": { - "@discordjs/builders": "^0.1.1", + "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", @@ -8880,7 +8880,7 @@ "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.a08ce7d.1625097834", + "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", diff --git a/backend/package.json b/backend/package.json index 68a57222..5b045bca 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.a08ce7d.1625097834", + "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/index.ts b/backend/src/index.ts index 560e5f45..83146fe2 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -263,8 +263,8 @@ connect().then(async () => { startUptimeCounter(); }); + bot.initialize(); + logger.info("Bot Initialized"); logger.info("Logging in..."); await client.login(process.env.token); - logger.info("Initializing the bot"); - bot.initialize(); }); diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index fc96efc6..7f868af1 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -10,7 +10,7 @@ import { autoReactionsEvt } from "../types"; const p = Permissions.FLAGS; export const AddReactionsEvt = autoReactionsEvt({ - event: "message", + event: "messageCreate", allowBots: true, allowSelf: true, diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index 90c051c5..93ee02ef 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -1,4 +1,4 @@ -import { MessageOptions } from "discord.js"; +import { MessageEditOptions, MessageOptions } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -14,7 +14,7 @@ export async function getCaseEmbed( caseOrCaseId: Case | number, requestMemberId?: string, noOriginalCaseLink?: boolean, -): Promise { +): Promise { const theCase = await pluginData.state.cases.with("notes").find(resolveCaseId(caseOrCaseId)); if (!theCase) { throw new Error("Unknown case"); diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index de83899b..23131dfb 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -54,14 +54,14 @@ export async function handleCompanionPermissions( const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel || !(channel instanceof TextChannel)) continue; await channel.permissionOverwrites - .get(userId as Snowflake) + .resolve(userId as Snowflake) ?.delete(`Companion Channel for ${oldChannel!.id} | User Left`); } for (const [channelId, permissions] of permsToSet) { const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel || !(channel instanceof TextChannel)) continue; - await channel.updateOverwrite(userId, new Permissions(BigInt(permissions)).serialize(), { + await channel.permissionOverwrites.create(userId as Snowflake, new Permissions(BigInt(permissions)).serialize(), { reason: `Companion Channel for ${voiceChannel!.id} | User Joined`, }); } diff --git a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts index b5549bce..d4f1b61a 100644 --- a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts +++ b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { canActOn } from "../../../pluginUtils"; @@ -30,6 +31,6 @@ export async function addRoleAction( const rolesToAdd = Array.isArray(action.role) ? action.role : [action.role]; await target.edit({ - roles: Array.from(new Set([...target.roles.cache.array(), ...rolesToAdd])), + roles: Array.from(new Set([...target.roles.cache.array(), ...rolesToAdd])) as Snowflake[], }); } diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index e9497ed1..80acd61c 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Permissions, Snowflake, TextChannel } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { ActionError } from "../ActionError"; @@ -31,9 +31,16 @@ export async function setChannelPermissionOverridesAction( } for (const override of action.overrides) { - await channel.overwritePermissions( + channel.permissionOverwrites.create( + override.id as Snowflake, + new Permissions(BigInt(override.allow)).add(BigInt(override.deny)).serialize(), + ); + + /* + await channel.permissionOverwrites overwritePermissions( [{ id: override.id, allow: BigInt(override.allow), deny: BigInt(override.deny), type: override.type }], `Custom event: ${event.name}`, ); + */ } } diff --git a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts index c9b093cd..97f4fe6d 100644 --- a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts +++ b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts @@ -2,7 +2,7 @@ import { Message } from "discord.js"; import { messageSaverEvt } from "../types"; export const MessageCreateEvt = messageSaverEvt({ - event: "message", + event: "messageCreate", allowBots: true, allowSelf: true, diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 666d6c94..207693ec 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -213,7 +213,7 @@ export const MutesCmd = mutesCmd({ await listMessage.edit({ components: [row] }); const filter = (iac: MessageComponentInteraction) => iac.message.id === listMessage.id; - const collector = listMessage.createMessageComponentInteractionCollector({ + const collector = listMessage.createMessageComponentCollector({ filter, time: stopCollectionDebounce, }); diff --git a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts index a1a942fa..749d194a 100644 --- a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts +++ b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars } from "../../../utils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; @@ -15,7 +16,7 @@ export const ReapplyActiveMuteOnJoinEvt = mutesEvt({ if (muteRole) { const memberRoleLock = await pluginData.locks.acquire(memberRolesLock(member)); - await member.roles.add(muteRole); + await member.roles.add(muteRole as Snowflake); memberRoleLock.unlock(); } diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index 9217e1a2..efd6a2bd 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -16,7 +16,7 @@ export async function clearExpiredMutes(pluginData: GuildPluginData x.managed).map(y => y.id); newRoles = currentUserRoles.filter(r => !managedRoles.includes(r)); - await member.roles.set(newRoles); + await member.roles.set(newRoles as Snowflake[]); } } else { newRoles = currentUserRoles.filter(x => !(removeRoles).includes(x)); - await member.roles.set(newRoles); + await member.roles.set(newRoles as Snowflake[]); } // set roles to be restored @@ -88,7 +88,7 @@ export async function muteUser( // Apply mute role if it's missing if (!currentUserRoles.includes(muteRole as Snowflake)) { try { - await member.roles.add(muteRole); + await member.roles.add(muteRole as Snowflake); } catch (e) { const actualMuteRole = pluginData.guild.roles.cache.find(x => x.id === muteRole); if (!actualMuteRole) { diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index 437baf31..f1b35db8 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -37,7 +37,7 @@ export async function unmuteUser( const muteRole = pluginData.config.get().mute_role; if (muteRole && member.roles.cache.has(muteRole as Snowflake)) { - await member.roles.remove(muteRole); + await member.roles.remove(muteRole as Snowflake); } if (existingMute?.roles_to_restore) { const guildRoles = pluginData.guild.roles.cache; @@ -46,7 +46,7 @@ export async function unmuteUser( for (const toRestore of existingMute.roles_to_restore) { if (guildRoles.has(toRestore as Snowflake) && toRestore !== muteRole) newRoles.push(toRestore); } - await member.roles.set(newRoles); + await member.roles.set(newRoles as Snowflake[]); } lock.unlock(); diff --git a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts index 706c93cc..c41e2cc9 100644 --- a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts +++ b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts @@ -15,7 +15,7 @@ export const ChannelJoinEvt = nameHistoryEvt({ }); export const MessageCreateEvt = nameHistoryEvt({ - event: "message", + event: "messageCreate", async listener(meta) { meta.pluginData.state.updateQueue.add(() => updateNickname(meta.pluginData, meta.args.message.member!)); diff --git a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts index 23c4627c..8153f094 100644 --- a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts +++ b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts @@ -29,7 +29,7 @@ export const TypingEnablePingableEvt = pingableRolesEvt({ }); export const MessageCreateDisablePingableEvt = pingableRolesEvt({ - event: "message", + event: "messageCreate", async listener(meta) { const pluginData = meta.pluginData; diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index 9943a9bb..0568ea41 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -80,7 +80,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ try { await msg.member.edit({ - roles: Array.from(newRoleIds), + roles: Array.from(newRoleIds) as Snowflake[], }); } catch { sendErrorMessage( diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 45f35d58..bcc32d55 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -11,16 +11,13 @@ export async function applyBotSlowmodeToUserId( userId: string, ) { // Deny sendMessage permission from the user. If there are existing permission overwrites, take those into account. - const existingOverride = channel.permissionOverwrites.get(userId as Snowflake); - const newDeniedPermissions = - (existingOverride ? existingOverride.deny.bitfield : 0n) | Permissions.FLAGS.SEND_MESSAGES; - const newAllowedPermissions = - (existingOverride ? existingOverride.allow.bitfield : 0n) & ~Permissions.FLAGS.SEND_MESSAGES; - + const existingOverride = channel.permissionOverwrites.resolve(userId as Snowflake); try { - await channel.overwritePermissions([ - { id: userId, allow: newAllowedPermissions, deny: newDeniedPermissions, type: "member" }, - ]); + if (existingOverride) { + await existingOverride.edit({ SEND_MESSAGES: false }); + } else { + await channel.permissionOverwrites.create(userId as Snowflake, { SEND_MESSAGES: false }, { type: 1 }); + } } catch (e) { const user = pluginData.client.users.fetch(userId as Snowflake) || new UnknownUser({ id: userId }); diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index c0943900..733a2cdd 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -13,7 +13,7 @@ export async function clearBotSlowmodeFromUserId( // Previously we diffed the overrides so we could clear the "send messages" override without touching other // overrides. Unfortunately, it seems that was a bit buggy - we didn't always receive the event for the changed // overrides and then we also couldn't diff against them. For consistency's sake, we just delete the override now. - await channel.permissionOverwrites.get(userId as Snowflake)?.delete(); + await channel.permissionOverwrites.resolve(userId as Snowflake)?.delete(); } catch (e) { if (!force) { throw e; diff --git a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts index 10e134b9..093dbce7 100644 --- a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts +++ b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts @@ -2,7 +2,7 @@ import { usernameSaverEvt } from "../types"; import { updateUsername } from "../updateUsername"; export const MessageCreateUpdateUsernameEvt = usernameSaverEvt({ - event: "message", + event: "messageCreate", async listener(meta) { if (meta.args.message.author.bot) return; diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index f535539d..c4a78c15 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -198,7 +198,7 @@ export async function displaySearch( await searchMsg.edit({ content: result, components: [row] }); const filter = (iac: MessageComponentInteraction) => iac.message.id === searchMsg.id; - const collector = searchMsg.createMessageComponentInteractionCollector({ filter, time: 2 * MINUTES }); + const collector = searchMsg.createMessageComponentCollector({ filter, time: 2 * MINUTES }); collector.on("collect", async (interaction: MessageComponentInteraction) => { if (msg.author.id !== interaction.user.id) { diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index 66da9f0b..6bd6aae0 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,9 +1,18 @@ -import { Client, Message, MessageOptions, MessageReaction, PartialUser, TextChannel, User } from "discord.js"; +import { + Client, + Message, + MessageEditOptions, + MessageOptions, + MessageReaction, + PartialUser, + TextChannel, + User, +} from "discord.js"; import { Awaitable } from "knub/dist/utils"; import { MINUTES, noop } from "../utils"; import Timeout = NodeJS.Timeout; -export type LoadPageFn = (page: number) => Awaitable; +export type LoadPageFn = (page: number) => Awaitable; export interface PaginateMessageOpts { timeout: number; diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 7e790436..d3ac1b7d 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -23,7 +23,7 @@ export async function waitForButtonConfirm( const message = await channel.send({ ...toPost, components: [row] }); const filter = (iac: MessageComponentInteraction) => iac.message.id === message.id; - const collector = message.createMessageComponentInteractionCollector({ filter, time: 10000 }); + const collector = message.createMessageComponentCollector({ filter, time: 10000 }); collector.on("collect", (interaction: MessageComponentInteraction) => { if (options?.restrictToId && options.restrictToId !== interaction.user.id) { From 4d1924b1ec800e3b27a3f7f510741a998051fb1d Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 4 Jul 2021 17:48:26 +0200 Subject: [PATCH 30/79] Add sticker count to server info embed Still need to wait on DJS update for actual sticker count --- .../plugins/Utility/functions/getServerInfoEmbed.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 960a3d0c..c413aff9 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -185,9 +185,19 @@ export async function getServerInfoEmbed( 2: 150, 3: 250, }[restGuild.premiumTier] || 50; + const maxStickers = + { + 0: 0, + 1: 15, + 2: 30, + 3: 60, + }[restGuild.premiumTier] || 0; + otherStats.push(`Emojis: **${restGuild.emojis.cache.size}** / ${maxEmojis * 2}`); + otherStats.push(`Stickers: ? / ${maxStickers}`); // Wait on DJS: **${restGuild.stickers.cache.size}** } else { otherStats.push(`Emojis: **${guildPreview!.emojis.size}**`); + // otherStats.push(`Stickers: **${guildPreview!.stickers.size}**`); Wait on DJS } if (thisServer) { From dda19de6e62ba30ca9da22f4d4fa36e8193955dd Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 4 Jul 2021 23:14:12 +0200 Subject: [PATCH 31/79] Fix various bugs, update djs --- backend/package-lock.json | 20 +++++++--------- backend/package.json | 2 +- .../plugins/Automod/actions/setSlowmode.ts | 2 +- .../plugins/Automod/functions/runAutomod.ts | 2 +- .../plugins/BotControl/commands/ServersCmd.ts | 2 +- ...etCompanionChannelOptsForVoiceChannelId.ts | 2 +- .../actions/moveToVoiceChannelAction.ts | 2 +- .../GuildInfoSaver/GuildInfoSaverPlugin.ts | 2 +- .../plugins/LocateUser/utils/moveMember.ts | 4 ++-- .../src/plugins/LocateUser/utils/sendWhere.ts | 4 ++-- .../events/LogsStageInstanceModifyEvts.ts | 6 ++--- .../src/plugins/Mutes/commands/MutesCmd.ts | 24 ++++++++++--------- .../commands/PostButtonRolesCmd.ts | 2 +- .../events/ButtonInteractionEvt.ts | 11 ++++----- .../util/buttonActionHandlers.ts | 2 +- .../util/buttonCustomIdFunctions.ts | 2 ++ .../util/splitButtonsIntoRows.ts | 1 + .../events/StarboardReactionAddEvt.ts | 2 +- backend/src/plugins/Tags/TagsPlugin.ts | 2 ++ .../src/plugins/Tags/util/onMessageCreate.ts | 4 ++-- backend/src/plugins/Utility/UtilityPlugin.ts | 7 ++++++ .../src/plugins/Utility/commands/CleanCmd.ts | 2 +- .../Utility/commands/VcdisconnectCmd.ts | 4 ++-- .../src/plugins/Utility/commands/VcmoveCmd.ts | 6 ++--- .../Utility/events/AutoJoinThreadEvt.ts | 12 ++++++++++ .../Utility/functions/getChannelInfoEmbed.ts | 4 ++-- .../Utility/functions/getServerInfoEmbed.ts | 10 ++++---- .../Utility/functions/getUserInfoEmbed.ts | 2 +- backend/src/plugins/Utility/search.ts | 14 +++++------ backend/src/plugins/Utility/types.ts | 1 + backend/src/utils/waitForInteraction.ts | 8 +++---- 31 files changed, 96 insertions(+), 72 deletions(-) create mode 100644 backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 3c496965..461ff917 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", + "discord.js": "^13.0.0-dev.a7c6678.1625427504", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -81,9 +81,8 @@ "version": "30.0.0-beta.38", "license": "MIT", "dependencies": { - "@discordjs/voice": "^0.5.1", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", + "discord.js": "^13.0.0-dev.a7c6678.1625427504", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -2160,9 +2159,9 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.ab0b3b9.1625400166", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.ab0b3b9.1625400166.tgz", - "integrity": "sha512-nTdUyPEvy1OxCoSXVJrJDFMxEIEUr/NIpuf8x0gz0XTdrghDrGR756hX4KuqGT12fm9PpqciyT+52f7fkzIxCQ==", + "version": "13.0.0-dev.a7c6678.1625427504", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a7c6678.1625427504.tgz", + "integrity": "sha512-S4ntnGVUCRyyOtz8YvoWNpSZyZEFwXTkTjXbU0shveD/QVT+0cBCcMX6vp0zPt3lCkMUgdW+crrOfEYKMGwKoQ==", "dependencies": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8035,9 +8034,9 @@ "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" }, "discord.js": { - "version": "13.0.0-dev.ab0b3b9.1625400166", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.ab0b3b9.1625400166.tgz", - "integrity": "sha512-nTdUyPEvy1OxCoSXVJrJDFMxEIEUr/NIpuf8x0gz0XTdrghDrGR756hX4KuqGT12fm9PpqciyT+52f7fkzIxCQ==", + "version": "13.0.0-dev.a7c6678.1625427504", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a7c6678.1625427504.tgz", + "integrity": "sha512-S4ntnGVUCRyyOtz8YvoWNpSZyZEFwXTkTjXbU0shveD/QVT+0cBCcMX6vp0zPt3lCkMUgdW+crrOfEYKMGwKoQ==", "requires": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8872,7 +8871,6 @@ "knub": { "version": "file:../../Knub", "requires": { - "@discordjs/voice": "^0.5.1", "@types/chai": "^4.2.18", "@types/mocha": "^7.0.2", "@types/node": "^14.14.45", @@ -8880,7 +8878,7 @@ "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", + "discord.js": "^13.0.0-dev.a7c6678.1625427504", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", diff --git a/backend/package.json b/backend/package.json index 5b045bca..75169098 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.ab0b3b9.1625400166", + "discord.js": "^13.0.0-dev.a7c6678.1625427504", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index f2b9aeac..d0d286a8 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -30,7 +30,7 @@ export const SetSlowmodeAction = automodAction({ if (channel.type === ChannelTypeStrings.CATEGORY) { // Find all text channels within the category for (const ch of pluginData.guild.channels.cache.values()) { - if (ch.parentID === channel.id && ch.type === ChannelTypeStrings.TEXT) { + if (ch.parentId === channel.id && ch.type === ChannelTypeStrings.TEXT) { channelsToSlowmode.push(ch as TextChannel); } } diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts index d3520402..bf22cc5e 100644 --- a/backend/src/plugins/Automod/functions/runAutomod.ts +++ b/backend/src/plugins/Automod/functions/runAutomod.ts @@ -13,7 +13,7 @@ export async function runAutomod(pluginData: GuildPluginData, const member = context.member || (userId && pluginData.guild.members.cache.get(userId as Snowflake)) || null; const channelId = context.message?.channel_id; const channel = channelId ? (pluginData.guild.channels.cache.get(channelId as Snowflake) as TextChannel) : null; - const categoryId = channel?.parentID; + const categoryId = channel?.parentId; const config = await pluginData.config.getMatchingConfig({ channelId, diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index e9bbf694..39938e3a 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -48,7 +48,7 @@ export const ServersCmd = botControlCmd({ const longestId = filteredGuilds.reduce((longest, guild) => Math.max(longest, guild.id.length), 0); const lines = filteredGuilds.map(g => { const paddedId = g.id.padEnd(longestId, " "); - const owner = getUser(pluginData.client, g.ownerID); + const owner = getUser(pluginData.client, g.ownerId); return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.username}#${owner.discriminator}** \`${owner.id}\`)`; }); createChunkedMessage(msg.channel as TextChannel, lines.join("\n")); diff --git a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts index 8752f632..bfd94cbe 100644 --- a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts +++ b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts @@ -16,7 +16,7 @@ export async function getCompanionChannelOptsForVoiceChannelId( .filter( opts => opts.voice_channel_ids.includes(voiceChannel.id) || - (voiceChannel.parentID && opts.voice_channel_ids.includes(voiceChannel.parentID)), + (voiceChannel.parentId && opts.voice_channel_ids.includes(voiceChannel.parentId)), ) .map(opts => Object.assign({}, defaultCompanionChannelOpts, opts)); } diff --git a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts index fd4d756c..08507bac 100644 --- a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts +++ b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts @@ -34,7 +34,7 @@ export async function moveToVoiceChannelAction( if (!targetChannel) throw new ActionError("Unknown target channel"); if (!(targetChannel instanceof VoiceChannel)) throw new ActionError("Target channel is not a voice channel"); - if (!target.voice.channelID) return; + if (!target.voice.channelId) return; await target.edit({ channel: targetChannel.id, }); diff --git a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts index 4591b228..3f241c65 100644 --- a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts +++ b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts @@ -30,6 +30,6 @@ function updateGuildInfo(pluginData: GuildPluginData) pluginData.guild.id, pluginData.guild.name, pluginData.guild.iconURL(), - pluginData.guild.ownerID, + pluginData.guild.ownerId, ); } diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index 312adda2..d3c85ecd 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -10,10 +10,10 @@ export async function moveMember( errorChannel: TextChannel, ) { const modMember: GuildMember = await pluginData.guild.members.fetch(toMoveID as Snowflake); - if (modMember.voice.channelID != null) { + if (modMember.voice.channelId != null) { try { await modMember.edit({ - channel: target.voice.channelID, + channel: target.voice.channelId, }); } catch { sendErrorMessage(pluginData, errorChannel, "Failed to move you. Are you in a voice channel?"); diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 77b7dd56..dd6ddd69 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -11,8 +11,8 @@ export async function sendWhere( channel: TextChannel, prepend: string, ) { - const voice = member.voice.channelID - ? (pluginData.guild.channels.resolve(member.voice.channelID) as VoiceChannel) + const voice = member.voice.channelId + ? (pluginData.guild.channels.resolve(member.voice.channelId) as VoiceChannel) : null; if (voice == null) { diff --git a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts index 6ce0b98a..38e2e2d9 100644 --- a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts @@ -8,7 +8,7 @@ export const LogsStageInstanceCreateEvt = logsEvt({ async listener(meta) { const stageChannel = meta.args.stageInstance.channel ?? - (await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelID)); + (await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelId)); meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_CREATE, { stageInstance: stripObjectToScalars(meta.args.stageInstance), stageChannel: stripObjectToScalars(stageChannel), @@ -22,7 +22,7 @@ export const LogsStageInstanceDeleteEvt = logsEvt({ async listener(meta) { const stageChannel = meta.args.stageInstance.channel ?? - (await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelID)); + (await meta.pluginData.guild.channels.fetch(meta.args.stageInstance.channelId)); meta.pluginData.state.guildLogs.log(LogType.STAGE_INSTANCE_DELETE, { stageInstance: stripObjectToScalars(meta.args.stageInstance), stageChannel: stripObjectToScalars(stageChannel), @@ -36,7 +36,7 @@ export const LogsStageInstanceUpdateEvt = logsEvt({ async listener(meta) { const stageChannel = meta.args.newStageInstance.channel ?? - (await meta.pluginData.guild.channels.fetch(meta.args.newStageInstance.channelID)); + (await meta.pluginData.guild.channels.fetch(meta.args.newStageInstance.channelId)); const diff = getScalarDifference(meta.args.oldStageInstance, meta.args.newStageInstance); const differenceString = differenceToString(diff); diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 207693ec..fdc89c8b 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -27,10 +27,17 @@ export const MutesCmd = mutesCmd({ let totalMutes = 0; let hasFilters = false; - let stopCollectionFn; - let stopCollectionTimeout; + let stopCollectionFn = () => { + return; + }; + let stopCollectionTimeout: NodeJS.Timeout; const stopCollectionDebounce = 5 * MINUTES; + const bumpCollectionTimeout = () => { + clearTimeout(stopCollectionTimeout); + stopCollectionTimeout = setTimeout(stopCollectionFn, stopCollectionDebounce); + }; + let lines: string[] = []; // Active, logged mutes @@ -169,11 +176,6 @@ export const MutesCmd = mutesCmd({ bumpCollectionTimeout(); }; - const bumpCollectionTimeout = () => { - clearTimeout(stopCollectionTimeout); - stopCollectionTimeout = setTimeout(stopCollectionFn, stopCollectionDebounce); - }; - if (totalMutes === 0) { if (args.manual) { listMessage.edit("No manual mutes found!"); @@ -199,14 +201,14 @@ export const MutesCmd = mutesCmd({ new MessageButton() .setStyle("SECONDARY") .setEmoji("⬅") - .setCustomID(`previousButton:${idMod}`), + .setCustomId(`previousButton:${idMod}`), ); buttons.push( new MessageButton() .setStyle("SECONDARY") .setEmoji("➡") - .setCustomID(`nextButton:${idMod}`), + .setCustomId(`nextButton:${idMod}`), ); const row = new MessageActionRow().addComponents(buttons); @@ -223,10 +225,10 @@ export const MutesCmd = mutesCmd({ interaction.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }); } else { collector.resetTimer(); - if (interaction.customID === `previousButton:${idMod}` && currentPage > 1) { + if (interaction.customId === `previousButton:${idMod}` && currentPage > 1) { await interaction.deferUpdate(); await drawListPage(currentPage - 1); - } else if (interaction.customID === `nextButton:${idMod}` && currentPage < totalPages) { + } else if (interaction.customId === `nextButton:${idMod}` && currentPage < totalPages) { await interaction.deferUpdate(); await drawListPage(currentPage + 1); } else { diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index aa74c553..f54ef9ad 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -38,7 +38,7 @@ export const PostButtonRolesCmd = reactionRolesCmd({ const btn = new MessageButton() .setLabel(button.label ?? "") .setStyle(button.style ?? "PRIMARY") - .setCustomID(customId) + .setCustomId(customId) .setDisabled(button.disabled ?? false); if (button.emoji) { diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 47266478..2881b27d 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -14,18 +14,17 @@ import { handleModifyRole, handleOpenMenu } from "../util/buttonActionHandlers"; const BUTTON_INVALIDATION_TIME = 15 * MINUTES; export const ButtonInteractionEvt = reactionRolesEvt({ - event: "interaction", + event: "interactionCreate", async listener(meta) { const int = meta.args.interaction.isMessageComponent() ? (meta.args.interaction as MessageComponentInteraction) : null; if (!int) return; - const allOnMessage = await meta.pluginData.state.buttonRoles.getAllForMessageId(int.message.id); - if (allOnMessage.length === 0) return; + const cfg = meta.pluginData.config.get(); - const split = int.customID.split(BUTTON_CONTEXT_SEPARATOR); - const context = (await resolveStatefulCustomId(meta.pluginData, int.customID)) ?? { + const split = int.customId.split(BUTTON_CONTEXT_SEPARATOR); + const context = (await resolveStatefulCustomId(meta.pluginData, int.customId)) ?? { groupName: split[0], action: split[1], roleOrMenu: split[2], @@ -80,7 +79,7 @@ export const ButtonInteractionEvt = reactionRolesEvt({ } logger.warn( - `Action ${context.action} on button ${int.customID} (Guild: ${int.guildID}, Channel: ${int.channelID}) is unknown!`, + `Action ${context.action} on button ${int.customId} (Guild: ${int.guildId}, Channel: ${int.channelId}) is unknown!`, ); await sendEphemeralReply(int, `A internal error was encountered, please contact the Administrators!`); }, diff --git a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts index 45205035..10f4e631 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts @@ -33,7 +33,7 @@ export async function handleOpenMenu( const btn = new MessageButton() .setLabel(menuButton.label ?? "") .setStyle("PRIMARY") - .setCustomID(customId) + .setCustomId(customId) .setDisabled(menuButton.disabled ?? false); if (menuButton.emoji) { diff --git a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts index 9a758d0a..55113c7c 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts @@ -38,5 +38,7 @@ export async function resolveStatefulCustomId(pluginData: GuildPluginData= 1) rows.push(curRow); return rows; } diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts index b0f485ce..eed30bd4 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts @@ -34,7 +34,7 @@ export const StarboardReactionAddEvt = starboardEvt({ const config = await pluginData.config.getMatchingConfig({ member, channelId: msg.channel.id, - categoryId: (msg.channel as TextChannel).parentID, + categoryId: (msg.channel as TextChannel).parentId, }); const boardLock = await pluginData.locks.acquire(allStarboardsLock()); diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 220b896a..0ea369a0 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -150,6 +150,7 @@ export const TagsPlugin = zeppelinGuildPlugin()({ }, timeAdd(...args) { + if (args.length === 0) return; let reference; let delay; @@ -171,6 +172,7 @@ export const TagsPlugin = zeppelinGuildPlugin()({ }, timeSub(...args) { + if (args.length === 0) return; let reference; let delay; diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index a32ea6bc..43448df5 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -22,12 +22,12 @@ export async function onMessageCreate(pluginData: GuildPluginData = { jumbo_size: 128, can_avatar: false, info_on_single_result: true, + autojoin_threads: true, }, overrides: [ { @@ -148,6 +150,11 @@ export const UtilityPlugin = zeppelinGuildPlugin()({ EmojiInfoCmd, ], + // prettier-ignore + events: [ + AutoJoinThreadEvt, + ], + beforeLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index e7024866..9186e3c8 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -98,7 +98,7 @@ export const CleanCmd = utilityCmd({ userId: msg.author.id, member: msg.member, channelId: targetChannel.id, - categoryId: targetChannel.parentID, + categoryId: targetChannel.parentId, }); if (configForTargetChannel.can_clean !== true) { sendErrorMessage(pluginData, msg.channel, `Missing permissions to use clean on that channel`); diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index b0a44755..d749b9c7 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -21,11 +21,11 @@ export const VcdisconnectCmd = utilityCmd({ return; } - if (!args.member.voice || !args.member.voice.channelID) { + if (!args.member.voice || !args.member.voice.channelId) { sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); return; } - const channel = pluginData.guild.channels.cache.get(args.member.voice.channelID) as VoiceChannel; + const channel = pluginData.guild.channels.cache.get(args.member.voice.channelId) as VoiceChannel; try { await args.member.voice.kick(); diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index c7d68008..784c5f4c 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -52,17 +52,17 @@ export const VcmoveCmd = utilityCmd({ channel = closestMatch; } - if (!args.member.voice || !args.member.voice.channelID) { + if (!args.member.voice || !args.member.voice.channelId) { sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); return; } - if (args.member.voice.channelID === channel.id) { + if (args.member.voice.channelId === channel.id) { sendErrorMessage(pluginData, msg.channel, "Member is already on that channel!"); return; } - const oldVoiceChannel = pluginData.guild.channels.cache.get(args.member.voice.channelID); + const oldVoiceChannel = pluginData.guild.channels.cache.get(args.member.voice.channelId); try { await args.member.edit({ diff --git a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts new file mode 100644 index 00000000..c7d49d70 --- /dev/null +++ b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts @@ -0,0 +1,12 @@ +import { utilityEvt } from "../types"; + +export const AutoJoinThreadEvt = utilityEvt({ + event: "threadCreate", + + async listener(meta) { + const config = meta.pluginData.config.get(); + if (config.autojoin_threads && meta.args.thread.joinable && !meta.args.thread.joined) { + await meta.args.thread.join(); + } + }, +}); diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index 356ba4bd..fa2ea87d 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -105,11 +105,11 @@ export async function getChannelInfoEmbed( if (channel.type === ChannelTypeStrings.CATEGORY) { const textChannels = pluginData.guild.channels.cache.filter( - ch => ch.parentID === channel.id && ch.type !== ChannelTypeStrings.VOICE, + ch => ch.parentId === channel.id && ch.type !== ChannelTypeStrings.VOICE, ); const voiceChannels = pluginData.guild.channels.cache.filter( ch => - ch.parentID === channel.id && (ch.type === ChannelTypeStrings.VOICE || ch.type === ChannelTypeStrings.STAGE), + ch.parentId === channel.id && (ch.type === ChannelTypeStrings.VOICE || ch.type === ChannelTypeStrings.STAGE), ); embed.fields.push({ diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index c413aff9..f6a00847 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -64,10 +64,10 @@ export async function getServerInfoEmbed( basicInformation.push(`Created: **${serverAge} ago** (\`${prettyCreatedAt}\`)`); if (thisServer) { - const owner = await resolveUser(pluginData.client, thisServer.ownerID); + const owner = await resolveUser(pluginData.client, thisServer.ownerId); const ownerName = `${owner.username}#${owner.discriminator}`; - basicInformation.push(`Owner: **${ownerName}** (\`${thisServer.ownerID}\`)`); + basicInformation.push(`Owner: **${ownerName}** (\`${thisServer.ownerId}\`)`); // basicInformation.push(`Voice region: **${thisServer.region}**`); Outdated, as automatic voice regions are fully live } @@ -81,10 +81,10 @@ export async function getServerInfoEmbed( }); // IMAGE LINKS - const iconUrl = `[Link](${(restGuild || guildPreview)!.iconURL})`; - const bannerUrl = restGuild?.bannerURL ? `[Link](${restGuild.bannerURL})` : "None"; + const iconUrl = `[Link](${(restGuild || guildPreview)!.iconURL()})`; + const bannerUrl = restGuild?.bannerURL() ? `[Link](${restGuild.bannerURL()})` : "None"; const splashUrl = - (restGuild || guildPreview)!.splashURL != null + (restGuild || guildPreview)!.splashURL() != null ? `[Link](${(restGuild || guildPreview)!.splashURL()?.replace("size=128", "size=2048")})` : "None"; diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 96ed072a..e45d801b 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -114,7 +114,7 @@ export async function getUserInfoEmbed( `), }); - const voiceChannel = member.voice.channelID ? pluginData.guild.channels.cache.get(member.voice.channelID) : null; + const voiceChannel = member.voice.channelId ? pluginData.guild.channels.cache.get(member.voice.channelId) : null; if (voiceChannel || member.voice.mute || member.voice.deaf) { embed.fields.push({ name: preEmbedPadding + "Voice information", diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index c4a78c15..40bd1d1b 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -175,7 +175,7 @@ export async function displaySearch( new MessageButton() .setStyle("SECONDARY") .setEmoji("⬅") - .setCustomID(`previousButton:${idMod}`) + .setCustomId(`previousButton:${idMod}`) .setDisabled(currentPage === 1), ); @@ -183,7 +183,7 @@ export async function displaySearch( new MessageButton() .setStyle("SECONDARY") .setEmoji("➡") - .setCustomID(`nextButton:${idMod}`) + .setCustomId(`nextButton:${idMod}`) .setDisabled(currentPage === searchResult.lastPage), ); @@ -191,7 +191,7 @@ export async function displaySearch( new MessageButton() .setStyle("SECONDARY") .setEmoji("🔄") - .setCustomID(`reloadButton:${idMod}`), + .setCustomId(`reloadButton:${idMod}`), ); const row = new MessageActionRow().addComponents(buttons); @@ -204,15 +204,15 @@ export async function displaySearch( if (msg.author.id !== interaction.user.id) { interaction.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }); } else { - if (interaction.customID === `previousButton:${idMod}` && currentPage > 1) { + if (interaction.customId === `previousButton:${idMod}` && currentPage > 1) { collector.stop(); await interaction.deferUpdate(); await loadSearchPage(currentPage - 1); - } else if (interaction.customID === `nextButton:${idMod}` && currentPage < searchResult.lastPage) { + } else if (interaction.customId === `nextButton:${idMod}` && currentPage < searchResult.lastPage) { collector.stop(); await interaction.deferUpdate(); await loadSearchPage(currentPage + 1); - } else if (interaction.customID === `reloadButton:${idMod}`) { + } else if (interaction.customId === `reloadButton:${idMod}`) { collector.stop(); await interaction.deferUpdate(); await loadSearchPage(currentPage); @@ -325,7 +325,7 @@ async function performMemberSearch( } if (args.voice) { - matchingMembers = matchingMembers.filter(m => m.voice.channelID != null); + matchingMembers = matchingMembers.filter(m => m.voice.channelId != null); } if (args.bot) { diff --git a/backend/src/plugins/Utility/types.ts b/backend/src/plugins/Utility/types.ts index 6d02be57..15f6e925 100644 --- a/backend/src/plugins/Utility/types.ts +++ b/backend/src/plugins/Utility/types.ts @@ -34,6 +34,7 @@ export const ConfigSchema = t.type({ jumbo_size: t.Integer, can_avatar: t.boolean, info_on_single_result: t.boolean, + autojoin_threads: t.boolean, }); export type TConfigSchema = t.TypeOf; diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index d3ac1b7d..f984cdd4 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -13,12 +13,12 @@ export async function waitForButtonConfirm( new MessageButton() .setStyle("SUCCESS") .setLabel(options?.confirmText || "Confirm") - .setCustomID(`confirmButton:${idMod}`), + .setCustomId(`confirmButton:${idMod}`), new MessageButton() .setStyle("DANGER") .setLabel(options?.cancelText || "Cancel") - .setCustomID(`cancelButton:${idMod}`), + .setCustomId(`cancelButton:${idMod}`), ]); const message = await channel.send({ ...toPost, components: [row] }); @@ -29,10 +29,10 @@ export async function waitForButtonConfirm( if (options?.restrictToId && options.restrictToId !== interaction.user.id) { interaction.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }); } else { - if (interaction.customID === `confirmButton:${idMod}`) { + if (interaction.customId === `confirmButton:${idMod}`) { message.delete(); resolve(true); - } else if (interaction.customID === `cancelButton:${idMod}`) { + } else if (interaction.customId === `cancelButton:${idMod}`) { message.delete(); resolve(false); } From d2dd1031751694bbaebb8c7c47f68a8798532e10 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 6 Jul 2021 05:23:47 +0200 Subject: [PATCH 32/79] Start move to configAccessibleObjects, exclude perm overrides from logs configAccessibleObjects are used to guarantee backwards compatibility and consistency. Perm overrides from our own plugins are ignored as to not spam logs through bot managed slowmode or companion channels --- backend/package-lock.json | 18 +-- backend/package.json | 2 +- .../functions/getTextMatchPartialSummary.ts | 2 +- .../matchMultipleTextTypesOnMessage.ts | 2 +- .../CompanionChannelsPlugin.ts | 5 + .../functions/handleCompanionPermissions.ts | 2 + .../src/plugins/CompanionChannels/types.ts | 2 + .../Logs/events/LogsChannelModifyEvts.ts | 21 ++-- .../plugins/Logs/events/LogsGuildBanEvts.ts | 12 +- .../Logs/events/LogsGuildMemberAddEvt.ts | 3 +- .../Logs/events/LogsGuildMemberRemoveEvt.ts | 4 +- .../plugins/Logs/events/LogsRoleModifyEvts.ts | 11 +- .../events/LogsStageInstanceModifyEvts.ts | 23 ++-- .../Logs/events/LogsThreadModifyEvts.ts | 19 +-- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 12 +- .../Logs/events/LogsVoiceChannelEvts.ts | 21 ++-- .../src/plugins/Slowmode/SlowmodePlugin.ts | 1 + backend/src/plugins/Slowmode/types.ts | 1 + .../Slowmode/util/applyBotSlowmodeToUserId.ts | 1 + .../util/clearBotSlowmodeFromUserId.ts | 2 + .../Slowmode/util/clearExpiredSlowmodes.ts | 6 +- .../events/StarboardReactionAddEvt.ts | 6 +- backend/src/plugins/Starboard/types.ts | 1 + backend/src/plugins/Utility/UtilityPlugin.ts | 3 +- .../Utility/events/AutoJoinThreadEvt.ts | 15 +++ .../Utility/functions/getServerInfoEmbed.ts | 2 +- backend/src/utils.ts | 21 ++++ backend/src/utils/configAccessibleObjects.ts | 116 ++++++++++++++++++ 28 files changed, 259 insertions(+), 75 deletions(-) create mode 100644 backend/src/utils/configAccessibleObjects.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 461ff917..984a6020 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.a7c6678.1625427504", + "discord.js": "^13.0.0-dev.2e078e4.1625529824", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -82,7 +82,7 @@ "license": "MIT", "dependencies": { "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.a7c6678.1625427504", + "discord.js": "^13.0.0-dev.2e078e4.1625529824", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -2159,9 +2159,9 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.a7c6678.1625427504", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a7c6678.1625427504.tgz", - "integrity": "sha512-S4ntnGVUCRyyOtz8YvoWNpSZyZEFwXTkTjXbU0shveD/QVT+0cBCcMX6vp0zPt3lCkMUgdW+crrOfEYKMGwKoQ==", + "version": "13.0.0-dev.2e078e4.1625529824", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.2e078e4.1625529824.tgz", + "integrity": "sha512-NKNnoEmh3+4eCG44BOIBjlJS0bKQEH8OgWoEjdJ9K53MYa5lfqbSho4NKXe5+hVpMr+U43wJ8ByUvw96ogqu8w==", "dependencies": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8034,9 +8034,9 @@ "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" }, "discord.js": { - "version": "13.0.0-dev.a7c6678.1625427504", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.a7c6678.1625427504.tgz", - "integrity": "sha512-S4ntnGVUCRyyOtz8YvoWNpSZyZEFwXTkTjXbU0shveD/QVT+0cBCcMX6vp0zPt3lCkMUgdW+crrOfEYKMGwKoQ==", + "version": "13.0.0-dev.2e078e4.1625529824", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.2e078e4.1625529824.tgz", + "integrity": "sha512-NKNnoEmh3+4eCG44BOIBjlJS0bKQEH8OgWoEjdJ9K53MYa5lfqbSho4NKXe5+hVpMr+U43wJ8ByUvw96ogqu8w==", "requires": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8878,7 +8878,7 @@ "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.a7c6678.1625427504", + "discord.js": "^13.0.0-dev.2e078e4.1625529824", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", diff --git a/backend/package.json b/backend/package.json index 75169098..792d8126 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.a7c6678.1625427504", + "discord.js": "^13.0.0-dev.2e078e4.1625529824", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts index f88f9b69..fe0466e4 100644 --- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts +++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts @@ -29,6 +29,6 @@ export function getTextMatchPartialSummary( const visibleName = context.member?.nickname || context.user!.username; return `visible name: ${visibleName}`; } else if (type === "customstatus") { - return `custom status: ${context.member!.presence.activities.find(a => a.type === "CUSTOM")?.name}`; + return `custom status: ${context.member!.presence?.activities.find(a => a.type === "CUSTOM")?.name}`; } } diff --git a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts index 6b2e1038..10188f7e 100644 --- a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts +++ b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts @@ -52,7 +52,7 @@ export async function* matchMultipleTextTypesOnMessage( yield ["nickname", member.nickname]; } - for (const activity of member.presence.activities) { + for (const activity of member.presence?.activities ?? []) { if (activity.type === Constants.ActivityTypes[4]) { yield ["customstatus", `${activity.emoji} ${activity.name}`]; break; diff --git a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts index 64bda1c1..8565c67b 100644 --- a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts +++ b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts @@ -1,4 +1,5 @@ import { CooldownManager } from "knub"; +import { GuildLogs } from "../../../data/GuildLogs"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -32,4 +33,8 @@ export const CompanionChannelsPlugin = zeppelinGuildPlugin pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), - mod: stripObjectToScalars(mod), + mod: mod ? userToConfigAccessibleUser(mod) : {}, }, member.id, ); @@ -82,7 +82,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), - mod: stripObjectToScalars(mod), + mod: mod ? userToConfigAccessibleUser(mod) : {}, }, member.id, ); @@ -96,7 +96,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), - mod: stripObjectToScalars(mod), + mod: mod ? userToConfigAccessibleUser(mod) : {}, }, member.id, ); diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index 50d31bfa..ae19eb53 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -1,3 +1,4 @@ +import { channelToConfigAccessibleChannel, memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { stripObjectToScalars } from "../../../utils"; import { logsEvt } from "../types"; @@ -10,25 +11,23 @@ export const LogsVoiceStateUpdateEvt = logsEvt({ const newChannel = meta.args.newState.channel; const member = meta.args.newState.member ?? meta.args.oldState.member!; - if (!newChannel) { + if (!newChannel && oldChannel) { // Leave evt meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_LEAVE, { - member: stripObjectToScalars(member, ["user", "roles"]), - oldChannel: stripObjectToScalars(oldChannel), - newChannel: stripObjectToScalars(newChannel), + member: memberToConfigAccessibleMember(member), + oldChannel: channelToConfigAccessibleChannel(oldChannel!), }); - } else if (!oldChannel) { + } else if (!oldChannel && newChannel) { // Join Evt meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_JOIN, { - member: stripObjectToScalars(member, ["user", "roles"]), - oldChannel: stripObjectToScalars(oldChannel), - newChannel: stripObjectToScalars(newChannel), + member: memberToConfigAccessibleMember(member), + newChannel: channelToConfigAccessibleChannel(newChannel), }); } else { meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_MOVE, { - member: stripObjectToScalars(member, ["user", "roles"]), - oldChannel: stripObjectToScalars(oldChannel), - newChannel: stripObjectToScalars(newChannel), + member: memberToConfigAccessibleMember(member), + oldChannel: channelToConfigAccessibleChannel(oldChannel!), + newChannel: channelToConfigAccessibleChannel(newChannel!), }); } }, diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index 5dda25c9..f7dd06a3 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -66,6 +66,7 @@ export const SlowmodePlugin = zeppelinGuildPlugin()({ afterLoad(pluginData) { const { state } = pluginData; + state.serverLogs = new GuildLogs(pluginData.guild.id); state.clearInterval = setInterval(() => clearExpiredSlowmodes(pluginData), BOT_SLOWMODE_CLEAR_INTERVAL); state.onMessageCreateFn = msg => onMessageCreate(pluginData, msg); diff --git a/backend/src/plugins/Slowmode/types.ts b/backend/src/plugins/Slowmode/types.ts index 3c3824da..7679df34 100644 --- a/backend/src/plugins/Slowmode/types.ts +++ b/backend/src/plugins/Slowmode/types.ts @@ -19,6 +19,7 @@ export interface SlowmodePluginType extends BasePluginType { savedMessages: GuildSavedMessages; logs: GuildLogs; clearInterval: NodeJS.Timeout; + serverLogs: GuildLogs; onMessageCreateFn; }; diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index bcc32d55..2bcb7c9d 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -13,6 +13,7 @@ export async function applyBotSlowmodeToUserId( // Deny sendMessage permission from the user. If there are existing permission overwrites, take those into account. const existingOverride = channel.permissionOverwrites.resolve(userId as Snowflake); try { + pluginData.state.serverLogs.ignoreLog(LogType.CHANNEL_UPDATE, channel.id, 5 * 1000); if (existingOverride) { await existingOverride.edit({ SEND_MESSAGES: false }); } else { diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index 733a2cdd..381fa930 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,5 +1,6 @@ import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; +import { LogType } from "../../../data/LogType"; import { SlowmodePluginType } from "../types"; export async function clearBotSlowmodeFromUserId( @@ -13,6 +14,7 @@ export async function clearBotSlowmodeFromUserId( // Previously we diffed the overrides so we could clear the "send messages" override without touching other // overrides. Unfortunately, it seems that was a bit buggy - we didn't always receive the event for the changed // overrides and then we also couldn't diff against them. For consistency's sake, we just delete the override now. + pluginData.state.serverLogs.ignoreLog(LogType.CHANNEL_UPDATE, channel.id, 3 * 1000); await channel.permissionOverwrites.resolve(userId as Snowflake)?.delete(); } catch (e) { if (!force) { diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index dd7ced57..6c5fe46d 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -1,5 +1,6 @@ import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { stripObjectToScalars, UnknownUser } from "../../../utils"; @@ -22,10 +23,11 @@ export async function clearExpiredSlowmodes(pluginData: GuildPluginData()({ // prettier-ignore events: [ AutoJoinThreadEvt, + AutoJoinThreadSyncEvt, ], beforeLoad(pluginData) { diff --git a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts index c7d49d70..6789073c 100644 --- a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts +++ b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts @@ -10,3 +10,18 @@ export const AutoJoinThreadEvt = utilityEvt({ } }, }); + +export const AutoJoinThreadSyncEvt = utilityEvt({ + event: "threadListSync", + + async listener(meta) { + const config = meta.pluginData.config.get(); + if (config.autojoin_threads) { + for (const thread of meta.args.threads.values()) { + if (!thread.joined && thread.joinable) { + await thread.join(); + } + } + } + }, +}); diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index f6a00847..2eb04a60 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -126,7 +126,7 @@ export async function getServerInfoEmbed( } if (!onlineMemberCount && thisServer) { - onlineMemberCount = thisServer.members.cache.filter(m => m.presence.status !== "offline").size; // Extremely inaccurate fallback + onlineMemberCount = thisServer.members.cache.filter(m => m.presence?.status !== "offline").size; // Extremely inaccurate fallback } const offlineMemberCount = totalMembers - onlineMemberCount; diff --git a/backend/src/utils.ts b/backend/src/utils.ts index f9d9094a..be9c6767 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -36,6 +36,7 @@ import { sendDM } from "./utils/sendDM"; import { waitForButtonConfirm } from "./utils/waitForInteraction"; import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; import { isEqual } from "lodash"; +import humanizeDuration from "humanize-duration"; const fsp = fs.promises; @@ -184,8 +185,28 @@ export function getScalarDifference( return diff; } +// This is a stupid, messy solution that is not extendable at all. +// If anyone plans on adding anything to this, they should rewrite this first. +// I just want to get this done and this works for now :) +export function prettyDifference(diff: Map): Map { + const toReturn = new Map(); + + for (let [key, difference] of diff) { + if (key === "rateLimitPerUser") { + difference.is = humanizeDuration(difference.is * 1000); + difference.was = humanizeDuration(difference.was * 1000); + key = "slowmode"; + } + + toReturn.set(key, { was: difference.was, is: difference.is }); + } + + return toReturn; +} + export function differenceToString(diff: Map): string { let toReturn = ""; + diff = prettyDifference(diff); for (const [key, difference] of diff) { toReturn += `${key[0].toUpperCase() + key.slice(1)}: \`${difference.was}\` ➜ \`${difference.is}\`\n`; } diff --git a/backend/src/utils/configAccessibleObjects.ts b/backend/src/utils/configAccessibleObjects.ts new file mode 100644 index 00000000..92dc17c0 --- /dev/null +++ b/backend/src/utils/configAccessibleObjects.ts @@ -0,0 +1,116 @@ +import { + GuildChannel, + GuildMember, + PartialGuildMember, + Role, + Snowflake, + StageInstance, + ThreadChannel, + User, +} from "discord.js"; + +export interface IConfigAccessibleUser { + id: Snowflake; + username: string; + discriminator: string; + mention: string; + avatarURL: string; + bot: boolean; + createdAt: number; +} + +export interface IConfigAccessibleRole { + id: Snowflake; + name: string; + createdAt: number; + hexColor: string; + hoist: boolean; +} + +export interface IConfigAccessibleMember extends IConfigAccessibleUser { + user: IConfigAccessibleUser; + nick: string; + roles: IConfigAccessibleRole[]; + joinedAt?: number; + // guildAvatarURL: string, Once DJS supports per-server avatars + guildName: string; +} + +export function userToConfigAccessibleUser(user: User): IConfigAccessibleUser { + const toReturn: IConfigAccessibleUser = { + id: user.id, + username: user.username, + discriminator: user.discriminator, + mention: `<@${user.id}>`, + avatarURL: user.displayAvatarURL({ dynamic: true }), + bot: user.bot, + createdAt: user.createdTimestamp, + }; + + return toReturn; +} + +export function roleToConfigAccessibleRole(role: Role): IConfigAccessibleRole { + const toReturn: IConfigAccessibleRole = { + id: role.id, + name: role.name, + createdAt: role.createdTimestamp, + hexColor: role.hexColor, + hoist: role.hoist, + }; + + return toReturn; +} + +export function memberToConfigAccessibleMember(member: GuildMember | PartialGuildMember): IConfigAccessibleMember { + const user = userToConfigAccessibleUser(member.user!); + + const toReturn: IConfigAccessibleMember = { + ...user, + user, + nick: member.nickname ?? "*None*", + roles: member.roles.cache.mapValues(r => roleToConfigAccessibleRole(r)).array(), + joinedAt: member.joinedTimestamp ?? undefined, + guildName: member.guild.name, + }; + + return toReturn; +} + +export interface IConfigAccessibleChannel { + id: Snowflake; + name: string; + mention: string; + parentId?: Snowflake; +} + +export function channelToConfigAccessibleChannel(channel: GuildChannel | ThreadChannel): IConfigAccessibleChannel { + const toReturn: IConfigAccessibleChannel = { + id: channel.id, + name: channel.name, + mention: `<#${channel.id}>`, + parentId: channel.parentId ?? undefined, + }; + + return toReturn; +} + +export interface IConfigAccessibleStage { + channelId: Snowflake; + channelMention: string; + createdAt: number; + discoverable: boolean; + topic: string; +} + +export function stageToConfigAccessibleStage(stage: StageInstance): IConfigAccessibleStage { + const toReturn: IConfigAccessibleStage = { + channelId: stage.channelId, + channelMention: `<#${stage.channelId}>`, + createdAt: stage.createdTimestamp, + discoverable: !stage.discoverableDisabled, + topic: stage.topic, + }; + + return toReturn; +} From 4ad99975de61db461a740ca5d180f69bc4a33b71 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 7 Jul 2021 21:14:55 +0200 Subject: [PATCH 33/79] Update events for presetup-configurator --- presetup-configurator/src/LogChannels.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/presetup-configurator/src/LogChannels.tsx b/presetup-configurator/src/LogChannels.tsx index 4901750b..928d4c99 100644 --- a/presetup-configurator/src/LogChannels.tsx +++ b/presetup-configurator/src/LogChannels.tsx @@ -20,8 +20,13 @@ const LOG_TYPES = { "MEMBER_RESTORE": "Member roles restored", "CHANNEL_CREATE": "Channel created", "CHANNEL_DELETE": "Channel deleted", + "CHANNEL_UPDATE": "Channel updated", + "THREAD_CREATE": "Thread created", + "THREAD_DELETE": "Thread deleted", + "THREAD_UPDATE": "Thread updated", "ROLE_CREATE": "Role created", "ROLE_DELETE": "Role deleted", + "ROLE_UPDATE": "Role updated", "MESSAGE_EDIT": "Message edited", "MESSAGE_DELETE": "Message deleted", "MESSAGE_DELETE_BULK": "Messages deleted in bulk", @@ -29,6 +34,9 @@ const LOG_TYPES = { "VOICE_CHANNEL_JOIN": "Voice channel join", "VOICE_CHANNEL_LEAVE": "Voice channel leave", "VOICE_CHANNEL_MOVE": "Voice channel move", + "STAGE_INSTANCE_CREATE": "Stage created", + "STAGE_INSTANCE_DELETE": "Stage deleted", + "STAGE_INSTANCE_UPDATE": "Stage updated", "COMMAND": "Command used", "MESSAGE_SPAM_DETECTED": "Message spam detected", "CENSOR": "Message censored", From acb4913495dd9a5be43664757aeb3b09d85504fa Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Wed, 21 Jul 2021 22:14:09 +0200 Subject: [PATCH 34/79] More fixes, change rest of stripObjectToScalars to configAccessibleObj --- backend/package-lock.json | 38 +-- backend/package.json | 2 +- backend/src/data/GuildArchives.ts | 9 +- backend/src/data/GuildSavedMessages.ts | 3 +- backend/src/index.ts | 4 +- .../plugins/AutoDelete/util/deleteNextItem.ts | 9 +- backend/src/plugins/Automod/actions/reply.ts | 4 +- .../Automod/functions/setAntiraidLevel.ts | 4 +- .../src/plugins/Censor/util/censorMessage.ts | 11 +- .../ChannelArchiver/rehostAttachment.ts | 7 +- .../CompanionChannelsPlugin.ts | 2 +- .../Logs/events/LogsGuildMemberAddEvt.ts | 3 +- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 4 +- .../src/plugins/Logs/util/onMessageDelete.ts | 13 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 9 +- .../plugins/MessageSaver/saveMessagesToDB.ts | 4 +- .../plugins/ModActions/commands/AddCaseCmd.ts | 5 +- .../src/plugins/ModActions/commands/BanCmd.ts | 8 +- .../ModActions/commands/DeleteCaseCmd.ts | 3 +- .../ModActions/commands/ForcebanCmd.ts | 5 +- .../plugins/ModActions/commands/MassBanCmd.ts | 6 +- .../ModActions/commands/MassUnbanCmd.ts | 3 +- .../ModActions/commands/MassmuteCmd.ts | 3 +- .../plugins/ModActions/commands/NoteCmd.ts | 8 +- .../plugins/ModActions/commands/UnbanCmd.ts | 5 +- .../events/CreateBanCaseOnManualBanEvt.ts | 5 +- .../events/CreateKickCaseOnManualKickEvt.ts | 7 +- .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 5 +- .../functions/actualKickMemberCmd.ts | 4 +- .../ModActions/functions/actualMuteUserCmd.ts | 10 +- .../plugins/ModActions/functions/banUserId.ts | 5 +- .../ModActions/functions/kickMember.ts | 7 +- .../functions/outdatedTempbansLoop.ts | 3 +- .../functions/readContactMethodsFromArgs.ts | 4 +- .../ModActions/functions/warnMember.ts | 7 +- .../events/ReapplyActiveMuteOnJoinEvt.ts | 3 +- .../Mutes/functions/clearExpiredMutes.ts | 5 +- .../src/plugins/Mutes/functions/muteUser.ts | 11 +- .../src/plugins/Mutes/functions/unmuteUser.ts | 11 +- .../src/plugins/Persist/events/LoadDataEvt.ts | 3 +- .../src/plugins/Post/util/actualPostCmd.ts | 13 +- .../plugins/Post/util/scheduledPostLoop.ts | 9 +- .../util/buttonCustomIdFunctions.ts | 1 + .../src/plugins/Roles/commands/AddRoleCmd.ts | 5 +- .../plugins/Roles/commands/MassAddRoleCmd.ts | 5 +- .../Roles/commands/MassRemoveRoleCmd.ts | 5 +- .../plugins/Roles/commands/RemoveRoleCmd.ts | 5 +- .../Slowmode/commands/SlowmodeClearCmd.ts | 15 +- .../Slowmode/commands/SlowmodeSetCmd.ts | 7 +- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 11 +- .../util/clearBotSlowmodeFromUserId.ts | 4 +- .../util/disableBotSlowmodeForChannel.ts | 4 +- .../Spam/util/logAndDetectMessageSpam.ts | 5 +- .../Spam/util/logAndDetectOtherSpam.ts | 3 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 5 +- .../plugins/Tags/util/renderTagFromString.ts | 5 +- .../src/plugins/Utility/commands/CleanCmd.ts | 7 +- .../Utility/commands/VcdisconnectCmd.ts | 11 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 21 +- .../events/SendWelcomeMessageEvt.ts | 11 +- backend/src/types.ts | 21 +- backend/src/utils.ts | 27 +- backend/src/utils/configAccessibleObjects.ts | 37 ++- backend/src/utils/createPaginatedMessage.ts | 6 +- .../src/utils/getMissingChannelPermissions.ts | 4 +- backend/src/utils/isDefaultSticker.ts | 306 ++++++++++++++++++ 66 files changed, 623 insertions(+), 192 deletions(-) create mode 100644 backend/src/utils/isDefaultSticker.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 984a6020..1ec24d2c 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.2e078e4.1625529824", + "discord.js": "^13.0.0-dev.07017a9.1626869177", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -81,8 +81,8 @@ "version": "30.0.0-beta.38", "license": "MIT", "dependencies": { - "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.2e078e4.1625529824", + "discord-api-types": "^0.19.0-next.836e8fb.1625574825", + "discord.js": "^13.0.0-dev.07017a9.1626869177", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -2159,9 +2159,9 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.2e078e4.1625529824", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.2e078e4.1625529824.tgz", - "integrity": "sha512-NKNnoEmh3+4eCG44BOIBjlJS0bKQEH8OgWoEjdJ9K53MYa5lfqbSho4NKXe5+hVpMr+U43wJ8ByUvw96ogqu8w==", + "version": "13.0.0-dev.07017a9.1626869177", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.07017a9.1626869177.tgz", + "integrity": "sha512-awnE/59Sy6tnoAZUP7/f8tudcDT68WXxK0pgZZpA7WTGfyR5+IokWsFmkbS49dDll7OZQbi+L8iRt8ahYo3PGQ==", "dependencies": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -2169,7 +2169,7 @@ "@sapphire/async-queue": "^1.1.4", "@types/ws": "^7.4.5", "abort-controller": "^3.0.0", - "discord-api-types": "^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", + "discord-api-types": "^0.19.0", "node-fetch": "^2.6.1", "ws": "^7.5.1" }, @@ -2179,9 +2179,9 @@ } }, "node_modules/discord.js/node_modules/discord-api-types": { - "version": "0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e.tgz", - "integrity": "sha512-ttRA/8e/WKHDbGFfED5WlS7gID+kalmNr6iMiWBCvkphQ7kFHiTOVbnj/zX9ksaRaYXp/I38SCQ+qZvLu8DJZg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0.tgz", + "integrity": "sha512-t2HKLd43Lbe+rf+ffYfKVv9Kk5f6p7sFqvO6CMV55ZB0PgZv8WigCkt9FoJciYo5S3Q6CGYK+WnE/ZG+6vkBDQ==", "engines": { "node": ">=12" } @@ -8034,9 +8034,9 @@ "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" }, "discord.js": { - "version": "13.0.0-dev.2e078e4.1625529824", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.2e078e4.1625529824.tgz", - "integrity": "sha512-NKNnoEmh3+4eCG44BOIBjlJS0bKQEH8OgWoEjdJ9K53MYa5lfqbSho4NKXe5+hVpMr+U43wJ8ByUvw96ogqu8w==", + "version": "13.0.0-dev.07017a9.1626869177", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.07017a9.1626869177.tgz", + "integrity": "sha512-awnE/59Sy6tnoAZUP7/f8tudcDT68WXxK0pgZZpA7WTGfyR5+IokWsFmkbS49dDll7OZQbi+L8iRt8ahYo3PGQ==", "requires": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8044,15 +8044,15 @@ "@sapphire/async-queue": "^1.1.4", "@types/ws": "^7.4.5", "abort-controller": "^3.0.0", - "discord-api-types": "^0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", + "discord-api-types": "^0.19.0", "node-fetch": "^2.6.1", "ws": "^7.5.1" }, "dependencies": { "discord-api-types": { - "version": "0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e.tgz", - "integrity": "sha512-ttRA/8e/WKHDbGFfED5WlS7gID+kalmNr6iMiWBCvkphQ7kFHiTOVbnj/zX9ksaRaYXp/I38SCQ+qZvLu8DJZg==" + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0.tgz", + "integrity": "sha512-t2HKLd43Lbe+rf+ffYfKVv9Kk5f6p7sFqvO6CMV55ZB0PgZv8WigCkt9FoJciYo5S3Q6CGYK+WnE/ZG+6vkBDQ==" } } }, @@ -8877,8 +8877,8 @@ "@typescript-eslint/eslint-plugin": "^4.23.0", "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", - "discord-api-types": "^0.18.1", - "discord.js": "^13.0.0-dev.2e078e4.1625529824", + "discord-api-types": "^0.19.0-next.836e8fb.1625574825", + "discord.js": "^13.0.0-dev.07017a9.1626869177", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", diff --git a/backend/package.json b/backend/package.json index 792d8126..7751262b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.2e078e4.1625529824", + "discord.js": "^13.0.0-dev.07017a9.1626869177", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/data/GuildArchives.ts b/backend/src/data/GuildArchives.ts index df69e6c1..e55ac905 100644 --- a/backend/src/data/GuildArchives.ts +++ b/backend/src/data/GuildArchives.ts @@ -1,5 +1,6 @@ import { Guild, Snowflake } from "discord.js"; import moment from "moment-timezone"; +import { isDefaultSticker } from "src/utils/isDefaultSticker"; import { getRepository, Repository } from "typeorm"; import { renderTemplate } from "../templateFormatter"; import { trimLines } from "../utils"; @@ -13,7 +14,7 @@ const MESSAGE_ARCHIVE_HEADER_FORMAT = trimLines(` Server: {guild.name} ({guild.id}) `); const MESSAGE_ARCHIVE_MESSAGE_FORMAT = - "[#{channel.name}] [{user.id}] [{timestamp}] {user.username}#{user.discriminator}: {content}{attachments}"; + "[#{channel.name}] [{user.id}] [{timestamp}] {user.username}#{user.discriminator}: {content}{attachments}{stickers}"; export class GuildArchives extends BaseGuildRepository { protected archives: Repository; @@ -80,6 +81,12 @@ export class GuildArchives extends BaseGuildRepository { id: msg.id, timestamp: moment.utc(msg.posted_at).format("YYYY-MM-DD HH:mm:ss"), content: msg.data.content, + attachments: msg.data.attachments?.map(att => { + return JSON.stringify({ name: att.name, url: att.url, type: att.contentType }); + }), + stickers: msg.data.stickers?.map(sti => { + return JSON.stringify({ name: sti.name, id: sti.id, isDefault: isDefaultSticker(sti.id) }); + }), user, channel, }); diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index 0ede8e83..7fbcb120 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -1,6 +1,7 @@ import { GuildChannel, Message } from "discord.js"; import moment from "moment-timezone"; import { getRepository, Repository } from "typeorm"; +import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; import { isAPI } from "../globals"; import { QueuedEventEmitter } from "../QueuedEventEmitter"; import { MINUTES, SECONDS } from "../utils"; @@ -222,7 +223,7 @@ export class GuildSavedMessages extends BaseGuildRepository { // FIXME? { id }, { - data: newData, + data: newData as QueryDeepPartialEntity, }, ); diff --git a/backend/src/index.ts b/backend/src/index.ts index 83146fe2..52d555b3 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,4 +1,4 @@ -import { Client, Intents, TextChannel } from "discord.js"; +import { Client, Collection, Intents, Options, TextChannel } from "discord.js"; import fs from "fs"; import yaml from "js-yaml"; import { Knub, PluginError } from "knub"; @@ -166,7 +166,7 @@ connect().then(async () => { // Regular Intents.FLAGS.DIRECT_MESSAGES, Intents.FLAGS.GUILD_BANS, - Intents.FLAGS.GUILD_EMOJIS, + Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS, Intents.FLAGS.GUILD_INVITES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS, Intents.FLAGS.GUILD_MESSAGES, diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts index e18b8feb..0016a793 100644 --- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts +++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts @@ -1,9 +1,10 @@ -import { Permissions, Snowflake, TextChannel } from "discord.js"; +import { Permissions, Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { resolveUser, stripObjectToScalars, verboseChannelMention } from "../../../utils"; +import { resolveUser, verboseChannelMention } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; @@ -60,8 +61,8 @@ export async function deleteNextItem(pluginData: GuildPluginData renderTemplate(str, { - user: stripObjectToScalars(user), + user: userToConfigAccessibleUser(user), }); const formatted = typeof actionConfig === "string" diff --git a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts index 328a8772..a9f086be 100644 --- a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts @@ -1,7 +1,7 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { runAutomodOnAntiraidLevel } from "../events/runAutomodOnAntiraidLevel"; import { AutomodPluginType } from "../types"; @@ -21,7 +21,7 @@ export async function setAntiraidLevel( if (user) { logs.log(LogType.SET_ANTIRAID_USER, { level: newLevel ?? "off", - user: stripObjectToScalars(user), + user: userToConfigAccessibleUser(user), }); } else { logs.log(LogType.SET_ANTIRAID_AUTO, { diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index 29704425..bec20326 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -1,9 +1,10 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; -import { resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveUser } from "../../../utils"; import { CensorPluginType } from "../types"; export async function censorMessage( @@ -21,11 +22,11 @@ export async function censorMessage( } const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake); + const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)!; pluginData.state.serverLogs.log(LogType.CENSOR, { - user: stripObjectToScalars(user), - channel: stripObjectToScalars(channel), + user: userToConfigAccessibleUser(user), + channel: channelToConfigAccessibleChannel(channel), reason, message: savedMessage, messageText: disableCodeBlocks(deactivateMentions(savedMessage.data.content)), diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index 13b65cfc..9f5c6423 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -1,11 +1,14 @@ -import { MessageAttachment, MessageOptions, TextChannel } from "discord.js"; +import { MessageAttachment, MessageOptions, TextChannel, ThreadChannel } from "discord.js"; import fs from "fs"; import { downloadFile } from "../../utils"; const fsp = fs.promises; const MAX_ATTACHMENT_REHOST_SIZE = 1024 * 1024 * 8; -export async function rehostAttachment(attachment: MessageAttachment, targetChannel: TextChannel): Promise { +export async function rehostAttachment( + attachment: MessageAttachment, + targetChannel: TextChannel | ThreadChannel, +): Promise { if (attachment.size > MAX_ATTACHMENT_REHOST_SIZE) { return "Attachment too big to rehost"; } diff --git a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts index 8565c67b..54196d78 100644 --- a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts +++ b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts @@ -1,5 +1,5 @@ import { CooldownManager } from "knub"; -import { GuildLogs } from "../../../data/GuildLogs"; +import { GuildLogs } from "../../data/GuildLogs"; import { trimPluginDescription } from "../../utils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts index ff814dee..801229fd 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts @@ -2,7 +2,6 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { logsEvt } from "../types"; @@ -20,7 +19,7 @@ export const LogsGuildMemberAddEvt = logsEvt({ }); pluginData.state.guildLogs.log(LogType.MEMBER_JOIN, { - member: stripObjectToScalars(member, ["user", "roles"]), + member: memberToConfigAccessibleMember(member), new: member.user.createdTimestamp >= newThreshold ? " :new:" : "", account_age: accountAge, }); diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index eff1bd68..aa997913 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -27,8 +27,8 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ } if (!isEqual(oldMember.roles, member.roles)) { - const addedRoles = diff(member.roles, oldMember.roles); - const removedRoles = diff(oldMember.roles, member.roles); + const addedRoles = diff(member.roles.cache.keyArray(), oldMember.roles.cache.keyArray()); + const removedRoles = diff(oldMember.roles.cache.keyArray(), member.roles.cache.keyArray()); let skip = false; if ( diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index 637e6cd3..bcb10d14 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -1,15 +1,16 @@ -import { MessageAttachment, Snowflake } from "discord.js"; +import { MessageAttachment, Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; -import { resolveUser, stripObjectToScalars, useMediaUrls } from "../../../utils"; +import { resolveUser, useMediaUrls } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake); + const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake)!; if (user) { // Replace attachment URLs with media URLs @@ -27,8 +28,8 @@ export async function onMessageDelete(pluginData: GuildPluginData, - channel: TextChannel, + channel: TextChannel | ThreadChannel, ids: string[], ) { const failed: string[] = []; diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts index 6dbfb67d..794e96ed 100644 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts @@ -1,10 +1,11 @@ +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveMember, resolveUser } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { modActionsCmd } from "../types"; @@ -83,7 +84,7 @@ export const AddCaseCmd = modActionsCmd({ // Log the action pluginData.state.serverLogs.log(LogType.CASE_CREATE, { - mod: stripObjectToScalars(mod.user), + mod: userToConfigAccessibleUser(mod.user), userId: user.id, caseNum: theCase.case_number, caseType: type.toUpperCase(), diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index 8ebc8e2a..34a18e36 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -1,11 +1,13 @@ +import { User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { getMemberLevel } from "knub/dist/helpers"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveMember, resolveUser } from "../../../utils"; import { banLock } from "../../../utils/lockNameHelpers"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; import { banUserId } from "../functions/banUserId"; @@ -109,8 +111,8 @@ export const BanCmd = modActionsCmd({ }); const logtype = time ? LogType.MEMBER_TIMED_BAN : LogType.MEMBER_BAN; pluginData.state.serverLogs.log(logtype, { - mod: stripObjectToScalars(mod.user), - user: stripObjectToScalars(user), + mod: userToConfigAccessibleUser(mod.user), + user: userToConfigAccessibleUser(user), caseNumber: createdCase.case_number, reason, banTime: time ? humanizeDuration(time) : null, diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 931ce82c..0550942f 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -1,5 +1,6 @@ import { TextChannel } from "discord.js"; import { helpers } from "knub"; +import { memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; @@ -81,7 +82,7 @@ export const DeleteCaseCmd = modActionsCmd({ const logs = pluginData.getPlugin(LogsPlugin); logs.log(LogType.CASE_DELETE, { - mod: stripObjectToScalars(message.member, ["user", "roles"]), + mod: memberToConfigAccessibleMember(message.member), case: stripObjectToScalars(theCase), }); } diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index b84c2283..d14b15a4 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -1,10 +1,11 @@ import { Snowflake } from "discord.js"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveMember, resolveUser } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; import { isBanned } from "../functions/isBanned"; @@ -91,7 +92,7 @@ export const ForcebanCmd = modActionsCmd({ // Log the action pluginData.state.serverLogs.log(LogType.MEMBER_FORCEBAN, { - mod: stripObjectToScalars(mod.user), + mod: userToConfigAccessibleUser(mod.user), userId: user.id, caseNumber: createdCase.case_number, reason, diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index dc1e0855..bc737349 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -1,6 +1,7 @@ import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; import { performance } from "perf_hooks"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; @@ -80,6 +81,7 @@ export const MassbanCmd = modActionsCmd({ const startTime = performance.now(); const failedBans: string[] = []; const casesPlugin = pluginData.getPlugin(CasesPlugin); + const deleteDays = (await pluginData.config.getForMessage(msg)).ban_delete_message_days; for (const [i, userId] of args.userIds.entries()) { if (pluginData.state.unloaded) { break; @@ -92,7 +94,7 @@ export const MassbanCmd = modActionsCmd({ pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId, 120 * 1000); await pluginData.guild.bans.create(userId as Snowflake, { - days: 1, + days: deleteDays, reason: banReason != null ? encodeURIComponent(banReason) : undefined, }); @@ -128,7 +130,7 @@ export const MassbanCmd = modActionsCmd({ } else { // Some or all bans were successful. Create a log entry for the mass ban and notify the user. pluginData.state.serverLogs.log(LogType.MASSBAN, { - mod: stripObjectToScalars(msg.author), + mod: userToConfigAccessibleUser(msg.author), count: successfulBanCount, reason: banReason, }); diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index 1d6ec0c7..9913ceac 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -1,5 +1,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; @@ -87,7 +88,7 @@ export const MassunbanCmd = modActionsCmd({ } else { // Some or all unbans were successful. Create a log entry for the mass unban and notify the user. pluginData.state.serverLogs.log(LogType.MASSUNBAN, { - mod: stripObjectToScalars(msg.author), + mod: userToConfigAccessibleUser(msg.author), count: successfulUnbanCount, reason: unbanReason, }); diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index a2c1faf2..bd26f471 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -1,5 +1,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; @@ -87,7 +88,7 @@ export const MassmuteCmd = modActionsCmd({ } else { // Success on all or some mutes pluginData.state.serverLogs.log(LogType.MASSMUTE, { - mod: stripObjectToScalars(msg.author), + mod: userToConfigAccessibleUser(msg.author), count: successfulMuteCount, }); diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index c5cd7679..195f10ae 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -1,8 +1,10 @@ +import { User } from "discord.js"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { modActionsCmd } from "../types"; @@ -41,8 +43,8 @@ export const NoteCmd = modActionsCmd({ }); pluginData.state.serverLogs.log(LogType.MEMBER_NOTE, { - mod: stripObjectToScalars(msg.author), - user: stripObjectToScalars(user, ["user", "roles"]), + mod: userToConfigAccessibleUser(msg.author), + user: userToConfigAccessibleUser(user), caseNumber: createdCase.case_number, reason, }); diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index 5a9be476..5b4407f1 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -1,10 +1,11 @@ import { Snowflake } from "discord.js"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveUser } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; import { IgnoredEventType, modActionsCmd } from "../types"; @@ -73,7 +74,7 @@ export const UnbanCmd = modActionsCmd({ // Log the action pluginData.state.serverLogs.log(LogType.MEMBER_UNBAN, { - mod: stripObjectToScalars(mod.user), + mod: userToConfigAccessibleUser(mod.user), userId: user.id, caseNumber: createdCase.case_number, reason, diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index 850ed2c0..0638dcf9 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -1,4 +1,5 @@ import { GuildAuditLogs, User } from "discord.js"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; @@ -65,8 +66,8 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt({ } pluginData.state.serverLogs.log(LogType.MEMBER_BAN, { - mod: mod ? stripObjectToScalars(mod, ["user"]) : null, - user: stripObjectToScalars(user, ["user"]), + mod: mod ? userToConfigAccessibleUser(mod) : null, + user: userToConfigAccessibleUser(user), caseNumber: createdCase?.case_number ?? 0, reason, }); diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index 9bc6baf5..24c89e8d 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -1,9 +1,10 @@ import { GuildAuditLogs, User } from "discord.js"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { resolveUser, UnknownUser } from "../../../utils"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; @@ -58,8 +59,8 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({ } pluginData.state.serverLogs.log(LogType.MEMBER_KICK, { - user: stripObjectToScalars(member.user), - mod: mod ? stripObjectToScalars(mod) : null, + user: userToConfigAccessibleUser(member.user!), + mod: mod ? userToConfigAccessibleUser(mod) : null, caseNumber: createdCase?.case_number ?? 0, reason: kickAuditLogEntry.reason || "", }); diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index 7bec3cb7..5e788df5 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -1,8 +1,9 @@ import { GuildAuditLogs, User } from "discord.js"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; -import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { resolveUser, UnknownUser } from "../../../utils"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; @@ -63,7 +64,7 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({ } pluginData.state.serverLogs.log(LogType.MEMBER_UNBAN, { - mod: mod ? stripObjectToScalars(mod, ["user"]) : null, + mod: mod ? userToConfigAccessibleUser(mod) : null, userId: user.id, caseNumber: createdCase?.case_number ?? 0, }); diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index 06820890..a957696c 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -1,4 +1,4 @@ -import { GuildMember, TextChannel } from "discord.js"; +import { GuildMember, TextChannel, ThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { hasPermission } from "knub/dist/helpers"; import { LogType } from "../../../data/LogType"; @@ -19,7 +19,7 @@ export async function actualKickMemberCmd( reason: string; mod: GuildMember; notify?: string; - "notify-channel"?: TextChannel; + "notify-channel"?: TextChannel | ThreadChannel; clean?: boolean; }, ) { diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index 57b0f249..4dc16209 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -1,4 +1,4 @@ -import { GuildMember, Message, TextChannel, User } from "discord.js"; +import { GuildMember, Message, TextChannel, ThreadChannel, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; @@ -19,7 +19,13 @@ export async function actualMuteUserCmd( pluginData: GuildPluginData, user: User | UnknownUser, msg: Message, - args: { time?: number; reason?: string; mod: GuildMember; notify?: string; "notify-channel"?: TextChannel }, + args: { + time?: number; + reason?: string; + mod: GuildMember; + notify?: string; + "notify-channel"?: TextChannel | ThreadChannel; + }, ) { // The moderator who did the action is the message author or, if used, the specified -mod let mod: GuildMember = msg.member!; diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index 101014b9..f9b37678 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -1,6 +1,7 @@ import { DiscordAPIError, Snowflake, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; @@ -129,8 +130,8 @@ export async function banUserId( const mod = await resolveUser(pluginData.client, modId); const logtype = banTime ? LogType.MEMBER_TIMED_BAN : LogType.MEMBER_BAN; pluginData.state.serverLogs.log(logtype, { - mod: stripObjectToScalars(mod), - user: stripObjectToScalars(user), + mod: userToConfigAccessibleUser(mod), + user: userToConfigAccessibleUser(user), caseNumber: createdCase.case_number, reason, banTime: banTime ? humanizeDuration(banTime) : null, diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index d676e9aa..8c7d1563 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -1,5 +1,6 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; @@ -40,7 +41,7 @@ export async function kickMember( guildName: pluginData.guild.name, reason, moderator: kickOptions.caseArgs?.modId - ? stripObjectToScalars(await resolveUser(pluginData.client, kickOptions.caseArgs.modId)) + ? userToConfigAccessibleUser(await resolveUser(pluginData.client, kickOptions.caseArgs.modId)) : {}, }); @@ -79,8 +80,8 @@ export async function kickMember( // Log the action const mod = await resolveUser(pluginData.client, modId); pluginData.state.serverLogs.log(LogType.MEMBER_KICK, { - mod: stripObjectToScalars(mod), - user: stripObjectToScalars(member.user), + mod: userToConfigAccessibleUser(mod), + user: userToConfigAccessibleUser(member.user), caseNumber: createdCase.case_number, reason, }); diff --git a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts index f983dd3b..bf6f0ab4 100644 --- a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts +++ b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts @@ -4,6 +4,7 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; +import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { resolveUser, SECONDS, stripObjectToScalars } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; @@ -57,7 +58,7 @@ export async function outdatedTempbansLoop(pluginData: GuildPluginData: + Threads cannot have Bot Slowmode + `), + ); + return; + } } catch (e) { sendErrorMessage( pluginData, diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 5f9ec9a4..ce4894e0 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,5 +1,6 @@ -import { Permissions, TextChannel } from "discord.js"; +import { Permissions, TextChannel, ThreadChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; +import { ChannelTypeStrings } from "src/types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { asSingleLine, DAYS, disableInlineCode, HOURS, MINUTES } from "../../../utils"; @@ -38,7 +39,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ ], async run({ message: msg, args, pluginData }) { - const channel: TextChannel = args.channel || msg.channel; + const channel: TextChannel | ThreadChannel = args.channel || msg.channel; if (args.time === 0) { // Workaround until we can call SlowmodeDisableCmd from here @@ -122,7 +123,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ if (mode === "native") { // If there is an existing bot-maintained slowmode, disable that first const existingBotSlowmode = await pluginData.state.slowmodes.getChannelSlowmode(channel.id); - if (existingBotSlowmode) { + if (existingBotSlowmode && channel.type === ChannelTypeStrings.TEXT) { await disableBotSlowmodeForChannel(pluginData, channel); } diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 2bcb7c9d..6e180a36 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -1,5 +1,6 @@ import { GuildChannel, Permissions, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { isDiscordAPIError, stripObjectToScalars, UnknownUser } from "../../../utils"; @@ -20,7 +21,7 @@ export async function applyBotSlowmodeToUserId( await channel.permissionOverwrites.create(userId as Snowflake, { SEND_MESSAGES: false }, { type: 1 }); } } catch (e) { - const user = pluginData.client.users.fetch(userId as Snowflake) || new UnknownUser({ id: userId }); + const user = (await pluginData.client.users.fetch(userId as Snowflake)) || new UnknownUser({ id: userId }); if (isDiscordAPIError(e) && e.code === 50013) { logger.warn( @@ -28,14 +29,14 @@ export async function applyBotSlowmodeToUserId( ); pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Missing permissions to apply bot slowmode to {userMention(user)} in {channelMention(channel)}`, - user: stripObjectToScalars(user), - channel: stripObjectToScalars(channel), + user: userToConfigAccessibleUser(user), + channel: channelToConfigAccessibleChannel(channel), }); } else { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Failed to apply bot slowmode to {userMention(user)} in {channelMention(channel)}`, - user: stripObjectToScalars(user), - channel: stripObjectToScalars(channel), + user: userToConfigAccessibleUser(user), + channel: channelToConfigAccessibleChannel(channel), }); throw e; } diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index 381fa930..5c59aaf3 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,11 +1,11 @@ -import { GuildChannel, Snowflake, TextChannel } from "discord.js"; +import { GuildChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { SlowmodePluginType } from "../types"; export async function clearBotSlowmodeFromUserId( pluginData: GuildPluginData, - channel: GuildChannel & TextChannel, + channel: TextChannel, userId: string, force = false, ) { diff --git a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts index d1d40e0b..a6b06364 100644 --- a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts +++ b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts @@ -1,11 +1,11 @@ -import { GuildChannel, TextChannel } from "discord.js"; +import { GuildChannel, TextChannel, ThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { SlowmodePluginType } from "../types"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; export async function disableBotSlowmodeForChannel( pluginData: GuildPluginData, - channel: GuildChannel & TextChannel, + channel: TextChannel, ) { // Disable channel slowmode await pluginData.state.slowmodes.deleteChannelSlowmode(channel.id); diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index bd09847a..e3b67ed1 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -1,6 +1,7 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; +import { channelToConfigAccessibleChannel, memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -185,8 +186,8 @@ export async function logAndDetectMessageSpam( // Create a log entry logs.log(LogType.MESSAGE_SPAM_DETECTED, { - member: stripObjectToScalars(member, ["user", "roles"]), - channel: stripObjectToScalars(channel), + member: memberToConfigAccessibleMember(member!), + channel: channelToConfigAccessibleChannel(channel!), description, limit: spamConfig.count, interval: spamConfig.interval, diff --git a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts index 7e1b3c60..107cb45e 100644 --- a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts @@ -1,4 +1,5 @@ import { GuildPluginData } from "knub"; +import { memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; @@ -78,7 +79,7 @@ export async function logAndDetectOtherSpam( clearRecentUserActions(pluginData, RecentActionType.VoiceChannelMove, userId, actionGroupId); logs.log(LogType.OTHER_SPAM_DETECTED, { - member: stripObjectToScalars(member, ["user", "roles"]), + member: memberToConfigAccessibleMember(member!), description, limit: spamConfig.count, interval: spamConfig.interval, diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index e117983b..abf4a86c 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -1,3 +1,4 @@ +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { TemplateParseError } from "../../../templateFormatter"; @@ -20,8 +21,8 @@ export const TagEvalCmd = tagsCmd({ args.body, [], { - member: stripObjectToScalars(msg.member, ["user"]), - user: stripObjectToScalars(msg.member.user), + member: memberToConfigAccessibleMember(msg.member), + user: userToConfigAccessibleUser(msg.member.user), }, { member: msg.member }, ); diff --git a/backend/src/plugins/Tags/util/renderTagFromString.ts b/backend/src/plugins/Tags/util/renderTagFromString.ts index 930a70a5..4461f4a4 100644 --- a/backend/src/plugins/Tags/util/renderTagFromString.ts +++ b/backend/src/plugins/Tags/util/renderTagFromString.ts @@ -2,6 +2,7 @@ import { GuildMember } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { parseArguments } from "knub-command-manager"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { TemplateParseError } from "../../../templateFormatter"; import { StrictMessageContent, stripObjectToScalars } from "../../../utils"; @@ -27,8 +28,8 @@ export async function renderTagFromString( tagBody, tagArgs, { - member: stripObjectToScalars(member, ["user"]), - user: stripObjectToScalars(member.user), + member: memberToConfigAccessibleMember(member), + user: userToConfigAccessibleUser(member.user), }, { member }, ); diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 9186e3c8..cfdaec88 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -1,6 +1,7 @@ import { Message, Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -41,8 +42,8 @@ async function cleanMessages( const archiveUrl = pluginData.state.archives.getUrl(baseUrl, archiveId); pluginData.state.logs.log(LogType.CLEAN, { - mod: stripObjectToScalars(mod), - channel: stripObjectToScalars(channel), + mod: userToConfigAccessibleUser(mod), + channel: channelToConfigAccessibleChannel(channel), count: savedMessages.length, archiveUrl, }); @@ -172,7 +173,7 @@ export const CleanCmd = utilityCmd({ let responseText = `Cleaned ${messagesToClean.length} ${messagesToClean.length === 1 ? "message" : "messages"}`; if (targetChannel.id !== msg.channel.id) { - responseText += ` in <#${targetChannel.id}>\n${cleanResult.archiveUrl}`; + responseText += ` in <#${targetChannel.id}>: ${cleanResult.archiveUrl}`; } if (args.update) { diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index d749b9c7..169da88e 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -1,4 +1,9 @@ import { VoiceChannel } from "discord.js"; +import { + channelToConfigAccessibleChannel, + memberToConfigAccessibleMember, + userToConfigAccessibleUser, +} from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; @@ -35,9 +40,9 @@ export const VcdisconnectCmd = utilityCmd({ } pluginData.state.logs.log(LogType.VOICE_CHANNEL_FORCE_DISCONNECT, { - mod: stripObjectToScalars(msg.author), - member: stripObjectToScalars(args.member, ["user", "roles"]), - oldChannel: stripObjectToScalars(channel), + mod: userToConfigAccessibleUser(msg.author), + member: memberToConfigAccessibleMember(args.member), + oldChannel: channelToConfigAccessibleChannel(channel), }); sendSuccessMessage( diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 784c5f4c..76eb2161 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -1,4 +1,9 @@ import { Snowflake, VoiceChannel } from "discord.js"; +import { + channelToConfigAccessibleChannel, + memberToConfigAccessibleMember, + userToConfigAccessibleUser, +} from "src/utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; @@ -74,10 +79,10 @@ export const VcmoveCmd = utilityCmd({ } pluginData.state.logs.log(LogType.VOICE_CHANNEL_FORCE_MOVE, { - mod: stripObjectToScalars(msg.author), - member: stripObjectToScalars(args.member, ["user", "roles"]), - oldChannel: stripObjectToScalars(oldVoiceChannel), - newChannel: stripObjectToScalars(channel), + mod: userToConfigAccessibleUser(msg.author), + member: memberToConfigAccessibleMember(args.member), + oldChannel: channelToConfigAccessibleChannel(oldVoiceChannel!), + newChannel: channelToConfigAccessibleChannel(channel), }); sendSuccessMessage( @@ -182,10 +187,10 @@ export const VcmoveAllCmd = utilityCmd({ } pluginData.state.logs.log(LogType.VOICE_CHANNEL_FORCE_MOVE, { - mod: stripObjectToScalars(msg.author), - member: stripObjectToScalars(currMember, ["user", "roles"]), - oldChannel: stripObjectToScalars(args.oldChannel), - newChannel: stripObjectToScalars(channel), + mod: userToConfigAccessibleUser(msg.author), + member: memberToConfigAccessibleMember(currMember), + oldChannel: channelToConfigAccessibleChannel(args.oldChannel), + newChannel: channelToConfigAccessibleChannel(channel), }); } diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index 2cfa6e53..ce1bf066 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -1,4 +1,9 @@ import { Snowflake, TextChannel } from "discord.js"; +import { + channelToConfigAccessibleChannel, + memberToConfigAccessibleMember, + userToConfigAccessibleUser, +} from "src/utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { createChunkedMessage, stripObjectToScalars } from "../../../utils"; @@ -49,7 +54,7 @@ export const SendWelcomeMessageEvt = welcomeMessageEvt({ } catch { pluginData.state.logs.log(LogType.DM_FAILED, { source: "welcome message", - user: stripObjectToScalars(member.user), + user: userToConfigAccessibleUser(member.user), }); } } @@ -63,8 +68,8 @@ export const SendWelcomeMessageEvt = welcomeMessageEvt({ } catch { pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Failed send a welcome message for {userMention(member)} to {channelMention(channel)}`, - member: stripObjectToScalars(member), - channel: stripObjectToScalars(channel), + member: memberToConfigAccessibleMember(member), + channel: channelToConfigAccessibleChannel(channel), }); } } diff --git a/backend/src/types.ts b/backend/src/types.ts index 27286147..9f9c1a53 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -65,15 +65,18 @@ export interface CommandInfo { } export enum ChannelTypeStrings { - TEXT = "text", - DM = "dm", - VOICE = "voice", - GROUP = "group", - CATEGORY = "category", - NEWS = "news", - STORE = "store", - STAGE = "stage", - UNKNOWN = "unknown", + TEXT = "GUILD_TEXT", + DM = "DM", + VOICE = "GUILD_VOICE", + GROUP = "GROUP_DM", + CATEGORY = "GUILD_CATEGORY", + NEWS = "GUILD_NEWS", + STORE = "GUILD_STORE", + NEWS_THREAD = "GUILD_NEWS_THREAD", + PUBLIC_THREAD = "GUILD_PUBLIC_THREAD", + PRIVATE_THREAD = "GUILD_PRIVATE_THREAD", + STAGE = "GUILD_STAGE_VOICE", + UNKNOWN = "UNKNOWN", } export enum MessageTypeStrings { diff --git a/backend/src/utils.ts b/backend/src/utils.ts index be9c6767..5a22c12d 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -8,6 +8,7 @@ import { GuildChannel, GuildMember, Invite, + LimitedCollection, Message, MessageAttachment, MessageEmbed, @@ -17,7 +18,9 @@ import { PartialChannelData, PartialMessage, Snowflake, + Sticker, TextChannel, + ThreadChannel, User, } from "discord.js"; import emojiRegex from "emoji-regex"; @@ -37,6 +40,7 @@ import { waitForButtonConfirm } from "./utils/waitForInteraction"; import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; import { isEqual } from "lodash"; import humanizeDuration from "humanize-duration"; +import { ChannelTypeStrings } from "./types"; const fsp = fs.promises; @@ -247,7 +251,7 @@ export type InviteOpts = "withMetadata" | "withCount" | "withoutCount"; export type GuildInvite = Invite & { guild: Guild }; export type GroupDMInvite = Invite & { channel: PartialChannelData; - type: typeof Constants.ChannelTypes.GROUP; + type: typeof Constants.ChannelTypes.GROUP_DM; }; /** @@ -1015,7 +1019,7 @@ export type CustomEmoji = { id: string; } & Emoji; -export type UserNotificationMethod = { type: "dm" } | { type: "channel"; channel: TextChannel }; +export type UserNotificationMethod = { type: "dm" } | { type: "channel"; channel: TextChannel | ThreadChannel }; export const disableUserNotificationStrings = ["no", "none", "off"]; @@ -1312,6 +1316,18 @@ export async function resolveInvite( return promise as ResolveInviteReturnType; } +const internalStickerCache: LimitedCollection = new LimitedCollection(500); + +export async function resolveStickerId(bot: Client, id: Snowflake): Promise { + const cachedSticker = internalStickerCache.get(id); + if (cachedSticker) return cachedSticker; + + const fetchedSticker = await bot.fetchSticker(id).catch(undefined); + internalStickerCache.set(id, fetchedSticker); + + return fetchedSticker; +} + export async function confirm(channel: TextChannel, userId: string, content: MessageOptions): Promise { return waitForButtonConfirm(channel, content, { restrictToId: userId }); } @@ -1352,7 +1368,10 @@ export function verboseUserName(user: User | UnknownUser): string { } export function verboseChannelMention(channel: GuildChannel): string { - const plainTextName = channel.type === "voice" || channel.type === "stage" ? channel.name : `#${channel.name}`; + const plainTextName = + channel.type === ChannelTypeStrings.VOICE || channel.type === ChannelTypeStrings.STAGE + ? channel.name + : `#${channel.name}`; return `<#${channel.id}> (**${plainTextName}**, \`${channel.id}\`)`; } @@ -1478,7 +1497,7 @@ export function isGuildInvite(invite: Invite): invite is } export function isGroupDMInvite(invite: Invite): invite is GroupDMInvite { - return invite.guild == null && invite.channel?.type === "group"; + return invite.guild == null && invite.channel?.type === ChannelTypeStrings.GROUP; } export function inviteHasCounts(invite: Invite): invite is Invite { diff --git a/backend/src/utils/configAccessibleObjects.ts b/backend/src/utils/configAccessibleObjects.ts index 92dc17c0..1c281ed6 100644 --- a/backend/src/utils/configAccessibleObjects.ts +++ b/backend/src/utils/configAccessibleObjects.ts @@ -8,15 +8,16 @@ import { ThreadChannel, User, } from "discord.js"; +import { UnknownUser } from "src/utils"; export interface IConfigAccessibleUser { - id: Snowflake; + id: Snowflake | string; username: string; discriminator: string; mention: string; - avatarURL: string; - bot: boolean; - createdAt: number; + avatarURL?: string; + bot?: boolean; + createdAt?: number; } export interface IConfigAccessibleRole { @@ -36,15 +37,27 @@ export interface IConfigAccessibleMember extends IConfigAccessibleUser { guildName: string; } -export function userToConfigAccessibleUser(user: User): IConfigAccessibleUser { +export function userToConfigAccessibleUser(user: User | UnknownUser): IConfigAccessibleUser { + if (`${user.username}#${user.discriminator}` === "Unknown#0000") { + const toReturnPartial: IConfigAccessibleUser = { + id: user.id, + username: "Unknown", + discriminator: "0000", + mention: `<@${user.id}>`, + }; + + return toReturnPartial; + } + + const properUser = user as User; const toReturn: IConfigAccessibleUser = { - id: user.id, - username: user.username, - discriminator: user.discriminator, - mention: `<@${user.id}>`, - avatarURL: user.displayAvatarURL({ dynamic: true }), - bot: user.bot, - createdAt: user.createdTimestamp, + id: properUser.id, + username: properUser.username, + discriminator: properUser.discriminator, + mention: `<@${properUser.id}>`, + avatarURL: properUser.displayAvatarURL({ dynamic: true }), + bot: properUser.bot, + createdAt: properUser.createdTimestamp, }; return toReturn; diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index 6bd6aae0..e711c620 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -4,6 +4,7 @@ import { MessageEditOptions, MessageOptions, MessageReaction, + PartialMessageReaction, PartialUser, TextChannel, User, @@ -37,7 +38,10 @@ export async function createPaginatedMessage( let page = 1; let pageLoadId = 0; // Used to avoid race conditions when rapidly switching pages - const reactionListener = async (reactionMessage: MessageReaction, reactor: User | PartialUser) => { + const reactionListener = async ( + reactionMessage: MessageReaction | PartialMessageReaction, + reactor: User | PartialUser, + ) => { if (reactionMessage.message.id !== message.id) { return; } diff --git a/backend/src/utils/getMissingChannelPermissions.ts b/backend/src/utils/getMissingChannelPermissions.ts index 0d224887..a1a7be9a 100644 --- a/backend/src/utils/getMissingChannelPermissions.ts +++ b/backend/src/utils/getMissingChannelPermissions.ts @@ -1,4 +1,4 @@ -import { GuildChannel, GuildMember } from "discord.js"; +import { GuildChannel, GuildMember, ThreadChannel } from "discord.js"; import { getMissingPermissions } from "./getMissingPermissions"; /** @@ -7,7 +7,7 @@ import { getMissingPermissions } from "./getMissingPermissions"; */ export function getMissingChannelPermissions( member: GuildMember, - channel: GuildChannel, + channel: GuildChannel | ThreadChannel, requiredPermissions: number | bigint, ): bigint { const memberChannelPermissions = channel.permissionsFor(member.id); diff --git a/backend/src/utils/isDefaultSticker.ts b/backend/src/utils/isDefaultSticker.ts new file mode 100644 index 00000000..85e3e974 --- /dev/null +++ b/backend/src/utils/isDefaultSticker.ts @@ -0,0 +1,306 @@ +const defaultStickerIds = [ + "749044136589393960", + "749045492352155769", + "749045743976710154", + "749046077629399122", + "749046696482439188", + "749047112028651530", + "749049128012742676", + "749051158542417980", + "749051341325729913", + "749051517964648458", + "749051844663181383", + "749052011751932006", + "749052505308266645", + "749052707536371812", + "749052944682582036", + "749053210760577245", + "749053441527251087", + "749053689419006003", + "749053927907131433", + "749054120345993216", + "749054292937277450", + "749054660769218631", + "749054894585151518", + "749055120263872532", + "754112474868875294", + "755244355563815073", + "755244428305760266", + "755244598799892490", + "755244649655959615", + "755490897143136446", + "781291131828699156", + "781291442961383434", + "781291606493495306", + "781321379546398740", + "781321702805340200", + "781321874650562560", + "781321970301796372", + "781322427820277791", + "781322566060343296", + "781322673527193620", + "781322765641973770", + "781322967127818240", + "781323072102858782", + "781323157239103548", + "781323249505927198", + "781323366921404426", + "781323471249604648", + "781323560756707328", + "781323628267962408", + "781323712640974858", + "781323769960202280", + "781323880723251220", + "781324010952458270", + "781324114685329417", + "781324245468315668", + "781324376884248596", + "781324451014246460", + "781324562905432064", + "781324642736144424", + "781324722394103808", + "813950454420471818", + "813950661292064808", + "813950759296172092", + "813950952436531213", + "813951067557462106", + "813951129544818708", + "813951478803857408", + "813951723822645278", + "813951924604895242", + "813952523408113694", + "813952588650381332", + "813952646083772486", + "813952751200763934", + "813952825520291902", + "813952903064584202", + "809207198856904764", + "809207265092698112", + "809207315822936064", + "809207399054442526", + "809207795999572038", + "809207857773936710", + "809207919115239525", + "809208197235343410", + "809208263987953694", + "809208353884471376", + "809208424419426344", + "809208728251138088", + "809208771834019850", + "809209078261874688", + "809209146846871562", + "809209216966852628", + "809209266556764241", + "809209320494333952", + "809209482902503444", + "809209627450671114", + "809209856321650698", + "809209923765272586", + "809210027524620328", + "809210129978228766", + "809210201033932891", + "809210344311619584", + "809210578433736724", + "809210750702583868", + "809210904263917618", + "809211336633614346", + "818596923887583302", + "818596976521248819", + "818597244017049652", + "818597355619483688", + "818597454483161098", + "818597555608092722", + "818597623397220362", + "818597707132043285", + "818597810047680532", + "818597885671243776", + "818598022798770186", + "818598125077266432", + "818598371324592218", + "818598476883165194", + "818599312882794506", + "754104467573571584", + "754106820079124480", + "754107009720385556", + "754107496884338698", + "754107539200671765", + "754107634172297306", + "754108691493683221", + "754108771852222564", + "754108811354046554", + "754108835895181322", + "754108890559283200", + "754108923509997568", + "754108948356792320", + "754108992195919903", + "754109038693974057", + "754109076933443614", + "754109137830281297", + "754109419821727885", + "754109474691612782", + "754109519113617478", + "754109542526091434", + "754109580069437481", + "754109748999225374", + "754109772449710080", + "754109815877402634", + "754109869325549638", + "754109908995276810", + "754109937872928857", + "754109983108497468", + "754110021574328400", + "823973720266899506", + "823973812748025937", + "823974092700254238", + "823974203929526292", + "823974288897343518", + "823974429834477578", + "823974530686648440", + "823974669748666418", + "823974764057722910", + "823974837156446208", + "823974930399232020", + "823975146263412786", + "823976022025306152", + "823976102976290866", + "823976251269054494", + "751604756748959874", + "751605093065031760", + "751605170818777108", + "751605236476543086", + "751605353585836101", + "751605453842022562", + "751605541687787550", + "751605606070091887", + "751605670654246972", + "751605738270359592", + "751605803932319754", + "751605873083678802", + "751605941375598672", + "751606014054236261", + "751606065447305216", + "751606120493350982", + "751606190383038604", + "751606254073544784", + "751606317936017458", + "751606379340365864", + "751606441315401848", + "751606491542192200", + "751606539600527410", + "751606636698927157", + "751606719611928586", + "751606808837357608", + "751606868115193948", + "751606917494734959", + "751606992849862706", + "751607061762277396", + "819128604311027752", + "819129296374595614", + "819130301702995968", + "819131032259133440", + "819131232642007062", + "819131655738228796", + "819131835635466280", + "819131978401316864", + "819132831023628298", + "819139462373310494", + "819139728128344064", + "819140386551365642", + "819140940018352178", + "819141435474706472", + "819145601031733269", + "772963467622744075", + "772963523630071828", + "772963562553081886", + "772970847232458782", + "772972089963577354", + "772973760457605182", + "772974139053047829", + "772974519786799114", + "772975031487168582", + "772975484874522674", + "772975929998835722", + "772976230718111764", + "772976562831097906", + "772976718939160606", + "772976899152543745", + "773897032485175296", + "773898515990315028", + "773899933131604008", + "773901313578369044", + "773902656442728488", + "773903221272870973", + "773903633951490098", + "773904449440579624", + "773909554005540894", + "773911171987144754", + "773912319839043625", + "773912616425881630", + "773914273075429387", + "773914595756081172", + "773914892800622612", + "776241800930787349", + "776241838813216788", + "776241877862187048", + "776241909374910534", + "776242510334525460", + "776242536820899861", + "776242590148198400", + "776242614663512095", + "776242643717455882", + "776242672562077696", + "776242703834284132", + "776242899662405712", + "776242924542492672", + "776242962072993792", + "776243107654008872", + "776243140750606366", + "776243172258611200", + "776243957259698226", + "776243988038025287", + "776244033244627004", + "776244136725970974", + "776244212806713344", + "776244240753098752", + "776244473184256000", + "776244492948209674", + "776244520928542731", + "776244545096122379", + "776244577509179412", + "776244610917335070", + "776244640239452200", + "816086581509095424", + "816086770541396028", + "816086882823831613", + "816086934266839040", + "816087074310193162", + "816087132447178774", + "816087220753924096", + "816087273548415006", + "816087483640709131", + "816087668630618152", + "816087792291282944", + "816087883252760617", + "816087973053464606", + "816088051121258596", + "816088135334494267", + "831569193391489054", + "831569335696228352", + "831569414746144798", + "831569534459576381", + "831569719814914108", + "831569909288140832", + "831570117057970176", + "831570479415689309", + "831570715471380550", + "831571053569769492", + "831571151535996988", + "831571320377835540", + "831571470824112138", + "831571594055778304", + "831571726223540294", +]; + +export function isDefaultSticker(id: string): boolean { + return defaultStickerIds.includes(id); +} From c932269b7d5661d60a81a85d2e41da29b752edc7 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Sun, 25 Jul 2021 14:32:08 +0200 Subject: [PATCH 35/79] DJS Update, Full Import Cleanup --- backend/package-lock.json | 22 +++++++++---------- backend/package.json | 2 +- backend/src/data/entities/ButtonRole.ts | 2 +- backend/src/index.ts | 4 ++-- .../plugins/AutoDelete/util/deleteNextItem.ts | 4 ++-- backend/src/plugins/Automod/actions/reply.ts | 2 +- .../Automod/functions/setAntiraidLevel.ts | 2 +- .../src/plugins/Censor/util/censorMessage.ts | 4 ++-- .../Logs/events/LogsChannelModifyEvts.ts | 2 +- .../plugins/Logs/events/LogsGuildBanEvts.ts | 2 +- .../Logs/events/LogsGuildMemberAddEvt.ts | 2 +- .../Logs/events/LogsGuildMemberRemoveEvt.ts | 2 +- .../plugins/Logs/events/LogsRoleModifyEvts.ts | 2 +- .../events/LogsStageInstanceModifyEvts.ts | 4 ++-- .../Logs/events/LogsThreadModifyEvts.ts | 4 ++-- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 2 +- .../Logs/events/LogsVoiceChannelEvts.ts | 6 +++-- .../src/plugins/Logs/util/onMessageDelete.ts | 4 ++-- .../src/plugins/Logs/util/onMessageUpdate.ts | 6 ++--- .../plugins/ModActions/commands/AddCaseCmd.ts | 2 +- .../src/plugins/ModActions/commands/BanCmd.ts | 3 +-- .../ModActions/commands/DeleteCaseCmd.ts | 2 +- .../ModActions/commands/ForcebanCmd.ts | 2 +- .../plugins/ModActions/commands/MassBanCmd.ts | 4 ++-- .../ModActions/commands/MassUnbanCmd.ts | 3 +-- .../ModActions/commands/MassmuteCmd.ts | 3 +-- .../plugins/ModActions/commands/NoteCmd.ts | 3 +-- .../plugins/ModActions/commands/UnbanCmd.ts | 2 +- .../events/CreateBanCaseOnManualBanEvt.ts | 4 ++-- .../events/CreateKickCaseOnManualKickEvt.ts | 2 +- .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 2 +- .../plugins/ModActions/functions/banUserId.ts | 2 +- .../plugins/ModActions/functions/isBanned.ts | 2 +- .../ModActions/functions/kickMember.ts | 11 ++-------- .../functions/outdatedTempbansLoop.ts | 4 ++-- .../ModActions/functions/warnMember.ts | 11 ++-------- .../src/plugins/Mutes/commands/MutesCmd.ts | 2 +- .../events/ReapplyActiveMuteOnJoinEvt.ts | 3 +-- .../Mutes/functions/clearExpiredMutes.ts | 4 ++-- .../src/plugins/Mutes/functions/muteUser.ts | 3 +-- .../src/plugins/Mutes/functions/unmuteUser.ts | 4 ++-- .../src/plugins/Persist/events/LoadDataEvt.ts | 3 +-- .../src/plugins/Post/util/actualPostCmd.ts | 4 ++-- .../plugins/Post/util/scheduledPostLoop.ts | 4 ++-- .../ReactionRoles/ReactionRolesPlugin.ts | 4 ++-- .../commands/PostButtonRolesCmd.ts | 6 ++--- .../events/ButtonInteractionEvt.ts | 6 ++--- backend/src/plugins/ReactionRoles/types.ts | 2 +- .../util/buttonActionHandlers.ts | 2 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 4 ++-- .../plugins/Roles/commands/MassAddRoleCmd.ts | 4 ++-- .../Roles/commands/MassRemoveRoleCmd.ts | 4 ++-- .../plugins/Roles/commands/RemoveRoleCmd.ts | 4 ++-- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 6 ++--- .../util/clearBotSlowmodeFromUserId.ts | 2 +- .../Slowmode/util/clearExpiredSlowmodes.ts | 4 ++-- .../util/disableBotSlowmodeForChannel.ts | 2 +- .../Spam/util/logAndDetectMessageSpam.ts | 14 +++++------- .../Spam/util/logAndDetectOtherSpam.ts | 4 ++-- .../src/plugins/Tags/commands/TagEvalCmd.ts | 3 +-- .../plugins/Tags/util/renderTagFromString.ts | 4 ++-- .../src/plugins/Utility/commands/AboutCmd.ts | 2 +- .../src/plugins/Utility/commands/CleanCmd.ts | 4 ++-- .../Utility/commands/VcdisconnectCmd.ts | 3 +-- .../src/plugins/Utility/commands/VcmoveCmd.ts | 4 ++-- .../events/SendWelcomeMessageEvt.ts | 2 +- backend/src/utils.ts | 6 ++--- 67 files changed, 119 insertions(+), 144 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index 1ec24d2c..ad535f14 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.07017a9.1626869177", + "discord.js": "^13.0.0-dev.4886ae2.1627214570", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -81,8 +81,8 @@ "version": "30.0.0-beta.38", "license": "MIT", "dependencies": { - "discord-api-types": "^0.19.0-next.836e8fb.1625574825", - "discord.js": "^13.0.0-dev.07017a9.1626869177", + "discord-api-types": "^0.21.0-next.ab1951b.1626870574", + "discord.js": "^13.0.0-dev.4886ae2.1627214570", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -2159,9 +2159,9 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.07017a9.1626869177", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.07017a9.1626869177.tgz", - "integrity": "sha512-awnE/59Sy6tnoAZUP7/f8tudcDT68WXxK0pgZZpA7WTGfyR5+IokWsFmkbS49dDll7OZQbi+L8iRt8ahYo3PGQ==", + "version": "13.0.0-dev.4886ae2.1627214570", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.4886ae2.1627214570.tgz", + "integrity": "sha512-9eqVCQyqqSHJcR1nki9NlaTD7FjvfkjJt8zcmF5wcCs/7P9v27UrPYg9yxvghswDvDhz9ojotYGGcpK7tSypmA==", "dependencies": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8034,9 +8034,9 @@ "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" }, "discord.js": { - "version": "13.0.0-dev.07017a9.1626869177", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.07017a9.1626869177.tgz", - "integrity": "sha512-awnE/59Sy6tnoAZUP7/f8tudcDT68WXxK0pgZZpA7WTGfyR5+IokWsFmkbS49dDll7OZQbi+L8iRt8ahYo3PGQ==", + "version": "13.0.0-dev.4886ae2.1627214570", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.4886ae2.1627214570.tgz", + "integrity": "sha512-9eqVCQyqqSHJcR1nki9NlaTD7FjvfkjJt8zcmF5wcCs/7P9v27UrPYg9yxvghswDvDhz9ojotYGGcpK7tSypmA==", "requires": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8877,8 +8877,8 @@ "@typescript-eslint/eslint-plugin": "^4.23.0", "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", - "discord-api-types": "^0.19.0-next.836e8fb.1625574825", - "discord.js": "^13.0.0-dev.07017a9.1626869177", + "discord-api-types": "^0.21.0-next.ab1951b.1626870574", + "discord.js": "^13.0.0-dev.4886ae2.1627214570", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", diff --git a/backend/package.json b/backend/package.json index 7751262b..65ca54f0 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.07017a9.1626869177", + "discord.js": "^13.0.0-dev.4886ae2.1627214570", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/data/entities/ButtonRole.ts b/backend/src/data/entities/ButtonRole.ts index affcce07..3c3f695d 100644 --- a/backend/src/data/entities/ButtonRole.ts +++ b/backend/src/data/entities/ButtonRole.ts @@ -1,4 +1,4 @@ -import { Column, Entity, PrimaryColumn, Unique } from "typeorm"; +import { Column, Entity, PrimaryColumn } from "typeorm"; @Entity("button_roles") export class ButtonRole { diff --git a/backend/src/index.ts b/backend/src/index.ts index 52d555b3..163ba459 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,4 +1,4 @@ -import { Client, Collection, Intents, Options, TextChannel } from "discord.js"; +import { Client, Intents, TextChannel } from "discord.js"; import fs from "fs"; import yaml from "js-yaml"; import { Knub, PluginError } from "knub"; @@ -19,7 +19,7 @@ import { RecoverablePluginError } from "./RecoverablePluginError"; import { SimpleError } from "./SimpleError"; import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; import { startUptimeCounter } from "./uptime"; -import { errorMessage, isDiscordHTTPError, isDiscordAPIError, successMessage } from "./utils"; +import { errorMessage, isDiscordAPIError, isDiscordHTTPError, successMessage } from "./utils"; const fsp = fs.promises; diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts index 0016a793..332994cf 100644 --- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts +++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts @@ -1,7 +1,7 @@ -import { Permissions, Snowflake, TextChannel, User } from "discord.js"; +import { Permissions, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { resolveUser, verboseChannelMention } from "../../../utils"; diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index 1f58f18f..ad682ee9 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -1,6 +1,6 @@ import { MessageOptions, Permissions, Snowflake, TextChannel, User } from "discord.js"; import * as t from "io-ts"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; import { diff --git a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts index a9f086be..c4da61cd 100644 --- a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts @@ -1,6 +1,6 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { runAutomodOnAntiraidLevel } from "../events/runAutomodOnAntiraidLevel"; diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index bec20326..509680e2 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -1,7 +1,7 @@ -import { Snowflake, TextChannel, User } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { deactivateMentions, disableCodeBlocks } from "knub/dist/helpers"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { resolveUser } from "../../../utils"; diff --git a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts index 3d920981..a6aa8c64 100644 --- a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts @@ -1,6 +1,6 @@ -import { channelToConfigAccessibleChannel } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { differenceToString, getScalarDifference } from "../../../utils"; +import { channelToConfigAccessibleChannel } from "../../../utils/configAccessibleObjects"; import { logsEvt } from "../types"; export const LogsChannelCreateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index bdf2cb48..7e8d8eb9 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -1,6 +1,6 @@ import { GuildAuditLogs } from "discord.js"; -import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { logsEvt } from "../types"; diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts index 801229fd..099c3cb3 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts @@ -1,7 +1,7 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; -import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; +import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { logsEvt } from "../types"; diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts index ddae5383..8b18516d 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts @@ -1,5 +1,5 @@ -import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; +import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { logsEvt } from "../types"; export const LogsGuildMemberRemoveEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts index 01d344bb..e9ad1b07 100644 --- a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts @@ -1,6 +1,6 @@ -import { roleToConfigAccessibleRole } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { differenceToString, getScalarDifference } from "../../../utils"; +import { roleToConfigAccessibleRole } from "../../../utils/configAccessibleObjects"; import { logsEvt } from "../types"; export const LogsRoleCreateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts index 207f09fe..b2cb0989 100644 --- a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts @@ -1,6 +1,6 @@ -import { channelToConfigAccessibleChannel, stageToConfigAccessibleStage } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { differenceToString, getScalarDifference, stripObjectToScalars } from "../../../utils"; +import { differenceToString, getScalarDifference } from "../../../utils"; +import { channelToConfigAccessibleChannel, stageToConfigAccessibleStage } from "../../../utils/configAccessibleObjects"; import { logsEvt } from "../types"; export const LogsStageInstanceCreateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts index d6a5312a..f20c15e4 100644 --- a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts @@ -1,6 +1,6 @@ -import { channelToConfigAccessibleChannel } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars, getScalarDifference, differenceToString } from "../../../utils"; +import { differenceToString, getScalarDifference } from "../../../utils"; +import { channelToConfigAccessibleChannel } from "../../../utils/configAccessibleObjects"; import { logsEvt } from "../types"; export const LogsThreadCreateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index aa997913..5b29e3f0 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -1,7 +1,7 @@ import { GuildAuditLogs } from "discord.js"; import diff from "lodash.difference"; import isEqual from "lodash.isequal"; -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { logsEvt } from "../types"; diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index ae19eb53..727fa160 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -1,6 +1,8 @@ -import { channelToConfigAccessibleChannel, memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; +import { + channelToConfigAccessibleChannel, + memberToConfigAccessibleMember, +} from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; import { logsEvt } from "../types"; export const LogsVoiceStateUpdateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index bcb10d14..f1f64893 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -1,7 +1,7 @@ -import { MessageAttachment, Snowflake, User } from "discord.js"; +import { MessageAttachment, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { resolveUser, useMediaUrls } from "../../../utils"; diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index 6867fe62..1d0efd1a 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -1,10 +1,10 @@ -import { MessageEmbed, Snowflake, User } from "discord.js"; +import { MessageEmbed, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import cloneDeep from "lodash.clonedeep"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; -import { resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveUser } from "../../../utils"; import { LogsPluginType } from "../types"; export async function onMessageUpdate( diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts index 794e96ed..c72922d4 100644 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts @@ -1,4 +1,4 @@ -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index 34a18e36..110364b1 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -1,7 +1,6 @@ -import { User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { getMemberLevel } from "knub/dist/helpers"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 0550942f..09fbb8d0 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -1,6 +1,6 @@ import { TextChannel } from "discord.js"; import { helpers } from "knub"; -import { memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index d14b15a4..b7ff84da 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index bc737349..899d8ca3 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -1,14 +1,14 @@ import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; import { performance } from "perf_hooks"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { MINUTES, noop, stripObjectToScalars } from "../../../utils"; +import { MINUTES, noop } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; import { IgnoredEventType, modActionsCmd } from "../types"; diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index 9913ceac..059f85a7 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -1,11 +1,10 @@ import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { stripObjectToScalars } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index bd26f471..9f87ed81 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -1,12 +1,11 @@ import { Snowflake, TextChannel } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { stripObjectToScalars } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { modActionsCmd } from "../types"; diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index 195f10ae..efdb5adc 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -1,5 +1,4 @@ -import { User } from "discord.js"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index 5b4407f1..e425ddee 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index 0638dcf9..57790912 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -1,9 +1,9 @@ import { GuildAuditLogs, User } from "discord.js"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; -import { resolveUser, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { resolveUser, UnknownUser } from "../../../utils"; import { safeFindRelevantAuditLogEntry } from "../../../utils/safeFindRelevantAuditLogEntry"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index 24c89e8d..d69ede2a 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -1,5 +1,5 @@ import { GuildAuditLogs, User } from "discord.js"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index 5e788df5..83143606 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -1,5 +1,5 @@ import { GuildAuditLogs, User } from "discord.js"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index f9b37678..25613f7d 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -1,7 +1,7 @@ import { DiscordAPIError, Snowflake, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index dc476e63..09ec1e2e 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -1,7 +1,7 @@ import { Permissions, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; -import { isDiscordHTTPError, isDiscordAPIError, SECONDS, sleep } from "../../../utils"; +import { isDiscordAPIError, isDiscordHTTPError, SECONDS, sleep } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../types"; diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index 8c7d1563..5aa3d853 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -1,17 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; -import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult, -} from "../../../utils"; +import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types"; import { getDefaultContactMethods } from "./getDefaultContactMethods"; diff --git a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts index bf6f0ab4..fdf957ea 100644 --- a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts +++ b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts @@ -4,9 +4,9 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; -import { resolveUser, SECONDS, stripObjectToScalars } from "../../../utils"; +import { resolveUser, SECONDS } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../types"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index 500ea390..2f2acea1 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,17 +1,10 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { renderTemplate } from "../../../templateFormatter"; -import { - createUserNotificationError, - notifyUser, - resolveUser, - stripObjectToScalars, - ucfirst, - UserNotificationResult, -} from "../../../utils"; +import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { ModActionsPluginType, WarnOptions, WarnResult } from "../types"; diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index fdc89c8b..74e2dc84 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -3,7 +3,7 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { getBaseUrl } from "../../../pluginUtils"; -import { DBDateFormat, isFullMessage, MINUTES, noop, resolveMember } from "../../../utils"; +import { DBDateFormat, MINUTES, resolveMember } from "../../../utils"; import { IMuteWithDetails, mutesCmd } from "../types"; export const MutesCmd = mutesCmd({ diff --git a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts index 134aea79..7d4ece2d 100644 --- a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts +++ b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts @@ -1,7 +1,6 @@ import { Snowflake } from "discord.js"; -import { memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { mutesEvt } from "../types"; diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index 410409f8..7ad36e65 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -1,8 +1,8 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { resolveMember, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { resolveMember, UnknownUser } from "../../../utils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { MutesPluginType } from "../types"; diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 3da34794..78d0e4bd 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -1,7 +1,7 @@ import { Snowflake, TextChannel, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { LogType } from "../../../data/LogType"; @@ -12,7 +12,6 @@ import { notifyUser, resolveMember, resolveUser, - stripObjectToScalars, ucfirst, UserNotificationMethod, UserNotificationResult, diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index 83436188..3011efeb 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -1,10 +1,10 @@ import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; -import { resolveMember, resolveUser, stripObjectToScalars } from "../../../utils"; +import { resolveMember, resolveUser } from "../../../utils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseArgs } from "../../Cases/types"; diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 6948eaa1..75c3871d 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -1,8 +1,7 @@ import { GuildMemberEditData, Permissions } from "discord.js"; import intersection from "lodash.intersection"; -import { memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; -import { stripObjectToScalars } from "../../../utils"; import { canAssignRole } from "../../../utils/canAssignRole"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index 1f9ca18b..88135f38 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -2,10 +2,10 @@ import { Channel, Message, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { DBDateFormat, errorMessage, MINUTES, StrictMessageContent, stripObjectToScalars } from "../../../utils"; +import { DBDateFormat, errorMessage, MINUTES, StrictMessageContent } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { PostPluginType } from "../types"; import { parseScheduleTime } from "./parseScheduleTime"; diff --git a/backend/src/plugins/Post/util/scheduledPostLoop.ts b/backend/src/plugins/Post/util/scheduledPostLoop.ts index 544a57c0..766daed6 100644 --- a/backend/src/plugins/Post/util/scheduledPostLoop.ts +++ b/backend/src/plugins/Post/util/scheduledPostLoop.ts @@ -1,10 +1,10 @@ import { Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { DBDateFormat, SECONDS, stripObjectToScalars } from "../../../utils"; +import { DBDateFormat, SECONDS } from "../../../utils"; import { PostPluginType } from "../types"; import { postMessage } from "./postMessage"; diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 1c841457..d289f6db 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -1,11 +1,11 @@ import { PluginOptions } from "knub"; import { ConfigPreprocessorFn } from "knub/dist/config/configTypes"; import { GuildButtonRoles } from "../../data/GuildButtonRoles"; -import { isValidSnowflake } from "../../utils"; -import { StrictValidationError } from "../../validatorUtils"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; +import { isValidSnowflake } from "../../utils"; +import { StrictValidationError } from "../../validatorUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { ClearReactionRolesCmd } from "./commands/ClearReactionRolesCmd"; diff --git a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts index f54ef9ad..040acf1b 100644 --- a/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/PostButtonRolesCmd.ts @@ -1,9 +1,9 @@ -import { MessageActionRow, MessageButton, Snowflake, TextChannel } from "discord.js"; +import { createHash } from "crypto"; +import { MessageButton, Snowflake } from "discord.js"; +import moment from "moment"; import { sendErrorMessage, sendSuccessMessage } from "src/pluginUtils"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { reactionRolesCmd } from "../types"; -import { createHash } from "crypto"; -import moment from "moment"; import { splitButtonsIntoRows } from "../util/splitButtonsIntoRows"; export const PostButtonRolesCmd = reactionRolesCmd({ diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 2881b27d..704b0b6a 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -1,4 +1,5 @@ import { MessageComponentInteraction } from "discord.js"; +import humanizeDuration from "humanize-duration"; import moment from "moment"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; @@ -6,10 +7,9 @@ import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; import { MINUTES } from "src/utils"; import { idToTimestamp } from "src/utils/idToTimestamp"; import { reactionRolesEvt } from "../types"; -import { resolveStatefulCustomId, BUTTON_CONTEXT_SEPARATOR } from "../util/buttonCustomIdFunctions"; -import { ButtonMenuActions } from "../util/buttonMenuActions"; -import humanizeDuration from "humanize-duration"; import { handleModifyRole, handleOpenMenu } from "../util/buttonActionHandlers"; +import { BUTTON_CONTEXT_SEPARATOR, resolveStatefulCustomId } from "../util/buttonCustomIdFunctions"; +import { ButtonMenuActions } from "../util/buttonMenuActions"; const BUTTON_INVALIDATION_TIME = 15 * MINUTES; diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index 203a4327..27dc5d17 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -1,10 +1,10 @@ import * as t from "io-ts"; import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; import { GuildButtonRoles } from "src/data/GuildButtonRoles"; -import { tNullable } from "../../utils"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Queue } from "../../Queue"; +import { tNullable } from "../../utils"; // These need to be updated every time discord adds/removes a style, // but i cant figure out how to import MessageButtonStyles at runtime diff --git a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts index 10f4e631..314516b6 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts @@ -1,4 +1,4 @@ -import { MessageButton, MessageActionRow, MessageComponentInteraction, Snowflake } from "discord.js"; +import { MessageButton, MessageComponentInteraction, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index b45fe262..66dc2096 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -1,9 +1,9 @@ import { GuildChannel } from "discord.js"; -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; +import { resolveRoleId, verboseUserMention } from "../../../utils"; import { rolesCmd } from "../types"; export const AddRoleCmd = rolesCmd({ diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 1ac58128..5f15a3f0 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils"; +import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; import { rolesCmd } from "../types"; export const MassAddRoleCmd = rolesCmd({ diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index f10fa555..357f8049 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveMember, resolveRoleId, stripObjectToScalars, successMessage } from "../../../utils"; +import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; import { rolesCmd } from "../types"; export const MassRemoveRoleCmd = rolesCmd({ diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index 75d6f9c6..fdab1e23 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -1,9 +1,9 @@ import { GuildChannel } from "discord.js"; -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveRoleId, stripObjectToScalars, verboseUserMention } from "../../../utils"; +import { resolveRoleId, verboseUserMention } from "../../../utils"; import { rolesCmd } from "../types"; export const RemoveRoleCmd = rolesCmd({ diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 6e180a36..208f628a 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -1,9 +1,9 @@ -import { GuildChannel, Permissions, Snowflake, TextChannel } from "discord.js"; +import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { isDiscordAPIError, stripObjectToScalars, UnknownUser } from "../../../utils"; +import { isDiscordAPIError, UnknownUser } from "../../../utils"; import { SlowmodePluginType } from "../types"; export async function applyBotSlowmodeToUserId( diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index 5c59aaf3..b86862ae 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,4 +1,4 @@ -import { GuildChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { SlowmodePluginType } from "../types"; diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index 6c5fe46d..0d22bca8 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -1,9 +1,9 @@ import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; -import { stripObjectToScalars, UnknownUser } from "../../../utils"; +import { UnknownUser } from "../../../utils"; import { SlowmodePluginType } from "../types"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; diff --git a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts index a6b06364..43d6cb55 100644 --- a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts +++ b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts @@ -1,4 +1,4 @@ -import { GuildChannel, TextChannel, ThreadChannel } from "discord.js"; +import { TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { SlowmodePluginType } from "../types"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index e3b67ed1..b5f9bbba 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -1,7 +1,10 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToConfigAccessibleChannel, memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; +import { + channelToConfigAccessibleChannel, + memberToConfigAccessibleMember, +} from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -10,14 +13,7 @@ import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { MuteResult } from "../../../plugins/Mutes/types"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { - convertDelayStringToMS, - DBDateFormat, - noop, - resolveMember, - stripObjectToScalars, - trimLines, -} from "../../../utils"; +import { convertDelayStringToMS, DBDateFormat, noop, resolveMember, trimLines } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types"; import { addRecentAction } from "./addRecentAction"; diff --git a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts index 107cb45e..b9d5fd6d 100644 --- a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts @@ -1,11 +1,11 @@ import { GuildPluginData } from "knub"; -import { memberToConfigAccessibleMember } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember } from "../../../utils/configAccessibleObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { convertDelayStringToMS, resolveMember, stripObjectToScalars } from "../../../utils"; +import { convertDelayStringToMS, resolveMember } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RecentActionType, SpamPluginType } from "../types"; import { addRecentAction } from "./addRecentAction"; diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index abf4a86c..9ce1bf00 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -1,8 +1,7 @@ -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { TemplateParseError } from "../../../templateFormatter"; -import { stripObjectToScalars } from "../../../utils"; import { tagsCmd } from "../types"; import { renderTagBody } from "../util/renderTagBody"; diff --git a/backend/src/plugins/Tags/util/renderTagFromString.ts b/backend/src/plugins/Tags/util/renderTagFromString.ts index 4461f4a4..d54d836e 100644 --- a/backend/src/plugins/Tags/util/renderTagFromString.ts +++ b/backend/src/plugins/Tags/util/renderTagFromString.ts @@ -2,10 +2,10 @@ import { GuildMember } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { parseArguments } from "knub-command-manager"; -import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { memberToConfigAccessibleMember, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { TemplateParseError } from "../../../templateFormatter"; -import { StrictMessageContent, stripObjectToScalars } from "../../../utils"; +import { StrictMessageContent } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { Tag, TagsPluginType } from "../types"; import { renderTagBody } from "./renderTagBody"; diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index dd788816..8c7d4db5 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -4,7 +4,7 @@ import LCL from "last-commit-log"; import moment from "moment-timezone"; import { rootDir } from "../../../paths"; import { getCurrentUptime } from "../../../uptime"; -import { EmbedWith, multiSorter, resolveMember, sorter } from "../../../utils"; +import { multiSorter, resolveMember, sorter } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index cfdaec88..e7778215 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -1,14 +1,14 @@ import { Message, Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "src/utils/configAccessibleObjects"; +import { channelToConfigAccessibleChannel, userToConfigAccessibleUser } from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { allowTimeout } from "../../../RegExpRunner"; -import { DAYS, getInviteCodesInString, noop, SECONDS, stripObjectToScalars } from "../../../utils"; +import { DAYS, getInviteCodesInString, noop, SECONDS } from "../../../utils"; import { utilityCmd, UtilityPluginType } from "../types"; const MAX_CLEAN_COUNT = 150; diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index 169da88e..8c20adc4 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -3,11 +3,10 @@ import { channelToConfigAccessibleChannel, memberToConfigAccessibleMember, userToConfigAccessibleUser, -} from "src/utils/configAccessibleObjects"; +} from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { stripObjectToScalars } from "../../../utils"; import { utilityCmd } from "../types"; export const VcdisconnectCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 76eb2161..adb56d96 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -3,11 +3,11 @@ import { channelToConfigAccessibleChannel, memberToConfigAccessibleMember, userToConfigAccessibleUser, -} from "src/utils/configAccessibleObjects"; +} from "../../../utils/configAccessibleObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { channelMentionRegex, isSnowflake, simpleClosestStringMatch, stripObjectToScalars } from "../../../utils"; +import { channelMentionRegex, isSnowflake, simpleClosestStringMatch } from "../../../utils"; import { utilityCmd } from "../types"; export const VcmoveCmd = utilityCmd({ diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index ce1bf066..852c3650 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -3,7 +3,7 @@ import { channelToConfigAccessibleChannel, memberToConfigAccessibleMember, userToConfigAccessibleUser, -} from "src/utils/configAccessibleObjects"; +} from "../../../utils/configAccessibleObjects"; import { LogType } from "../../../data/LogType"; import { renderTemplate, TemplateParseError } from "../../../templateFormatter"; import { createChunkedMessage, stripObjectToScalars } from "../../../utils"; diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 5a22c12d..c4464f97 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -28,19 +28,19 @@ import { either } from "fp-ts/lib/Either"; import { unsafeCoerce } from "fp-ts/lib/function"; import fs from "fs"; import https from "https"; +import humanizeDuration from "humanize-duration"; import * as t from "io-ts"; +import { isEqual } from "lodash"; import moment from "moment-timezone"; import tlds from "tlds"; import tmp from "tmp"; import { URL } from "url"; import { SavedMessage } from "./data/entities/SavedMessage"; import { SimpleCache } from "./SimpleCache"; +import { ChannelTypeStrings } from "./types"; import { sendDM } from "./utils/sendDM"; import { waitForButtonConfirm } from "./utils/waitForInteraction"; import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils"; -import { isEqual } from "lodash"; -import humanizeDuration from "humanize-duration"; -import { ChannelTypeStrings } from "./types"; const fsp = fs.promises; From bc1330bf332f664dc59401be4d3b6e23866f35e4 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Tue, 27 Jul 2021 04:19:11 +0200 Subject: [PATCH 36/79] Various bugfixes and change ct.anyId return to Snowflake --- backend/src/commandTypes.ts | 12 ++++++------ .../plugins/BotControl/commands/ReloadServerCmd.ts | 2 +- .../functions/reloadChangedGuilds.ts | 3 ++- .../src/plugins/LocateUser/events/SendAlertsEvts.ts | 7 ++++--- .../plugins/LocateUser/utils/createOrReuseInvite.ts | 2 +- .../ReactionRoles/events/ButtonInteractionEvt.ts | 4 ++++ .../ReactionRoles/util/buttonCustomIdFunctions.ts | 2 +- 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index 04ca71fa..29a69d11 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -1,4 +1,4 @@ -import { GuildChannel, GuildMember, User } from "discord.js"; +import { GuildChannel, GuildMember, Snowflake, User } from "discord.js"; import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub"; import { createTypeHelper } from "knub-command-manager"; import { @@ -72,16 +72,16 @@ export const commandTypes = { async anyId(value: string, context: CommandContext) { const userId = resolveUserId(context.pluginData.client, value); - if (userId) return userId; + if (userId) return userId as Snowflake; const channelIdMatch = value.match(channelMentionRegex); - if (channelIdMatch) return channelIdMatch[1]; + if (channelIdMatch) return channelIdMatch[1] as Snowflake; const roleIdMatch = value.match(roleMentionRegex); - if (roleIdMatch) return roleIdMatch[1]; + if (roleIdMatch) return roleIdMatch[1] as Snowflake; if (isValidSnowflake(value)) { - return value; + return value as Snowflake; } throw new TypeConversionError(`Could not parse ID: \`${disableInlineCode(value)}\``); @@ -112,7 +112,7 @@ export const commandTypeHelpers = { resolvedUserLoose: createTypeHelper>(commandTypes.resolvedUserLoose), resolvedMember: createTypeHelper>(commandTypes.resolvedMember), messageTarget: createTypeHelper>(commandTypes.messageTarget), - anyId: createTypeHelper>(commandTypes.anyId), + anyId: createTypeHelper>(commandTypes.anyId), regex: createTypeHelper(commandTypes.regex), timezone: createTypeHelper(commandTypes.timezone), }; diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index fb652b65..88193fba 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -11,7 +11,7 @@ export const ReloadServerCmd = botControlCmd({ }, signature: { - guildId: ct.string(), + guildId: ct.anyId(), }, async run({ pluginData, message: msg, args }) { diff --git a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts index 65571b46..bc7eb6e9 100644 --- a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts +++ b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts @@ -1,3 +1,4 @@ +import { Snowflake } from "discord.js"; import { GlobalPluginData } from "knub"; import { SECONDS } from "../../../utils"; import { GuildConfigReloaderPluginType } from "../types"; @@ -11,7 +12,7 @@ export async function reloadChangedGuilds(pluginData: GlobalPluginData { const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel; - txtChannel.send( - `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`<#!${voiceChannel.id}>\``, - ); + txtChannel.send({ + content: `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`${voiceChannel.name}\``, + allowedMentions: { users: [alert.requestor_id as Snowflake] }, + }); }); } }, diff --git a/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts b/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts index 2853c7f0..3ac5dd1d 100644 --- a/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts +++ b/backend/src/plugins/LocateUser/utils/createOrReuseInvite.ts @@ -4,7 +4,7 @@ export async function createOrReuseInvite(vc: VoiceChannel) { const existingInvites = await vc.fetchInvites(); if (existingInvites.size !== 0) { - return existingInvites[0]; + return existingInvites.first()!; } else { return vc.createInvite(); } diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 704b0b6a..7f366140 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -32,6 +32,10 @@ export const ButtonInteractionEvt = reactionRolesEvt({ }; if (context.stateless) { + if (context.roleOrMenu == null) { + // Not reaction from this plugin + return; + } const timeSinceCreation = moment.utc().valueOf() - idToTimestamp(int.message.id)!; if (timeSinceCreation >= BUTTON_INVALIDATION_TIME) { sendEphemeralReply( diff --git a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts index ce1a9c3b..fa3644da 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonCustomIdFunctions.ts @@ -3,7 +3,7 @@ import { GuildPluginData } from "knub"; import { ReactionRolesPluginType } from "../types"; import { ButtonMenuActions } from "./buttonMenuActions"; -export const BUTTON_CONTEXT_SEPARATOR = "::"; +export const BUTTON_CONTEXT_SEPARATOR = ":rb:"; export async function getButtonAction(pluginData: GuildPluginData, roleOrMenu: string) { if (await pluginData.guild.roles.fetch(roleOrMenu as Snowflake).catch(() => false)) { From 12d2724256c9135acc0804852097e6c4ce9737f4 Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 16:08:36 +0100 Subject: [PATCH 37/79] fix: updated some properties that were renamed on the discord.js side --- backend/src/data/DefaultLogMessages.json | 4 ++-- backend/src/plugins/Logs/util/log.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/data/DefaultLogMessages.json b/backend/src/data/DefaultLogMessages.json index fccdb1ed..af22228f 100644 --- a/backend/src/data/DefaultLogMessages.json +++ b/backend/src/data/DefaultLogMessages.json @@ -26,8 +26,8 @@ "CHANNEL_DELETE": "🗑 Channel {channelMention(channel)} was deleted", "CHANNEL_UPDATE": "✏ Channel {channelMention(newChannel)} was edited. Changes:\n{differenceString}", - "THREAD_CREATE": "🖊 Thread {channelMention(thread)} was created in channel <#{thread.parentID}>", - "THREAD_DELETE": "🗑 Thread {channelMention(thread)} was deleted/archived from channel <#{thread.parentID}>", + "THREAD_CREATE": "🖊 Thread {channelMention(thread)} was created in channel <#{thread.parentId}>", + "THREAD_DELETE": "🗑 Thread {channelMention(thread)} was deleted/archived from channel <#{thread.parentId}>", "THREAD_UPDATE": "✏ Thread {channelMention(newThread)} was edited. Changes:\n{differenceString}", "ROLE_CREATE": "🖊 Role **{role.name}** (`{role.id}`) was created", diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 0fdce60e..b8e6eed0 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -94,7 +94,7 @@ export async function log(pluginData: GuildPluginData, type: Log type === LogType.CENSOR || type === LogType.CLEAN ) { - if (data.channel.parentID && opts.excluded_categories.includes(data.channel.parentID)) { + if (data.channel.parentId && opts.excluded_categories.includes(data.channel.parentId)) { continue logChannelLoop; } } From 77b33c18584b444edbb8c7d4edc682b8d75320a0 Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 16:43:31 +0100 Subject: [PATCH 38/79] renamed ErisError to DiscordJSError, use rateLimit event instead of debug, renamed the TOKEN variable back --- backend/src/{ErisError.ts => DiscordJSError.ts} | 4 ++-- backend/src/index.ts | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) rename backend/src/{ErisError.ts => DiscordJSError.ts} (65%) diff --git a/backend/src/ErisError.ts b/backend/src/DiscordJSError.ts similarity index 65% rename from backend/src/ErisError.ts rename to backend/src/DiscordJSError.ts index 732fa53b..26a3b8ed 100644 --- a/backend/src/ErisError.ts +++ b/backend/src/DiscordJSError.ts @@ -1,6 +1,6 @@ import util from "util"; -export class ErisError extends Error { +export class DiscordJSError extends Error { code: number | string | undefined; shardId: number; @@ -11,6 +11,6 @@ export class ErisError extends Error { } [util.inspect.custom]() { - return `[ERIS] [ERROR CODE ${this.code || "?"}] [SHARD ${this.shardId}] ${this.message}`; + return `[DISCORDJS] [ERROR CODE ${this.code ?? "?"}] [SHARD ${this.shardId}] ${this.message}`; } } diff --git a/backend/src/index.ts b/backend/src/index.ts index 163ba459..70bf4d2e 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,5 +1,4 @@ import { Client, Intents, TextChannel } from "discord.js"; -import fs from "fs"; import yaml from "js-yaml"; import { Knub, PluginError } from "knub"; import { PluginLoadError } from "knub/dist/plugins/PluginLoadError"; @@ -11,7 +10,7 @@ import { Configs } from "./data/Configs"; import { connect } from "./data/db"; import { GuildLogs } from "./data/GuildLogs"; import { LogType } from "./data/LogType"; -import { ErisError } from "./ErisError"; +import { DiscordJSError } from "./DiscordJSError"; import "./loadEnv"; import { logger } from "./logger"; import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availablePlugins"; @@ -21,8 +20,6 @@ import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; import { startUptimeCounter } from "./uptime"; import { errorMessage, isDiscordAPIError, isDiscordHTTPError, successMessage } from "./utils"; -const fsp = fs.promises; - if (!process.env.KEY) { // tslint:disable-next-line:no-console console.error("Project root .env with KEY is required!"); @@ -81,7 +78,7 @@ function errorHandler(err) { return; } - if (err instanceof ErisError) { + if (err instanceof DiscordJSError) { if (err.code && SAFE_TO_IGNORE_ERIS_ERROR_CODES.includes(err.code)) { return; } @@ -176,14 +173,12 @@ connect().then(async () => { }); client.setMaxListeners(200); - client.on("debug", message => { - if (message.includes(" 429 ")) { - logger.info(`[429] ${message}`); - } + client.on("rateLimit", rateLimitData => { + logger.info(`[429] ${rateLimitData}`); }); client.on("error", err => { - errorHandler(new ErisError(err.message, (err as any).code, 0)); + errorHandler(new DiscordJSError(err.message, (err as any).code, 0)); }); const allowedGuilds = new AllowedGuilds(); @@ -266,5 +261,5 @@ connect().then(async () => { bot.initialize(); logger.info("Bot Initialized"); logger.info("Logging in..."); - await client.login(process.env.token); + await client.login(process.env.TOKEN); }); From 88f53b4af9a39bed956ef0895368dda6b951631e Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 22:29:52 +0100 Subject: [PATCH 39/79] removed unnecessary non-null operator --- backend/src/plugins/Automod/events/runAutomodOnMessage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts index 34d14a74..7181b257 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts @@ -12,7 +12,7 @@ export function runAutomodOnMessage( message: SavedMessage, isEdit: boolean, ) { - const user = pluginData.client.users.cache!.get(message.user_id as Snowflake); + const user = pluginData.client.users.cache.get(message.user_id as Snowflake); const member = pluginData.guild.members.cache.get(message.user_id as Snowflake); const context: AutomodContext = { From 4047b7f921e4a9d244daf227c5ca20bbdc8292bf Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 23:15:40 +0100 Subject: [PATCH 40/79] removed unnecessary assertion --- .../src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 84e26317..c1b3a871 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -60,10 +60,10 @@ export const ArchiveChannelCmd = channelArchiverCmd({ while (archivedMessages < maxMessagesToArchive) { const messagesToFetch = Math.min(MAX_MESSAGES_PER_FETCH, maxMessagesToArchive - archivedMessages); - const messages = (await args.channel.messages.fetch({ + const messages = await args.channel.messages.fetch({ limit: messagesToFetch, before: previousId as Snowflake, - })) as Collection; + }); if (messages.size === 0) break; for (const message of messages.values()) { From 60caa3153b7d10f4f0f5aea050c1119458b723e4 Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 23:27:07 +0100 Subject: [PATCH 41/79] simplified ternary --- backend/src/plugins/Logs/events/LogsGuildBanEvts.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index 7e8d8eb9..580ce85e 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -16,7 +16,7 @@ export const LogsGuildBanAddEvt = logsEvt({ GuildAuditLogs.Actions.MEMBER_BAN_ADD as number, user.id, ); - const mod = relevantAuditLogEntry ? relevantAuditLogEntry.executor : null; + const mod = relevantAuditLogEntry?.executor ?? null; pluginData.state.guildLogs.log( LogType.MEMBER_BAN, @@ -41,7 +41,7 @@ export const LogsGuildBanRemoveEvt = logsEvt({ GuildAuditLogs.Actions.MEMBER_BAN_REMOVE as number, user.id, ); - const mod = relevantAuditLogEntry ? relevantAuditLogEntry.executor : null; + const mod = relevantAuditLogEntry?.executor ?? null; pluginData.state.guildLogs.log( LogType.MEMBER_UNBAN, From b4ba1daa762256e879f86aefa827e67e61f03df9 Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 23:30:52 +0100 Subject: [PATCH 42/79] simplify --- backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts | 10 +++++----- .../ModActions/events/CreateBanCaseOnManualBanEvt.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index 5b29e3f0..1f37a360 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -52,7 +52,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ GuildAuditLogs.Actions.MEMBER_ROLE_UPDATE as number, member.id, ); - const mod = relevantAuditLogEntry ? relevantAuditLogEntry.executor : null; + const mod = relevantAuditLogEntry?.executor ?? null; if (addedRoles.length && removedRoles.length) { // Roles added *and* removed @@ -61,11 +61,11 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ { member: logMember, addedRoles: addedRoles - .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), removedRoles: removedRoles - .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), mod: mod ? userToConfigAccessibleUser(mod) : {}, @@ -79,7 +79,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ { member: logMember, roles: addedRoles - .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), mod: mod ? userToConfigAccessibleUser(mod) : {}, @@ -93,7 +93,7 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ { member: logMember, roles: removedRoles - .map(roleId => pluginData.guild.roles.cache.get(roleId) || { id: roleId, name: `Unknown (${roleId})` }) + .map(roleId => pluginData.guild.roles.cache.get(roleId) ?? { id: roleId, name: `Unknown (${roleId})` }) .map(r => r.name) .join(", "), mod: mod ? userToConfigAccessibleUser(mod) : {}, diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index 57790912..875f8cd7 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -44,7 +44,7 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt({ const config = mod instanceof UnknownUser ? pluginData.config.get() : await pluginData.config.getForUser(mod); if (config.create_cases_for_manual_actions) { - reason = relevantAuditLogEntry.reason || ""; + reason = relevantAuditLogEntry.reason ?? ""; createdCase = await casesPlugin.createCase({ userId: user.id, modId, From f9e134300301f670b2a5bad3d468333130bfbe4a Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 23:40:20 +0100 Subject: [PATCH 43/79] use User#displayAvatarURL and dont encode reason --- backend/src/plugins/ModActions/commands/CasesModCmd.ts | 2 +- backend/src/plugins/ModActions/commands/CasesUserCmd.ts | 2 +- backend/src/plugins/ModActions/commands/ForcebanCmd.ts | 2 +- backend/src/plugins/ModActions/commands/UnbanCmd.ts | 2 +- backend/src/plugins/ModActions/functions/banUserId.ts | 2 +- backend/src/plugins/ModActions/functions/kickMember.ts | 2 +- .../src/plugins/ModActions/functions/outdatedTempbansLoop.ts | 5 +---- backend/src/plugins/Utility/commands/AvatarCmd.ts | 2 +- backend/src/plugins/Utility/functions/getUserInfoEmbed.ts | 2 +- 9 files changed, 9 insertions(+), 12 deletions(-) diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 6b06c56c..9569e859 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -57,7 +57,7 @@ export const CasesModCmd = modActionsCmd({ const embed: MessageEmbedOptions = { author: { name: title, - iconURL: mod instanceof User ? mod.avatarURL() || mod.defaultAvatarURL : undefined, + iconURL: mod instanceof User ? mod.displayAvatarURL() : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index ac1d2eb5..f551369f 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -119,7 +119,7 @@ export const CasesUserCmd = modActionsCmd({ lineChunks.length === 1 ? `Cases for ${userName} (${lines.length} total)` : `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`, - icon_url: user instanceof User ? user.avatarURL() || user.defaultAvatarURL : undefined, + icon_url: user instanceof User ? user.displayAvatarURL() : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")), diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index b7ff84da..67df9ece 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -70,7 +70,7 @@ export const ForcebanCmd = modActionsCmd({ // FIXME: Use banUserId()? await pluginData.guild.bans.create(user.id as Snowflake, { days: 1, - reason: reason != null ? encodeURIComponent(reason) : undefined, + reason: reason ?? undefined, }); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to forceban member"); diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index e425ddee..38bb49f0 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -51,7 +51,7 @@ export const UnbanCmd = modActionsCmd({ try { ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); - await pluginData.guild.bans.remove(user.id as Snowflake, reason != null ? encodeURIComponent(reason) : undefined); + await pluginData.guild.bans.remove(user.id as Snowflake, reason ?? undefined); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to unban member; are you sure they're banned?"); return; diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index 25613f7d..3462842d 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -80,7 +80,7 @@ export async function banUserId( const deleteMessageDays = Math.min(30, Math.max(0, banOptions.deleteMessageDays ?? 1)); await pluginData.guild.bans.create(userId as Snowflake, { days: deleteMessageDays, - reason: reason != null ? encodeURIComponent(reason) : undefined, + reason: reason ?? undefined, }); } catch (e) { let errorMessage; diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index 5aa3d853..3ffcab6b 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -49,7 +49,7 @@ export async function kickMember( pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_KICK, member.id); ignoreEvent(pluginData, IgnoredEventType.Kick, member.id); try { - await member.kick(reason != null ? encodeURIComponent(reason) : undefined); + await member.kick(reason ?? undefined); } catch (e) { return { status: "failed", diff --git a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts index fdf957ea..935e16a4 100644 --- a/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts +++ b/backend/src/plugins/ModActions/functions/outdatedTempbansLoop.ts @@ -32,10 +32,7 @@ export async function outdatedTempbansLoop(pluginData: GuildPluginData Date: Wed, 28 Jul 2021 23:50:25 +0100 Subject: [PATCH 44/79] removed unnecessary encodeURIComponent on reasons --- backend/src/plugins/ModActions/commands/MassBanCmd.ts | 2 +- backend/src/plugins/ModActions/commands/MassUnbanCmd.ts | 5 +---- .../src/plugins/ModActions/functions/actualKickMemberCmd.ts | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 899d8ca3..7e61bb48 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -95,7 +95,7 @@ export const MassbanCmd = modActionsCmd({ await pluginData.guild.bans.create(userId as Snowflake, { days: deleteDays, - reason: banReason != null ? encodeURIComponent(banReason) : undefined, + reason: banReason ?? undefined, }); await casesPlugin.createCase({ diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index 059f85a7..1141c26c 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -60,10 +60,7 @@ export const MassunbanCmd = modActionsCmd({ } try { - await pluginData.guild.bans.remove( - userId as Snowflake, - unbanReason != null ? encodeURIComponent(unbanReason) : undefined, - ); + await pluginData.guild.bans.remove(userId as Snowflake, unbanReason ?? undefined); await casesPlugin.createCase({ userId, diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index a957696c..0ed86ded 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -82,7 +82,7 @@ export async function actualKickMemberCmd( ignoreEvent(pluginData, IgnoredEventType.Ban, memberToKick.id); try { - await memberToKick.ban({ days: 1, reason: encodeURIComponent("kick -clean") }); + await memberToKick.ban({ days: 1, reason: "kick -clean" }); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to ban the user to clean messages (-clean)"); } @@ -91,7 +91,7 @@ export async function actualKickMemberCmd( ignoreEvent(pluginData, IgnoredEventType.Unban, memberToKick.id); try { - await pluginData.guild.bans.remove(memberToKick.id, encodeURIComponent("kick -clean")); + await pluginData.guild.bans.remove(memberToKick.id, "kick -clean"); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to unban the user after banning them (-clean)"); } From d9d1793e5907cba16e2153ebec0d515dce16f0a2 Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 23:54:34 +0100 Subject: [PATCH 45/79] removed unnecessary type annotation --- backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 77fc0f85..ad5b9666 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -12,7 +12,7 @@ export const ClearBannedMutesCmd = mutesCmd({ const activeMutes = await pluginData.state.mutes.getActiveMutes(); - const bans: Array<{ reason: string; user: User }> = (await pluginData.guild.bans.fetch({ cache: true })) as any; + const bans = await pluginData.guild.bans.fetch({ cache: true }); const bannedIds = bans.map(b => b.user.id); await msg.channel.send(`Found ${activeMutes.length} mutes and ${bannedIds.length} bans, cross-referencing...`); From 9ddfc48bb2fb98d5586fdef3bb777aa0612267d6 Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 28 Jul 2021 23:57:29 +0100 Subject: [PATCH 46/79] simplify --- backend/src/plugins/Mutes/commands/MutesCmd.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 74e2dc84..27b33523 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -225,14 +225,11 @@ export const MutesCmd = mutesCmd({ interaction.reply({ content: `You are not permitted to use these buttons.`, ephemeral: true }); } else { collector.resetTimer(); + await interaction.deferUpdate(); if (interaction.customId === `previousButton:${idMod}` && currentPage > 1) { - await interaction.deferUpdate(); await drawListPage(currentPage - 1); } else if (interaction.customId === `nextButton:${idMod}` && currentPage < totalPages) { - await interaction.deferUpdate(); await drawListPage(currentPage + 1); - } else { - await interaction.deferUpdate(); } } }); From 3886d2d1dd33b09f19f46cf3f86cc740505333da Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 29 Jul 2021 01:02:29 +0200 Subject: [PATCH 47/79] Include Sticker and Emoji events in Logs --- backend/src/data/DefaultLogMessages.json | 8 ++ backend/src/data/LogType.ts | 8 ++ backend/src/plugins/Logs/LogsPlugin.ts | 14 ++++ .../Logs/events/LogsStickerEmojiModifyEvts.ts | 82 +++++++++++++++++++ backend/src/utils.ts | 2 +- backend/src/utils/configAccessibleObjects.ts | 50 +++++++++++ presetup-configurator/src/LogChannels.tsx | 6 ++ 7 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 backend/src/plugins/Logs/events/LogsStickerEmojiModifyEvts.ts diff --git a/backend/src/data/DefaultLogMessages.json b/backend/src/data/DefaultLogMessages.json index af22228f..c666ff43 100644 --- a/backend/src/data/DefaultLogMessages.json +++ b/backend/src/data/DefaultLogMessages.json @@ -50,6 +50,14 @@ "STAGE_INSTANCE_DELETE": "📣 Stage Instance `{stageInstance.topic}` was deleted in Stage Channel <#{stageChannel.id}>", "STAGE_INSTANCE_UPDATE": "📣 Stage Instance `{newStageInstance.topic}` was edited in Stage Channel <#{stageChannel.id}>. Changes:\n{differenceString}", + "EMOJI_CREATE": "<{emoji.identifier}> Emoji `{emoji.name} ({emoji.id})` was created", + "EMOJI_DELETE": "👋 Emoji `{emoji.name} ({emoji.id})` was deleted", + "EMOJI_UPDATE": "<{newEmoji.identifier}> Emoji `{newEmoji.name} ({newEmoji.id})` was updated. Changes:\n{differenceString}", + + "STICKER_CREATE": "🖼️ Sticker `{sticker.name} ({sticker.id})` was created. Description: `{sticker.description}` Format: {emoji.format}", + "STICKER_DELETE": "🖼️ Sticker `{sticker.name} ({sticker.id})` was deleted.", + "STICKER_UPDATE": "🖼️ Sticker `{newSticker.name} ({sticker.id})` was updated. Changes:\n{differenceString}", + "COMMAND": "🤖 {userMention(member)} used command in {channelMention(channel)}:\n`{command}`", "MESSAGE_SPAM_DETECTED": "🛑 {userMention(member)} spam detected in {channelMention(channel)}: {description} (more than {limit} in {interval}s)\n{archiveUrl}", diff --git a/backend/src/data/LogType.ts b/backend/src/data/LogType.ts index eb6e66e5..90c81173 100644 --- a/backend/src/data/LogType.ts +++ b/backend/src/data/LogType.ts @@ -41,6 +41,14 @@ export enum LogType { STAGE_INSTANCE_DELETE, STAGE_INSTANCE_UPDATE, + EMOJI_CREATE, + EMOJI_DELETE, + EMOJI_UPDATE, + + STICKER_CREATE, + STICKER_DELETE, + STICKER_UPDATE, + COMMAND, MESSAGE_SPAM_DETECTED, diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 64c62444..3f65e9bc 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -20,6 +20,14 @@ import { LogsStageInstanceDeleteEvt, LogsStageInstanceUpdateEvt, } from "./events/LogsStageInstanceModifyEvts"; +import { + LogsEmojiCreateEvt, + LogsEmojiDeleteEvt, + LogsEmojiUpdateEvt, + LogsStickerCreateEvt, + LogsStickerDeleteEvt, + LogsStickerUpdateEvt, +} from "./events/LogsStickerEmojiModifyEvts"; import { LogsThreadCreateEvt, LogsThreadDeleteEvt, LogsThreadUpdateEvt } from "./events/LogsThreadModifyEvts"; import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts"; import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts"; @@ -81,6 +89,12 @@ export const LogsPlugin = zeppelinGuildPlugin()({ LogsThreadCreateEvt, LogsThreadDeleteEvt, LogsThreadUpdateEvt, + LogsEmojiCreateEvt, + LogsEmojiDeleteEvt, + LogsEmojiUpdateEvt, + LogsStickerCreateEvt, + LogsStickerDeleteEvt, + LogsStickerUpdateEvt, ], public: { diff --git a/backend/src/plugins/Logs/events/LogsStickerEmojiModifyEvts.ts b/backend/src/plugins/Logs/events/LogsStickerEmojiModifyEvts.ts new file mode 100644 index 00000000..3535174c --- /dev/null +++ b/backend/src/plugins/Logs/events/LogsStickerEmojiModifyEvts.ts @@ -0,0 +1,82 @@ +import { LogType } from "../../../data/LogType"; +import { differenceToString, getScalarDifference } from "../../../utils"; +import { + channelToConfigAccessibleChannel, + emojiToConfigAccessibleEmoji, + stickerToConfigAccessibleSticker, +} from "../../../utils/configAccessibleObjects"; +import { logsEvt } from "../types"; + +export const LogsEmojiCreateEvt = logsEvt({ + event: "emojiCreate", + + async listener(meta) { + meta.pluginData.state.guildLogs.log(LogType.EMOJI_CREATE, { + emoji: emojiToConfigAccessibleEmoji(meta.args.emoji), + }); + }, +}); + +export const LogsEmojiDeleteEvt = logsEvt({ + event: "emojiDelete", + + async listener(meta) { + meta.pluginData.state.guildLogs.log(LogType.EMOJI_DELETE, { + emoji: emojiToConfigAccessibleEmoji(meta.args.emoji), + }); + }, +}); + +export const LogsEmojiUpdateEvt = logsEvt({ + event: "emojiUpdate", + + async listener(meta) { + const diff = getScalarDifference(meta.args.oldEmoji, meta.args.newEmoji); + const differenceString = differenceToString(diff); + + meta.pluginData.state.guildLogs.log(LogType.EMOJI_UPDATE, { + oldEmoji: emojiToConfigAccessibleEmoji(meta.args.oldEmoji), + newEmoji: emojiToConfigAccessibleEmoji(meta.args.newEmoji), + differenceString, + }); + }, +}); + +export const LogsStickerCreateEvt = logsEvt({ + event: "stickerCreate", + + async listener(meta) { + meta.pluginData.state.guildLogs.log(LogType.STICKER_CREATE, { + thread: stickerToConfigAccessibleSticker(meta.args.sticker), + }); + }, +}); + +export const LogsStickerDeleteEvt = logsEvt({ + event: "stickerDelete", + + async listener(meta) { + meta.pluginData.state.guildLogs.log(LogType.STICKER_DELETE, { + thread: stickerToConfigAccessibleSticker(meta.args.sticker), + }); + }, +}); + +export const LogsStickerUpdateEvt = logsEvt({ + event: "stickerUpdate", + + async listener(meta) { + const diff = getScalarDifference(meta.args.oldSticker, meta.args.newSticker); + const differenceString = differenceToString(diff); + + meta.pluginData.state.guildLogs.log( + LogType.STICKER_UPDATE, + { + oldThread: stickerToConfigAccessibleSticker(meta.args.oldSticker), + newThread: stickerToConfigAccessibleSticker(meta.args.newSticker), + differenceString, + }, + meta.args.newSticker.id, + ); + }, +}); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index c4464f97..a1e10430 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -212,7 +212,7 @@ export function differenceToString(diff: Map): st let toReturn = ""; diff = prettyDifference(diff); for (const [key, difference] of diff) { - toReturn += `${key[0].toUpperCase() + key.slice(1)}: \`${difference.was}\` ➜ \`${difference.is}\`\n`; + toReturn += `**${key[0].toUpperCase() + key.slice(1)}**: \`${difference.was}\` ➜ \`${difference.is}\`\n`; } return toReturn; } diff --git a/backend/src/utils/configAccessibleObjects.ts b/backend/src/utils/configAccessibleObjects.ts index 1c281ed6..e28c61a5 100644 --- a/backend/src/utils/configAccessibleObjects.ts +++ b/backend/src/utils/configAccessibleObjects.ts @@ -1,10 +1,12 @@ import { + Emoji, GuildChannel, GuildMember, PartialGuildMember, Role, Snowflake, StageInstance, + Sticker, ThreadChannel, User, } from "discord.js"; @@ -127,3 +129,51 @@ export function stageToConfigAccessibleStage(stage: StageInstance): IConfigAcces return toReturn; } + +export interface IConfigAccessibleEmoji { + id: Snowflake; + name: string; + createdAt?: number; + animated: boolean; + identifier: string; +} + +export function emojiToConfigAccessibleEmoji(emoji: Emoji): IConfigAccessibleEmoji { + const toReturn: IConfigAccessibleEmoji = { + id: emoji.id!, + name: emoji.name!, + createdAt: emoji.createdTimestamp ?? undefined, + animated: emoji.animated ?? false, + identifier: emoji.identifier, + }; + + return toReturn; +} + +export interface IConfigAccessibleSticker { + id: Snowflake; + guildId?: Snowflake; + packId?: Snowflake; + name: string; + description: string; + tags: string; + format: string; + animated: boolean; + url: string; +} + +export function stickerToConfigAccessibleSticker(sticker: Sticker): IConfigAccessibleSticker { + const toReturn: IConfigAccessibleSticker = { + id: sticker.id, + guildId: sticker.guildId ?? undefined, + packId: sticker.packId ?? undefined, + name: sticker.name, + description: sticker.description ?? "", + tags: sticker.tags?.join(", ") ?? "", + format: sticker.format, + animated: sticker.format === "PNG" ? false : true, + url: sticker.url, + }; + + return toReturn; +} diff --git a/presetup-configurator/src/LogChannels.tsx b/presetup-configurator/src/LogChannels.tsx index 928d4c99..85300d37 100644 --- a/presetup-configurator/src/LogChannels.tsx +++ b/presetup-configurator/src/LogChannels.tsx @@ -37,6 +37,12 @@ const LOG_TYPES = { "STAGE_INSTANCE_CREATE": "Stage created", "STAGE_INSTANCE_DELETE": "Stage deleted", "STAGE_INSTANCE_UPDATE": "Stage updated", + "EMOJI_CREATE": "Emoji created", + "EMOJI_DELETE": "Emoji deleted", + "EMOJI_UPDATE": "Emoji updated", + "STICKER_CREATE": "Sticker created", + "STICKER_DELETE": "Sticker deleted", + "STICKER_UPDATE": "Sticker updated", "COMMAND": "Command used", "MESSAGE_SPAM_DETECTED": "Message spam detected", "CENSOR": "Message censored", From 3d29963b871eb4081bf8202d45b8395ff253cda1 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 00:03:25 +0100 Subject: [PATCH 48/79] perf --- backend/src/plugins/Mutes/functions/muteUser.ts | 2 +- backend/src/plugins/NameHistory/events/UpdateNameEvts.ts | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 78d0e4bd..cbfa3870 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -90,7 +90,7 @@ export async function muteUser( try { await member.roles.add(muteRole as Snowflake); } catch (e) { - const actualMuteRole = pluginData.guild.roles.cache.find(x => x.id === muteRole); + const actualMuteRole = pluginData.guild.roles.cache.get(muteRole as Snowflake); if (!actualMuteRole) { lock.unlock(); logs.log(LogType.BOT_ALERT, { diff --git a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts index c41e2cc9..0d644663 100644 --- a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts +++ b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts @@ -6,10 +6,7 @@ export const ChannelJoinEvt = nameHistoryEvt({ async listener(meta) { meta.pluginData.state.updateQueue.add(() => - updateNickname( - meta.pluginData, - meta.args.newState.member ? meta.args.newState.member : meta.args.oldState.member!, - ), + updateNickname(meta.pluginData, meta.args.newState.member ?? meta.args.oldState.member!), ); }, }); From e5985e8776b5b6e155ca8bd1d2b71cd1b8a2907a Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 29 Jul 2021 01:14:21 +0200 Subject: [PATCH 49/79] Allow =0 condition in counter triggers --- backend/src/data/entities/CounterTrigger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/data/entities/CounterTrigger.ts b/backend/src/data/entities/CounterTrigger.ts index 71b6bf52..91cbf995 100644 --- a/backend/src/data/entities/CounterTrigger.ts +++ b/backend/src/data/entities/CounterTrigger.ts @@ -17,7 +17,7 @@ export function getReverseCounterComparisonOp(op: TriggerComparisonOp): TriggerC return REVERSE_OPS[op]; } -const comparisonStringRegex = new RegExp(`^(${TRIGGER_COMPARISON_OPS.join("|")})([1-9]\\d*)$`); +const comparisonStringRegex = new RegExp(`^(${TRIGGER_COMPARISON_OPS.join("|")})(\\d*)$`); /** * @return Parsed comparison op and value, or null if the comparison string was invalid From 74a676913ee781df2ef0ce856aa12987dd835832 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 00:37:19 +0100 Subject: [PATCH 50/79] user.tag --- backend/src/plugins/Automod/triggers/roleAdded.ts | 2 +- .../src/plugins/Automod/triggers/roleRemoved.ts | 2 +- .../BotControl/commands/AddDashboardUserCmd.ts | 4 +--- .../BotControl/commands/ListDashboardPermsCmd.ts | 6 ++---- .../BotControl/commands/ListDashboardUsersCmd.ts | 4 +--- .../BotControl/commands/RemoveDashboardUserCmd.ts | 4 +--- .../src/plugins/BotControl/commands/ServersCmd.ts | 2 +- backend/src/plugins/Cases/functions/createCase.ts | 6 +++--- .../src/plugins/Cases/functions/createCaseNote.ts | 2 +- .../src/plugins/ModActions/commands/AddCaseCmd.ts | 6 +----- backend/src/plugins/ModActions/commands/BanCmd.ts | 2 +- .../src/plugins/ModActions/commands/CasesModCmd.ts | 2 +- .../plugins/ModActions/commands/CasesUserCmd.ts | 5 +---- .../plugins/ModActions/commands/DeleteCaseCmd.ts | 2 +- backend/src/plugins/ModActions/commands/NoteCmd.ts | 2 +- backend/src/plugins/ModActions/commands/WarnCmd.ts | 2 +- .../ModActions/events/PostAlertOnMemberJoinEvt.ts | 2 +- .../ModActions/functions/actualKickMemberCmd.ts | 2 +- .../ModActions/functions/actualMuteUserCmd.ts | 8 ++++---- .../ModActions/functions/actualUnmuteUserCmd.ts | 4 ++-- backend/src/plugins/Mutes/commands/MutesCmd.ts | 4 ++-- .../src/plugins/NameHistory/commands/NamesCmd.ts | 2 +- backend/src/plugins/Post/util/actualPostCmd.ts | 2 +- .../util/addMemberPendingRoleChange.ts | 4 +--- .../plugins/Slowmode/commands/SlowmodeClearCmd.ts | 10 +++------- .../util/createStarboardEmbedFromMessage.ts | 2 +- .../src/plugins/UsernameSaver/updateUsername.ts | 2 +- backend/src/plugins/Utility/commands/AvatarCmd.ts | 2 +- backend/src/plugins/Utility/commands/LevelCmd.ts | 4 +--- .../plugins/Utility/commands/VcdisconnectCmd.ts | 6 +----- backend/src/plugins/Utility/commands/VcmoveCmd.ts | 14 +++----------- .../Utility/functions/getInviteInfoEmbed.ts | 4 ++-- .../Utility/functions/getMessageInfoEmbed.ts | 2 +- .../Utility/functions/getServerInfoEmbed.ts | 2 +- .../plugins/Utility/functions/getUserInfoEmbed.ts | 4 ++-- backend/src/plugins/Utility/search.ts | 8 ++++---- backend/src/utils.ts | 9 +++++---- backend/src/utils/configAccessibleObjects.ts | 2 +- 38 files changed, 59 insertions(+), 93 deletions(-) diff --git a/backend/src/plugins/Automod/triggers/roleAdded.ts b/backend/src/plugins/Automod/triggers/roleAdded.ts index d3fd0cf9..387f4d9b 100644 --- a/backend/src/plugins/Automod/triggers/roleAdded.ts +++ b/backend/src/plugins/Automod/triggers/roleAdded.ts @@ -37,7 +37,7 @@ export const RoleAddedTrigger = automodTrigger()({ const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId as Snowflake); const roleName = role?.name || "Unknown"; const member = contexts[0].member!; - const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; + const memberName = `**${member.user.tag}** (\`${member.id}\`)`; return `Role ${roleName} (\`${matchResult.extra.matchedRoleId}\`) was added to ${memberName}`; }, }); diff --git a/backend/src/plugins/Automod/triggers/roleRemoved.ts b/backend/src/plugins/Automod/triggers/roleRemoved.ts index 45360086..46b68376 100644 --- a/backend/src/plugins/Automod/triggers/roleRemoved.ts +++ b/backend/src/plugins/Automod/triggers/roleRemoved.ts @@ -37,7 +37,7 @@ export const RoleRemovedTrigger = automodTrigger()({ const role = pluginData.guild.roles.cache.get(matchResult.extra.matchedRoleId as Snowflake); const roleName = role?.name || "Unknown"; const member = contexts[0].member!; - const memberName = `**${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; + const memberName = `**${member.user.tag}** (\`${member.id}\`)`; return `Role ${roleName} (\`${matchResult.extra.matchedRoleId}\`) was removed from ${memberName}`; }, }); diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index 156606da..84cce432 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -35,9 +35,7 @@ export const AddDashboardUserCmd = botControlCmd({ await pluginData.state.apiPermissionAssignments.addUser(args.guildId, user.id, [ApiPermissions.EditConfig]); } - const userNameList = args.users.map( - user => `<@!${user.id}> (**${user.username}#${user.discriminator}**, \`${user.id}\`)`, - ); + const userNameList = args.users.map(user => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`); sendSuccessMessage( pluginData, msg.channel as TextChannel, diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index d9310906..4a8a609c 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -46,7 +46,7 @@ export const ListDashboardPermsCmd = botControlCmd({ // If we have user, always display which guilds they have permissions in (or only specified guild permissions) if (args.user) { - const userInfo = `**${args.user.username}#${args.user.discriminator}** (\`${args.user.id}\`)`; + const userInfo = `**${args.user.tag}** (\`${args.user.id}\`)`; for (const assignment of existingUserAssignment!) { if (guild != null && assignment.guild_id !== args.guildId) continue; @@ -82,9 +82,7 @@ export const ListDashboardPermsCmd = botControlCmd({ finalMessage += `The server ${guildInfo} has the following assigned permissions:\n`; // Double \n for consistency with AddDashboardUserCmd for (const assignment of existingGuildAssignment) { const user = await resolveUser(pluginData.client, assignment.target_id); - finalMessage += `\n**${user.username}#${user.discriminator}**, \`${ - assignment.target_id - }\`: ${assignment.permissions.join(", ")}`; + finalMessage += `\n**${user.tag}**, \`${assignment.target_id}\`: ${assignment.permissions.join(", ")}`; } } diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index 81e58fb7..52c3083f 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -24,9 +24,7 @@ export const ListDashboardUsersCmd = botControlCmd({ const dashboardUsers = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id); const users = await Promise.all(dashboardUsers.map(perm => resolveUser(pluginData.client, perm.target_id))); - const userNameList = users.map( - user => `<@!${user.id}> (**${user.username}#${user.discriminator}**, \`${user.id}\`)`, - ); + const userNameList = users.map(user => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`); sendSuccessMessage( pluginData, diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 75085491..3dfafb42 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -34,9 +34,7 @@ export const RemoveDashboardUserCmd = botControlCmd({ await pluginData.state.apiPermissionAssignments.removeUser(args.guildId, user.id); } - const userNameList = args.users.map( - user => `<@!${user.id}> (**${user.username}#${user.discriminator}**, \`${user.id}\`)`, - ); + const userNameList = args.users.map(user => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`); sendSuccessMessage( pluginData, msg.channel as TextChannel, diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index 39938e3a..d226e14c 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -49,7 +49,7 @@ export const ServersCmd = botControlCmd({ const lines = filteredGuilds.map(g => { const paddedId = g.id.padEnd(longestId, " "); const owner = getUser(pluginData.client, g.ownerId); - return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.username}#${owner.discriminator}** \`${owner.id}\`)`; + return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.tag}** \`${owner.id}\`)`; }); createChunkedMessage(msg.channel as TextChannel, lines.join("\n")); } else { diff --git a/backend/src/plugins/Cases/functions/createCase.ts b/backend/src/plugins/Cases/functions/createCase.ts index 0d66c71e..5a03c1c2 100644 --- a/backend/src/plugins/Cases/functions/createCase.ts +++ b/backend/src/plugins/Cases/functions/createCase.ts @@ -7,15 +7,15 @@ import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; export async function createCase(pluginData: GuildPluginData, args: CaseArgs) { const user = await resolveUser(pluginData.client, args.userId); - const userName = `${user.username}#${user.discriminator}`; + const userName = `${user.tag}`; const mod = await resolveUser(pluginData.client, args.modId); - const modName = `${mod.username}#${mod.discriminator}`; + const modName = `${mod.tag}`; let ppName: string | null = null; if (args.ppId) { const pp = await resolveUser(pluginData.client, args.ppId); - ppName = `${pp.username}#${pp.discriminator}`; + ppName = `${pp.tag}`; } if (args.auditLogId) { diff --git a/backend/src/plugins/Cases/functions/createCaseNote.ts b/backend/src/plugins/Cases/functions/createCaseNote.ts index ed95e7a7..2f9d801c 100644 --- a/backend/src/plugins/Cases/functions/createCaseNote.ts +++ b/backend/src/plugins/Cases/functions/createCaseNote.ts @@ -16,7 +16,7 @@ export async function createCaseNote(pluginData: GuildPluginData !c.is_hidden); const hiddenCases = cases.filter(c => c.is_hidden); - const userName = - user instanceof UnknownUser && cases.length - ? cases[cases.length - 1].user_name - : `${user.username}#${user.discriminator}`; + const userName = user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : `${user.tag}`; if (cases.length === 0) { msg.channel.send(`No cases found for **${userName}**`); diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 09fbb8d0..b783fbbd 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -68,7 +68,7 @@ export const DeleteCaseCmd = modActionsCmd({ } } - const deletedByName = `${message.author.username}#${message.author.discriminator}`; + const deletedByName = `${message.author.tag}`; const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); const deletedAt = timeAndDate.inGuildTz().format(timeAndDate.getDateFormat("pretty_datetime")); diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index efdb5adc..0fbd1dbd 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -30,7 +30,7 @@ export const NoteCmd = modActionsCmd({ return; } - const userName = `${user.username}#${user.discriminator}`; + const userName = `${user.tag}`; const reason = formatReasonWithAttachments(args.note, msg.attachments.array()); const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index f85e1bdb..d06f91b8 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -107,7 +107,7 @@ export const WarnCmd = modActionsCmd({ sendSuccessMessage( pluginData, msg.channel, - `Warned **${memberToWarn.user.username}#${memberToWarn.user.discriminator}** (Case #${warnResult.case.case_number})${messageResultText}`, + `Warned **${memberToWarn.user.tag}** (Case #${warnResult.case.case_number})${messageResultText}`, ); }, }); diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index b8925aa1..136e41cc 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -47,7 +47,7 @@ export const PostAlertOnMemberJoinEvt = modActionsEvt({ } await alertChannel.send( - `<@!${member.id}> (${member.user.username}#${member.user.discriminator} \`${member.id}\`) joined with ${actions.length} prior record(s)`, + `<@!${member.id}> (${member.user.tag} \`${member.id}\`) joined with ${actions.length} prior record(s)`, ); } }, diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index 0ed86ded..92178edc 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -103,7 +103,7 @@ export async function actualKickMemberCmd( } // Confirm the action to the moderator - let response = `Kicked **${memberToKick.user.username}#${memberToKick.user.discriminator}** (Case #${kickResult.case.case_number})`; + let response = `Kicked **${memberToKick.user.tag}** (Case #${kickResult.case.case_number})`; if (kickResult.notifyResult.text) response += ` (${kickResult.notifyResult.text})`; sendSuccessMessage(pluginData, msg.channel, response); diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index 4dc16209..64fd30df 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -85,24 +85,24 @@ export async function actualMuteUserCmd( if (args.time) { if (muteResult.updatedExistingMute) { response = asSingleLine(` - Updated **${user.username}#${user.discriminator}**'s + Updated **${user.tag}**'s mute to ${timeUntilUnmute} (Case #${muteResult.case.case_number}) `); } else { response = asSingleLine(` - Muted **${user.username}#${user.discriminator}** + Muted **${user.tag}** for ${timeUntilUnmute} (Case #${muteResult.case.case_number}) `); } } else { if (muteResult.updatedExistingMute) { response = asSingleLine(` - Updated **${user.username}#${user.discriminator}**'s + Updated **${user.tag}**'s mute to indefinite (Case #${muteResult.case.case_number}) `); } else { response = asSingleLine(` - Muted **${user.username}#${user.discriminator}** + Muted **${user.tag}** indefinitely (Case #${muteResult.case.case_number}) `); } diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts index 9f95b417..fb7465c7 100644 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts @@ -48,7 +48,7 @@ export async function actualUnmuteCmd( pluginData, msg.channel as TextChannel, asSingleLine(` - Unmuting **${user.username}#${user.discriminator}** + Unmuting **${user.tag}** in ${timeUntilUnmute} (Case #${result.case.case_number}) `), ); @@ -57,7 +57,7 @@ export async function actualUnmuteCmd( pluginData, msg.channel as TextChannel, asSingleLine(` - Unmuted **${user.username}#${user.discriminator}** + Unmuted **${user.tag}** (Case #${result.case.case_number}) `), ); diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 27b33523..4ee88e74 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -67,7 +67,7 @@ export const MutesCmd = mutesCmd({ totalMutes = manuallyMutedMembers.length; lines = manuallyMutedMembers.map(member => { - return `<@!${member.id}> (**${member.user.username}#${member.user.discriminator}**, \`${member.id}\`) 🔧 Manual mute`; + return `<@!${member.id}> (**${member.user.tag}**, \`${member.id}\`) 🔧 Manual mute`; }); } else { // Show filtered active mutes (but not manual mutes) @@ -119,7 +119,7 @@ export const MutesCmd = mutesCmd({ lines = filteredMutes.map(mute => { const user = pluginData.client.users.resolve(mute.user_id as Snowflake); - const username = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; + const username = user ? `${user.tag}` : "Unknown#0000"; const theCase = muteCasesById.get(mute.case_id); const caseName = theCase ? `Case #${theCase.case_number}` : "No case"; diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index f2a7348a..0ee42166 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -31,7 +31,7 @@ export const NamesCmd = nameHistoryCmd({ const usernameRows = usernames.map(r => `\`[${r.timestamp}]\` **${disableCodeBlocks(r.username)}**`); const user = await pluginData.client.users.fetch(args.userId as Snowflake); - const currentUsername = user ? `${user.username}#${user.discriminator}` : args.userId; + const currentUsername = user ? `${user.tag}` : args.userId; const nicknameDays = Math.round(NICKNAME_RETENTION_PERIOD / DAYS); const usernameDays = Math.round(NICKNAME_RETENTION_PERIOD / DAYS); diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index 88135f38..db8f51a4 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -138,7 +138,7 @@ export async function actualPostCmd( await pluginData.state.scheduledPosts.create({ author_id: msg.author.id, - author_name: `${msg.author.username}#${msg.author.discriminator}`, + author_name: `${msg.author.tag}`, channel_id: targetChannel.id, content, attachments: msg.attachments.array(), diff --git a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts index 41ec5710..f4e4bfcb 100644 --- a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts +++ b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts @@ -38,9 +38,7 @@ export async function addMemberPendingRoleChange( "Reaction roles", ); } catch (e) { - logger.warn( - `Failed to apply role changes to ${member.user.username}#${member.user.discriminator} (${member.id}): ${e.message}`, - ); + logger.warn(`Failed to apply role changes to ${member.user.tag} (${member.id}): ${e.message}`); } } lock.unlock(); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index 3f67b710..75835e6b 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -45,7 +45,7 @@ export const SlowmodeClearCmd = slowmodeCmd({ pluginData, msg.channel, asSingleLine(` - Failed to clear slowmode from **${args.user.username}#${args.user.discriminator}** in <#${args.channel.id}>: + Failed to clear slowmode from **${args.user.tag}** in <#${args.channel.id}>: Threads cannot have Bot Slowmode `), ); @@ -56,17 +56,13 @@ export const SlowmodeClearCmd = slowmodeCmd({ pluginData, msg.channel, asSingleLine(` - Failed to clear slowmode from **${args.user.username}#${args.user.discriminator}** in <#${args.channel.id}>: + Failed to clear slowmode from **${args.user.tag}** in <#${args.channel.id}>: \`${disableInlineCode(e.message)}\` `), ); return; } - sendSuccessMessage( - pluginData, - msg.channel, - `Slowmode cleared from **${args.user.username}#${args.user.discriminator}** in <#${args.channel.id}>`, - ); + sendSuccessMessage(pluginData, msg.channel, `Slowmode cleared from **${args.user.tag}** in <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index a66f09f8..209d8ca8 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -18,7 +18,7 @@ export function createStarboardEmbedFromMessage( text: `#${(msg.channel as GuildChannel).name}`, }, author: { - name: `${msg.author.username}#${msg.author.discriminator}`, + name: `${msg.author.tag}`, }, fields: [], timestamp: msg.createdAt, diff --git a/backend/src/plugins/UsernameSaver/updateUsername.ts b/backend/src/plugins/UsernameSaver/updateUsername.ts index 56debeac..baaa3bd1 100644 --- a/backend/src/plugins/UsernameSaver/updateUsername.ts +++ b/backend/src/plugins/UsernameSaver/updateUsername.ts @@ -4,7 +4,7 @@ import { UsernameSaverPluginType } from "./types"; export async function updateUsername(pluginData: GuildPluginData, user: User) { if (!user) return; - const newUsername = `${user.username}#${user.discriminator}`; + const newUsername = `${user.tag}`; const latestEntry = await pluginData.state.usernameHistory.getLastEntry(user.id); if (!latestEntry || newUsername !== latestEntry.username) { await pluginData.state.usernameHistory.addEntry(user.id, newUsername); diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index 7fe01bb9..cf8714b1 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -24,7 +24,7 @@ export const AvatarCmd = utilityCmd({ const embed: MessageEmbedOptions = { image: { url: avatarUrl + `${extension}?size=2048` }, }; - embed.title = `Avatar of ${user.username}#${user.discriminator}:`; + embed.title = `Avatar of ${user.tag}:`; msg.channel.send({ embeds: [embed] }); } else { sendErrorMessage(pluginData, msg.channel, "Invalid user ID"); diff --git a/backend/src/plugins/Utility/commands/LevelCmd.ts b/backend/src/plugins/Utility/commands/LevelCmd.ts index 404412b5..e0be2605 100644 --- a/backend/src/plugins/Utility/commands/LevelCmd.ts +++ b/backend/src/plugins/Utility/commands/LevelCmd.ts @@ -17,8 +17,6 @@ export const LevelCmd = utilityCmd({ run({ message, args, pluginData }) { const member = args.member || message.member; const level = getMemberLevel(pluginData, member); - message.channel.send( - `The permission level of ${member.user.username}#${member.user.discriminator} is **${level}**`, - ); + message.channel.send(`The permission level of ${member.user.tag} is **${level}**`); }, }); diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index 8c20adc4..d473b491 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -44,10 +44,6 @@ export const VcdisconnectCmd = utilityCmd({ oldChannel: channelToConfigAccessibleChannel(channel), }); - sendSuccessMessage( - pluginData, - msg.channel, - `**${args.member.user.username}#${args.member.user.discriminator}** disconnected from **${channel.name}**`, - ); + sendSuccessMessage(pluginData, msg.channel, `**${args.member.user.tag}** disconnected from **${channel.name}**`); }, }); diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index adb56d96..0e7bface 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -85,11 +85,7 @@ export const VcmoveCmd = utilityCmd({ newChannel: channelToConfigAccessibleChannel(channel), }); - sendSuccessMessage( - pluginData, - msg.channel, - `**${args.member.user.username}#${args.member.user.discriminator}** moved to **${channel.name}**`, - ); + sendSuccessMessage(pluginData, msg.channel, `**${args.member.user.tag}** moved to **${channel.name}**`); }, }); @@ -162,7 +158,7 @@ export const VcmoveAllCmd = utilityCmd({ sendErrorMessage( pluginData, msg.channel, - `Failed to move ${currMember.user.username}#${currMember.user.discriminator} (${currMember.id}): You cannot act on this member`, + `Failed to move ${currMember.user.tag} (${currMember.id}): You cannot act on this member`, ); errAmt++; continue; @@ -177,11 +173,7 @@ export const VcmoveAllCmd = utilityCmd({ sendErrorMessage(pluginData, msg.channel, "Unknown error when trying to move members"); return; } - sendErrorMessage( - pluginData, - msg.channel, - `Failed to move ${currMember.user.username}#${currMember.user.discriminator} (${currMember.id})`, - ); + sendErrorMessage(pluginData, msg.channel, `Failed to move ${currMember.user.tag} (${currMember.id})`); errAmt++; continue; } diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index c8ddfad8..a95de14b 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -96,7 +96,7 @@ export async function getInviteInfoEmbed( embed.fields.push({ name: preEmbedPadding + "Invite creator", value: trimLines(` - Name: **${invite.inviter.username}#${invite.inviter.discriminator}** + Name: **${invite.inviter.tag}** ID: \`${invite.inviter.id}\` Mention: <@!${invite.inviter.id}> `), @@ -143,7 +143,7 @@ export async function getInviteInfoEmbed( embed.fields.push({ name: preEmbedPadding + "Invite creator", value: trimLines(` - Name: **${invite.inviter.username}#${invite.inviter.discriminator}** + Name: **${invite.inviter.tag}** ID: \`${invite.inviter.id}\` Mention: <@!${invite.inviter.id}> `), diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 5b8fc4bc..17e2c63f 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -112,7 +112,7 @@ export async function getMessageInfoEmbed( embed.fields.push({ name: preEmbedPadding + "Author information", value: trimLines(` - Name: **${message.author.username}#${message.author.discriminator}** + Name: **${message.author.tag}** ID: \`${message.author.id}\` Created: **${authorAccountAge} ago** (\`${prettyAuthorCreatedAt}\`) ${authorJoinedAt ? `Joined: **${authorServerAge} ago** (\`${prettyAuthorJoinedAt}\`)` : ""} diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 2eb04a60..93b4d45e 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -65,7 +65,7 @@ export async function getServerInfoEmbed( if (thisServer) { const owner = await resolveUser(pluginData.client, thisServer.ownerId); - const ownerName = `${owner.username}#${owner.discriminator}`; + const ownerName = `${owner.tag}`; basicInformation.push(`Owner: **${ownerName}** (\`${thisServer.ownerId}\`)`); // basicInformation.push(`Voice region: **${thisServer.region}**`); Outdated, as automatic voice regions are fully live diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 581193fb..4f87dabc 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -36,7 +36,7 @@ export async function getUserInfoEmbed( const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); embed.author = { - name: `User: ${user.username}#${user.discriminator}`, + name: `User: ${user.tag}`, }; const avatarURL = user.displayAvatarURL(); @@ -84,7 +84,7 @@ export async function getUserInfoEmbed( embed.fields.push({ name: preEmbedPadding + "User information", value: trimLines(` - Name: **${user.username}#${user.discriminator}** + Name: **${user.tag}** ID: \`${user.id}\` Created: **${accountAge} ago** (\`${prettyCreatedAt}\`) Mention: <@!${user.id}> diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 40bd1d1b..97bc1bd4 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -391,7 +391,7 @@ async function performMemberSearch( return true; } - const fullUsername = `${member.user.username}#${member.user.discriminator}`; + const fullUsername = `${member.user.tag}`; if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; return false; @@ -458,7 +458,7 @@ async function performBanSearch( const execRegExp = getOptimizedRegExpRunner(pluginData, isSafeRegex); matchingBans = await asyncFilter(matchingBans, async user => { - const fullUsername = `${user.username}#${user.discriminator}`; + const fullUsername = `${user.tag}`; if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; return false; }); @@ -502,10 +502,10 @@ function formatSearchResultList(members: Array): string { const paddedId = member.id.padEnd(longestId, " "); let line; if (member instanceof GuildMember) { - line = `${paddedId} ${member.user.username}#${member.user.discriminator}`; + line = `${paddedId} ${member.user.tag}`; if (member.nickname) line += ` (${member.nickname})`; } else { - line = `${paddedId} ${member.username}#${member.discriminator}`; + line = `${paddedId} ${member.tag}`; } return line; }); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index c4464f97..99d46617 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1099,6 +1099,7 @@ export class UnknownUser { public id: string; public username = "Unknown"; public discriminator = "0000"; + public tag = "Unknown#0000"; constructor(props = {}) { for (const key in props) { @@ -1353,18 +1354,18 @@ export function messageSummary(msg: SavedMessage) { export function verboseUserMention(user: User | UnknownUser): string { if (user.id == null) { - return `**${user.username}#${user.discriminator}**`; + return `**${user.tag}**`; } - return `<@!${user.id}> (**${user.username}#${user.discriminator}**, \`${user.id}\`)`; + return `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`; } export function verboseUserName(user: User | UnknownUser): string { if (user.id == null) { - return `**${user.username}#${user.discriminator}**`; + return `**${user.tag}**`; } - return `**${user.username}#${user.discriminator}** (\`${user.id}\`)`; + return `**${user.tag}** (\`${user.id}\`)`; } export function verboseChannelMention(channel: GuildChannel): string { diff --git a/backend/src/utils/configAccessibleObjects.ts b/backend/src/utils/configAccessibleObjects.ts index 1c281ed6..638fb6ca 100644 --- a/backend/src/utils/configAccessibleObjects.ts +++ b/backend/src/utils/configAccessibleObjects.ts @@ -38,7 +38,7 @@ export interface IConfigAccessibleMember extends IConfigAccessibleUser { } export function userToConfigAccessibleUser(user: User | UnknownUser): IConfigAccessibleUser { - if (`${user.username}#${user.discriminator}` === "Unknown#0000") { + if (`${user.tag}` === "Unknown#0000") { const toReturnPartial: IConfigAccessibleUser = { id: user.id, username: "Unknown", From bd5e5100a597a50a963dde8c6f10b931588b6742 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 00:50:41 +0100 Subject: [PATCH 51/79] typo and return --- .../ReactionRoles/events/ButtonInteractionEvt.ts | 4 ++-- .../ReactionRoles/util/buttonActionHandlers.ts | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index 7f366140..a08e4579 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -55,7 +55,7 @@ export const ButtonInteractionEvt = reactionRolesEvt({ .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, group **${context.groupName}** not found in config`, + `**A configuration error occurred** on buttons for message ${int.message.id}, group **${context.groupName}** not found in config`, ); return; } @@ -67,7 +67,7 @@ export const ButtonInteractionEvt = reactionRolesEvt({ .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A internal error occured** on buttons for message ${int.message.id}, action **${context.action}** is not known`, + `**A internal error occurred** on buttons for message ${int.message.id}, action **${context.action}** is not known`, ); return; } diff --git a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts index 314516b6..446cc0ee 100644 --- a/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts +++ b/backend/src/plugins/ReactionRoles/util/buttonActionHandlers.ts @@ -22,7 +22,7 @@ export async function handleOpenMenu( .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, no menus found in config`, + `**A configuration error occurred** on buttons for message ${int.message.id}, no menus found in config`, ); return; } @@ -52,14 +52,13 @@ export async function handleOpenMenu( .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, menu **${context.roleOrMenu}** not found in config`, + `**A configuration error occurred** on buttons for message ${int.message.id}, menu **${context.roleOrMenu}** not found in config`, ); return; } const rows = splitButtonsIntoRows(menuButtons, Object.values(group.button_menus[context.roleOrMenu])); // new MessageActionRow().addComponents(menuButtons); int.reply({ content: `Click to add/remove a role`, components: rows, ephemeral: true }); - return; } export async function handleModifyRole( @@ -78,7 +77,7 @@ export async function handleModifyRole( .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, role **${context.roleOrMenu}** not found on server`, + `**A configuration error occurred** on buttons for message ${int.message.id}, role **${context.roleOrMenu}** not found on server`, ); return; } @@ -101,10 +100,7 @@ export async function handleModifyRole( .getPlugin(LogsPlugin) .log( LogType.BOT_ALERT, - `**A configuration error occured** on buttons for message ${int.message.id}, error: ${e}. We might be missing permissions!`, + `**A configuration error occurred** on buttons for message ${int.message.id}, error: ${e}. We might be missing permissions!`, ); - return; } - - return; } From de7c721c0e2f63234ed52a7f0d51f205d3ce1e92 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 00:52:19 +0100 Subject: [PATCH 52/79] simplify ternary --- backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index ce4894e0..22bc74d7 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -89,7 +89,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ if (mode === "native") { const missingPermissions = getMissingPermissions( - channelPermissions ? channelPermissions : new Permissions(), + channelPermissions ?? new Permissions(), NATIVE_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { @@ -104,7 +104,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ if (mode === "bot") { const missingPermissions = getMissingPermissions( - channelPermissions ? channelPermissions : new Permissions(), + channelPermissions ?? new Permissions(), BOT_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { From cfe3bff74289291b5656b8afb35f63a701b35e4b Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 00:55:03 +0100 Subject: [PATCH 53/79] fetch fix --- backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 208f628a..3a29a711 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -21,7 +21,7 @@ export async function applyBotSlowmodeToUserId( await channel.permissionOverwrites.create(userId as Snowflake, { SEND_MESSAGES: false }, { type: 1 }); } } catch (e) { - const user = (await pluginData.client.users.fetch(userId as Snowflake)) || new UnknownUser({ id: userId }); + const user = await pluginData.client.users.fetch(userId as Snowflake).catch(() => new UnknownUser({ id: userId })); if (isDiscordAPIError(e) && e.code === 50013) { logger.warn( From c98de0f554e95608632b211f16a89ebba92976a6 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 00:58:11 +0100 Subject: [PATCH 54/79] fetch fix --- backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index 0d22bca8..f8490e4d 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -21,8 +21,9 @@ export async function clearExpiredSlowmodes(pluginData: GuildPluginData new UnknownUser({ id: user.user_id })); pluginData.state.logs.log(LogType.BOT_ALERT, { body: `Failed to clear slowmode permissions from {userMention(user)} in {channelMention(channel)}`, From 9539c5a7de1d355d83bf33a7dc93b766bc553e0b Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 01:08:00 +0100 Subject: [PATCH 55/79] corrected type assertion --- backend/src/plugins/Starboard/util/saveMessageToStarboard.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index 12e2785a..ed2bd3f9 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -1,4 +1,4 @@ -import { Message, MessageEmbed, Snowflake, TextChannel } from "discord.js"; +import { Message, MessageEmbedOptions, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { StarboardPluginType, TStarboardOpts } from "../types"; import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; @@ -16,6 +16,6 @@ export async function saveMessageToStarboard( const embed = createStarboardEmbedFromMessage(msg, Boolean(starboard.copy_full_embed), starboard.color); embed.fields!.push(createStarboardPseudoFooterForMessage(starboard, msg, starboard.star_emoji![0], starCount)); - const starboardMessage = await (channel as TextChannel).send({ embeds: [embed as MessageEmbed] }); + const starboardMessage = await (channel as TextChannel).send({ embeds: [embed as MessageEmbedOptions] }); await pluginData.state.starboardMessages.createStarboardMessage(channel.id, msg.id, starboardMessage.id); } From 87cc461c79a87efe9d065b9d27a31480e8978317 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 01:10:53 +0100 Subject: [PATCH 56/79] always set author icon url using dynamic --- .../plugins/Starboard/util/createStarboardEmbedFromMessage.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 209d8ca8..0cc579a9 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -28,9 +28,7 @@ export function createStarboardEmbedFromMessage( embed.color = color; } - if (msg.author.avatarURL()) { - embed.author.icon_url = msg.author.avatarURL()!; - } + embed.author.icon_url = msg.author.displayAvatarURL({ dynamic: true }); // The second condition here checks for messages with only an image link that is then embedded. // The message content in that case is hidden by the Discord client, so we hide it here too. From 3a59f772ae0668d4b1f1e5706fb2d254679d0a9d Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 01:18:06 +0100 Subject: [PATCH 57/79] use optional chaining and createdTimestamp on embed --- backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts | 4 ++-- .../plugins/Starboard/util/createStarboardEmbedFromMessage.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index b5f9bbba..e34b34c2 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -120,8 +120,8 @@ export async function logAndDetectMessageSpam( // Then, if enabled, remove the spam messages if (spamConfig.clean !== false) { msgIds.forEach(id => pluginData.state.logs.ignoreLog(LogType.MESSAGE_DELETE, id)); - (pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake)! as TextChannel) - .bulkDelete(msgIds as Snowflake[]) + (pluginData.guild.channels.cache.get(savedMessage.channel_id as Snowflake)! as TextChannel | undefined) + ?.bulkDelete(msgIds as Snowflake[]) .catch(noop); } diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 0cc579a9..e1fe0aed 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -21,7 +21,7 @@ export function createStarboardEmbedFromMessage( name: `${msg.author.tag}`, }, fields: [], - timestamp: msg.createdAt, + timestamp: msg.createdTimestamp, }; if (color != null) { From 0f5162ee21b9ed4e9e47ee752acf7dc0c0da9e25 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 01:20:40 +0100 Subject: [PATCH 58/79] ping in about cmd --- backend/src/plugins/Utility/commands/AboutCmd.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 8c7d4db5..0d6f8493 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -39,8 +39,6 @@ export const AboutCmd = utilityCmd({ version = "?"; } - // const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; FIXME Sharding stuff - const lastReload = humanizeDuration(Date.now() - pluginData.state.lastReload, { largest: 2, round: true, @@ -51,7 +49,7 @@ export const AboutCmd = utilityCmd({ ["Last reload", `${lastReload} ago`], ["Last update", lastUpdate], ["Version", version], - // ["API latency", `${shard.latency}ms`], + ["API latency", `${pluginData.client.ws.ping}ms`], ["Server timezone", timeAndDate.getGuildTz()], ]; @@ -70,11 +68,7 @@ export const AboutCmd = utilityCmd({ fields: [ { name: "Status", - value: basicInfoRows - .map(([label, value]) => { - return `${label}: **${value}**`; - }) - .join("\n"), + value: basicInfoRows.map(([label, value]) => `${label}: **${value}**`).join("\n"), }, { name: `Loaded plugins on this server (${loadedPlugins.length})`, From 80f2dacb7f3f98efd18d661163f6b8cce9b8b435 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 01:22:37 +0100 Subject: [PATCH 59/79] simplified avatar cmd --- backend/src/plugins/Utility/commands/AvatarCmd.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index cf8714b1..d503bc97 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -16,15 +16,12 @@ export const AvatarCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { const user = args.user || msg.author; if (!(user instanceof UnknownUser)) { - const avatar = user.displayAvatarURL(); - let extension = avatar.slice(avatar.lastIndexOf("."), avatar.lastIndexOf("?")); - // Some pngs can have the .jpg extention for some reason, so we always use .png for static images - extension = extension === ".gif" ? extension : ".png"; - const avatarUrl = avatar.slice(0, avatar.lastIndexOf(".")); const embed: MessageEmbedOptions = { - image: { url: avatarUrl + `${extension}?size=2048` }, + image: { + url: user.displayAvatarURL({ dynamic: true, format: "png", size: 2048 }), + }, + title: `Avatar of ${user.tag}:`, }; - embed.title = `Avatar of ${user.tag}:`; msg.channel.send({ embeds: [embed] }); } else { sendErrorMessage(pluginData, msg.channel, "Invalid user ID"); From a8298d4faa38d7720fd3af0949070bb454fd4ce2 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 01:43:50 +0100 Subject: [PATCH 60/79] fixed jumbo cmd, simplified checks and fixed ping cmd --- .../src/plugins/Utility/commands/JumboCmd.ts | 35 +++++++++---------- .../src/plugins/Utility/commands/PingCmd.ts | 5 ++- .../Utility/commands/VcdisconnectCmd.ts | 2 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 2 +- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index 4e2e99a7..bc117d45 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -1,3 +1,4 @@ +import { MessageAttachment } from "discord.js"; import fs from "fs"; import sharp from "sharp"; import twemoji from "twemoji"; @@ -39,8 +40,8 @@ export const JumboCmd = utilityCmd({ const size = config.jumbo_size > 2048 ? 2048 : config.jumbo_size; const emojiRegex = new RegExp(`(<.*:).*:(\\d+)`); const results = emojiRegex.exec(args.emoji); - let extention = ".png"; - let file; + let extension = ".png"; + let file: MessageAttachment | undefined; if (!isEmoji(args.emoji)) { sendErrorMessage(pluginData, msg.channel, "Invalid emoji"); @@ -50,25 +51,19 @@ export const JumboCmd = utilityCmd({ if (results) { let url = "https://cdn.discordapp.com/emojis/"; if (results[1] === " total + ms, 0) / times.length); - // const shard = pluginData.client.shards.get(pluginData.client.guildShardMap[pluginData.guild.id])!; FIXME sharding stuff - msg.channel.send( trimLines(` **Ping:** @@ -38,7 +36,8 @@ export const PingCmd = utilityCmd({ Highest: **${highest}ms** Mean: **${mean}ms** Time between ping command and first reply: **${msgToMsgDelay!}ms** - `), // Omitted line: Shard latency: **${shard.latency}ms** + Shard latency: **${pluginData.client.ws.ping}ms** + `), ); // Clean up test messages diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index d473b491..c5d4b14d 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -25,7 +25,7 @@ export const VcdisconnectCmd = utilityCmd({ return; } - if (!args.member.voice || !args.member.voice.channelId) { + if (!args.member.voice?.channelId) { sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); return; } diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 0e7bface..9e51dd5b 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -57,7 +57,7 @@ export const VcmoveCmd = utilityCmd({ channel = closestMatch; } - if (!args.member.voice || !args.member.voice.channelId) { + if (!args.member.voice?.channelId) { sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); return; } From a3e6e4f31992db5ac31c8c8fb67163c672e19bf2 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 01:51:11 +0100 Subject: [PATCH 61/79] removed unnecessary conditional --- backend/src/index.ts | 2 +- .../src/plugins/Utility/events/AutoJoinThreadEvt.ts | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/backend/src/index.ts b/backend/src/index.ts index 70bf4d2e..7ab1032d 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -174,7 +174,7 @@ connect().then(async () => { client.setMaxListeners(200); client.on("rateLimit", rateLimitData => { - logger.info(`[429] ${rateLimitData}`); + logger.info(`[429] ${JSON.stringify(rateLimitData)}`); }); client.on("error", err => { diff --git a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts index 6789073c..84c36768 100644 --- a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts +++ b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts @@ -5,7 +5,7 @@ export const AutoJoinThreadEvt = utilityEvt({ async listener(meta) { const config = meta.pluginData.config.get(); - if (config.autojoin_threads && meta.args.thread.joinable && !meta.args.thread.joined) { + if (config.autojoin_threads && meta.args.thread.joinable) { await meta.args.thread.join(); } }, @@ -16,11 +16,10 @@ export const AutoJoinThreadSyncEvt = utilityEvt({ async listener(meta) { const config = meta.pluginData.config.get(); - if (config.autojoin_threads) { - for (const thread of meta.args.threads.values()) { - if (!thread.joined && thread.joinable) { - await thread.join(); - } + if (config.autojoin_threads) return; + for (const thread of meta.args.threads.values()) { + if (!thread.joined && thread.joinable) { + await thread.join(); } } }, From 30010247b19c9395ae415b24532bb96e56fb742c Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 29 Jul 2021 03:02:00 +0200 Subject: [PATCH 62/79] Fix object names --- backend/src/plugins/Logs/LogsPlugin.ts | 2 +- ...mojiModifyEvts.ts => LogsEmojiAndStickerModifyEvts.ts} | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename backend/src/plugins/Logs/events/{LogsStickerEmojiModifyEvts.ts => LogsEmojiAndStickerModifyEvts.ts} (87%) diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 3f65e9bc..e61d0857 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -27,7 +27,7 @@ import { LogsStickerCreateEvt, LogsStickerDeleteEvt, LogsStickerUpdateEvt, -} from "./events/LogsStickerEmojiModifyEvts"; +} from "./events/LogsEmojiAndStickerModifyEvts"; import { LogsThreadCreateEvt, LogsThreadDeleteEvt, LogsThreadUpdateEvt } from "./events/LogsThreadModifyEvts"; import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts"; import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts"; diff --git a/backend/src/plugins/Logs/events/LogsStickerEmojiModifyEvts.ts b/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts similarity index 87% rename from backend/src/plugins/Logs/events/LogsStickerEmojiModifyEvts.ts rename to backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts index 3535174c..4f8ce433 100644 --- a/backend/src/plugins/Logs/events/LogsStickerEmojiModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts @@ -47,7 +47,7 @@ export const LogsStickerCreateEvt = logsEvt({ async listener(meta) { meta.pluginData.state.guildLogs.log(LogType.STICKER_CREATE, { - thread: stickerToConfigAccessibleSticker(meta.args.sticker), + sticker: stickerToConfigAccessibleSticker(meta.args.sticker), }); }, }); @@ -57,7 +57,7 @@ export const LogsStickerDeleteEvt = logsEvt({ async listener(meta) { meta.pluginData.state.guildLogs.log(LogType.STICKER_DELETE, { - thread: stickerToConfigAccessibleSticker(meta.args.sticker), + sticker: stickerToConfigAccessibleSticker(meta.args.sticker), }); }, }); @@ -72,8 +72,8 @@ export const LogsStickerUpdateEvt = logsEvt({ meta.pluginData.state.guildLogs.log( LogType.STICKER_UPDATE, { - oldThread: stickerToConfigAccessibleSticker(meta.args.oldSticker), - newThread: stickerToConfigAccessibleSticker(meta.args.newSticker), + oldSticker: stickerToConfigAccessibleSticker(meta.args.oldSticker), + newSticker: stickerToConfigAccessibleSticker(meta.args.newSticker), differenceString, }, meta.args.newSticker.id, From afe0ec1194e7f7f765ad7fc52f84e88c4e416111 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 10:08:55 +0100 Subject: [PATCH 63/79] removed unnecessary string literal and simplified stuff --- backend/src/pluginUtils.ts | 4 ++-- backend/src/plugins/Cases/functions/createCase.ts | 6 +++--- backend/src/plugins/Cases/functions/createCaseNote.ts | 2 +- backend/src/plugins/ModActions/commands/CasesModCmd.ts | 2 +- backend/src/plugins/ModActions/commands/CasesUserCmd.ts | 2 +- backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts | 2 +- backend/src/plugins/ModActions/commands/NoteCmd.ts | 2 +- backend/src/plugins/Mutes/commands/MutesCmd.ts | 2 +- backend/src/plugins/NameHistory/commands/NamesCmd.ts | 4 ++-- backend/src/plugins/Post/util/actualPostCmd.ts | 2 +- .../plugins/ReactionRoles/events/ButtonInteractionEvt.ts | 6 ++---- .../Starboard/util/createStarboardEmbedFromMessage.ts | 2 +- backend/src/plugins/UsernameSaver/updateUsername.ts | 2 +- backend/src/plugins/Utility/commands/HelpCmd.ts | 2 +- backend/src/plugins/Utility/functions/getServerInfoEmbed.ts | 2 +- backend/src/plugins/Utility/search.ts | 4 ++-- backend/src/utils/configAccessibleObjects.ts | 2 +- 17 files changed, 23 insertions(+), 25 deletions(-) diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 733ba59a..14dcf85e 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -198,7 +198,7 @@ export async function sendSuccessMessage( return channel .send({ ...content }) // Force line break .catch(err => { - const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : `${channel.id}`; + const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id; logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); return undefined; }); @@ -219,7 +219,7 @@ export async function sendErrorMessage( return channel .send({ ...content }) // Force line break .catch(err => { - const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : `${channel.id}`; + const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id; logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); return undefined; }); diff --git a/backend/src/plugins/Cases/functions/createCase.ts b/backend/src/plugins/Cases/functions/createCase.ts index 5a03c1c2..9df38f26 100644 --- a/backend/src/plugins/Cases/functions/createCase.ts +++ b/backend/src/plugins/Cases/functions/createCase.ts @@ -7,15 +7,15 @@ import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; export async function createCase(pluginData: GuildPluginData, args: CaseArgs) { const user = await resolveUser(pluginData.client, args.userId); - const userName = `${user.tag}`; + const userName = user.tag; const mod = await resolveUser(pluginData.client, args.modId); - const modName = `${mod.tag}`; + const modName = mod.tag; let ppName: string | null = null; if (args.ppId) { const pp = await resolveUser(pluginData.client, args.ppId); - ppName = `${pp.tag}`; + ppName = pp.tag; } if (args.auditLogId) { diff --git a/backend/src/plugins/Cases/functions/createCaseNote.ts b/backend/src/plugins/Cases/functions/createCaseNote.ts index 2f9d801c..c03a5b3c 100644 --- a/backend/src/plugins/Cases/functions/createCaseNote.ts +++ b/backend/src/plugins/Cases/functions/createCaseNote.ts @@ -16,7 +16,7 @@ export async function createCaseNote(pluginData: GuildPluginData !c.is_hidden); const hiddenCases = cases.filter(c => c.is_hidden); - const userName = user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : `${user.tag}`; + const userName = user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : user.tag; if (cases.length === 0) { msg.channel.send(`No cases found for **${userName}**`); diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index b783fbbd..925d97c6 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -68,7 +68,7 @@ export const DeleteCaseCmd = modActionsCmd({ } } - const deletedByName = `${message.author.tag}`; + const deletedByName = message.author.tag; const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); const deletedAt = timeAndDate.inGuildTz().format(timeAndDate.getDateFormat("pretty_datetime")); diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index 0fbd1dbd..3ed21806 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -30,7 +30,7 @@ export const NoteCmd = modActionsCmd({ return; } - const userName = `${user.tag}`; + const userName = user.tag; const reason = formatReasonWithAttachments(args.note, msg.attachments.array()); const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 4ee88e74..5de51a3d 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -119,7 +119,7 @@ export const MutesCmd = mutesCmd({ lines = filteredMutes.map(mute => { const user = pluginData.client.users.resolve(mute.user_id as Snowflake); - const username = user ? `${user.tag}` : "Unknown#0000"; + const username = user ? user.tag : "Unknown#0000"; const theCase = muteCasesById.get(mute.case_id); const caseName = theCase ? `Case #${theCase.case_number}` : "No case"; diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index 0ee42166..710e7ba6 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -30,8 +30,8 @@ export const NamesCmd = nameHistoryCmd({ ); const usernameRows = usernames.map(r => `\`[${r.timestamp}]\` **${disableCodeBlocks(r.username)}**`); - const user = await pluginData.client.users.fetch(args.userId as Snowflake); - const currentUsername = user ? `${user.tag}` : args.userId; + const user = await pluginData.client.users.fetch(args.userId as Snowflake).catch(() => null); + const currentUsername = user ? user.tag : args.userId; const nicknameDays = Math.round(NICKNAME_RETENTION_PERIOD / DAYS); const usernameDays = Math.round(NICKNAME_RETENTION_PERIOD / DAYS); diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index db8f51a4..54492c10 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -138,7 +138,7 @@ export async function actualPostCmd( await pluginData.state.scheduledPosts.create({ author_id: msg.author.id, - author_name: `${msg.author.tag}`, + author_name: msg.author.tag, channel_id: targetChannel.id, content, attachments: msg.attachments.array(), diff --git a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts index a08e4579..3d7fb3d5 100644 --- a/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/ButtonInteractionEvt.ts @@ -17,10 +17,8 @@ export const ButtonInteractionEvt = reactionRolesEvt({ event: "interactionCreate", async listener(meta) { - const int = meta.args.interaction.isMessageComponent() - ? (meta.args.interaction as MessageComponentInteraction) - : null; - if (!int) return; + const int = meta.args.interaction; + if (!int.isMessageComponent()) return; const cfg = meta.pluginData.config.get(); const split = int.customId.split(BUTTON_CONTEXT_SEPARATOR); diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index e1fe0aed..dc6e8781 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -18,7 +18,7 @@ export function createStarboardEmbedFromMessage( text: `#${(msg.channel as GuildChannel).name}`, }, author: { - name: `${msg.author.tag}`, + name: msg.author.tag, }, fields: [], timestamp: msg.createdTimestamp, diff --git a/backend/src/plugins/UsernameSaver/updateUsername.ts b/backend/src/plugins/UsernameSaver/updateUsername.ts index baaa3bd1..207e6540 100644 --- a/backend/src/plugins/UsernameSaver/updateUsername.ts +++ b/backend/src/plugins/UsernameSaver/updateUsername.ts @@ -4,7 +4,7 @@ import { UsernameSaverPluginType } from "./types"; export async function updateUsername(pluginData: GuildPluginData, user: User) { if (!user) return; - const newUsername = `${user.tag}`; + const newUsername = user.tag; const latestEntry = await pluginData.state.usernameHistory.getLastEntry(user.id); if (!latestEntry || newUsername !== latestEntry.username) { await pluginData.state.usernameHistory.addEntry(user.id, newUsername); diff --git a/backend/src/plugins/Utility/commands/HelpCmd.ts b/backend/src/plugins/Utility/commands/HelpCmd.ts index d53f19b4..112e932e 100644 --- a/backend/src/plugins/Utility/commands/HelpCmd.ts +++ b/backend/src/plugins/Utility/commands/HelpCmd.ts @@ -80,7 +80,7 @@ export const HelpCmd = utilityCmd({ ? `Results (${totalResults} total, showing first ${limitedResults.length}):\n\n` : ""; - message += `${commandSnippets.join("\n\n")}`; + message += commandSnippets.join("\n\n"); createChunkedMessage(msg.channel, message); }, }); diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 93b4d45e..13e0652f 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -65,7 +65,7 @@ export async function getServerInfoEmbed( if (thisServer) { const owner = await resolveUser(pluginData.client, thisServer.ownerId); - const ownerName = `${owner.tag}`; + const ownerName = owner.tag; basicInformation.push(`Owner: **${ownerName}** (\`${thisServer.ownerId}\`)`); // basicInformation.push(`Voice region: **${thisServer.region}**`); Outdated, as automatic voice regions are fully live diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 97bc1bd4..45f77cd4 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -391,7 +391,7 @@ async function performMemberSearch( return true; } - const fullUsername = `${member.user.tag}`; + const fullUsername = member.user.tag; if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; return false; @@ -458,7 +458,7 @@ async function performBanSearch( const execRegExp = getOptimizedRegExpRunner(pluginData, isSafeRegex); matchingBans = await asyncFilter(matchingBans, async user => { - const fullUsername = `${user.tag}`; + const fullUsername = user.tag; if (await execRegExp(queryRegex, fullUsername).catch(allowTimeout)) return true; return false; }); diff --git a/backend/src/utils/configAccessibleObjects.ts b/backend/src/utils/configAccessibleObjects.ts index 14f13fec..379aaea0 100644 --- a/backend/src/utils/configAccessibleObjects.ts +++ b/backend/src/utils/configAccessibleObjects.ts @@ -40,7 +40,7 @@ export interface IConfigAccessibleMember extends IConfigAccessibleUser { } export function userToConfigAccessibleUser(user: User | UnknownUser): IConfigAccessibleUser { - if (`${user.tag}` === "Unknown#0000") { + if (user.tag === "Unknown#0000") { const toReturnPartial: IConfigAccessibleUser = { id: user.id, username: "Unknown", From e12f37bb6acafe6f58b1afb7c29bbe9316488c72 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 10:26:05 +0100 Subject: [PATCH 64/79] show created timestamp and sticker info on server info --- backend/src/plugins/Utility/functions/getServerInfoEmbed.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 13e0652f..753d4d7c 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -1,4 +1,4 @@ -import { CategoryChannel, MessageEmbedOptions, Snowflake, TextChannel, VoiceChannel } from "discord.js"; +import { CategoryChannel, MessageEmbedOptions, Snowflake, SnowflakeUtil, TextChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -50,7 +50,7 @@ export async function getServerInfoEmbed( // BASIC INFORMATION const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - const createdAt = moment.utc((guildPreview || restGuild)!.id, "x"); // FIXME ID -> Timestamp + const createdAt = moment.utc(SnowflakeUtil.deconstruct((guildPreview || restGuild)!.id).timestamp, "x"); const tzCreatedAt = requestMemberId ? await timeAndDate.inMemberTz(requestMemberId, createdAt) : timeAndDate.inGuildTz(createdAt); @@ -194,7 +194,7 @@ export async function getServerInfoEmbed( }[restGuild.premiumTier] || 0; otherStats.push(`Emojis: **${restGuild.emojis.cache.size}** / ${maxEmojis * 2}`); - otherStats.push(`Stickers: ? / ${maxStickers}`); // Wait on DJS: **${restGuild.stickers.cache.size}** + otherStats.push(`Stickers: **${restGuild.stickers.cache.size}** / ${maxStickers}`); } else { otherStats.push(`Emojis: **${guildPreview!.emojis.size}**`); // otherStats.push(`Stickers: **${guildPreview!.stickers.size}**`); Wait on DJS From f4b4747d086bd831f8d9c20384e953f32ab39e71 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 10:47:47 +0100 Subject: [PATCH 65/79] simplified --- backend/src/plugins/Utility/functions/getUserInfoEmbed.ts | 4 ++-- backend/src/plugins/Utility/search.ts | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 4f87dabc..78970a0e 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -103,7 +103,7 @@ export async function getUserInfoEmbed( }); const roles = member.roles.cache .map(role => pluginData.guild.roles.cache.get(role.id)) - .filter(r => r != null) as Role[]; + .filter((r): r is Role => !!r); roles.sort(sorter("position", "DESC")); embed.fields.push({ @@ -119,7 +119,7 @@ export async function getUserInfoEmbed( embed.fields.push({ name: preEmbedPadding + "Voice information", value: trimLines(` - ${voiceChannel ? `Current voice channel: **${voiceChannel ? voiceChannel.name : "None"}**` : ""} + ${voiceChannel ? `Current voice channel: **${voiceChannel.name ?? "None"}**` : ""} ${member.voice.mute ? "Server voice muted: **Yes**" : ""} ${member.voice.deaf ? "Server voice deafened: **Yes**" : ""} `), diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 45f77cd4..788eadc7 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -177,17 +177,11 @@ export async function displaySearch( .setEmoji("⬅") .setCustomId(`previousButton:${idMod}`) .setDisabled(currentPage === 1), - ); - - buttons.push( new MessageButton() .setStyle("SECONDARY") .setEmoji("➡") .setCustomId(`nextButton:${idMod}`) .setDisabled(currentPage === searchResult.lastPage), - ); - - buttons.push( new MessageButton() .setStyle("SECONDARY") .setEmoji("🔄") @@ -325,7 +319,7 @@ async function performMemberSearch( } if (args.voice) { - matchingMembers = matchingMembers.filter(m => m.voice.channelId != null); + matchingMembers = matchingMembers.filter(m => m.voice.channelId); } if (args.bot) { From afab564628b28ec4ab59a0b0fad3df6847cacff4 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 13:00:32 +0100 Subject: [PATCH 66/79] remove camelcase permission stuff --- backend/src/utils/getPermissionNames.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/backend/src/utils/getPermissionNames.ts b/backend/src/utils/getPermissionNames.ts index 47202c96..bc05ee64 100644 --- a/backend/src/utils/getPermissionNames.ts +++ b/backend/src/utils/getPermissionNames.ts @@ -1,18 +1,11 @@ import { Permissions } from "discord.js"; -const camelCaseToTitleCase = str => - str - .replace(/([a-z])([A-Z])/g, "$1 $2") - .split(" ") - .map(w => w[0].toUpperCase() + w.slice(1)) - .join(" "); - const permissionNumberToName: Map = new Map(); const ignoredPermissionConstants = ["all", "allGuild", "allText", "allVoice"]; for (const key in Permissions.FLAGS) { if (ignoredPermissionConstants.includes(key)) continue; - permissionNumberToName.set(BigInt(Permissions.FLAGS[key]), camelCaseToTitleCase(key)); + permissionNumberToName.set(BigInt(Permissions.FLAGS[key]), key); } /** From 71cc3176f683a7cead6d346ffd14a7a2bb920d95 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 13:14:45 +0100 Subject: [PATCH 67/79] Use SnowflakeUtil.deconstruct --- backend/src/utils/idToTimestamp.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/backend/src/utils/idToTimestamp.ts b/backend/src/utils/idToTimestamp.ts index 62dd4743..10b964a5 100644 --- a/backend/src/utils/idToTimestamp.ts +++ b/backend/src/utils/idToTimestamp.ts @@ -1,10 +1,6 @@ -import moment from "moment"; - -const EPOCH = 1420070400000; +import { Snowflake, SnowflakeUtil } from "discord.js"; export function idToTimestamp(id: string) { if (typeof id === "number") return null; - return moment(+id / 4194304 + EPOCH) - .utc() - .valueOf(); + return SnowflakeUtil.deconstruct(id as Snowflake).timestamp; } From 72893e7f7d441157be89e83034df863955644570 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 16:34:11 +0100 Subject: [PATCH 68/79] fix autojoin threads --- backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts index 84c36768..7dddcedf 100644 --- a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts +++ b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts @@ -16,7 +16,7 @@ export const AutoJoinThreadSyncEvt = utilityEvt({ async listener(meta) { const config = meta.pluginData.config.get(); - if (config.autojoin_threads) return; + if (!config.autojoin_threads) return; for (const thread of meta.args.threads.values()) { if (!thread.joined && thread.joinable) { await thread.join(); From 35bf6e5b82a1b2ee3c7ce36c7b017e2308efc68a Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 16:36:00 +0100 Subject: [PATCH 69/79] use idToTimestamp method --- backend/src/plugins/Utility/functions/getServerInfoEmbed.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 753d4d7c..89e601fe 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -1,4 +1,4 @@ -import { CategoryChannel, MessageEmbedOptions, Snowflake, SnowflakeUtil, TextChannel, VoiceChannel } from "discord.js"; +import { CategoryChannel, MessageEmbedOptions, Snowflake, TextChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -13,6 +13,7 @@ import { resolveUser, trimLines, } from "../../../utils"; +import { idToTimestamp } from "../../../utils/idToTimestamp"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; import { getGuildPreview } from "./getGuildPreview"; @@ -50,7 +51,7 @@ export async function getServerInfoEmbed( // BASIC INFORMATION const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - const createdAt = moment.utc(SnowflakeUtil.deconstruct((guildPreview || restGuild)!.id).timestamp, "x"); + const createdAt = moment.utc(idToTimestamp((guildPreview || restGuild)!.id)!, "x"); const tzCreatedAt = requestMemberId ? await timeAndDate.inMemberTz(requestMemberId, createdAt) : timeAndDate.inGuildTz(createdAt); From 5fad488a635b0045d5d8cf2c1bcfb7175f02cb37 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 17:18:49 +0100 Subject: [PATCH 70/79] changes to serverinfo and fixes in utils --- .../Utility/functions/getServerInfoEmbed.ts | 20 +++++++++---------- backend/src/utils.ts | 11 +++++----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 89e601fe..a0922399 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -1,7 +1,8 @@ -import { CategoryChannel, MessageEmbedOptions, Snowflake, TextChannel, VoiceChannel } from "discord.js"; +import { MessageEmbedOptions, Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; +import { ChannelTypeStrings } from "../../../types"; import { EmbedWith, formatNumber, @@ -82,12 +83,11 @@ export async function getServerInfoEmbed( }); // IMAGE LINKS - const iconUrl = `[Link](${(restGuild || guildPreview)!.iconURL()})`; - const bannerUrl = restGuild?.bannerURL() ? `[Link](${restGuild.bannerURL()})` : "None"; - const splashUrl = - (restGuild || guildPreview)!.splashURL() != null - ? `[Link](${(restGuild || guildPreview)!.splashURL()?.replace("size=128", "size=2048")})` - : "None"; + const iconUrl = `[Link](${(restGuild || guildPreview)!.iconURL({ dynamic: true, format: "png", size: 2048 })})`; + const bannerUrl = restGuild?.banner ? `[Link](${restGuild.bannerURL({ format: "png", size: 2048 })})` : "None"; + const splashUrl = (restGuild || guildPreview)!.splash + ? `[Link](${(restGuild || guildPreview)!.splashURL({ format: "png", size: 2048 })})` + : "None"; embed.fields.push( { @@ -155,9 +155,9 @@ export async function getServerInfoEmbed( // CHANNEL COUNTS if (thisServer) { const totalChannels = thisServer.channels.cache.size; - const categories = thisServer.channels.cache.filter(channel => channel instanceof CategoryChannel); - const textChannels = thisServer.channels.cache.filter(channel => channel instanceof TextChannel); - const voiceChannels = thisServer.channels.cache.filter(channel => channel instanceof VoiceChannel); + const categories = thisServer.channels.cache.filter(channel => channel.type === ChannelTypeStrings.CATEGORY); + const textChannels = thisServer.channels.cache.filter(channel => channel.type === ChannelTypeStrings.TEXT); + const voiceChannels = thisServer.channels.cache.filter(channel => channel.type === ChannelTypeStrings.VOICE); embed.fields.push({ name: preEmbedPadding + "Channels", diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 350fd830..a2ea3005 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1282,7 +1282,7 @@ export async function resolveRoleId(bot: Client, guildId: string, value: string) } // Role name - const roleList = await (await bot.guilds.fetch(guildId as Snowflake)).roles.cache; + const roleList = (await bot.guilds.fetch(guildId as Snowflake)).roles.cache; const role = roleList.filter(x => x.name.toLocaleLowerCase() === value.toLocaleLowerCase()); if (role[0]) { return role[0].id; @@ -1310,7 +1310,6 @@ export async function resolveInvite( return inviteCache.get(key) as ResolveInviteReturnType; } - // @ts-ignore: the getInvite() withCounts typings are blergh const promise = client.fetchInvite(code).catch(() => null); inviteCache.set(key, promise); @@ -1319,12 +1318,14 @@ export async function resolveInvite( const internalStickerCache: LimitedCollection = new LimitedCollection(500); -export async function resolveStickerId(bot: Client, id: Snowflake): Promise { +export async function resolveStickerId(bot: Client, id: Snowflake): Promise { const cachedSticker = internalStickerCache.get(id); if (cachedSticker) return cachedSticker; - const fetchedSticker = await bot.fetchSticker(id).catch(undefined); - internalStickerCache.set(id, fetchedSticker); + const fetchedSticker = await bot.fetchSticker(id).catch(() => null); + if (fetchedSticker) { + internalStickerCache.set(id, fetchedSticker); + } return fetchedSticker; } From 5e91a9fed361885d559a2ba3e7dc67953a3ac6be Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 17:24:53 +0100 Subject: [PATCH 71/79] removed unnecessary collector filters --- backend/src/plugins/Mutes/commands/MutesCmd.ts | 6 +----- backend/src/plugins/Utility/search.ts | 3 +-- backend/src/utils/waitForInteraction.ts | 3 +-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 5de51a3d..99356e54 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -214,11 +214,7 @@ export const MutesCmd = mutesCmd({ const row = new MessageActionRow().addComponents(buttons); await listMessage.edit({ components: [row] }); - const filter = (iac: MessageComponentInteraction) => iac.message.id === listMessage.id; - const collector = listMessage.createMessageComponentCollector({ - filter, - time: stopCollectionDebounce, - }); + const collector = listMessage.createMessageComponentCollector({ time: stopCollectionDebounce }); collector.on("collect", async (interaction: MessageComponentInteraction) => { if (msg.author.id !== interaction.user.id) { diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 788eadc7..4717dd31 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -191,8 +191,7 @@ export async function displaySearch( const row = new MessageActionRow().addComponents(buttons); await searchMsg.edit({ content: result, components: [row] }); - const filter = (iac: MessageComponentInteraction) => iac.message.id === searchMsg.id; - const collector = searchMsg.createMessageComponentCollector({ filter, time: 2 * MINUTES }); + const collector = searchMsg.createMessageComponentCollector({ time: 2 * MINUTES }); collector.on("collect", async (interaction: MessageComponentInteraction) => { if (msg.author.id !== interaction.user.id) { diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index f984cdd4..afc3641f 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -22,8 +22,7 @@ export async function waitForButtonConfirm( ]); const message = await channel.send({ ...toPost, components: [row] }); - const filter = (iac: MessageComponentInteraction) => iac.message.id === message.id; - const collector = message.createMessageComponentCollector({ filter, time: 10000 }); + const collector = message.createMessageComponentCollector({ time: 10000 }); collector.on("collect", (interaction: MessageComponentInteraction) => { if (options?.restrictToId && options.restrictToId !== interaction.user.id) { From 5de35f711d7b83e74f8aa4ecc66b22380b660ec3 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 17:35:27 +0100 Subject: [PATCH 72/79] use Util methods for escaping inline code and code blocks --- backend/src/commandTypes.ts | 18 ++++++++--------- .../Automod/triggers/matchAttachmentType.ts | 6 +++--- .../plugins/Automod/triggers/matchLinks.ts | 5 +++-- .../plugins/Automod/triggers/matchRegex.ts | 4 ++-- .../plugins/Automod/triggers/matchWords.ts | 4 ++-- backend/src/plugins/Logs/LogsPlugin.ts | 4 ++-- .../Post/commands/ScheduledPostsListCmd.ts | 14 ++++--------- .../Slowmode/commands/SlowmodeClearCmd.ts | 5 +++-- .../Slowmode/commands/SlowmodeSetCmd.ts | 6 +++--- .../TimeAndDate/commands/SetTimezoneCmd.ts | 5 +++-- backend/src/utils.ts | 20 +++---------------- 11 files changed, 36 insertions(+), 55 deletions(-) diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index 29a69d11..e3f1ece3 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -1,11 +1,9 @@ -import { GuildChannel, GuildMember, Snowflake, User } from "discord.js"; +import { GuildChannel, GuildMember, Snowflake, Util, User } from "discord.js"; import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub"; import { createTypeHelper } from "knub-command-manager"; import { channelMentionRegex, convertDelayStringToMS, - disableCodeBlocks, - disableInlineCode, isValidSnowflake, resolveMember, resolveUser, @@ -32,7 +30,7 @@ export const commandTypes = { async resolvedUser(value, context: CommandContext) { const result = await resolveUser(context.pluginData.client, value); if (result == null || result instanceof UnknownUser) { - throw new TypeConversionError(`User \`${disableCodeBlocks(value)}\` was not found`); + throw new TypeConversionError(`User \`${Util.escapeCodeBlock(value)}\` was not found`); } return result; }, @@ -40,7 +38,7 @@ export const commandTypes = { async resolvedUserLoose(value, context: CommandContext) { const result = await resolveUser(context.pluginData.client, value); if (result == null) { - throw new TypeConversionError(`Invalid user: \`${disableCodeBlocks(value)}\``); + throw new TypeConversionError(`Invalid user: \`${Util.escapeCodeBlock(value)}\``); } return result; }, @@ -53,7 +51,7 @@ export const commandTypes = { const result = await resolveMember(context.pluginData.client, context.message.channel.guild, value); if (result == null) { throw new TypeConversionError( - `Member \`${disableCodeBlocks(value)}\` was not found or they have left the server`, + `Member \`${Util.escapeCodeBlock(value)}\` was not found or they have left the server`, ); } return result; @@ -64,7 +62,7 @@ export const commandTypes = { const result = await resolveMessageTarget(context.pluginData, value); if (!result) { - throw new TypeConversionError(`Unknown message \`${disableInlineCode(value)}\``); + throw new TypeConversionError(`Unknown message \`${Util.escapeInlineCode(value)}\``); } return result; @@ -84,20 +82,20 @@ export const commandTypes = { return value as Snowflake; } - throw new TypeConversionError(`Could not parse ID: \`${disableInlineCode(value)}\``); + throw new TypeConversionError(`Could not parse ID: \`${Util.escapeInlineCode(value)}\``); }, regex(value: string, context: CommandContext): RegExp { try { return inputPatternToRegExp(value); } catch (e) { - throw new TypeConversionError(`Could not parse RegExp: \`${disableInlineCode(e.message)}\``); + throw new TypeConversionError(`Could not parse RegExp: \`${Util.escapeInlineCode(e.message)}\``); } }, timezone(value: string) { if (!isValidTimezone(value)) { - throw new TypeConversionError(`Invalid timezone: ${disableInlineCode(value)}`); + throw new TypeConversionError(`Invalid timezone: ${Util.escapeInlineCode(value)}`); } return value; diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index d69cc9a8..ba8e4e59 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -1,6 +1,6 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake, TextChannel, Util } from "discord.js"; import * as t from "io-ts"; -import { asSingleLine, disableInlineCode, messageSummary, verboseChannelMention } from "../../../utils"; +import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; interface MatchResultType { @@ -73,7 +73,7 @@ export const MatchAttachmentTypeTrigger = automodTrigger()({ return ( asSingleLine(` - Matched attachment type \`${disableInlineCode(matchResult.extra.matchedType)}\` + Matched attachment type \`${Util.escapeInlineCode(matchResult.extra.matchedType)}\` (${matchResult.extra.mode === "blacklist" ? "(blacklisted)" : "(not in whitelist)"}) in message (\`${contexts[0].message!.id}\`) in ${prettyChannel}: `) + messageSummary(contexts[0].message!) diff --git a/backend/src/plugins/Automod/triggers/matchLinks.ts b/backend/src/plugins/Automod/triggers/matchLinks.ts index 193a184c..2c70387c 100644 --- a/backend/src/plugins/Automod/triggers/matchLinks.ts +++ b/backend/src/plugins/Automod/triggers/matchLinks.ts @@ -1,7 +1,8 @@ +import { Util } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import * as t from "io-ts"; import { allowTimeout } from "../../../RegExpRunner"; -import { disableInlineCode, getUrlsInString, tNullable } from "../../../utils"; +import { getUrlsInString, tNullable } from "../../../utils"; import { TRegex } from "../../../validatorUtils"; import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; @@ -129,6 +130,6 @@ export const MatchLinksTrigger = automodTrigger()({ renderMatchInformation({ pluginData, contexts, matchResult }) { const partialSummary = getTextMatchPartialSummary(pluginData, matchResult.extra.type, contexts[0]); - return `Matched link \`${disableInlineCode(matchResult.extra.link)}\` in ${partialSummary}`; + return `Matched link \`${Util.escapeInlineCode(matchResult.extra.link)}\` in ${partialSummary}`; }, }); diff --git a/backend/src/plugins/Automod/triggers/matchRegex.ts b/backend/src/plugins/Automod/triggers/matchRegex.ts index 5d585f08..3e0b2e38 100644 --- a/backend/src/plugins/Automod/triggers/matchRegex.ts +++ b/backend/src/plugins/Automod/triggers/matchRegex.ts @@ -1,6 +1,6 @@ +import { Util } from "discord.js"; import * as t from "io-ts"; import { allowTimeout } from "../../../RegExpRunner"; -import { disableInlineCode } from "../../../utils"; import { normalizeText } from "../../../utils/normalizeText"; import { stripMarkdown } from "../../../utils/stripMarkdown"; import { TRegex } from "../../../validatorUtils"; @@ -72,6 +72,6 @@ export const MatchRegexTrigger = automodTrigger()({ renderMatchInformation({ pluginData, contexts, matchResult }) { const partialSummary = getTextMatchPartialSummary(pluginData, matchResult.extra.type, contexts[0]); - return `Matched regex \`${disableInlineCode(matchResult.extra.pattern)}\` in ${partialSummary}`; + return `Matched regex \`${Util.escapeInlineCode(matchResult.extra.pattern)}\` in ${partialSummary}`; }, }); diff --git a/backend/src/plugins/Automod/triggers/matchWords.ts b/backend/src/plugins/Automod/triggers/matchWords.ts index 2a011546..387f2208 100644 --- a/backend/src/plugins/Automod/triggers/matchWords.ts +++ b/backend/src/plugins/Automod/triggers/matchWords.ts @@ -1,6 +1,6 @@ +import { Util } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import * as t from "io-ts"; -import { disableInlineCode } from "../../../utils"; import { normalizeText } from "../../../utils/normalizeText"; import { stripMarkdown } from "../../../utils/stripMarkdown"; import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; @@ -89,6 +89,6 @@ export const MatchWordsTrigger = automodTrigger()({ renderMatchInformation({ pluginData, contexts, matchResult }) { const partialSummary = getTextMatchPartialSummary(pluginData, matchResult.extra.type, contexts[0]); - return `Matched word \`${disableInlineCode(matchResult.extra.word)}\` in ${partialSummary}`; + return `Matched word \`${Util.escapeInlineCode(matchResult.extra.word)}\` in ${partialSummary}`; }, }); diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index e61d0857..d4285de8 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -7,7 +7,6 @@ import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { LogType } from "../../data/LogType"; import { logger } from "../../logger"; import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { disableCodeBlocks } from "../../utils"; import { CasesPlugin } from "../Cases/CasesPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -37,6 +36,7 @@ import { log } from "./util/log"; import { onMessageDelete } from "./util/onMessageDelete"; import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk"; import { onMessageUpdate } from "./util/onMessageUpdate"; +import { Util } from "discord.js"; const defaultOptions: PluginOptions = { config: { @@ -147,7 +147,7 @@ export const LogsPlugin = zeppelinGuildPlugin()({ The following regex has taken longer than ${timeoutMs}ms for ${failedTimes} times and has been temporarily disabled: `.trim() + "\n```" + - disableCodeBlocks(regexSource) + + Util.escapeCodeBlock(regexSource) + "```", }); }; diff --git a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts index 65e76041..7ac59698 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts @@ -1,13 +1,7 @@ +import { Util } from "discord.js"; import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; -import { - createChunkedMessage, - DBDateFormat, - deactivateMentions, - disableCodeBlocks, - sorter, - trimLines, -} from "../../../utils"; +import { createChunkedMessage, DBDateFormat, deactivateMentions, sorter, trimLines } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { postCmd } from "../types"; @@ -33,7 +27,7 @@ export const ScheduledPostsListCmd = postCmd({ const isTruncated = previewText.length > SCHEDULED_POST_PREVIEW_TEXT_LENGTH; - previewText = disableCodeBlocks(deactivateMentions(previewText)) + previewText = Util.escapeCodeBlock(deactivateMentions(previewText)) .replace(/\s+/g, " ") .slice(0, SCHEDULED_POST_PREVIEW_TEXT_LENGTH); @@ -61,7 +55,7 @@ export const ScheduledPostsListCmd = postCmd({ const finalMessage = trimLines(` ${postLines.join("\n")} - + Use \`scheduled_posts \` to view a scheduled post in full Use \`scheduled_posts delete \` to delete a scheduled post `); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index 75835e6b..c9a31ddd 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -1,7 +1,8 @@ +import { Util } from "discord.js"; import { ChannelTypeStrings } from "src/types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { asSingleLine, disableInlineCode } from "../../../utils"; +import { asSingleLine } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { BOT_SLOWMODE_CLEAR_PERMISSIONS } from "../requiredPermissions"; @@ -57,7 +58,7 @@ export const SlowmodeClearCmd = slowmodeCmd({ msg.channel, asSingleLine(` Failed to clear slowmode from **${args.user.tag}** in <#${args.channel.id}>: - \`${disableInlineCode(e.message)}\` + \`${Util.escapeInlineCode(e.message)}\` `), ); return; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 22bc74d7..3b316c6f 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,9 +1,9 @@ -import { Permissions, TextChannel, ThreadChannel } from "discord.js"; +import { Permissions, TextChannel, ThreadChannel, Util } from "discord.js"; import humanizeDuration from "humanize-duration"; import { ChannelTypeStrings } from "src/types"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { asSingleLine, DAYS, disableInlineCode, HOURS, MINUTES } from "../../../utils"; +import { asSingleLine, DAYS, HOURS, MINUTES } from "../../../utils"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { BOT_SLOWMODE_PERMISSIONS, NATIVE_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; @@ -133,7 +133,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ rateLimitPerUser: rateLimitSeconds, }); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Failed to set native slowmode: ${disableInlineCode(e.message)}`); + sendErrorMessage(pluginData, msg.channel, `Failed to set native slowmode: ${Util.escapeInlineCode(e.message)}`); return; } } else { diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index 1786bd34..d88a0740 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -1,6 +1,7 @@ +import { Util } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { disableInlineCode, trimLines } from "../../../utils"; +import { trimLines } from "../../../utils"; import { parseFuzzyTimezone } from "../../../utils/parseFuzzyTimezone"; import { timeAndDateCmd } from "../types"; @@ -19,7 +20,7 @@ export const SetTimezoneCmd = timeAndDateCmd({ pluginData, message.channel, trimLines(` - Invalid timezone: \`${disableInlineCode(args.timezone)}\` + Invalid timezone: \`${Util.escapeInlineCode(args.timezone)}\` Zeppelin uses timezone locations rather than specific timezone names. See the **TZ database name** column at for a list of valid options. `), diff --git a/backend/src/utils.ts b/backend/src/utils.ts index a2ea3005..a3dcec39 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -22,6 +22,7 @@ import { TextChannel, ThreadChannel, User, + Util, } from "discord.js"; import emojiRegex from "emoji-regex"; import { either } from "fp-ts/lib/Either"; @@ -785,21 +786,6 @@ export function deactivateMentions(content: string): string { return content.replace(/@/g, "@\u200b"); } -/** - * Disable inline code in the given string by replacing backticks/grave accents with acute accents - * FIXME: Find a better way that keeps the grave accents? Can't use the code block approach here since it's just 1 character. - */ -export function disableInlineCode(content: string): string { - return content.replace(/`/g, "\u00b4"); -} - -/** - * Disable code blocks in the given string by adding invisible unicode characters between backticks - */ -export function disableCodeBlocks(content: string): string { - return content.replace(/`/g, "`\u200b"); -} - export function useMediaUrls(content: string): string { return content.replace(/cdn\.discord(app)?\.com/g, "media.discordapp.net"); } @@ -1336,11 +1322,11 @@ export async function confirm(channel: TextChannel, userId: string, content: Mes export function messageSummary(msg: SavedMessage) { // Regular text content - let result = "```\n" + (msg.data.content ? disableCodeBlocks(msg.data.content) : "") + "```"; + let result = "```\n" + (msg.data.content ? Util.escapeCodeBlock(msg.data.content) : "") + "```"; // Rich embed const richEmbed = (msg.data.embeds || []).find(e => (e as MessageEmbed).type === "rich"); - if (richEmbed) result += "Embed:```" + disableCodeBlocks(JSON.stringify(richEmbed)) + "```"; + if (richEmbed) result += "Embed:```" + Util.escapeCodeBlock(JSON.stringify(richEmbed)) + "```"; // Attachments if (msg.data.attachments) { From b5ea866e62ff6a3166576b7d7789f11e0d2a9410 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 29 Jul 2021 17:45:45 +0100 Subject: [PATCH 73/79] upgraded discord.js --- backend/package-lock.json | 14 +++++++------- backend/package.json | 2 +- .../plugins/Slowmode/commands/SlowmodeGetCmd.ts | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index ad535f14..bbc5e4e7 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.4886ae2.1627214570", + "discord.js": "^13.0.0-dev.d310e4f.1627560163", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -2159,9 +2159,9 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.4886ae2.1627214570", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.4886ae2.1627214570.tgz", - "integrity": "sha512-9eqVCQyqqSHJcR1nki9NlaTD7FjvfkjJt8zcmF5wcCs/7P9v27UrPYg9yxvghswDvDhz9ojotYGGcpK7tSypmA==", + "version": "13.0.0-dev.d310e4f.1627560163", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.d310e4f.1627560163.tgz", + "integrity": "sha512-qJmQrG4xCnBqYF/WQIOxl4IWY3gYAwK0UyNOAKhRpHzMXYHX99wx3FcGaYrZiqtXxGbN2lgVanBakKNsq/uYYw==", "dependencies": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", @@ -8034,9 +8034,9 @@ "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" }, "discord.js": { - "version": "13.0.0-dev.4886ae2.1627214570", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.4886ae2.1627214570.tgz", - "integrity": "sha512-9eqVCQyqqSHJcR1nki9NlaTD7FjvfkjJt8zcmF5wcCs/7P9v27UrPYg9yxvghswDvDhz9ojotYGGcpK7tSypmA==", + "version": "13.0.0-dev.d310e4f.1627560163", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.d310e4f.1627560163.tgz", + "integrity": "sha512-qJmQrG4xCnBqYF/WQIOxl4IWY3gYAwK0UyNOAKhRpHzMXYHX99wx3FcGaYrZiqtXxGbN2lgVanBakKNsq/uYYw==", "requires": { "@discordjs/builders": "^0.2.0", "@discordjs/collection": "^0.1.6", diff --git a/backend/package.json b/backend/package.json index 65ca54f0..8c917b27 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.4886ae2.1627214570", + "discord.js": "^13.0.0-dev.d310e4f.1627560163", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts index d3f743d0..e1302464 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts @@ -27,7 +27,7 @@ export const SlowmodeGetCmd = slowmodeCmd({ } if (currentSlowmode) { - const humanized = humanizeDuration(channel.rateLimitPerUser * 1000); + const humanized = humanizeDuration(currentSlowmode * 1000); const slowmodeType = isNative ? "native" : "bot-maintained"; msg.channel.send(`The current slowmode of <#${channel.id}> is **${humanized}** (${slowmodeType})`); } else { From 0053f55576f2fbc5d56247329d108b14d2356f85 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 29 Jul 2021 18:46:52 +0200 Subject: [PATCH 74/79] Fix role member counts, add threads to channel info command --- .../src/plugins/Utility/commands/RolesCmd.ts | 10 ++--- .../Utility/functions/getChannelInfoEmbed.ts | 45 ++++++++++++++----- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index 8aa7e85a..2aa3f459 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -34,13 +34,9 @@ export const RolesCmd = utilityCmd({ if (args.counts) { await refreshMembersIfNeeded(guild); - // If the user requested role member counts as well, calculate them and sort the roles by their member count - const roleCounts: Map = Array.from(guild.members.cache.values()).reduce((map, member) => { - for (const roleId of member.roles.cache) { - if (!map.has(roleId)) map.set(roleId, 0); - map.set(roleId, map.get(roleId) + 1); - } - + // If the user requested role member counts as well, fetch them and sort the roles by their member count + const roleCounts: Map = Array.from(guild.roles.cache.values()).reduce((map, role) => { + map.set(role.id, role.members.size); return map; }, new Map()); diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index fa2ea87d..c1dcc7d8 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -1,9 +1,9 @@ -import { MessageEmbedOptions, Snowflake, StageChannel, VoiceChannel } from "discord.js"; +import { MessageEmbedOptions, Snowflake, StageChannel, ThreadChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { ChannelTypeStrings } from "src/types"; -import { EmbedWith, formatNumber, preEmbedPadding, trimLines } from "../../../utils"; +import { EmbedWith, formatNumber, MINUTES, preEmbedPadding, trimLines, verboseUserMention } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; @@ -15,6 +15,10 @@ const ANNOUNCEMENT_CHANNEL_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740656841687564348/announcement-channel.png"; const STAGE_CHANNEL_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/839930647711186995/stage-channel.png"; +const PUBLIC_THREAD_ICON = + "https://cdn.discordapp.com/attachments/740650744830623756/870343055855738921/public-thread.png"; +const PRIVATE_THREAD_UCON = + "https://cdn.discordapp.com/attachments/740650744830623756/870343402447839242/private-thread.png"; export async function getChannelInfoEmbed( pluginData: GuildPluginData, @@ -30,14 +34,14 @@ export async function getChannelInfoEmbed( fields: [], }; - let icon = TEXT_CHANNEL_ICON; - if (channel.type === ChannelTypeStrings.VOICE) { - icon = VOICE_CHANNEL_ICON; - } else if (channel.type === ChannelTypeStrings.NEWS) { - icon = ANNOUNCEMENT_CHANNEL_ICON; - } else if (channel.type === ChannelTypeStrings.STAGE) { - icon = STAGE_CHANNEL_ICON; - } + const icon = + { + [ChannelTypeStrings.VOICE]: VOICE_CHANNEL_ICON, + [ChannelTypeStrings.NEWS]: ANNOUNCEMENT_CHANNEL_ICON, + [ChannelTypeStrings.STAGE]: STAGE_CHANNEL_ICON, + [ChannelTypeStrings.PUBLIC_THREAD]: PUBLIC_THREAD_ICON, + [ChannelTypeStrings.PRIVATE_THREAD]: PRIVATE_THREAD_UCON, + }[channel.type] || TEXT_CHANNEL_ICON; const channelType = { @@ -47,6 +51,9 @@ export async function getChannelInfoEmbed( [ChannelTypeStrings.NEWS]: "Announcement channel", [ChannelTypeStrings.STORE]: "Store channel", [ChannelTypeStrings.STAGE]: "Stage channel", + [ChannelTypeStrings.PUBLIC_THREAD]: "Public Thread channel", + [ChannelTypeStrings.PRIVATE_THREAD]: "Private Thread channel", + [ChannelTypeStrings.NEWS_THREAD]: "News Thread channel", }[channel.type] || "Channel"; embed.author = { @@ -121,5 +128,23 @@ export async function getChannelInfoEmbed( }); } + if (channel.type === ChannelTypeStrings.PRIVATE_THREAD || channel.type === ChannelTypeStrings.PUBLIC_THREAD) { + const thread = channel as ThreadChannel; + const parentChannelName = thread.parent?.name ? thread.parent.name : `<#${thread.parentId}>`; + const memberCount = thread.memberCount ?? thread.members.cache.size; + const owner = await pluginData.guild.members.fetch(thread.ownerId).catch(() => null); + const ownerMention = owner ? verboseUserMention(owner.user) : "Unknown#0000"; + const humanizedArchiveTime = `Archive duration: **${humanizeDuration(thread.autoArchiveDuration * MINUTES)}**`; + + embed.fields.push({ + name: preEmbedPadding + "Thread information", + value: trimLines(` + Parent channel: **#${parentChannelName}** + Member count: **${memberCount}** + Thread creator: ${ownerMention} + ${thread.archived ? "Archived: **True**" : humanizedArchiveTime}`), + }); + } + return embed; } From 036d46f08a613408a5e500acda553cd498ae7a2a Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Thu, 29 Jul 2021 19:08:22 +0200 Subject: [PATCH 75/79] Fix log bugs --- backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts | 4 ++-- backend/src/utils/configAccessibleObjects.ts | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index 727fa160..935c7847 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -17,13 +17,13 @@ export const LogsVoiceStateUpdateEvt = logsEvt({ // Leave evt meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_LEAVE, { member: memberToConfigAccessibleMember(member), - oldChannel: channelToConfigAccessibleChannel(oldChannel!), + channel: channelToConfigAccessibleChannel(oldChannel!), }); } else if (!oldChannel && newChannel) { // Join Evt meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_JOIN, { member: memberToConfigAccessibleMember(member), - newChannel: channelToConfigAccessibleChannel(newChannel), + channel: channelToConfigAccessibleChannel(newChannel), }); } else { meta.pluginData.state.guildLogs.log(LogType.VOICE_CHANNEL_MOVE, { diff --git a/backend/src/utils/configAccessibleObjects.ts b/backend/src/utils/configAccessibleObjects.ts index 379aaea0..5904e48d 100644 --- a/backend/src/utils/configAccessibleObjects.ts +++ b/backend/src/utils/configAccessibleObjects.ts @@ -17,6 +17,7 @@ export interface IConfigAccessibleUser { username: string; discriminator: string; mention: string; + tag: string; avatarURL?: string; bot?: boolean; createdAt?: number; @@ -46,6 +47,7 @@ export function userToConfigAccessibleUser(user: User | UnknownUser): IConfigAcc username: "Unknown", discriminator: "0000", mention: `<@${user.id}>`, + tag: "Unknown#0000", }; return toReturnPartial; @@ -57,6 +59,7 @@ export function userToConfigAccessibleUser(user: User | UnknownUser): IConfigAcc username: properUser.username, discriminator: properUser.discriminator, mention: `<@${properUser.id}>`, + tag: properUser.tag, avatarURL: properUser.displayAvatarURL({ dynamic: true }), bot: properUser.bot, createdAt: properUser.createdTimestamp, From 3537305c59b00904d688e14fa824c5a65f640b41 Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 4 Aug 2021 20:45:42 +0100 Subject: [PATCH 76/79] upgrade discord.js --- backend/package-lock.json | 236 +++++++++++++----- backend/package.json | 2 +- backend/src/data/GuildSavedMessages.ts | 4 +- .../src/plugins/Automod/actions/addRoles.ts | 2 +- .../plugins/Automod/actions/removeRoles.ts | 2 +- .../CustomEvents/actions/addRoleAction.ts | 2 +- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 4 +- .../MessageSaver/commands/SavePinsToDB.ts | 2 +- .../plugins/ModActions/commands/AddCaseCmd.ts | 2 +- .../src/plugins/ModActions/commands/BanCmd.ts | 2 +- .../ModActions/commands/ForcebanCmd.ts | 2 +- .../plugins/ModActions/commands/MassBanCmd.ts | 2 +- .../ModActions/commands/MassUnbanCmd.ts | 2 +- .../ModActions/commands/MassmuteCmd.ts | 2 +- .../plugins/ModActions/commands/NoteCmd.ts | 2 +- .../plugins/ModActions/commands/UnbanCmd.ts | 2 +- .../plugins/ModActions/commands/WarnCmd.ts | 2 +- .../ModActions/functions/actualMuteUserCmd.ts | 2 +- .../functions/actualUnmuteUserCmd.ts | 2 +- .../ModActions/functions/updateCase.ts | 2 +- .../Mutes/functions/clearExpiredMutes.ts | 2 +- .../src/plugins/Mutes/functions/muteUser.ts | 2 +- .../src/plugins/Mutes/functions/unmuteUser.ts | 2 +- .../src/plugins/Post/util/actualPostCmd.ts | 4 +- .../util/addMemberPendingRoleChange.ts | 2 +- .../Starboard/commands/MigratePinsCmd.ts | 2 +- .../src/plugins/Utility/commands/CleanCmd.ts | 12 +- .../Utility/commands/VcdisconnectCmd.ts | 2 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 17 +- .../Utility/functions/getChannelInfoEmbed.ts | 10 +- backend/src/utils.ts | 4 +- backend/src/utils/configAccessibleObjects.ts | 2 +- 32 files changed, 232 insertions(+), 107 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index bbc5e4e7..e0744d93 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,7 +14,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.d310e4f.1627560163", + "discord.js": "^13.0.0-dev.t1628078860.90c2e07", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -81,8 +81,8 @@ "version": "30.0.0-beta.38", "license": "MIT", "dependencies": { - "discord-api-types": "^0.21.0-next.ab1951b.1626870574", - "discord.js": "^13.0.0-dev.4886ae2.1627214570", + "discord-api-types": "^0.18.1", + "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -161,11 +161,14 @@ } }, "node_modules/@discordjs/builders": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.2.0.tgz", - "integrity": "sha512-TVq7NZBCJrrTRc3CfxOr3IdgY5nrtqVxZ7qDUF1mN6LgxIiOldmFxsSwMrQBzLFVmOwqFyNLKCeblley8UpEuw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.3.0.tgz", + "integrity": "sha512-yFBPqohVAtCWoDTQCYk5ubgmkiRbGpbiR4RfYGHCmV5S2YZc7j8WzfKVksjuy2o5IWRfXFsW6G2Lr+KpW41pEA==", "dependencies": { - "discord-api-types": "^0.18.1", + "@sindresorhus/is": "^4.0.1", + "discord-api-types": "^0.22.0", + "ow": "^0.26.0", + "ts-mixer": "^5.4.1", "tslib": "^2.3.0" }, "engines": { @@ -173,15 +176,29 @@ "npm": ">=7.0.0" } }, + "node_modules/@discordjs/builders/node_modules/@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@discordjs/builders/node_modules/tslib": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" }, "node_modules/@discordjs/collection": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", - "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", + "integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==", + "engines": { + "node": ">=14.0.0" + } }, "node_modules/@discordjs/form-data": { "version": "3.0.1", @@ -1389,7 +1406,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -2151,41 +2167,33 @@ } }, "node_modules/discord-api-types": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.18.1.tgz", - "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==", + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", + "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==", "engines": { "node": ">=12" } }, "node_modules/discord.js": { - "version": "13.0.0-dev.d310e4f.1627560163", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.d310e4f.1627560163.tgz", - "integrity": "sha512-qJmQrG4xCnBqYF/WQIOxl4IWY3gYAwK0UyNOAKhRpHzMXYHX99wx3FcGaYrZiqtXxGbN2lgVanBakKNsq/uYYw==", + "version": "13.0.0-dev.t1628078860.90c2e07", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.t1628078860.90c2e07.tgz", + "integrity": "sha512-Yet0FjFizVzCZkV2+cxenTh6Y2CzNWnA9BK12gmifSa6GuUJ0o98ptx5jpo+jpaXpwkKooivOCNl3wrulupmzg==", "dependencies": { - "@discordjs/builders": "^0.2.0", - "@discordjs/collection": "^0.1.6", + "@discordjs/builders": "^0.3.0", + "@discordjs/collection": "^0.2.1", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", "@types/ws": "^7.4.5", "abort-controller": "^3.0.0", - "discord-api-types": "^0.19.0", + "discord-api-types": "^0.22.0", "node-fetch": "^2.6.1", "ws": "^7.5.1" }, "engines": { - "node": ">=14.0.0", + "node": ">=14.6.0", "npm": ">=7.0.0" } }, - "node_modules/discord.js/node_modules/discord-api-types": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0.tgz", - "integrity": "sha512-t2HKLd43Lbe+rf+ffYfKVv9Kk5f6p7sFqvO6CMV55ZB0PgZv8WigCkt9FoJciYo5S3Q6CGYK+WnE/ZG+6vkBDQ==", - "engines": { - "node": ">=12" - } - }, "node_modules/dot-prop": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", @@ -2277,6 +2285,7 @@ "version": "0.1.3", "resolved": "git+ssh://git@github.com/discord/erlpack.git#e27db8f82892bdb9b28a0547cc394d68b5d2242d", "integrity": "sha512-uDE+ma9xOMfF4ncJHoymBWA084DqoO8q/hBDvGx4WUxmvFQfHoCsk3BYk1D1Lei/lhNCZXLf1vkeNYVBSqrSgw==", + "hasInstallScript": true, "license": "MIT", "dependencies": { "bindings": "^1.5.0", @@ -3106,7 +3115,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, "engines": { "node": ">=8" } @@ -3961,6 +3969,61 @@ "node": ">=0.10.0" } }, + "node_modules/ow": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/ow/-/ow-0.26.0.tgz", + "integrity": "sha512-22YUQW9d6oUSCpIQuBV25djtC1uMtpWqmtUYnuh2UHWeNMpppCFCvq3eSBIWWMDbe2UVq26kWYvBHDzOIu5NYg==", + "dependencies": { + "@sindresorhus/is": "^4.0.1", + "callsites": "^3.1.0", + "dot-prop": "^6.0.1", + "lodash.isequal": "^4.5.0", + "type-fest": "^1.2.1", + "vali-date": "^1.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ow/node_modules/@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/ow/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/ow/node_modules/type-fest": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.3.0.tgz", + "integrity": "sha512-mYUYkAy6fPatVWtUeCV/qGeGL3IVucmdJOzeAEfwgCJDx8gP0JaW8jn6KQ5xDfPec31e0KXWn5EUOZMhquR1zA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -5428,6 +5491,11 @@ "node": ">=0.10.0" } }, + "node_modules/ts-mixer": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", + "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA==" + }, "node_modules/tsc-watch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-4.0.0.tgz", @@ -5903,6 +5971,14 @@ "uuid": "bin/uuid" } }, + "node_modules/vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -6437,14 +6513,22 @@ } }, "@discordjs/builders": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.2.0.tgz", - "integrity": "sha512-TVq7NZBCJrrTRc3CfxOr3IdgY5nrtqVxZ7qDUF1mN6LgxIiOldmFxsSwMrQBzLFVmOwqFyNLKCeblley8UpEuw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.3.0.tgz", + "integrity": "sha512-yFBPqohVAtCWoDTQCYk5ubgmkiRbGpbiR4RfYGHCmV5S2YZc7j8WzfKVksjuy2o5IWRfXFsW6G2Lr+KpW41pEA==", "requires": { - "discord-api-types": "^0.18.1", + "@sindresorhus/is": "^4.0.1", + "discord-api-types": "^0.22.0", + "ow": "^0.26.0", + "ts-mixer": "^5.4.1", "tslib": "^2.3.0" }, "dependencies": { + "@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" + }, "tslib": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", @@ -6453,9 +6537,9 @@ } }, "@discordjs/collection": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.6.tgz", - "integrity": "sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ==" + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz", + "integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==" }, "@discordjs/form-data": { "version": "3.0.1", @@ -7442,8 +7526,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { "version": "5.3.1", @@ -8029,31 +8112,24 @@ } }, "discord-api-types": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.18.1.tgz", - "integrity": "sha512-hNC38R9ZF4uaujaZQtQfm5CdQO58uhdkoHQAVvMfIL0LgOSZeW575W8H6upngQOuoxWd8tiRII3LLJm9zuQKYg==" + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz", + "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==" }, "discord.js": { - "version": "13.0.0-dev.d310e4f.1627560163", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.d310e4f.1627560163.tgz", - "integrity": "sha512-qJmQrG4xCnBqYF/WQIOxl4IWY3gYAwK0UyNOAKhRpHzMXYHX99wx3FcGaYrZiqtXxGbN2lgVanBakKNsq/uYYw==", + "version": "13.0.0-dev.t1628078860.90c2e07", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.t1628078860.90c2e07.tgz", + "integrity": "sha512-Yet0FjFizVzCZkV2+cxenTh6Y2CzNWnA9BK12gmifSa6GuUJ0o98ptx5jpo+jpaXpwkKooivOCNl3wrulupmzg==", "requires": { - "@discordjs/builders": "^0.2.0", - "@discordjs/collection": "^0.1.6", + "@discordjs/builders": "^0.3.0", + "@discordjs/collection": "^0.2.1", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", "@types/ws": "^7.4.5", "abort-controller": "^3.0.0", - "discord-api-types": "^0.19.0", + "discord-api-types": "^0.22.0", "node-fetch": "^2.6.1", "ws": "^7.5.1" - }, - "dependencies": { - "discord-api-types": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.19.0.tgz", - "integrity": "sha512-t2HKLd43Lbe+rf+ffYfKVv9Kk5f6p7sFqvO6CMV55ZB0PgZv8WigCkt9FoJciYo5S3Q6CGYK+WnE/ZG+6vkBDQ==" - } } }, "dot-prop": { @@ -8760,8 +8836,7 @@ "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, "is-path-cwd": { "version": "2.2.0", @@ -8877,8 +8952,8 @@ "@typescript-eslint/eslint-plugin": "^4.23.0", "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", - "discord-api-types": "^0.21.0-next.ab1951b.1626870574", - "discord.js": "^13.0.0-dev.4886ae2.1627214570", + "discord-api-types": "^0.18.1", + "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", @@ -9462,6 +9537,39 @@ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, + "ow": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/ow/-/ow-0.26.0.tgz", + "integrity": "sha512-22YUQW9d6oUSCpIQuBV25djtC1uMtpWqmtUYnuh2UHWeNMpppCFCvq3eSBIWWMDbe2UVq26kWYvBHDzOIu5NYg==", + "requires": { + "@sindresorhus/is": "^4.0.1", + "callsites": "^3.1.0", + "dot-prop": "^6.0.1", + "lodash.isequal": "^4.5.0", + "type-fest": "^1.2.1", + "vali-date": "^1.0.0" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", + "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" + }, + "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" + } + }, + "type-fest": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.3.0.tgz", + "integrity": "sha512-mYUYkAy6fPatVWtUeCV/qGeGL3IVucmdJOzeAEfwgCJDx8gP0JaW8jn6KQ5xDfPec31e0KXWn5EUOZMhquR1zA==" + } + } + }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -10623,6 +10731,11 @@ "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, + "ts-mixer": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", + "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA==" + }, "tsc-watch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-4.0.0.tgz", @@ -10976,6 +11089,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, + "vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=" + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/backend/package.json b/backend/package.json index 8c917b27..d9c76424 100644 --- a/backend/package.json +++ b/backend/package.json @@ -29,7 +29,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.d310e4f.1627560163", + "discord.js": "^13.0.0-dev.t1628078860.90c2e07", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index 7fbcb120..ff4daf7f 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -45,9 +45,9 @@ export class GuildSavedMessages extends BaseGuildRepository { timestamp: msg.createdTimestamp, }; - if (msg.attachments.size) data.attachments = msg.attachments.array(); + if (msg.attachments.size) data.attachments = [...msg.attachments.values()]; if (msg.embeds.length) data.embeds = msg.embeds; - if (msg.stickers?.size) data.stickers = msg.stickers.array(); + if (msg.stickers?.size) data.stickers = [...msg.stickers.values()]; return data; } diff --git a/backend/src/plugins/Automod/actions/addRoles.ts b/backend/src/plugins/Automod/actions/addRoles.ts index e87a2cc2..91a12bca 100644 --- a/backend/src/plugins/Automod/actions/addRoles.ts +++ b/backend/src/plugins/Automod/actions/addRoles.ts @@ -53,7 +53,7 @@ export const AddRolesAction = automodAction({ await Promise.all( members.map(async member => { - const memberRoles = new Set(member.roles.cache.keyArray()); + const memberRoles = new Set(member.roles.cache.keys()); for (const roleId of rolesToAssign) { memberRoles.add(roleId as Snowflake); ignoreRoleChange(pluginData, member.id, roleId); diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index 54ce11f1..0e125fb7 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -54,7 +54,7 @@ export const RemoveRolesAction = automodAction({ await Promise.all( members.map(async member => { - const memberRoles = new Set(member.roles.cache.keyArray()); + const memberRoles = new Set(member.roles.cache.keys()); for (const roleId of rolesToRemove) { memberRoles.delete(roleId as Snowflake); ignoreRoleChange(pluginData, member.id, roleId); diff --git a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts index d4f1b61a..6621763d 100644 --- a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts +++ b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts @@ -31,6 +31,6 @@ export async function addRoleAction( const rolesToAdd = Array.isArray(action.role) ? action.role : [action.role]; await target.edit({ - roles: Array.from(new Set([...target.roles.cache.array(), ...rolesToAdd])) as Snowflake[], + roles: Array.from(new Set([...target.roles.cache.values(), ...rolesToAdd])) as Snowflake[], }); } diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index 1f37a360..a5f7e9c7 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -27,8 +27,8 @@ export const LogsGuildMemberUpdateEvt = logsEvt({ } if (!isEqual(oldMember.roles, member.roles)) { - const addedRoles = diff(member.roles.cache.keyArray(), oldMember.roles.cache.keyArray()); - const removedRoles = diff(oldMember.roles.cache.keyArray(), member.roles.cache.keyArray()); + const addedRoles = diff([...member.roles.cache.keys()], [...oldMember.roles.cache.keys()]); + const removedRoles = diff([...oldMember.roles.cache.keys()], [...member.roles.cache.keys()]); let skip = false; if ( diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index ede884d6..e81c73fe 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -16,7 +16,7 @@ export const SavePinsToDBCmd = messageSaverCmd({ await msg.channel.send(`Saving pins from <#${args.channel.id}>...`); const pins = await args.channel.messages.fetchPinned(); - const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, pins.keyArray()); + const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, [...pins.keys()]); if (failed.length) { sendSuccessMessage( diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts index f23d9500..dd968c76 100644 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts @@ -60,7 +60,7 @@ export const AddCaseCmd = modActionsCmd({ return; } - const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); + const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); // Create the case const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index 8a40da77..6437a5e9 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -51,7 +51,7 @@ export const BanCmd = modActionsCmd({ } const time = args["time"] ? args["time"] : null; - const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); + const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id); // The moderator who did the action is the message author or, if used, the specified -mod let mod = msg.member; diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index 67df9ece..8a1df43e 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -61,7 +61,7 @@ export const ForcebanCmd = modActionsCmd({ mod = args.mod; } - const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); + const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); ignoreEvent(pluginData, IgnoredEventType.Ban, user.id); pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, user.id); diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 7e61bb48..e4e4fd44 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -39,7 +39,7 @@ export const MassbanCmd = modActionsCmd({ return; } - const banReason = formatReasonWithAttachments(banReasonReply.content, msg.attachments.array()); + const banReason = formatReasonWithAttachments(banReasonReply.content, [...msg.attachments.values()]); // Verify we can act on each of the users specified for (const userId of args.userIds) { diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index 1141c26c..ea5e5770 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -37,7 +37,7 @@ export const MassunbanCmd = modActionsCmd({ return; } - const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, msg.attachments.array()); + const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, [...msg.attachments.values()]); // Ignore automatic unban cases and logs for these users // We'll create our own cases below and post a single "mass unbanned" log instead diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index 9f87ed81..5c82dd5b 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -39,7 +39,7 @@ export const MassmuteCmd = modActionsCmd({ return; } - const muteReason = formatReasonWithAttachments(muteReasonReceived.content, msg.attachments.array()); + const muteReason = formatReasonWithAttachments(muteReasonReceived.content, [...msg.attachments.values()]); // Verify we can act upon all users for (const userId of args.userIds) { diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index 3ed21806..92e1b0fa 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -31,7 +31,7 @@ export const NoteCmd = modActionsCmd({ } const userName = user.tag; - const reason = formatReasonWithAttachments(args.note, msg.attachments.array()); + const reason = formatReasonWithAttachments(args.note, [...msg.attachments.values()]); const casesPlugin = pluginData.getPlugin(CasesPlugin); const createdCase = await casesPlugin.createCase({ diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index 38bb49f0..0e199b25 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -47,7 +47,7 @@ export const UnbanCmd = modActionsCmd({ } pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, user.id); - const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); + const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); try { ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index d06f91b8..03d79b76 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -63,7 +63,7 @@ export const WarnCmd = modActionsCmd({ } const config = pluginData.config.get(); - const reason = formatReasonWithAttachments(args.reason, msg.attachments.array()); + const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); const casesPlugin = pluginData.getPlugin(CasesPlugin); const priorWarnAmount = await casesPlugin.getCaseTypeAmountForUserId(memberToWarn.id, CaseTypes.Warn); diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index 64fd30df..f790604a 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -42,7 +42,7 @@ export async function actualMuteUserCmd( } const timeUntilUnmute = args.time && humanizeDuration(args.time); - const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments.array()) : undefined; + const reason = args.reason ? formatReasonWithAttachments(args.reason, [...msg.attachments.values()]) : undefined; let muteResult: MuteResult; const mutesPlugin = pluginData.getPlugin(MutesPlugin); diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts index fb7465c7..46ab7be6 100644 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts @@ -27,7 +27,7 @@ export async function actualUnmuteCmd( pp = msg.author; } - const reason = args.reason ? formatReasonWithAttachments(args.reason, msg.attachments.array()) : undefined; + const reason = args.reason ? formatReasonWithAttachments(args.reason, [...msg.attachments.values()]) : undefined; const mutesPlugin = pluginData.getPlugin(MutesPlugin); const result = await mutesPlugin.unmuteUser(user.id, args.time, { diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index 21b6e050..4d89105a 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -24,7 +24,7 @@ export async function updateCase(pluginData, msg: Message, args) { return; } - const note = formatReasonWithAttachments(args.note, msg.attachments.array()); + const note = formatReasonWithAttachments(args.note, [...msg.attachments.values()]); const casesPlugin = pluginData.getPlugin(CasesPlugin); await casesPlugin.createCaseNote({ diff --git a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts index 7ad36e65..d812dd9d 100644 --- a/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts +++ b/backend/src/plugins/Mutes/functions/clearExpiredMutes.ts @@ -21,7 +21,7 @@ export async function clearExpiredMutes(pluginData: GuildPluginData to <#${starboardChannel.id}>...`); - const pins = (await args.pinChannel.messages.fetchPinned()).array(); + const pins = [...(await args.pinChannel.messages.fetchPinned().catch(() => [])).values()]; pins.reverse(); // Migrate pins starting from the oldest message for (const pin of pins) { diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index e7778215..ca96d57f 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -118,7 +118,7 @@ export const CleanCmd = utilityCmd({ const deletePins = args["delete-pins"] != null ? args["delete-pins"] : false; let pins: Message[] = []; if (!deletePins) { - pins = (await msg.channel.messages.fetchPinned()).array(); + pins = [...(await msg.channel.messages.fetchPinned().catch(() => [])).values()]; } while (messagesToClean.length < args.count) { @@ -128,14 +128,14 @@ export const CleanCmd = utilityCmd({ }); if (potentialMessages.size === 0) break; - const existingStored = await pluginData.state.savedMessages.getMultiple(potentialMessages.keyArray()); + const existingStored = await pluginData.state.savedMessages.getMultiple([...potentialMessages.keys()]); const alreadyStored = existingStored.map(stored => stored.id); - const messagesToStore = potentialMessages - .array() - .filter(potentialMsg => !alreadyStored.includes(potentialMsg.id)); + const messagesToStore = [ + ...potentialMessages.filter(potentialMsg => !alreadyStored.includes(potentialMsg.id)).values(), + ]; await pluginData.state.savedMessages.createFromMessages(messagesToStore); - const potentialMessagesToClean = await pluginData.state.savedMessages.getMultiple(potentialMessages.keyArray()); + const potentialMessagesToClean = await pluginData.state.savedMessages.getMultiple([...potentialMessages.keys()]); if (potentialMessagesToClean.length === 0) break; const filtered: SavedMessage[] = []; diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index c5d4b14d..5bb69961 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -32,7 +32,7 @@ export const VcdisconnectCmd = utilityCmd({ const channel = pluginData.guild.channels.cache.get(args.member.voice.channelId) as VoiceChannel; try { - await args.member.voice.kick(); + await args.member.voice.disconnect(); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to disconnect member"); return; diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 9e51dd5b..409918dd 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -9,6 +9,7 @@ import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { channelMentionRegex, isSnowflake, simpleClosestStringMatch } from "../../../utils"; import { utilityCmd } from "../types"; +import { ChannelTypeStrings } from "../../../types"; export const VcmoveCmd = utilityCmd({ trigger: "vcmove", @@ -45,9 +46,11 @@ export const VcmoveCmd = utilityCmd({ channel = potentialChannel; } else { // Search string -> find closest matching voice channel name - const voiceChannels = pluginData.guild.channels.cache.array().filter(theChannel => { - return theChannel instanceof VoiceChannel; - }) as VoiceChannel[]; + const voiceChannels = [ + ...pluginData.guild.channels.cache + .filter((c): c is VoiceChannel => c.type === ChannelTypeStrings.VOICE) + .values(), + ]; const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, ch => ch.name); if (!closestMatch) { sendErrorMessage(pluginData, msg.channel, "No matching voice channels"); @@ -124,9 +127,11 @@ export const VcmoveAllCmd = utilityCmd({ channel = potentialChannel; } else { // Search string -> find closest matching voice channel name - const voiceChannels = pluginData.guild.channels.cache.array().filter(theChannel => { - return theChannel instanceof VoiceChannel; - }) as VoiceChannel[]; + const voiceChannels = [ + ...pluginData.guild.channels.cache + .filter((c): c is VoiceChannel => c.type === ChannelTypeStrings.VOICE) + .values(), + ]; const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, ch => ch.name); if (!closestMatch) { sendErrorMessage(pluginData, msg.channel, "No matching voice channels"); diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index c1dcc7d8..d1788bce 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -130,11 +130,13 @@ export async function getChannelInfoEmbed( if (channel.type === ChannelTypeStrings.PRIVATE_THREAD || channel.type === ChannelTypeStrings.PUBLIC_THREAD) { const thread = channel as ThreadChannel; - const parentChannelName = thread.parent?.name ? thread.parent.name : `<#${thread.parentId}>`; + const parentChannelName = thread.parent?.name ?? `<#${thread.parentId}>`; const memberCount = thread.memberCount ?? thread.members.cache.size; - const owner = await pluginData.guild.members.fetch(thread.ownerId).catch(() => null); - const ownerMention = owner ? verboseUserMention(owner.user) : "Unknown#0000"; - const humanizedArchiveTime = `Archive duration: **${humanizeDuration(thread.autoArchiveDuration * MINUTES)}**`; + const owner = await thread.fetchOwner().catch(() => null); + const ownerMention = owner?.user ? verboseUserMention(owner.user) : "Unknown#0000"; + const humanizedArchiveTime = `Archive duration: **${humanizeDuration( + (thread.autoArchiveDuration ?? 0) * MINUTES, + )}**`; embed.fields.push({ name: preEmbedPadding + "Thread information", diff --git a/backend/src/utils.ts b/backend/src/utils.ts index a3dcec39..6f0edca8 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -535,7 +535,7 @@ export async function findRelevantAuditLogEntry( } } - const entries = auditLogs ? auditLogs.entries.array() : []; + const entries = auditLogs ? [...auditLogs.entries.values()] : []; entries.sort((a, b) => { if (a.createdAt > b.createdAt) return -1; @@ -1302,7 +1302,7 @@ export async function resolveInvite( return promise as ResolveInviteReturnType; } -const internalStickerCache: LimitedCollection = new LimitedCollection(500); +const internalStickerCache: LimitedCollection = new LimitedCollection({ maxSize: 500 }); export async function resolveStickerId(bot: Client, id: Snowflake): Promise { const cachedSticker = internalStickerCache.get(id); diff --git a/backend/src/utils/configAccessibleObjects.ts b/backend/src/utils/configAccessibleObjects.ts index 5904e48d..9319fc08 100644 --- a/backend/src/utils/configAccessibleObjects.ts +++ b/backend/src/utils/configAccessibleObjects.ts @@ -87,7 +87,7 @@ export function memberToConfigAccessibleMember(member: GuildMember | PartialGuil ...user, user, nick: member.nickname ?? "*None*", - roles: member.roles.cache.mapValues(r => roleToConfigAccessibleRole(r)).array(), + roles: [...member.roles.cache.mapValues(r => roleToConfigAccessibleRole(r)).values()], joinedAt: member.joinedTimestamp ?? undefined, guildName: member.guild.name, }; From a11c39cd0a4bcd5ef915c02bc7957f6bdbd5b75a Mon Sep 17 00:00:00 2001 From: almeidx Date: Wed, 4 Aug 2021 21:02:12 +0100 Subject: [PATCH 77/79] transform to array before filtering --- .../src/plugins/Utility/commands/VcmoveCmd.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index 409918dd..f2feb8ef 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -46,11 +46,9 @@ export const VcmoveCmd = utilityCmd({ channel = potentialChannel; } else { // Search string -> find closest matching voice channel name - const voiceChannels = [ - ...pluginData.guild.channels.cache - .filter((c): c is VoiceChannel => c.type === ChannelTypeStrings.VOICE) - .values(), - ]; + const voiceChannels = [...pluginData.guild.channels.cache.values()].filter( + (c): c is VoiceChannel => c.type === ChannelTypeStrings.VOICE, + ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, ch => ch.name); if (!closestMatch) { sendErrorMessage(pluginData, msg.channel, "No matching voice channels"); @@ -127,11 +125,9 @@ export const VcmoveAllCmd = utilityCmd({ channel = potentialChannel; } else { // Search string -> find closest matching voice channel name - const voiceChannels = [ - ...pluginData.guild.channels.cache - .filter((c): c is VoiceChannel => c.type === ChannelTypeStrings.VOICE) - .values(), - ]; + const voiceChannels = [...pluginData.guild.channels.cache.values()].filter( + (c): c is VoiceChannel => c.type === ChannelTypeStrings.VOICE, + ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, ch => ch.name); if (!closestMatch) { sendErrorMessage(pluginData, msg.channel, "No matching voice channels"); From d854ae48ecfc58509b6ab219124b56ef0fb562e1 Mon Sep 17 00:00:00 2001 From: almeidx Date: Thu, 12 Aug 2021 13:20:09 +0100 Subject: [PATCH 78/79] use node 16 --- .nvmrc | 2 +- backend/package-lock.json | 525 ++++++++++++++------------------------ backend/package.json | 10 +- 3 files changed, 200 insertions(+), 337 deletions(-) diff --git a/.nvmrc b/.nvmrc index 8351c193..d925544b 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -14 +16.6 diff --git a/backend/package-lock.json b/backend/package-lock.json index e0744d93..5255f48e 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -8,16 +8,14 @@ "name": "@zeppelin/backend", "version": "0.0.1", "dependencies": { - "@types/sharp": "^0.23.1", - "@types/twemoji": "^12.1.0", "bufferutil": "^4.0.3", "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.t1628078860.90c2e07", + "discord.js": "^13.0.1", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", - "erlpack": "github:discord/erlpack", + "erlpack": "github:almeidx/erlpack#f0c535f73817fd914806d6ca26a7730c14e0fb7c", "escape-string-regexp": "^1.0.5", "express": "^4.17.0", "fp-ts": "^2.0.1", @@ -44,7 +42,7 @@ "regexp-worker": "^1.1.0", "safe-regex": "^2.0.2", "seedrandom": "^3.0.1", - "sharp": "^0.23.4", + "sharp": "github:almeidx/sharp#68b4f387ae2ee1ee2dd8f289f5ec5fcf722fd3d3", "strip-combining-marks": "^1.0.0", "tlds": "^1.203.1", "tmp": "0.0.33", @@ -68,7 +66,9 @@ "@types/passport-oauth2": "^1.4.8", "@types/passport-strategy": "^0.2.35", "@types/safe-regex": "^1.1.2", + "@types/sharp": "^0.23.1", "@types/tmp": "0.0.33", + "@types/twemoji": "^12.1.0", "ava": "^3.10.0", "rimraf": "^2.6.2", "source-map-support": "^0.5.16", @@ -81,8 +81,8 @@ "version": "30.0.0-beta.38", "license": "MIT", "dependencies": { - "discord-api-types": "^0.18.1", - "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", + "discord-api-types": "^0.21.0-next.ab1951b.1626870574", + "discord.js": "^13.0.1", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -161,14 +161,14 @@ } }, "node_modules/@discordjs/builders": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.3.0.tgz", - "integrity": "sha512-yFBPqohVAtCWoDTQCYk5ubgmkiRbGpbiR4RfYGHCmV5S2YZc7j8WzfKVksjuy2o5IWRfXFsW6G2Lr+KpW41pEA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.4.0.tgz", + "integrity": "sha512-EiwLltKph6TSaPJIzJYdzNc1PnA2ZNaaE0t0ODg3ghnpVHqfgd0YX9/srsleYHW2cw1sfIq+kbM+h0etf7GWLA==", "dependencies": { "@sindresorhus/is": "^4.0.1", "discord-api-types": "^0.22.0", - "ow": "^0.26.0", - "ts-mixer": "^5.4.1", + "ow": "^0.27.0", + "ts-mixer": "^6.0.0", "tslib": "^2.3.0" }, "engines": { @@ -486,6 +486,7 @@ "version": "0.23.1", "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz", "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==", + "dev": true, "dependencies": { "@types/node": "*" } @@ -499,27 +500,17 @@ "node_modules/@types/twemoji": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.0.tgz", - "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==" + "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==", + "dev": true }, "node_modules/@types/ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA==", + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "dependencies": { "@types/node": "*" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -1455,9 +1446,9 @@ } }, "node_modules/chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/chunkd": { "version": "2.0.1", @@ -1758,12 +1749,12 @@ } }, "node_modules/color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "dependencies": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, "node_modules/color-convert": { @@ -1780,9 +1771,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "node_modules/color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -2175,22 +2166,21 @@ } }, "node_modules/discord.js": { - "version": "13.0.0-dev.t1628078860.90c2e07", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.t1628078860.90c2e07.tgz", - "integrity": "sha512-Yet0FjFizVzCZkV2+cxenTh6Y2CzNWnA9BK12gmifSa6GuUJ0o98ptx5jpo+jpaXpwkKooivOCNl3wrulupmzg==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.1.tgz", + "integrity": "sha512-pEODCFfxypBnGEYpSgjkn1jt70raCS1um7Zp0AXEfW1DcR29wISzQ/WeWdnjP5KTXGi0LTtkRiUjOsMgSoukxA==", "dependencies": { - "@discordjs/builders": "^0.3.0", + "@discordjs/builders": "^0.4.0", "@discordjs/collection": "^0.2.1", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", - "@types/ws": "^7.4.5", - "abort-controller": "^3.0.0", + "@types/ws": "^7.4.7", "discord-api-types": "^0.22.0", "node-fetch": "^2.6.1", "ws": "^7.5.1" }, "engines": { - "node": ">=14.6.0", + "node": ">=16.6.0", "npm": ">=7.0.0" } }, @@ -2283,8 +2273,7 @@ }, "node_modules/erlpack": { "version": "0.1.3", - "resolved": "git+ssh://git@github.com/discord/erlpack.git#e27db8f82892bdb9b28a0547cc394d68b5d2242d", - "integrity": "sha512-uDE+ma9xOMfF4ncJHoymBWA084DqoO8q/hBDvGx4WUxmvFQfHoCsk3BYk1D1Lei/lhNCZXLf1vkeNYVBSqrSgw==", + "resolved": "git+ssh://git@github.com/almeidx/erlpack.git#f0c535f73817fd914806d6ca26a7730c14e0fb7c", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -2375,14 +2364,6 @@ "through": "~2.3.1" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -2584,17 +2565,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/fs-minipass": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz", - "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3594,50 +3564,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, - "node_modules/minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/minizlib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", - "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -3728,6 +3654,11 @@ "semver": "^5.4.1" } }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node_modules/node-cleanup": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", @@ -3752,11 +3683,6 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" - }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -3970,9 +3896,9 @@ } }, "node_modules/ow": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/ow/-/ow-0.26.0.tgz", - "integrity": "sha512-22YUQW9d6oUSCpIQuBV25djtC1uMtpWqmtUYnuh2UHWeNMpppCFCvq3eSBIWWMDbe2UVq26kWYvBHDzOIu5NYg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz", + "integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==", "dependencies": { "@sindresorhus/is": "^4.0.1", "callsites": "^3.1.0", @@ -4014,9 +3940,9 @@ } }, "node_modules/ow/node_modules/type-fest": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.3.0.tgz", - "integrity": "sha512-mYUYkAy6fPatVWtUeCV/qGeGL3IVucmdJOzeAEfwgCJDx8gP0JaW8jn6KQ5xDfPec31e0KXWn5EUOZMhquR1zA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "engines": { "node": ">=10" }, @@ -4403,9 +4329,9 @@ } }, "node_modules/prebuild-install": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", - "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", "dependencies": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", @@ -4413,15 +4339,13 @@ "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", + "node-abi": "^2.21.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^3.0.3", "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" + "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" @@ -4901,36 +4825,57 @@ } }, "node_modules/sharp": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.4.tgz", - "integrity": "sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q==", + "version": "0.28.3", + "resolved": "git+ssh://git@github.com/almeidx/sharp.git#68b4f387ae2ee1ee2dd8f289f5ec5fcf722fd3d3", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "color": "^3.1.2", + "color": "^3.1.3", "detect-libc": "^1.0.3", - "nan": "^2.14.0", - "npmlog": "^4.1.2", - "prebuild-install": "^5.3.3", - "semver": "^6.3.0", + "node-addon-api": "^3.2.0", + "prebuild-install": "^6.1.2", + "semver": "^7.3.5", "simple-get": "^3.1.0", - "tar": "^5.0.5", + "tar-fs": "^2.1.1", "tunnel-agent": "^0.6.0" }, "engines": { - "node": ">=8.5.0" + "node": ">=10" }, "funding": { "url": "https://opencollective.com/libvips" } }, + "node_modules/sharp/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/sharp/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "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/sharp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -4956,9 +4901,23 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "node_modules/simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/simple-get": { "version": "3.1.0", @@ -4982,11 +4941,14 @@ } }, "node_modules/simple-get/node_modules/mimic-response": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz", - "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/simple-swizzle": { @@ -5319,22 +5281,6 @@ "node": ">=4" } }, - "node_modules/tar": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz", - "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==", - "dependencies": { - "chownr": "^1.1.3", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.0", - "mkdirp": "^0.5.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -5374,11 +5320,6 @@ "node": ">= 6" } }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -5492,9 +5433,9 @@ } }, "node_modules/ts-mixer": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", - "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA==" + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz", + "integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==" }, "node_modules/tsc-watch": { "version": "4.0.0", @@ -6032,11 +5973,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "node_modules/which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, "node_modules/wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -6513,14 +6449,14 @@ } }, "@discordjs/builders": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.3.0.tgz", - "integrity": "sha512-yFBPqohVAtCWoDTQCYk5ubgmkiRbGpbiR4RfYGHCmV5S2YZc7j8WzfKVksjuy2o5IWRfXFsW6G2Lr+KpW41pEA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.4.0.tgz", + "integrity": "sha512-EiwLltKph6TSaPJIzJYdzNc1PnA2ZNaaE0t0ODg3ghnpVHqfgd0YX9/srsleYHW2cw1sfIq+kbM+h0etf7GWLA==", "requires": { "@sindresorhus/is": "^4.0.1", "discord-api-types": "^0.22.0", - "ow": "^0.26.0", - "ts-mixer": "^5.4.1", + "ow": "^0.27.0", + "ts-mixer": "^6.0.0", "tslib": "^2.3.0" }, "dependencies": { @@ -6805,6 +6741,7 @@ "version": "0.23.1", "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz", "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==", + "dev": true, "requires": { "@types/node": "*" } @@ -6818,24 +6755,17 @@ "@types/twemoji": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/@types/twemoji/-/twemoji-12.1.0.tgz", - "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==" + "integrity": "sha512-dTHU1ZE83qUlF3oFWrdxKBmOimM+/3o9hzDBszcKjajmNu5G/DjWgQrRNkq+zxeR+zDN030ciAt5qTH+WXBD8A==", + "dev": true }, "@types/ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-8mbDgtc8xpxDDem5Gwj76stBDJX35KQ3YBoayxlqUQcL5BZUthiqP/VQ4PQnLHqM4PmlbyO74t98eJpURO+gPA==", + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", + "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", "requires": { "@types/node": "*" } }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -7562,9 +7492,9 @@ } }, "chownr": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "chunkd": { "version": "2.0.1", @@ -7789,12 +7719,12 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" + "color-convert": "^1.9.3", + "color-string": "^1.6.0" } }, "color-convert": { @@ -7811,9 +7741,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", + "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -8117,16 +8047,15 @@ "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==" }, "discord.js": { - "version": "13.0.0-dev.t1628078860.90c2e07", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.0-dev.t1628078860.90c2e07.tgz", - "integrity": "sha512-Yet0FjFizVzCZkV2+cxenTh6Y2CzNWnA9BK12gmifSa6GuUJ0o98ptx5jpo+jpaXpwkKooivOCNl3wrulupmzg==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.1.tgz", + "integrity": "sha512-pEODCFfxypBnGEYpSgjkn1jt70raCS1um7Zp0AXEfW1DcR29wISzQ/WeWdnjP5KTXGi0LTtkRiUjOsMgSoukxA==", "requires": { - "@discordjs/builders": "^0.3.0", + "@discordjs/builders": "^0.4.0", "@discordjs/collection": "^0.2.1", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", - "@types/ws": "^7.4.5", - "abort-controller": "^3.0.0", + "@types/ws": "^7.4.7", "discord-api-types": "^0.22.0", "node-fetch": "^2.6.1", "ws": "^7.5.1" @@ -8202,9 +8131,8 @@ "dev": true }, "erlpack": { - "version": "git+ssh://git@github.com/discord/erlpack.git#e27db8f82892bdb9b28a0547cc394d68b5d2242d", - "integrity": "sha512-uDE+ma9xOMfF4ncJHoymBWA084DqoO8q/hBDvGx4WUxmvFQfHoCsk3BYk1D1Lei/lhNCZXLf1vkeNYVBSqrSgw==", - "from": "erlpack@github:discord/erlpack", + "version": "git+ssh://git@github.com/almeidx/erlpack.git#f0c535f73817fd914806d6ca26a7730c14e0fb7c", + "from": "erlpack@github:almeidx/erlpack#f0c535f73817fd914806d6ca26a7730c14e0fb7c", "requires": { "bindings": "^1.5.0", "nan": "^2.14.0" @@ -8271,11 +8199,6 @@ "through": "~2.3.1" } }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, "expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -8443,14 +8366,6 @@ } } }, - "fs-minipass": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz", - "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==", - "requires": { - "minipass": "^3.0.0" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -8952,8 +8867,8 @@ "@typescript-eslint/eslint-plugin": "^4.23.0", "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", - "discord-api-types": "^0.18.1", - "discord.js": "github:monbrey/discord.js#9c42f571093b2565df28b756fdca4ac59cad0fe3", + "discord-api-types": "^0.21.0-next.ab1951b.1626870574", + "discord.js": "^13.0.1", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", @@ -9236,45 +9151,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, - "minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "minizlib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", - "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -9353,6 +9229,11 @@ "semver": "^5.4.1" } }, + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" + }, "node-cleanup": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", @@ -9369,11 +9250,6 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" - }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -9538,9 +9414,9 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "ow": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/ow/-/ow-0.26.0.tgz", - "integrity": "sha512-22YUQW9d6oUSCpIQuBV25djtC1uMtpWqmtUYnuh2UHWeNMpppCFCvq3eSBIWWMDbe2UVq26kWYvBHDzOIu5NYg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz", + "integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==", "requires": { "@sindresorhus/is": "^4.0.1", "callsites": "^3.1.0", @@ -9564,9 +9440,9 @@ } }, "type-fest": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.3.0.tgz", - "integrity": "sha512-mYUYkAy6fPatVWtUeCV/qGeGL3IVucmdJOzeAEfwgCJDx8gP0JaW8jn6KQ5xDfPec31e0KXWn5EUOZMhquR1zA==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" } } }, @@ -9858,9 +9734,9 @@ } }, "prebuild-install": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.6.tgz", - "integrity": "sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", + "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", "requires": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", @@ -9868,15 +9744,13 @@ "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", + "node-abi": "^2.21.0", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^3.0.3", "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" + "tunnel-agent": "^0.6.0" } }, "prepend-http": { @@ -10256,25 +10130,39 @@ } }, "sharp": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.4.tgz", - "integrity": "sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q==", + "version": "git+ssh://git@github.com/almeidx/sharp.git#68b4f387ae2ee1ee2dd8f289f5ec5fcf722fd3d3", + "from": "sharp@github:almeidx/sharp#68b4f387ae2ee1ee2dd8f289f5ec5fcf722fd3d3", "requires": { - "color": "^3.1.2", + "color": "^3.1.3", "detect-libc": "^1.0.3", - "nan": "^2.14.0", - "npmlog": "^4.1.2", - "prebuild-install": "^5.3.3", - "semver": "^6.3.0", + "node-addon-api": "^3.2.0", + "prebuild-install": "^6.1.2", + "semver": "^7.3.5", "simple-get": "^3.1.0", - "tar": "^5.0.5", + "tar-fs": "^2.1.1", "tunnel-agent": "^0.6.0" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -10297,9 +10185,9 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { "version": "3.1.0", @@ -10320,9 +10208,9 @@ } }, "mimic-response": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz", - "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" } } }, @@ -10597,26 +10485,6 @@ "has-flag": "^3.0.0" } }, - "tar": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz", - "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==", - "requires": { - "chownr": "^1.1.3", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.0", - "mkdirp": "^0.5.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, "tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", @@ -10732,9 +10600,9 @@ "dev": true }, "ts-mixer": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-5.4.1.tgz", - "integrity": "sha512-Zo9HgPCtNouDgJ+LGtrzVOjSg8+7WGQktIKLwAfaNrlOK1mWGlz1ejsAF/YqUEqAGjUTeB5fEg8gH9Aui6w9xA==" + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz", + "integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ==" }, "tsc-watch": { "version": "4.0.0", @@ -11138,11 +11006,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", diff --git a/backend/package.json b/backend/package.json index d9c76424..582edf50 100644 --- a/backend/package.json +++ b/backend/package.json @@ -23,16 +23,14 @@ "test-watch": "tsc-watch --onSuccess \"npx ava\"" }, "dependencies": { - "@types/sharp": "^0.23.1", - "@types/twemoji": "^12.1.0", "bufferutil": "^4.0.3", "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.0-dev.t1628078860.90c2e07", + "discord.js": "^13.0.1", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", - "erlpack": "github:discord/erlpack", + "erlpack": "github:almeidx/erlpack#f0c535f73817fd914806d6ca26a7730c14e0fb7c", "escape-string-regexp": "^1.0.5", "express": "^4.17.0", "fp-ts": "^2.0.1", @@ -59,7 +57,7 @@ "regexp-worker": "^1.1.0", "safe-regex": "^2.0.2", "seedrandom": "^3.0.1", - "sharp": "^0.23.4", + "sharp": "github:almeidx/sharp#68b4f387ae2ee1ee2dd8f289f5ec5fcf722fd3d3", "strip-combining-marks": "^1.0.0", "tlds": "^1.203.1", "tmp": "0.0.33", @@ -83,7 +81,9 @@ "@types/passport-oauth2": "^1.4.8", "@types/passport-strategy": "^0.2.35", "@types/safe-regex": "^1.1.2", + "@types/sharp": "^0.23.1", "@types/tmp": "0.0.33", + "@types/twemoji": "^12.1.0", "ava": "^3.10.0", "rimraf": "^2.6.2", "source-map-support": "^0.5.16", From ff774aa5f65d21dbfb7610377ef20dad8c02a339 Mon Sep 17 00:00:00 2001 From: Dark <7890309+DarkView@users.noreply.github.com> Date: Fri, 13 Aug 2021 05:01:08 +0200 Subject: [PATCH 79/79] Context Menu Actions v1, clean and mute support with full options --- backend/package-lock.json | 51 ++-- backend/package.json | 3 +- backend/src/data/GuildContextMenuLinks.ts | 35 +++ backend/src/data/entities/ContextMenuLink.ts | 10 + .../1628809879962-CreateContextMenuTable.ts | 32 +++ .../plugins/ContextMenus/ContextMenuPlugin.ts | 61 ++++ .../ContextMenus/actions/availableActions.ts | 19 ++ .../src/plugins/ContextMenus/actions/clean.ts | 64 +++++ .../src/plugins/ContextMenus/actions/mute.ts | 83 ++++++ .../ContextMenus/events/ContextClickedEvt.ts | 13 + backend/src/plugins/ContextMenus/helpers.ts | 25 ++ backend/src/plugins/ContextMenus/types.ts | 38 +++ .../ContextMenus/utils/contextRouter.ts | 28 ++ .../ContextMenus/utils/loadAllCommands.ts | 37 +++ .../utils/resolveActionContactMethods.ts | 32 +++ backend/src/plugins/Utility/UtilityPlugin.ts | 10 +- .../src/plugins/Utility/commands/CleanCmd.ts | 261 ++++++++++-------- .../Utility/functions/getChannelInfoEmbed.ts | 5 +- backend/src/plugins/availablePlugins.ts | 2 + 19 files changed, 657 insertions(+), 152 deletions(-) create mode 100644 backend/src/data/GuildContextMenuLinks.ts create mode 100644 backend/src/data/entities/ContextMenuLink.ts create mode 100644 backend/src/migrations/1628809879962-CreateContextMenuTable.ts create mode 100644 backend/src/plugins/ContextMenus/ContextMenuPlugin.ts create mode 100644 backend/src/plugins/ContextMenus/actions/availableActions.ts create mode 100644 backend/src/plugins/ContextMenus/actions/clean.ts create mode 100644 backend/src/plugins/ContextMenus/actions/mute.ts create mode 100644 backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts create mode 100644 backend/src/plugins/ContextMenus/helpers.ts create mode 100644 backend/src/plugins/ContextMenus/types.ts create mode 100644 backend/src/plugins/ContextMenus/utils/contextRouter.ts create mode 100644 backend/src/plugins/ContextMenus/utils/loadAllCommands.ts create mode 100644 backend/src/plugins/ContextMenus/utils/resolveActionContactMethods.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 5255f48e..b44de2a2 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -12,7 +12,8 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.1", + "discord-api-types": "^0.22.0", + "discord.js": "^13.1.0", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:almeidx/erlpack#f0c535f73817fd914806d6ca26a7730c14e0fb7c", @@ -81,8 +82,8 @@ "version": "30.0.0-beta.38", "license": "MIT", "dependencies": { - "discord-api-types": "^0.21.0-next.ab1951b.1626870574", - "discord.js": "^13.0.1", + "discord-api-types": "^0.22.0", + "discord.js": "^13.1.0", "knub-command-manager": "^9.1.0", "ts-essentials": "^6.0.7" }, @@ -161,9 +162,9 @@ } }, "node_modules/@discordjs/builders": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.4.0.tgz", - "integrity": "sha512-EiwLltKph6TSaPJIzJYdzNc1PnA2ZNaaE0t0ODg3ghnpVHqfgd0YX9/srsleYHW2cw1sfIq+kbM+h0etf7GWLA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.5.0.tgz", + "integrity": "sha512-HP5y4Rqw68o61Qv4qM5tVmDbWi4mdTFftqIOGRo33SNPpLJ1Ga3KEIR2ibKofkmsoQhEpLmopD1AZDs3cKpHuw==", "dependencies": { "@sindresorhus/is": "^4.0.1", "discord-api-types": "^0.22.0", @@ -188,9 +189,9 @@ } }, "node_modules/@discordjs/builders/node_modules/tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, "node_modules/@discordjs/collection": { "version": "0.2.1", @@ -2166,11 +2167,11 @@ } }, "node_modules/discord.js": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.1.tgz", - "integrity": "sha512-pEODCFfxypBnGEYpSgjkn1jt70raCS1um7Zp0AXEfW1DcR29wISzQ/WeWdnjP5KTXGi0LTtkRiUjOsMgSoukxA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.1.0.tgz", + "integrity": "sha512-gxO4CXKdHpqA+WKG+f5RNnd3srTDj5uFJHgOathksDE90YNq/Qijkd2WlMgTTMS6AJoEnHxI7G9eDQHCuZ+xDA==", "dependencies": { - "@discordjs/builders": "^0.4.0", + "@discordjs/builders": "^0.5.0", "@discordjs/collection": "^0.2.1", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", @@ -6449,9 +6450,9 @@ } }, "@discordjs/builders": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.4.0.tgz", - "integrity": "sha512-EiwLltKph6TSaPJIzJYdzNc1PnA2ZNaaE0t0ODg3ghnpVHqfgd0YX9/srsleYHW2cw1sfIq+kbM+h0etf7GWLA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.5.0.tgz", + "integrity": "sha512-HP5y4Rqw68o61Qv4qM5tVmDbWi4mdTFftqIOGRo33SNPpLJ1Ga3KEIR2ibKofkmsoQhEpLmopD1AZDs3cKpHuw==", "requires": { "@sindresorhus/is": "^4.0.1", "discord-api-types": "^0.22.0", @@ -6466,9 +6467,9 @@ "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" }, "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" } } }, @@ -8047,11 +8048,11 @@ "integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==" }, "discord.js": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.0.1.tgz", - "integrity": "sha512-pEODCFfxypBnGEYpSgjkn1jt70raCS1um7Zp0AXEfW1DcR29wISzQ/WeWdnjP5KTXGi0LTtkRiUjOsMgSoukxA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.1.0.tgz", + "integrity": "sha512-gxO4CXKdHpqA+WKG+f5RNnd3srTDj5uFJHgOathksDE90YNq/Qijkd2WlMgTTMS6AJoEnHxI7G9eDQHCuZ+xDA==", "requires": { - "@discordjs/builders": "^0.4.0", + "@discordjs/builders": "^0.5.0", "@discordjs/collection": "^0.2.1", "@discordjs/form-data": "^3.0.1", "@sapphire/async-queue": "^1.1.4", @@ -8867,8 +8868,8 @@ "@typescript-eslint/eslint-plugin": "^4.23.0", "@typescript-eslint/parser": "^4.23.0", "chai": "^4.3.4", - "discord-api-types": "^0.21.0-next.ab1951b.1626870574", - "discord.js": "^13.0.1", + "discord-api-types": "^0.22.0", + "discord.js": "^13.1.0", "eslint": "^7.2.0", "husky": "^4.3.8", "knub-command-manager": "^9.1.0", diff --git a/backend/package.json b/backend/package.json index 582edf50..3f9589e4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -27,7 +27,8 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord.js": "^13.0.1", + "discord-api-types": "^0.22.0", + "discord.js": "^13.1.0", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:almeidx/erlpack#f0c535f73817fd914806d6ca26a7730c14e0fb7c", diff --git a/backend/src/data/GuildContextMenuLinks.ts b/backend/src/data/GuildContextMenuLinks.ts new file mode 100644 index 00000000..76afd3da --- /dev/null +++ b/backend/src/data/GuildContextMenuLinks.ts @@ -0,0 +1,35 @@ +import { DeleteResult, getRepository, InsertResult, Repository } from "typeorm"; +import { BaseGuildRepository } from "./BaseGuildRepository"; +import { ContextMenuLink } from "./entities/ContextMenuLink"; + +export class GuildContextMenuLinks extends BaseGuildRepository { + private contextLinks: Repository; + + constructor(guildId) { + super(guildId); + this.contextLinks = getRepository(ContextMenuLink); + } + + async get(id: string): Promise { + return this.contextLinks.findOne({ + where: { + guild_id: this.guildId, + context_id: id, + }, + }); + } + + async create(contextId: string, contextAction: string): Promise { + return this.contextLinks.insert({ + guild_id: this.guildId, + context_id: contextId, + action_name: contextAction, + }); + } + + async deleteAll(): Promise { + return this.contextLinks.delete({ + guild_id: this.guildId, + }); + } +} diff --git a/backend/src/data/entities/ContextMenuLink.ts b/backend/src/data/entities/ContextMenuLink.ts new file mode 100644 index 00000000..df66fae3 --- /dev/null +++ b/backend/src/data/entities/ContextMenuLink.ts @@ -0,0 +1,10 @@ +import { Column, Entity, PrimaryColumn } from "typeorm"; + +@Entity("context_menus") +export class ContextMenuLink { + @Column() guild_id: string; + + @Column() @PrimaryColumn() context_id: string; + + @Column() action_name: string; +} diff --git a/backend/src/migrations/1628809879962-CreateContextMenuTable.ts b/backend/src/migrations/1628809879962-CreateContextMenuTable.ts new file mode 100644 index 00000000..236b7b3c --- /dev/null +++ b/backend/src/migrations/1628809879962-CreateContextMenuTable.ts @@ -0,0 +1,32 @@ +import { MigrationInterface, QueryRunner, Table } from "typeorm"; + +export class CreateContextMenuTable1628809879962 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: "context_menus", + columns: [ + { + name: "guild_id", + type: "bigint", + }, + { + name: "context_id", + type: "bigint", + isPrimary: true, + isUnique: true, + }, + { + name: "action_name", + type: "varchar", + length: "100", + }, + ], + }), + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable("context_menus"); + } +} diff --git a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts new file mode 100644 index 00000000..7aefe88f --- /dev/null +++ b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts @@ -0,0 +1,61 @@ +import { PluginOptions } from "knub"; +import { StrictValidationError } from "src/validatorUtils"; +import { ConfigPreprocessorFn } from "../../../../../Knub/dist/config/configTypes"; +import { GuildContextMenuLinks } from "../../data/GuildContextMenuLinks"; +import { LogsPlugin } from "../Logs/LogsPlugin"; +import { MutesPlugin } from "../Mutes/MutesPlugin"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { availableTypes } from "./actions/availableActions"; +import { ContextClickedEvt } from "./events/ContextClickedEvt"; +import { ConfigSchema, ContextMenuPluginType } from "./types"; +import { loadAllCommands } from "./utils/loadAllCommands"; + +const defaultOptions: PluginOptions = { + config: { + context_actions: {}, + }, +}; + +const configPreprocessor: ConfigPreprocessorFn = options => { + if (options.config.context_actions) { + for (const [name, contextMenu] of Object.entries(options.config.context_actions)) { + if (Object.entries(contextMenu.action).length !== 1) { + throw new StrictValidationError([`Invalid value for context_actions/${name}: Must have exactly one action.`]); + } + + const actionName = Object.entries(contextMenu.action)[0][0]; + if (!availableTypes[actionName].includes(contextMenu.type)) { + throw new StrictValidationError([ + `Invalid value for context_actions/${name}/${actionName}: ${actionName} is not allowed on type ${contextMenu.type}.`, + ]); + } + } + } + + return options; +}; + +export const ContextMenuPlugin = zeppelinGuildPlugin()({ + name: "context_menu", + + configSchema: ConfigSchema, + defaultOptions, + configPreprocessor, + + // prettier-ignore + events: [ + ContextClickedEvt, + ], + + beforeLoad(pluginData) { + const { state, guild } = pluginData; + + state.contextMenuLinks = new GuildContextMenuLinks(guild.id); + }, + + afterLoad(pluginData) { + loadAllCommands(pluginData); + }, + + dependencies: [MutesPlugin, LogsPlugin], +}); diff --git a/backend/src/plugins/ContextMenus/actions/availableActions.ts b/backend/src/plugins/ContextMenus/actions/availableActions.ts new file mode 100644 index 00000000..24816790 --- /dev/null +++ b/backend/src/plugins/ContextMenus/actions/availableActions.ts @@ -0,0 +1,19 @@ +import * as t from "io-ts"; +import { ContextActionBlueprint } from "../helpers"; +import { CleanAction } from "./clean"; +import { MuteAction } from "./mute"; + +export const availableActions: Record> = { + mute: MuteAction, + clean: CleanAction, +}; + +export const AvailableActions = t.type({ + mute: MuteAction.configType, + clean: CleanAction.configType, +}); + +export const availableTypes: Record = { + mute: ["USER"], + clean: ["MESSAGE"], +}; diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts new file mode 100644 index 00000000..8184d480 --- /dev/null +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -0,0 +1,64 @@ +import { TextChannel } from "discord.js"; +import * as t from "io-ts"; +import { canActOn } from "src/pluginUtils"; +import { LogType } from "../../../data/LogType"; +import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { tNullable } from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { contextMenuAction } from "../helpers"; + +export const CleanAction = contextMenuAction({ + configType: t.type({ + amount: tNullable(t.number), + targetUserOnly: tNullable(t.boolean), + "delete-pins": tNullable(t.boolean), + }), + + defaultConfig: { + amount: 10, + targetUserOnly: false, + "delete-pins": false, + }, + + async apply({ pluginData, actionConfig, actionName, interaction }) { + interaction.deferReply({ ephemeral: true }); + const targetMessage = interaction.channel + ? await interaction.channel.messages.fetch(interaction.targetId) + : await (pluginData.guild.channels.resolve(interaction.channelId) as TextChannel).messages.fetch( + interaction.targetId, + ); + + const amount = actionConfig.amount ?? 10; + const targetUserOnly = actionConfig.targetUserOnly ?? false; + const deletePins = actionConfig["delete-pins"] ?? false; + + const user = targetUserOnly ? targetMessage.author.id : undefined; + const targetMember = await pluginData.guild.members.fetch(targetMessage.author.id); + const executingMember = await pluginData.guild.members.fetch(interaction.user.id); + const utility = pluginData.getPlugin(UtilityPlugin); + + if (targetUserOnly && !canActOn(pluginData, executingMember, targetMember)) { + interaction.followUp({ ephemeral: true, content: "Cannot clean users messages: insufficient permissions" }); + return; + } + + try { + interaction.followUp(`Cleaning... Amount: ${amount}, User Only: ${targetUserOnly}, Pins: ${deletePins}`); + utility.clean( + { count: amount, user, channel: targetMessage.channel.id, "delete-pins": deletePins }, + targetMessage, + ); + } catch (e) { + interaction.followUp({ ephemeral: true, content: "Plugin error, please check your BOT_ALERTs" }); + + if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { + pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, { + body: `Failed to clean in <#${interaction.channelId}> in ContextMenu action \`${actionName}\``, + }); + } else { + throw e; + } + } + }, +}); diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts new file mode 100644 index 00000000..00a9c131 --- /dev/null +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -0,0 +1,83 @@ +import humanizeDuration from "humanize-duration"; +import * as t from "io-ts"; +import { canActOn } from "src/pluginUtils"; +import { LogType } from "../../../data/LogType"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { convertDelayStringToMS, tDelayString, tNullable } from "../../../utils"; +import { CaseArgs } from "../../Cases/types"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { MutesPlugin } from "../../Mutes/MutesPlugin"; +import { contextMenuAction } from "../helpers"; +import { resolveActionContactMethods } from "../utils/resolveActionContactMethods"; + +export const MuteAction = contextMenuAction({ + configType: t.type({ + reason: tNullable(t.string), + duration: tNullable(tDelayString), + notify: tNullable(t.string), + notifyChannel: tNullable(t.string), + remove_roles_on_mute: tNullable(t.union([t.boolean, t.array(t.string)])), + restore_roles_on_mute: tNullable(t.union([t.boolean, t.array(t.string)])), + postInCaseLog: tNullable(t.boolean), + hide_case: tNullable(t.boolean), + }), + + defaultConfig: { + notify: null, // Use defaults from ModActions + hide_case: false, + }, + + async apply({ pluginData, actionConfig, actionName, interaction }) { + const duration = actionConfig.duration ? convertDelayStringToMS(actionConfig.duration)! : undefined; + const reason = actionConfig.reason || "Context Menu Action"; + const contactMethods = actionConfig.notify ? resolveActionContactMethods(pluginData, actionConfig) : undefined; + const rolesToRemove = actionConfig.remove_roles_on_mute; + const rolesToRestore = actionConfig.restore_roles_on_mute; + + const caseArgs: Partial = { + modId: pluginData.client.user!.id, + automatic: true, + postInCaseLogOverride: actionConfig.postInCaseLog ?? undefined, + hide: Boolean(actionConfig.hide_case), + }; + + interaction.deferReply({ ephemeral: true }); + const mutes = pluginData.getPlugin(MutesPlugin); + const userId = interaction.targetId; + const targetMember = await pluginData.guild.members.fetch(interaction.targetId); + const executingMember = await pluginData.guild.members.fetch(interaction.user.id); + + if (!canActOn(pluginData, executingMember, targetMember)) { + interaction.followUp({ ephemeral: true, content: "Cannot mute: insufficient permissions" }); + return; + } + + try { + const result = await mutes.muteUser( + userId, + duration, + reason, + { contactMethods, caseArgs, isAutomodAction: true }, + rolesToRemove, + rolesToRestore, + ); + + const muteMessage = `Muted **${result.case.user_name}** ${ + duration ? `for ${humanizeDuration(duration)}` : "indefinitely" + } (Case #${result.case.case_number}) (user notified via ${result.notifyResult.method ?? + "dm"})\nPlease update the new case with the \`update\` command`; + + interaction.followUp({ ephemeral: true, content: muteMessage }); + } catch (e) { + interaction.followUp({ ephemeral: true, content: "Plugin error, please check your BOT_ALERTs" }); + + if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { + pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, { + body: `Failed to mute <@!${userId}> in ContextMenu action \`${actionName}\` because a mute role has not been specified in server config`, + }); + } else { + throw e; + } + } + }, +}); diff --git a/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts b/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts new file mode 100644 index 00000000..62675e41 --- /dev/null +++ b/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts @@ -0,0 +1,13 @@ +import { ContextMenuInteraction } from "discord.js"; +import { contextMenuEvt } from "../types"; +import { routeContextAction } from "../utils/contextRouter"; + +export const ContextClickedEvt = contextMenuEvt({ + event: "interactionCreate", + + async listener(meta) { + if (!meta.args.interaction.isContextMenu) return; + const inter = meta.args.interaction as ContextMenuInteraction; + await routeContextAction(meta.pluginData, inter); + }, +}); diff --git a/backend/src/plugins/ContextMenus/helpers.ts b/backend/src/plugins/ContextMenus/helpers.ts new file mode 100644 index 00000000..5a98f505 --- /dev/null +++ b/backend/src/plugins/ContextMenus/helpers.ts @@ -0,0 +1,25 @@ +import { ContextMenuInteraction } from "discord.js"; +import * as t from "io-ts"; +import { GuildPluginData } from "../../../../../Knub/dist"; +import { Awaitable } from "../../../../../Knub/dist/utils"; +import { ContextMenuPluginType } from "./types"; + +type ContextActionApplyFn = (meta: { + actionName: string; + pluginData: GuildPluginData; + actionConfig: TConfigType; + interaction: ContextMenuInteraction; +}) => Awaitable; + +export interface ContextActionBlueprint { + configType: TConfigType; + defaultConfig: Partial>; + + apply: ContextActionApplyFn>; +} + +export function contextMenuAction( + blueprint: ContextActionBlueprint, +): ContextActionBlueprint { + return blueprint; +} diff --git a/backend/src/plugins/ContextMenus/types.ts b/backend/src/plugins/ContextMenus/types.ts new file mode 100644 index 00000000..9b34cb6a --- /dev/null +++ b/backend/src/plugins/ContextMenus/types.ts @@ -0,0 +1,38 @@ +import * as t from "io-ts"; +import { BasePluginType, typedGuildCommand, typedGuildEventListener } from "knub"; +import { GuildContextMenuLinks } from "../../data/GuildContextMenuLinks"; +import { tNullable } from "../../utils"; +import { AvailableActions } from "./actions/availableActions"; + +export enum ContextMenuTypes { + USER = 2, + MESSAGE = 3, +} + +export const ContextMenuTypeNameToNumber: Record = { + USER: 2, + MESSAGE: 3, +}; + +const ContextActionOpts = t.type({ + enabled: tNullable(t.boolean), + label: t.string, + type: t.keyof(ContextMenuTypes), + action: t.partial(AvailableActions.props), +}); +export type TContextActionOpts = t.TypeOf; + +export const ConfigSchema = t.type({ + context_actions: t.record(t.string, ContextActionOpts), +}); +export type TConfigSchema = t.TypeOf; + +export interface ContextMenuPluginType extends BasePluginType { + config: TConfigSchema; + state: { + contextMenuLinks: GuildContextMenuLinks; + }; +} + +export const contextMenuCmd = typedGuildCommand(); +export const contextMenuEvt = typedGuildEventListener(); diff --git a/backend/src/plugins/ContextMenus/utils/contextRouter.ts b/backend/src/plugins/ContextMenus/utils/contextRouter.ts new file mode 100644 index 00000000..c3fd3abe --- /dev/null +++ b/backend/src/plugins/ContextMenus/utils/contextRouter.ts @@ -0,0 +1,28 @@ +import { ContextMenuInteraction } from "discord.js"; +import { GuildPluginData } from "../../../../../../Knub/dist"; +import { availableActions } from "../actions/availableActions"; +import { ContextMenuPluginType } from "../types"; + +export async function routeContextAction( + pluginData: GuildPluginData, + interaction: ContextMenuInteraction, +) { + const contextLink = await pluginData.state.contextMenuLinks.get(interaction.commandId); + if (!contextLink) return; + const contextActions = Object.entries(pluginData.config.get().context_actions); + + const configLink = contextActions.find(x => x[0] === contextLink.action_name); + if (!configLink) return; + + for (const [actionName, actionConfig] of Object.entries(configLink[1].action)) { + if (actionConfig == null) return; + const action = availableActions[actionName]; + action.apply({ + actionName, + pluginData, + actionConfig, + interaction, + }); + return; + } +} diff --git a/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts b/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts new file mode 100644 index 00000000..a83cbd4a --- /dev/null +++ b/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts @@ -0,0 +1,37 @@ +import { ApplicationCommandData } from "discord.js"; +import { LogType } from "src/data/LogType"; +import { LogsPlugin } from "src/plugins/Logs/LogsPlugin"; +import { GuildPluginData } from "../../../../../../Knub/dist"; +import { ContextMenuPluginType, ContextMenuTypeNameToNumber } from "../types"; + +export async function loadAllCommands(pluginData: GuildPluginData) { + const comms = await pluginData.client.application!.commands; + const actions = pluginData.config.get().context_actions; + const newCommands: ApplicationCommandData[] = []; + const addedNames: string[] = []; + + for (const [name, configAction] of Object.entries(actions)) { + if (!configAction.enabled) continue; + + const data: ApplicationCommandData = { + type: ContextMenuTypeNameToNumber[configAction.type], + name: configAction.label, + }; + addedNames.push(name); + newCommands.push(data); + } + + const setCommands = await comms.set(newCommands, pluginData.guild.id).catch(e => { + pluginData.getPlugin(LogsPlugin).log(LogType.BOT_ALERT, `Unable to overwrite context menus: ${e}`); + return undefined; + }); + if (!setCommands) return; + + const setCommandsArray = [...setCommands.values()]; + await pluginData.state.contextMenuLinks.deleteAll(); + + for (let i = 0; i < setCommandsArray.length; i++) { + const command = setCommandsArray[i]; + pluginData.state.contextMenuLinks.create(command.id, addedNames[i]); + } +} diff --git a/backend/src/plugins/ContextMenus/utils/resolveActionContactMethods.ts b/backend/src/plugins/ContextMenus/utils/resolveActionContactMethods.ts new file mode 100644 index 00000000..bec64765 --- /dev/null +++ b/backend/src/plugins/ContextMenus/utils/resolveActionContactMethods.ts @@ -0,0 +1,32 @@ +import { Snowflake, TextChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; +import { ContextMenuPluginType } from "../types"; + +export function resolveActionContactMethods( + pluginData: GuildPluginData, + actionConfig: { + notify?: string | null; + notifyChannel?: string | null; + }, +): UserNotificationMethod[] { + if (actionConfig.notify === "dm") { + return [{ type: "dm" }]; + } else if (actionConfig.notify === "channel") { + if (!actionConfig.notifyChannel) { + throw new RecoverablePluginError(ERRORS.NO_USER_NOTIFICATION_CHANNEL); + } + + const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel as Snowflake); + if (!(channel instanceof TextChannel)) { + throw new RecoverablePluginError(ERRORS.INVALID_USER_NOTIFICATION_CHANNEL); + } + + return [{ type: "channel", channel }]; + } else if (actionConfig.notify && disableUserNotificationStrings.includes(actionConfig.notify)) { + return []; + } + + return []; +} diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 2b7a7b41..a2e9a6e7 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -13,7 +13,7 @@ import { AboutCmd } from "./commands/AboutCmd"; import { AvatarCmd } from "./commands/AvatarCmd"; import { BanSearchCmd } from "./commands/BanSearchCmd"; import { ChannelInfoCmd } from "./commands/ChannelInfoCmd"; -import { CleanCmd } from "./commands/CleanCmd"; +import { CleanArgs, cleanCmd, CleanCmd } from "./commands/CleanCmd"; import { ContextCmd } from "./commands/ContextCmd"; import { EmojiInfoCmd } from "./commands/EmojiInfoCmd"; import { HelpCmd } from "./commands/HelpCmd"; @@ -156,6 +156,14 @@ export const UtilityPlugin = zeppelinGuildPlugin()({ AutoJoinThreadSyncEvt, ], + public: { + clean(pluginData) { + return (args: CleanArgs, msg) => { + cleanCmd(pluginData, args, msg); + }; + }, + }, + beforeLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index ca96d57f..c7f8e6c3 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -10,12 +10,13 @@ import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../plugi import { allowTimeout } from "../../../RegExpRunner"; import { DAYS, getInviteCodesInString, noop, SECONDS } from "../../../utils"; import { utilityCmd, UtilityPluginType } from "../types"; +import { boolean, number } from "io-ts"; const MAX_CLEAN_COUNT = 150; const MAX_CLEAN_TIME = 1 * DAYS; const CLEAN_COMMAND_DELETE_DELAY = 5 * SECONDS; -async function cleanMessages( +export async function cleanMessages( pluginData: GuildPluginData, channel: TextChannel, savedMessages: SavedMessage[], @@ -61,6 +62,142 @@ const opts = { "to-id": ct.anyId({ option: true, shortcut: "id" }), }; +export interface CleanArgs { + count: number; + update?: boolean; + user?: string; + channel?: string; + bots?: boolean; + "delete-pins"?: boolean; + "has-invites"?: boolean; + match?: RegExp; + "to-id"?: string; +} + +export async function cleanCmd(pluginData: GuildPluginData, args: CleanArgs | any, msg) { + if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { + sendErrorMessage(pluginData, msg.channel, `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`); + return; + } + + const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; + if (!targetChannel || !(targetChannel instanceof TextChannel)) { + sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`); + return; + } + + if (targetChannel.id !== msg.channel.id) { + const configForTargetChannel = await pluginData.config.getMatchingConfig({ + userId: msg.author.id, + member: msg.member, + channelId: targetChannel.id, + categoryId: targetChannel.parentId, + }); + if (configForTargetChannel.can_clean !== true) { + sendErrorMessage(pluginData, msg.channel, `Missing permissions to use clean on that channel`); + return; + } + } + + const cleaningMessage = msg.channel.send("Cleaning..."); + + const messagesToClean: SavedMessage[] = []; + let beforeId = msg.id; + const timeCutoff = msg.createdTimestamp - MAX_CLEAN_TIME; + const upToMsgId = args["to-id"]; + let foundId = false; + + const deletePins = args["delete-pins"] != null ? args["delete-pins"] : false; + let pins: Message[] = []; + if (!deletePins) { + pins = [...(await msg.channel.messages.fetchPinned().catch(() => [])).values()]; + } + + while (messagesToClean.length < args.count) { + const potentialMessages = await targetChannel.messages.fetch({ + before: beforeId, + limit: args.count, + }); + if (potentialMessages.size === 0) break; + + const existingStored = await pluginData.state.savedMessages.getMultiple([...potentialMessages.keys()]); + const alreadyStored = existingStored.map(stored => stored.id); + const messagesToStore = [ + ...potentialMessages.filter(potentialMsg => !alreadyStored.includes(potentialMsg.id)).values(), + ]; + await pluginData.state.savedMessages.createFromMessages(messagesToStore); + + const potentialMessagesToClean = await pluginData.state.savedMessages.getMultiple([...potentialMessages.keys()]); + if (potentialMessagesToClean.length === 0) break; + + const filtered: SavedMessage[] = []; + for (const message of potentialMessagesToClean) { + const contentString = message.data.content || ""; + if (args.user && message.user_id !== args.user) continue; + if (args.bots && !message.is_bot) continue; + if (!deletePins && pins.find(x => x.id === message.id) != null) continue; + if (args["has-invites"] && getInviteCodesInString(contentString).length === 0) continue; + if (upToMsgId != null && message.id < upToMsgId) { + foundId = true; + break; + } + if (moment.utc(message.posted_at).valueOf() < timeCutoff) continue; + if (args.match && !(await pluginData.state.regexRunner.exec(args.match, contentString).catch(allowTimeout))) { + continue; + } + + filtered.push(message); + } + const remaining = args.count - messagesToClean.length; + const withoutOverflow = filtered.slice(0, remaining); + messagesToClean.push(...withoutOverflow); + + beforeId = potentialMessages.lastKey()!; + + if (foundId || moment.utc(potentialMessages.last()!.createdTimestamp).valueOf() < timeCutoff) { + break; + } + } + + let responseMsg: Message | undefined; + if (messagesToClean.length > 0) { + const cleanResult = await cleanMessages(pluginData, targetChannel, messagesToClean, msg.author); + + let responseText = `Cleaned ${messagesToClean.length} ${messagesToClean.length === 1 ? "message" : "messages"}`; + if (targetChannel.id !== msg.channel.id) { + responseText += ` in <#${targetChannel.id}>: ${cleanResult.archiveUrl}`; + } + + if (args.update) { + const modActions = pluginData.getPlugin(ModActionsPlugin); + const channelId = targetChannel.id !== msg.channel.id ? targetChannel.id : msg.channel.id; + const updateMessage = `Cleaned ${messagesToClean.length} ${ + messagesToClean.length === 1 ? "message" : "messages" + } in <#${channelId}>: ${cleanResult.archiveUrl}`; + if (typeof args.update === "number") { + modActions.updateCase(msg, args.update, updateMessage); + } else { + modActions.updateCase(msg, null, updateMessage); + } + } + + responseMsg = await sendSuccessMessage(pluginData, msg.channel, responseText); + } else { + responseMsg = await sendErrorMessage(pluginData, msg.channel, `Found no messages to clean!`); + } + + await (await cleaningMessage).delete(); + + if (targetChannel.id === msg.channel.id) { + // Delete the !clean command and the bot response if a different channel wasn't specified + // (so as not to spam the cleaned channel with the command itself) + setTimeout(() => { + msg.delete().catch(noop); + responseMsg?.delete().catch(noop); + }, CLEAN_COMMAND_DELETE_DELAY); + } +} + export const CleanCmd = utilityCmd({ trigger: ["clean", "clear"], description: "Remove a number of recent messages", @@ -83,126 +220,6 @@ export const CleanCmd = utilityCmd({ ], async run({ message: msg, args, pluginData }) { - if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { - sendErrorMessage(pluginData, msg.channel, `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`); - return; - } - - const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; - if (!targetChannel || !(targetChannel instanceof TextChannel)) { - sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`); - return; - } - - if (targetChannel.id !== msg.channel.id) { - const configForTargetChannel = await pluginData.config.getMatchingConfig({ - userId: msg.author.id, - member: msg.member, - channelId: targetChannel.id, - categoryId: targetChannel.parentId, - }); - if (configForTargetChannel.can_clean !== true) { - sendErrorMessage(pluginData, msg.channel, `Missing permissions to use clean on that channel`); - return; - } - } - - const cleaningMessage = msg.channel.send("Cleaning..."); - - const messagesToClean: SavedMessage[] = []; - let beforeId = msg.id; - const timeCutoff = msg.createdTimestamp - MAX_CLEAN_TIME; - const upToMsgId = args["to-id"]; - let foundId = false; - - const deletePins = args["delete-pins"] != null ? args["delete-pins"] : false; - let pins: Message[] = []; - if (!deletePins) { - pins = [...(await msg.channel.messages.fetchPinned().catch(() => [])).values()]; - } - - while (messagesToClean.length < args.count) { - const potentialMessages = await targetChannel.messages.fetch({ - before: beforeId, - limit: args.count, - }); - if (potentialMessages.size === 0) break; - - const existingStored = await pluginData.state.savedMessages.getMultiple([...potentialMessages.keys()]); - const alreadyStored = existingStored.map(stored => stored.id); - const messagesToStore = [ - ...potentialMessages.filter(potentialMsg => !alreadyStored.includes(potentialMsg.id)).values(), - ]; - await pluginData.state.savedMessages.createFromMessages(messagesToStore); - - const potentialMessagesToClean = await pluginData.state.savedMessages.getMultiple([...potentialMessages.keys()]); - if (potentialMessagesToClean.length === 0) break; - - const filtered: SavedMessage[] = []; - for (const message of potentialMessagesToClean) { - const contentString = message.data.content || ""; - if (args.user && message.user_id !== args.user) continue; - if (args.bots && !message.is_bot) continue; - if (!deletePins && pins.find(x => x.id === message.id) != null) continue; - if (args["has-invites"] && getInviteCodesInString(contentString).length === 0) continue; - if (upToMsgId != null && message.id < upToMsgId) { - foundId = true; - break; - } - if (moment.utc(message.posted_at).valueOf() < timeCutoff) continue; - if (args.match && !(await pluginData.state.regexRunner.exec(args.match, contentString).catch(allowTimeout))) { - continue; - } - - filtered.push(message); - } - const remaining = args.count - messagesToClean.length; - const withoutOverflow = filtered.slice(0, remaining); - messagesToClean.push(...withoutOverflow); - - beforeId = potentialMessages.lastKey()!; - - if (foundId || moment.utc(potentialMessages.last()!.createdTimestamp).valueOf() < timeCutoff) { - break; - } - } - - let responseMsg: Message | undefined; - if (messagesToClean.length > 0) { - const cleanResult = await cleanMessages(pluginData, targetChannel, messagesToClean, msg.author); - - let responseText = `Cleaned ${messagesToClean.length} ${messagesToClean.length === 1 ? "message" : "messages"}`; - if (targetChannel.id !== msg.channel.id) { - responseText += ` in <#${targetChannel.id}>: ${cleanResult.archiveUrl}`; - } - - if (args.update) { - const modActions = pluginData.getPlugin(ModActionsPlugin); - const channelId = targetChannel.id !== msg.channel.id ? targetChannel.id : msg.channel.id; - const updateMessage = `Cleaned ${messagesToClean.length} ${ - messagesToClean.length === 1 ? "message" : "messages" - } in <#${channelId}>: ${cleanResult.archiveUrl}`; - if (typeof args.update === "number") { - modActions.updateCase(msg, args.update, updateMessage); - } else { - modActions.updateCase(msg, null, updateMessage); - } - } - - responseMsg = await sendSuccessMessage(pluginData, msg.channel, responseText); - } else { - responseMsg = await sendErrorMessage(pluginData, msg.channel, `Found no messages to clean!`); - } - - await (await cleaningMessage).delete(); - - if (targetChannel.id === msg.channel.id) { - // Delete the !clean command and the bot response if a different channel wasn't specified - // (so as not to spam the cleaned channel with the command itself) - setTimeout(() => { - msg.delete().catch(noop); - responseMsg?.delete().catch(noop); - }, CLEAN_COMMAND_DELETE_DELAY); - } + cleanCmd(pluginData, args, msg); }, }); diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index d1788bce..5052ac11 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -134,9 +134,8 @@ export async function getChannelInfoEmbed( const memberCount = thread.memberCount ?? thread.members.cache.size; const owner = await thread.fetchOwner().catch(() => null); const ownerMention = owner?.user ? verboseUserMention(owner.user) : "Unknown#0000"; - const humanizedArchiveTime = `Archive duration: **${humanizeDuration( - (thread.autoArchiveDuration ?? 0) * MINUTES, - )}**`; + const autoArchiveDuration = thread.autoArchiveDuration === "MAX" ? 10080 : thread.autoArchiveDuration; // TODO: Boost level check + const humanizedArchiveTime = `Archive duration: **${humanizeDuration((autoArchiveDuration ?? 0) * MINUTES)}**`; embed.fields.push({ name: preEmbedPadding + "Thread information", diff --git a/backend/src/plugins/availablePlugins.ts b/backend/src/plugins/availablePlugins.ts index 3f0568f6..34535b7c 100644 --- a/backend/src/plugins/availablePlugins.ts +++ b/backend/src/plugins/availablePlugins.ts @@ -6,6 +6,7 @@ import { CasesPlugin } from "./Cases/CasesPlugin"; import { CensorPlugin } from "./Censor/CensorPlugin"; import { ChannelArchiverPlugin } from "./ChannelArchiver/ChannelArchiverPlugin"; import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin"; +import { ContextMenuPlugin } from "./ContextMenus/ContextMenuPlugin"; import { CountersPlugin } from "./Counters/CountersPlugin"; import { CustomEventsPlugin } from "./CustomEvents/CustomEventsPlugin"; import { GuildAccessMonitorPlugin } from "./GuildAccessMonitor/GuildAccessMonitorPlugin"; @@ -67,6 +68,7 @@ export const guildPlugins: Array> = [ CustomEventsPlugin, TimeAndDatePlugin, CountersPlugin, + ContextMenuPlugin, ]; // prettier-ignore