huge changes once again
diff --git a/ClicksMigratingProblems/randomPunishments.js b/ClicksMigratingProblems/randomPunishments.js
new file mode 100644
index 0000000..a2d9bf5
--- /dev/null
+++ b/ClicksMigratingProblems/randomPunishments.js
@@ -0,0 +1,26 @@
+import { MongoClient } from 'mongodb';
+
+const mongoClient = new MongoClient('mongodb://127.0.0.1:27017/local');
+await mongoClient.connect()
+const database = mongoClient.db("Nucleus");
+const collection = database.collection("history");
+
+for (let i = 0; i < 100; i++) {
+ // Select a type
+ let type = ["join", "unban", "leave", "ban", "softban", "kick", "mute", "purge", "warn", "nickname"][Math.floor(Math.random() * 9)];
+ // Select a random date in the last year
+ let date = new Date(new Date().getTime() - Math.floor(Math.random() * 31536000000));
+ // Add to database
+ await collection.insertOne({
+ type: type,
+ occurredAt: date,
+ user: "438733159748599813",
+ guild: "864185037078790195",
+ moderator: (["unban", "ban", "softban", "kick", "mute", "purge", "warn"].includes(type)) ? "438733159748599813" : null,
+ reason: (["unban", "ban", "softban", "kick", "mute", "purge", "warn"].includes(type)) ? "Test" : null,
+ before: (type == "nickname") ? "TestBefore" : null,
+ after: (type == "nickname") ? "TestAfter" : null,
+ amount: (type == "purge") ? Math.floor(Math.random() * 100) : null,
+ });
+ console.log("Inserted document " + i);
+}
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 3e187f2..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,2920 +0,0 @@
-{
- "name": "nucleus",
- "version": "0.0.1",
- "lockfileVersion": 2,
- "requires": true,
- "packages": {
- "": {
- "name": "nucleus",
- "version": "0.0.1",
- "license": "SEE LICENSE IN LICENSE",
- "dependencies": {
- "@discordjs/builders": "^0.12.0",
- "@ungap/structured-clone": "^1.0.1",
- "body-parser": "^1.20.0",
- "discord.js": "^13.8.0",
- "express": "^4.18.1",
- "humanize": "^0.0.9",
- "humanize-duration": "^3.27.1",
- "jshaiku": "file:../haiku",
- "json-diff": "^0.7.1",
- "mongodb": "^4.7.0",
- "node-tesseract": "^0.2.7",
- "structured-clone": "^0.2.2",
- "tesseract.js": "^2.1.5",
- "typescript": "^4.5.5",
- "unscan": "^1.1.2"
- }
- },
- "../haiku": {
- "name": "jshaiku",
- "version": "1.0.0",
- "license": "AGPL-3.0",
- "dependencies": {
- "@discordjs/builders": "^0.11.0",
- "@discordjs/rest": "^0.2.0-canary.0",
- "@types/node-cron": "^3.0.1",
- "ansi-styles": "^6.1.0",
- "chalk": "^5.0.0",
- "discord-api-types": "^0.26.1",
- "discord.js": "^13.8.0",
- "node-cron": "^3.0.0"
- },
- "devDependencies": {
- "@babel/core": "^7.16.7",
- "@babel/preset-env": "^7.16.8",
- "@babel/preset-typescript": "^7.16.7",
- "@types/jest": "^27.4.0",
- "babel-jest": "^27.4.6",
- "jest": "^27.4.7",
- "ts-node": "^10.4.0",
- "typescript": "4.5.4"
- }
- },
- "node_modules/@discordjs/builders": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.12.0.tgz",
- "integrity": "sha512-Vx2MjUZd6QVo1uS2uWt708Fd6cHWGFblAvbpL5EBO+kLl0BADmPwwvts+YJ/VfSywed6Vsk6K2cEooR/Ytjhjw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@sindresorhus/is": "^4.3.0",
- "discord-api-types": "^0.26.1",
- "ts-mixer": "^6.0.0",
- "tslib": "^2.3.1",
- "zod": "^3.11.6"
- },
- "engines": {
- "node": ">=16.9.0"
- }
- },
- "node_modules/@discordjs/collection": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
- "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==",
- "engines": {
- "node": ">=16.9.0"
- }
- },
- "node_modules/@sapphire/async-queue": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.3.1.tgz",
- "integrity": "sha512-FFTlPOWZX1kDj9xCAsRzH5xEJfawg1lNoYAA+ecOWJMHOfiZYb1uXOI3ne9U4UILSEPwfE68p3T9wUHwIQfR0g==",
- "engines": {
- "node": ">=v14.0.0",
- "npm": ">=7.0.0"
- }
- },
- "node_modules/@sapphire/shapeshift": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.2.0.tgz",
- "integrity": "sha512-asNgE5Ooil2/oGIAj6vZMoUc2ZFED0TGYD7jwvZsjHPQZBEh9ITj94ca4bCgiCR1s2ER/UjzykH+5wE3ebVZnQ==",
- "engines": {
- "node": ">=v15.0.0",
- "npm": ">=7.0.0"
- }
- },
- "node_modules/@sindresorhus/is": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
- "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/is?sponsor=1"
- }
- },
- "node_modules/@types/node": {
- "version": "17.0.21",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
- "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==",
- "license": "MIT"
- },
- "node_modules/@types/node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "form-data": "^3.0.0"
- }
- },
- "node_modules/@types/node-fetch/node_modules/form-data": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
- "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/@types/webidl-conversions": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
- "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==",
- "license": "MIT"
- },
- "node_modules/@types/whatwg-url": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
- "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "@types/webidl-conversions": "*"
- }
- },
- "node_modules/@types/ws": {
- "version": "8.5.3",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
- "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@ungap/structured-clone": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.0.1.tgz",
- "integrity": "sha512-zKVyTt6rELvPXYwcVPTJcPFtY0AckN5A7xWuc7owBqR0FdtuDYhE9MZZUi6IY1kZUQFSXV1B3UOOIyLkVHYd2w==",
- "license": "ISC"
- },
- "node_modules/accepts": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
- "license": "MIT"
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
- "license": "MIT"
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "license": "MIT"
- },
- "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"
- }
- ],
- "license": "MIT"
- },
- "node_modules/blueimp-load-image": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-3.0.0.tgz",
- "integrity": "sha512-Q9rFbd4ZUNvzSFmRXx9MoG0RwWwJeMjjEUbG7WIOJgUg22Jgkow0wL5b35B6qwiBscxACW9OHdrP5s2vQ3x8DQ==",
- "license": "MIT"
- },
- "node_modules/bmp-js": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
- "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=",
- "license": "MIT"
- },
- "node_modules/body-parser": {
- "version": "1.20.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
- "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.10.3",
- "raw-body": "2.5.1",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/bson": {
- "version": "4.6.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.4.tgz",
- "integrity": "sha512-TdQ3FzguAu5HKPPlr0kYQCyrYUYh8tFM+CMTpxjNzVzxeiJY00Rtuj3LXLHSgiGvmaWlZ8PE+4KyM2thqE38pQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "buffer": "^5.6.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "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"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
- }
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/cli-color": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.1.tgz",
- "integrity": "sha512-eBbxZF6fqPUNnf7CLAFOersUnyYzv83tHFLSlts+OAHsNendaqv2tHCq+/MO+b3Y+9JeoUlIvobyxG/Z8GNeOg==",
- "license": "ISC",
- "dependencies": {
- "d": "^1.0.1",
- "es5-ext": "^0.10.53",
- "es6-iterator": "^2.0.3",
- "memoizee": "^0.4.15",
- "timers-ext": "^0.1.7"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/colors": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
- "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.1.90"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/commander": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
- "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
- "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=",
- "license": "MIT"
- },
- "node_modules/content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "5.2.1"
- },
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
- "license": "MIT",
- "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=",
- "license": "MIT"
- },
- "node_modules/d": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
- "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
- "license": "ISC",
- "dependencies": {
- "es5-ext": "^0.10.50",
- "type": "^1.0.1"
- }
- },
- "node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "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=",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/denque": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
- "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/difflib": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz",
- "integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=",
- "dependencies": {
- "heap": ">= 0.2.0"
- }
- },
- "node_modules/discord-api-types": {
- "version": "0.26.1",
- "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz",
- "integrity": "sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/discord.js": {
- "version": "13.8.0",
- "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz",
- "integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==",
- "dependencies": {
- "@discordjs/builders": "^0.14.0",
- "@discordjs/collection": "^0.7.0",
- "@sapphire/async-queue": "^1.3.1",
- "@types/node-fetch": "^2.6.1",
- "@types/ws": "^8.5.3",
- "discord-api-types": "^0.33.3",
- "form-data": "^4.0.0",
- "node-fetch": "^2.6.1",
- "ws": "^8.7.0"
- },
- "engines": {
- "node": ">=16.6.0",
- "npm": ">=7.0.0"
- }
- },
- "node_modules/discord.js/node_modules/@discordjs/builders": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz",
- "integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==",
- "dependencies": {
- "@sapphire/shapeshift": "^3.1.0",
- "@sindresorhus/is": "^4.6.0",
- "discord-api-types": "^0.33.3",
- "fast-deep-equal": "^3.1.3",
- "ts-mixer": "^6.0.1",
- "tslib": "^2.4.0"
- },
- "engines": {
- "node": ">=16.9.0"
- }
- },
- "node_modules/discord.js/node_modules/discord-api-types": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
- "integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
- },
- "node_modules/dreamopt": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.8.0.tgz",
- "integrity": "sha1-W8yAvnCX5F/EicNCQFq2gUCowdk=",
- "dependencies": {
- "wordwrap": ">=0.0.2"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
- "license": "MIT"
- },
- "node_modules/encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/es5-ext": {
- "version": "0.10.57",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.57.tgz",
- "integrity": "sha512-L7cCNoPwTkAp7IBHxrKLsh7NKiVFkcdxlP9vbVw9QUvb7gF0Mz9bEBN0WY9xqdTjGF907EMT/iG013vnbqwu1Q==",
- "hasInstallScript": true,
- "license": "ISC",
- "dependencies": {
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.3",
- "next-tick": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
- "license": "MIT",
- "dependencies": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
- "node_modules/es6-symbol": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
- "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
- "license": "ISC",
- "dependencies": {
- "d": "^1.0.1",
- "ext": "^1.1.2"
- }
- },
- "node_modules/es6-weak-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
- "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
- "license": "ISC",
- "dependencies": {
- "d": "1",
- "es5-ext": "^0.10.46",
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.1"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
- "license": "MIT"
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/event-emitter": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
- "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
- "license": "MIT",
- "dependencies": {
- "d": "1",
- "es5-ext": "~0.10.14"
- }
- },
- "node_modules/express": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
- "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
- "license": "MIT",
- "dependencies": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.0",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.5.0",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.2.0",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.7",
- "qs": "6.10.3",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.18.0",
- "serve-static": "1.15.0",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "engines": {
- "node": ">= 0.10.0"
- }
- },
- "node_modules/ext": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
- "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
- "license": "ISC",
- "dependencies": {
- "type": "^2.5.0"
- }
- },
- "node_modules/ext/node_modules/type": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz",
- "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==",
- "license": "ISC"
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
- },
- "node_modules/file-type": {
- "version": "12.4.2",
- "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz",
- "integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
- "license": "ISC"
- },
- "node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
- "license": "MIT"
- },
- "node_modules/get-intrinsic": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
- "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/glob": {
- "version": "5.0.15",
- "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
- "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
- "license": "ISC",
- "dependencies": {
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "2 || 3",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/heap": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz",
- "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==",
- "license": "MIT"
- },
- "node_modules/http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/humanize": {
- "version": "0.0.9",
- "resolved": "https://registry.npmjs.org/humanize/-/humanize-0.0.9.tgz",
- "integrity": "sha1-GZT/rs3+nEQe0r2sdFK3u0yeQaQ=",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/humanize-duration": {
- "version": "3.27.1",
- "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.1.tgz",
- "integrity": "sha512-jCVkMl+EaM80rrMrAPl96SGG4NRac53UyI1o/yAzebDntEY6K6/Fj2HOjdPg8omTqIe5Y0wPBai2q5xXrIbarA==",
- "license": "Unlicense"
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/idb-keyval": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.2.0.tgz",
- "integrity": "sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ==",
- "license": "Apache-2.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"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "license": "ISC",
- "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==",
- "license": "ISC"
- },
- "node_modules/ip": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
- "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
- "license": "MIT"
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-electron": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.1.tgz",
- "integrity": "sha512-r8EEQQsqT+Gn0aXFx7lTFygYQhILLCB+wn0WCDL5LZRINeLH/Rvw1j2oKodELLXYNImQ3CRlVsY8wW4cGOsyuw==",
- "license": "MIT"
- },
- "node_modules/is-promise": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
- "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
- "license": "MIT"
- },
- "node_modules/is-url": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
- "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==",
- "license": "MIT"
- },
- "node_modules/jpeg-autorotate": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/jpeg-autorotate/-/jpeg-autorotate-7.1.1.tgz",
- "integrity": "sha512-ewTZTG/QWOM0D5h/yKcQ3QgyrnQYsr3qmcS+bqoAwgQAY1KBa31aJ+q+FlElaxo/rSYqfF1ixf+8EIgluBkgTg==",
- "license": "MIT",
- "dependencies": {
- "colors": "^1.4.0",
- "glob": "^7.1.6",
- "jpeg-js": "^0.4.2",
- "piexifjs": "^1.0.6",
- "yargs-parser": "^20.2.1"
- },
- "bin": {
- "jpeg-autorotate": "src/cli.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jpeg-autorotate/node_modules/glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
- "license": "ISC",
- "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/jpeg-js": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz",
- "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==",
- "license": "BSD-3-Clause"
- },
- "node_modules/jshaiku": {
- "resolved": "../haiku",
- "link": true
- },
- "node_modules/json-diff": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.7.3.tgz",
- "integrity": "sha512-VBvNBt3cIrCBHa3gYbVsCFUEReqWZPf+Biq1ZtFdIiQ6rytRLDp3qvtrGv7z/iZDd1D4vXWpW7Nx1nP8muLzkg==",
- "license": "MIT",
- "dependencies": {
- "cli-color": "^2.0.0",
- "difflib": "~0.2.1",
- "dreamopt": "~0.8.0"
- },
- "bin": {
- "json-diff": "bin/json-diff.js"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/lru-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
- "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
- "license": "MIT",
- "dependencies": {
- "es5-ext": "~0.10.2"
- }
- },
- "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=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/memoizee": {
- "version": "0.4.15",
- "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
- "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==",
- "license": "ISC",
- "dependencies": {
- "d": "^1.0.1",
- "es5-ext": "^0.10.53",
- "es6-weak-map": "^2.0.3",
- "event-emitter": "^0.3.5",
- "is-promise": "^2.2.2",
- "lru-queue": "^0.1.0",
- "next-tick": "^1.1.0",
- "timers-ext": "^0.1.7"
- }
- },
- "node_modules/memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "license": "MIT",
- "optional": true
- },
- "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=",
- "license": "MIT"
- },
- "node_modules/methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/mime-db": {
- "version": "1.51.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
- "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.34",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
- "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.51.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/mongodb": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.7.0.tgz",
- "integrity": "sha512-HhVar6hsUeMAVlIbwQwWtV36iyjKd9qdhY+s4wcU8K6TOj4Q331iiMy+FoPuxEntDIijTYWivwFJkLv8q/ZgvA==",
- "license": "Apache-2.0",
- "dependencies": {
- "bson": "^4.6.3",
- "denque": "^2.0.1",
- "mongodb-connection-string-url": "^2.5.2",
- "socks": "^2.6.2"
- },
- "engines": {
- "node": ">=12.9.0"
- },
- "optionalDependencies": {
- "saslprep": "^1.0.3"
- }
- },
- "node_modules/mongodb-connection-string-url": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
- "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/whatwg-url": "^8.2.1",
- "whatwg-url": "^11.0.0"
- }
- },
- "node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "license": "MIT"
- },
- "node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/next-tick": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
- "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
- "license": "ISC"
- },
- "node_modules/node-fetch": {
- "version": "2.6.7",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
- "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-fetch/node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
- "license": "MIT"
- },
- "node_modules/node-fetch/node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/node-tesseract": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/node-tesseract/-/node-tesseract-0.2.7.tgz",
- "integrity": "sha1-yPAvuDUaQnByc1d4wFGYI/JgG4Q=",
- "license": "MIT",
- "dependencies": {
- "glob": "^5.0.10",
- "node-uuid": "^1.4.1"
- }
- },
- "node_modules/node-uuid": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
- "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=",
- "bin": {
- "uuid": "bin/uuid"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
- "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "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=",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/opencollective-postinstall": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
- "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==",
- "license": "MIT",
- "bin": {
- "opencollective-postinstall": "index.js"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.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=",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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=",
- "license": "MIT"
- },
- "node_modules/piexifjs": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/piexifjs/-/piexifjs-1.0.6.tgz",
- "integrity": "sha512-0wVyH0cKohzBQ5Gi2V1BuxYpxWfxF3cSqfFXfPIpl5tl9XLS5z4ogqhUCD20AbHi0h9aJkqXNJnkVev6gwh2ag==",
- "license": "MIT"
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "license": "MIT",
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/qs": {
- "version": "6.10.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
- "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.0.4"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "license": "MIT",
- "dependencies": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
- "license": "MIT"
- },
- "node_modules/resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
- "license": "MIT"
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "license": "MIT"
- },
- "node_modules/saslprep": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
- "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "sparse-bitfield": "^3.0.3"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/send": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
- "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "mime": "1.6.0",
- "ms": "2.1.3",
- "on-finished": "2.4.1",
- "range-parser": "~1.2.1",
- "statuses": "2.0.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/send/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.18.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/smart-buffer": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
- "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
- "license": "MIT",
- "engines": {
- "node": ">= 6.0.0",
- "npm": ">= 3.0.0"
- }
- },
- "node_modules/socks": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
- "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
- "license": "MIT",
- "dependencies": {
- "ip": "^1.1.5",
- "smart-buffer": "^4.2.0"
- },
- "engines": {
- "node": ">= 10.13.0",
- "npm": ">= 3.0.0"
- }
- },
- "node_modules/sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "memory-pager": "^1.0.2"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/structured-clone": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/structured-clone/-/structured-clone-0.2.2.tgz",
- "integrity": "sha1-rJK2vjGVimQ9sw8TNavGobAt/cI=",
- "license": "MIT"
- },
- "node_modules/tesseract.js": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-2.1.5.tgz",
- "integrity": "sha512-7CIS3SWr7TXpeaH9+HS7iUtVbCfPFYOO3p6rkRAkdtsOtrbz6496x59na6SCbFAIaZulQxy8BjwSu3qL3AoDRg==",
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "dependencies": {
- "blueimp-load-image": "^3.0.0",
- "bmp-js": "^0.1.0",
- "file-type": "^12.4.1",
- "idb-keyval": "^3.2.0",
- "is-electron": "^2.2.0",
- "is-url": "^1.2.4",
- "jpeg-autorotate": "^7.1.1",
- "node-fetch": "^2.6.0",
- "opencollective-postinstall": "^2.0.2",
- "regenerator-runtime": "^0.13.3",
- "resolve-url": "^0.2.1",
- "tesseract.js-core": "^2.2.0",
- "zlibjs": "^0.3.1"
- }
- },
- "node_modules/tesseract.js-core": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-2.2.0.tgz",
- "integrity": "sha512-a8L+OJTbUipBsEDsJhDPlnLB0TY1MkTZqw5dqUwmiDSjUzwvU7HWLg/2+WDRulKUi4LE+7PnHlaBlW0k+V0U0w==",
- "license": "Apache License 2.0"
- },
- "node_modules/timers-ext": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
- "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
- "license": "ISC",
- "dependencies": {
- "es5-ext": "~0.10.46",
- "next-tick": "1"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/tr46": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
- "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
- "license": "MIT",
- "dependencies": {
- "punycode": "^2.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/ts-mixer": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz",
- "integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg=="
- },
- "node_modules/tslib": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
- "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
- },
- "node_modules/type": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
- "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
- "license": "ISC"
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/typescript": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
- "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/unscan": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/unscan/-/unscan-1.1.2.tgz",
- "integrity": "sha512-a5RcGaBFMO9l78QWKffeWUo2cvfqUv05JCXuphE8MFOA92qyqp1Da7isnR+zjJspi45+yS8tTSuhd0vV3asWdA==",
- "license": "MIT",
- "dependencies": {
- "commander": "^8.3.0",
- "form-data": "^4.0.0",
- "node-fetch": "^2.6.5"
- },
- "bin": {
- "unscan": "bin/unscan.js"
- }
- },
- "node_modules/utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
- "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
- "license": "MIT",
- "dependencies": {
- "tr46": "^3.0.0",
- "webidl-conversions": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/whatwg-url/node_modules/webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
- "license": "MIT"
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
- "license": "ISC"
- },
- "node_modules/ws": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz",
- "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==",
- "engines": {
- "node": ">=10.0.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
- "node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/zlibjs": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
- "integrity": "sha1-UBl+2yihxCymWcyLTmqd3W1ERVQ=",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/zod": {
- "version": "3.13.4",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.13.4.tgz",
- "integrity": "sha512-LZRucWt4j/ru5azOkJxCfpR87IyFDn8h2UODdqvXzZLb3K7bb9chUrUIGTy3BPsr8XnbQYfQ5Md5Hu2OYIo1mg==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- },
- "dependencies": {
- "@discordjs/builders": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.12.0.tgz",
- "integrity": "sha512-Vx2MjUZd6QVo1uS2uWt708Fd6cHWGFblAvbpL5EBO+kLl0BADmPwwvts+YJ/VfSywed6Vsk6K2cEooR/Ytjhjw==",
- "requires": {
- "@sindresorhus/is": "^4.3.0",
- "discord-api-types": "^0.26.1",
- "ts-mixer": "^6.0.0",
- "tslib": "^2.3.1",
- "zod": "^3.11.6"
- }
- },
- "@discordjs/collection": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
- "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA=="
- },
- "@sapphire/async-queue": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.3.1.tgz",
- "integrity": "sha512-FFTlPOWZX1kDj9xCAsRzH5xEJfawg1lNoYAA+ecOWJMHOfiZYb1uXOI3ne9U4UILSEPwfE68p3T9wUHwIQfR0g=="
- },
- "@sapphire/shapeshift": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.2.0.tgz",
- "integrity": "sha512-asNgE5Ooil2/oGIAj6vZMoUc2ZFED0TGYD7jwvZsjHPQZBEh9ITj94ca4bCgiCR1s2ER/UjzykH+5wE3ebVZnQ=="
- },
- "@sindresorhus/is": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
- "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="
- },
- "@types/node": {
- "version": "17.0.21",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz",
- "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ=="
- },
- "@types/node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==",
- "requires": {
- "@types/node": "*",
- "form-data": "^3.0.0"
- },
- "dependencies": {
- "form-data": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
- "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- }
- }
- }
- },
- "@types/webidl-conversions": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
- "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
- },
- "@types/whatwg-url": {
- "version": "8.2.1",
- "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz",
- "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==",
- "requires": {
- "@types/node": "*",
- "@types/webidl-conversions": "*"
- }
- },
- "@types/ws": {
- "version": "8.5.3",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz",
- "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==",
- "requires": {
- "@types/node": "*"
- }
- },
- "@ungap/structured-clone": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.0.1.tgz",
- "integrity": "sha512-zKVyTt6rELvPXYwcVPTJcPFtY0AckN5A7xWuc7owBqR0FdtuDYhE9MZZUi6IY1kZUQFSXV1B3UOOIyLkVHYd2w=="
- },
- "accepts": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "requires": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- }
- },
- "array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
- },
- "balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
- },
- "base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
- },
- "blueimp-load-image": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-3.0.0.tgz",
- "integrity": "sha512-Q9rFbd4ZUNvzSFmRXx9MoG0RwWwJeMjjEUbG7WIOJgUg22Jgkow0wL5b35B6qwiBscxACW9OHdrP5s2vQ3x8DQ=="
- },
- "bmp-js": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
- "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
- },
- "body-parser": {
- "version": "1.20.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
- "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
- "requires": {
- "bytes": "3.1.2",
- "content-type": "~1.0.4",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "on-finished": "2.4.1",
- "qs": "6.10.3",
- "raw-body": "2.5.1",
- "type-is": "~1.6.18",
- "unpipe": "1.0.0"
- }
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "bson": {
- "version": "4.6.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.4.tgz",
- "integrity": "sha512-TdQ3FzguAu5HKPPlr0kYQCyrYUYh8tFM+CMTpxjNzVzxeiJY00Rtuj3LXLHSgiGvmaWlZ8PE+4KyM2thqE38pQ==",
- "requires": {
- "buffer": "^5.6.0"
- }
- },
- "buffer": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
- "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "requires": {
- "base64-js": "^1.3.1",
- "ieee754": "^1.1.13"
- }
- },
- "bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
- },
- "call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
- "requires": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
- }
- },
- "cli-color": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.1.tgz",
- "integrity": "sha512-eBbxZF6fqPUNnf7CLAFOersUnyYzv83tHFLSlts+OAHsNendaqv2tHCq+/MO+b3Y+9JeoUlIvobyxG/Z8GNeOg==",
- "requires": {
- "d": "^1.0.1",
- "es5-ext": "^0.10.53",
- "es6-iterator": "^2.0.3",
- "memoizee": "^0.4.15",
- "timers-ext": "^0.1.7"
- }
- },
- "colors": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
- "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
- },
- "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"
- }
- },
- "commander": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
- "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "content-disposition": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
- "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
- "requires": {
- "safe-buffer": "5.2.1"
- }
- },
- "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=="
- },
- "cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
- },
- "cookie-signature": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
- },
- "d": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
- "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
- "requires": {
- "es5-ext": "^0.10.50",
- "type": "^1.0.1"
- }
- },
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
- },
- "denque": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz",
- "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ=="
- },
- "depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
- },
- "destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
- },
- "difflib": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz",
- "integrity": "sha1-teMDYabbAjF21WKJLbhZQKcY9H4=",
- "requires": {
- "heap": ">= 0.2.0"
- }
- },
- "discord-api-types": {
- "version": "0.26.1",
- "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.26.1.tgz",
- "integrity": "sha512-T5PdMQ+Y1MEECYMV5wmyi9VEYPagEDEi4S0amgsszpWY0VB9JJ/hEvM6BgLhbdnKky4gfmZEXtEEtojN8ZKJQQ=="
- },
- "discord.js": {
- "version": "13.8.0",
- "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz",
- "integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==",
- "requires": {
- "@discordjs/builders": "^0.14.0",
- "@discordjs/collection": "^0.7.0",
- "@sapphire/async-queue": "^1.3.1",
- "@types/node-fetch": "^2.6.1",
- "@types/ws": "^8.5.3",
- "discord-api-types": "^0.33.3",
- "form-data": "^4.0.0",
- "node-fetch": "^2.6.1",
- "ws": "^8.7.0"
- },
- "dependencies": {
- "@discordjs/builders": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz",
- "integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==",
- "requires": {
- "@sapphire/shapeshift": "^3.1.0",
- "@sindresorhus/is": "^4.6.0",
- "discord-api-types": "^0.33.3",
- "fast-deep-equal": "^3.1.3",
- "ts-mixer": "^6.0.1",
- "tslib": "^2.4.0"
- }
- },
- "discord-api-types": {
- "version": "0.33.5",
- "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
- "integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
- }
- }
- },
- "dreamopt": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.8.0.tgz",
- "integrity": "sha1-W8yAvnCX5F/EicNCQFq2gUCowdk=",
- "requires": {
- "wordwrap": ">=0.0.2"
- }
- },
- "ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
- },
- "encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
- },
- "es5-ext": {
- "version": "0.10.57",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.57.tgz",
- "integrity": "sha512-L7cCNoPwTkAp7IBHxrKLsh7NKiVFkcdxlP9vbVw9QUvb7gF0Mz9bEBN0WY9xqdTjGF907EMT/iG013vnbqwu1Q==",
- "requires": {
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.3",
- "next-tick": "^1.1.0"
- }
- },
- "es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
- "es6-symbol": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
- "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
- "requires": {
- "d": "^1.0.1",
- "ext": "^1.1.2"
- }
- },
- "es6-weak-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
- "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.46",
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.1"
- }
- },
- "escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
- },
- "etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
- },
- "event-emitter": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
- "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
- "requires": {
- "d": "1",
- "es5-ext": "~0.10.14"
- }
- },
- "express": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
- "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
- "requires": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.0",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.5.0",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.2.0",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.7",
- "qs": "6.10.3",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.18.0",
- "serve-static": "1.15.0",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- }
- },
- "ext": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
- "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
- "requires": {
- "type": "^2.5.0"
- },
- "dependencies": {
- "type": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz",
- "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ=="
- }
- }
- },
- "fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
- },
- "file-type": {
- "version": "12.4.2",
- "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz",
- "integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg=="
- },
- "finalhandler": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
- }
- },
- "form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- }
- },
- "forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
- },
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
- },
- "get-intrinsic": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
- "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
- "requires": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1"
- }
- },
- "glob": {
- "version": "5.0.15",
- "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
- "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
- "requires": {
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "2 || 3",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "requires": {
- "function-bind": "^1.1.1"
- }
- },
- "has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
- },
- "heap": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz",
- "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg=="
- },
- "http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "requires": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- }
- },
- "humanize": {
- "version": "0.0.9",
- "resolved": "https://registry.npmjs.org/humanize/-/humanize-0.0.9.tgz",
- "integrity": "sha1-GZT/rs3+nEQe0r2sdFK3u0yeQaQ="
- },
- "humanize-duration": {
- "version": "3.27.1",
- "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.27.1.tgz",
- "integrity": "sha512-jCVkMl+EaM80rrMrAPl96SGG4NRac53UyI1o/yAzebDntEY6K6/Fj2HOjdPg8omTqIe5Y0wPBai2q5xXrIbarA=="
- },
- "iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "idb-keyval": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.2.0.tgz",
- "integrity": "sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ=="
- },
- "ieee754": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
- "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "ip": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
- "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
- },
- "ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
- },
- "is-electron": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.1.tgz",
- "integrity": "sha512-r8EEQQsqT+Gn0aXFx7lTFygYQhILLCB+wn0WCDL5LZRINeLH/Rvw1j2oKodELLXYNImQ3CRlVsY8wW4cGOsyuw=="
- },
- "is-promise": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
- "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
- },
- "is-url": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
- "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
- },
- "jpeg-autorotate": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/jpeg-autorotate/-/jpeg-autorotate-7.1.1.tgz",
- "integrity": "sha512-ewTZTG/QWOM0D5h/yKcQ3QgyrnQYsr3qmcS+bqoAwgQAY1KBa31aJ+q+FlElaxo/rSYqfF1ixf+8EIgluBkgTg==",
- "requires": {
- "colors": "^1.4.0",
- "glob": "^7.1.6",
- "jpeg-js": "^0.4.2",
- "piexifjs": "^1.0.6",
- "yargs-parser": "^20.2.1"
- },
- "dependencies": {
- "glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
- "requires": {
- "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"
- }
- }
- }
- },
- "jpeg-js": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz",
- "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q=="
- },
- "jshaiku": {
- "version": "file:../haiku",
- "requires": {
- "@babel/core": "^7.16.7",
- "@babel/preset-env": "^7.16.8",
- "@babel/preset-typescript": "^7.16.7",
- "@discordjs/builders": "^0.11.0",
- "@discordjs/rest": "^0.2.0-canary.0",
- "@types/jest": "^27.4.0",
- "@types/node-cron": "^3.0.1",
- "ansi-styles": "^6.1.0",
- "babel-jest": "^27.4.6",
- "chalk": "^5.0.0",
- "discord-api-types": "^0.26.1",
- "discord.js": "^13.8.0",
- "jest": "^27.4.7",
- "node-cron": "^3.0.0",
- "ts-node": "^10.4.0",
- "typescript": "4.5.4"
- }
- },
- "json-diff": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.7.3.tgz",
- "integrity": "sha512-VBvNBt3cIrCBHa3gYbVsCFUEReqWZPf+Biq1ZtFdIiQ6rytRLDp3qvtrGv7z/iZDd1D4vXWpW7Nx1nP8muLzkg==",
- "requires": {
- "cli-color": "^2.0.0",
- "difflib": "~0.2.1",
- "dreamopt": "~0.8.0"
- }
- },
- "lru-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
- "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
- "requires": {
- "es5-ext": "~0.10.2"
- }
- },
- "media-typer": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
- },
- "memoizee": {
- "version": "0.4.15",
- "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz",
- "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==",
- "requires": {
- "d": "^1.0.1",
- "es5-ext": "^0.10.53",
- "es6-weak-map": "^2.0.3",
- "event-emitter": "^0.3.5",
- "is-promise": "^2.2.2",
- "lru-queue": "^0.1.0",
- "next-tick": "^1.1.0",
- "timers-ext": "^0.1.7"
- }
- },
- "memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "optional": true
- },
- "merge-descriptors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
- },
- "methods": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
- "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
- },
- "mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
- },
- "mime-db": {
- "version": "1.51.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
- "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
- },
- "mime-types": {
- "version": "2.1.34",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
- "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
- "requires": {
- "mime-db": "1.51.0"
- }
- },
- "minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "mongodb": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.7.0.tgz",
- "integrity": "sha512-HhVar6hsUeMAVlIbwQwWtV36iyjKd9qdhY+s4wcU8K6TOj4Q331iiMy+FoPuxEntDIijTYWivwFJkLv8q/ZgvA==",
- "requires": {
- "bson": "^4.6.3",
- "denque": "^2.0.1",
- "mongodb-connection-string-url": "^2.5.2",
- "saslprep": "^1.0.3",
- "socks": "^2.6.2"
- }
- },
- "mongodb-connection-string-url": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz",
- "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==",
- "requires": {
- "@types/whatwg-url": "^8.2.1",
- "whatwg-url": "^11.0.0"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
- },
- "next-tick": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
- "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
- },
- "node-fetch": {
- "version": "2.6.7",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
- "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
- "requires": {
- "whatwg-url": "^5.0.0"
- },
- "dependencies": {
- "tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
- },
- "whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
- "requires": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- }
- }
- },
- "node-tesseract": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/node-tesseract/-/node-tesseract-0.2.7.tgz",
- "integrity": "sha1-yPAvuDUaQnByc1d4wFGYI/JgG4Q=",
- "requires": {
- "glob": "^5.0.10",
- "node-uuid": "^1.4.1"
- }
- },
- "node-uuid": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
- "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc="
- },
- "object-inspect": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
- "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
- },
- "on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1"
- }
- },
- "opencollective-postinstall": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz",
- "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q=="
- },
- "parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
- },
- "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="
- },
- "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="
- },
- "piexifjs": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/piexifjs/-/piexifjs-1.0.6.tgz",
- "integrity": "sha512-0wVyH0cKohzBQ5Gi2V1BuxYpxWfxF3cSqfFXfPIpl5tl9XLS5z4ogqhUCD20AbHi0h9aJkqXNJnkVev6gwh2ag=="
- },
- "proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "requires": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- }
- },
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
- },
- "qs": {
- "version": "6.10.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
- "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
- "requires": {
- "side-channel": "^1.0.4"
- }
- },
- "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=="
- },
- "raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "requires": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- }
- },
- "regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
- },
- "resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
- },
- "safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "saslprep": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
- "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
- "optional": true,
- "requires": {
- "sparse-bitfield": "^3.0.3"
- }
- },
- "send": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
- "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
- "requires": {
- "debug": "2.6.9",
- "depd": "2.0.0",
- "destroy": "1.2.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "mime": "1.6.0",
- "ms": "2.1.3",
- "on-finished": "2.4.1",
- "range-parser": "~1.2.1",
- "statuses": "2.0.1"
- },
- "dependencies": {
- "ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- }
- }
- },
- "serve-static": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
- "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
- "requires": {
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "0.18.0"
- }
- },
- "setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
- },
- "side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
- "requires": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
- }
- },
- "smart-buffer": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
- "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
- },
- "socks": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
- "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
- "requires": {
- "ip": "^1.1.5",
- "smart-buffer": "^4.2.0"
- }
- },
- "sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
- "optional": true,
- "requires": {
- "memory-pager": "^1.0.2"
- }
- },
- "statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
- },
- "structured-clone": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/structured-clone/-/structured-clone-0.2.2.tgz",
- "integrity": "sha1-rJK2vjGVimQ9sw8TNavGobAt/cI="
- },
- "tesseract.js": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-2.1.5.tgz",
- "integrity": "sha512-7CIS3SWr7TXpeaH9+HS7iUtVbCfPFYOO3p6rkRAkdtsOtrbz6496x59na6SCbFAIaZulQxy8BjwSu3qL3AoDRg==",
- "requires": {
- "blueimp-load-image": "^3.0.0",
- "bmp-js": "^0.1.0",
- "file-type": "^12.4.1",
- "idb-keyval": "^3.2.0",
- "is-electron": "^2.2.0",
- "is-url": "^1.2.4",
- "jpeg-autorotate": "^7.1.1",
- "node-fetch": "^2.6.0",
- "opencollective-postinstall": "^2.0.2",
- "regenerator-runtime": "^0.13.3",
- "resolve-url": "^0.2.1",
- "tesseract.js-core": "^2.2.0",
- "zlibjs": "^0.3.1"
- }
- },
- "tesseract.js-core": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-2.2.0.tgz",
- "integrity": "sha512-a8L+OJTbUipBsEDsJhDPlnLB0TY1MkTZqw5dqUwmiDSjUzwvU7HWLg/2+WDRulKUi4LE+7PnHlaBlW0k+V0U0w=="
- },
- "timers-ext": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
- "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
- "requires": {
- "es5-ext": "~0.10.46",
- "next-tick": "1"
- }
- },
- "toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
- },
- "tr46": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
- "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
- "requires": {
- "punycode": "^2.1.1"
- }
- },
- "ts-mixer": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.1.tgz",
- "integrity": "sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg=="
- },
- "tslib": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
- "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
- },
- "type": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
- "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
- },
- "type-is": {
- "version": "1.6.18",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
- "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
- "requires": {
- "media-typer": "0.3.0",
- "mime-types": "~2.1.24"
- }
- },
- "typescript": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
- "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg=="
- },
- "unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
- },
- "unscan": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/unscan/-/unscan-1.1.2.tgz",
- "integrity": "sha512-a5RcGaBFMO9l78QWKffeWUo2cvfqUv05JCXuphE8MFOA92qyqp1Da7isnR+zjJspi45+yS8tTSuhd0vV3asWdA==",
- "requires": {
- "commander": "^8.3.0",
- "form-data": "^4.0.0",
- "node-fetch": "^2.6.5"
- }
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
- },
- "vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
- },
- "webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
- },
- "whatwg-url": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
- "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
- "requires": {
- "tr46": "^3.0.0",
- "webidl-conversions": "^7.0.0"
- },
- "dependencies": {
- "webidl-conversions": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
- "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
- }
- }
- },
- "wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
- },
- "ws": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz",
- "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==",
- "requires": {}
- },
- "yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="
- },
- "zlibjs": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz",
- "integrity": "sha1-UBl+2yihxCymWcyLTmqd3W1ERVQ="
- },
- "zod": {
- "version": "3.13.4",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.13.4.tgz",
- "integrity": "sha512-LZRucWt4j/ru5azOkJxCfpR87IyFDn8h2UODdqvXzZLb3K7bb9chUrUIGTy3BPsr8XnbQYfQ5Md5Hu2OYIo1mg=="
- }
- }
-}
diff --git a/package.json b/package.json
index 39257d9..56f7dc2 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"@discordjs/builders": "^0.12.0",
"@ungap/structured-clone": "^1.0.1",
"body-parser": "^1.20.0",
- "discord.js": "^13.8.0",
+ "discord.js": "13.8.1",
"express": "^4.18.1",
"humanize": "^0.0.9",
"humanize-duration": "^3.27.1",
@@ -11,6 +11,7 @@
"json-diff": "^0.7.1",
"mongodb": "^4.7.0",
"node-tesseract": "^0.2.7",
+ "opencv.js": "^1.2.1",
"structured-clone": "^0.2.2",
"tesseract.js": "^2.1.5",
"typescript": "^4.5.5",
diff --git a/src/api/index.ts b/src/api/index.ts
index 07131ff..f5424b3 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -1,7 +1,7 @@
import { HaikuClient } from 'jshaiku';
import express from 'express';
import bodyParser from 'body-parser';
-import generateEmojiEmbed from "../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import structuredClone from '@ungap/structured-clone';
@@ -27,7 +27,7 @@
let interaction = client.verify[code].interaction;
if (interaction) {
- interaction.editReply({embeds: [new generateEmojiEmbed()
+ interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Verification complete`)
.setStatus("Success")
@@ -45,7 +45,7 @@
try {
let interaction = client.verify[code].interaction;
if (interaction) {
- interaction.editReply({embeds: [new generateEmojiEmbed()
+ interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Verify was opened in another tab or window, please complete the CAPTCHA there to continue`)
.setStatus("Success")
diff --git a/src/automations/createModActionTicket.ts b/src/automations/createModActionTicket.ts
index a9a5a27..fad9a62 100644
--- a/src/automations/createModActionTicket.ts
+++ b/src/automations/createModActionTicket.ts
@@ -1,10 +1,10 @@
import Discord, { MessageActionRow, MessageButton } from 'discord.js';
-import generateEmojiEmbed from '../utils/generateEmojiEmbed.js';
+import EmojiEmbed from '../utils/generateEmojiEmbed.js';
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
export async function create(guild: Discord.Guild, member: Discord.User, createdBy: Discord.User, reason: string) {
- let config = await client.database.read(guild.id);
+ let config = await client.database.guilds.read(guild.id);
// @ts-ignore
const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger
let overwrites = [{
@@ -48,7 +48,7 @@
}
}
)
- await c.send({ embeds: [new generateEmojiEmbed()
+ await c.send({ embeds: [new EmojiEmbed()
.setTitle("New Ticket")
.setDescription(
`Ticket created by a Moderator\n` +
@@ -83,12 +83,12 @@
guild: guild.id
}
}
- log(data, client);
+ log(data);
} catch (e) { console.log(e); return null }
return c.id
}
export async function areTicketsEnabled(guild: string) {
- let config = await client.database.read(guild);
+ let config = await client.database.guilds.read(guild);
return config.tickets.enabled;
}
\ No newline at end of file
diff --git a/src/automations/guide.ts b/src/automations/guide.ts
index 2a686b9..8e0e6cd 100644
--- a/src/automations/guide.ts
+++ b/src/automations/guide.ts
@@ -1,6 +1,6 @@
import { SelectMenuOption } from '@discordjs/builders';
import Discord, { MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import createPageIndicator from "../utils/createPageIndicator.js";
@@ -20,7 +20,7 @@
c = c ? c : guild.channels.cache.find(ch => ch.type === "GUILD_TEXT" && ch.permissionsFor(guild.roles.everyone).has("SEND_MESSAGES") && ch.permissionsFor(guild.me).has("EMBED_LINKS"));
let pages = [
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Welcome to Nucleus")
.setDescription(
"Thanks for adding Nucleus to your server\n\n" +
@@ -31,7 +31,7 @@
.setStatus("Danger")
).setTitle("Welcome").setDescription("About Nucleus").setPageId(0),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Logging")
.setDescription(
"Nucleus can log server events and keep you informed with what content is being posted to your server.\n" +
@@ -45,7 +45,7 @@
.setStatus("Danger")
).setTitle("Logging").setDescription("Logging, staff warning logs etc.").setPageId(1),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Moderation")
.setDescription(
"Nucleus has a number of commands that can be used to moderate your server.\n" +
@@ -63,7 +63,7 @@
.setStatus("Danger")
).setTitle("Moderation").setDescription("Basic moderation commands").setPageId(2),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Verify")
.setDescription(
"Nucleus has a verification system that allows users to prove they aren't bots.\n" +
@@ -75,7 +75,7 @@
.setStatus("Danger")
).setTitle("Verify").setDescription("Captcha verification system").setPageId(3),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Content Scanning")
.setDescription(
"Nucleus has a content scanning system that automatically scans links and images sent by users.\n" +
@@ -86,7 +86,7 @@
.setStatus("Danger")
).setTitle("Content Scanning").setDescription("Content (NSFW, malware, scams) scanning").setPageId(4),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Tickets")
.setDescription(
"Nucleus has a ticket system that allows users to create tickets and have a support team respond to them.\n" +
@@ -98,7 +98,7 @@
.setStatus("Danger")
).setTitle("Tickets").setDescription("Ticket system").setPageId(5),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Tags")
.setDescription(
"Add a tag system to your server with the `/tag` and `/tags` commands.\n" +
@@ -114,7 +114,7 @@
let m;
if (interaction) {
m = await interaction.reply({embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setTitle("Welcome")
.setDescription(`One moment...`)
.setStatus("Danger")
@@ -122,7 +122,7 @@
], fetchReply: true, ephemeral: true});
} else {
m = await c.send({embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setTitle("Welcome")
.setDescription(`One moment...`)
.setStatus("Danger")
diff --git a/src/automations/roleMenu.ts b/src/automations/roleMenu.ts
index b13f949..e82c82c 100644
--- a/src/automations/roleMenu.ts
+++ b/src/automations/roleMenu.ts
@@ -1,24 +1,24 @@
import { Message, MessageButton } from "discord.js";
-import generateEmojiEmbed from '../utils/generateEmojiEmbed.js'
+import EmojiEmbed from '../utils/generateEmojiEmbed.js'
import { MessageActionRow, MessageSelectMenu } from 'discord.js';
import getEmojiByName from "../utils/getEmojiByName.js";
import client from "../utils/client.js";
export async function callback(interaction) {
- let config = await client.database.read(interaction.guild.id);
- if (!config.roleMenu.enabled) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ let config = await client.database.guilds.read(interaction.guild.id);
+ if (!config.roleMenu.enabled) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Roles")
.setDescription("Self roles are currently disabled. Please contact a staff member or try again later.")
.setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS")
], ephemeral: true})
- if (config.roleMenu.options.length === 0) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (config.roleMenu.options.length === 0) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Roles")
.setDescription("There are no roles available. Please contact a staff member or try again later.")
.setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS")
], ephemeral: true})
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Roles")
.setDescription("Loading...")
.setStatus("Success")
@@ -49,7 +49,7 @@
interaction: interaction
};
m = await interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Roles")
.setDescription("Select how to choose your roles")
.setStatus("Success")
@@ -75,7 +75,7 @@
let object = config.roleMenu.options[i];
let m = await interaction.editReply({
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setTitle("Roles")
.setEmoji("GUILD.GREEN")
.setDescription(`**${object.name}**` + (object.description ? `\n${object.description}` : ``) +
@@ -115,7 +115,7 @@
if (component.customId == "rolemenu") {
rolesToAdd = rolesToAdd.concat(component.values)
} else if (component.customId == "cancel") {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Roles")
.setDescription("Cancelled. No changes were made.")
.setStatus("Danger")
@@ -131,14 +131,14 @@
await interaction.member.roles.remove(rolesToRemove)
await interaction.member.roles.add(rolesToAdd)
} catch (e) {
- return await interaction.reply({embeds: [new generateEmojiEmbed()
+ return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Roles")
.setDescription("Something went wrong and your roles were not added. Please contact a staff member or try again later.")
.setStatus("Danger")
.setEmoji("GUILD.RED")
], components: []})
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Roles")
.setDescription("Roles have been added. You may close this message.")
.setStatus("Success")
diff --git a/src/automations/statsChannelAdd.ts b/src/automations/statsChannelAdd.ts
index 01dfef1..32de0ff 100644
--- a/src/automations/statsChannelAdd.ts
+++ b/src/automations/statsChannelAdd.ts
@@ -3,7 +3,7 @@
import client from '../utils/client.js';
export async function callback(_, member) {
- let config = await client.database.read(member.guild.id);
+ let config = await client.database.guilds.read(member.guild.id);
config.stats.forEach(async element => {
if (element.enabled) {
diff --git a/src/automations/statsChannelRemove.ts b/src/automations/statsChannelRemove.ts
index fee0d2d..da4f43b 100644
--- a/src/automations/statsChannelRemove.ts
+++ b/src/automations/statsChannelRemove.ts
@@ -3,7 +3,7 @@
import singleNotify from '../utils/singleNotify.js';
export async function callback(_, member) {
- let config = await client.database.read(member.guild.id);
+ let config = await client.database.guilds.read(member.guild.id);
config.stats.forEach(async element => {
if (element.enabled) {
diff --git a/src/automations/tickets/create.ts b/src/automations/tickets/create.ts
index 06e7e07..8eee3b2 100644
--- a/src/automations/tickets/create.ts
+++ b/src/automations/tickets/create.ts
@@ -1,7 +1,7 @@
import Discord, { MessageActionRow, MessageButton } from "discord.js";
import { tickets, toHexArray } from "../../utils/calculate.js";
import client from "../../utils/client.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
function capitalize(s: string) {
@@ -12,9 +12,9 @@
export default async function (interaction) {
const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger
- let config = await client.database.read(interaction.guild.id);
+ let config = await client.database.guilds.read(interaction.guild.id);
if (!config.tickets.enabled || !config.tickets.category) {
- return await interaction.reply({embeds: [new generateEmojiEmbed()
+ return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tickets are disabled")
.setDescription("Please enable tickets in the configuration to use this command.")
.setStatus("Danger")
@@ -32,7 +32,7 @@
}
});
if (count >= config.tickets.maxTickets) {
- return await interaction.reply({embeds: [new generateEmojiEmbed()
+ return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Create Ticket")
.setDescription(`You have reached the maximum amount of tickets (${config.tickets.maxTickets}). Please close one of your active tickets before creating a new one.`)
.setStatus("Danger")
@@ -41,7 +41,7 @@
}
let ticketTypes;
let custom = false
- if (config.tickets.customTypes) { ticketTypes = config.tickets.customTypes; custom = true }
+ if (config.tickets.customTypes && config.tickets.useCustom) { ticketTypes = config.tickets.customTypes; custom = true }
else if (config.tickets.types) ticketTypes = toHexArray(config.tickets.types, tickets);
else ticketTypes = [];
let chosenType;
@@ -65,7 +65,7 @@
for (let i = 0; i < formattedTicketTypes.length; i += 5) {
splitFormattedTicketTypes.push(new MessageActionRow().addComponents(formattedTicketTypes.slice(i, i + 5)));
}
- let m = await interaction.reply({embeds: [new generateEmojiEmbed()
+ let m = await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Create Ticket")
.setDescription("Select a ticket type")
.setStatus("Success")
@@ -99,7 +99,7 @@
for (let i = 0; i < formattedTicketTypes.length; i += 5) {
splitFormattedTicketTypes.push(new MessageActionRow().addComponents(formattedTicketTypes.slice(i, i + 5)));
}
- component.update({embeds: [new generateEmojiEmbed()
+ component.update({embeds: [new EmojiEmbed()
.setTitle("Create Ticket")
.setDescription("Select a ticket type")
.setStatus("Success")
@@ -107,7 +107,7 @@
], components: splitFormattedTicketTypes});
} else {
chosenType = null
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Create Ticket")
.setEmoji("GUILD.TICKET.OPEN")
], ephemeral: true, components: splitFormattedTicketTypes})
@@ -141,7 +141,7 @@
reason: "Creating ticket"
})
} catch (e) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Create Ticket")
.setDescription("Failed to create ticket")
.setStatus("Danger")
@@ -161,7 +161,7 @@
let content = interaction.options ? interaction.options.getString("message") || "" : "";
if (content) content = `**Message:**\n> ${content}\n`;
let emoji = custom ? "" : getEmojiByName("TICKETS." + chosenType.toUpperCase());
- await c.send({ embeds: [new generateEmojiEmbed()
+ await c.send({ embeds: [new EmojiEmbed()
.setTitle("New Ticket")
.setDescription(
`Ticket created by <@${interaction.member.user.id}>\n` +
@@ -195,9 +195,9 @@
guild: interaction.guild.id
}
}
- log(data, client);
+ log(data);
} catch (e) { console.log(e)}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Create Ticket")
.setDescription(`Ticket created. You can view it here: <#${c.id}>`)
.setStatus("Success")
diff --git a/src/automations/tickets/delete.ts b/src/automations/tickets/delete.ts
index a974b2e..3df284b 100644
--- a/src/automations/tickets/delete.ts
+++ b/src/automations/tickets/delete.ts
@@ -1,18 +1,18 @@
import Discord, { MessageButton, MessageActionRow } from "discord.js";
import client from "../../utils/client.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
export default async function (interaction) {
// @ts-ignore
const { log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger
- let config = await client.database.read(interaction.guild.id);
+ let config = await client.database.guilds.read(interaction.guild.id);
let thread = false; let threadChannel
if (interaction.channel instanceof Discord.ThreadChannel) thread = true; threadChannel = interaction.channel as Discord.ThreadChannel
let channel = (interaction.channel as Discord.TextChannel)
if (!channel.parent || config.tickets.category != channel.parent.id || (thread ? (threadChannel.parent.parent.id != config.tickets.category) : false)) {
- return interaction.reply({embeds: [new generateEmojiEmbed()
+ return interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Deleting Ticket...")
.setDescription("This ticket is not in your tickets category, so cannot be deleted. You cannot run close in a thread.")
.setStatus("Danger")
@@ -21,7 +21,7 @@
}
let status = channel.topic.split(" ")[1];
if (status == "Archived") {
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Delete Ticket")
.setDescription("Your ticket is being deleted...")
.setStatus("Danger")
@@ -45,11 +45,11 @@
guild: interaction.guild.id
}
}
- log(data, client);
+ log(data);
interaction.channel.delete();
return;
} else if (status == "Active") {
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Close Ticket")
.setDescription("Your ticket is being closed...")
.setStatus("Warning")
@@ -95,8 +95,8 @@
guild: interaction.guild.id
}
}
- log(data, client);
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ log(data);
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Close Ticket")
.setDescription("This ticket has been closed.\nType `/ticket close` again to delete it.")
.setStatus("Warning")
@@ -112,7 +112,7 @@
}
async function purgeByUser(member, guild) {
- let config = await client.database.read(guild.id);
+ let config = await client.database.guilds.read(guild.id);
if (!config.tickets.category) return;
let tickets = guild.channels.cache.get(config.tickets.category);
if (!tickets) return;
@@ -147,7 +147,7 @@
guild: guild.id
}
}
- log(data, member.client);
+ log(data);
} catch {}
}
}
diff --git a/src/automations/unscan.ts b/src/automations/unscan.ts
index d3a2a18..940a1fe 100644
--- a/src/automations/unscan.ts
+++ b/src/automations/unscan.ts
@@ -1,5 +1,4 @@
import * as scan from '../utils/scanners.js'
-import process from 'tesseract.js'
export async function LinkCheck(message): Promise<boolean> {
let links = message.content.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi) ?? []
@@ -7,11 +6,15 @@
const promises = links.map(async element => {
try {
if (element.match(/https?:\/\/[a-zA-Z]+\.?discord(app)?\.(com|net)\/?/)) return // Also matches discord.net, not enough of a bug
+ console.log(1.1)
element = await scan.testLink(element)
+ console.log(1.2)
} catch {}
detections.push({tags: element.tags || [], safe: element.safe})
});
+ console.log(1)
await Promise.all(promises);
+ console.log(2)
let types = [
"PHISHING", "DATING", "TRACKERS", "ADVERTISEMENTS", "FACEBOOK",
"AMP", "FACEBOOK TRACKERS", "IP GRABBERS", "PORN",
@@ -21,9 +24,10 @@
let detectionsTypes = detections.map(element => {
let type = types.find(type => element.tags.includes(type))
if (type) return type
- if (!element.safe) return "UNSAFE"
+ // if (!element.safe) return "UNSAFE"
return undefined
}).filter(element => element !== undefined)
+ console.log(detectionsTypes)
return detectionsTypes.length > 0
}
diff --git a/src/automations/verify.ts b/src/automations/verify.ts
index f84ba20..ed24d25 100644
--- a/src/automations/verify.ts
+++ b/src/automations/verify.ts
@@ -1,5 +1,5 @@
import Discord, { GuildMember } from "discord.js";
-import generateEmojiEmbed from "../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import fetch from "node-fetch";
import { TestString, NSFWCheck } from "../automations/unscan.js";
import createPageIndicator from "../utils/createPageIndicator.js";
@@ -11,28 +11,28 @@
export default async function(interaction) {
let verify = client.verify
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Loading")
.setDescription(step(-1))
.setStatus("Danger")
.setEmoji("NUCLEUS.LOADING")
], ephemeral: true, fetchReply: true});
- let config = await client.database.read(interaction.guild.id);
- if ((!config.verify.enabled ) || (!config.verify.role)) return interaction.editReply({embeds: [new generateEmojiEmbed()
+ let config = await client.database.guilds.read(interaction.guild.id);
+ if ((!config.verify.enabled ) || (!config.verify.role)) return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Verify is not enabled on this server`)
.setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS")
], ephemeral: true, fetchReply: true});
if ((interaction.member as GuildMember).roles.cache.has(config.verify.role)) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`You already have the <@&${config.verify.role}> role` + step(0))
.setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS")
]});
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Checking our servers are up` + step(0))
.setStatus("Warning")
@@ -41,7 +41,7 @@
try {
let status = await fetch(client.config.baseUrl).then(res => res.status);
if (status != 200) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Our servers appear to be down, please try again later` + step(0))
.setStatus("Danger")
@@ -49,7 +49,7 @@
]});
}
} catch {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Our servers appear to be down, please try again later` + step(0))
.setStatus("Danger")
@@ -66,14 +66,14 @@
])]});
}
if (config.filters.images.NSFW) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Checking your avatar is safe for work` + step(1))
.setStatus("Warning")
.setEmoji("NUCLEUS.LOADING")
]});
if (await NSFWCheck((interaction.member as GuildMember).user.avatarURL({format: "png"}))) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Your avatar was detected as NSFW, which we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake` + step(1))
.setStatus("Danger")
@@ -82,14 +82,14 @@
}
}
if (config.filters.wordFilter) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Checking your name is allowed` + step(2))
.setStatus("Warning")
.setEmoji("NUCLEUS.LOADING")
]});
if (TestString((interaction.member as Discord.GuildMember).displayName, config.filters.wordFilter.words.loose, config.filters.wordFilter.words.strict) != "none") {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Your name contained a word we do not allow in this server.\nPlease contact one of our staff members if you believe this is a mistake` + step(2))
.setStatus("Danger")
@@ -97,7 +97,7 @@
]});
}
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`One moment...` + step(3))
.setStatus("Warning")
@@ -129,7 +129,7 @@
gIcon: interaction.guild.iconURL({format: "png"}),
interaction: interaction
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify")
.setDescription(`Looking good!\nClick the button below to get verified` + step(4))
.setStatus("Success")
diff --git a/src/automations/welcome.ts b/src/automations/welcome.ts
index 11c4844..5b80fbd 100644
--- a/src/automations/welcome.ts
+++ b/src/automations/welcome.ts
@@ -4,7 +4,7 @@
export async function callback(_, member) {
if (member.bot) return
- let config = await client.database.read(member.guild.id);
+ let config = await client.database.guilds.read(member.guild.id);
if (!config.welcome.enabled) return
if (!config.welcome.verificationRequired.role) {
diff --git a/src/commands/categorisationTest.ts b/src/commands/categorisationTest.ts
index 4a28841..a6c7479 100644
--- a/src/commands/categorisationTest.ts
+++ b/src/commands/categorisationTest.ts
@@ -1,21 +1,22 @@
import { CommandInteraction, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
-import { SelectMenuComponent, SelectMenuOption, SlashCommandBuilder } from "@discordjs/builders";
+import { SlashCommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import generateKeyValueList, { toCapitals } from "../utils/generateKeyValueList.js";
import getEmojiByName from "../utils/getEmojiByName.js";
+import client from "../utils/client.js"
const command = new SlashCommandBuilder()
.setName("categorise")
.setDescription("Categorises your servers channels")
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
const { renderChannel } = client.logger
let channels = interaction.guild.channels.cache.filter(c => c.type !== "GUILD_CATEGORY");
let categorised = {}
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Loading...")
.setEmoji("NUCLEUS.LOADING")
.setStatus("Success")
@@ -40,7 +41,7 @@
}
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Categorise")
.setDescription(generateKeyValueList({
channel: renderChannel(c),
diff --git a/src/commands/mod/ban.ts b/src/commands/mod/ban.ts
index 8b17db3..4581c0f 100644
--- a/src/commands/mod/ban.ts
+++ b/src/commands/mod/ban.ts
@@ -2,7 +2,7 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import addPlurals from "../../utils/plurals.js";
import client from "../../utils/client.js";
@@ -18,13 +18,14 @@
)
.addIntegerOption(option => option.setName("delete").setDescription("The days of messages to delete | Default 0").setMinValue(0).setMaxValue(7).setRequired(false))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ const { renderUser } = client.logger
// TODO:[Modals] Replace this with a modal
let confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.BAN.RED")
.setTitle("Ban")
.setDescription(keyValueList({
- "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+ "user": renderUser(interaction.options.getUser("user")),
"reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
})
+ `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n`
@@ -35,11 +36,11 @@
if (confirmation.success) {
let dmd = false
let dm;
- let config = await client.database.read(interaction.guild.id);
+ let config = await client.database.guilds.read(interaction.guild.id);
try {
if (interaction.options.getString("notify") != "no") {
dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("PUNISH.BAN.RED")
.setTitle("Banned")
.setDescription(`You have been banned in ${interaction.guild.name}` +
@@ -57,13 +58,13 @@
} catch {}
try {
let member = (interaction.options.getMember("user") as GuildMember)
- let reason = interaction.options.getString("reason") ?? "No reason provided"
+ let reason = interaction.options.getString("reason")
member.ban({
days: Number(interaction.options.getInteger("delete") ?? 0),
- reason: reason
+ reason: reason ?? "No reason provided"
})
- // @ts-ignore
- const { log, NucleusColors, entry, renderUser, renderDelta } = interaction.user.client.logger
+ try { await client.database.history.create("ban", interaction.guild.id, member.user, interaction.user, reason) } catch {}
+ const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger
let data = {
meta: {
type: 'memberBan',
@@ -86,9 +87,9 @@
guild: interaction.guild.id
}
}
- log(data, member.user.client);
+ log(data);
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.BAN.RED")
.setTitle(`Ban`)
.setDescription("Something went wrong and the user was not banned")
@@ -98,14 +99,14 @@
return
}
let failed = (dmd == false && interaction.options.getString("notify") != "no")
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
.setTitle(`Ban`)
.setDescription("The member was banned" + (failed ? ", but could not be notified" : ""))
.setStatus(failed ? "Warning" : "Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.BAN.GREEN")
.setTitle(`Ban`)
.setDescription("No changes were made")
@@ -125,13 +126,13 @@
// Check if Nucleus can ban the member
if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
// Check if Nucleus has permission to ban
- if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the `ban_members` permission";
+ if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the Ban members permission";
// Do not allow banning Nucleus
if (member.id == interaction.guild.me.id) throw "I cannot ban myself"
// Allow the owner to ban anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user has ban_members permission
- if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the `ban_members` permission";
+ if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the Ban members permission";
// Check if the user is below on the role list
if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
// Allow ban
diff --git a/src/commands/mod/info.ts b/src/commands/mod/info.ts
new file mode 100644
index 0000000..c3a4388
--- /dev/null
+++ b/src/commands/mod/info.ts
@@ -0,0 +1,285 @@
+import { HistorySchema } from '../../utils/database';
+import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
+import { SlashCommandSubcommandBuilder, SelectMenuOption } from "@discordjs/builders";
+import { WrappedCheck } from "jshaiku";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+import client from "../../utils/client.js";
+import { modalInteractionCollector } from '../../utils/dualCollector.js';
+import pageIndicator from '../../utils/createPageIndicator.js';
+
+const command = (builder: SlashCommandSubcommandBuilder) =>
+ builder
+ .setName("info")
+ .setDescription("Shows moderator information about a user")
+ .addUserOption(option => option.setName("user").setDescription("The user to get information about").setRequired(true))
+
+
+const types = {
+ "warn": {emoji: "PUNISH.WARN.YELLOW", text: "Warned"},
+ "mute": {emoji: "PUNISH.MUTE.YELLOW", text: "Muted"},
+ "join": {emoji: "MEMBER.JOIN", text: "Joined"},
+ "leave": {emoji: "MEMBER.LEAVE", text: "Left"},
+ "kick": {emoji: "MEMBER.KICK", text: "Kicked"},
+ "softban": {emoji: "PUNISH.SOFTBAN", text: "Softbanned"},
+ "ban": {emoji: "MEMBER.BAN", text: "Banned"},
+ "unban": {emoji: "MEMBER.UNBAN", text: "Unbanned"},
+ "purge": {emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared"},
+ "nickname": {emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed"}
+}
+
+function historyToString(history: HistorySchema) {
+ let s = `${getEmojiByName(types[history.type].emoji)} ${
+ history.amount ? (history.amount + " ") : ""
+ }${
+ types[history.type].text
+ } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
+ if (history.moderator) { s += ` by <@${history.moderator}>`; }
+ if (history.reason) { s += `\n**Reason:**\n> ${history.reason}`; }
+ if (history.before) { s += `\n**Before:**\n> ${history.before}`; }
+ if (history.after) { s += `\n**After:**\n> ${history.after}`; }
+ return s + "\n";
+}
+
+
+class TimelineSection {
+ name: string;
+ content: {data: HistorySchema, rendered: string}[] = []
+
+ addContent = (content: {data: HistorySchema, rendered: string}) => { this.content.push(content); return this; }
+ contentLength = () => { return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0); };
+ generateName = () => {
+ let first = Math.round(this.content[0].data.occurredAt.getTime() / 1000)
+ let last = Math.round(this.content[this.content.length - 1].data.occurredAt.getTime() / 1000)
+ if (first === last) { return this.name = `<t:${first}:F>`; }
+ return this.name = `<t:${first}:F> - <t:${last}:F>`;
+ }
+}
+
+const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
+
+async function showHistory(member, interaction: CommandInteraction) {
+ let currentYear = new Date().getFullYear();
+ let pageIndex = null;
+ let m, history, current;
+ let refresh = true;
+ let filteredTypes = [];
+ let openFilterPane = false;
+ while (true) {
+ if (refresh) {
+ history = await client.database.history.read(member.guild.id, member.id, currentYear);
+ history = history.sort((a, b) => b.occurredAt.getTime() - a.occurredAt.getTime()).reverse();
+ if (openFilterPane) {
+ let tempFilteredTypes = filteredTypes
+ if (filteredTypes.length === 0) { tempFilteredTypes = Object.keys(types); }
+ history = history.filter(h => tempFilteredTypes.includes(h.type))
+ };
+ refresh = false;
+ }
+ let groups: TimelineSection[] = []
+ if (history.length > 0) {
+ current = new TimelineSection()
+ history.forEach(event => {
+ if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
+ groups.push(current);
+ current.generateName();
+ current = new TimelineSection();
+ }
+ current.addContent({data: event, rendered: historyToString(event)});
+ });
+ current.generateName();
+ groups.push(current);
+ if (pageIndex === null) { pageIndex = groups.length - 1; }
+ }
+ let components = (
+ openFilterPane ? [
+ new MessageActionRow().addComponents([new Discord.MessageSelectMenu().setOptions(
+ Object.entries(types).map(([key, value]) => ({
+ label: value.text,
+ value: key,
+ default: filteredTypes.includes(key),
+ emoji: client.emojis.resolve(getEmojiByName(value.emoji, "id"))
+ }))
+ ).setMinValues(1).setMaxValues(Object.keys(types).length).setCustomId("filter").setPlaceholder("Select at least one event")])
+ ] : []).concat([
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setCustomId("prevYear")
+ .setLabel((currentYear - 1).toString())
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("SECONDARY"),
+ new MessageButton()
+ .setCustomId("prevPage")
+ .setLabel("Previous page")
+ .setStyle("PRIMARY"),
+ new MessageButton()
+ .setCustomId("today")
+ .setLabel("Today")
+ .setStyle("PRIMARY"),
+ new MessageButton()
+ .setCustomId("nextPage")
+ .setLabel("Next page")
+ .setStyle("PRIMARY")
+ .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
+ new MessageButton()
+ .setCustomId("nextYear")
+ .setLabel((currentYear + 1).toString())
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("SECONDARY")
+ .setDisabled(currentYear === new Date().getFullYear()),
+ ]), new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Mod notes")
+ .setCustomId("modNotes")
+ .setStyle("PRIMARY")
+ .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
+ new MessageButton()
+ .setLabel("Filter")
+ .setCustomId("openFilter")
+ .setStyle(openFilterPane ? "SUCCESS" : "PRIMARY")
+ .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
+ ])
+ ])
+ let end = "\n\nJanuary " + currentYear.toString() + pageIndicator(
+ Math.max(groups.length, 1),
+ groups.length === 0 ? 1 : pageIndex
+ ) + (currentYear == new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December"
+ ) + " " + currentYear.toString()
+ if (groups.length > 0) {
+ let toRender = groups[Math.min(pageIndex, groups.length - 1)]
+ m = await interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Moderation history for " + member.user.username)
+ .setDescription(`**${toRender.name}**\n\n` + toRender.content.map(c => c.rendered).join("\n") + end)
+ .setStatus("Success")
+ .setFooter({text: (openFilterPane && filteredTypes.length) ? "Filters are currently enabled" : ""})
+ ], components: components});
+ } else {
+ m = await interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Moderation history for " + member.user.username)
+ .setDescription(`**${currentYear}**\n\n*No events*` + `\n\n` + end)
+ .setStatus("Success")
+ .setFooter({text: (openFilterPane && filteredTypes.length) ? "Filters are currently enabled" : ""})
+ ], components: components});
+ }
+ let i;
+ try {
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) {
+ interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Moderation history for " + member.user.username)
+ .setDescription(m.embeds[0].description)
+ .setStatus("Danger")
+ .setFooter({text: "Message timed out"})
+ ]});
+ return 0
+ }
+ i.deferUpdate()
+ if (i.customId === "filter") {
+ filteredTypes = i.values;
+ pageIndex = null;
+ refresh = true;
+ }
+ if (i.customId === "prevYear") { currentYear--; pageIndex = null; refresh = true; }
+ if (i.customId === "nextYear") { currentYear++; pageIndex = null; refresh = true; }
+ if (i.customId === "prevPage") {
+ pageIndex--;
+ if (pageIndex < 0) { pageIndex = null; currentYear--; refresh = true; }
+ }
+ if (i.customId === "nextPage") {
+ pageIndex++;
+ if (pageIndex >= groups.length) { pageIndex = 0; currentYear++; refresh = true; }
+ }
+ if (i.customId === "today") { currentYear = new Date().getFullYear(); pageIndex = null; refresh = true; }
+ if (i.customId === "modNotes") { return 1 }
+ if (i.customId === "openFilter") { openFilterPane = !openFilterPane; refresh = true }
+ }
+}
+
+
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ let m;
+ let member = (interaction.options.getMember("user")) as Discord.GuildMember;
+ await interaction.reply({embeds: [new EmojiEmbed()
+ .setEmoji("NUCLEUS.LOADING")
+ .setTitle("Downloading data...")
+ .setStatus("Success")
+ ], ephemeral: true, fetchReply: true});
+ let note;
+ let firstLoad = true;
+ while (true) {
+ note = await client.database.notes.read(member.guild.id, member.id);
+ if (firstLoad && !note) { await showHistory(member, interaction); }
+ firstLoad = false;
+ m = await interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji("MEMBER.JOIN")
+ .setTitle("Mod notes for " + member.user.username)
+ .setDescription(note ? note : "*No note set*")
+ .setStatus("Success")
+ ], components: [new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel(`${note ? "Modify" : "Create"} note`)
+ .setStyle("PRIMARY")
+ .setCustomId("modify")
+ .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
+ new MessageButton()
+ .setLabel("View moderation history")
+ .setStyle("PRIMARY")
+ .setCustomId("history")
+ .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
+ ])]});
+ let i;
+ try {
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) { return }
+ if (i.customId === "modify") {
+ await i.showModal(new Discord.Modal().setCustomId("modal").setTitle(`Editing moderator note`).addComponents(
+ // @ts-ignore
+ new MessageActionRow().addComponents(new TextInputComponent()
+ .setCustomId("note")
+ .setLabel("Note")
+ .setMaxLength(4000)
+ .setRequired(false)
+ .setStyle("PARAGRAPH")
+ .setValue(note ? note : "")
+ )
+ ))
+ await interaction.editReply({
+ embeds: [new EmojiEmbed()
+ .setTitle("Mod notes for " + member.user.username)
+ .setDescription("Modal opened. If you can't see it, click back and try again.")
+ .setStatus("Success")
+ .setEmoji("GUILD.TICKET.OPEN")
+ ], components: [new MessageActionRow().addComponents([new MessageButton()
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])]
+ });
+ let out;
+ try {
+ out = await modalInteractionCollector(m, (m) => m.channel.id == interaction.channel.id, (m) => m.customId == "modify")
+ } catch (e) { continue }
+ if (out.fields) {
+ let toAdd = out.fields.getTextInputValue("note") || null;
+ await client.database.notes.create(member.guild.id, member.id, toAdd);
+ } else { continue }
+ } else if (i.customId === "history") {
+ i.deferUpdate();
+ if (!await showHistory(member, interaction) ) return
+ }
+ }
+}
+
+const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+ let member = (interaction.member as GuildMember)
+ if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
+ return true
+}
+
+export { command };
+export { callback };
+export { check };
\ No newline at end of file
diff --git a/src/commands/mod/kick.ts b/src/commands/mod/kick.ts
index 20fbc01..97ead7b 100644
--- a/src/commands/mod/kick.ts
+++ b/src/commands/mod/kick.ts
@@ -3,7 +3,7 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js";
@@ -17,13 +17,14 @@
.addChoices([["Yes", "yes"], ["No", "no"]])
)
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ const { renderUser } = client.logger
// TODO:[Modals] Replace this with a modal
let confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.KICK.RED")
.setTitle("Kick")
.setDescription(keyValueList({
- "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+ "user": renderUser(interaction.options.getUser("user")),
"reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
})
+ `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n\n`
@@ -33,11 +34,11 @@
if (confirmation.success) {
let dmd = false
let dm;
- let config = await client.database.read(interaction.guild.id);
+ let config = await client.database.guilds.read(interaction.guild.id);
try {
if (interaction.options.getString("notify") != "no") {
dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("PUNISH.KICK.RED")
.setTitle("Kicked")
.setDescription(`You have been kicked in ${interaction.guild.name}` +
@@ -57,8 +58,9 @@
(interaction.options.getMember("user") as GuildMember).kick(interaction.options.getString("reason") ?? "No reason provided.")
let member = (interaction.options.getMember("user") as GuildMember)
let reason = interaction.options.getString("reason") ?? null
+ try { await client.database.history.create("kick", interaction.guild.id, member.user, interaction.user, reason) } catch {}
// @ts-ignore
- const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
+ const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
let data = {
meta: {
type: 'memberKick',
@@ -83,9 +85,9 @@
guild: member.guild.id
}
}
- log(data, member.client);
+ log(data);
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.KICK.RED")
.setTitle(`Kick`)
.setDescription("Something went wrong and the user was not kicked")
@@ -95,14 +97,14 @@
return
}
let failed = (dmd == false && interaction.options.getString("notify") != "no")
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.KICK.${failed ? "YELLOW" : "GREEN"}`)
.setTitle(`Kick`)
.setDescription("The member was kicked" + (failed ? ", but could not be notified" : ""))
.setStatus(failed ? "Warning" : "Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.KICK.GREEN")
.setTitle(`Kick`)
.setDescription("No changes were made")
@@ -122,13 +124,13 @@
// Check if Nucleus can kick the member
if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
// Check if Nucleus has permission to kick
- if (! me.permissions.has("KICK_MEMBERS")) throw "I do not have the `kick_members` permission";
+ if (! me.permissions.has("KICK_MEMBERS")) throw "I do not have the Kick members permission";
// Do not allow kicking Nucleus
if (member.id == interaction.guild.me.id) throw "I cannot kick myself"
// Allow the owner to kick anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user has kick_members permission
- if (! member.permissions.has("KICK_MEMBERS")) throw "You do not have the `kick_members` permission";
+ if (! member.permissions.has("KICK_MEMBERS")) throw "You do not have the Kick members permission";
// Check if the user is below on the role list
if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
// Allow kick
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index 79beeb3..5f42b27 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -1,7 +1,7 @@
import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import keyValueList from "../../utils/generateKeyValueList.js";
@@ -31,14 +31,14 @@
minutes: interaction.options.getInteger("minutes") || 0,
seconds: interaction.options.getInteger("seconds") || 0
}
- let config = await client.database.read(interaction.guild.id)
+ let config = await client.database.guilds.read(interaction.guild.id)
let serverSettingsDescription = (config.moderation.mute.timeout ? "given a timeout" : "")
if (config.moderation.mute.role) serverSettingsDescription += (serverSettingsDescription ? " and " : "") + `given the <@&${config.moderation.mute.role}> role`
let muteTime = (time.days * 24 * 60 * 60) + (time.hours * 60 * 60) + (time.minutes * 60) + time.seconds
if (muteTime == 0) {
let m = await interaction.reply({embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setEmoji("PUNISH.MUTE.GREEN")
.setTitle("Mute")
.setDescription("How long should the user be muted")
@@ -93,7 +93,7 @@
component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
} catch { return }
component.deferUpdate();
- if (component.customId == "cancel") return interaction.editReply({embeds: [new generateEmojiEmbed()
+ if (component.customId == "cancel") return interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Mute")
.setDescription("Mute cancelled")
@@ -111,7 +111,7 @@
}
} else {
await interaction.reply({embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setEmoji("PUNISH.MUTE.GREEN")
.setTitle("Mute")
.setDescription("Loading...")
@@ -123,7 +123,7 @@
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Mute")
.setDescription(keyValueList({
- "user": `<@!${user.id}> (${user.user.username})`,
+ "user": renderUser(user),
"time": `${humanizeDuration(muteTime * 1000, {round: true})}`,
"reason": `\n> ${reason ? reason : "*No reason provided*"}`
})
@@ -135,11 +135,11 @@
if (confirmation.success) {
let dmd = false
let dm;
- let config = await client.database.read(interaction.guild.id);
+ let config = await client.database.guilds.read(interaction.guild.id);
try {
if (interaction.options.getString("notify") != "no") {
dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Muted")
.setDescription(`You have been muted in ${interaction.guild.name}` +
@@ -156,15 +156,16 @@
dmd = true
}
} catch {}
+ let member = (interaction.options.getMember("user") as GuildMember)
try {
if (config.moderation.mute.timeout) {
- (interaction.options.getMember("user") as GuildMember).timeout(muteTime * 1000, interaction.options.getString("reason") || "No reason provided")
+ member.timeout(muteTime * 1000, interaction.options.getString("reason") || "No reason provided")
}
if (config.moderation.mute.role) {
- (interaction.options.getMember("user") as GuildMember).roles.add(config.moderation.mute.role)
+ member.roles.add(config.moderation.mute.role)
}
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.RED")
.setTitle(`Mute`)
.setDescription("Something went wrong and the user was not mute")
@@ -173,8 +174,9 @@
if (dmd) await dm.delete()
return
}
+ try { await client.database.history.create("mute", interaction.guild.id, member.user, interaction.user, reason) } catch {}
let failed = (dmd == false && interaction.options.getString("notify") != "no")
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
.setTitle(`Mute`)
.setDescription("The member was muted" + (failed ? ", but could not be notified" : ""))
@@ -190,7 +192,7 @@
timestamp: new Date().getTime()
},
list: {
- user: entry((interaction.options.getMember("user") as GuildMember).user.id, renderUser((interaction.options.getMember("user") as GuildMember).user)),
+ user: entry(member.user.id, renderUser(member.user)),
mutedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
time: entry(muteTime, `${humanizeDuration(muteTime * 1000, {round: true})}`),
reason: (interaction.options.getString("reason") ? `\n> ${interaction.options.getString("reason")}` : "No reason provided")
@@ -199,9 +201,9 @@
guild: interaction.guild.id
}
}
- log(data, client);
+ log(data);
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.GREEN")
.setTitle(`Mute`)
.setDescription("No changes were made")
@@ -221,7 +223,7 @@
// Check if Nucleus can mute the member
if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
// Check if Nucleus has permission to mute
- if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the `moderate_members` permission";
+ if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the Moderate members permission";
// Do not allow the user to have admin or be the owner
if (apply.permissions.has("ADMINISTRATOR") || (interaction.options.getMember("user") as GuildMember).id == interaction.guild.ownerId) throw "You cannot mute an admin or the owner"
// Do not allow muting Nucleus
@@ -229,7 +231,7 @@
// Allow the owner to mute anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user has moderate_members permission
- if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the `moderate_members` permission";
+ if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
// Check if the user is below on the role list
if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
// Allow mute
diff --git a/src/commands/mod/nick.ts b/src/commands/mod/nick.ts
index c09e197..e154277 100644
--- a/src/commands/mod/nick.ts
+++ b/src/commands/mod/nick.ts
@@ -2,9 +2,10 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import { create, areTicketsEnabled } from "../../automations/createModActionTicket.js";
+import client from "../../utils/client.js"
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -16,13 +17,14 @@
.addChoices([["Yes", "yes"], ["No", "no"]])
)
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ const { renderUser } = client.logger
// TODO:[Modals] Replace this with a modal
let confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.NICKNAME.RED")
.setTitle("Nickname")
.setDescription(keyValueList({
- "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+ "user": renderUser(interaction.options.getUser("user")),
"new nickname": `${interaction.options.getString("name") ? interaction.options.getString("name") : "*No nickname*"}`
})
+ `The user **will${interaction.options.getString("notify") == "yes" ? '' : ' not'}** be notified\n\n`
@@ -39,7 +41,7 @@
try {
if (interaction.options.getString("notify") == "yes") {
dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("PUNISH.NICKNAME.RED")
.setTitle("Nickname changed")
.setDescription(`Your nickname was ${interaction.options.getString("name") ? "changed" : "cleared"} in ${interaction.guild.name}.` +
@@ -56,6 +58,9 @@
let before = member.nickname
let nickname = interaction.options.getString("name")
member.setNickname(nickname ?? null, "Nucleus Nickname command")
+ try { await client.database.history.create(
+ "nickname", interaction.guild.id, member.user, interaction.user,
+ null, before, nickname) } catch {}
// @ts-ignore
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger
let data = {
@@ -78,9 +83,9 @@
guild: interaction.guild.id
}
}
- log(data, client);
+ log(data);
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.NICKNAME.RED")
.setTitle(`Nickname`)
.setDescription("Something went wrong and the users nickname could not be changed.")
@@ -90,14 +95,14 @@
return
}
let failed = (dmd == false && interaction.options.getString("notify") == "yes")
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
.setTitle(`Nickname`)
.setDescription("The members nickname was changed" + (failed ? ", but was not notified" : "") + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
.setStatus(failed ? "Warning" : "Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.NICKNAME.GREEN")
.setTitle(`Nickname`)
.setDescription("No changes were made")
@@ -117,11 +122,11 @@
// Check if Nucleus can change the nickname
if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
// Check if Nucleus has permission to change the nickname
- if (! me.permissions.has("MANAGE_NICKNAMES")) throw "I do not have the `manage_nicknames` permission";
+ if (! me.permissions.has("MANAGE_NICKNAMES")) throw "I do not have the Manage nicknames permission";
// Allow the owner to change anyone's nickname
if (member.id == interaction.guild.ownerId) return true
// Check if the user has manage_nicknames permission
- if (! member.permissions.has("MANAGE_NICKNAMES")) throw "You do not have the `manage_nicknames` permission";
+ if (! member.permissions.has("MANAGE_NICKNAMES")) throw "You do not have the Manage nicknames permission";
// Allow changing your own nickname
if (member == apply) return true
// Check if the user is below on the role list
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index c6a44b3..9aab260 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -2,9 +2,10 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
+import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -25,7 +26,7 @@
if (!(["GUILD_TEXT", "GUILD_NEWS", "GUILD_NEWS_THREAD", "GUILD_PUBLIC_THREAD", "GUILD_PRIVATE_THREAD"].includes(channel.type.toString()))) {
return await interaction.reply({
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.RED")
.setTitle("Purge")
.setDescription("You cannot purge this channel")
@@ -39,7 +40,7 @@
if ( !interaction.options.getInteger("amount") ) {
await interaction.reply({
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.RED")
.setTitle("Purge")
.setDescription("Select how many messages to delete")
@@ -53,7 +54,7 @@
while (true) {
let m = await interaction.editReply({
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.RED")
.setTitle("Purge")
.setDescription("Select how many messages to delete. You can continue clicking until all messages are cleared.")
@@ -118,7 +119,7 @@
}
if (deleted.length === 0) return await interaction.editReply({
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.RED")
.setTitle("Purge")
.setDescription("No messages were deleted")
@@ -126,10 +127,13 @@
],
components: []
})
+ if (user) {
+ try { await client.database.history.create("purge", interaction.guild.id, user, interaction.options.getString("reason"), null, null, deleted.length) } catch {}
+ }
let attachmentObject;
try {
// @ts-ignore
- const { log, NucleusColors, entry, renderUser, renderChannel } = interaction.user.client.logger
+ const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
let data = {
meta: {
type: 'channelPurge',
@@ -149,7 +153,7 @@
guild: interaction.guild.id
}
}
- log(data, interaction.user.client);
+ log(data);
let out = ""
deleted.reverse().forEach(message => {
out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`
@@ -163,7 +167,7 @@
description: "Purge log"
}
} catch {}
- let m = await interaction.editReply({embeds: [new generateEmojiEmbed()
+ let m = await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`CHANNEL.PURGE.GREEN`)
.setTitle(`Purge`)
.setDescription("Messages cleared")
@@ -180,14 +184,14 @@
component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
} catch {}
if (component && component.customId === "download") {
- interaction.editReply({embeds: [new generateEmojiEmbed()
+ interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.GREEN")
.setTitle(`Purge`)
.setDescription("Uploaded")
.setStatus("Success")
], components: [], files: [attachmentObject]})
} else {
- interaction.editReply({embeds: [new generateEmojiEmbed()
+ interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.GREEN")
.setTitle(`Purge`)
.setDescription("Messages cleared")
@@ -218,17 +222,20 @@
messages = await (channel as TextChannel).bulkDelete(toDelete, true);
}
} catch(e) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.RED")
.setTitle(`Purge`)
.setDescription("Something went wrong and no messages were deleted")
.setStatus("Danger")
], components: []})
}
+ if (user) {
+ try { await client.database.history.create("purge", interaction.guild.id, user, interaction.options.getString("reason"), null, null, messages.size) } catch {}
+ }
let attachmentObject;
try {
// @ts-ignore
- const { log, NucleusColors, entry, renderUser, renderChannel } = interaction.user.client.logger
+ const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
let data = {
meta: {
type: 'channelPurge',
@@ -248,7 +255,7 @@
guild: interaction.guild.id
}
}
- log(data, interaction.user.client);
+ log(data);
let out = ""
messages.reverse().forEach(message => {
out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`
@@ -262,7 +269,7 @@
description: `Purge log`
}
} catch {}
- let m = await interaction.editReply({embeds: [new generateEmojiEmbed()
+ let m = await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`CHANNEL.PURGE.GREEN`)
.setTitle(`Purge`)
.setDescription("Messages cleared")
@@ -279,14 +286,14 @@
component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
} catch {}
if (component && component.customId === "download") {
- interaction.editReply({embeds: [new generateEmojiEmbed()
+ interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.GREEN")
.setTitle(`Purge`)
.setDescription("Transcript uploaded above")
.setStatus("Success")
], components: [], files: [attachmentObject]})
} else {
- interaction.editReply({embeds: [new generateEmojiEmbed()
+ interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.GREEN")
.setTitle(`Purge`)
.setDescription("Messages cleared")
@@ -294,7 +301,7 @@
], components: []})
}
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.PURGE.GREEN")
.setTitle(`Purge`)
.setDescription("No changes were made")
@@ -310,9 +317,9 @@
// Allow the owner to purge
if (member.id == interaction.guild.ownerId) return true
// Check if the user has manage_messages permission
- if (! member.permissions.has("MANAGE_MESSAGES")) throw "You do not have the `manage_messages` permission";
+ if (! member.permissions.has("MANAGE_MESSAGES")) throw "You do not have the Manage messages permission";
// Check if nucleus has the manage_messages permission
- if (! me.permissions.has("MANAGE_MESSAGES")) throw "I do not have the `manage_messages` permission";
+ if (! me.permissions.has("MANAGE_MESSAGES")) throw "I do not have the Manage messages permission";
// Allow warn
return true
}
diff --git a/src/commands/mod/slowmode.ts b/src/commands/mod/slowmode.ts
index 2498746..d9a8421 100644
--- a/src/commands/mod/slowmode.ts
+++ b/src/commands/mod/slowmode.ts
@@ -4,7 +4,8 @@
import { WrappedCheck } from "jshaiku";
import keyValueList from "../../utils/generateKeyValueList.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -18,11 +19,11 @@
["1 hour", "3600"], ["2 hours", "7200"], ["6 hours", "21600"]
]))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
let time = parseInt(interaction.options.getString("time") ?? "0");
if (time === 0 && (interaction.channel as TextChannel).rateLimitPerUser === 0) { time = 10 }
let confirmation = await new confirmationMessage(interaction)
- .setEmoji("CHANNEL.SLOWMODE.RED")
+ .setEmoji("CHANNEL.SLOWMODE.OFF")
.setTitle("Slowmode")
.setDescription(keyValueList({
"time": time ? humanizeDuration(time * 1000, { round: true }) : "No delay",
@@ -34,22 +35,22 @@
try {
(interaction.channel as TextChannel).setRateLimitPerUser(time)
} catch (e) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
- .setEmoji("CHANNEL.SLOWMODE.RED")
+ await interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji("CHANNEL.SLOWMODE.OFF")
.setTitle(`Slowmode`)
.setDescription("Something went wrong while setting the slowmode")
.setStatus("Danger")
], components: []})
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
- .setEmoji(`CHANNEL.SLOWMODE.GREEN`)
+ await interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji(`CHANNEL.SLOWMODE.ON`)
.setTitle(`Slowmode`)
.setDescription("The channel slowmode was set successfully")
.setStatus("Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
- .setEmoji("CHANNEL.SLOWMODE.GREEN")
+ await interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji("CHANNEL.SLOWMODE.ON")
.setTitle(`Slowmode`)
.setDescription("No changes were made")
.setStatus("Success")
@@ -60,9 +61,9 @@
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
let member = (interaction.member as GuildMember)
// Check if Nucleus can set the slowmode
- if (! interaction.guild.me.permissions.has("MANAGE_CHANNELS")) throw "I do not have the `manage_channels` permission";
+ if (! interaction.guild.me.permissions.has("MANAGE_CHANNELS")) throw "I do not have the Manage channels permission";
// Check if the user has manage_channel permission
- if (! member.permissions.has("MANAGE_CHANNELS")) throw "You do not have the `manage_channels` permission";
+ if (! member.permissions.has("MANAGE_CHANNELS")) throw "You do not have the Manage channels permission";
// Allow slowmode
return true
}
diff --git a/src/commands/mod/softban.ts b/src/commands/mod/softban.ts
index 5a01287..ea4a447 100644
--- a/src/commands/mod/softban.ts
+++ b/src/commands/mod/softban.ts
@@ -2,7 +2,7 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js";
import addPlural from "../../utils/plurals.js";
@@ -18,13 +18,14 @@
)
.addIntegerOption(option => option.setName("delete").setDescription("The days of messages to delete | Default 0").setMinValue(0).setMaxValue(7).setRequired(false))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ const { renderUser } = client.logger
// TODO:[Modals] Replace this with a modal
let confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.BAN.RED")
.setTitle("Softban")
.setDescription(keyValueList({
- "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+ "user": renderUser(interaction.options.getUser("user")),
"reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
})
+ `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n`
@@ -34,11 +35,11 @@
.send()
if (confirmation.success) {
let dmd = false;
- let config = await client.database.read(interaction.guild.id);
+ let config = await client.database.guilds.read(interaction.guild.id);
try {
if (interaction.options.getString("notify") != "no") {
await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("PUNISH.BAN.RED")
.setTitle("Softbanned")
.setDescription(`You have been softbanned from ${interaction.guild.name}` +
@@ -54,29 +55,31 @@
dmd = true
}
} catch {}
+ let member = (interaction.options.getMember("user") as GuildMember)
try {
- await (interaction.options.getMember("user") as GuildMember).ban({
+ await member.ban({
days: Number(interaction.options.getInteger("delete") ?? 0),
reason: interaction.options.getString("reason")
});
- await interaction.guild.members.unban(interaction.options.getMember("user") as GuildMember, "Softban");
+ await interaction.guild.members.unban(member, "Softban");
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.BAN.RED")
.setTitle(`Softban`)
.setDescription("Something went wrong and the user was not softbanned")
.setStatus("Danger")
], components: []})
}
+ try { await client.database.history.create("softban", interaction.guild.id, member.user, interaction.options.getString("reason")) } catch {}
let failed = (dmd == false && interaction.options.getString("notify") != "no")
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
.setTitle(`Softban`)
.setDescription("The member was softbanned" + (failed ? ", but could not be notified" : ""))
.setStatus(failed ? "Warning" : "Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.BAN.GREEN")
.setTitle(`Softban`)
.setDescription("No changes were made")
@@ -96,13 +99,13 @@
// Check if Nucleus can ban the member
if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
// Check if Nucleus has permission to ban
- if (!me.permissions.has("BAN_MEMBERS")) throw "I do not have the `ban_members` permission";
+ if (!me.permissions.has("BAN_MEMBERS")) throw "I do not have the Ban members permission";
// Do not allow softbanning Nucleus
if (member.id == me.id) throw "I cannot softban myself"
// Allow the owner to ban anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user has ban_members permission
- if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the `ban_members` permission";
+ if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the Ban members permission";
// Check if the user is below on the role list
if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
// Allow softban
diff --git a/src/commands/mod/unban.ts b/src/commands/mod/unban.ts
index f7bf74f..7f605d9 100644
--- a/src/commands/mod/unban.ts
+++ b/src/commands/mod/unban.ts
@@ -1,9 +1,10 @@
import { CommandInteraction, GuildMember, User } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
+import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -11,14 +12,14 @@
.setDescription("Unbans a user")
.addStringOption(option => option.setName("user").setDescription("The user to unban (Username or ID)").setRequired(true))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
let bans = await interaction.guild.bans.fetch()
let user = interaction.options.getString("user")
let resolved = bans.find(ban => ban.user.id == user)
if (!resolved) resolved = bans.find(ban => ban.user.username.toLowerCase() == user.toLowerCase())
if (!resolved) resolved = bans.find(ban => ban.user.tag.toLowerCase() == user.toLowerCase())
if (!resolved) {
- return interaction.reply({embeds: [new generateEmojiEmbed()
+ return interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Unban")
.setDescription(`Could not find any user called \`${user}\``)
.setEmoji("PUNISH.UNBAN.RED")
@@ -39,8 +40,9 @@
try {
await interaction.guild.members.unban(resolved.user as User, "Unban");
let member = (resolved.user as User)
+ try { await client.database.history.create("unban", interaction.guild.id, member, interaction.user) } catch {}
// @ts-ignore
- const { log, NucleusColors, entry, renderUser, renderDelta } = interaction.user.client.logger
+ const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger
let data = {
meta: {
type: 'memberUnban',
@@ -61,23 +63,23 @@
guild: interaction.guild.id
}
}
- log(data, member.client);
+ log(data);
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.UNBAN.RED")
.setTitle(`Unban`)
.setDescription("Something went wrong and the user was not unbanned")
.setStatus("Danger")
], components: []})
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.UNBAN.GREEN`)
.setTitle(`Unban`)
.setDescription("The member was unbanned")
.setStatus("Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.UNBAN.GREEN")
.setTitle(`Unban`)
.setDescription("No changes were made")
@@ -90,11 +92,11 @@
let member = (interaction.member as GuildMember)
let me = (interaction.guild.me as GuildMember)
// Check if Nucleus can unban members
- if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the `ban_members` permission";
+ if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the Ban members permission";
// Allow the owner to unban anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user has ban_members permission
- if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the `ban_members` permission";
+ if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the Ban members permission";
// Allow unban
return true
}
diff --git a/src/commands/mod/unmute.ts b/src/commands/mod/unmute.ts
index 2a98c54..5a1b67c 100644
--- a/src/commands/mod/unmute.ts
+++ b/src/commands/mod/unmute.ts
@@ -2,8 +2,9 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
+import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -15,13 +16,14 @@
.addChoices([["Yes", "yes"], ["No", "no"]])
)
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ const { renderUser } = client.logger
// TODO:[Modals] Replace this with a modal
let confirmation = await new confirmationMessage(interaction)
.setEmoji("PUNISH.MUTE.RED")
.setTitle("Unmute")
.setDescription(keyValueList({
- "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+ "user": renderUser(interaction.options.getUser("user")),
"reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
})
+ `The user **will${interaction.options.getString("notify") === "yes" ? '' : ' not'}** be notified\n\n`
@@ -34,7 +36,7 @@
try {
if (interaction.options.getString("notify") != "no") {
dm = await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.GREEN")
.setTitle("Unmuted")
.setDescription(`You have been unmuted in ${interaction.guild.name}` +
@@ -48,7 +50,7 @@
try {
(interaction.options.getMember("user") as GuildMember).timeout(0, interaction.options.getString("reason") || "No reason provided")
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.RED")
.setTitle(`Unmute`)
.setDescription("Something went wrong and the user was not unmuted")
@@ -57,15 +59,16 @@
if (dmd) await dm.delete()
return
}
+ try { await client.database.history.create("unmute", interaction.guild.id, (interaction.options.getMember("user") as GuildMember).user, interaction.user, interaction.options.getString("reason")) } catch {}
let failed = (dmd == false && interaction.options.getString("notify") != "no")
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
.setTitle(`Unmute`)
.setDescription("The member was unmuted" + (failed ? ", but could not be notified" : ""))
.setStatus(failed ? "Warning" : "Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.MUTE.GREEN")
.setTitle(`Unmute`)
.setDescription("No changes were made")
@@ -85,13 +88,13 @@
// Check if Nucleus can unmute the member
if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
// Check if Nucleus has permission to unmute
- if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the `moderate_members` permission";
+ if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the Moderate members permission";
// Do not allow the user to have admin or be the owner
if (apply.permissions.has("ADMINISTRATOR") || apply.id == interaction.guild.ownerId) throw "You cannot unmute an admin or the owner"
// Allow the owner to unmute anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user has moderate_members permission
- if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the `moderate_members` permission";
+ if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
// Check if the user is below on the role list
if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
// Allow unmute
diff --git a/src/commands/mod/viewas.ts b/src/commands/mod/viewas.ts
index 705c04a..b3875a7 100644
--- a/src/commands/mod/viewas.ts
+++ b/src/commands/mod/viewas.ts
@@ -1,8 +1,9 @@
-import Discord, { CategoryChannel, CommandInteraction } from "discord.js";
+import Discord, { CategoryChannel, CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import { WrappedCheck } from "jshaiku";
import getEmojiByName from "../../utils/getEmojiByName.js";
+import pageIndicator from "../../utils/createPageIndicator.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -10,8 +11,9 @@
.setDescription("View the server as a specific member")
.addUserOption(option => option.setName("member").setDescription("The member to view as").setRequired(true))
-const callback = async (interaction: CommandInteraction) => {
- let channels = []
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ let channels = [];
+ let m;
interaction.guild.channels.cache.forEach(channel => {
if (!channel.parent && channel.type !== "GUILD_CATEGORY") channels.push(channel)
})
@@ -22,39 +24,83 @@
)
let autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"]
channels = channels.map(c => c.sort((a, b) => {
- if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.name.localeCompare(b.name)
- if (autoSortBelow.includes(a.type)) return -1
- if (autoSortBelow.includes(b.type)) return 1
+ if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position
+ if (autoSortBelow.includes(a.type)) return 1
+ if (autoSortBelow.includes(b.type)) return -1
return a.position - b.position
}))
+ // Sort all arrays by the position of the first channels parent position
+ channels = channels.sort((a, b) => {
+ if (!a[0].parent) return -1
+ if (!b[0].parent) return 1
+ return a[0].parent.position - b[0].parent.position
+ })
let member = interaction.options.getMember("member") as Discord.GuildMember
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ m = await interaction.reply({embeds: [new EmojiEmbed()
.setEmoji("MEMBER.JOIN")
.setTitle("Viewing as " + member.displayName)
.setStatus("Success")
- ], ephemeral: true})
+ ], ephemeral: true, fetchReply: true})
let page = 0;
while (true) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ m = await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("MEMBER.JOIN")
.setTitle("Viewing as " + member.displayName)
.setStatus("Success")
.setDescription(
- `${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}` +
- "Visible:\n" +
+ `**${channels[page][0].parent ? channels[page][0].parent.name : "Uncategorised"}**` + "\n" +
channels[page].map(c => {
- console.log(c)
- return (channels[page] as Discord.GuildChannel).permissionsFor(member).has("VIEW_CHANNEL") ?
- `${getEmojiByName("ICONS.CHANNEL." + c.type)} ${c.name}\n` : ""
- }).join("")
+ let channelType = c.type
+ if (interaction.guild.rulesChannelId == c.id) channelType = "RULES"
+ else if ("nsfw" in c && c.nsfw) channelType += "_NSFW"
+ return c.permissionsFor(member).has("VIEW_CHANNEL") ? (
+ `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` + (() => {
+ if ("threads" in c && c.threads.cache.size > 0) {
+ return c.threads.cache.map(t => ` ${
+ getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") + " " +
+ getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")} ${t.name}`).join("\n") + "\n"
+ }return ""
+ })()) : ""
+ }).join("") + "\n" + pageIndicator(channels.length, page)
)
+ ], components: [
+ new MessageActionRow().addComponents([new MessageSelectMenu().setOptions(channels.map((c, index) => ({
+ label: c[0].parent ? c[0].parent.name : "Uncategorised",
+ value: index.toString(),
+ default: page === index
+ }))).setCustomId("select").setMaxValues(1).setMinValues(1).setPlaceholder("Select a category")]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel(page === 0 ? "" : (channels[page - 1][0].parent ? channels[page - 1][0].parent.name : "Uncategorised"))
+ .setDisabled(page === 0)
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("previous"),
+ new MessageButton()
+ .setLabel(page === channels.length - 1 ? "" : (channels[page + 1][0].parent ? channels[page + 1][0].parent.name : "Uncategorised"))
+ .setDisabled(page === channels.length - 1)
+ .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("next")
+ ])
]})
- break
+ let i;
+ try {
+ i = await m.awaitMessageComponent({ time: 300000 });
+ } catch (e) { return }
+ i.deferUpdate()
+ if (i.customId === "next") { page++; }
+ else if (i.customId === "previous") { page--; }
+ else if (i.customId === "select") { page = parseInt(i.values[0]); }
}
}
+
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
- return true;
+ return true // FIXME FOR RELEASE
+ let member = (interaction.member as GuildMember)
+ if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
+ return true
}
export { command, callback, check };
\ No newline at end of file
diff --git a/src/commands/mod/warn.ts b/src/commands/mod/warn.ts
index b8fb98f..370f347 100644
--- a/src/commands/mod/warn.ts
+++ b/src/commands/mod/warn.ts
@@ -2,9 +2,10 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import { create, areTicketsEnabled } from "../../automations/createModActionTicket.js";
+import client from "../../utils/client.js"
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -23,7 +24,7 @@
.setEmoji("PUNISH.WARN.RED")
.setTitle("Warn")
.setDescription(keyValueList({
- "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+ "user": renderUser(interaction.options.getUser("user")),
"reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
})
+ `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n\n`
@@ -39,7 +40,7 @@
try {
if (interaction.options.getString("notify") != "no") {
await (interaction.options.getMember("user") as GuildMember).send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("PUNISH.WARN.RED")
.setTitle("Warned")
.setDescription(`You have been warned in ${interaction.guild.name}` +
@@ -51,7 +52,7 @@
dmd = true
}
} catch {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.WARN.RED")
.setTitle(`Warn`)
.setDescription("Something went wrong and the user was not warned")
@@ -76,10 +77,15 @@
guild: interaction.guild.id
}
}
- log(data, client);
+ try { await client.database.history.create(
+ "warn", interaction.guild.id,
+ (interaction.options.getMember("user") as GuildMember).user,
+ interaction.user, interaction.options.getString("reason")
+ )} catch {}
+ log(data);
let failed = (dmd == false && interaction.options.getString("notify") != "no")
if (!failed) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.WARN.GREEN`)
.setTitle(`Warn`)
.setDescription("The user was warned" + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
@@ -87,7 +93,7 @@
], components: []})
} else {
let m = await interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.WARN.RED`)
.setTitle(`Warn`)
.setDescription("The user's DMs are not open\n\nWhat would you like to do?")
@@ -110,7 +116,7 @@
try {
component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
} catch (e) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.WARN.GREEN`)
.setTitle(`Warn`)
.setDescription("No changes were made")
@@ -119,7 +125,7 @@
}
if ( component.customId == "here" ) {
await interaction.channel.send({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.WARN.RED`)
.setTitle(`Warn`)
.setDescription(`You have been warned` +
@@ -129,14 +135,14 @@
content: `<@!${(interaction.options.getMember("user") as GuildMember).id}>`,
allowedMentions: {users: [(interaction.options.getMember("user") as GuildMember).id]}
})
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.WARN.GREEN`)
.setTitle(`Warn`)
.setDescription("The user was warned" + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
.setStatus("Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji(`PUNISH.WARN.GREEN`)
.setTitle(`Warn`)
.setDescription("The warn was logged")
@@ -145,7 +151,7 @@
}
}
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("PUNISH.WARN.GREEN")
.setTitle(`Warn`)
.setDescription("No changes were made")
@@ -167,7 +173,7 @@
// Allow the owner to warn anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user has moderate_members permission
- if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the `moderate_members` permission";
+ if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
// Check if the user is below on the role list
if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
// Allow warn
diff --git a/src/commands/nucleus/guide.ts b/src/commands/nucleus/guide.ts
index 814d2f5..eb94de4 100644
--- a/src/commands/nucleus/guide.ts
+++ b/src/commands/nucleus/guide.ts
@@ -2,7 +2,7 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import getEmojiByName from "../../utils/getEmojiByName.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import guide from "../../automations/guide.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
diff --git a/src/commands/nucleus/invite.ts b/src/commands/nucleus/invite.ts
index 8b25820..7f7d4b8 100644
--- a/src/commands/nucleus/invite.ts
+++ b/src/commands/nucleus/invite.ts
@@ -1,7 +1,7 @@
import { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js"
const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -10,7 +10,7 @@
.setDescription("Invites Nucleus to your server")
const callback = (interaction: CommandInteraction) => {
- interaction.reply({embeds: [new generateEmojiEmbed()
+ interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Invite")
.setDescription("You can invite Nucleus to your server by clicking the button below")
.setEmoji("NUCLEUS.LOGO")
diff --git a/src/commands/nucleus/ping.ts b/src/commands/nucleus/ping.ts
index 58413c6..f10dcae 100644
--- a/src/commands/nucleus/ping.ts
+++ b/src/commands/nucleus/ping.ts
@@ -1,6 +1,6 @@
import { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import { WrappedCheck } from "jshaiku";
import client from "../../utils/client.js"
@@ -9,18 +9,18 @@
.setName("ping")
.setDescription("Gets the bot's ping time")
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
// WEBSOCKET | Nucleus -> Discord
// EDITING | Nucleus -> discord -> nucleus | edit time / 2
let initial = new Date().getTime();
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Ping")
.setDescription(`Checking ping times...`)
.setEmoji("NUCLEUS.LOADING")
.setStatus("Danger")
], ephemeral: true});
let ping = new Date().getTime() - initial;
- interaction.editReply({embeds: [new generateEmojiEmbed()
+ interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Ping")
.setDescription(
`**Ping:** \`${ping}ms\`\n` +
diff --git a/src/commands/nucleus/stats.ts b/src/commands/nucleus/stats.ts
index 1a0602e..cb10e7a 100644
--- a/src/commands/nucleus/stats.ts
+++ b/src/commands/nucleus/stats.ts
@@ -1,7 +1,7 @@
import { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js"
const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -11,7 +11,7 @@
const callback = (interaction: CommandInteraction) => {
interaction.reply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Stats")
.setDescription(
`**Servers:** ${client.guilds.cache.size}\n` +
diff --git a/src/commands/nucleus/suggest.ts b/src/commands/nucleus/suggest.ts
index c07d9b8..4e3a1c8 100644
--- a/src/commands/nucleus/suggest.ts
+++ b/src/commands/nucleus/suggest.ts
@@ -2,7 +2,7 @@
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js"
const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -11,7 +11,7 @@
.setDescription("Sends a suggestion to the developers")
.addStringOption(option => option.setName("suggestion").setDescription("The suggestion to send").setRequired(true))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
// @ts-ignore
const { renderUser } = client.logger
let suggestion = interaction.options.getString("suggestion");
@@ -26,21 +26,21 @@
if (confirmation.success) {
await (client.channels.cache.get('955161206459600976') as Discord.TextChannel).send({
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setTitle(`Suggestion`)
.setDescription(`**From:** ${renderUser(interaction.member.user)}\n**Suggestion:**\n> ${suggestion}`)
.setStatus("Danger")
.setEmoji("NUCLEUS.LOGO")
]
})
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("ICONS.ADD")
.setTitle(`Suggest`)
.setDescription("Your suggestion was sent successfully")
.setStatus("Success")
], components: []})
} else {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("ICONS.OPP.ADD")
.setTitle(`Suggest`)
.setDescription("No changes were made")
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index 3174421..cc6c554 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -8,7 +8,7 @@
.setDescription("we changed the fucking charger again!")
.addStringOption(option => option.setName("link").setDescription("fuck you").setRequired(false))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
console.log(await testLink(interaction.options.getString("link")))
}
diff --git a/src/commands/role/all.ts b/src/commands/role/all.ts
index 44e77fd..d24110b 100644
--- a/src/commands/role/all.ts
+++ b/src/commands/role/all.ts
@@ -1,17 +1,161 @@
-import { CommandInteraction } from "discord.js";
+import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+import addPlural from "../../utils/plurals.js";
+import client from "../../utils/client.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("all")
.setDescription("Gives or removes a role from everyone")
-const callback = (interaction: CommandInteraction) => {
- interaction.reply("This command is not yet finished [role/all]");
+class Filter {
+ name: string;
+ data: object;
+ checkFunction: (member) => boolean;
+ inverted: boolean = false;
+ constructor(name: (data) => string | string, data: object, check: (member) => boolean) {
+ if (typeof name === "function") { this.name = name(data);
+ } else { this.name = name; }
+ this.data = data;
+ this.checkFunction = check;
+ }
+ flip() { this.inverted = true; return this; }
+ check(member) {
+ if (this.inverted) return !this.checkFunction(member)
+ else return this.checkFunction(member)
+ }
}
-const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+const filterList = {
+ member: {
+ render: "Member",
+ has: {
+ render: "has",
+ role: (role) => ( new Filter((data) => `Member has role <@&${data.role}>`, {role: role, type: Discord.Role, render: "role"}, (member) => { return member.roles.cache.has(role)}))
+ },
+ joined: {
+ render: "joined",
+ before: (date) => ( new Filter((data) => `Joined server before <t:${Math.round(date.getTime() / 1000)}:F>`, {date: date, type: Date, render: "before"}, (member) => {
+ return member.joinedTimestamp < date.getTime()
+ })),
+ after: (date) => ( new Filter((data) => `Joined server after <t:${Math.round(date.getTime() / 1000)}:F>`, {date: date, type: Date, render: "after"}, (member) => {
+ return member.joinedTimestamp > date.getTime()
+ }).flip())
+ },
+ nickname: {
+ render: "Nickname",
+ set: () => ( new Filter((data) => `Member has a nickname set"`, {render: "set"}, (member) => { return member.nickname !== null})),
+ include: (name) => ( new Filter((data) => `Nickname includes "${name}"`, {nickname: name, type: String, render: "includes"}, (member) => {
+ return member.displayName.includes(name)})),
+ startsWith: (name) => ( new Filter((data) => `Nickname starts with "${name}"`, {nickname: name, type: String, render: "starts with"}, (member) => {
+ return member.displayName.startsWith(name)})),
+ endsWith: (name) => ( new Filter((data) => `Nickname ends with "${name}"`, {nickname: name, type: String, render: "ends with"}, (member) => {
+ return member.displayName.endsWith(name)}))
+ }
+ },
+ account: {
+ render: "Account",
+ created: {
+ render: "created",
+ before: (date) => ( new Filter((data) => `Account created before <t:${Math.round(date.getTime() / 1000)}:D>`, {date: date, type: Date, render: "before"}, (member) => {
+ return member.user.createdTimestamp < date.getTime()
+ })),
+ after: (date) => ( new Filter((data) => `Account created after <t:${Math.round(date.getTime() / 1000)}:D>`, {date: date, type: Date, render: "after"}, (member) => {
+ return member.user.createdTimestamp < date.getTime()
+ }).flip())
+ },
+ is: {
+ render: "is",
+ human: () => ( new Filter((data) => `Member is a human`, {human: true, render: "human"}, (member) => { return !member.bot })),
+ },
+ username: {
+ render: "Username",
+ include: (name) => ( new Filter((data) => `Nickname includes "${name}"`, {nickname: name, type: String, render: "includes"}, (member) => {
+ return member.user.name.includes(name)})),
+ startsWith: (name) => ( new Filter((data) => `Nickname starts with "${name}"`, {nickname: name, type: String, render: "starts with"}, (member) => {
+ return member.user.name.startsWith(name)})),
+ endsWith: (name) => ( new Filter((data) => `Nickname ends with "${name}"`, {nickname: name, type: String, render: "ends with"}, (member) => {
+ return member.user.name.endsWith(name)}))
+ }
+ }
+}
+
+const callback = async (interaction: CommandInteraction) => {
+ await interaction.reply({embeds: [new EmojiEmbed()
+ .setTitle("Role all")
+ .setDescription("Loading...")
+ .setStatus("Danger")
+ .setEmoji("NUCLEUS.LOADING")
+ ], ephemeral: true, fetchReply: true})
+ let filters: Filter[] = [
+ filterList.member.has.role("959901346000154674"),
+ filterList.member.nickname.startsWith("Pinea"),
+ filterList.member.joined.before(new Date(2022, 1)).flip()
+ ]
+ let all = true;
+ while (true) {
+ let count = 0;
+ let affected = []
+ let members = interaction.guild.members.cache
+ if (all) {
+ members.forEach(member => {
+ let applies = true;
+ filters.forEach(filter => { if (!filter.check(member)) { applies = false } })
+ if (applies) { affected.push(member) }
+ })
+ } else {
+ members.forEach(member => {
+ let applies = false;
+ filters.forEach(filter => { if (filter.check(member)) { applies = true } })
+ if (applies) { affected.push(member) }
+ })
+ }
+ await interaction.editReply({embeds: [new EmojiEmbed()
+ .setTitle("Role all")
+ .setDescription((all ? "All of the following must be true:" : "Any of the following must be true") + "\n" +
+ filters.map((f) => {
+ count ++;
+ return (count == 1 ? getEmojiByName("ICONS.FILTER") : (all ? "**and** " : "**or** ")) +
+ (f.inverted ? "**not** " : "") + `${f.name}`
+ }).join("\n") + "\n\n" + `This will affect ${addPlural(affected.length.toString(), "member")}`)
+ .setEmoji("GUILD.ROLES.CREATE")
+ .setStatus("Success")
+ ], components: [
+ new MessageActionRow().addComponents([new MessageSelectMenu().setOptions(filters.map((f, index) => ({
+ label: (f.inverted ? "(Not) " : "") + f.name,
+ value: index.toString()
+ }))).setMinValues(1).setMaxValues(filters.length).setCustomId("select").setPlaceholder("Remove a filter")]),
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Apply")
+ .setStyle("PRIMARY")
+ .setCustomId("apply")
+ .setEmoji(client.emojis.cache.get(getEmojiByName("CONTROL.TICK", "id")))
+ .setDisabled(affected.length === 0),
+ new MessageButton()
+ .setLabel("Add filter")
+ .setStyle("PRIMARY")
+ .setCustomId("add")
+ .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.FILTER", "id")))
+ .setDisabled(filters.length >= 25)
+ ])
+ ]})
+ break
+ }
+}
+
+const check = async (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+ let member = (interaction.member as GuildMember)
+ let me = (interaction.guild.me as GuildMember)
+ if (!me.permissions.has("MANAGE_ROLES")) throw "I do not have the Manage roles permission";
+ // Allow the owner to role anyone
+ if (member.id == interaction.guild.ownerId) return true
+ // Check if the user has manage_roles permission
+ if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
+ // Allow role
return true;
}
diff --git a/src/commands/role/user.ts b/src/commands/role/user.ts
index b45e1d1..bb79098 100644
--- a/src/commands/role/user.ts
+++ b/src/commands/role/user.ts
@@ -1,17 +1,84 @@
-import { CommandInteraction } from "discord.js";
+import { CommandInteraction, GuildMember, Role } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
+import client from "../../utils/client.js";
+import confirmationMessage from "../../utils/confirmationMessage.js";
+import keyValueList from "../../utils/generateKeyValueList.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
.setName("user")
.setDescription("Gives or removes a role from someone")
+ .addUserOption(option => option.setName("user").setDescription("The member to give or remove the role from").setRequired(true))
+ .addRoleOption(option => option.setName("role").setDescription("The role to give or remove").setRequired(true))
+ .addStringOption(option => option.setName("action").setDescription("The action to perform").setRequired(true).addChoices([
+ ["Add", "give"],
+ ["Remove", "remove"]
+ ]))
-const callback = (interaction: CommandInteraction) => {
- interaction.reply("This command is not yet finished [role/user]");
+
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ const { renderUser, renderRole } = client.logger
+ let action = interaction.options.getString("action");
+ // TODO:[Modals] Replace this with a modal
+ let confirmation = await new confirmationMessage(interaction)
+ .setEmoji("GUILD.ROLES.DELETE")
+ .setTitle("Role")
+ .setDescription(keyValueList({
+ "user": renderUser(interaction.options.getUser("user")),
+ "role": renderRole(interaction.options.getRole("role"))
+ })
+ + `\nAre you sure you want to ${action == "give" ? "give the role to" : "remove the role from"} ${interaction.options.getUser("user")}?`)
+ .setColor("Danger")
+ .send()
+ if (confirmation.success) {
+ try {
+ let member = interaction.options.getMember("user") as GuildMember
+ let role = interaction.options.getRole("role") as Role
+ if (interaction.options.getString("action") == "give") {
+ member.roles.add(role)
+ } else {
+ member.roles.remove(role)
+ }
+ } catch (e) {
+ return await interaction.editReply({embeds: [new EmojiEmbed()
+ .setTitle("Role")
+ .setDescription("Something went wrong and the role could not be added")
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ], components: []})
+ }
+ return await interaction.editReply({embeds: [new EmojiEmbed()
+ .setTitle("Role")
+ .setDescription(`The role has been ${action == "give" ? "given" : "removed"} successfully`)
+ .setStatus("Success")
+ .setEmoji("GUILD.ROLES.CREATE")
+ ], components: []})
+ } else {
+ await interaction.editReply({embeds: [new EmojiEmbed()
+ .setEmoji("GUILD.ROLES.CREATE")
+ .setTitle("Role")
+ .setDescription(`You have cancelled the role change.`)
+ .setStatus("Danger")
+ ], components: []})
+ }
}
const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+ let member = (interaction.member as GuildMember)
+ let me = (interaction.guild.me as GuildMember)
+ let apply = (interaction.options.getMember("user") as GuildMember)
+ if (member == null || me == null || apply == null) throw "That member is not in the server"
+ // Check if Nucleus has permission to role
+ if (!me.permissions.has("MANAGE_ROLES")) throw "I do not have the Manage roles permission";
+ // Allow the owner to role anyone
+ if (member.id == interaction.guild.ownerId) return true
+ // Check if the user has manage_roles permission
+ if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
+ // Check if the role is above or equal to the user's highest role
+ if (apply.roles.highest.comparePositionTo(member.roles.highest) >= 0) throw "You cannot give a role higher than your highest role";
+ // Allow role
return true;
}
diff --git a/src/commands/server/about.ts b/src/commands/server/about.ts
index 895d2cc..28e09aa 100644
--- a/src/commands/server/about.ts
+++ b/src/commands/server/about.ts
@@ -1,7 +1,7 @@
import Discord, { CommandInteraction, Guild, MessageActionRow, MessageButton } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import generateKeyValueList, { toCapitals } from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js"
@@ -10,10 +10,10 @@
.setName("about")
.setDescription("Shows info about the server")
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
let guild = interaction.guild as Guild;
const { renderUser, renderDelta } = client.logger
- interaction.reply({embeds: [new generateEmojiEmbed()
+ interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Server Info")
.setStatus("Success")
.setEmoji("GUILD.GREEN")
diff --git a/src/commands/settings/logs/channel.ts b/src/commands/settings/logs/channel.ts
index 448f26a..19a389b 100644
--- a/src/commands/settings/logs/channel.ts
+++ b/src/commands/settings/logs/channel.ts
@@ -1,6 +1,6 @@
import { ChannelType } from 'discord-api-types';
import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../../utils/confirmationMessage.js";
import getEmojiByName from "../../../utils/getEmojiByName.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -17,7 +17,7 @@
const callback = async (interaction: CommandInteraction): Promise<any> => {
let m;
- m = await interaction.reply({embeds: [new generateEmojiEmbed()
+ m = await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Loading")
.setStatus("Danger")
.setEmoji("NUCLEUS.LOADING")
@@ -27,7 +27,7 @@
try {
channel = interaction.options.getChannel("channel")
} catch {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.TEXT.DELETE")
.setTitle("Log Channel")
.setDescription("The channel you provided is not a valid channel")
@@ -36,7 +36,7 @@
}
channel = channel as Discord.TextChannel
if (channel.guild.id != interaction.guild.id) {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Log Channel")
.setDescription(`You must choose a channel in this server`)
.setStatus("Danger")
@@ -52,10 +52,10 @@
.send(true)
if (confirmation.success) {
try {
- await client.database.write(interaction.guild.id, {"logging.logs.channel": channel.id})
+ await client.database.guilds.write(interaction.guild.id, {"logging.logs.channel": channel.id})
} catch (e) {
console.log(e)
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Log Channel")
.setDescription(`Something went wrong and the log channel could not be set`)
.setStatus("Danger")
@@ -63,7 +63,7 @@
], components: []});
}
} else {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Log Channel")
.setDescription(`No changes were made`)
.setStatus("Success")
@@ -72,10 +72,10 @@
}
}
let clicks = 0;
- let data = await client.database.read(interaction.guild.id);
+ let data = await client.database.guilds.read(interaction.guild.id);
let channel = data.logging.logs.channel;
while (true) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Log channel")
.setDescription(channel ? `Your log channel is currently set to <#${channel}>` : "This server does not have a log channel")
.setStatus("Success")
@@ -96,14 +96,14 @@
clicks += 1;
if (clicks == 2) {
clicks = 0;
- await client.database.write(interaction.guild.id, {}, ["logging.logs.channel"])
+ await client.database.guilds.write(interaction.guild.id, {}, ["logging.logs.channel"])
channel = undefined;
}
} else {
break
}
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Log channel")
.setDescription(channel ? `Your log channel is currently set to <#${channel}>` : "This server does not have a log channel")
.setStatus("Success")
diff --git a/src/commands/settings/logs/ignore.ts b/src/commands/settings/logs/ignore.ts
index 4b66307..12af085 100644
--- a/src/commands/settings/logs/ignore.ts
+++ b/src/commands/settings/logs/ignore.ts
@@ -1,7 +1,7 @@
import { ChannelType } from 'discord-api-types';
import Discord, { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import { WrappedCheck } from "jshaiku";
import confirmationMessage from '../../../utils/confirmationMessage.js';
import keyValueList from '../../../utils/generateKeyValueList.js';
@@ -24,7 +24,7 @@
let channel = interaction.options.getChannel("addchannel")
let user = interaction.options.getUser("adduser")
let role = interaction.options.getRole("addrole")
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Loading")
.setStatus("Danger")
.setEmoji("NUCLEUS.LOADING")
@@ -34,7 +34,7 @@
try {
channel = interaction.guild.channels.cache.get(channel.id)
} catch {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.TEXT.DELETE")
.setTitle("Logs > Ignore")
.setDescription("The channel you provided is not a valid channel")
@@ -43,7 +43,7 @@
}
channel = channel as Discord.TextChannel
if (channel.guild.id != interaction.guild.id) {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Logs > Ignore")
.setDescription(`You must choose a channel in this server`)
.setStatus("Danger")
@@ -55,7 +55,7 @@
try {
user = interaction.guild.members.cache.get(user.id).user
} catch {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("USER.DELETE")
.setTitle("Logs > Ignore")
.setDescription("The user you provided is not a valid user")
@@ -68,7 +68,7 @@
try {
role = interaction.guild.roles.cache.get(role.id)
} catch {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("ROLE.DELETE")
.setTitle("Logs > Ignore")
.setDescription("The role you provided is not a valid role")
@@ -77,7 +77,7 @@
}
role = role as Discord.Role
if (role.guild.id != interaction.guild.id) {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Logs > Ignore")
.setDescription(`You must choose a role in this server`)
.setStatus("Danger")
@@ -97,12 +97,12 @@
.setColor("Warning")
.send(true)
if (confirmation.success) {
- let data = client.database.read(interaction.guild.id)
+ let data = client.database.guilds.read(interaction.guild.id)
if (channel) data.logging.logs.ignore.channels.concat([channel.id])
if (user) data.logging.logs.ignore.users.concat([user.id])
if (role) data.logging.logs.ignore.roles.concat([role.id])
if (interaction.options.getString("action") == "add") {
- await client.database.append(interaction.guild.id, data)
+ await client.database.guilds.append(interaction.guild.id, data)
}
}
}
diff --git a/src/commands/settings/staff/channel.ts b/src/commands/settings/staff/channel.ts
index 354d7f1..74605cf 100644
--- a/src/commands/settings/staff/channel.ts
+++ b/src/commands/settings/staff/channel.ts
@@ -1,6 +1,6 @@
import { ChannelType } from 'discord-api-types';
import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../../utils/confirmationMessage.js";
import getEmojiByName from "../../../utils/getEmojiByName.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -17,7 +17,7 @@
const callback = async (interaction: CommandInteraction): Promise<any> => {
let m;
- m = await interaction.reply({embeds: [new generateEmojiEmbed()
+ m = await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Loading")
.setStatus("Danger")
.setEmoji("NUCLEUS.LOADING")
@@ -27,7 +27,7 @@
try {
channel = interaction.options.getChannel("channel")
} catch {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.TEXT.DELETE")
.setTitle("Staff Notifications Channel")
.setDescription("The channel you provided is not a valid channel")
@@ -36,7 +36,7 @@
}
channel = channel as Discord.TextChannel
if (channel.guild.id != interaction.guild.id) {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Staff Notifications Channel")
.setDescription(`You must choose a channel in this server`)
.setStatus("Danger")
@@ -55,9 +55,9 @@
.send(true)
if (confirmation.success) {
try {
- await client.database.write(interaction.guild.id, {"logging.staff.channel": channel.id})
+ await client.database.guilds.write(interaction.guild.id, {"logging.staff.channel": channel.id})
} catch (e) {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Staff Notifications Channel")
.setDescription(`Something went wrong and the staff notifications channel could not be set`)
.setStatus("Danger")
@@ -65,7 +65,7 @@
], components: []});
}
} else {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Staff Notifications Channel")
.setDescription(`No changes were made`)
.setStatus("Success")
@@ -74,10 +74,10 @@
}
}
let clicks = 0;
- let data = await client.database.read(interaction.guild.id);
+ let data = await client.database.guilds.read(interaction.guild.id);
let channel = data.logging.staff.channel;
while (true) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Staff Notifications channel")
.setDescription(channel ? `Your staff notifications channel is currently set to <#${channel}>` : "This server does not have a staff notifications channel")
.setStatus("Success")
@@ -98,14 +98,14 @@
clicks += 1;
if (clicks == 2) {
clicks = 0;
- await client.database.write(interaction.guild.id, {}, ["logging.staff.channel"])
+ await client.database.guilds.write(interaction.guild.id, {}, ["logging.staff.channel"])
channel = undefined;
}
} else {
break
}
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Staff Notifications channel")
.setDescription(channel ? `Your staff notifications channel is currently set to <#${channel}>` : "This server does not have a staff notifications channel")
.setStatus("Success")
diff --git a/src/commands/settings/tickets.ts b/src/commands/settings/tickets.ts
index 670a2f2..b505c5c 100644
--- a/src/commands/settings/tickets.ts
+++ b/src/commands/settings/tickets.ts
@@ -1,5 +1,5 @@
import getEmojiByName from "../../utils/getEmojiByName.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import Discord, { CommandInteraction, MessageActionRow, MessageButton, MessageSelectMenu, TextInputComponent } from "discord.js";
import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -22,7 +22,7 @@
const callback = async (interaction: CommandInteraction): Promise<any> => {
let m;
m = await interaction.reply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Loading")
.setStatus("Danger")
.setEmoji("NUCLEUS.LOADING")
@@ -42,7 +42,7 @@
channel = interaction.guild.channels.cache.get(options.category.id)
} catch {
return await interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("CHANNEL.TEXT.DELETE")
.setTitle("Tickets > Category")
.setDescription("The channel you provided is not a valid category")
@@ -52,7 +52,7 @@
}
channel = channel as Discord.CategoryChannel
if (channel.guild.id != interaction.guild.id) return interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets > Category")
.setDescription(`You must choose a category in this server`)
.setStatus("Danger")
@@ -62,7 +62,7 @@
}
if (options.maxtickets) {
if (options.maxtickets < 1) return interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets > Max Tickets")
.setDescription(`You must choose a number greater than 0`)
.setStatus("Danger")
@@ -76,7 +76,7 @@
role = interaction.guild.roles.cache.get(options.supportping.id)
} catch {
return await interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setEmoji("GUILD.ROLE.DELETE")
.setTitle("Tickets > Support Ping")
.setDescription("The role you provided is not a valid role")
@@ -86,7 +86,7 @@
}
role = role as Discord.Role
if (role.guild.id != interaction.guild.id) return interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets > Support Ping")
.setDescription(`You must choose a role in this server`)
.setStatus("Danger")
@@ -116,10 +116,10 @@
if (options.maxtickets) toUpdate["tickets.maxTickets"] = options.maxtickets
if (options.supportping) toUpdate["tickets.supportRole"] = options.supportping.id
try {
- await client.database.write(interaction.guild.id, toUpdate)
+ await client.database.guilds.write(interaction.guild.id, toUpdate)
} catch (e) {
return interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets")
.setDescription(`Something went wrong and the staff notifications channel could not be set`)
.setStatus("Danger")
@@ -129,7 +129,7 @@
}
} else {
return interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets")
.setDescription(`No changes were made`)
.setStatus("Success")
@@ -138,7 +138,7 @@
});
}
}
- let data = await client.database.read(interaction.guild.id);
+ let data = await client.database.guilds.read(interaction.guild.id);
data.tickets.customTypes = data.tickets.customTypes.filter((v, i, a) => a.indexOf(v) === i)
let lastClicked = "";
let embed;
@@ -152,7 +152,7 @@
customTypes: data.tickets.customTypes
}
while (true) {
- embed = new generateEmojiEmbed()
+ embed = new EmojiEmbed()
.setTitle("Tickets")
.setDescription(
`${data.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${data.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`}\n` +
@@ -206,23 +206,23 @@
if (i.component.customId == "clearCategory") {
if (lastClicked == "cat") {
lastClicked = "";
- await client.database.write(interaction.guild.id, {}, ["tickets.category"])
+ await client.database.guilds.write(interaction.guild.id, {}, ["tickets.category"])
data.category = undefined;
} else lastClicked = "cat";
} else if (i.component.customId == "clearMaxTickets") {
if (lastClicked == "max") {
lastClicked = "";
- await client.database.write(interaction.guild.id, {}, ["tickets.maxTickets"])
+ await client.database.guilds.write(interaction.guild.id, {}, ["tickets.maxTickets"])
data.maxTickets = 5;
} else lastClicked = "max";
} else if (i.component.customId == "clearSupportPing") {
if (lastClicked == "sup") {
lastClicked = "";
- await client.database.write(interaction.guild.id, {}, ["tickets.supportRole"])
+ await client.database.guilds.write(interaction.guild.id, {}, ["tickets.supportRole"])
data.supportRole = undefined;
} else lastClicked = "sup";
} else if (i.component.customId == "enabled") {
- await client.database.write(interaction.guild.id, { "tickets.enabled": !data.enabled })
+ await client.database.guilds.write(interaction.guild.id, { "tickets.enabled": !data.enabled })
data.enabled = !data.enabled;
} else if (i.component.customId == "manageTypes") {
data = await manageTypes(interaction, data, m);
@@ -238,7 +238,7 @@
if (data.useCustom) {
let customTypes = data.customTypes;
await interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets > Types")
.setDescription(
"**Custom types enabled**\n\n" +
@@ -299,7 +299,7 @@
.setPlaceholder("Select types to use")
])
await interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets > Types")
.setDescription(
"**Default types enabled**\n\n" +
@@ -331,7 +331,7 @@
if (i.component.customId == "types") {
i.deferUpdate()
let types = toHexInteger(i.values, ticketTypes);
- await client.database.write(interaction.guild.id, { "tickets.types": types })
+ await client.database.guilds.write(interaction.guild.id, { "tickets.types": types })
data.types = types;
} else if (i.component.customId == "removeTypes") {
i.deferUpdate()
@@ -340,7 +340,7 @@
if (customTypes) {
customTypes = customTypes.filter((t) => !types.includes(t));
customTypes = customTypes.length > 0 ? customTypes : null;
- await client.database.write(interaction.guild.id, { "tickets.customTypes": customTypes })
+ await client.database.guilds.write(interaction.guild.id, { "tickets.customTypes": customTypes })
data.customTypes = customTypes;
}
} else if (i.component.customId == "addType") {
@@ -357,7 +357,7 @@
)
))
await interaction.editReply({
- embeds: [new generateEmojiEmbed()
+ embeds: [new EmojiEmbed()
.setTitle("Tickets > Types")
.setDescription("Modal opened. If you can't see it, click back and try again.")
.setStatus("Success")
@@ -369,15 +369,16 @@
.setCustomId("back")
])]
});
- let out
+ let out;
try {
out = await modalInteractionCollector(m, (m) => m.channel.id == interaction.channel.id, (m) => m.customId == "addType")
} catch (e) { continue }
if (out.fields) {
let toAdd = out.fields.getTextInputValue("type");
if (!toAdd) { continue }
+ toAdd = toAdd.substring(0, 80)
try {
- await client.database.append(interaction.guild.id, "tickets.customTypes", toAdd)
+ await client.database.guilds.append(interaction.guild.id, "tickets.customTypes", toAdd)
} catch { continue }
data.customTypes = data.customTypes || [];
if (!data.customTypes.includes(toAdd)) {
@@ -386,11 +387,11 @@
} else { continue }
} else if (i.component.customId == "switchToDefault") {
i.deferUpdate()
- await client.database.write(interaction.guild.id, { "tickets.useCustom": false }, [])
+ await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": false }, [])
data.useCustom = false;
} else if (i.component.customId == "switchToCustom") {
i.deferUpdate()
- await client.database.write(interaction.guild.id, { "tickets.useCustom": true }, [])
+ await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": true }, [])
data.useCustom = true;
} else {
i.deferUpdate()
diff --git a/src/commands/settings/verify/role.ts b/src/commands/settings/verify/role.ts
index 68b4bf9..44406e9 100644
--- a/src/commands/settings/verify/role.ts
+++ b/src/commands/settings/verify/role.ts
@@ -1,5 +1,5 @@
import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../../utils/confirmationMessage.js";
import getEmojiByName from "../../../utils/getEmojiByName.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -14,7 +14,7 @@
const callback = async (interaction: CommandInteraction): Promise<any> => {
let m;
- m = await interaction.reply({embeds: [new generateEmojiEmbed()
+ m = await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Loading")
.setStatus("Danger")
.setEmoji("NUCLEUS.LOADING")
@@ -24,7 +24,7 @@
try {
role = interaction.options.getRole("role")
} catch {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("GUILD.ROLES.DELETE")
.setTitle("Verify Role")
.setDescription("The role you provided is not a valid role")
@@ -33,7 +33,7 @@
}
role = role as Discord.Role
if (role.guild.id != interaction.guild.id) {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify Role")
.setDescription(`You must choose a role in this server`)
.setStatus("Danger")
@@ -49,10 +49,10 @@
.send(true)
if (confirmation.success) {
try {
- await client.database.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
+ await client.database.guilds.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
} catch (e) {
console.log(e)
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify Role")
.setDescription(`Something went wrong while setting the verify role`)
.setStatus("Danger")
@@ -60,7 +60,7 @@
], components: []});
}
} else {
- return interaction.editReply({embeds: [new generateEmojiEmbed()
+ return interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify Role")
.setDescription(`No changes were made`)
.setStatus("Success")
@@ -69,10 +69,10 @@
}
}
let clicks = 0;
- let data = await client.database.read(interaction.guild.id);
+ let data = await client.database.guilds.read(interaction.guild.id);
let role = data.verify.role;
while (true) {
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify Role")
.setDescription(role ? `Your verify role is currently set to <@&${role}>` : `You have not set a verify role`)
.setStatus("Success")
@@ -93,14 +93,14 @@
clicks += 1;
if (clicks == 2) {
clicks = 0;
- await client.database.write(interaction.guild.id, {}, ["verify.role", "verify.enabled"])
+ await client.database.guilds.write(interaction.guild.id, {}, ["verify.role", "verify.enabled"])
role = undefined;
}
} else {
break
}
}
- await interaction.editReply({embeds: [new generateEmojiEmbed()
+ await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Verify Role")
.setDescription(role ? `Your verify role is currently set to <@&${role}}>` : `You have not set a verify role`)
.setStatus("Success")
diff --git a/src/commands/tag.ts b/src/commands/tag.ts
index 80bcbad..a9f0075 100644
--- a/src/commands/tag.ts
+++ b/src/commands/tag.ts
@@ -9,7 +9,6 @@
.setDescription("Get and manage the servers tags")
const callback = (interaction: CommandInteraction) => {
- // try { statsChannelAdd(interaction.client, interaction.member); } catch {} // TODO: REMOVE THIS FOR PRODUCTION
interaction.reply("This command is not yet finished [tag]");
}
diff --git a/src/commands/tags/create.ts b/src/commands/tags/create.ts
index e53f94f..c1ed839 100644
--- a/src/commands/tags/create.ts
+++ b/src/commands/tags/create.ts
@@ -1,7 +1,7 @@
import Discord, { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js";
@@ -16,26 +16,26 @@
const callback = async (interaction: CommandInteraction): Promise<any> => {
let name = interaction.options.getString("name");
let value = interaction.options.getString("value");
- if (name.length > 100) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (name.length > 100) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Create")
.setDescription("Tag names cannot be longer than 100 characters")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], ephemeral: true});
- if (value.length > 1000) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (value.length > 1000) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Create")
.setDescription("Tag values cannot be longer than 1000 characters")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], ephemeral: true});
- let data = await client.database.read(interaction.guild.id);
- if (data.tags.length >= 100) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ let data = await client.database.guilds.read(interaction.guild.id);
+ if (data.tags.length >= 100) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Create")
.setDescription("You cannot have more than 100 tags")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], ephemeral: true});
- if (data.tags[name]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Create")
.setDescription("That tag already exists")
.setStatus("Danger")
@@ -52,23 +52,23 @@
.setColor("Warning")
.setInverted(true)
.send()
- if (!confirmation) return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Create")
.setDescription("No changes were made")
.setStatus("Success")
.setEmoji("PUNISH.NICKNAME.GREEN")
]});
try {
- await client.database.write(interaction.guild.id, {[`tags.${name}`]: value});
+ await client.database.guilds.write(interaction.guild.id, {[`tags.${name}`]: value});
} catch (e) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Create")
.setDescription("Something went wrong and the tag was not created")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], components: []});
}
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Create")
.setDescription("Tag created")
.setStatus("Success")
diff --git a/src/commands/tags/delete.ts b/src/commands/tags/delete.ts
index ff54ee5..f24a5fc 100644
--- a/src/commands/tags/delete.ts
+++ b/src/commands/tags/delete.ts
@@ -1,7 +1,7 @@
import Discord, { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js";
@@ -14,8 +14,8 @@
const callback = async (interaction: CommandInteraction): Promise<any> => {
let name = interaction.options.getString("name");
- let data = await client.database.read(interaction.guild.id);
- if (!data.tags[name]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ let data = await client.database.guilds.read(interaction.guild.id);
+ if (!data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tags")
.setDescription("That tag does not exist")
.setStatus("Danger")
@@ -32,25 +32,25 @@
.setColor("Warning")
.setInverted(true)
.send()
- if (!confirmation) return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Delete")
.setDescription("No changes were made")
.setStatus("Success")
.setEmoji("PUNISH.NICKNAME.GREEN")
]});
try {
- data = await client.database.read(interaction.guild.id);
+ data = await client.database.guilds.read(interaction.guild.id);
delete data.tags[name];
- await client.database.write(interaction.guild.id, {tags: data});
+ await client.database.guilds.write(interaction.guild.id, {tags: data});
} catch (e) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Delete")
.setDescription("Something went wrong and the tag was not deleted")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], components: []});
}
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Delete")
.setDescription("Tag deleted")
.setStatus("Success")
diff --git a/src/commands/tags/edit.ts b/src/commands/tags/edit.ts
index 3cf73e5..b0a4835 100644
--- a/src/commands/tags/edit.ts
+++ b/src/commands/tags/edit.ts
@@ -1,7 +1,7 @@
import Discord, { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import confirmationMessage from "../../utils/confirmationMessage.js";
import keyValueList from "../../utils/generateKeyValueList.js";
import client from "../../utils/client.js";
@@ -18,32 +18,32 @@
let name = interaction.options.getString("name");
let value = interaction.options.getString("value") || "";
let newname = interaction.options.getString("newname") || "";
- if (!newname && !value) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (!newname && !value) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Edit")
.setDescription("You must specify a value or a new name")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], ephemeral: true});
- if (newname.length > 100) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (newname.length > 100) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Edit")
.setDescription("Tag names cannot be longer than 100 characters")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], ephemeral: true});
- if (value.length > 2000) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (value.length > 2000) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Edit")
.setDescription("Tag values cannot be longer than 2000 characters")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], ephemeral: true});
- let data = await client.database.read(interaction.guild.id);
- if (!data.tags[name]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ let data = await client.database.guilds.read(interaction.guild.id);
+ if (!data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Edit")
.setDescription("That tag does not exist")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], ephemeral: true});
- if (newname && newname !== name && data.tags[newname]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+ if (newname && newname !== name && data.tags[newname]) return await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Tag Edit")
.setDescription("A tag with that name already exists")
.setStatus("Danger")
@@ -60,7 +60,7 @@
.setColor("Warning")
.setInverted(true)
.send()
- if (!confirmation) return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Edit")
.setDescription("No changes were made")
.setStatus("Success")
@@ -74,16 +74,16 @@
toUnset.push(`tags.${name}`);
toSet[`tags.${newname}`] = data.tags[name];
}
- await client.database.write(interaction.guild.id, toSet, toUnset);
+ await client.database.guilds.write(interaction.guild.id, toSet, toUnset);
} catch (e) {
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tag Edit")
.setDescription("Something went wrong and the tag was not edited")
.setStatus("Danger")
.setEmoji("PUNISH.NICKNAME.RED")
], components: []});
}
- return await interaction.editReply({embeds: [new generateEmojiEmbed()
+ return await interaction.editReply({embeds: [new EmojiEmbed()
.setTitle("Tags")
.setDescription("Tag edited successfully")
.setStatus("Success")
diff --git a/src/commands/tags/list.ts b/src/commands/tags/list.ts
index 5052a6b..a534791 100644
--- a/src/commands/tags/list.ts
+++ b/src/commands/tags/list.ts
@@ -1,8 +1,7 @@
import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
-import keyValueList from "../../utils/generateKeyValueList.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import client from "../../utils/client.js";
import { SelectMenuOption } from '@discordjs/builders';
import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -25,10 +24,9 @@
.setName("list")
.setDescription("Lists all tags in the server")
-const callback = async (interaction: CommandInteraction) => {
- let data = await client.database.read(interaction.guild.id);
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+ let data = await client.database.guilds.read(interaction.guild.id);
let tags = data.getKey("tags");
- console.log(tags)
let strings = []
if (data === {}) strings = ["*No tags exist*"]
else {
@@ -39,7 +37,6 @@
strings.push(string.slice(0, -1))
string = ""
}
- console.log(string)
string += proposed
}
strings.push(string.slice(0, -1))
@@ -48,7 +45,7 @@
let pages = []
for (let string of strings) {
pages.push(new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("Tags")
.setDescription(string)
.setEmoji("PUNISH.NICKNAME.GREEN")
@@ -58,7 +55,7 @@
let m;
m = await interaction.reply({
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setTitle("Welcome")
.setDescription(`One moment...`)
.setStatus("Danger")
@@ -128,7 +125,7 @@
return;
}
}
- let em = new Discord.MessageEmbed(pages[page])
+ let em = new Discord.MessageEmbed(pages[page].embed)
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out");
await interaction.editReply({
embeds: [em],
diff --git a/src/commands/ticket/close.ts b/src/commands/ticket/close.ts
index 237623d..15abb0a 100644
--- a/src/commands/ticket/close.ts
+++ b/src/commands/ticket/close.ts
@@ -8,7 +8,7 @@
.setName("close")
.setDescription("Closes a ticket")
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
await close(interaction);
}
diff --git a/src/commands/ticket/create.ts b/src/commands/ticket/create.ts
index 6567c49..c44e576 100644
--- a/src/commands/ticket/create.ts
+++ b/src/commands/ticket/create.ts
@@ -9,7 +9,7 @@
.setDescription("Creates a new modmail ticket")
.addStringOption(option => option.setName("message").setDescription("The content of the ticket").setRequired(false))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
await create(interaction)
}
diff --git a/src/commands/user/about.ts b/src/commands/user/about.ts
index 0c7a3eb..8557d15 100644
--- a/src/commands/user/about.ts
+++ b/src/commands/user/about.ts
@@ -1,7 +1,7 @@
import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import generateKeyValueList from "../../utils/generateKeyValueList.js";
import createPageIndicator from "../../utils/createPageIndicator.js";
@@ -26,7 +26,7 @@
}
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
const { renderUser, renderDelta } = client.logger
let member = (interaction.options.getMember("user") || interaction.member) as Discord.GuildMember;
let flags: string[] = [];
@@ -105,7 +105,7 @@
let embeds = [
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("User Info: General")
.setStatus("Success")
.setEmoji("MEMBER.JOIN")
@@ -129,7 +129,7 @@
.setImage((await member.user.fetch()).bannerURL({format: "gif"}))
).setTitle("General").setDescription("General information about the user").setPageId(0),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("User Info: Roles")
.setStatus("Success")
.setEmoji("GUILD.ROLES.CREATE")
@@ -144,7 +144,7 @@
.setThumbnail(await member.user.displayAvatarURL({dynamic: true}))
).setTitle("Roles").setDescription("Roles the user has").setPageId(1),
new Embed()
- .setEmbed(new generateEmojiEmbed()
+ .setEmbed(new EmojiEmbed()
.setTitle("User Info: Key Permissions")
.setStatus("Success")
.setEmoji("GUILD.ROLES.CREATE")
@@ -158,7 +158,7 @@
).setTitle("Key Permissions").setDescription("Key permissions the user has").setPageId(2),
]
let m
- m = await interaction.reply({embeds: [new generateEmojiEmbed().setTitle("Loading").setEmoji("NUCLEUS.LOADING").setStatus("Danger")], fetchReply: true, ephemeral: true});
+ m = await interaction.reply({embeds: [new EmojiEmbed().setTitle("Loading").setEmoji("NUCLEUS.LOADING").setStatus("Danger")], fetchReply: true, ephemeral: true});
let page = 0
let breakReason = ""
while (true) {
diff --git a/src/commands/user/avatar.ts b/src/commands/user/avatar.ts
index 9a84118..e72506f 100644
--- a/src/commands/user/avatar.ts
+++ b/src/commands/user/avatar.ts
@@ -1,10 +1,10 @@
import Discord, { CommandInteraction } from "discord.js";
import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import generateKeyValueList from "../../utils/generateKeyValueList.js";
-import client from "../../client.js"
+import client from "../../utils/client.js"
const command = (builder: SlashCommandSubcommandBuilder) =>
builder
@@ -12,10 +12,10 @@
.setDescription("Shows the avatar of a user")
.addUserOption(option => option.setName("user").setDescription("The user to get the avatar of | Default: Yourself"))
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
const { renderUser } = client.logger
let member = (interaction.options.getMember("user") || interaction.member) as Discord.GuildMember;
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("User Info")
.setStatus("Success")
.setEmoji("MEMBER.JOIN")
diff --git a/src/commands/user/track.ts b/src/commands/user/track.ts
index 0e6fafd..da332da 100644
--- a/src/commands/user/track.ts
+++ b/src/commands/user/track.ts
@@ -1,7 +1,7 @@
import Discord, { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton } from "discord.js";
import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
import getEmojiByName from "../../utils/getEmojiByName.js";
import addPlural from "../../utils/plurals.js";
import client from "../../utils/client.js";
@@ -21,12 +21,12 @@
return "TRACKS.VERTICAL.MIDDLE." + disabled + active
}
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
const { renderUser } = client.logger;
const member = interaction.options.getMember("user") as GuildMember;
const guild = interaction.guild;
- let config = await client.database.read(guild.id);
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ let config = await client.database.guilds.read(guild.id);
+ await interaction.reply({embeds: [new EmojiEmbed()
.setEmoji("NUCLEUS.LOADING")
.setTitle("Loading")
.setStatus("Danger")
@@ -35,9 +35,11 @@
let generated;
const roles = await guild.roles.fetch()
let memberRoles = await member.roles
+ let managed
while (true) {
let data = config.tracks[track]
- let managed = data.manageableBy.some(element => {return memberRoles.cache.has(element)})
+ if (data.manageableBy !== undefined) managed = data.manageableBy.some(element => {return memberRoles.cache.has(element)})
+ else managed = false
let dropdown = new Discord.MessageSelectMenu().addOptions(config.tracks.map((option, index) => {
let hasRoleInTrack = option.track.some(element => {return memberRoles.cache.has(element)})
return new SelectMenuOption({
@@ -94,7 +96,7 @@
} else {
currentRoleIndex = selected.length == 0 ? -1 : data.track.indexOf(selected[0].toString())
}
- let m = await interaction.editReply({embeds: [new generateEmojiEmbed()
+ let m = await interaction.editReply({embeds: [new EmojiEmbed()
.setEmoji("TRACKS.ICON")
.setTitle("Tracks")
.setDescription(`${generated}`)
@@ -160,16 +162,19 @@
}
const check = async (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+ let tracks = (await client.database.guilds.read(interaction.guild.id)).tracks
+ if (!tracks) throw "This server does not have any tracks"
let member = (interaction.member as GuildMember)
// Allow the owner to promote anyone
if (member.id == interaction.guild.ownerId) return true
// Check if the user can manage any of the tracks
- // @ts-ignore
- let tracks = (await client.database.get(interaction.guild.id)).tracks
let managed = false
- tracks.forEach(element => { if (element.track.manageableBy.some(role => member.roles.cache.has(role))) managed = true });
+ tracks.forEach(element => {
+ if (!element.track.manageableBy) return
+ if (element.track.manageableBy.some(role => member.roles.cache.has(role))) managed = true
+ });
// Check if the user has manage_roles permission
- if (!managed && ! member.permissions.has("MANAGE_ROLES")) throw "You do not have the `manage_roles` permission";
+ if (!managed && ! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
// Allow track
return true;
}
diff --git a/src/commands/verify.ts b/src/commands/verify.ts
index c9abb77..4ccc807 100644
--- a/src/commands/verify.ts
+++ b/src/commands/verify.ts
@@ -7,7 +7,7 @@
.setName("verify")
.setDescription("Get verified in the server")
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
verify(interaction);
}
diff --git a/src/config/emojis.json b/src/config/emojis.json
index 7fba0e5..b91cdbf 100644
--- a/src/config/emojis.json
+++ b/src/config/emojis.json
@@ -17,16 +17,25 @@
"ICONS": {
"ADD": "826823514904330251",
"REMOVE": "826823515268186152",
+ "EDIT": "989911820267577366",
+ "HISTORY": "989911933069168690",
+ "FILTER": "990242059451514902",
"OPP": {
"ADD": "837355918831124500",
"REMOVE": "837355918420869162"
},
"CHANNEL": {
- "GUILD_TEXT": "752971441351426089",
- "GUILD_VOICE": "752971441586307091",
+ "GUILD_TEXT": "990209996182679632",
+ "GUILD_TEXT_NSFW": "990216363526221824",
+ "GUILD_VOICE": "990213162697637969",
+ "GUILD_VOICE_NSFW": "990216017244463124",
"GUILD_STORE": "853668786925469706",
"GUILD_NEWS": "853668786493063169",
- "GUILD_STAGE": "853668786842763294"
+ "GUILD_NEWS_NSFW": "990216028300673094",
+ "GUILD_STAGE_VOICE": "853668786842763294",
+ "THREAD_CHANNEL": "990210005108158514",
+ "THREAD_PIPE": "990213168183779348",
+ "RULES": "990213153080115250"
}
},
"CONTROL": {
@@ -81,7 +90,7 @@
"SLOWMODE": {
"ON": "777138171301068831",
"OFF": "777138171447869480",
- "//TODO": "// TODO"
+ "// TODO": "Make these green and red respectively"
},
"NSFW": {
"ON": "729064531208175736",
diff --git a/src/events/channelCreate.ts b/src/events/channelCreate.ts
index ec788f7..3bde0f2 100644
--- a/src/events/channelCreate.ts
+++ b/src/events/channelCreate.ts
@@ -66,6 +66,6 @@
guild: channel.guild.id
}
}
- log(data, channel.client);
+ log(data);
} catch {}
}
diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts
index e8c888a..2188141 100644
--- a/src/events/channelDelete.ts
+++ b/src/events/channelDelete.ts
@@ -68,6 +68,6 @@
guild: channel.guild.id
}
}
- log(data, channel.client);
+ log(data);
} catch {}
}
diff --git a/src/events/channelUpdate.ts b/src/events/channelUpdate.ts
index 25b7375..560ca11 100644
--- a/src/events/channelUpdate.ts
+++ b/src/events/channelUpdate.ts
@@ -130,6 +130,6 @@
guild: nc.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
\ No newline at end of file
diff --git a/src/events/commandError.ts b/src/events/commandError.ts
index ba47426..8edb480 100644
--- a/src/events/commandError.ts
+++ b/src/events/commandError.ts
@@ -1,17 +1,17 @@
-import generateEmojiEmbed from "../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
export const event = 'commandError'
export async function callback(client, interaction, error) {
if (interaction.replied || interaction.deferred) {
- await interaction.followUp({embeds: [new generateEmojiEmbed()
+ await interaction.followUp({embeds: [new EmojiEmbed()
.setTitle("Something went wrong")
.setDescription(error.message ?? error.toString())
.setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS")
], ephemeral: true})
} else {
- await interaction.reply({embeds: [new generateEmojiEmbed()
+ await interaction.reply({embeds: [new EmojiEmbed()
.setTitle("Something went wrong")
.setDescription(error.message ?? error.toString())
.setStatus("Danger")
diff --git a/src/events/emojiCreate.ts b/src/events/emojiCreate.ts
index c1ed3c5..1048869 100644
--- a/src/events/emojiCreate.ts
+++ b/src/events/emojiCreate.ts
@@ -25,6 +25,6 @@
guild: emoji.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
diff --git a/src/events/emojiDelete.ts b/src/events/emojiDelete.ts
index 59bed1e..02bec0d 100644
--- a/src/events/emojiDelete.ts
+++ b/src/events/emojiDelete.ts
@@ -26,6 +26,6 @@
guild: emoji.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
diff --git a/src/events/emojiUpdate.ts b/src/events/emojiUpdate.ts
index 2171b18..eb39cb9 100644
--- a/src/events/emojiUpdate.ts
+++ b/src/events/emojiUpdate.ts
@@ -32,6 +32,6 @@
guild: ne.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
\ No newline at end of file
diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts
index 4209788..a1848fd 100644
--- a/src/events/guildBanAdd.ts
+++ b/src/events/guildBanAdd.ts
@@ -11,7 +11,7 @@
let auditLog = await getAuditLog(ban.guild, 'MEMBER_BAN_ADD')
let audit = auditLog.entries.filter(entry => entry.target.id == ban.user.id).first();
if (audit.executor.id == client.user.id) return
- console.log(ban.reason)
+ try { await client.database.history.create("ban", ban.guild.id, ban.user, audit.executor, audit.reason) } catch {}
let data = {
meta: {
type: 'memberBan',
@@ -34,6 +34,6 @@
guild: ban.guild.id
}
}
- log(data, ban.user.client);
+ log(data);
} catch {}
}
diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts
index 11661f7..59fbf7a 100644
--- a/src/events/guildBanRemove.ts
+++ b/src/events/guildBanRemove.ts
@@ -12,6 +12,7 @@
let auditLog = await getAuditLog(ban.guild, 'MEMBER_BAN_REMOVE')
let audit = auditLog.entries.filter(entry => entry.target.id == ban.user.id).first();
if (audit.executor.id == client.user.id) return
+ try { await client.database.history.create("unban", ban.guild.id, ban.user, audit.executor, audit.reason) } catch {}
let data = {
meta: {
type: 'memberUnban',
@@ -32,6 +33,6 @@
guild: ban.guild.id
}
}
- log(data, ban.user.client);
+ log(data);
} catch (e) {console.log(e)}
}
diff --git a/src/events/guildCreate.ts b/src/events/guildCreate.ts
index 0222c7c..10986a5 100644
--- a/src/events/guildCreate.ts
+++ b/src/events/guildCreate.ts
@@ -1,5 +1,5 @@
import { MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import guide from "../automations/guide.js";
diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts
index a1601bb..2175aaf 100644
--- a/src/events/guildMemberUpdate.ts
+++ b/src/events/guildMemberUpdate.ts
@@ -10,6 +10,9 @@
let auditLog = await getAuditLog(after.guild, 'MEMBER_UPDATE');
let audit = auditLog.entries.filter(entry => entry.target.id == after.id).first();
if (audit.executor.id == client.user.id) return;
+ try { await client.database.history.create(
+ "nickname", after.guild.id, after.user, audit.executor,
+ null, before.nickname || before.user.username, after.nickname || after.user.username) } catch {}
let data = {
meta: {
type: 'memberUpdate',
@@ -30,7 +33,7 @@
guild: after.guild.id
}
}
- log(data, after.client);
+ log(data);
}
} catch (e) { console.log(e) }
}
diff --git a/src/events/guildUpdate.ts b/src/events/guildUpdate.ts
index 400cfe4..ee02b66 100644
--- a/src/events/guildUpdate.ts
+++ b/src/events/guildUpdate.ts
@@ -53,6 +53,6 @@
guild: after.id
}
}
- log(data, after.client);
+ log(data);
} catch (e) {}
}
diff --git a/src/events/inviteCreate.ts b/src/events/inviteCreate.ts
index bdfeede..5081dd1 100644
--- a/src/events/inviteCreate.ts
+++ b/src/events/inviteCreate.ts
@@ -27,6 +27,6 @@
guild: invite.guild.id
}
}
- log(data, invite.client);
+ log(data);
} catch {}
}
diff --git a/src/events/inviteDelete.ts b/src/events/inviteDelete.ts
index dec234f..b6ddd22 100644
--- a/src/events/inviteDelete.ts
+++ b/src/events/inviteDelete.ts
@@ -27,6 +27,6 @@
guild: invite.guild.id
}
}
- log(data, invite.client);
+ log(data);
} catch {}
}
diff --git a/src/events/memberJoin.ts b/src/events/memberJoin.ts
index 317cc3a..f3c4d18 100644
--- a/src/events/memberJoin.ts
+++ b/src/events/memberJoin.ts
@@ -1,6 +1,8 @@
import { callback as statsChannelAdd } from '../automations/statsChannelAdd.js';
import { callback as welcome } from '../automations/welcome.js';
import log from '../utils/log.js';
+import client from '../utils/client.js';
+
export const event = 'guildMemberAdd'
export async function callback(_, member) {
@@ -8,6 +10,7 @@
try { statsChannelAdd(_, member); } catch {}
try {
const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
+ try { await client.database.history.create("join", member.guild.id, member.user, null, null) } catch {}
let data = {
meta: {
type: 'memberJoin',
@@ -28,6 +31,6 @@
guild: member.guild.id
}
}
- log(data, member.client);
+ log(data);
} catch {}
}
diff --git a/src/events/memberLeave.ts b/src/events/memberLeave.ts
index 22b7cd3..50901dc 100644
--- a/src/events/memberLeave.ts
+++ b/src/events/memberLeave.ts
@@ -19,6 +19,7 @@
}
let data
if (type == "kick") {
+ try { await client.database.history.create("kick", member.guild.id, member.user, audit.executor, audit.reason) } catch {}
data = {
meta: {
type: 'memberKick',
@@ -44,6 +45,7 @@
}
}
} else {
+ try { await client.database.history.create("leave", member.guild.id, member.user, null, null) } catch {}
data = {
meta: {
type: 'memberLeave',
@@ -67,6 +69,6 @@
}
}
}
- log(data, member.client);
+ log(data);
} catch {}
}
diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts
index f0f5e00..229b126 100644
--- a/src/events/messageDelete.ts
+++ b/src/events/messageDelete.ts
@@ -40,6 +40,6 @@
guild: message.channel.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts
index ec713a2..0d42fb9 100644
--- a/src/events/messageEdit.ts
+++ b/src/events/messageEdit.ts
@@ -41,6 +41,6 @@
guild: newMessage.channel.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
diff --git a/src/events/roleCreate.ts b/src/events/roleCreate.ts
index 2664790..61d0a87 100644
--- a/src/events/roleCreate.ts
+++ b/src/events/roleCreate.ts
@@ -26,6 +26,6 @@
guild: role.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
diff --git a/src/events/roleDelete.ts b/src/events/roleDelete.ts
index 6edfeed..b0cb0f7 100644
--- a/src/events/roleDelete.ts
+++ b/src/events/roleDelete.ts
@@ -33,6 +33,6 @@
guild: role.guild.id
}
}
- log(data, client);
+ log(data);
} catch {}
}
diff --git a/src/events/roleUpdate.ts b/src/events/roleUpdate.ts
index faf3237..982d915 100644
--- a/src/events/roleUpdate.ts
+++ b/src/events/roleUpdate.ts
@@ -41,7 +41,7 @@
hidden: {
guild: nr.guild.id
}
- }
- log(data, client);
+ } // TODO: show perms changed
+ log(data);
} catch {}
}
\ No newline at end of file
diff --git a/src/events/threadCreate.ts b/src/events/threadCreate.ts
index 77e9dea..5c65d78 100644
--- a/src/events/threadCreate.ts
+++ b/src/events/threadCreate.ts
@@ -29,6 +29,6 @@
guild: thread.guild.id
}
}
- log(data, thread.client);
+ log(data);
} catch {}
}
diff --git a/src/events/threadDelete.ts b/src/events/threadDelete.ts
index 7bf8537..9507469 100644
--- a/src/events/threadDelete.ts
+++ b/src/events/threadDelete.ts
@@ -31,6 +31,6 @@
guild: thread.guild.id
}
}
- log(data, thread.client);
+ log(data);
} catch {}
}
diff --git a/src/events/threadUpdate.ts b/src/events/threadUpdate.ts
index 4067eba..f554a6c 100644
--- a/src/events/threadUpdate.ts
+++ b/src/events/threadUpdate.ts
@@ -38,6 +38,6 @@
guild: after.guild.id
}
}
- log(data, after.client);
+ log(data);
} catch {}
}
diff --git a/src/index.ts b/src/index.ts
index ca14cdb..35afc14 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,10 +1,10 @@
-import config from './config/main.json' assert {type: 'json'};
import { Logger } from './utils/log.js';
import runServer from './api/index.js';
import Memory from './utils/memory.js';
-import Database from './utils/database.js';
+import { Guilds, History, ModNotes, EventSchedulerDatabase } from './utils/database.js';
import client from './utils/client.js';
+import EventScheduler from './utils/eventScheduler.js';
await client.registerCommandsIn("./commands");
await client.registerEventsIn("./events");
@@ -16,6 +16,11 @@
client.verify = {}
client.roleMenu = {}
client.memory = new Memory()
-client.database = await new Database(config.mongoUrl).connect()
+client.database = {
+ guilds: await new Guilds().setup(),
+ history: await new History().setup(),
+ notes: await new ModNotes().setup(),
+ eventScheduler: new EventSchedulerDatabase()
+}
await client.login();
\ No newline at end of file
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index dbcd52f..7eaa369 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -1,5 +1,5 @@
import Discord, { CommandInteraction, MessageActionRow, Message } from "discord.js";
-import generateEmojiEmbed from "./generateEmojiEmbed.js"
+import EmojiEmbed from "./generateEmojiEmbed.js"
import getEmojiByName from "./getEmojiByName.js";
class confirmationMessage {
@@ -58,7 +58,7 @@
while (true) {
let object = {
embeds: [
- new generateEmojiEmbed()
+ new EmojiEmbed()
.setEmoji(this.emoji)
.setTitle(this.title)
.setDescription(this.description)
diff --git a/src/utils/database.ts b/src/utils/database.ts
index 4e37652..66d7e67 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -1,5 +1,12 @@
-import { Collection, Db, MongoClient } from 'mongodb';
+import Discord from 'discord.js';
+import { Collection, MongoClient } from 'mongodb';
import structuredClone from '@ungap/structured-clone';
+import config from '../config/main.json' assert {type: 'json'};
+
+
+const mongoClient = new MongoClient(config.mongoUrl);
+await mongoClient.connect()
+const database = mongoClient.db("Nucleus");
export const Entry = data => {
@@ -19,21 +26,11 @@
}
-export default class Database {
- mongoClient: MongoClient;
- database: Db;
+export class Guilds {
guilds: Collection<GuildConfig>;
defaultData: GuildConfig;
-
- constructor(url) {
- this.mongoClient = new MongoClient(url);
- }
-
- async connect() {
- await this.mongoClient.connect()
- this.database = this.mongoClient.db("Nucleus");
- this.guilds = this.database.collection<GuildConfig>("guilds");
- await this.guilds.createIndex({ id: "text" }, { unique: true });
+ async setup() {
+ this.guilds = database.collection<GuildConfig>("guilds");
this.defaultData = (await import("../config/default.json", { assert: { type: "json" }})).default as unknown as GuildConfig;
return this;
}
@@ -79,6 +76,85 @@
}
}
+
+export class History {
+ histories: Collection<HistorySchema>;
+ defaultData: GuildConfig;
+
+ async setup() {
+ this.histories = database.collection<HistorySchema>("history");
+ return this;
+ }
+
+ async create(type: string, guild: string, user: Discord.User, moderator: Discord.User | null, reason: string | null, before?: null, after?: null, amount?: null) {
+ await this.histories.insertOne({
+ type: type,
+ guild: guild,
+ user: user.id,
+ moderator: moderator.id,
+ reason: reason,
+ occurredAt: new Date(),
+ before: before,
+ after: after,
+ amount: amount
+ });
+ }
+
+ async read(guild: string, user: string, year: number) {
+ let entry = (await this.histories.find({
+ guild: guild,
+ user: user,
+ occurredAt: {
+ $gte: new Date(year - 1, 11, 31, 23, 59, 59),
+ $lt: new Date(year + 1, 0, 1, 0, 0, 0)
+ }
+ }).toArray()) as HistorySchema[];
+ return entry;
+ }
+}
+
+export class ModNotes {
+ modNotes: Collection<ModNoteSchema>;
+ defaultData: GuildConfig;
+
+ async setup() {
+ this.modNotes = database.collection<ModNoteSchema>("modNotes");
+ return this;
+ }
+
+ async create(guild: string, user: string, note: string | null) {
+ await this.modNotes.updateOne({ guild: guild, user: user }, { $set: { note: note }}, { upsert: true });
+ }
+
+ async read(guild: string, user: string) {
+ let entry = await this.modNotes.findOne({ guild: guild, user: user });
+ return entry?.note ?? null;
+ }
+}
+
+export class EventSchedulerDatabase {
+ events: Collection<EventSchedulerSchema>;
+ defaultData: GuildConfig;
+
+ async setup() {
+ this.events = database.collection<EventSchedulerSchema>("eventScheduler");
+ return this;
+ }
+
+ async create(timestamp: Date, data: object) {
+ await this.events.insertOne({ timestamp: timestamp, data: data});
+ }
+
+ async getNext() {
+ let entry = await this.events.findOne({ timestamp: { $lte: new Date() }});
+ return entry;
+ }
+
+ async remove(timestamp: Date, data: object) {
+ await this.events.deleteOne({ timestamp: timestamp, data: data});
+ }
+}
+
export interface GuildConfig {
id: string,
version: number,
@@ -205,10 +281,33 @@
max: number,
options: {
name: string,
- description: string,
+ description: string | null,
role: string
}[]
}[]
}
tags: {}
-};
\ No newline at end of file
+};
+
+export interface HistorySchema {
+ type: string,
+ guild: string,
+ user: string,
+ moderator: string | null,
+ reason: string,
+ occurredAt: Date,
+ before: string | null,
+ after: string | null,
+ amount: string | null
+}
+
+export interface ModNoteSchema {
+ guild: string,
+ user: string,
+ note: string
+}
+
+export interface EventSchedulerSchema {
+ timestamp: Date,
+ data: object
+}
\ No newline at end of file
diff --git a/src/utils/dualCollector.ts b/src/utils/dualCollector.ts
index 902822a..67cef5c 100644
--- a/src/utils/dualCollector.ts
+++ b/src/utils/dualCollector.ts
@@ -1,6 +1,6 @@
import Discord from 'discord.js';
import client from './client.js';
-import generateEmojiEmbed from "./generateEmojiEmbed.js";
+import EmojiEmbed from "./generateEmojiEmbed.js";
export default async function (m, interactionFilter, messageFilter) {
let out;
diff --git a/src/utils/eventScheduler.ts b/src/utils/eventScheduler.ts
new file mode 100644
index 0000000..9210883
--- /dev/null
+++ b/src/utils/eventScheduler.ts
@@ -0,0 +1,37 @@
+import { EventSchedulerDatabase } from './database';
+import client from './client.js';
+
+class EventScheduler {
+ database: any;
+ next: {timestamp: Date, data: object, responded: boolean} | {};
+
+ constructor() {
+ this.database = EventSchedulerDatabase;
+ this.next = {};
+ }
+
+ async create(timestamp: Date, data: object) {
+ await this.database.create(timestamp, data);
+ if (this.next === {}) {
+ this.next = this.next = await this.getNext();
+ return
+ }
+ if (timestamp.getTime() < (this.next as {timestamp: Date}).timestamp.getTime()) {
+ this.next = {timestamp: timestamp, data: data, responded: false};
+ }
+ }
+
+ async getNext() {
+ let entry = await this.database.getNext();
+ if (entry) {
+ this.next = entry;
+ }
+ return this.next;
+ }
+
+ async delete(timestamp: Date, data: object) {
+ await this.database.delete(timestamp, data);
+ } // TODO: add a loop
+}
+
+export default EventScheduler;
\ No newline at end of file
diff --git a/src/utils/log.ts b/src/utils/log.ts
index 19eb2b6..55f8f4c 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -53,7 +53,7 @@
}
async log(log: any): Promise<void> {
- let config = await client.database.read(log.hidden.guild);
+ let config = await client.database.guilds.read(log.hidden.guild);
if (!config.logging.logs.enabled) return;
if (!(log.meta.calculateType == true)) {
if(!toHexArray(config.logging.logs.toLog).includes(log.meta.calculateType)) return console.log('Not logging this type of event');
diff --git a/src/utils/memory.ts b/src/utils/memory.ts
index 7e21fa9..a06705b 100644
--- a/src/utils/memory.ts
+++ b/src/utils/memory.ts
@@ -16,7 +16,7 @@
async readGuildInfo(guild: string): Promise<object> {
if (!this.memory[guild]) {
- let guildData = await client.database.read(guild);
+ let guildData = await client.database.guilds.read(guild);
this.memory[guild] = {
lastUpdated: Date.now(),
filters: guildData.filters,
diff --git a/src/utils/singleNotify.ts b/src/utils/singleNotify.ts
index a983478..051ec4d 100644
--- a/src/utils/singleNotify.ts
+++ b/src/utils/singleNotify.ts
@@ -1,5 +1,5 @@
import client from './client.js';
-import generateEmojiEmbed from "./generateEmojiEmbed.js";
+import EmojiEmbed from "./generateEmojiEmbed.js";
let severities = {
"Critical": "Danger",
@@ -8,14 +8,14 @@
}
export default async function(type: string, guild: string, message: string, severity: string) {
- let data = await client.database.read(guild);
+ let data = await client.database.guilds.read(guild);
if (data.singleEventNotifications[type]) return;
data.singleEventNotifications[type] = true;
- client.database.write(guild, data);
+ client.database.guilds.write(guild, data);
try {
let channel = await client.channels.fetch(data.logging.staff.channel);
if (!channel) return;
- await channel.send({embeds: [new generateEmojiEmbed()
+ await channel.send({embeds: [new EmojiEmbed()
.setTitle(`${severity} notification`)
.setDescription(message)
.setStatus(severities[severity])