diff options
35 files changed, 855 insertions, 6517 deletions
diff --git a/util/.vscode/launch.json b/util/.vscode/launch.json index 0de6e587..524622d1 100644 --- a/util/.vscode/launch.json +++ b/util/.vscode/launch.json @@ -18,6 +18,7 @@ "type": "node", "request": "launch", "runtimeArgs": ["--inspect-brk", "${workspaceRoot}/node_modules/jest/bin/jest.js", "--runInBand"], + "preLaunchTask": "tsc: build - tsconfig.json", "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "port": 9229 diff --git a/util/package-lock.json b/util/package-lock.json index f30fcf47..bb04d0bc 100644 --- a/util/package-lock.json +++ b/util/package-lock.json @@ -16,10 +16,11 @@ "dot-prop": "^6.0.1", "env-paths": "^2.2.1", "jsonwebtoken": "^8.5.1", - "lambert-server": "^1.2.8", - "missing-native-js-functions": "^1.2.10", + "lambert-server": "^1.2.10", + "missing-native-js-functions": "^1.2.11", "node-fetch": "^2.6.1", "patch-package": "^6.4.7", + "pg": "^8.7.1", "reflect-metadata": "^0.1.13", "sqlite3": "^5.0.2", "typeorm": "^0.2.37", @@ -1765,6 +1766,14 @@ "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, "node_modules/bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -6098,16 +6107,16 @@ } }, "node_modules/lambert-server": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.2.8.tgz", - "integrity": "sha512-vi/Ku/QudY+WIdGO9bc0qLfVhfuJFWXk1+etesPW1vW29sPbmevLL6IwfvCtw+/MyzRAJLOyCBfQ310a68+2QQ==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.2.10.tgz", + "integrity": "sha512-BHGPmpUrRklFJHPu0vAA8NBewtEd4IX80FRpV4nX9z8kHTUYHqnYHoBeUEWoUmxAeFQvQae1Axk5RQXRQk4VNw==", "dependencies": { "body-parser": "^1.19.0", "chalk": "^4.1.1", "express": "^4.17.1", "express-async-errors": "^3.1.1", "helmet": "^4.4.1", - "missing-native-js-functions": "^1.1.8" + "missing-native-js-functions": "^1.2.11" } }, "node_modules/leven": { @@ -6329,9 +6338,9 @@ } }, "node_modules/missing-native-js-functions": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.10.tgz", - "integrity": "sha512-sq+oAw/C3OtUyKopLNOf/+U85YNx7db6fy5nVfGVKlGdcV8tX24GjOSkcZeCAnAIjMEnlQBWTr17JXa3OJj22g==" + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.11.tgz", + "integrity": "sha512-U97IscNBL4Wg9adYjEBT46Hb0Ld5dPT8vbdwFX+TNzGrFQCc4WqoGAZouaLNFwUqxzzHZ9DVg59unwnQyeIIQg==" }, "node_modules/mkdirp": { "version": "1.0.4", @@ -6916,6 +6925,11 @@ "node": ">=6" } }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, "node_modules/parent-require": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", @@ -7065,6 +7079,80 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "optional": true }, + "node_modules/pg": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz", + "integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.4.1", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "pg-native": ">=2.0.0" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz", + "integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", + "dependencies": { + "split2": "^3.1.1" + } + }, "node_modules/picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -7088,6 +7176,41 @@ "node": ">= 6" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -7604,6 +7727,35 @@ "memory-pager": "^1.0.2" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/split2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/split2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -8492,6 +8644,14 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -10030,6 +10190,11 @@ "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -13373,16 +13538,16 @@ "dev": true }, "lambert-server": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.2.8.tgz", - "integrity": "sha512-vi/Ku/QudY+WIdGO9bc0qLfVhfuJFWXk1+etesPW1vW29sPbmevLL6IwfvCtw+/MyzRAJLOyCBfQ310a68+2QQ==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/lambert-server/-/lambert-server-1.2.10.tgz", + "integrity": "sha512-BHGPmpUrRklFJHPu0vAA8NBewtEd4IX80FRpV4nX9z8kHTUYHqnYHoBeUEWoUmxAeFQvQae1Axk5RQXRQk4VNw==", "requires": { "body-parser": "^1.19.0", "chalk": "^4.1.1", "express": "^4.17.1", "express-async-errors": "^3.1.1", "helmet": "^4.4.1", - "missing-native-js-functions": "^1.1.8" + "missing-native-js-functions": "^1.2.11" } }, "leven": { @@ -13570,9 +13735,9 @@ } }, "missing-native-js-functions": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.10.tgz", - "integrity": "sha512-sq+oAw/C3OtUyKopLNOf/+U85YNx7db6fy5nVfGVKlGdcV8tX24GjOSkcZeCAnAIjMEnlQBWTr17JXa3OJj22g==" + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.11.tgz", + "integrity": "sha512-U97IscNBL4Wg9adYjEBT46Hb0Ld5dPT8vbdwFX+TNzGrFQCc4WqoGAZouaLNFwUqxzzHZ9DVg59unwnQyeIIQg==" }, "mkdirp": { "version": "1.0.4", @@ -14013,6 +14178,11 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, "parent-require": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", @@ -14136,6 +14306,61 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "optional": true }, + "pg": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz", + "integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.5.0", + "pg-pool": "^3.4.1", + "pg-protocol": "^1.5.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + } + }, + "pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz", + "integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ==", + "requires": {} + }, + "pg-protocol": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", + "integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", + "requires": { + "split2": "^3.1.1" + } + }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -14150,6 +14375,29 @@ "node-modules-regexp": "^1.0.0" } }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -14564,6 +14812,34 @@ "memory-pager": "^1.0.2" } }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -15187,6 +15463,11 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/util/package.json b/util/package.json index fc474d68..af14a521 100644 --- a/util/package.json +++ b/util/package.json @@ -9,8 +9,7 @@ "patch": "patch-package", "test": "npm run build && jest", "postinstall": "npm run patch && npm run build", - "build": "npx tsc -b .", - "generate:schema": "npx typescript-json-schema tsconfig.json '*' -o src/entities/schema.json" + "build": "npx tsc -b ." }, "repository": { "type": "git", @@ -44,10 +43,11 @@ "dot-prop": "^6.0.1", "env-paths": "^2.2.1", "jsonwebtoken": "^8.5.1", - "lambert-server": "^1.2.8", - "missing-native-js-functions": "^1.2.10", + "lambert-server": "^1.2.10", + "missing-native-js-functions": "^1.2.11", "node-fetch": "^2.6.1", "patch-package": "^6.4.7", + "pg": "^8.7.1", "reflect-metadata": "^0.1.13", "sqlite3": "^5.0.2", "typeorm": "^0.2.37", diff --git a/util/src/entities/Application.ts b/util/src/entities/Application.ts index 90d0f056..a87b5cea 100644 --- a/util/src/entities/Application.ts +++ b/util/src/entities/Application.ts @@ -8,13 +8,13 @@ export class Application extends BaseClass { @Column() name: string; - @Column() + @Column({ nullable: true }) icon?: string; @Column() description: string; - @Column("simple-array") + @Column({ type: "simple-array", nullable: true }) rpc_origins?: string[]; @Column() @@ -23,16 +23,16 @@ export class Application extends BaseClass { @Column() bot_require_code_grant: boolean; - @Column() + @Column({ nullable: true }) terms_of_service_url?: string; - @Column() + @Column({ nullable: true }) privacy_policy_url?: string; @Column() owner_id: string; - @Column() + @Column({ nullable: true }) summary?: string; @Column() @@ -52,13 +52,13 @@ export class Application extends BaseClass { @ManyToOne(() => Guild, (guild: Guild) => guild.id) guild: Guild; // if this application is a game sold, this field will be the guild to which it has been linked - @Column() + @Column({ nullable: true }) primary_sku_id?: string; // if this application is a game sold, this field will be the id of the "Game SKU" that is created, - @Column() + @Column({ nullable: true }) slug?: string; // if this application is a game sold, this field will be the URL slug that links to the store page - @Column() + @Column({ nullable: true }) cover_image?: string; // the application's default rich presence invite cover image hash @Column() diff --git a/util/src/entities/AuditLog.ts b/util/src/entities/AuditLog.ts index 2195771b..ea8aa641 100644 --- a/util/src/entities/AuditLog.ts +++ b/util/src/entities/AuditLog.ts @@ -46,7 +46,7 @@ export class AuditLogEntry extends BaseClass { @RelationId((auditlog: AuditLogEntry) => auditlog.target) target_id: string; - @JoinColumn({ name: "user_id" }) + @JoinColumn({ name: "target_id" }) @ManyToOne(() => User, (user: User) => user.id) target?: User; @@ -63,7 +63,7 @@ export class AuditLogEntry extends BaseClass { }) action_type: AuditLogEvents; - @Column("simple-json") + @Column({ type: "simple-json", nullable: true }) options?: { delete_member_days?: string; members_removed?: string; @@ -76,10 +76,10 @@ export class AuditLogEntry extends BaseClass { }; @Column() - @Column("simple-json") + @Column({ type: "simple-json" }) changes: AuditLogChange[]; - @Column() + @Column({ nullable: true }) reason?: string; } diff --git a/util/src/entities/Ban.ts b/util/src/entities/Ban.ts index 2553e886..f1cbd849 100644 --- a/util/src/entities/Ban.ts +++ b/util/src/entities/Ban.ts @@ -29,6 +29,6 @@ export class Ban extends BaseClass { @Column() ip: string; - @Column() + @Column({ nullable: true }) reason?: string; } diff --git a/util/src/entities/BaseClass.ts b/util/src/entities/BaseClass.ts index bb6ccea1..31338ff6 100644 --- a/util/src/entities/BaseClass.ts +++ b/util/src/entities/BaseClass.ts @@ -1,34 +1,26 @@ import "reflect-metadata"; -import { BaseEntity, BeforeInsert, BeforeUpdate, PrimaryColumn } from "typeorm"; +import { + BaseEntity, + BeforeInsert, + BeforeUpdate, + EntityMetadata, + FindConditions, + FindManyOptions, + PrimaryColumn, +} from "typeorm"; import { Snowflake } from "../util/Snowflake"; -import Ajv, { ValidateFunction } from "ajv"; -import schema from "./schema.json"; import "missing-native-js-functions"; // TODO use class-validator https://typeorm.io/#/validation with class annotators (isPhone/isEmail) combined with types from typescript-json-schema // btw. we don't use class-validator for everything, because we need to explicitly set the type instead of deriving it from typescript also it doesn't easily support nested objects -const ajv = new Ajv({ - removeAdditional: "all", - useDefaults: true, - coerceTypes: true, - // @ts-ignore - validateFormats: false, - allowUnionTypes: true, -}); - export class BaseClass extends BaseEntity { @PrimaryColumn() id: string; // @ts-ignore - constructor(props?: any, public opts: { id?: string } = {}) { + constructor(public props?: any, public opts: { id?: string } = {}) { super(); - this.assign(props); - - if (!this.construct.schema) { - this.construct.schema = ajv.compile({ ...schema, $ref: `#/definitions/${this.construct.name}` }); - } this.id = this.opts.id || Snowflake.generate(); } @@ -38,19 +30,20 @@ export class BaseClass extends BaseEntity { } get metadata() { - return this.construct.getRepository().metadata; + return this.construct.getRepository().metadata as EntityMetadata; } assign(props: any) { if (!props || typeof props !== "object") return; + delete props.id; delete props.opts; + delete props.props; const properties = new Set(this.metadata.columns.map((x: any) => x.propertyName)); // will not include relational properties (e.g. @RelationId @ManyToMany) for (const key in props) { - if (this.hasOwnProperty(key)) continue; if (!properties.has(key)) continue; // @ts-ignore const setter = this[`set${key.capitalize()}`]; @@ -66,8 +59,7 @@ export class BaseClass extends BaseEntity { @BeforeUpdate() @BeforeInsert() validate() { - const valid = this.construct.schema(this.toJSON()); - if (!valid) throw ajv.errors; + this.assign(this.props); return this; } @@ -75,4 +67,14 @@ export class BaseClass extends BaseEntity { // @ts-ignore return Object.fromEntries(this.metadata.columns.map((x) => [x.propertyName, this[x.propertyName]])); } + + static increment<T extends BaseClass>(conditions: FindConditions<T>, propertyPath: string, value: number | string) { + const repository = this.getRepository(); + return repository.increment(conditions, propertyPath, value); + } + + static decrement<T extends BaseClass>(conditions: FindConditions<T>, propertyPath: string, value: number | string) { + const repository = this.getRepository(); + return repository.decrement(conditions, propertyPath, value); + } } diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts index d26f1054..d02cedb4 100644 --- a/util/src/entities/Channel.ts +++ b/util/src/entities/Channel.ts @@ -60,25 +60,25 @@ export class Channel extends BaseClass { @ManyToOne(() => User, (user: User) => user.id) owner: User; - @Column() + @Column({ nullable: true }) last_pin_timestamp?: number; - @Column() + @Column({ nullable: true }) default_auto_archive_duration?: number; @Column() position: number; - @Column("simple-json") + @Column({ type: "simple-json" }) permission_overwrites: ChannelPermissionOverwrite[]; - @Column() + @Column({ nullable: true }) video_quality_mode?: number; - @Column() + @Column({ nullable: true }) bitrate?: number; - @Column() + @Column({ nullable: true }) user_limit?: number; @Column() @@ -87,7 +87,7 @@ export class Channel extends BaseClass { @Column() rate_limit_per_user: number; - @Column() + @Column({ nullable: true }) topic?: string; } diff --git a/util/src/entities/Config.ts b/util/src/entities/Config.ts index c9326be2..320a729c 100644 --- a/util/src/entities/Config.ts +++ b/util/src/entities/Config.ts @@ -5,7 +5,7 @@ import { Snowflake } from "../util/Snowflake"; @Entity("config") export class ConfigEntity extends BaseClass { - @Column("simple-json") + @Column({ type: "simple-json" }) value: ConfigValue; } diff --git a/util/src/entities/ConnectedAccount.ts b/util/src/entities/ConnectedAccount.ts index 6aa2b401..e48bc322 100644 --- a/util/src/entities/ConnectedAccount.ts +++ b/util/src/entities/ConnectedAccount.ts @@ -1,21 +1,29 @@ -import { Column, Entity } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; +import { User } from "./User"; @Entity("connected_accounts") export class ConnectedAccount extends BaseClass { - @Column() + @RelationId((account: ConnectedAccount) => account.user) + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.connected_accounts) + user: User; + + @Column({ select: false }) access_token: string; - @Column() + @Column({ select: false }) friend_sync: boolean; @Column() name: string; - @Column() + @Column({ select: false }) revoked: boolean; - @Column() + @Column({ select: false }) show_activity: boolean; @Column() @@ -24,6 +32,6 @@ export class ConnectedAccount extends BaseClass { @Column() verifie: boolean; - @Column() + @Column({ select: false }) visibility: number; } diff --git a/util/src/entities/Emoji.ts b/util/src/entities/Emoji.ts index b31ddb3b..0686d476 100644 --- a/util/src/entities/Emoji.ts +++ b/util/src/entities/Emoji.ts @@ -9,7 +9,7 @@ export class Emoji extends BaseClass { animated: boolean; @Column() - available: boolean; + available: boolean; // whether this emoji can be used, may be false due to loss of Server Boosts @Column() guild_id: string; @@ -27,9 +27,6 @@ export class Emoji extends BaseClass { @Column() require_colons: boolean; - @Column() - url: string; - @RelationId((emoji: Emoji) => emoji.roles) role_ids: string[]; diff --git a/util/src/entities/Guild.ts b/util/src/entities/Guild.ts index d7b4dff4..9ca4b1e4 100644 --- a/util/src/entities/Guild.ts +++ b/util/src/entities/Guild.ts @@ -17,51 +17,51 @@ export class Guild extends BaseClass { @ManyToOne(() => Channel, (channel: Channel) => channel.id) afk_channel?: Channel; - @Column() + @Column({ nullable: true }) afk_timeout?: number; // * commented out -> use owner instead // application id of the guild creator if it is bot-created - // @Column() + // @Column({ nullable: true }) // application?: string; - @Column() + @Column({ nullable: true }) banner?: string; - @Column() + @Column({ nullable: true }) default_message_notifications?: number; - @Column() + @Column({ nullable: true }) description?: string; - @Column() + @Column({ nullable: true }) discovery_splash?: string; - @Column() + @Column({ nullable: true }) explicit_content_filter?: number; - @Column("simple-array") + @Column({ type: "simple-array" }) features: string[]; - @Column() + @Column({ nullable: true }) icon?: string; - @Column() + @Column({ nullable: true }) large?: boolean; - @Column() + @Column({ nullable: true }) max_members?: number; // e.g. default 100.000 - @Column() + @Column({ nullable: true }) max_presences?: number; - @Column() + @Column({ nullable: true }) max_video_channel_users?: number; // ? default: 25, is this max 25 streaming or watching - @Column() + @Column({ nullable: true }) member_count?: number; - @Column() + @Column({ nullable: true }) presence_count?: number; // users online @RelationId((guild: Guild) => guild.members) @@ -99,7 +99,7 @@ export class Guild extends BaseClass { @ManyToMany(() => VoiceState, (voicestate: VoiceState) => voicestate.id) voice_states: VoiceState[]; - @Column() + @Column({ nullable: true }) mfa_level?: number; @Column() @@ -112,13 +112,13 @@ export class Guild extends BaseClass { @ManyToOne(() => User, (user: User) => user.id) owner: User; - @Column() + @Column({ nullable: true }) preferred_locale?: string; // only community guilds can choose this - @Column() + @Column({ nullable: true }) premium_subscription_count?: number; - @Column() + @Column({ nullable: true }) premium_tier?: number; // nitro boost level @RelationId((guild: Guild) => guild.public_updates_channel) @@ -135,10 +135,10 @@ export class Guild extends BaseClass { @ManyToOne(() => Channel, (channel: Channel) => channel.id) rules_channel?: string; - @Column() + @Column({ nullable: true }) region?: string; - @Column() + @Column({ nullable: true }) splash?: string; @RelationId((guild: Guild) => guild.system_channel) @@ -148,10 +148,10 @@ export class Guild extends BaseClass { @ManyToMany(() => Channel, (channel: Channel) => channel.id) system_channel?: Channel; - @Column() + @Column({ nullable: true }) system_channel_flags?: number; - @Column() + @Column({ nullable: true }) unavailable?: boolean; @RelationId((guild: Guild) => guild.vanity_url) @@ -161,10 +161,10 @@ export class Guild extends BaseClass { @OneToOne(() => Invite, (invite: Invite) => invite.code) vanity_url?: Invite; - @Column() + @Column({ nullable: true }) verification_level?: number; - @Column("simple-json") + @Column({ type: "simple-json" }) welcome_screen: { enabled: boolean; description: string; @@ -183,6 +183,6 @@ export class Guild extends BaseClass { @ManyToOne(() => Channel, (channel: Channel) => channel.id) widget_channel?: Channel; - @Column() + @Column({ nullable: true }) widget_enabled?: boolean; } diff --git a/util/src/entities/Invite.ts b/util/src/entities/Invite.ts index eac0cba0..d8c6d69c 100644 --- a/util/src/entities/Invite.ts +++ b/util/src/entities/Invite.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { Channel } from "./Channel"; import { Guild } from "./Guild"; @@ -6,7 +6,7 @@ import { User } from "./User"; @Entity("invites") export class Invite extends BaseClass { - @Column() + @PrimaryColumn() code: string; @Column() @@ -55,6 +55,6 @@ export class Invite extends BaseClass { @ManyToOne(() => User, (user: User) => user.id) target_user?: string; // could be used for "User specific invites" https://github.com/fosscord/fosscord/issues/62 - @Column() + @Column({ nullable: true }) target_user_type?: number; } diff --git a/util/src/entities/Member.ts b/util/src/entities/Member.ts index 01634d9e..5b588d70 100644 --- a/util/src/entities/Member.ts +++ b/util/src/entities/Member.ts @@ -1,7 +1,17 @@ import { PublicUser, User } from "./User"; import { BaseClass } from "./BaseClass"; -import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, RelationId } from "typeorm"; import { Guild } from "./Guild"; +import { Config, emitEvent } from "../util"; +import { + GuildCreateEvent, + GuildDeleteEvent, + GuildMemberAddEvent, + GuildMemberRemoveEvent, + GuildMemberUpdateEvent, +} from "../interfaces"; +import { HTTPError } from "lambert-server"; +import { Role } from "./Role"; @Entity("members") export class Member extends BaseClass { @@ -19,16 +29,20 @@ export class Member extends BaseClass { @ManyToOne(() => Guild, (guild: Guild) => guild.id) guild: Guild; - @Column() + @Column({ nullable: true }) nick?: string; - @Column("simple-array") - roles: string[]; + @RelationId((member: Member) => member.roles) + role_ids: string[]; + + @JoinColumn({ name: "role_ids" }) + @ManyToMany(() => Role) + roles: Role[]; @Column() joined_at: Date; - @Column() + @Column({ nullable: true }) premium_since?: number; @Column() @@ -40,12 +54,180 @@ export class Member extends BaseClass { @Column() pending: boolean; - @Column("simple-json") + @Column({ type: "simple-json" }) settings: UserGuildSettings; // TODO: update - @Column("simple-json") + @Column({ type: "simple-json" }) read_state: Record<string, string | null>; + + static async IsInGuildOrFail(user_id: string, guild_id: string) { + if (await Member.count({ id: user_id, guild_id })) return true; + throw new HTTPError("You are not member of this guild", 403); + } + + static async removeFromGuild(user_id: string, guild_id: string) { + const guild = await Guild.findOneOrFail({ select: ["owner_id"], where: { id: guild_id } }); + if (guild.owner_id === user_id) throw new Error("The owner cannot be removed of the guild"); + const member = await Member.findOneOrFail({ where: { id: user_id, guild_id }, relations: ["user"] }); + + // use promise all to execute all promises at the same time -> save time + return Promise.all([ + Member.delete({ + id: user_id, + guild_id: guild_id, + }), + Guild.decrement({ id: guild_id }, "member_count", -1), + + emitEvent({ + event: "GUILD_DELETE", + data: { + id: guild_id, + }, + user_id: user_id, + } as GuildDeleteEvent), + emitEvent({ + event: "GUILD_MEMBER_REMOVE", + data: { + guild_id: guild_id, + user: member.user, + }, + guild_id: guild_id, + } as GuildMemberRemoveEvent), + ]); + } + + static async addRole(user_id: string, guild_id: string, role_id: string) { + const [member] = await Promise.all([ + Member.findOneOrFail({ + where: { id: user_id, guild_id: guild_id }, + relations: ["user"], // we don't want to load the role objects just the ids + }), + await Role.findOneOrFail({ id: role_id, guild_id: guild_id }), + ]); + member.role_ids.push(role_id); + member.save(); + + await emitEvent({ + event: "GUILD_MEMBER_UPDATE", + data: { + guild_id: guild_id, + user: member.user, + roles: member.role_ids, + }, + guild_id: guild_id, + } as GuildMemberUpdateEvent); + } + + static async removeRole(user_id: string, guild_id: string, role_id: string) { + const [member] = await Promise.all([ + Member.findOneOrFail({ + where: { id: user_id, guild_id: guild_id }, + relations: ["user"], // we don't want to load the role objects just the ids + }), + await Role.findOneOrFail({ id: role_id, guild_id: guild_id }), + ]); + member.role_ids.remove(role_id); + member.save(); + + await emitEvent({ + event: "GUILD_MEMBER_UPDATE", + data: { + guild_id: guild_id, + user: member.user, + roles: member.role_ids, + }, + guild_id: guild_id, + } as GuildMemberUpdateEvent); + } + + static async changeNickname(user_id: string, guild_id: string, nickname: string) { + const member = await Member.findOneOrFail({ + where: { + id: user_id, + guild_id: guild_id, + }, + relations: ["user"], + }); + member.nick = nickname; + + await Promise.all([ + member.save(), + + emitEvent({ + event: "GUILD_MEMBER_UPDATE", + data: { + guild_id: guild_id, + user: member.user, + nick: nickname, + }, + guild_id: guild_id, + } as GuildMemberUpdateEvent), + ]); + } + + static async addToGuild(user_id: string, guild_id: string) { + const user = await User.getPublicUser(user_id); + + const { maxGuilds } = Config.get().limits.user; + const guild_count = await Member.count({ id: user_id }); + if (guild_count >= maxGuilds) { + throw new HTTPError(`You are at the ${maxGuilds} server limit.`, 403); + } + + const guild = await Guild.findOneOrFail(guild_id, { + relations: ["channels", "emojis", "members", "roles", "stickers"], + }); + + if (await Member.count({ id: user.id, guild_id })) + throw new HTTPError("You are already a member of this guild", 400); + + const member = { + id: user_id, + guild_id: guild_id, + nick: undefined, + roles: [guild_id], // @everyone role + joined_at: new Date(), + premium_since: undefined, + deaf: false, + mute: false, + pending: false, + }; + // @ts-ignore + guild.joined_at = member.joined_at; + + await Promise.all([ + new Member({ + ...member, + read_state: {}, + settings: { + channel_overrides: [], + message_notifications: 0, + mobile_push: true, + mute_config: null, + muted: false, + suppress_everyone: false, + suppress_roles: false, + version: 0, + }, + }).save(), + Guild.increment({ id: guild_id }, "member_count", 1), + emitEvent({ + event: "GUILD_MEMBER_ADD", + data: { + ...member, + user, + guild_id: guild_id, + }, + guild_id: guild_id, + } as GuildMemberAddEvent), + emitEvent({ + event: "GUILD_CREATE", + data: guild, + user_id, + } as GuildCreateEvent), + ]); + } } export interface UserGuildSettings { @@ -69,19 +251,31 @@ export interface MuteConfig { selected_time_window: number; } +export type PublicMemberKeys = + | "id" + | "guild_id" + | "nick" + | "roles" + | "joined_at" + | "pending" + | "deaf" + | "mute" + | "premium_since"; + +export const PublicMemberProjection: PublicMemberKeys[] = [ + "id", + "guild_id", + "nick", + "roles", + "joined_at", + "pending", + "deaf", + "mute", + "premium_since", +]; + // @ts-ignore -export interface PublicMember extends Omit<Member, "settings" | "id" | "read_state"> { +export type PublicMember = Pick<Member, Omit<PublicMemberKeys, "roles">> & { user: PublicUser; -} - -export const PublicMemberProjection = { - id: true, - guild_id: true, - nick: true, - roles: true, - joined_at: true, - pending: true, - deaf: true, - mute: true, - premium_since: true, + roles: string[]; // only role ids not objects }; diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts index 9daf042c..0c41a2eb 100644 --- a/util/src/entities/Message.ts +++ b/util/src/entities/Message.ts @@ -17,6 +17,7 @@ import { import { BaseClass } from "./BaseClass"; import { Guild } from "./Guild"; import { Webhook } from "./Webhook"; +import { Sticker } from "./Sticker"; export enum MessageType { DEFAULT = 0, @@ -51,7 +52,7 @@ export class Message extends BaseClass { channel: Channel; @RelationId((message: Message) => message.guild) - guild_id: string; + guild_id?: string; @JoinColumn({ name: "guild_id" }) @ManyToOne(() => Guild, (guild: Guild) => guild.id) @@ -85,7 +86,7 @@ export class Message extends BaseClass { @ManyToOne(() => Application, (application: Application) => application.id) application?: Application; - @Column() + @Column({ nullable: true }) content?: string; @Column() @@ -96,18 +97,18 @@ export class Message extends BaseClass { @UpdateDateColumn() edited_timestamp?: Date; - @Column() + @Column({ nullable: true }) tts?: boolean; - @Column() + @Column({ nullable: true }) mention_everyone?: boolean; - @RelationId((message: Message) => message.mention_users) + @RelationId((message: Message) => message.mentions) mention_user_ids: string[]; @JoinColumn({ name: "mention_user_ids" }) @ManyToMany(() => User, (user: User) => user.id) - mention_users: User[]; + mentions: User[]; @RelationId((message: Message) => message.mention_roles) mention_role_ids: string[]; @@ -123,44 +124,52 @@ export class Message extends BaseClass { @ManyToMany(() => Channel, (channel: Channel) => channel.id) mention_channels: Channel[]; - @Column("simple-json") + @Column({ type: "simple-json" }) attachments: Attachment[]; - @Column("simple-json") + @Column({ type: "simple-json" }) embeds: Embed[]; - @Column("simple-json") + @Column({ type: "simple-json" }) reactions: Reaction[]; - @Column({ type: "text" }) + @Column({ type: "text", nullable: true }) nonce?: string | number; - @Column() + @Column({ nullable: true }) pinned?: boolean; @Column({ type: "simple-enum", enum: MessageType }) type: MessageType; - @Column("simple-json") + @Column({ type: "simple-json", nullable: true }) activity?: { type: number; party_id: string; }; - @Column({ type: "bigint" }) + @Column({ type: "bigint", nullable: true }) flags?: bigint; - @Column("simple-json") - stickers?: any[]; + @RelationId((message: Message) => message.stickers) + sticker_ids: string[]; + + @JoinColumn({ name: "sticker_ids" }) + @ManyToMany(() => Sticker, (sticker: Sticker) => sticker.id) + stickers?: Sticker[]; - @Column("simple-json") + @Column({ type: "simple-json", nullable: true }) message_reference?: { message_id: string; channel_id?: string; guild_id?: string; }; - @Column("simple-json") + @JoinColumn({ name: "message_reference_id" }) + @ManyToOne(() => Message, (message: Message) => message.id) + referenced_message?: Message; + + @Column({ type: "simple-json", nullable: true }) interaction?: { id: string; type: InteractionType; @@ -169,7 +178,7 @@ export class Message extends BaseClass { // user: User; // TODO: autopopulate user }; - @Column("simple-json") + @Column({ type: "simple-json" }) components: MessageComponent[]; } diff --git a/util/src/entities/ReadState.ts b/util/src/entities/ReadState.ts index 70a38b84..650ee4c3 100644 --- a/util/src/entities/ReadState.ts +++ b/util/src/entities/ReadState.ts @@ -31,7 +31,7 @@ export class ReadState extends BaseClass { @ManyToOne(() => Message, (message: Message) => message.id) last_message?: Message; - @Column() + @Column({ nullable: true }) last_pin_timestamp?: Date; @Column() diff --git a/util/src/entities/Relationship.ts b/util/src/entities/Relationship.ts index 3e1280c7..cf3624bf 100644 --- a/util/src/entities/Relationship.ts +++ b/util/src/entities/Relationship.ts @@ -1,4 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; +import { Column, Entity, JoinColumn, ManyToOne, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { User } from "./User"; @@ -15,10 +15,10 @@ export class Relationship extends BaseClass { user_id: string; @JoinColumn({ name: "user_id" }) - @ManyToOne(() => User, (user: User) => user.id) + @ManyToOne(() => User, (user: User) => user.relationships) user: User; - @Column() + @Column({ nullable: true }) nickname?: string; @Column({ type: "simple-enum", enum: RelationshipType }) diff --git a/util/src/entities/Role.ts b/util/src/entities/Role.ts index e48fd293..7c6ce64e 100644 --- a/util/src/entities/Role.ts +++ b/util/src/entities/Role.ts @@ -32,7 +32,7 @@ export class Role extends BaseClass { @Column() position: number; - @Column({ type: "simple-json" }) + @Column({ type: "simple-json", nullable: true }) tags?: { bot_id?: string; integration_id?: string; diff --git a/util/src/entities/Sticker.ts b/util/src/entities/Sticker.ts new file mode 100644 index 00000000..12394207 --- /dev/null +++ b/util/src/entities/Sticker.ts @@ -0,0 +1,42 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; + +export enum StickerType { + STANDARD = 1, + GUILD = 2, +} + +export enum StickerFormatType { + PNG = 1, + APNG = 2, + LOTTIE = 3, +} + +@Entity("stickers") +export class Sticker extends BaseClass { + @Column() + name: string; + + @Column({ nullable: true }) + description?: string; + + @Column() + tags: string; + + @Column() + pack_id: string; + + @Column({ nullable: true }) + guild_id?: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild?: Guild; + + @Column({ type: "simple-enum", enum: StickerType }) + type: StickerType; + + @Column({ type: "simple-enum", enum: StickerFormatType }) + format_type: StickerFormatType; +} diff --git a/util/src/entities/Team.ts b/util/src/entities/Team.ts index fa1b0ed2..b37f368c 100644 --- a/util/src/entities/Team.ts +++ b/util/src/entities/Team.ts @@ -5,7 +5,7 @@ import { User } from "./User"; @Entity("teams") export class Team extends BaseClass { - @Column() + @Column({ nullable: true }) icon?: string; @RelationId((team: Team) => team.members) diff --git a/util/src/entities/TeamMember.ts b/util/src/entities/TeamMember.ts index f0b54c6f..d4c95397 100644 --- a/util/src/entities/TeamMember.ts +++ b/util/src/entities/TeamMember.ts @@ -12,7 +12,7 @@ export class TeamMember extends BaseClass { @Column({ type: "simple-enum", enum: TeamMemberState }) membership_state: TeamMemberState; - @Column("simple-array") + @Column({ type: "simple-array" }) permissions: string[]; @RelationId((member: TeamMember) => member.team) diff --git a/util/src/entities/Template.ts b/util/src/entities/Template.ts index 1dfc3b1b..2d8c9b6c 100644 --- a/util/src/entities/Template.ts +++ b/util/src/entities/Template.ts @@ -11,10 +11,10 @@ export class Template extends BaseClass { @Column() name: string; - @Column() + @Column({ nullable: true }) description?: string; - @Column() + @Column({ nullable: true }) usage_count?: number; @RelationId((template: Template) => template.creator) @@ -37,6 +37,6 @@ export class Template extends BaseClass { @ManyToOne(() => Guild, (guild: Guild) => guild.id) source_guild: Guild; - @Column("simple-json") + @Column({ type: "simple-json" }) serialized_source_guild: Guild; } diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts index 03cb3af4..c5f870fa 100644 --- a/util/src/entities/User.ts +++ b/util/src/entities/User.ts @@ -1,22 +1,34 @@ -import { Column, Entity, JoinColumn, OneToMany, RelationId } from "typeorm"; +import { Column, Entity, FindOneOptions, JoinColumn, OneToMany, RelationId } from "typeorm"; import { BaseClass } from "./BaseClass"; import { BitField } from "../util/BitField"; import { Relationship } from "./Relationship"; import { ConnectedAccount } from "./ConnectedAccount"; import { HTTPError } from "lambert-server"; -import { Guild } from "./Guild"; - -export const PublicUserProjection = { - username: true, - discriminator: true, - id: true, - public_flags: true, - avatar: true, - accent_color: true, - banner: true, - bio: true, - bot: true, -}; + +type PublicUserKeys = + | "username" + | "discriminator" + | "id" + | "public_flags" + | "avatar" + | "accent_color" + | "banner" + | "bio" + | "bot"; +export const PublicUserProjection: PublicUserKeys[] = [ + "username", + "discriminator", + "id", + "public_flags", + "avatar", + "accent_color", + "banner", + "bio", + "bot", +]; + +// Private user data that should never get sent to the client +export type PublicUser = Pick<User, PublicUserKeys>; @Entity("users") export class User extends BaseClass { @@ -30,115 +42,145 @@ export class User extends BaseClass { const number = Number(val); if (isNaN(number)) throw new Error("invalid discriminator"); if (number <= 0 || number > 10000) throw new Error("discriminator must be between 1 and 9999"); - this.discriminator = val.toString(); + this.discriminator = val.toString().padStart(4, "0"); } - @Column() + @Column({ nullable: true }) avatar?: string; // hash of the user avatar - @Column() - accent_color?: number; // banner color of user + @Column({ nullable: true }) + accent_color?: number = 0; // banner color of user - @Column() + @Column({ nullable: true }) banner?: string; // hash of the user banner - @Column() + @Column({ nullable: true }) phone?: string; // phone number of the user @Column() - desktop: boolean; // if the user has desktop app installed + desktop: boolean = false; // if the user has desktop app installed @Column() - mobile: boolean; // if the user has mobile app installed + mobile: boolean = false; // if the user has mobile app installed @Column() - premium: boolean; // if user bought nitro + premium: boolean = false; // if user bought nitro @Column() - premium_type: number; // nitro level + premium_type: number = 0; // nitro level @Column() - bot: boolean; // if user is bot + bot: boolean = false; // if user is bot @Column() - bio: string; // short description of the user (max 190 chars -> should be configurable) + bio: string = ""; // short description of the user (max 190 chars -> should be configurable) @Column() - system: boolean; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author + system: boolean = false; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author @Column() - nsfw_allowed: boolean; // if the user is older than 18 (resp. Config) + nsfw_allowed: boolean = false; // if the user is older than 18 (resp. Config) @Column() - mfa_enabled: boolean; // if multi factor authentication is enabled + mfa_enabled: boolean = false; // if multi factor authentication is enabled @Column() - created_at: Date; // registration date + created_at: Date = new Date(); // registration date @Column() - verified: boolean; // if the user is offically verified + verified: boolean = false; // if the user is offically verified @Column() - disabled: boolean; // if the account is disabled + disabled: boolean = false; // if the account is disabled @Column() - deleted: boolean; // if the user was deleted + deleted: boolean = false; // if the user was deleted - @Column() + @Column({ nullable: true }) email?: string; // email of the user @Column({ type: "bigint" }) - flags: bigint; // UserFlags + flags: bigint = BigInt(0); // UserFlags @Column({ type: "bigint" }) - public_flags: bigint; - - @RelationId((user: User) => user.guilds) - guild_ids: string[]; // array of guild ids the user is part of - - @JoinColumn({ name: "guild_ids" }) - @OneToMany(() => Guild, (guild: Guild) => guild.id) - guilds: Guild[]; + public_flags: bigint = BigInt(0); @RelationId((user: User) => user.relationships) relationship_ids: string[]; // array of guild ids the user is part of @JoinColumn({ name: "relationship_ids" }) - @OneToMany(() => User, (user: User) => user.id) + @OneToMany(() => Relationship, (relationship: Relationship) => relationship.user, { cascade: true }) relationships: Relationship[]; @RelationId((user: User) => user.connected_accounts) connected_account_ids: string[]; // array of guild ids the user is part of @JoinColumn({ name: "connected_account_ids" }) - @OneToMany(() => ConnectedAccount, (account: ConnectedAccount) => account.id) + @OneToMany(() => ConnectedAccount, (account: ConnectedAccount) => account.user) connected_accounts: ConnectedAccount[]; @Column({ type: "simple-json", select: false }) data: { valid_tokens_since: Date; // all tokens with a previous issue date are invalid - hash: string; // hash of the password, salt is saved in password (bcrypt) - }; + hash?: string; // hash of the password, salt is saved in password (bcrypt) + } = { valid_tokens_since: new Date() }; @Column({ type: "simple-array" }) - fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts - - @Column("simple-json") - settings: UserSettings; - - static async getPublicUser(user_id: string, additional_fields?: any) { - const user = await User.findOne( - { id: user_id }, - { - ...PublicUserProjection, - ...additional_fields, - } - ); + fingerprints: string[] = []; // array of fingerprints -> used to prevent multiple accounts + + @Column({ type: "simple-json" }) + settings: UserSettings = defaultSettings; + + static async getPublicUser(user_id: string, opts?: FindOneOptions<User>) { + const user = await User.findOne(user_id, { + ...opts, + select: [...PublicUserProjection, ...(opts?.select || [])], + }); if (!user) throw new HTTPError("User not found", 404); return user; } } +export const defaultSettings: UserSettings = { + afk_timeout: 300, + allow_accessibility_detection: true, + animate_emoji: true, + animate_stickers: 0, + contact_sync_enabled: false, + convert_emoticons: false, + custom_status: { + emoji_id: undefined, + emoji_name: undefined, + expires_at: undefined, + text: undefined, + }, + default_guilds_restricted: false, + detect_platform_accounts: true, + developer_mode: false, + disable_games_tab: false, + enable_tts_command: true, + explicit_content_filter: 0, + friend_source_flags: { all: true }, + gateway_connected: false, + gif_auto_play: true, + guild_folders: [], + guild_positions: [], + inline_attachment_media: true, + inline_embed_media: true, + locale: "en", + message_display_compact: false, + native_phone_integration_enabled: true, + render_embeds: true, + render_reactions: true, + restricted_guilds: [], + show_current_game: true, + status: "offline", + stream_notifications_enabled: true, + theme: "dark", + timezone_offset: 0, + // timezone_offset: // TODO: timezone from request +}; + export interface UserSettings { afk_timeout: number; allow_accessibility_detection: boolean; @@ -184,18 +226,6 @@ export interface UserSettings { timezone_offset: number; // e.g -60 } -// Private user data that should never get sent to the client -export interface PublicUser { - id: string; - discriminator: string; - username: string; - avatar?: string; - accent_color?: number; - banner?: string; - public_flags: bigint; - bot: boolean; -} - export class UserFlags extends BitField { static FLAGS = { DISCORD_EMPLOYEE: BigInt(1) << BigInt(0), diff --git a/util/src/entities/VoiceState.ts b/util/src/entities/VoiceState.ts index 6707a575..e9d3dfa2 100644 --- a/util/src/entities/VoiceState.ts +++ b/util/src/entities/VoiceState.ts @@ -42,7 +42,7 @@ export class VoiceState extends BaseClass { @Column() self_mute: boolean; - @Column() + @Column({ nullable: true }) self_stream?: boolean; @Column() diff --git a/util/src/entities/Webhook.ts b/util/src/entities/Webhook.ts index dc929c18..a75cb959 100644 --- a/util/src/entities/Webhook.ts +++ b/util/src/entities/Webhook.ts @@ -18,13 +18,13 @@ export class Webhook extends BaseClass { @Column({ type: "simple-enum", enum: WebhookType }) type: WebhookType; - @Column() + @Column({ nullable: true }) name?: string; - @Column() + @Column({ nullable: true }) avatar?: string; - @Column() + @Column({ nullable: true }) token?: string; @RelationId((webhook: Webhook) => webhook.guild) diff --git a/util/src/entities/schema.json b/util/src/entities/schema.json deleted file mode 100644 index 7f192690..00000000 --- a/util/src/entities/schema.json +++ /dev/null @@ -1,6218 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "definitions": { - "Activity": { - "properties": { - "application_id": { - "type": "string" - }, - "assets": { - "properties": { - "large_image": { - "type": "string" - }, - "large_text": { - "type": "string" - }, - "small_image": { - "type": "string" - }, - "small_text": { - "type": "string" - } - }, - "type": "object" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "details": { - "type": "string" - }, - "emoji": { - "properties": { - "amimated": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "flags": { - "type": "bigint" - }, - "instance": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "party": { - "properties": { - "id": { - "type": "string" - }, - "size": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "maxItems": 2, - "minItems": 2, - "type": "array" - } - }, - "type": "object" - }, - "secrets": { - "properties": { - "join": { - "type": "string" - }, - "match": { - "type": "string" - }, - "spectate": { - "type": "string" - } - }, - "type": "object" - }, - "state": { - "type": "string" - }, - "timestamps": { - "items": { - "properties": { - "end": { - "type": "number" - }, - "start": { - "type": "number" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": { - "$ref": "#/definitions/ActivityType" - }, - "url": { - "type": "string" - } - }, - "type": "object" - }, - "ActivityType": { - "enum": [ - 0, - 1, - 2, - 4, - 5 - ], - "type": "number" - }, - "AllowedMentions": { - "properties": { - "parse": { - "items": { - "enum": [ - "everyone", - "roles", - "users" - ], - "type": "string" - }, - "type": "array" - }, - "replied_user": { - "type": "boolean" - }, - "roles": { - "items": { - "type": "string" - }, - "type": "array" - }, - "users": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "Application": { - "properties": { - "bot_public": { - "type": "boolean" - }, - "bot_require_code_grant": { - "type": "boolean" - }, - "construct": { - }, - "cover_image": { - "type": "string" - }, - "description": { - "type": "string" - }, - "flags": { - "type": "number" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "owner_id": { - "type": "string" - }, - "primary_sku_id": { - "type": "string" - }, - "privacy_policy_url": { - "type": "string" - }, - "rpc_origins": { - "items": { - "type": "string" - }, - "type": "array" - }, - "slug": { - "type": "string" - }, - "summary": { - "type": "string" - }, - "team": { - "$ref": "#/definitions/Team" - }, - "team_id": { - "type": "string" - }, - "terms_of_service_url": { - "type": "string" - }, - "verify_key": { - "type": "string" - } - }, - "type": "object" - }, - "ApplicationCommand": { - "properties": { - "application_id": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "options": { - "items": { - "$ref": "#/definitions/ApplicationCommandOption" - }, - "type": "array" - } - }, - "type": "object" - }, - "ApplicationCommandCreateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/ApplicationCommand" - }, - { - "properties": { - "guild_id": { - "type": "string" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "APPLICATION_COMMAND_CREATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "ApplicationCommandDeleteEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/ApplicationCommand" - }, - { - "properties": { - "guild_id": { - "type": "string" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "APPLICATION_COMMAND_DELETE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "ApplicationCommandInteractionData": { - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "options": { - "items": { - "$ref": "#/definitions/ApplicationCommandInteractionDataOption" - }, - "type": "array" - } - }, - "type": "object" - }, - "ApplicationCommandInteractionDataOption": { - "properties": { - "name": { - "type": "string" - }, - "options": { - "items": { - "$ref": "#/definitions/ApplicationCommandInteractionDataOption" - }, - "type": "array" - }, - "value": { - } - }, - "type": "object" - }, - "ApplicationCommandOption": { - "properties": { - "choices": { - "items": { - "$ref": "#/definitions/ApplicationCommandOptionChoice" - }, - "type": "array" - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "options": { - "items": { - "$ref": "#/definitions/ApplicationCommandOption" - }, - "type": "array" - }, - "required": { - "type": "boolean" - }, - "type": { - "$ref": "#/definitions/ApplicationCommandOptionType" - } - }, - "type": "object" - }, - "ApplicationCommandOptionChoice": { - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": [ - "string", - "number" - ] - } - }, - "type": "object" - }, - "ApplicationCommandOptionType": { - "enum": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8 - ], - "type": "number" - }, - "ApplicationCommandPayload": { - "allOf": [ - { - "$ref": "#/definitions/ApplicationCommand" - }, - { - "properties": { - "guild_id": { - "type": "string" - } - }, - "type": "object" - } - ] - }, - "ApplicationCommandUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/ApplicationCommand" - }, - { - "properties": { - "guild_id": { - "type": "string" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "APPLICATION_COMMAND_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "Attachment": { - "properties": { - "content_type": { - "type": "string" - }, - "filename": { - "type": "string" - }, - "height": { - "type": "number" - }, - "id": { - "type": "string" - }, - "proxy_url": { - "type": "string" - }, - "size": { - "type": "number" - }, - "url": { - "type": "string" - }, - "width": { - "type": "number" - } - }, - "type": "object" - }, - "AuditLogChange": { - "properties": { - "key": { - "type": "string" - }, - "new_value": { - "$ref": "#/definitions/AuditLogChangeValue" - }, - "old_value": { - "$ref": "#/definitions/AuditLogChangeValue" - } - }, - "type": "object" - }, - "AuditLogChangeValue": { - "properties": { - "$add": { - "items": { - "properties": { - }, - "type": "object" - }, - "type": "array" - }, - "$remove": { - "items": { - "properties": { - }, - "type": "object" - }, - "type": "array" - }, - "afk_channel_id": { - "type": "string" - }, - "afk_timeout": { - "type": "number" - }, - "allow": { - "type": "string" - }, - "application_id": { - "type": "string" - }, - "avatar_hash": { - "type": "string" - }, - "banner_hash": { - "type": "string" - }, - "bitrate": { - "type": "number" - }, - "channel_id": { - "type": "string" - }, - "code": { - "type": "string" - }, - "color": { - "type": "number" - }, - "deaf": { - "type": "boolean" - }, - "default_message_notifications": { - "type": "number" - }, - "deny": { - "type": "string" - }, - "description": { - "type": "string" - }, - "discovery_splash_hash": { - "type": "string" - }, - "enable_emoticons": { - "type": "boolean" - }, - "expire_behavior": { - "type": "number" - }, - "expire_grace_period": { - "type": "number" - }, - "explicit_content_filter": { - "type": "number" - }, - "hoist": { - "type": "boolean" - }, - "icon_hash": { - "type": "string" - }, - "id": { - "type": "string" - }, - "inviter_id": { - "type": "string" - }, - "max_age": { - "type": "number" - }, - "max_uses": { - "type": "number" - }, - "mentionable": { - "type": "boolean" - }, - "mfa_level": { - "type": "number" - }, - "mute": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "nick": { - "type": "string" - }, - "nsfw": { - "type": "boolean" - }, - "owner_id": { - "type": "string" - }, - "permission_overwrites": { - "items": { - "$ref": "#/definitions/ChannelPermissionOverwrite" - }, - "type": "array" - }, - "permissions": { - "type": "string" - }, - "position": { - "type": "number" - }, - "preferred_locale": { - "type": "string" - }, - "prune_delete_days": { - "type": "number" - }, - "public_updates_channel_id": { - "type": "string" - }, - "rate_limit_per_user": { - "type": "number" - }, - "region": { - "type": "string" - }, - "rules_channel_id": { - "type": "string" - }, - "splash_hash": { - "type": "string" - }, - "system_channel_id": { - "type": "string" - }, - "temporary": { - "type": "boolean" - }, - "topic": { - "type": "string" - }, - "type": { - "type": "number" - }, - "user_limit": { - "type": "number" - }, - "uses": { - "type": "number" - }, - "vanity_url_code": { - "type": "string" - }, - "verification_level": { - "type": "number" - }, - "widget_channel_id": { - "type": "string" - }, - "widget_enabled": { - "type": "boolean" - } - }, - "type": "object" - }, - "AuditLogEntry": { - "properties": { - "action_type": { - "$ref": "#/definitions/AuditLogEvents" - }, - "changes": { - "items": { - "$ref": "#/definitions/AuditLogChange" - }, - "type": "array" - }, - "construct": { - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "options": { - "properties": { - "channel_id": { - "type": "string" - }, - "count": { - "type": "string" - }, - "delete_member_days": { - "type": "string" - }, - "id": { - "type": "string" - }, - "members_removed": { - "type": "string" - }, - "messaged_id": { - "type": "string" - }, - "role_name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "type": "object" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "reason": { - "type": "string" - }, - "target": { - "$ref": "#/definitions/User" - }, - "target_id": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "AuditLogEvents": { - "enum": [ - 1, - 10, - 11, - 12, - 13, - 14, - 15, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 30, - 31, - 32, - 40, - 41, - 42, - 50, - 51, - 52, - 60, - 61, - 62, - 72, - 73, - 74, - 75, - 80, - 81, - 82 - ], - "type": "number" - }, - "Ban": { - "properties": { - "construct": { - }, - "executor": { - "$ref": "#/definitions/User" - }, - "executor_id": { - "type": "string" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "reason": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "BaseClass": { - "properties": { - "construct": { - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "BigInt": { - "properties": { - "__@toStringTag": { - "enum": [ - "BigInt" - ], - "type": "string" - } - }, - "type": "object" - }, - "BitField": { - "description": "Data structure that makes it easy to interact with a bitfield.", - "properties": { - "bitfield": { - "type": "bigint" - } - }, - "type": "object" - }, - "BitFieldResolvable": { - "anyOf": [ - { - "$ref": "#/definitions/BigInt" - }, - { - "$ref": "#/definitions/BitField" - }, - { - "items": { - "$ref": "#/definitions/BitFieldResolvable" - }, - "type": "array" - }, - { - "type": [ - "string", - "number" - ] - } - ] - }, - "CUSTOMEVENTS": { - "enum": [ - "INVALIDATED" - ], - "type": "string" - }, - "Channel": { - "properties": { - "bitrate": { - "type": "number" - }, - "construct": { - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "default_auto_archive_duration": { - "type": "number" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "last_message": { - "$ref": "#/definitions/Message" - }, - "last_message_id": { - "type": "string" - }, - "last_pin_timestamp": { - "type": "number" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "nsfw": { - "type": "boolean" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "owner": { - "$ref": "#/definitions/User" - }, - "owner_id": { - "type": "string" - }, - "parent": { - "$ref": "#/definitions/Channel" - }, - "parent_id": { - "type": "string" - }, - "permission_overwrites": { - "items": { - "$ref": "#/definitions/ChannelPermissionOverwrite" - }, - "type": "array" - }, - "position": { - "type": "number" - }, - "rate_limit_per_user": { - "type": "number" - }, - "recipient_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "recipients": { - "items": { - "$ref": "#/definitions/User" - }, - "type": "array" - }, - "topic": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/ChannelType" - }, - "user_limit": { - "type": "number" - }, - "video_quality_mode": { - "type": "number" - } - }, - "type": "object" - }, - "ChannelCreateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Channel" - }, - "event": { - "enum": [ - "CHANNEL_CREATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "ChannelDeleteEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Channel" - }, - "event": { - "enum": [ - "CHANNEL_DELETE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "ChannelPermissionOverwrite": { - "properties": { - "allow": { - "type": "bigint" - }, - "deny": { - "type": "bigint" - }, - "id": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/ChannelPermissionOverwriteType" - } - }, - "type": "object" - }, - "ChannelPermissionOverwriteType": { - "enum": [ - 0, - 1 - ], - "type": "number" - }, - "ChannelPinsUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "last_pin_timestamp": { - "type": "number" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "CHANNEL_PINS_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "ChannelType": { - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6 - ], - "type": "number" - }, - "ChannelUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Channel" - }, - "event": { - "enum": [ - "CHANNEL_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "Channel_1": { - "type": "object" - }, - "ClientStatus": { - "properties": { - "desktop": { - "type": "string" - }, - "mobile": { - "type": "string" - }, - "web": { - "type": "string" - } - }, - "type": "object" - }, - "ConfigEntity": { - "properties": { - "construct": { - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "value": { - "$ref": "#/definitions/ConfigValue" - } - }, - "type": "object" - }, - "ConfigValue": { - "properties": { - "cdn": { - "properties": { - "endpoint": { - "type": [ - "null", - "string" - ] - }, - "endpointClient": { - "type": [ - "null", - "string" - ] - } - }, - "type": "object" - }, - "gateway": { - "properties": { - "endpoint": { - "type": [ - "null", - "string" - ] - }, - "endpointClient": { - "type": [ - "null", - "string" - ] - } - }, - "type": "object" - }, - "general": { - "properties": { - "instance_id": { - "type": "string" - } - }, - "type": "object" - }, - "kafka": { - "properties": { - "brokers": { - "anyOf": [ - { - "items": { - "$ref": "#/definitions/KafkaBroker" - }, - "type": "array" - }, - { - "type": "null" - } - ] - } - }, - "type": "object" - }, - "limits": { - "properties": { - "channel": { - "properties": { - "maxPins": { - "type": "number" - }, - "maxTopic": { - "type": "number" - } - }, - "type": "object" - }, - "guild": { - "properties": { - "hideOfflineMember": { - "type": "number" - }, - "maxChannels": { - "type": "number" - }, - "maxChannelsInCategory": { - "type": "number" - }, - "maxMembers": { - "type": "number" - }, - "maxRoles": { - "type": "number" - } - }, - "type": "object" - }, - "message": { - "properties": { - "maxAttachmentSize": { - "type": "number" - }, - "maxBulkDelete": { - "type": "number" - }, - "maxCharacters": { - "type": "number" - }, - "maxReactions": { - "type": "number" - }, - "maxTTSCharacters": { - "type": "number" - } - }, - "type": "object" - }, - "rate": { - "properties": { - "error": { - "$ref": "#/definitions/RateLimitOptions" - }, - "global": { - "$ref": "#/definitions/RateLimitOptions" - }, - "ip": { - "$ref": "#/definitions/Omit<RateLimitOptions,\"bot_count\">" - }, - "routes": { - "properties": { - "auth": { - "properties": { - "login": { - "$ref": "#/definitions/RateLimitOptions" - }, - "register": { - "$ref": "#/definitions/RateLimitOptions" - } - }, - "type": "object" - }, - "channel": { - "$ref": "#/definitions/RateLimitOptions" - }, - "guild": { - "$ref": "#/definitions/RateLimitOptions" - }, - "webhook": { - "$ref": "#/definitions/RateLimitOptions" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "user": { - "properties": { - "maxFriends": { - "type": "number" - }, - "maxGuilds": { - "type": "number" - }, - "maxUsername": { - "type": "number" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "login": { - "properties": { - "requireCaptcha": { - "type": "boolean" - } - }, - "type": "object" - }, - "permissions": { - "properties": { - "user": { - "properties": { - "createGuilds": { - "type": "boolean" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "rabbitmq": { - "properties": { - "host": { - "type": [ - "null", - "string" - ] - } - }, - "type": "object" - }, - "regions": { - "properties": { - "available": { - "items": { - "$ref": "#/definitions/Region" - }, - "type": "array" - }, - "default": { - "type": "string" - } - }, - "type": "object" - }, - "register": { - "properties": { - "allowMultipleAccounts": { - "type": "boolean" - }, - "allowNewRegistration": { - "type": "boolean" - }, - "blockProxies": { - "type": "boolean" - }, - "dateOfBirth": { - "properties": { - "minimum": { - "type": "number" - }, - "necessary": { - "type": "boolean" - } - }, - "type": "object" - }, - "email": { - "properties": { - "allowlist": { - "type": "boolean" - }, - "blocklist": { - "type": "boolean" - }, - "domains": { - "items": { - "type": "string" - }, - "type": "array" - }, - "necessary": { - "type": "boolean" - } - }, - "type": "object" - }, - "password": { - "properties": { - "minLength": { - "type": "number" - }, - "minNumbers": { - "type": "number" - }, - "minSymbols": { - "type": "number" - }, - "minUpperCase": { - "type": "number" - } - }, - "type": "object" - }, - "requireCaptcha": { - "type": "boolean" - }, - "requireInvite": { - "type": "boolean" - } - }, - "type": "object" - }, - "security": { - "properties": { - "autoUpdate": { - "type": [ - "number", - "boolean" - ] - }, - "captcha": { - "properties": { - "enabled": { - "type": "boolean" - }, - "secret": { - "type": [ - "null", - "string" - ] - }, - "service": { - "anyOf": [ - { - "enum": [ - "hcaptcha", - "recaptcha" - ], - "type": "string" - }, - { - "type": "null" - } - ] - }, - "sitekey": { - "type": [ - "null", - "string" - ] - } - }, - "type": "object" - }, - "forwadedFor": { - "type": [ - "null", - "string" - ] - }, - "ipdataApiKey": { - "type": [ - "null", - "string" - ] - }, - "jwtSecret": { - "type": "string" - }, - "requestSignature": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "ConnectedAccount": { - "properties": { - "access_token": { - "type": "string" - }, - "construct": { - }, - "friend_sync": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "revoked": { - "type": "boolean" - }, - "show_activity": { - "type": "boolean" - }, - "type": { - "type": "string" - }, - "verifie": { - "type": "boolean" - }, - "visibility": { - "type": "number" - } - }, - "type": "object" - }, - "EVENT": { - "enum": [ - "APPLICATION_COMMAND_CREATE", - "APPLICATION_COMMAND_DELETE", - "APPLICATION_COMMAND_UPDATE", - "CHANNEL_CREATE", - "CHANNEL_DELETE", - "CHANNEL_PINS_UPDATE", - "CHANNEL_UPDATE", - "GUILD_BAN_ADD", - "GUILD_BAN_REMOVE", - "GUILD_CREATE", - "GUILD_DELETE", - "GUILD_EMOJI_UPDATE", - "GUILD_INTEGRATIONS_UPDATE", - "GUILD_MEMBERS_CHUNK", - "GUILD_MEMBER_ADD", - "GUILD_MEMBER_REMOVE", - "GUILD_MEMBER_SPEAKING", - "GUILD_MEMBER_UPDATE", - "GUILD_ROLE_CREATE", - "GUILD_ROLE_DELETE", - "GUILD_ROLE_UPDATE", - "GUILD_UPDATE", - "INTERACTION_CREATE", - "INVALIDATED", - "INVITE_CREATE", - "INVITE_DELETE", - "MESSAGE_ACK", - "MESSAGE_CREATE", - "MESSAGE_DELETE", - "MESSAGE_DELETE_BULK", - "MESSAGE_REACTION_ADD", - "MESSAGE_REACTION_REMOVE", - "MESSAGE_REACTION_REMOVE_ALL", - "MESSAGE_REACTION_REMOVE_EMOJI", - "MESSAGE_UPDATE", - "PRESENCE_UPDATE", - "READY", - "RELATIONSHIP_ADD", - "RELATIONSHIP_REMOVE", - "TYPING_START", - "USER_UPDATE", - "VOICE_SERVER_UPDATE", - "VOICE_STATE_UPDATE", - "WEBHOOKS_UPDATE" - ], - "type": "string" - }, - "EVENTEnum": { - "enum": [ - "APPLICATION_COMMAND_CREATE", - "APPLICATION_COMMAND_DELETE", - "APPLICATION_COMMAND_UPDATE", - "CHANNEL_CREATE", - "CHANNEL_DELETE", - "CHANNEL_PINS_UPDATE", - "CHANNEL_UPDATE", - "GUILD_BAN_ADD", - "GUILD_BAN_REMOVE", - "GUILD_CREATE", - "GUILD_DELETE", - "GUILD_EMOJI_UPDATE", - "GUILD_INTEGRATIONS_UPDATE", - "GUILD_MEMBERS_CHUNK", - "GUILD_MEMBER_ADD", - "GUILD_MEMBER_REMOVE", - "GUILD_MEMBER_SPEAKING", - "GUILD_MEMBER_UPDATE", - "GUILD_ROLE_CREATE", - "GUILD_ROLE_DELETE", - "GUILD_ROLE_UPDATE", - "GUILD_UPDATE", - "INTERACTION_CREATE", - "INVITE_CREATE", - "INVITE_DELETE", - "MESSAGE_CREATE", - "MESSAGE_DELETE", - "MESSAGE_DELETE_BULK", - "MESSAGE_REACTION_ADD", - "MESSAGE_REACTION_REMOVE", - "MESSAGE_REACTION_REMOVE_ALL", - "MESSAGE_REACTION_REMOVE_EMOJI", - "MESSAGE_UPDATE", - "PRESENCE_UPDATE", - "READY", - "TYPING_START", - "USER_UPDATE", - "VOICE_SERVER_UPDATE", - "VOICE_STATE_UPDATE", - "WEBHOOKS_UPDATE" - ], - "type": "string" - }, - "Embed": { - "properties": { - "author": { - "properties": { - "icon_url": { - "type": "string" - }, - "name": { - "type": "string" - }, - "proxy_icon_url": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "type": "object" - }, - "color": { - "type": "number" - }, - "description": { - "type": "string" - }, - "fields": { - "items": { - "properties": { - "inline": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "footer": { - "properties": { - "icon_url": { - "type": "string" - }, - "proxy_icon_url": { - "type": "string" - }, - "text": { - "type": "string" - } - }, - "type": "object" - }, - "image": { - "$ref": "#/definitions/EmbedImage" - }, - "provider": { - "properties": { - "name": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "type": "object" - }, - "thumbnail": { - "$ref": "#/definitions/EmbedImage" - }, - "timestamp": { - "format": "date-time", - "type": "string" - }, - "title": { - "type": "string" - }, - "type": { - "enum": [ - "article", - "gifv", - "image", - "link", - "rich", - "video" - ], - "type": "string" - }, - "url": { - "type": "string" - }, - "video": { - "$ref": "#/definitions/EmbedImage" - } - }, - "type": "object" - }, - "EmbedImage": { - "properties": { - "height": { - "type": "number" - }, - "proxy_url": { - "type": "string" - }, - "url": { - "type": "string" - }, - "width": { - "type": "number" - } - }, - "type": "object" - }, - "EmbedType": { - "enum": [ - "article", - "gifv", - "image", - "link", - "rich", - "video" - ], - "type": "string" - }, - "Emoji": { - "properties": { - "animated": { - "type": "boolean" - }, - "available": { - "type": "boolean" - }, - "construct": { - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "managed": { - "type": "boolean" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "require_colons": { - "type": "boolean" - }, - "role_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "roles": { - "items": { - "$ref": "#/definitions/Role" - }, - "type": "array" - }, - "url": { - "type": "string" - } - }, - "type": "object" - }, - "Event": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - }, - "event": { - "$ref": "#/definitions/EVENT" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "EventOpts": { - "properties": { - "acknowledge": { - "$ref": "#/definitions/Function" - }, - "cancel": { - "$ref": "#/definitions/Function" - }, - "channel": { - "$ref": "#/definitions/Channel_1" - }, - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - }, - "event": { - "$ref": "#/definitions/EVENT" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "Function": { - "properties": { - "arguments": { - }, - "caller": { - "$ref": "#/definitions/Function" - }, - "length": { - "type": "number" - }, - "name": { - "type": "string" - }, - "prototype": { - } - }, - "type": "object" - }, - "Guild": { - "properties": { - "afk_channel": { - "$ref": "#/definitions/Channel" - }, - "afk_channel_id": { - "type": "string" - }, - "afk_timeout": { - "type": "number" - }, - "banner": { - "type": "string" - }, - "channel_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "channels": { - "items": { - "$ref": "#/definitions/Channel" - }, - "type": "array" - }, - "construct": { - }, - "default_message_notifications": { - "type": "number" - }, - "description": { - "type": "string" - }, - "discovery_splash": { - "type": "string" - }, - "emoji_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "emojis": { - "items": { - "$ref": "#/definitions/Emoji" - }, - "type": "array" - }, - "explicit_content_filter": { - "type": "number" - }, - "features": { - "items": { - "type": "string" - }, - "type": "array" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string" - }, - "large": { - "type": "boolean" - }, - "max_members": { - "type": "number" - }, - "max_presences": { - "type": "number" - }, - "max_video_channel_users": { - "type": "number" - }, - "member_count": { - "type": "number" - }, - "member_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "members": { - "items": { - "$ref": "#/definitions/Member" - }, - "type": "array" - }, - "metadata": { - }, - "mfa_level": { - "type": "number" - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "owner": { - "$ref": "#/definitions/User" - }, - "owner_id": { - "type": "string" - }, - "preferred_locale": { - "type": "string" - }, - "premium_subscription_count": { - "type": "number" - }, - "premium_tier": { - "type": "number" - }, - "presence_count": { - "type": "number" - }, - "public_updates_channel": { - "$ref": "#/definitions/Channel" - }, - "public_updates_channel_id": { - "type": "string" - }, - "region": { - "type": "string" - }, - "role_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "roles": { - "items": { - "$ref": "#/definitions/Role" - }, - "type": "array" - }, - "rules_channel": { - "type": "string" - }, - "rules_channel_id": { - "type": "string" - }, - "splash": { - "type": "string" - }, - "system_channel": { - "$ref": "#/definitions/Channel" - }, - "system_channel_flags": { - "type": "number" - }, - "system_channel_id": { - "type": "string" - }, - "unavailable": { - "type": "boolean" - }, - "vanity_url": { - "$ref": "#/definitions/Invite" - }, - "vanity_url_code": { - "type": "string" - }, - "verification_level": { - "type": "number" - }, - "voice_state_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "voice_states": { - "items": { - "$ref": "#/definitions/VoiceState" - }, - "type": "array" - }, - "welcome_screen": { - "properties": { - "description": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "welcome_channels": { - "items": { - "properties": { - "channel_id": { - "type": "string" - }, - "description": { - "type": "string" - }, - "emoji_id": { - "type": "string" - }, - "emoji_name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "widget_channel": { - "$ref": "#/definitions/Channel" - }, - "widget_channel_id": { - "type": "string" - }, - "widget_enabled": { - "type": "boolean" - } - }, - "type": "object" - }, - "GuildBanAddEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/User" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_BAN_ADD" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildBanRemoveEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/User" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_BAN_REMOVE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildCreateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Guild" - }, - "event": { - "enum": [ - "GUILD_CREATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildDeleteEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "id": { - "type": "string" - }, - "unavailable": { - "type": "boolean" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_DELETE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildEmojiUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "emojis": { - "items": { - "$ref": "#/definitions/Emoji" - }, - "type": "array" - }, - "guild_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_EMOJI_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildIntegrationUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_INTEGRATIONS_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildMemberAddEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/PublicMember" - }, - { - "properties": { - "guild_id": { - "type": "string" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "GUILD_MEMBER_ADD" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildMemberRemoveEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/User" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_MEMBER_REMOVE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildMemberUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - }, - "joined_at": { - "format": "date-time", - "type": "string" - }, - "nick": { - "type": "string" - }, - "pending": { - "type": "boolean" - }, - "premium_since": { - "type": "number" - }, - "roles": { - "items": { - "type": "string" - }, - "type": "array" - }, - "user": { - "$ref": "#/definitions/User" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_MEMBER_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildMembersChunkEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "chunk_count": { - "type": "number" - }, - "chunk_index": { - "type": "number" - }, - "guild_id": { - "type": "string" - }, - "members": { - "items": { - "$ref": "#/definitions/PublicMember" - }, - "type": "array" - }, - "nonce": { - "type": "string" - }, - "not_found": { - "items": { - "type": "string" - }, - "type": "array" - }, - "presences": { - "items": { - "$ref": "#/definitions/Presence" - }, - "type": "array" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_MEMBERS_CHUNK" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildRoleCreateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - }, - "role": { - "$ref": "#/definitions/Role" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_ROLE_CREATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildRoleDeleteEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - }, - "role_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_ROLE_DELETE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildRoleUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "guild_id": { - "type": "string" - }, - "role": { - "$ref": "#/definitions/Role" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "GUILD_ROLE_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "GuildUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Guild" - }, - "event": { - "enum": [ - "GUILD_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "Intents": { - "properties": { - "bitfield": { - "type": "bigint" - } - }, - "type": "object" - }, - "Interaction": { - "properties": { - "channel_id": { - "type": "string" - }, - "data": { - "properties": { - }, - "type": "object" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "member_id": { - "type": "string" - }, - "token": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/InteractionType" - }, - "version": { - "type": "number" - } - }, - "type": "object" - }, - "InteractionApplicationCommandCallbackData": { - "properties": { - "allowed_mentions": { - "$ref": "#/definitions/AllowedMentions" - }, - "content": { - "type": "string" - }, - "embeds": { - "items": { - "$ref": "#/definitions/Embed" - }, - "type": "array" - }, - "tts": { - "type": "boolean" - } - }, - "type": "object" - }, - "InteractionCreateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Interaction" - }, - "event": { - "enum": [ - "INTERACTION_CREATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "InteractionResponseType": { - "enum": [ - 1, - 2, - 3, - 4, - 5 - ], - "type": "number" - }, - "InteractionType": { - "enum": [ - 1, - 2 - ], - "type": "number" - }, - "InvalidatedEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - }, - "event": { - "enum": [ - "INVALIDATED" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "Invite": { - "properties": { - "channel": { - "$ref": "#/definitions/Channel" - }, - "channel_id": { - "type": "string" - }, - "code": { - "type": "string" - }, - "construct": { - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "expires_at": { - "format": "date-time", - "type": "string" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "inviter": { - "$ref": "#/definitions/User" - }, - "inviter_id": { - "type": "string" - }, - "max_age": { - "type": "number" - }, - "max_uses": { - "type": "number" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "target_user": { - "type": "string" - }, - "target_user_id": { - "type": "string" - }, - "target_user_type": { - "type": "number" - }, - "temporary": { - "type": "boolean" - }, - "uses": { - "type": "number" - } - }, - "type": "object" - }, - "InviteCreateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/Omit<Invite,\"guild\"|\"channel\">" - }, - { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "INVITE_CREATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "InviteDeleteEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "code": { - "type": "string" - }, - "guild_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "INVITE_DELETE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "KafkaBroker": { - "properties": { - "ip": { - "type": "string" - }, - "port": { - "type": "number" - } - }, - "type": "object" - }, - "ListenEventOpts": { - "properties": { - "acknowledge": { - "type": "boolean" - }, - "channel": { - "$ref": "#/definitions/Channel_1" - } - }, - "type": "object" - }, - "Member": { - "properties": { - "construct": { - }, - "deaf": { - "type": "boolean" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "joined_at": { - "format": "date-time", - "type": "string" - }, - "metadata": { - }, - "mute": { - "type": "boolean" - }, - "nick": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "pending": { - "type": "boolean" - }, - "premium_since": { - "type": "number" - }, - "read_state": { - "$ref": "#/definitions/Record<string,string|null>" - }, - "roles": { - "items": { - "type": "string" - }, - "type": "array" - }, - "settings": { - "$ref": "#/definitions/UserGuildSettings" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "Message": { - "properties": { - "activity": { - "properties": { - "party_id": { - "type": "string" - }, - "type": { - "type": "number" - } - }, - "type": "object" - }, - "application": { - "$ref": "#/definitions/Application" - }, - "application_id": { - "type": "string" - }, - "attachments": { - "items": { - "$ref": "#/definitions/Attachment" - }, - "type": "array" - }, - "author": { - "$ref": "#/definitions/User" - }, - "author_id": { - "type": "string" - }, - "channel": { - "$ref": "#/definitions/Channel" - }, - "channel_id": { - "type": "string" - }, - "components": { - "items": { - "$ref": "#/definitions/MessageComponent" - }, - "type": "array" - }, - "construct": { - }, - "content": { - "type": "string" - }, - "edited_timestamp": { - "format": "date-time", - "type": "string" - }, - "embeds": { - "items": { - "$ref": "#/definitions/Embed" - }, - "type": "array" - }, - "flags": { - "type": "bigint" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "interaction": { - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/InteractionType" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "member": { - "$ref": "#/definitions/Member" - }, - "member_id": { - "type": "string" - }, - "mention_channel_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "mention_channels": { - "items": { - "$ref": "#/definitions/Channel" - }, - "type": "array" - }, - "mention_everyone": { - "type": "boolean" - }, - "mention_role_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "mention_roles": { - "items": { - "$ref": "#/definitions/Role" - }, - "type": "array" - }, - "mention_user_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "mention_users": { - "items": { - "$ref": "#/definitions/User" - }, - "type": "array" - }, - "message_reference": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "message_id": { - "type": "string" - } - }, - "type": "object" - }, - "metadata": { - }, - "nonce": { - "type": [ - "string", - "number" - ] - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "pinned": { - "type": "boolean" - }, - "reactions": { - "items": { - "$ref": "#/definitions/Reaction" - }, - "type": "array" - }, - "stickers": { - "items": { - }, - "type": "array" - }, - "timestamp": { - "format": "date-time", - "type": "string" - }, - "tts": { - "type": "boolean" - }, - "type": { - "$ref": "#/definitions/MessageType" - }, - "webhook": { - "$ref": "#/definitions/Webhook" - }, - "webhook_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageAckEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "manual": { - "type": "boolean" - }, - "mention_count": { - "type": "number" - }, - "message_id": { - "type": "string" - }, - "version": { - "type": "number" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "MESSAGE_ACK" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageComponent": { - "properties": { - "components": { - "items": { - "$ref": "#/definitions/MessageComponent" - }, - "type": "array" - }, - "custom_id": { - "type": "string" - }, - "disabled": { - "type": "boolean" - }, - "emoji": { - "$ref": "#/definitions/PartialEmoji" - }, - "label": { - "type": "string" - }, - "style": { - "type": "number" - }, - "type": { - "type": "number" - }, - "url": { - "type": "string" - } - }, - "type": "object" - }, - "MessageComponentType": { - "enum": [ - 1, - 2 - ], - "type": "number" - }, - "MessageCreateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/Omit<Message,\"author_id\">" - }, - { - "properties": { - "author": { - "$ref": "#/definitions/PublicUser" - }, - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "member": { - "$ref": "#/definitions/PublicMember" - }, - "mentions": { - "items": { - "allOf": [ - { - "$ref": "#/definitions/PublicUser" - }, - { - "properties": { - "member": { - "$ref": "#/definitions/PublicMember" - } - }, - "type": "object" - } - ] - }, - "type": "array" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "MESSAGE_CREATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageDeleteBulkEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "ids": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "MESSAGE_DELETE_BULK" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageDeleteEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "MESSAGE_DELETE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageFlags": { - "properties": { - "bitfield": { - "type": "bigint" - } - }, - "type": "object" - }, - "MessagePayload": { - "allOf": [ - { - "$ref": "#/definitions/Omit<Message,\"author_id\">" - }, - { - "properties": { - "author": { - "$ref": "#/definitions/PublicUser" - }, - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "member": { - "$ref": "#/definitions/PublicMember" - }, - "mentions": { - "items": { - "allOf": [ - { - "$ref": "#/definitions/PublicUser" - }, - { - "properties": { - "member": { - "$ref": "#/definitions/PublicMember" - } - }, - "type": "object" - } - ] - }, - "type": "array" - } - }, - "type": "object" - } - ] - }, - "MessageReactionAddEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "emoji": { - "$ref": "#/definitions/PartialEmoji" - }, - "guild_id": { - "type": "string" - }, - "member": { - "$ref": "#/definitions/PublicMember" - }, - "message_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "MESSAGE_REACTION_ADD" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageReactionRemoveAllEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "message_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "MESSAGE_REACTION_REMOVE_ALL" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageReactionRemoveEmojiEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "emoji": { - "$ref": "#/definitions/PartialEmoji" - }, - "guild_id": { - "type": "string" - }, - "message_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "MESSAGE_REACTION_REMOVE_EMOJI" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageReactionRemoveEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "emoji": { - "$ref": "#/definitions/PartialEmoji" - }, - "guild_id": { - "type": "string" - }, - "message_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "MESSAGE_REACTION_REMOVE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MessageType": { - "enum": [ - 0, - 1, - 10, - 11, - 12, - 14, - 15, - 19, - 2, - 20, - 3, - 4, - 5, - 6, - 7, - 8, - 9 - ], - "type": "number" - }, - "MessageUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/Omit<Message,\"author_id\">" - }, - { - "properties": { - "author": { - "$ref": "#/definitions/PublicUser" - }, - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "member": { - "$ref": "#/definitions/PublicMember" - }, - "mentions": { - "items": { - "allOf": [ - { - "$ref": "#/definitions/PublicUser" - }, - { - "properties": { - "member": { - "$ref": "#/definitions/PublicMember" - } - }, - "type": "object" - } - ] - }, - "type": "array" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "MESSAGE_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "MuteConfig": { - "properties": { - "end_time": { - "type": "number" - }, - "selected_time_window": { - "type": "number" - } - }, - "type": "object" - }, - "Omit<Invite,\"guild\"|\"channel\">": { - "properties": { - "assign": { - "type": "object" - }, - "channel_id": { - "type": "string" - }, - "code": { - "type": "string" - }, - "construct": { - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "expires_at": { - "format": "date-time", - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "hasId": { - "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", - "type": "object" - }, - "id": { - "type": "string" - }, - "inviter": { - "$ref": "#/definitions/User" - }, - "inviter_id": { - "type": "string" - }, - "max_age": { - "type": "number" - }, - "max_uses": { - "type": "number" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "recover": { - "description": "Recovers a given entity in the database.", - "type": "object" - }, - "reload": { - "description": "Reloads entity data from the database.", - "type": "object" - }, - "remove": { - "description": "Removes current entity from the database.", - "type": "object" - }, - "save": { - "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", - "type": "object" - }, - "softRemove": { - "description": "Records the delete date of current entity.", - "type": "object" - }, - "target_user": { - "type": "string" - }, - "target_user_id": { - "type": "string" - }, - "target_user_type": { - "type": "number" - }, - "temporary": { - "type": "boolean" - }, - "toJSON": { - "type": "object" - }, - "uses": { - "type": "number" - }, - "validate": { - "type": "object" - } - }, - "type": "object" - }, - "Omit<Member,\"settings\"|\"user\">": { - "properties": { - "assign": { - "type": "object" - }, - "construct": { - }, - "deaf": { - "type": "boolean" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "hasId": { - "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", - "type": "object" - }, - "id": { - "type": "string" - }, - "joined_at": { - "format": "date-time", - "type": "string" - }, - "metadata": { - }, - "mute": { - "type": "boolean" - }, - "nick": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "pending": { - "type": "boolean" - }, - "premium_since": { - "type": "number" - }, - "read_state": { - "$ref": "#/definitions/Record<string,string|null>" - }, - "recover": { - "description": "Recovers a given entity in the database.", - "type": "object" - }, - "reload": { - "description": "Reloads entity data from the database.", - "type": "object" - }, - "remove": { - "description": "Removes current entity from the database.", - "type": "object" - }, - "roles": { - "items": { - "type": "string" - }, - "type": "array" - }, - "save": { - "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", - "type": "object" - }, - "softRemove": { - "description": "Records the delete date of current entity.", - "type": "object" - }, - "toJSON": { - "type": "object" - }, - "user_id": { - "type": "string" - }, - "validate": { - "type": "object" - } - }, - "type": "object" - }, - "Omit<Message,\"author_id\">": { - "properties": { - "activity": { - "properties": { - "party_id": { - "type": "string" - }, - "type": { - "type": "number" - } - }, - "type": "object" - }, - "application": { - "$ref": "#/definitions/Application" - }, - "application_id": { - "type": "string" - }, - "assign": { - "type": "object" - }, - "attachments": { - "items": { - "$ref": "#/definitions/Attachment" - }, - "type": "array" - }, - "author": { - "$ref": "#/definitions/User" - }, - "channel": { - "$ref": "#/definitions/Channel" - }, - "channel_id": { - "type": "string" - }, - "components": { - "items": { - "$ref": "#/definitions/MessageComponent" - }, - "type": "array" - }, - "construct": { - }, - "content": { - "type": "string" - }, - "edited_timestamp": { - "format": "date-time", - "type": "string" - }, - "embeds": { - "items": { - "$ref": "#/definitions/Embed" - }, - "type": "array" - }, - "flags": { - "type": "bigint" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "hasId": { - "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", - "type": "object" - }, - "id": { - "type": "string" - }, - "interaction": { - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/InteractionType" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "member": { - "$ref": "#/definitions/Member" - }, - "member_id": { - "type": "string" - }, - "mention_channel_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "mention_channels": { - "items": { - "$ref": "#/definitions/Channel" - }, - "type": "array" - }, - "mention_everyone": { - "type": "boolean" - }, - "mention_role_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "mention_roles": { - "items": { - "$ref": "#/definitions/Role" - }, - "type": "array" - }, - "mention_user_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "mention_users": { - "items": { - "$ref": "#/definitions/User" - }, - "type": "array" - }, - "message_reference": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "message_id": { - "type": "string" - } - }, - "type": "object" - }, - "metadata": { - }, - "nonce": { - "type": [ - "string", - "number" - ] - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "pinned": { - "type": "boolean" - }, - "reactions": { - "items": { - "$ref": "#/definitions/Reaction" - }, - "type": "array" - }, - "recover": { - "description": "Recovers a given entity in the database.", - "type": "object" - }, - "reload": { - "description": "Reloads entity data from the database.", - "type": "object" - }, - "remove": { - "description": "Removes current entity from the database.", - "type": "object" - }, - "save": { - "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", - "type": "object" - }, - "softRemove": { - "description": "Records the delete date of current entity.", - "type": "object" - }, - "stickers": { - "items": { - }, - "type": "array" - }, - "timestamp": { - "format": "date-time", - "type": "string" - }, - "toJSON": { - "type": "object" - }, - "tts": { - "type": "boolean" - }, - "type": { - "$ref": "#/definitions/MessageType" - }, - "validate": { - "type": "object" - }, - "webhook": { - "$ref": "#/definitions/Webhook" - }, - "webhook_id": { - "type": "string" - } - }, - "type": "object" - }, - "Omit<RateLimitOptions,\"bot_count\">": { - "properties": { - "bot": { - "type": "number" - }, - "count": { - "type": "number" - }, - "onyIp": { - "type": "boolean" - }, - "window": { - "type": "number" - } - }, - "type": "object" - }, - "Omit<Relationship,\"nickname\">": { - "properties": { - "assign": { - "type": "object" - }, - "construct": { - }, - "hasId": { - "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", - "type": "object" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "recover": { - "description": "Recovers a given entity in the database.", - "type": "object" - }, - "reload": { - "description": "Reloads entity data from the database.", - "type": "object" - }, - "remove": { - "description": "Removes current entity from the database.", - "type": "object" - }, - "save": { - "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", - "type": "object" - }, - "softRemove": { - "description": "Records the delete date of current entity.", - "type": "object" - }, - "toJSON": { - "type": "object" - }, - "type": { - "$ref": "#/definitions/RelationshipType" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - }, - "validate": { - "type": "object" - } - }, - "type": "object" - }, - "PartialEmoji": { - "properties": { - "animated": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "PermissionCache": { - "properties": { - "channel": { - "anyOf": [ - { - "$ref": "#/definitions/Channel" - }, - { - "type": "null" - } - ] - }, - "guild": { - "anyOf": [ - { - "$ref": "#/definitions/Guild" - }, - { - "type": "null" - } - ] - }, - "member": { - "anyOf": [ - { - "$ref": "#/definitions/Member" - }, - { - "type": "null" - } - ] - }, - "roles": { - "anyOf": [ - { - "items": { - "$ref": "#/definitions/Role" - }, - "type": "array" - }, - { - "type": "null" - } - ] - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "PermissionResolvable": { - "anyOf": [ - { - "$ref": "#/definitions/Permissions" - }, - { - "items": { - "$ref": "#/definitions/PermissionResolvable" - }, - "type": "array" - }, - { - "enum": [ - "ADD_REACTIONS", - "ADMINISTRATOR", - "ATTACH_FILES", - "BAN_MEMBERS", - "CHANGE_NICKNAME", - "CONNECT", - "CREATE_INSTANT_INVITE", - "DEAFEN_MEMBERS", - "EMBED_LINKS", - "KICK_MEMBERS", - "MANAGE_CHANNELS", - "MANAGE_EMOJIS_AND_STICKERS", - "MANAGE_GUILD", - "MANAGE_MESSAGES", - "MANAGE_NICKNAMES", - "MANAGE_ROLES", - "MANAGE_WEBHOOKS", - "MENTION_EVERYONE", - "MOVE_MEMBERS", - "MUTE_MEMBERS", - "PRIORITY_SPEAKER", - "READ_MESSAGE_HISTORY", - "SEND_MESSAGES", - "SEND_TTS_MESSAGES", - "SPEAK", - "STREAM", - "USE_EXTERNAL_EMOJIS", - "USE_VAD", - "VIEW_AUDIT_LOG", - "VIEW_CHANNEL", - "VIEW_GUILD_INSIGHTS" - ], - "type": "string" - }, - { - "type": [ - "number", - "bigint" - ] - } - ] - }, - "PermissionString": { - "enum": [ - "ADD_REACTIONS", - "ADMINISTRATOR", - "ATTACH_FILES", - "BAN_MEMBERS", - "CHANGE_NICKNAME", - "CONNECT", - "CREATE_INSTANT_INVITE", - "DEAFEN_MEMBERS", - "EMBED_LINKS", - "KICK_MEMBERS", - "MANAGE_CHANNELS", - "MANAGE_EMOJIS_AND_STICKERS", - "MANAGE_GUILD", - "MANAGE_MESSAGES", - "MANAGE_NICKNAMES", - "MANAGE_ROLES", - "MANAGE_WEBHOOKS", - "MENTION_EVERYONE", - "MOVE_MEMBERS", - "MUTE_MEMBERS", - "PRIORITY_SPEAKER", - "READ_MESSAGE_HISTORY", - "SEND_MESSAGES", - "SEND_TTS_MESSAGES", - "SPEAK", - "STREAM", - "USE_EXTERNAL_EMOJIS", - "USE_VAD", - "VIEW_AUDIT_LOG", - "VIEW_CHANNEL", - "VIEW_GUILD_INSIGHTS" - ], - "type": "string" - }, - "Permissions": { - "properties": { - "bitfield": { - "type": "bigint" - }, - "cache": { - "properties": { - "channel": { - "anyOf": [ - { - "$ref": "#/definitions/Channel" - }, - { - "type": "null" - } - ] - }, - "guild": { - "anyOf": [ - { - "$ref": "#/definitions/Guild" - }, - { - "type": "null" - } - ] - }, - "member": { - "anyOf": [ - { - "$ref": "#/definitions/Member" - }, - { - "type": "null" - } - ] - }, - "roles": { - "anyOf": [ - { - "items": { - "$ref": "#/definitions/Role" - }, - "type": "array" - }, - { - "type": "null" - } - ] - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "Presence": { - "properties": { - "activities": { - "items": { - "$ref": "#/definitions/Activity" - }, - "type": "array" - }, - "client_status": { - "$ref": "#/definitions/ClientStatus" - }, - "guild_id": { - "type": "string" - }, - "status": { - "$ref": "#/definitions/Status" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "PresenceUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Presence" - }, - "event": { - "enum": [ - "PRESENCE_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "PublicMember": { - "properties": { - "assign": { - "type": "object" - }, - "construct": { - }, - "deaf": { - "type": "boolean" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "hasId": { - "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", - "type": "object" - }, - "joined_at": { - "format": "date-time", - "type": "string" - }, - "metadata": { - }, - "mute": { - "type": "boolean" - }, - "nick": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "pending": { - "type": "boolean" - }, - "premium_since": { - "type": "number" - }, - "recover": { - "description": "Recovers a given entity in the database.", - "type": "object" - }, - "reload": { - "description": "Reloads entity data from the database.", - "type": "object" - }, - "remove": { - "description": "Removes current entity from the database.", - "type": "object" - }, - "roles": { - "items": { - "type": "string" - }, - "type": "array" - }, - "save": { - "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", - "type": "object" - }, - "softRemove": { - "description": "Records the delete date of current entity.", - "type": "object" - }, - "toJSON": { - "type": "object" - }, - "user": { - "$ref": "#/definitions/PublicUser" - }, - "user_id": { - "type": "string" - }, - "validate": { - "type": "object" - } - }, - "type": "object" - }, - "PublicUser": { - "properties": { - "accent_color": { - "type": "number" - }, - "avatar": { - "type": "string" - }, - "banner": { - "type": "string" - }, - "bot": { - "type": "boolean" - }, - "discriminator": { - "type": "string" - }, - "id": { - "type": "string" - }, - "public_flags": { - "type": "bigint" - }, - "username": { - "type": "string" - } - }, - "type": "object" - }, - "RateLimit": { - "properties": { - "blocked": { - "type": "boolean" - }, - "construct": { - }, - "expires_at": { - "format": "date-time", - "type": "string" - }, - "hits": { - "type": "number" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "RateLimitOptions": { - "properties": { - "bot": { - "type": "number" - }, - "count": { - "type": "number" - }, - "onyIp": { - "type": "boolean" - }, - "window": { - "type": "number" - } - }, - "type": "object" - }, - "Reaction": { - "properties": { - "count": { - "type": "number" - }, - "emoji": { - "$ref": "#/definitions/PartialEmoji" - }, - "user_ids": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "ReadState": { - "properties": { - "channel": { - "$ref": "#/definitions/Channel" - }, - "channel_id": { - "type": "string" - }, - "construct": { - }, - "id": { - "type": "string" - }, - "last_message": { - "$ref": "#/definitions/Message" - }, - "last_message_id": { - "type": "string" - }, - "last_pin_timestamp": { - "format": "date-time", - "type": "string" - }, - "manual": { - "type": "boolean" - }, - "mention_count": { - "type": "number" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "ReadyEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/ReadyEventData" - }, - "event": { - "enum": [ - "READY" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "ReadyEventData": { - "properties": { - "analytics_token": { - "type": "string" - }, - "application": { - "properties": { - "flags": { - "type": "bigint" - }, - "id": { - "type": "string" - } - }, - "type": "object" - }, - "connected_accounts": { - "items": { - "$ref": "#/definitions/ConnectedAccount" - }, - "type": "array" - }, - "consents": { - "properties": { - "personalization": { - "properties": { - "consented": { - "type": "boolean" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "country_code": { - "type": "string" - }, - "experiments": { - "items": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - }, - { - "type": "number" - }, - { - "type": "number" - }, - { - "type": "number" - } - ], - "maxItems": 5, - "minItems": 5, - "type": "array" - }, - "type": "array" - }, - "friend_suggestion_count": { - "type": "number" - }, - "geo_ordered_rtc_regions": { - "items": { - "type": "string" - }, - "type": "array" - }, - "guild_experiments": { - "items": { - "items": [ - { - "type": "number" - }, - { - "type": "null" - }, - { - "type": "number" - }, - { - "items": [ - { - "items": [ - { - "type": "number" - }, - { - "items": { - "properties": { - "e": { - "type": "number" - }, - "s": { - "type": "number" - } - }, - "type": "object" - }, - "type": "array" - } - ], - "maxItems": 2, - "minItems": 2, - "type": "array" - } - ], - "maxItems": 1, - "minItems": 1, - "type": "array" - }, - { - "items": [ - { - "type": "number" - }, - { - "items": [ - { - "items": [ - { - "type": "number" - }, - { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "maxItems": 2, - "minItems": 2, - "type": "array" - } - ], - "maxItems": 2, - "minItems": 2, - "type": "array" - } - ], - "maxItems": 1, - "minItems": 1, - "type": "array" - } - ], - "maxItems": 2, - "minItems": 2, - "type": "array" - }, - { - "items": { - "properties": { - "b": { - "type": "number" - }, - "k": { - "items": { - "type": "bigint" - }, - "type": "array" - } - }, - "type": "object" - }, - "type": "array" - } - ], - "maxItems": 6, - "minItems": 6, - "type": "array" - }, - "type": "array" - }, - "guild_join_requests": { - "items": { - }, - "type": "array" - }, - "guilds": { - "items": { - "$ref": "#/definitions/Guild" - }, - "type": "array" - }, - "merged_members": { - "items": { - "items": { - "$ref": "#/definitions/Omit<Member,\"settings\"|\"user\">" - }, - "type": "array" - }, - "type": "array" - }, - "private_channels": { - "items": { - "$ref": "#/definitions/Channel" - }, - "type": "array" - }, - "read_state": { - "properties": { - "entries": { - "items": { - }, - "type": "array" - }, - "partial": { - "type": "boolean" - }, - "version": { - "type": "number" - } - }, - "type": "object" - }, - "relationships": { - "items": { - "$ref": "#/definitions/Relationship" - }, - "type": "array" - }, - "session_id": { - "type": "string" - }, - "shard": { - "items": [ - { - "type": "number" - }, - { - "type": "number" - } - ], - "maxItems": 2, - "minItems": 2, - "type": "array" - }, - "user": { - "allOf": [ - { - "$ref": "#/definitions/PublicUser" - }, - { - "properties": { - "bot": { - "type": "boolean" - }, - "desktop": { - "type": "boolean" - }, - "email": { - "type": [ - "null", - "string" - ] - }, - "flags": { - "type": "bigint" - }, - "mfa_enabled": { - "type": "boolean" - }, - "mobile": { - "type": "boolean" - }, - "nsfw_allowed": { - "type": "boolean" - }, - "phone": { - "type": [ - "null", - "string" - ] - }, - "premium": { - "type": "boolean" - }, - "premium_type": { - "type": "number" - }, - "verified": { - "type": "boolean" - } - }, - "type": "object" - } - ] - }, - "user_guild_settings": { - "properties": { - "entries": { - "items": { - "$ref": "#/definitions/UserGuildSettings" - }, - "type": "array" - }, - "partial": { - "type": "boolean" - }, - "version": { - "type": "number" - } - }, - "type": "object" - }, - "user_settings": { - "$ref": "#/definitions/UserSettings" - }, - "users": { - "items": { - "properties": { - "avatar": { - "type": [ - "null", - "string" - ] - }, - "bot": { - "type": "boolean" - }, - "discriminator": { - "type": "string" - }, - "id": { - "type": "string" - }, - "public_flags": { - "type": "bigint" - }, - "username": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "v": { - "type": "number" - } - }, - "type": "object" - }, - "Record<string,string|null>": { - "type": "object" - }, - "Region": { - "properties": { - "custom": { - "type": "boolean" - }, - "deprecated": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "optimal": { - "type": "boolean" - }, - "vip": { - "type": "boolean" - } - }, - "type": "object" - }, - "Relationship": { - "properties": { - "construct": { - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "nickname": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "type": { - "$ref": "#/definitions/RelationshipType" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "RelationshipAddEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/Relationship" - }, - { - "properties": { - "should_notify": { - "type": "boolean" - }, - "user": { - "$ref": "#/definitions/PublicUser" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "RELATIONSHIP_ADD" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "RelationshipRemoveEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/Omit<Relationship,\"nickname\">" - }, - "event": { - "enum": [ - "RELATIONSHIP_REMOVE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "RelationshipType": { - "enum": [ - 1, - 2, - 3, - 4 - ], - "type": "number" - }, - "Role": { - "properties": { - "color": { - "type": "number" - }, - "construct": { - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "hoist": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "managed": { - "type": "boolean" - }, - "mentionable": { - "type": "boolean" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "permissions": { - "type": "bigint" - }, - "position": { - "type": "number" - }, - "tags": { - "properties": { - "bot_id": { - "type": "string" - }, - "integration_id": { - "type": "string" - }, - "premium_subscriber": { - "type": "boolean" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "Snowflake": { - "description": "A container for useful snowflake-related methods.", - "type": "object" - }, - "Status": { - "enum": [ - "dnd", - "idle", - "offline", - "online" - ], - "type": "string" - }, - "Team": { - "properties": { - "construct": { - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string" - }, - "member_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "members": { - "items": { - "$ref": "#/definitions/TeamMember" - }, - "type": "array" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "owner_user": { - "$ref": "#/definitions/User" - }, - "owner_user_id": { - "type": "string" - } - }, - "type": "object" - }, - "TeamMember": { - "properties": { - "construct": { - }, - "id": { - "type": "string" - }, - "membership_state": { - "$ref": "#/definitions/TeamMemberState" - }, - "metadata": { - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "permissions": { - "items": { - "type": "string" - }, - "type": "array" - }, - "team": { - "$ref": "#/definitions/Team" - }, - "team_id": { - "type": "string" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "TeamMemberState": { - "enum": [ - 1, - 2 - ], - "type": "number" - }, - "Template": { - "properties": { - "code": { - "type": "string" - }, - "construct": { - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "creator": { - "$ref": "#/definitions/User" - }, - "creator_id": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "serialized_source_guild": { - "$ref": "#/definitions/Guild" - }, - "source_guild": { - "$ref": "#/definitions/Guild" - }, - "source_guild_id": { - "type": "string" - }, - "updated_at": { - "format": "date-time", - "type": "string" - }, - "usage_count": { - "type": "number" - } - }, - "type": "object" - }, - "TypingStartEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "member": { - "$ref": "#/definitions/PublicMember" - }, - "timestamp": { - "type": "number" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "TYPING_START" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "User": { - "properties": { - "accent_color": { - "type": "number" - }, - "avatar": { - "type": "string" - }, - "banner": { - "type": "string" - }, - "bio": { - "type": "string" - }, - "bot": { - "type": "boolean" - }, - "connected_account_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "connected_accounts": { - "items": { - "$ref": "#/definitions/ConnectedAccount" - }, - "type": "array" - }, - "construct": { - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "hash": { - "type": "string" - }, - "valid_tokens_since": { - "format": "date-time", - "type": "string" - } - }, - "type": "object" - }, - "deleted": { - "type": "boolean" - }, - "desktop": { - "type": "boolean" - }, - "disabled": { - "type": "boolean" - }, - "discriminator": { - "type": "string" - }, - "email": { - "type": "string" - }, - "fingerprints": { - "items": { - "type": "string" - }, - "type": "array" - }, - "flags": { - "type": "bigint" - }, - "guild_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "guilds": { - "items": { - "$ref": "#/definitions/Guild" - }, - "type": "array" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "mfa_enabled": { - "type": "boolean" - }, - "mobile": { - "type": "boolean" - }, - "nsfw_allowed": { - "type": "boolean" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "phone": { - "type": "string" - }, - "premium": { - "type": "boolean" - }, - "premium_type": { - "type": "number" - }, - "public_flags": { - "type": "bigint" - }, - "relationship_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "relationships": { - "items": { - "$ref": "#/definitions/Relationship" - }, - "type": "array" - }, - "settings": { - "$ref": "#/definitions/UserSettings" - }, - "system": { - "type": "boolean" - }, - "username": { - "type": "string" - }, - "verified": { - "type": "boolean" - } - }, - "type": "object" - }, - "UserFlags": { - "properties": { - "bitfield": { - "type": "bigint" - } - }, - "type": "object" - }, - "UserGuildSettings": { - "properties": { - "channel_overrides": { - "items": { - "properties": { - "channel_id": { - "type": "string" - }, - "message_notifications": { - "type": "number" - }, - "mute_config": { - "$ref": "#/definitions/MuteConfig" - }, - "muted": { - "type": "boolean" - } - }, - "type": "object" - }, - "type": "array" - }, - "message_notifications": { - "type": "number" - }, - "mobile_push": { - "type": "boolean" - }, - "mute_config": { - "$ref": "#/definitions/MuteConfig" - }, - "muted": { - "type": "boolean" - }, - "suppress_everyone": { - "type": "boolean" - }, - "suppress_roles": { - "type": "boolean" - }, - "version": { - "type": "number" - } - }, - "type": "object" - }, - "UserSettings": { - "properties": { - "afk_timeout": { - "type": "number" - }, - "allow_accessibility_detection": { - "type": "boolean" - }, - "animate_emoji": { - "type": "boolean" - }, - "animate_stickers": { - "type": "number" - }, - "contact_sync_enabled": { - "type": "boolean" - }, - "convert_emoticons": { - "type": "boolean" - }, - "custom_status": { - "properties": { - "emoji_id": { - "type": "string" - }, - "emoji_name": { - "type": "string" - }, - "expires_at": { - "type": "number" - }, - "text": { - "type": "string" - } - }, - "type": "object" - }, - "default_guilds_restricted": { - "type": "boolean" - }, - "detect_platform_accounts": { - "type": "boolean" - }, - "developer_mode": { - "type": "boolean" - }, - "disable_games_tab": { - "type": "boolean" - }, - "enable_tts_command": { - "type": "boolean" - }, - "explicit_content_filter": { - "type": "number" - }, - "friend_source_flags": { - "properties": { - "all": { - "type": "boolean" - } - }, - "type": "object" - }, - "gateway_connected": { - "type": "boolean" - }, - "gif_auto_play": { - "type": "boolean" - }, - "guild_folders": { - "items": { - "properties": { - "color": { - "type": "number" - }, - "guild_ids": { - "items": { - "type": "string" - }, - "type": "array" - }, - "id": { - "type": "number" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "guild_positions": { - "items": { - "type": "string" - }, - "type": "array" - }, - "inline_attachment_media": { - "type": "boolean" - }, - "inline_embed_media": { - "type": "boolean" - }, - "locale": { - "type": "string" - }, - "message_display_compact": { - "type": "boolean" - }, - "native_phone_integration_enabled": { - "type": "boolean" - }, - "render_embeds": { - "type": "boolean" - }, - "render_reactions": { - "type": "boolean" - }, - "restricted_guilds": { - "items": { - "type": "string" - }, - "type": "array" - }, - "show_current_game": { - "type": "boolean" - }, - "status": { - "enum": [ - "dnd", - "idle", - "offline", - "online" - ], - "type": "string" - }, - "stream_notifications_enabled": { - "type": "boolean" - }, - "theme": { - "enum": [ - "dark", - "white" - ], - "type": "string" - }, - "timezone_offset": { - "type": "number" - } - }, - "type": "object" - }, - "UserUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "$ref": "#/definitions/User" - }, - "event": { - "enum": [ - "USER_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "VoiceServerUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "endpoint": { - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "token": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "VOICE_SERVER_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "VoiceState": { - "properties": { - "channel": { - "$ref": "#/definitions/Channel" - }, - "channel_id": { - "type": "string" - }, - "construct": { - }, - "deaf": { - "type": "boolean" - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "mute": { - "type": "boolean" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "self_deaf": { - "type": "boolean" - }, - "self_mute": { - "type": "boolean" - }, - "self_stream": { - "type": "boolean" - }, - "self_video": { - "type": "boolean" - }, - "session_id": { - "type": "string" - }, - "suppress": { - "type": "boolean" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "VoiceStateUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "allOf": [ - { - "$ref": "#/definitions/VoiceState" - }, - { - "properties": { - "member": { - "$ref": "#/definitions/PublicMember" - } - }, - "type": "object" - } - ] - }, - "event": { - "enum": [ - "VOICE_STATE_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "Webhook": { - "properties": { - "application": { - "$ref": "#/definitions/Application" - }, - "application_id": { - "type": "string" - }, - "avatar": { - "type": "string" - }, - "channel": { - "$ref": "#/definitions/Channel" - }, - "channel_id": { - "type": "string" - }, - "construct": { - }, - "guild": { - "$ref": "#/definitions/Guild" - }, - "guild_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "metadata": { - }, - "name": { - "type": "string" - }, - "opts": { - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "source_guild": { - "$ref": "#/definitions/Guild" - }, - "source_guild_id": { - "type": "string" - }, - "token": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/WebhookType" - }, - "user": { - "$ref": "#/definitions/User" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - }, - "WebhookType": { - "enum": [ - 1, - 2 - ], - "type": "number" - }, - "WebhooksUpdateEvent": { - "properties": { - "channel_id": { - "type": "string" - }, - "created_at": { - "format": "date-time", - "type": "string" - }, - "data": { - "properties": { - "channel_id": { - "type": "string" - }, - "guild_id": { - "type": "string" - } - }, - "type": "object" - }, - "event": { - "enum": [ - "WEBHOOKS_UPDATE" - ], - "type": "string" - }, - "guild_id": { - "type": "string" - }, - "user_id": { - "type": "string" - } - }, - "type": "object" - } - } -} - diff --git a/util/src/interfaces/Event.ts b/util/src/interfaces/Event.ts index 1897706e..bab6f4dc 100644 --- a/util/src/interfaces/Event.ts +++ b/util/src/interfaces/Event.ts @@ -259,22 +259,14 @@ export interface InviteDeleteEvent extends Event { }; } -export type MessagePayload = Omit<Message, "author_id"> & { - channel_id: string; - guild_id?: string; - author: PublicUser; - member: PublicMember; - mentions: (PublicUser & { member: PublicMember })[]; -}; - export interface MessageCreateEvent extends Event { event: "MESSAGE_CREATE"; - data: MessagePayload; + data: Message; } export interface MessageUpdateEvent extends Event { event: "MESSAGE_UPDATE"; - data: MessagePayload; + data: Message; } export interface MessageDeleteEvent extends Event { diff --git a/util/src/tes.ts b/util/src/tes.ts new file mode 100644 index 00000000..b469f1d8 --- /dev/null +++ b/util/src/tes.ts @@ -0,0 +1,19 @@ +import { performance } from "perf_hooks"; +import { Guild, Relationship, RelationshipType } from "./entities"; +import { User } from "./entities/User"; +import { initDatabase } from "./util"; + +initDatabase().then(async (x) => { + try { + const user = await new User( + { guilds: [], discriminator: "1", username: "test", flags: "0", public_flags: "0" }, + { id: "0" } + ).save(); + + user.relationships = [new Relationship({ type: RelationshipType.friends })]; + + user.save(); + } catch (error) { + console.error(error); + } +}); diff --git a/util/src/util/AutoUpdate.ts b/util/src/util/AutoUpdate.ts index a2ce73c2..cafc7bdb 100644 --- a/util/src/util/AutoUpdate.ts +++ b/util/src/util/AutoUpdate.ts @@ -40,6 +40,7 @@ export function enableAutoUpdate(opts: { console.log(`[Auto update] updating ...`); download(opts.downloadUrl, opts.path); } else { + console.log(`[Auto update] aborted`); } } ); diff --git a/util/src/util/Database.ts b/util/src/util/Database.ts index 8bb8078e..f49fb04c 100644 --- a/util/src/util/Database.ts +++ b/util/src/util/Database.ts @@ -14,11 +14,17 @@ export function initDatabase() { console.log("[Database] connecting ..."); // @ts-ignore promise = createConnection({ - type: "sqlite", - database: "database.db", + // type: "sqlite", + // database: "database.db", + type: "postgres", + url: "postgres://fosscord:wb94SmuURM2Syv&@localhost/fosscord", + // entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"), synchronize: true, - logging: false, + logging: true, + cache: { + duration: 1000 * 3, // cache all find queries for 3 seconds + }, }); promise.then((connection) => { diff --git a/util/src/util/Permissions.ts b/util/src/util/Permissions.ts index 630db36f..5082d8ea 100644 --- a/util/src/util/Permissions.ts +++ b/util/src/util/Permissions.ts @@ -198,50 +198,41 @@ export class Permissions extends BitField { } export type PermissionCache = { - channel?: Channel | null; - member?: Member | null; - guild?: Guild | null; - roles?: Role[] | null; + channel?: Channel | undefined; + member?: Member | undefined; + guild?: Guild | undefined; + roles?: Role[] | undefined; user_id?: string; }; -export async function getPermission( - user_id?: string, - guild_id?: string, - channel_id?: string, - cache: PermissionCache = {} -) { - var { channel, member, guild, roles } = cache; - +export async function getPermission(user_id?: string, guild_id?: string, channel_id?: string) { if (!user_id) throw new HTTPError("User not found"); + var channel: Channel | undefined; + var member: Member | undefined; + var guild: Guild | undefined; - if (channel_id && !channel) { + if (channel_id) { channel = await Channel.findOneOrFail( { id: channel_id }, { select: ["permission_overwrites", "recipients", "owner", "guild"] } ); - if (!channel) throw new HTTPError("Channel not found", 404); - if (channel.guild_id) guild_id = channel.guild_id; + if (channel.guild_id) guild_id = channel.guild_id; // derive guild_id from the channel } if (guild_id) { - if (!guild) guild = await Guild.findOneOrFail({ id: guild_id }, { select: ["owner"] }); - if (!guild) throw new HTTPError("Guild not found"); + guild = await Guild.findOneOrFail({ id: guild_id }, { select: ["owner"] }); if (guild.owner_id === user_id) return new Permissions(Permissions.FLAGS.ADMINISTRATOR); - if (!member) member = await Member.findOneOrFail({ guild_id, id: user_id }, { select: ["roles"] }); - if (!member) throw new HTTPError("Member not found"); - - if (!roles) roles = await Role.find({ guild_id, id: In(member.roles) }); + member = await Member.findOneOrFail({ guild_id, id: user_id }, { select: ["roles"] }); } var permission = Permissions.finalPermission({ user: { id: user_id, - roles: member?.roles || [], + roles: member?.role_ids || [], }, guild: { - roles: roles || [], + roles: member?.roles || [], }, channel: { overwrites: channel?.permission_overwrites, @@ -253,7 +244,7 @@ export async function getPermission( const obj = new Permissions(permission); // pass cache to permission for possible future getPermission calls - obj.cache = { guild, member, channel, roles, user_id }; + obj.cache = { guild, member, channel, roles: member?.roles, user_id }; return obj; } diff --git a/util/tests/User.test.js b/util/tests/User.test.js index b87c753d..c0852ebc 100644 --- a/util/tests/User.test.js +++ b/util/tests/User.test.js @@ -1,10 +1,9 @@ const { initDatabase, closeDatabase } = require("../dist/util/Database"); const { User } = require("../dist/entities/User"); -jest.setTimeout(10000); +jest.setTimeout(20000); beforeAll((done) => { initDatabase().then(() => { - new User().validate(); // warm up schema/model done(); }); }); @@ -28,4 +27,17 @@ describe("User", () => { new User({ discriminator: "0" }).validate(); }).toThrow(); }); + + test("add guild", async () => { + try { + await new User({ guilds: [], discriminator: "1" }, { id: "0" }).save(); + const user = await User.find("0"); + + user.guilds.push(new Guild({ name: "test" })); + + user.save(); + } catch (error) { + console.error(error); + } + }); }); diff --git a/util/tests/setupJest.js b/util/tests/setupJest.js index 551d2be5..35a3cb52 100644 --- a/util/tests/setupJest.js +++ b/util/tests/setupJest.js @@ -1,4 +1,8 @@ const { performance } = require("perf_hooks"); +const fs = require("fs"); +const path = require("path"); + +// fs.unlinkSync(path.join(__dirname, "..", "database.db")); global.expect.extend({ toBeFasterThan: async (func, target) => { diff --git a/util/tests/validate.test.js b/util/tests/validate.test.js deleted file mode 100644 index 434422f8..00000000 --- a/util/tests/validate.test.js +++ /dev/null @@ -1,33 +0,0 @@ -const { initDatabase, closeDatabase } = require("../dist/util/Database"); -const { User } = require("../dist/entities/User"); -jest.setTimeout(10000); - -beforeAll((done) => { - initDatabase().then(() => { - new User().validate(); // warm up schema/model - done(); - }); -}); - -afterAll(() => { - closeDatabase(); -}); - -describe("Validate model class properties", () => { - test("object instead of string", async () => { - expect(() => { - new User({}, { id: {} }).validate(); - }).toThrow(); - }); - - test("validation should be faster than 20ms", () => { - expect(() => { - new User().validate(); - }).toBeFasterThan(20); - }); - - test("should not set opts", () => { - const user = new User({ opts: { id: 0 } }); - expect(user.opts.id).not.toBe(0); - }); -}); diff --git a/util/tsconfig.json b/util/tsconfig.json index 3fe76ee7..ac41cea5 100644 --- a/util/tsconfig.json +++ b/util/tsconfig.json @@ -1,5 +1,5 @@ { - "include": ["src/**/*.ts"], + "include": ["src/**/*.ts", "tests/Test.ts"], "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ |