diff --git a/.githooks/pre-commit b/.githooks/pre-commit
new file mode 100755
index 00000000..0d2c8db7
--- /dev/null
+++ b/.githooks/pre-commit
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments. The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=$(git hash-object -t tree /dev/null)
+fi
+
+# If you want to allow non-ASCII filenames set this variable to true.
+allownonascii=$(git config --type=bool hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ASCII filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+ # Note that the use of brackets around a tr range is ok here, (it's
+ # even required, for portability to Solaris 10's /usr/bin/tr), since
+ # the square bracket bytes happen to fall in the designated range.
+ test $(git diff --cached --name-only --diff-filter=A -z $against |
+ LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+ cat <<\EOF
+Error: Attempt to add a non-ASCII file name.
+
+This can cause problems if you want to work with people on other platforms.
+
+To be portable it is advisable to rename the file.
+
+If you know what you are doing you can disable this check using:
+
+ git config hooks.allownonascii true
+EOF
+ exit 1
+fi
+
+rm -rf dist
+
+#npx prettier -w .
+npx --yes -p prettier@latest -p pretty-quick pretty-quick
+git update-index --again
+
+# If there are whitespace errors, print the offending file names and fail.
+#exec git diff-index --check --cached $against --
diff --git a/.gitignore b/.gitignore
index e9f3f39c..9629f85c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,5 +19,6 @@ api/assets/plugins/*.js
bundle/depclean.*
*.tmp
tmp/
-
-assets/cache/
\ No newline at end of file
+assets/cache/
+*.generated
+initial.json
diff --git a/.prettierrc b/.prettierrc
index 0defea23..cf69bed0 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -2,5 +2,7 @@
"tabWidth": 4,
"useTabs": true,
"printWidth": 140,
- "trailingComma": "none"
-}
\ No newline at end of file
+ "trailingComma": "none",
+ "pluginSearchDirs": ["./node_modules"],
+ "plugins": ["prettier-plugin-organize-imports"]
+}
diff --git a/assets/checkLocale.js b/assets/checkLocale.js
index 016d66c8..091add1f 100644
--- a/assets/checkLocale.js
+++ b/assets/checkLocale.js
@@ -1,47 +1,47 @@
- const localStorage = window.localStorage;
- // TODO: remote auth
- // window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, "");
- localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT);
- localStorage.setItem(
- "DeveloperOptionsStore",
- `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}`
- );
+const localStorage = window.localStorage;
+// TODO: remote auth
+// window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, "");
+localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT);
+localStorage.setItem(
+ "DeveloperOptionsStore",
+ `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}`
+);
- const supportedLocales = [
- "bg",
- "cs",
- "da",
- "de",
- "el",
- "en-GB",
- "es-ES",
- "fi",
- "fr",
- "hi",
- "hr",
- "hu",
- "it",
- "ja",
- "ko",
- "lt",
- "nl",
- "no",
- "pl",
- "pt-BR",
- "ro",
- "ru",
- "sv-SE",
- "th",
- "tr",
- "uk",
- "vi",
- "zh-CN",
- "zh-TW"
- ];
+const supportedLocales = [
+ "bg",
+ "cs",
+ "da",
+ "de",
+ "el",
+ "en-GB",
+ "es-ES",
+ "fi",
+ "fr",
+ "hi",
+ "hr",
+ "hu",
+ "it",
+ "ja",
+ "ko",
+ "lt",
+ "nl",
+ "no",
+ "pl",
+ "pt-BR",
+ "ro",
+ "ru",
+ "sv-SE",
+ "th",
+ "tr",
+ "uk",
+ "vi",
+ "zh-CN",
+ "zh-TW"
+];
- const settings = JSON.parse(localStorage.getItem("UserSettingsStore"));
- if (settings && !supportedLocales.includes(settings.locale)) {
- // fix client locale wrong and client not loading at all
- settings.locale = "en-US";
- localStorage.setItem("UserSettingsStore", JSON.stringify(settings));
- }
\ No newline at end of file
+const settings = JSON.parse(localStorage.getItem("UserSettingsStore"));
+if (settings && !supportedLocales.includes(settings.locale)) {
+ // fix client locale wrong and client not loading at all
+ settings.locale = "en-US";
+ localStorage.setItem("UserSettingsStore", JSON.stringify(settings));
+}
diff --git a/assets/developers.html b/assets/developers.html
index 87595e77..b33009dd 100644
--- a/assets/developers.html
+++ b/assets/developers.html
@@ -1,44 +1,42 @@
<!DOCTYPE html>
<html class="theme-dark" data-theme="dark">
+ <head>
+ <meta charset="utf-8" />
+ <meta content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no" name="viewport" />
-<head>
- <meta charset="utf-8" />
- <meta content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no" name="viewport" />
+ <link rel="stylesheet" href="/assets/532.03aaeef88460fae60534.css" integrity="" />
+ <link rel="icon" href="/assets/07dca80a102d4149e9736d4b162cff6f.ico" />
+ <title>Discord Test Client Developer Portal</title>
+ <meta charset="utf-8" data-react-helmet="true" />
+ </head>
- <link rel="stylesheet" href="/assets/532.03aaeef88460fae60534.css" integrity="" />
- <link rel="icon" href="/assets/07dca80a102d4149e9736d4b162cff6f.ico" />
- <title>Discord Test Client Developer Portal</title>
- <meta charset="utf-8" data-react-helmet="true" />
-</head>
+ <body>
+ <div id="app-mount"></div>
+ <script>
+ window.GLOBAL_ENV = {
+ API_VERSION: 9,
+ API_ENDPOINT: "/api",
+ WEBAPP_ENDPOINT: "",
+ CDN_HOST: `${location.hostname}:3003`,
-<body>
- <div id="app-mount"></div>
- <script>
- window.GLOBAL_ENV = {
- API_VERSION: 9,
- API_ENDPOINT: "/api",
- WEBAPP_ENDPOINT: "",
- CDN_HOST: `${location.hostname}:3003`,
-
- BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387",
- STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi",
- MARKETING_ENDPOINT: "//discord.com",
- RELEASE_CHANNEL: "stable",
- ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0"
- };
- GLOBAL_ENV.MEDIA_PROXY_ENDPOINT = location.protocol + "//" + GLOBAL_ENV.CDN_HOST;
- const localStorage = window.localStorage;
- // TODO: remote auth
- // window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, "");
- localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT);
- localStorage.setItem(
- "DeveloperOptionsStore",
- `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}`
- );
- </script>
- <script src="/assets/38f40c32d3c8a2fdf73b.js" integrity=""></script>
- <script src="/assets/aa190934324e05fcc35c.js" integrity=""></script>
- <script src="/assets/45664a0209e828a528b4.js" integrity=""></script>
-</body>
-
-</html>
\ No newline at end of file
+ BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387",
+ STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi",
+ MARKETING_ENDPOINT: "//discord.com",
+ RELEASE_CHANNEL: "stable",
+ ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0"
+ };
+ GLOBAL_ENV.MEDIA_PROXY_ENDPOINT = location.protocol + "//" + GLOBAL_ENV.CDN_HOST;
+ const localStorage = window.localStorage;
+ // TODO: remote auth
+ // window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, "");
+ localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT);
+ localStorage.setItem(
+ "DeveloperOptionsStore",
+ `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}`
+ );
+ </script>
+ <script src="/assets/38f40c32d3c8a2fdf73b.js" integrity=""></script>
+ <script src="/assets/aa190934324e05fcc35c.js" integrity=""></script>
+ <script src="/assets/45664a0209e828a528b4.js" integrity=""></script>
+ </body>
+</html>
diff --git a/assets/fosscord-login.css b/assets/fosscord-login.css
index d507c545..975bf908 100644
--- a/assets/fosscord-login.css
+++ b/assets/fosscord-login.css
@@ -1,12 +1,12 @@
/* replace tos acceptance popup */
#app-mount > div:nth-child(7) > div > div > div.tooltipContent-bqVLWK {
- visibility: hidden;
+ visibility: hidden;
}
-#app-mount > div:nth-child(7) > div > div > div.tooltipContent-bqVLWK::after{
- visibility: visible;
- display: block;
- content: "You need to agree to this instance's rules to continue";
- margin-top: -32px;
+#app-mount > div:nth-child(7) > div > div > div.tooltipContent-bqVLWK::after {
+ visibility: visible;
+ display: block;
+ content: "You need to agree to this instance's rules to continue";
+ margin-top: -32px;
}
/* replace login header */
#app-mount > div.app-1q1i1E > div > div > div > div > form > div > div > div.mainLoginContainer-1ddwnR > h3 {
diff --git a/assets/fosscord.css b/assets/fosscord.css
index 6078fdeb..fa503d39 100644
--- a/assets/fosscord.css
+++ b/assets/fosscord.css
@@ -1,4 +1,3 @@
-
/* loading spinner */
#app-mount > div.app-1q1i1E > div.container-16j22k.fixClipping-3qAKRb > div.content-1-zrf2 > video {
filter: opacity(1);
@@ -11,14 +10,62 @@
}
/* home button icon */
-#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div.tutorialContainer-2sGCg9 > div > div.listItemWrapper-KhRmzM > div > svg > foreignObject > div > div
-{
- background-image: url(https://raw.githubusercontent.com/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-Icon-Rounded-Subtract.svg);
- background-size: contain;
- border-radius: 50%;
+#app-mount
+ > div.app-1q1i1E
+ > div
+ > div.layers-3iHuyZ.layers-3q14ss
+ > div
+ > div
+ > nav
+ > ul
+ > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih
+ > div.tutorialContainer-2sGCg9
+ > div
+ > div.listItemWrapper-KhRmzM
+ > div
+ > svg
+ > foreignObject
+ > div
+ > div {
+ background-image: url(https://raw.githubusercontent.com/fosscord/fosscord/master/assets-rebrand/svg/Fosscord-Icon-Rounded-Subtract.svg);
+ background-size: contain;
+ border-radius: 50%;
}
-#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div.tutorialContainer-2sGCg9 > div > div.listItemWrapper-KhRmzM > div > svg > foreignObject > div > div, #app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div.tutorialContainer-2sGCg9 > div > div.listItemWrapper-KhRmzM > div > svg > foreignObject > div > div:hover {
+#app-mount
+ > div.app-1q1i1E
+ > div
+ > div.layers-3iHuyZ.layers-3q14ss
+ > div
+ > div
+ > nav
+ > ul
+ > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih
+ > div.tutorialContainer-2sGCg9
+ > div
+ > div.listItemWrapper-KhRmzM
+ > div
+ > svg
+ > foreignObject
+ > div
+ > div,
+#app-mount
+ > div.app-1q1i1E
+ > div
+ > div.layers-3iHuyZ.layers-3q14ss
+ > div
+ > div
+ > nav
+ > ul
+ > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih
+ > div.tutorialContainer-2sGCg9
+ > div
+ > div.listItemWrapper-KhRmzM
+ > div
+ > svg
+ > foreignObject
+ > div
+ > div:hover {
background-color: white;
}
/* Login QR */
@@ -40,7 +87,6 @@
/* Thread permissions etc popups */
#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > div > div.content-98HsJk > div.sidebar-2K8pFh.hasNotice-1XRy4h > nav > div.container-3O_wAf,
/* home button icon */
-#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div.tutorialContainer-2sGCg9 > div > div.listItemWrapper-KhRmzM > div > svg > foreignObject > div > div > svg
-{
- display: none;
-}
\ No newline at end of file
+#app-mount > div.app-1q1i1E > div > div.layers-3iHuyZ.layers-3q14ss > div > div > nav > ul > div.scroller-1Bvpku.none-2Eo-qx.scrollerBase-289Jih > div.tutorialContainer-2sGCg9 > div > div.listItemWrapper-KhRmzM > div > svg > foreignObject > div > div > svg {
+ display: none;
+}
diff --git a/assets/index.html b/assets/index.html
index 64a2bdbf..1d4e4543 100644
--- a/assets/index.html
+++ b/assets/index.html
@@ -1,84 +1,82 @@
<!DOCTYPE html>
<html lang="en">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>Discord Test Client</title>
+ <link rel="stylesheet" href="/assets/fosscord.css" />
+ <link id="logincss" rel="stylesheet" href="/assets/fosscord-login.css" />
+ <link id="customcss" rel="stylesheet" href="/assets/user.css" />
+ <!-- inline plugin marker -->
+ <!-- preload plugin marker -->
+ </head>
-<head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Discord Test Client</title>
- <link rel="stylesheet" href="/assets/fosscord.css" />
- <link id="logincss" rel="stylesheet" href="/assets/fosscord-login.css" />
- <link id="customcss" rel="stylesheet" href="/assets/user.css" />
- <!-- inline plugin marker -->
- <!-- preload plugin marker -->
-</head>
+ <body>
+ <div id="app-mount"></div>
+ <script>
+ window.__OVERLAY__ = /overlay/.test(location.pathname);
+ window.__BILLING_STANDALONE__ = /^\/billing/.test(location.pathname);
+ window.GLOBAL_ENV = {
+ API_ENDPOINT: "/api",
+ API_VERSION: 9,
+ GATEWAY_ENDPOINT: `${location.protocol === "https:" ? "wss://" : "ws://"}${location.host}`,
+ WEBAPP_ENDPOINT: "",
+ CDN_HOST: `${location.hostname}:3003`,
+ ASSET_ENDPOINT: "",
+ MEDIA_PROXY_ENDPOINT: "https://media.discordapp.net",
+ WIDGET_ENDPOINT: `//${location.host}/widget`,
+ INVITE_HOST: `${location.hostname}/invite`,
+ GUILD_TEMPLATE_HOST: "${location.host}",
+ GIFT_CODE_HOST: "${location.hostname}",
+ RELEASE_CHANNEL: "stable",
+ MARKETING_ENDPOINT: "//discord.com",
+ BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387",
+ STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi",
+ NETWORKING_ENDPOINT: "//router.discordapp.net",
+ RTC_LATENCY_ENDPOINT: "//${location.hostname}/rtc",
+ ACTIVITY_APPLICATION_HOST: "discordsays.com",
+ PROJECT_ENV: "production",
+ REMOTE_AUTH_ENDPOINT: "//localhost:3020",
+ SENTRY_TAGS: { buildId: "75e36d9", buildType: "normal" },
+ MIGRATION_SOURCE_ORIGIN: "https://${location.hostname}",
+ MIGRATION_DESTINATION_ORIGIN: "https://${location.hostname}",
+ HTML_TIMESTAMP: Date.now(),
+ ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0"
+ };
+ GLOBAL_ENV.MEDIA_PROXY_ENDPOINT = location.protocol + "//" + GLOBAL_ENV.CDN_HOST;
+ const localStorage = window.localStorage;
+ // TODO: remote auth
+ // window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, "");
+ localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT);
+ localStorage.setItem(
+ "DeveloperOptionsStore",
+ `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}`
+ );
-<body>
- <div id="app-mount"></div>
- <script>
- window.__OVERLAY__ = /overlay/.test(location.pathname);
- window.__BILLING_STANDALONE__ = /^\/billing/.test(location.pathname);
- window.GLOBAL_ENV = {
- API_ENDPOINT: "/api",
- API_VERSION: 9,
- GATEWAY_ENDPOINT: `${location.protocol === "https:" ? "wss://" : "ws://"}${location.host}`,
- WEBAPP_ENDPOINT: "",
- CDN_HOST: `${location.hostname}:3003`,
- ASSET_ENDPOINT: "",
- MEDIA_PROXY_ENDPOINT: "https://media.discordapp.net",
- WIDGET_ENDPOINT: `//${location.host}/widget`,
- INVITE_HOST: `${location.hostname}/invite`,
- GUILD_TEMPLATE_HOST: "${location.host}",
- GIFT_CODE_HOST: "${location.hostname}",
- RELEASE_CHANNEL: "stable",
- MARKETING_ENDPOINT: "//discord.com",
- BRAINTREE_KEY: "production_5st77rrc_49pp2rp4phym7387",
- STRIPE_KEY: "pk_live_CUQtlpQUF0vufWpnpUmQvcdi",
- NETWORKING_ENDPOINT: "//router.discordapp.net",
- RTC_LATENCY_ENDPOINT: "//${location.hostname}/rtc",
- ACTIVITY_APPLICATION_HOST: 'discordsays.com',
- PROJECT_ENV: "production",
- REMOTE_AUTH_ENDPOINT: "//localhost:3020",
- SENTRY_TAGS: { buildId: "75e36d9", buildType: "normal" },
- MIGRATION_SOURCE_ORIGIN: "https://${location.hostname}",
- MIGRATION_DESTINATION_ORIGIN: "https://${location.hostname}",
- HTML_TIMESTAMP: Date.now(),
- ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0",
- };
- GLOBAL_ENV.MEDIA_PROXY_ENDPOINT = location.protocol + "//" + GLOBAL_ENV.CDN_HOST;
- const localStorage = window.localStorage;
- // TODO: remote auth
- // window.GLOBAL_ENV.REMOTE_AUTH_ENDPOINT = window.GLOBAL_ENV.GATEWAY_ENDPOINT.replace(/wss?:/, "");
- localStorage.setItem("gatewayURL", window.GLOBAL_ENV.GATEWAY_ENDPOINT);
- localStorage.setItem(
- "DeveloperOptionsStore",
- `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":true,"logAnalyticsEvents":true,"sourceMapsEnabled":false,"axeEnabled":false}`
- );
-
- setInterval(() => {
- let token = JSON.parse(localStorage.getItem("token"));
- if (token) {
- let logincss = document.querySelector('#logincss'),
- canRemove = logincss ? logincss : "";
- if (canRemove !== "") {
- document.querySelector("#logincss").remove();
- canRemove = "";
+ setInterval(() => {
+ let token = JSON.parse(localStorage.getItem("token"));
+ if (token) {
+ let logincss = document.querySelector("#logincss"),
+ canRemove = logincss ? logincss : "";
+ if (canRemove !== "") {
+ document.querySelector("#logincss").remove();
+ canRemove = "";
+ }
}
- }
- }, 1000)
+ }, 1000);
- const settings = JSON.parse(localStorage.getItem("UserSettingsStore"));
- if (settings && settings.locale.length <= 2) {
- // fix client locale wrong and client not loading at all
- settings.locale = "en-US";
- localStorage.setItem("UserSettingsStore", JSON.stringify(settings));
- }
- </script>
- <script src="/assets/checkLocale.js"></script>
- <script src="/assets/2f2e0c25e45eb2f5a6f1.js"></script>
- <script src="/assets/006e72c08a4c69cb66fc.js"></script>
- <script src="/assets/2f94a3ba801087653a38.js"></script>
- <script src="/assets/f7703f092bdbfc607cc7.js"></script>
- <!-- plugin marker -->
-</body>
-
-</html>
\ No newline at end of file
+ const settings = JSON.parse(localStorage.getItem("UserSettingsStore"));
+ if (settings && settings.locale.length <= 2) {
+ // fix client locale wrong and client not loading at all
+ settings.locale = "en-US";
+ localStorage.setItem("UserSettingsStore", JSON.stringify(settings));
+ }
+ </script>
+ <script src="/assets/checkLocale.js"></script>
+ <script src="/assets/2f2e0c25e45eb2f5a6f1.js"></script>
+ <script src="/assets/006e72c08a4c69cb66fc.js"></script>
+ <script src="/assets/2f94a3ba801087653a38.js"></script>
+ <script src="/assets/f7703f092bdbfc607cc7.js"></script>
+ <!-- plugin marker -->
+ </body>
+</html>
diff --git a/assets/schemas.json b/assets/schemas.json
index 0fe3dfa1..e3200800 100644
--- a/assets/schemas.json
+++ b/assets/schemas.json
@@ -1,1471 +1,1271 @@
{
- "ActivitySchema": {
- "type": "object",
- "properties": {
- "afk": {
- "type": "boolean"
- },
- "status": {},
- "activities": {
- "type": "array",
- "items": {}
- },
- "since": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "required": [
- "afk",
- "status"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "BanCreateSchema": {
- "type": "object",
- "properties": {
- "delete_message_days": {
- "type": "string"
- },
- "reason": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "BanModeratorSchema": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "user_id": {
- "type": "string"
- },
- "guild_id": {
- "type": "string"
- },
- "executor_id": {
- "type": "string"
- },
- "reason": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "executor_id",
- "guild_id",
- "id",
- "user_id"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "BanRegistrySchema": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "user_id": {
- "type": "string"
- },
- "guild_id": {
- "type": "string"
- },
- "executor_id": {
- "type": "string"
- },
- "ip": {
- "type": "string"
- },
- "reason": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "executor_id",
- "guild_id",
- "id",
- "user_id"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "BulkDeleteSchema": {
- "type": "object",
- "properties": {
- "messages": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "additionalProperties": false,
- "required": [
- "messages"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ts.server.TypingInstallerResponse": {
- "type": "object",
- "properties": {
- "kind": {
- "enum": [
- "action::invalidate",
- "action::packageInstalled",
- "action::set",
- "event::beginInstallTypes",
- "event::endInstallTypes",
- "event::initializationFailed",
- "event::typesRegistry"
- ],
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "kind"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ts.server.PackageInstalledResponse": {
- "type": "object",
- "properties": {
- "kind": {
- "type": "string",
- "enum": [
- "action::packageInstalled"
- ]
- },
- "success": {
- "type": "boolean"
- },
- "message": {
- "type": "string"
- },
- "projectName": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "kind",
- "message",
- "projectName",
- "success"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ts.server.InitializationFailedResponse": {
- "type": "object",
- "properties": {
- "kind": {
- "type": "string",
- "enum": [
- "event::initializationFailed"
- ]
- },
- "message": {
- "type": "string"
- },
- "stack": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "kind",
- "message"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ts.server.ProjectResponse": {
- "type": "object",
- "properties": {
- "projectName": {
- "type": "string"
- },
- "kind": {
- "enum": [
- "action::invalidate",
- "action::packageInstalled",
- "action::set",
- "event::beginInstallTypes",
- "event::endInstallTypes",
- "event::initializationFailed",
- "event::typesRegistry"
- ],
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "kind",
- "projectName"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ChannelPermissionOverwriteSchema": {
- "type": "object",
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ChannelReorderSchema": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "position": {
- "type": "integer"
- },
- "lock_permissions": {
- "type": "boolean"
- },
- "parent_id": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "id"
- ]
- },
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "DmChannelCreateSchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "recipients": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "additionalProperties": false,
- "required": [
- "recipients"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "EmojiCreateSchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "image": {
- "type": "string"
- },
- "require_colons": {
- "type": [
- "null",
- "boolean"
- ]
- },
- "roles": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "additionalProperties": false,
- "required": [
- "image"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "EmojiModifySchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "roles": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "GuildCreateSchema": {
- "type": "object",
- "properties": {
- "name": {
- "maxLength": 100,
- "type": "string"
- },
- "region": {
- "type": "string"
- },
- "icon": {
- "type": [
- "null",
- "string"
- ]
- },
- "channels": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/ChannelModifySchema"
- }
- },
- "guild_template_code": {
- "type": "string"
- },
- "system_channel_id": {
- "type": "string"
- },
- "rules_channel_id": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "name"
- ],
- "definitions": {
- "ChannelModifySchema": {
- "type": "object",
- "properties": {
- "name": {
- "maxLength": 100,
- "type": "string"
- },
- "type": {
- "enum": [
- 0,
- 1,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 2,
- 255,
- 3,
- 33,
- 34,
- 35,
- 4,
- 5,
- 6,
- 64,
- 7,
- 8,
- 9
- ],
- "type": "number"
- },
- "topic": {
- "type": "string"
- },
- "icon": {
- "type": [
- "null",
- "string"
- ]
- },
- "bitrate": {
- "type": "integer"
- },
- "user_limit": {
- "type": "integer"
- },
- "rate_limit_per_user": {
- "type": "integer"
- },
- "position": {
- "type": "integer"
- },
- "permission_overwrites": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "type": {
- "$ref": "#/definitions/ChannelPermissionOverwriteType"
- },
- "allow": {
- "type": "string"
- },
- "deny": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "allow",
- "deny",
- "id",
- "type"
- ]
- }
- },
- "parent_id": {
- "type": "string"
- },
- "id": {
- "type": "string"
- },
- "nsfw": {
- "type": "boolean"
- },
- "rtc_region": {
- "type": "string"
- },
- "default_auto_archive_duration": {
- "type": "integer"
- },
- "flags": {
- "type": "integer"
- },
- "default_thread_rate_limit_per_user": {
- "type": "integer"
- }
- },
- "additionalProperties": false
- },
- "ChannelPermissionOverwriteType": {
- "enum": [
- 0,
- 1,
- 2
- ],
- "type": "number"
- }
- },
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "GuildTemplateCreateSchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "avatar": {
- "type": [
- "null",
- "string"
- ]
- }
- },
- "additionalProperties": false,
- "required": [
- "name"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "GuildUpdateSchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "banner": {
- "type": [
- "null",
- "string"
- ]
- },
- "splash": {
- "type": [
- "null",
- "string"
- ]
- },
- "description": {
- "type": "string"
- },
- "features": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "verification_level": {
- "type": "integer"
- },
- "default_message_notifications": {
- "type": "integer"
- },
- "system_channel_flags": {
- "type": "integer"
- },
- "explicit_content_filter": {
- "type": "integer"
- },
- "public_updates_channel_id": {
- "type": "string"
- },
- "afk_timeout": {
- "type": "integer"
- },
- "afk_channel_id": {
- "type": "string"
- },
- "preferred_locale": {
- "type": "string"
- },
- "premium_progress_bar_enabled": {
- "type": "boolean"
- },
- "region": {
- "type": "string"
- },
- "icon": {
- "type": [
- "null",
- "string"
- ]
- },
- "guild_template_code": {
- "type": "string"
- },
- "system_channel_id": {
- "type": "string"
- },
- "rules_channel_id": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "GuildUpdateWelcomeScreenSchema": {
- "type": "object",
- "properties": {
- "welcome_channels": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "channel_id": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "emoji_id": {
- "type": "string"
- },
- "emoji_name": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "channel_id",
- "description",
- "emoji_name"
- ]
- }
- },
- "enabled": {
- "type": "boolean"
- },
- "description": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "IdentifySchema": {
- "type": "object",
- "properties": {
- "token": {
- "type": "string"
- },
- "properties": {
- "type": "object",
- "properties": {
- "os": {
- "type": "string"
- },
- "os_atch": {
- "type": "string"
- },
- "browser": {
- "type": "string"
- },
- "device": {
- "type": "string"
- },
- "$os": {
- "type": "string"
- },
- "$browser": {
- "type": "string"
- },
- "$device": {
- "type": "string"
- },
- "browser_user_agent": {
- "type": "string"
- },
- "browser_version": {
- "type": "string"
- },
- "os_version": {
- "type": "string"
- },
- "referrer": {
- "type": "string"
- },
- "referring_domain": {
- "type": "string"
- },
- "referrer_current": {
- "type": "string"
- },
- "referring_domain_current": {
- "type": "string"
- },
- "release_channel": {
- "enum": [
- "canary",
- "dev",
- "ptb",
- "stable"
- ],
- "type": "string"
- },
- "client_build_number": {
- "type": "integer"
- },
- "client_event_source": {},
- "client_version": {
- "type": "string"
- },
- "system_locale": {
- "type": "string"
- }
- },
- "additionalProperties": false
- },
- "intents": {
- "type": "string"
- },
- "presence": {
- "$ref": "#/definitions/ActivitySchema"
- },
- "compress": {
- "type": "boolean"
- },
- "large_threshold": {
- "type": "integer"
- },
- "shard": {
- "type": "array",
- "items": [
- {
- "type": "integer"
- },
- {
- "type": "integer"
- }
- ],
- "minItems": 2,
- "maxItems": 2
- },
- "guild_subscriptions": {
- "type": "boolean"
- },
- "capabilities": {
- "type": "integer"
- },
- "client_state": {
- "type": "object",
- "properties": {
- "guild_hashes": {},
- "highest_last_message_id": {
- "type": "string"
- },
- "read_state_version": {
- "type": "integer"
- },
- "user_guild_settings_version": {
- "type": "integer"
- },
- "user_settings_version": {
- "type": "integer"
- }
- },
- "additionalProperties": false
- },
- "v": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "required": [
- "properties",
- "token"
- ],
- "definitions": {
- "ActivitySchema": {
- "type": "object",
- "properties": {
- "afk": {
- "type": "boolean"
- },
- "status": {},
- "activities": {
- "type": "array",
- "items": {}
- },
- "since": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "required": [
- "afk",
- "status"
- ]
- }
- },
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "InviteCreateSchema": {
- "type": "object",
- "properties": {
- "target_user_id": {
- "type": "string"
- },
- "target_type": {
- "type": "string"
- },
- "validate": {
- "type": "string"
- },
- "max_age": {
- "type": "integer"
- },
- "max_uses": {
- "type": "integer"
- },
- "temporary": {
- "type": "boolean"
- },
- "unique": {
- "type": "boolean"
- },
- "target_user": {
- "type": "string"
- },
- "target_user_type": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "LoginSchema": {
- "type": "object",
- "properties": {
- "login": {
- "type": "string"
- },
- "password": {
- "type": "string"
- },
- "undelete": {
- "type": "boolean"
- },
- "captcha_key": {
- "type": "string"
- },
- "login_source": {
- "type": "string"
- },
- "gift_code_sku_id": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "login",
- "password"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "MemberChangeSchema": {
- "type": "object",
- "properties": {
- "roles": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "MemberNickChangeSchema": {
- "type": "object",
- "properties": {
- "nick": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "nick"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "MessageAcknowledgeSchema": {
- "type": "object",
- "properties": {
- "manual": {
- "type": "boolean"
- },
- "mention_count": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "MessageCreateSchema": {
- "type": "object",
- "properties": {
- "type": {
- "type": "integer"
- },
- "content": {
- "type": "string"
- },
- "nonce": {
- "type": "string"
- },
- "channel_id": {
- "type": "string"
- },
- "tts": {
- "type": "boolean"
- },
- "flags": {
- "type": "string"
- },
- "embeds": {
- "type": "array",
- "items": {}
- },
- "embed": {},
- "allowed_mentions": {
- "type": "object",
- "properties": {
- "parse": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "roles": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "users": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "replied_user": {
- "type": "boolean"
- }
- },
- "additionalProperties": false
- },
- "message_reference": {
- "type": "object",
- "properties": {
- "message_id": {
- "type": "string"
- },
- "channel_id": {
- "type": "string"
- },
- "guild_id": {
- "type": "string"
- },
- "fail_if_not_exists": {
- "type": "boolean"
- }
- },
- "additionalProperties": false,
- "required": [
- "channel_id",
- "message_id"
- ]
- },
- "payload_json": {
- "type": "string"
- },
- "file": {},
- "attachments": {
- "description": "TODO: we should create an interface for attachments\nTODO: OpenWAAO<-->attachment-style metadata conversion",
- "type": "array",
- "items": {}
- },
- "sticker_ids": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "MfaCodesSchema": {
- "type": "object",
- "properties": {
- "password": {
- "type": "string"
- },
- "regenerate": {
- "type": "boolean"
- }
- },
- "additionalProperties": false,
- "required": [
- "password"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ModifyGuildStickerSchema": {
- "type": "object",
- "properties": {
- "name": {
- "minLength": 2,
- "maxLength": 30,
- "type": "string"
- },
- "description": {
- "maxLength": 100,
- "type": "string"
- },
- "tags": {
- "maxLength": 200,
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "name",
- "tags"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "PruneSchema": {
- "type": "object",
- "properties": {
- "days": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "required": [
- "days"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "PurgeSchema": {
- "type": "object",
- "properties": {
- "before": {
- "type": "string"
- },
- "after": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "after",
- "before"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "RegisterSchema": {
- "type": "object",
- "properties": {
- "username": {
- "minLength": 2,
- "maxLength": 32,
- "type": "string"
- },
- "password": {
- "minLength": 1,
- "maxLength": 72,
- "type": "string"
- },
- "consent": {
- "type": "boolean"
- },
- "email": {
- "format": "email",
- "type": "string"
- },
- "fingerprint": {
- "type": "string"
- },
- "invite": {
- "type": "string"
- },
- "date_of_birth": {
- "type": "string"
- },
- "gift_code_sku_id": {
- "type": "string"
- },
- "captcha_key": {
- "type": "string"
- },
- "promotional_email_opt_in": {
- "type": "boolean"
- }
- },
- "additionalProperties": false,
- "required": [
- "consent",
- "username"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "RelationshipPostSchema": {
- "type": "object",
- "properties": {
- "discriminator": {
- "type": "string"
- },
- "username": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "discriminator",
- "username"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "RelationshipPutSchema": {
- "type": "object",
- "properties": {
- "type": {}
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "RoleModifySchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "permissions": {
- "type": "string"
- },
- "color": {
- "type": "integer"
- },
- "hoist": {
- "type": "boolean"
- },
- "mentionable": {
- "type": "boolean"
- },
- "position": {
- "type": "integer"
- },
- "icon": {
- "type": "string"
- },
- "unicode_emoji": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "RolePositionUpdateSchema": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "position": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "required": [
- "id",
- "position"
- ]
- },
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "TemplateCreateSchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "description": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "name"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "TemplateModifySchema": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string"
- },
- "description": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "name"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "TotpDisableSchema": {
- "type": "object",
- "properties": {
- "code": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "code"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "TotpEnableSchema": {
- "type": "object",
- "properties": {
- "password": {
- "type": "string"
- },
- "code": {
- "type": "string"
- },
- "secret": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "password"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "TotpSchema": {
- "type": "object",
- "properties": {
- "code": {
- "type": "string"
- },
- "ticket": {
- "type": "string"
- },
- "gift_code_sku_id": {
- "type": [
- "null",
- "string"
- ]
- },
- "login_source": {
- "type": [
- "null",
- "string"
- ]
- }
- },
- "additionalProperties": false,
- "required": [
- "code",
- "ticket"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "UserModifySchema": {
- "type": "object",
- "properties": {
- "username": {
- "minLength": 1,
- "maxLength": 100,
- "type": "string"
- },
- "discriminator": {
- "type": "string"
- },
- "avatar": {
- "type": [
- "null",
- "string"
- ]
- },
- "bio": {
- "maxLength": 1024,
- "type": "string"
- },
- "accent_color": {
- "type": "integer"
- },
- "banner": {
- "type": [
- "null",
- "string"
- ]
- },
- "password": {
- "type": "string"
- },
- "new_password": {
- "type": "string"
- },
- "code": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "UserSettingsSchema": {
- "type": "object",
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "VanityUrlSchema": {
- "type": "object",
- "properties": {
- "code": {
- "minLength": 1,
- "maxLength": 20,
- "type": "string"
- }
- },
- "additionalProperties": false,
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "VoiceStateUpdateSchema": {
- "type": "object",
- "properties": {
- "channel_id": {
- "type": "string"
- },
- "guild_id": {
- "type": "string"
- },
- "suppress": {
- "type": "boolean"
- },
- "request_to_speak_timestamp": {
- "type": "string",
- "format": "date-time"
- },
- "self_mute": {
- "type": "boolean"
- },
- "self_deaf": {
- "type": "boolean"
- },
- "self_video": {
- "type": "boolean"
- }
- },
- "additionalProperties": false,
- "required": [
- "channel_id"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "WebhookCreateSchema": {
- "type": "object",
- "properties": {
- "name": {
- "maxLength": 80,
- "type": "string"
- },
- "avatar": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "name"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "WidgetModifySchema": {
- "type": "object",
- "properties": {
- "enabled": {
- "type": "boolean"
- },
- "channel_id": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "channel_id",
- "enabled"
- ],
- "$schema": "http://json-schema.org/draft-07/schema#"
- },
- "ChannelModifySchema": {
- "type": "object",
- "properties": {
- "name": {
- "maxLength": 100,
- "type": "string"
- },
- "type": {
- "enum": [
- 0,
- 1,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 2,
- 255,
- 3,
- 33,
- 34,
- 35,
- 4,
- 5,
- 6,
- 64,
- 7,
- 8,
- 9
- ],
- "type": "number"
- },
- "topic": {
- "type": "string"
- },
- "icon": {
- "type": [
- "null",
- "string"
- ]
- },
- "bitrate": {
- "type": "integer"
- },
- "user_limit": {
- "type": "integer"
- },
- "rate_limit_per_user": {
- "type": "integer"
- },
- "position": {
- "type": "integer"
- },
- "permission_overwrites": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "type": {
- "$ref": "#/definitions/ChannelPermissionOverwriteType"
- },
- "allow": {
- "type": "string"
- },
- "deny": {
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": [
- "allow",
- "deny",
- "id",
- "type"
- ]
- }
- },
- "parent_id": {
- "type": "string"
- },
- "id": {
- "type": "string"
- },
- "nsfw": {
- "type": "boolean"
- },
- "rtc_region": {
- "type": "string"
- },
- "default_auto_archive_duration": {
- "type": "integer"
- },
- "flags": {
- "type": "integer"
- },
- "default_thread_rate_limit_per_user": {
- "type": "integer"
- }
- },
- "additionalProperties": false,
- "definitions": {
- "ChannelPermissionOverwriteType": {
- "enum": [
- 0,
- 1,
- 2
- ],
- "type": "number"
- }
- },
- "$schema": "http://json-schema.org/draft-07/schema#"
- }
-}
\ No newline at end of file
+ "ActivitySchema": {
+ "type": "object",
+ "properties": {
+ "afk": {
+ "type": "boolean"
+ },
+ "status": {},
+ "activities": {
+ "type": "array",
+ "items": {}
+ },
+ "since": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["afk", "status"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "BanCreateSchema": {
+ "type": "object",
+ "properties": {
+ "delete_message_days": {
+ "type": "string"
+ },
+ "reason": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "BanModeratorSchema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "user_id": {
+ "type": "string"
+ },
+ "guild_id": {
+ "type": "string"
+ },
+ "executor_id": {
+ "type": "string"
+ },
+ "reason": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["executor_id", "guild_id", "id", "user_id"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "BanRegistrySchema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "user_id": {
+ "type": "string"
+ },
+ "guild_id": {
+ "type": "string"
+ },
+ "executor_id": {
+ "type": "string"
+ },
+ "ip": {
+ "type": "string"
+ },
+ "reason": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["executor_id", "guild_id", "id", "user_id"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "BulkDeleteSchema": {
+ "type": "object",
+ "properties": {
+ "messages": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["messages"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ts.server.TypingInstallerResponse": {
+ "type": "object",
+ "properties": {
+ "kind": {
+ "enum": [
+ "action::invalidate",
+ "action::packageInstalled",
+ "action::set",
+ "event::beginInstallTypes",
+ "event::endInstallTypes",
+ "event::initializationFailed",
+ "event::typesRegistry"
+ ],
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["kind"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ts.server.PackageInstalledResponse": {
+ "type": "object",
+ "properties": {
+ "kind": {
+ "type": "string",
+ "enum": ["action::packageInstalled"]
+ },
+ "success": {
+ "type": "boolean"
+ },
+ "message": {
+ "type": "string"
+ },
+ "projectName": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["kind", "message", "projectName", "success"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ts.server.InitializationFailedResponse": {
+ "type": "object",
+ "properties": {
+ "kind": {
+ "type": "string",
+ "enum": ["event::initializationFailed"]
+ },
+ "message": {
+ "type": "string"
+ },
+ "stack": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["kind", "message"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ts.server.ProjectResponse": {
+ "type": "object",
+ "properties": {
+ "projectName": {
+ "type": "string"
+ },
+ "kind": {
+ "enum": [
+ "action::invalidate",
+ "action::packageInstalled",
+ "action::set",
+ "event::beginInstallTypes",
+ "event::endInstallTypes",
+ "event::initializationFailed",
+ "event::typesRegistry"
+ ],
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["kind", "projectName"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ChannelPermissionOverwriteSchema": {
+ "type": "object",
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ChannelReorderSchema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "position": {
+ "type": "integer"
+ },
+ "lock_permissions": {
+ "type": "boolean"
+ },
+ "parent_id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["id"]
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "DmChannelCreateSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "recipients": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["recipients"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "EmojiCreateSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "image": {
+ "type": "string"
+ },
+ "require_colons": {
+ "type": ["null", "boolean"]
+ },
+ "roles": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["image"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "EmojiModifySchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "roles": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "GuildCreateSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "region": {
+ "type": "string"
+ },
+ "icon": {
+ "type": ["null", "string"]
+ },
+ "channels": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/ChannelModifySchema"
+ }
+ },
+ "guild_template_code": {
+ "type": "string"
+ },
+ "system_channel_id": {
+ "type": "string"
+ },
+ "rules_channel_id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["name"],
+ "definitions": {
+ "ChannelModifySchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "type": {
+ "enum": [0, 1, 10, 11, 12, 13, 14, 15, 2, 255, 3, 33, 34, 35, 4, 5, 6, 64, 7, 8, 9],
+ "type": "number"
+ },
+ "topic": {
+ "type": "string"
+ },
+ "icon": {
+ "type": ["null", "string"]
+ },
+ "bitrate": {
+ "type": "integer"
+ },
+ "user_limit": {
+ "type": "integer"
+ },
+ "rate_limit_per_user": {
+ "type": "integer"
+ },
+ "position": {
+ "type": "integer"
+ },
+ "permission_overwrites": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/definitions/ChannelPermissionOverwriteType"
+ },
+ "allow": {
+ "type": "string"
+ },
+ "deny": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["allow", "deny", "id", "type"]
+ }
+ },
+ "parent_id": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "nsfw": {
+ "type": "boolean"
+ },
+ "rtc_region": {
+ "type": "string"
+ },
+ "default_auto_archive_duration": {
+ "type": "integer"
+ },
+ "flags": {
+ "type": "integer"
+ },
+ "default_thread_rate_limit_per_user": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ },
+ "ChannelPermissionOverwriteType": {
+ "enum": [0, 1, 2],
+ "type": "number"
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "GuildTemplateCreateSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "avatar": {
+ "type": ["null", "string"]
+ }
+ },
+ "additionalProperties": false,
+ "required": ["name"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "GuildUpdateSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "banner": {
+ "type": ["null", "string"]
+ },
+ "splash": {
+ "type": ["null", "string"]
+ },
+ "description": {
+ "type": "string"
+ },
+ "features": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "verification_level": {
+ "type": "integer"
+ },
+ "default_message_notifications": {
+ "type": "integer"
+ },
+ "system_channel_flags": {
+ "type": "integer"
+ },
+ "explicit_content_filter": {
+ "type": "integer"
+ },
+ "public_updates_channel_id": {
+ "type": "string"
+ },
+ "afk_timeout": {
+ "type": "integer"
+ },
+ "afk_channel_id": {
+ "type": "string"
+ },
+ "preferred_locale": {
+ "type": "string"
+ },
+ "premium_progress_bar_enabled": {
+ "type": "boolean"
+ },
+ "region": {
+ "type": "string"
+ },
+ "icon": {
+ "type": ["null", "string"]
+ },
+ "guild_template_code": {
+ "type": "string"
+ },
+ "system_channel_id": {
+ "type": "string"
+ },
+ "rules_channel_id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "GuildUpdateWelcomeScreenSchema": {
+ "type": "object",
+ "properties": {
+ "welcome_channels": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "channel_id": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "emoji_id": {
+ "type": "string"
+ },
+ "emoji_name": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["channel_id", "description", "emoji_name"]
+ }
+ },
+ "enabled": {
+ "type": "boolean"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "IdentifySchema": {
+ "type": "object",
+ "properties": {
+ "token": {
+ "type": "string"
+ },
+ "properties": {
+ "type": "object",
+ "properties": {
+ "os": {
+ "type": "string"
+ },
+ "os_atch": {
+ "type": "string"
+ },
+ "browser": {
+ "type": "string"
+ },
+ "device": {
+ "type": "string"
+ },
+ "$os": {
+ "type": "string"
+ },
+ "$browser": {
+ "type": "string"
+ },
+ "$device": {
+ "type": "string"
+ },
+ "browser_user_agent": {
+ "type": "string"
+ },
+ "browser_version": {
+ "type": "string"
+ },
+ "os_version": {
+ "type": "string"
+ },
+ "referrer": {
+ "type": "string"
+ },
+ "referring_domain": {
+ "type": "string"
+ },
+ "referrer_current": {
+ "type": "string"
+ },
+ "referring_domain_current": {
+ "type": "string"
+ },
+ "release_channel": {
+ "enum": ["canary", "dev", "ptb", "stable"],
+ "type": "string"
+ },
+ "client_build_number": {
+ "type": "integer"
+ },
+ "client_event_source": {},
+ "client_version": {
+ "type": "string"
+ },
+ "system_locale": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "intents": {
+ "type": "string"
+ },
+ "presence": {
+ "$ref": "#/definitions/ActivitySchema"
+ },
+ "compress": {
+ "type": "boolean"
+ },
+ "large_threshold": {
+ "type": "integer"
+ },
+ "shard": {
+ "type": "array",
+ "items": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "integer"
+ }
+ ],
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "guild_subscriptions": {
+ "type": "boolean"
+ },
+ "capabilities": {
+ "type": "integer"
+ },
+ "client_state": {
+ "type": "object",
+ "properties": {
+ "guild_hashes": {},
+ "highest_last_message_id": {
+ "type": "string"
+ },
+ "read_state_version": {
+ "type": "integer"
+ },
+ "user_guild_settings_version": {
+ "type": "integer"
+ },
+ "user_settings_version": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ },
+ "v": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["properties", "token"],
+ "definitions": {
+ "ActivitySchema": {
+ "type": "object",
+ "properties": {
+ "afk": {
+ "type": "boolean"
+ },
+ "status": {},
+ "activities": {
+ "type": "array",
+ "items": {}
+ },
+ "since": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["afk", "status"]
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "InviteCreateSchema": {
+ "type": "object",
+ "properties": {
+ "target_user_id": {
+ "type": "string"
+ },
+ "target_type": {
+ "type": "string"
+ },
+ "validate": {
+ "type": "string"
+ },
+ "max_age": {
+ "type": "integer"
+ },
+ "max_uses": {
+ "type": "integer"
+ },
+ "temporary": {
+ "type": "boolean"
+ },
+ "unique": {
+ "type": "boolean"
+ },
+ "target_user": {
+ "type": "string"
+ },
+ "target_user_type": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "LoginSchema": {
+ "type": "object",
+ "properties": {
+ "login": {
+ "type": "string"
+ },
+ "password": {
+ "type": "string"
+ },
+ "undelete": {
+ "type": "boolean"
+ },
+ "captcha_key": {
+ "type": "string"
+ },
+ "login_source": {
+ "type": "string"
+ },
+ "gift_code_sku_id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["login", "password"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "MemberChangeSchema": {
+ "type": "object",
+ "properties": {
+ "roles": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "MemberNickChangeSchema": {
+ "type": "object",
+ "properties": {
+ "nick": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["nick"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "MessageAcknowledgeSchema": {
+ "type": "object",
+ "properties": {
+ "manual": {
+ "type": "boolean"
+ },
+ "mention_count": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "MessageCreateSchema": {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "integer"
+ },
+ "content": {
+ "type": "string"
+ },
+ "nonce": {
+ "type": "string"
+ },
+ "channel_id": {
+ "type": "string"
+ },
+ "tts": {
+ "type": "boolean"
+ },
+ "flags": {
+ "type": "string"
+ },
+ "embeds": {
+ "type": "array",
+ "items": {}
+ },
+ "embed": {},
+ "allowed_mentions": {
+ "type": "object",
+ "properties": {
+ "parse": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "roles": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "users": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "replied_user": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false
+ },
+ "message_reference": {
+ "type": "object",
+ "properties": {
+ "message_id": {
+ "type": "string"
+ },
+ "channel_id": {
+ "type": "string"
+ },
+ "guild_id": {
+ "type": "string"
+ },
+ "fail_if_not_exists": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["channel_id", "message_id"]
+ },
+ "payload_json": {
+ "type": "string"
+ },
+ "file": {},
+ "attachments": {
+ "description": "TODO: we should create an interface for attachments\nTODO: OpenWAAO<-->attachment-style metadata conversion",
+ "type": "array",
+ "items": {}
+ },
+ "sticker_ids": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "MfaCodesSchema": {
+ "type": "object",
+ "properties": {
+ "password": {
+ "type": "string"
+ },
+ "regenerate": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["password"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ModifyGuildStickerSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "minLength": 2,
+ "maxLength": 30,
+ "type": "string"
+ },
+ "description": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "tags": {
+ "maxLength": 200,
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["name", "tags"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "PruneSchema": {
+ "type": "object",
+ "properties": {
+ "days": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["days"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "PurgeSchema": {
+ "type": "object",
+ "properties": {
+ "before": {
+ "type": "string"
+ },
+ "after": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["after", "before"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "RegisterSchema": {
+ "type": "object",
+ "properties": {
+ "username": {
+ "minLength": 2,
+ "maxLength": 32,
+ "type": "string"
+ },
+ "password": {
+ "minLength": 1,
+ "maxLength": 72,
+ "type": "string"
+ },
+ "consent": {
+ "type": "boolean"
+ },
+ "email": {
+ "format": "email",
+ "type": "string"
+ },
+ "fingerprint": {
+ "type": "string"
+ },
+ "invite": {
+ "type": "string"
+ },
+ "date_of_birth": {
+ "type": "string"
+ },
+ "gift_code_sku_id": {
+ "type": "string"
+ },
+ "captcha_key": {
+ "type": "string"
+ },
+ "promotional_email_opt_in": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["consent", "username"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "RelationshipPostSchema": {
+ "type": "object",
+ "properties": {
+ "discriminator": {
+ "type": "string"
+ },
+ "username": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["discriminator", "username"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "RelationshipPutSchema": {
+ "type": "object",
+ "properties": {
+ "type": {}
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "RoleModifySchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "permissions": {
+ "type": "string"
+ },
+ "color": {
+ "type": "integer"
+ },
+ "hoist": {
+ "type": "boolean"
+ },
+ "mentionable": {
+ "type": "boolean"
+ },
+ "position": {
+ "type": "integer"
+ },
+ "icon": {
+ "type": "string"
+ },
+ "unicode_emoji": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "RolePositionUpdateSchema": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "position": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["id", "position"]
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "TemplateCreateSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["name"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "TemplateModifySchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["name"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "TotpDisableSchema": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["code"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "TotpEnableSchema": {
+ "type": "object",
+ "properties": {
+ "password": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ },
+ "secret": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["password"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "TotpSchema": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "string"
+ },
+ "ticket": {
+ "type": "string"
+ },
+ "gift_code_sku_id": {
+ "type": ["null", "string"]
+ },
+ "login_source": {
+ "type": ["null", "string"]
+ }
+ },
+ "additionalProperties": false,
+ "required": ["code", "ticket"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "UserModifySchema": {
+ "type": "object",
+ "properties": {
+ "username": {
+ "minLength": 1,
+ "maxLength": 100,
+ "type": "string"
+ },
+ "discriminator": {
+ "type": "string"
+ },
+ "avatar": {
+ "type": ["null", "string"]
+ },
+ "bio": {
+ "maxLength": 1024,
+ "type": "string"
+ },
+ "accent_color": {
+ "type": "integer"
+ },
+ "banner": {
+ "type": ["null", "string"]
+ },
+ "password": {
+ "type": "string"
+ },
+ "new_password": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "UserSettingsSchema": {
+ "type": "object",
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "VanityUrlSchema": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "minLength": 1,
+ "maxLength": 20,
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "VoiceStateUpdateSchema": {
+ "type": "object",
+ "properties": {
+ "channel_id": {
+ "type": "string"
+ },
+ "guild_id": {
+ "type": "string"
+ },
+ "suppress": {
+ "type": "boolean"
+ },
+ "request_to_speak_timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "self_mute": {
+ "type": "boolean"
+ },
+ "self_deaf": {
+ "type": "boolean"
+ },
+ "self_video": {
+ "type": "boolean"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["channel_id"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "WebhookCreateSchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "maxLength": 80,
+ "type": "string"
+ },
+ "avatar": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["name"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "WidgetModifySchema": {
+ "type": "object",
+ "properties": {
+ "enabled": {
+ "type": "boolean"
+ },
+ "channel_id": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["channel_id", "enabled"],
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ },
+ "ChannelModifySchema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "maxLength": 100,
+ "type": "string"
+ },
+ "type": {
+ "enum": [0, 1, 10, 11, 12, 13, 14, 15, 2, 255, 3, 33, 34, 35, 4, 5, 6, 64, 7, 8, 9],
+ "type": "number"
+ },
+ "topic": {
+ "type": "string"
+ },
+ "icon": {
+ "type": ["null", "string"]
+ },
+ "bitrate": {
+ "type": "integer"
+ },
+ "user_limit": {
+ "type": "integer"
+ },
+ "rate_limit_per_user": {
+ "type": "integer"
+ },
+ "position": {
+ "type": "integer"
+ },
+ "permission_overwrites": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "type": {
+ "$ref": "#/definitions/ChannelPermissionOverwriteType"
+ },
+ "allow": {
+ "type": "string"
+ },
+ "deny": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["allow", "deny", "id", "type"]
+ }
+ },
+ "parent_id": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "nsfw": {
+ "type": "boolean"
+ },
+ "rtc_region": {
+ "type": "string"
+ },
+ "default_auto_archive_duration": {
+ "type": "integer"
+ },
+ "flags": {
+ "type": "integer"
+ },
+ "default_thread_rate_limit_per_user": {
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false,
+ "definitions": {
+ "ChannelPermissionOverwriteType": {
+ "enum": [0, 1, 2],
+ "type": "number"
+ }
+ },
+ "$schema": "http://json-schema.org/draft-07/schema#"
+ }
+}
diff --git a/assets/user.css b/assets/user.css
index a7e5c4f3..652306af 100644
--- a/assets/user.css
+++ b/assets/user.css
@@ -1 +1 @@
-/* Your custom CSS goes here, enjoy! */
\ No newline at end of file
+/* Your custom CSS goes here, enjoy! */
diff --git a/build.json.default b/build.json.default
new file mode 100644
index 00000000..cac0a850
--- /dev/null
+++ b/build.json.default
@@ -0,0 +1,16 @@
+{
+ "compiler": "tsc",
+ "verbose": true,
+ "writeBuildLog": true,
+ "writeAnsiBuildLog": true,
+ "logErrors": true,
+ "tsc": {
+ "prettyErrors": true
+ },
+ "clean": true,
+ "quiet": false,
+ "steps": {
+ "pre": ["clean"],
+ "post": ["remap_imports"]
+ }
+}
diff --git a/docker-compose.cfg.yml b/docker-compose.cfg.yml
index 18a7031d..e7a4b879 100644
--- a/docker-compose.cfg.yml
+++ b/docker-compose.cfg.yml
@@ -1,6 +1,5 @@
-version: '3.9'
+version: "3.9"
services:
-
- fosscord:
- entrypoint: [ "npm", "run", "setup" ]
+ fosscord:
+ entrypoint: ["npm", "run", "setup"]
diff --git a/docker-compose.yml b/docker-compose.yml
index 4dc1ee41..8da4010c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,25 +1,24 @@
-version: '3.9'
+version: "3.9"
services:
-
- fosscord:
- container_name: fosscord
- image: fosscord
- restart: on-failure:5
- build: .
- ports:
- - '3001-3005:3001-3005'
- volumes:
- - ./:/srv/fosscord-server/
- environment:
- THREADS: ${THREADS:-1}
- HTTP_PORT: 3001
- WS_PORT: 3002
- CDN_PORT: 3003
- RTC_PORT: 3004
- ADMIN_PORT: 3005
+ fosscord:
+ container_name: fosscord
+ image: fosscord
+ restart: on-failure:5
+ build: .
+ ports:
+ - "3001-3005:3001-3005"
+ volumes:
+ - ./:/srv/fosscord-server/
+ environment:
+ THREADS: ${THREADS:-1}
+ HTTP_PORT: 3001
+ WS_PORT: 3002
+ CDN_PORT: 3003
+ RTC_PORT: 3004
+ ADMIN_PORT: 3005
networks:
- default:
- name: fosscord
- driver: bridge
+ default:
+ name: fosscord
+ driver: bridge
diff --git a/env-vars.md b/env-vars.md
index 6c56c184..c66a7a9b 100644
--- a/env-vars.md
+++ b/env-vars.md
@@ -1,18 +1,18 @@
#Fosscord Environment Variables:
-|NAME|VALUE|DESCRIPTION|
-|----|-----|-----------|
-|LOG\_REQUESTS | ports to include, or exclude (-) | logs requests |
-|PORT|number|sets port number to listen on|
-|CDN|string|CDN address|
-|GATEWAY|string|Gateway address|
-|NODE\_ENV|production/development|sets node environment|
-|DATABASE|database url|points to what database to use|
-|EVENT\_TRANSMISSION|string|event transmission type|
-|STORAGE\_PROVIDER|s3/file|How to store files for CDN|
-|STORAGE\_LOCATION|path|Directory to store files in|
-|STORAGE\_BUCKET|s3 bucket name|S3 bucket name|
-|DB\_UNSAFE|any|Ignores migrations for database, enabled if defined|
-|DB\_VERBOSE|any|Log database queries, enabled if defined|
-|DB\_MIGRATE|any|Exit fosscord after connecting to and migrating database, used internally|
-|LOG\_INVALID\_BODY|any|Log request method, path and body if invalid|
+| NAME | VALUE | DESCRIPTION |
+| ------------------ | -------------------------------- | ------------------------------------------------------------------------- |
+| LOG_REQUESTS | ports to include, or exclude (-) | logs requests |
+| PORT | number | sets port number to listen on |
+| CDN | string | CDN address |
+| GATEWAY | string | Gateway address |
+| NODE_ENV | production/development | sets node environment |
+| DATABASE | database url | points to what database to use |
+| EVENT_TRANSMISSION | string | event transmission type |
+| STORAGE_PROVIDER | s3/file | How to store files for CDN |
+| STORAGE_LOCATION | path | Directory to store files in |
+| STORAGE_BUCKET | s3 bucket name | S3 bucket name |
+| DB_UNSAFE | any | Ignores migrations for database, enabled if defined |
+| DB_VERBOSE | any | Log database queries, enabled if defined |
+| DB_MIGRATE | any | Exit fosscord after connecting to and migrating database, used internally |
+| LOG_INVALID_BODY | any | Log request method, path and body if invalid |
diff --git a/fosscord-server.code-workspace b/fosscord-server.code-workspace
index f2df1e9e..56450f85 100644
--- a/fosscord-server.code-workspace
+++ b/fosscord-server.code-workspace
@@ -17,5 +17,22 @@
"files.exclude": {
"*.ansi": true,
}
+ },
+ "launch": {
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "command": "npm run start:bundle:vscode-dbg",
+ "name": "Run Fosscord with debugger",
+ "request": "launch",
+ "type": "node-terminal"
+ },
+ {
+ "command": "kitty npm run start:bundle:vscode-dbg",
+ "name": "Run Fosscord with debugger (kitty)",
+ "request": "launch",
+ "type": "node-terminal"
+ }
+ ]
}
-}
\ No newline at end of file
+}
diff --git a/package.json b/package.json
index a6d3ed0a..44be6b7f 100644
--- a/package.json
+++ b/package.json
@@ -4,18 +4,18 @@
"description": "",
"main": "src/start.js",
"scripts": {
- "setup": "npm install --omit optional && ts-patch install -s && patch-package && npm run build",
+ "setup": "npm install --omit optional && patch-package && npm run build",
+ "build": "node scripts/build_new.js",
+ "start": "npm run build && npm run start:bundle",
+ "start:bundle": "node --enable-source-maps dist/start.js",
+ "start:bundle:dbg": "node --enable-source-maps --inspect dist/start.js",
+ "start:bundle:vscode-dbg": "npm run build && node --enable-source-maps --inspect dist/start.js",
"depclean": "node scripts/depclean.js",
"depcheck": "node scripts/depcheck.js",
- "build": "node scripts/build.js",
- "postinstall": "patch-package",
+ "tsnode": "npx ts-node --transpile-only -P tsnode.tsconfig.json src/start.ts",
"genschemas": "node scripts/generate_schemas.js",
- "start": "node scripts/build.js && node --enable-source-maps dist/start.js",
- "start:bundle": "node --enable-source-maps dist/start.js",
- "start:bundle:dbg": "node --enable-source-maps --inspect dist/start.js",
- "start:bundle:vscode-dbg": "npm run build clean logerrors pretty-errors && node --enable-source-maps --inspect dist/start.js",
"migrate": "cd ../util/ && npm i && node --require ts-node/register node_modules/typeorm/cli.js -f ../util/ormconfig.json migration:run",
- "tsnode": "npx ts-node --transpile-only -P tsnode.tsconfig.json src/start.ts"
+ "postinstall": "patch-package && npx --yes node-git-hooks"
},
"repository": {
"type": "git",
@@ -28,12 +28,16 @@
"url": "https://github.com/fosscord/fosscord-server/issues"
},
"homepage": "https://fosscord.com",
+ "imports": {
+ "#*": "./dist/*/index.js"
+ },
"devDependencies": {
"@babel/core": "^7.18.9",
"@babel/preset-env": "^7.18.9",
"@babel/preset-typescript": "^7.15.0",
"@types/amqplib": "^0.8.1",
"@types/bcrypt": "^5.0.0",
+ "@types/bcryptjs": "^2.4.2",
"@types/body-parser": "^1.19.0",
"@types/dotenv": "^8.2.0",
"@types/express": "^4.17.12",
@@ -42,30 +46,29 @@
"@types/morgan": "^1.9.3",
"@types/multer": "^1.4.7",
"@types/node": "^18.7.3",
+ "@types/node-fetch": "^2.6.2",
"@types/node-os-utils": "^1.3.0",
"@types/ws": "^8.5.3",
"jest": "^28.1.3",
"jest-expect-message": "^1.0.2",
+ "prettier-plugin-organize-imports": "^3.0.3",
"supertest": "^6.1.6",
"ts-node": "^10.2.1",
"ts-node-dev": "^2.0.0",
- "ts-patch": "^2.0.2",
"typescript": "^4.2.3",
"typescript-json-schema": "^0.54.0"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.137.0",
"@babel/preset-typescript": "^7.15.0",
- "@ovos-media/ts-transform-paths": "^1.7.18-1",
"@sentry/node": "^7.7.0",
"@sentry/tracing": "^7.7.0",
- "@types/node-fetch": "^2.6.2",
"ajv": "^8.6.2",
"ajv-formats": "^2.1.1",
"amqplib": "^0.10.1",
"bcrypt": "^5.0.1",
+ "bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
- "canvas": "^2.9.3",
"cheerio": "^1.0.0-rc.10",
"dotenv": "^16.0.1",
"exif-be-gone": "^1.3.1",
@@ -93,6 +96,7 @@
"ws": "^8.8.1"
},
"optionalDependencies": {
+ "canvas": "^2.9.3",
"mysql2": "^2.3.3",
"pg": "^8.7.3",
"sqlite3": "^5.0.11"
diff --git a/scripts/benchmark.js b/scripts/benchmark.js
index e7435191..53db92c5 100644
--- a/scripts/benchmark.js
+++ b/scripts/benchmark.js
@@ -3,9 +3,7 @@ const Models = require("../dist/entities");
const { PrimaryColumn } = require("typeorm");
function shouldIncludeEntity(name) {
- return ![Models.BaseClassWithoutId, PrimaryColumn, Models.BaseClass, Models.PrimaryGeneratedColumn]
- .map((x) => x?.name)
- .includes(name);
+ return ![Models.BaseClassWithoutId, PrimaryColumn, Models.BaseClass, Models.PrimaryGeneratedColumn].map((x) => x?.name).includes(name);
}
async function main() {
@@ -14,7 +12,7 @@ async function main() {
type: "sqlite",
database: ":memory:",
entities: Object.values(Models).filter((x) => x.constructor.name == "Function" && shouldIncludeEntity(x.name)),
- synchronize: true,
+ synchronize: true
});
await db.initialize();
console.log("Initialized database");
diff --git a/scripts/benchmark/connections.js b/scripts/benchmark/connections.js
index 661548c3..f74d0c6d 100644
--- a/scripts/benchmark/connections.js
+++ b/scripts/benchmark/connections.js
@@ -8,7 +8,7 @@ let cores = 1;
try {
cores = Number(process.env.THREADS) || os.cpus().length;
} catch {
- console.log("[Bundle] Failed to get thread count! Using 1...")
+ console.log("[Bundle] Failed to get thread count! Using 1...");
}
if (!token) {
@@ -46,8 +46,8 @@ function connect() {
op: 2,
d: {
token,
- properties: {},
- },
+ properties: {}
+ }
})
);
diff --git a/scripts/benchmark/users.js b/scripts/benchmark/users.js
index bce67bf4..415d6d8b 100644
--- a/scripts/benchmark/users.js
+++ b/scripts/benchmark/users.js
@@ -14,9 +14,9 @@ async function main() {
consent: true,
date_of_birth: "2000-01-01",
gift_code_sku_id: null,
- captcha_key: null,
+ captcha_key: null
}),
- headers: { "content-type": "application/json" },
+ headers: { "content-type": "application/json" }
});
console.log(i);
}
diff --git a/scripts/build.js b/scripts/build.js
index 2c0d7328..f618100c 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -2,20 +2,22 @@ const { execSync } = require("child_process");
const path = require("path");
const fs = require("fs");
const { argv, stdout, exit } = require("process");
-const { execIn, parts } = require('./utils');
+const { execIn, parts, getDirs, walk, sanitizeVarName } = require("./utils");
-if(argv.includes("help")) {
+if (argv.includes("help")) {
console.log(`Fosscord build script help:
Arguments:
clean Cleans up previous builds
verbose Enable verbose logging
logerrors Log build errors to console
pretty-errors Pretty-print build errors
- silent No output to console or files.`);
+ silent No output to console or files.
+ propagate-err Exit script with error code if build fails.`);
exit(0);
}
-let steps = 1, i = 0;
+let steps = 5,
+ i = 0;
if (argv.includes("clean")) steps++;
const verbose = argv.includes("verbose") || argv.includes("v");
@@ -23,7 +25,7 @@ const logerr = argv.includes("logerrors");
const pretty = argv.includes("pretty-errors");
const silent = argv.includes("silent");
-if(silent) console.error = console.log = function(){}
+if (silent) console.error = console.log = function () {};
if (argv.includes("clean")) {
console.log(`[${++i}/${steps}] Cleaning...`);
@@ -36,37 +38,79 @@ if (argv.includes("clean")) {
console.log(`[${++i}/${steps}] Compiling src files ...`);
-let buildFlags = ''
-if(pretty) buildFlags += '--pretty '
+let buildFlags = "";
+if (pretty) buildFlags += "--pretty ";
-try {
- execSync(
- 'node "' +
- path.join(__dirname, "..", "node_modules", "typescript", "lib", "tsc.js") +
- '" -p "' +
- path.join(__dirname, "..") +
- '" ' + buildFlags,
- {
- cwd: path.join(__dirname, ".."),
- shell: true,
- env: process.env,
- encoding: "utf8"
- }
- )
-} catch (error) {
- if(verbose || logerr) {
- error.stdout.split(/\r?\n/).forEach((line) => {
- let _line = line.replace('dist/','',1);
- if(!pretty && _line.includes('.ts(')) {
- //reformat file path for easy jumping
- _line = _line.replace('(',':',1).replace(',',':',1).replace(')','',1)
- }
- console.error(_line);
- })
+console.log(`[${++i}/${steps}] Building plugin index...`);
+let pluginDir = path.join(__dirname, "..", "src", "plugins");
+let output = 'import { Plugin } from "util/plugin";\n';
+
+const dirs = fs.readdirSync(pluginDir).filter((x) => {
+ try {
+ fs.readdirSync(path.join(pluginDir, x));
+ return true;
+ } catch (e) {
+ return false;
}
- console.error(`Build failed! Please check build.log for info!`);
- if(!silent){
- if(pretty) fs.writeFileSync("build.log.ansi", error.stdout);
- fs.writeFileSync("build.log", error.stdout.replaceAll(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ''));
+});
+dirs.forEach((x) => {
+ let pluginManifest = require(path.join(pluginDir, x, "plugin.json"));
+ output += `import * as ${sanitizeVarName(x)} from "./${x}/${pluginManifest.mainClass}";\n`;
+});
+output += `\nexport const PluginIndex: any = {\n`;
+dirs.forEach((x) => {
+ output += ` "${x}": new ${sanitizeVarName(x)}.default(),\n`; //ctor test: '${path.resolve(path.join(pluginDir, x))}', require('./${x}/plugin.json')
+});
+output += `};`;
+
+fs.writeFileSync(path.join(__dirname, "..", "src", "plugins", "PluginIndex.ts"), output);
+
+if (!argv.includes("copyonly")) {
+ console.log(`[${++i}/${steps}] Compiling source code...`);
+
+ let buildFlags = "";
+ if (pretty) buildFlags += "--pretty ";
+
+ try {
+ execSync(
+ 'node "' +
+ path.join(__dirname, "..", "node_modules", "typescript", "lib", "tsc.js") +
+ '" -p "' +
+ path.join(__dirname, "..") +
+ '" ' +
+ buildFlags,
+ {
+ cwd: path.join(__dirname, ".."),
+ shell: true,
+ env: process.env,
+ encoding: "utf8"
+ }
+ );
+ } catch (error) {
+ if (verbose || logerr) {
+ error.stdout.split(/\r?\n/).forEach((line) => {
+ let _line = line.replace("dist/", "", 1);
+ if (!pretty && _line.includes(".ts(")) {
+ //reformat file path for easy jumping
+ _line = _line.replace("(", ":", 1).replace(",", ":", 1).replace(")", "", 1);
+ }
+ console.error(_line);
+ });
+ }
+ console.error(`Build failed! Please check build.log for info!`);
+ if (!silent) {
+ if (pretty) fs.writeFileSync("build.log.ansi", error.stdout);
+ fs.writeFileSync(
+ "build.log",
+ error.stdout.replaceAll(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "")
+ );
+ }
+ throw error;
}
-}
\ No newline at end of file
+}
+
+console.log(`[${++i}/${steps}] Copying plugin data...`);
+let pluginFiles = walk(pluginDir).filter((x) => !x.endsWith(".ts"));
+pluginFiles.forEach((x) => {
+ fs.copyFileSync(x, x.replace("src", "dist"));
+});
diff --git a/scripts/build/clean.js b/scripts/build/clean.js
new file mode 100644
index 00000000..92ec6d77
--- /dev/null
+++ b/scripts/build/clean.js
@@ -0,0 +1,18 @@
+const { execSync } = require("child_process");
+const path = require("path");
+const fs = require("fs");
+const { argv, stdout, exit } = require("process");
+const { execIn, parts, getDirs, walk, sanitizeVarName } = require("../utils");
+
+module.exports = function (config) {
+ if (fs.existsSync(config.buildLog)) fs.rmSync(config.buildLog);
+ if (fs.existsSync(config.buildLogAnsi)) fs.rmSync(config.buildLogAnsi);
+
+ if (config.clean) {
+ console.log(`==> Cleaning...`);
+ if (fs.existsSync(config.distDir)) {
+ fs.rmSync(config.distDir, { recursive: true });
+ if (config.verbose) console.log(`Deleted ${path.resolve(config.distDir)}!`);
+ }
+ }
+};
diff --git a/scripts/build/compile_tsc.js b/scripts/build/compile_tsc.js
new file mode 100644
index 00000000..179707a3
--- /dev/null
+++ b/scripts/build/compile_tsc.js
@@ -0,0 +1,48 @@
+const { execSync } = require("child_process");
+const path = require("path");
+const fs = require("fs");
+const { argv, stdout, exit } = require("process");
+const { execIn, parts, getDirs, walk, sanitizeVarName } = require("../utils");
+
+module.exports = function (config) {
+ console.log("==> Compiling source with tsc...");
+ let buildFlags = "";
+ if (config.pretty) buildFlags += "--pretty ";
+
+ try {
+ execSync(
+ 'node "' +
+ path.join(config.rootDir, "node_modules", "typescript", "lib", "tsc.js") +
+ '" -p "' +
+ path.join(config.rootDir) +
+ '" ' +
+ buildFlags,
+ {
+ cwd: path.join(config.rootDir),
+ shell: true,
+ env: process.env,
+ encoding: "utf8"
+ }
+ );
+ } catch (error) {
+ if (config.verbose || config.logerr) {
+ error.stdout.split(/\r?\n/).forEach((line) => {
+ let _line = line.replace("dist/", "", 1);
+ if (!config.pretty && _line.includes(".ts(")) {
+ //reformat file path for easy jumping
+ _line = _line.replace("(", ":", 1).replace(",", ":", 1).replace(")", "", 1);
+ }
+ console.error(_line);
+ });
+ }
+ console.error(`Build failed! Please check build.log for info!`);
+ if (!config.silent) {
+ if (config.pretty) fs.writeFileSync(path.join(config.rootDir, "build.log.ansi"), error.stdout);
+ fs.writeFileSync(
+ path.join(config.rootDir, "build.log"),
+ error.stdout.replaceAll(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "")
+ );
+ }
+ throw error;
+ }
+};
diff --git a/scripts/build/plugin_prepare.js b/scripts/build/plugin_prepare.js
new file mode 100644
index 00000000..247ad22d
--- /dev/null
+++ b/scripts/build/plugin_prepare.js
@@ -0,0 +1,31 @@
+const { execSync } = require("child_process");
+const path = require("path");
+const fs = require("fs");
+const { argv, stdout, exit } = require("process");
+const { execIn, parts, getDirs, walk, sanitizeVarName } = require("../utils");
+
+module.exports = function (config) {
+ console.log(`==> Building plugin index...`);
+ let output = 'import { Plugin } from "util/plugin";\n';
+
+ const dirs = fs.readdirSync(config.pluginDir).filter((x) => {
+ try {
+ fs.readdirSync(path.join(config.pluginDir, x));
+ return true;
+ } catch (e) {
+ return false;
+ }
+ });
+ dirs.forEach((x) => {
+ let pluginManifest = require(path.join(config.pluginDir, x, "plugin.json"));
+ console.log(` ==> Registering plugin: ${pluginManifest.name} (${pluginManifest.id}) by ${pluginManifest.authors}`);
+ output += `import * as ${sanitizeVarName(x)} from "./${x}/${pluginManifest.mainClass}";\n`;
+ });
+ output += `\nexport const PluginIndex: any = {\n`;
+ dirs.forEach((x) => {
+ output += ` "${x}": new ${sanitizeVarName(x)}.default(),\n`; //ctor test: '${path.resolve(path.join(pluginDir, x))}', require('./${x}/plugin.json')
+ });
+ output += `};`;
+
+ fs.writeFileSync(path.join(config.pluginDir, "PluginIndex.ts"), output);
+};
diff --git a/scripts/build/plugin_resources.js b/scripts/build/plugin_resources.js
new file mode 100644
index 00000000..5b4b97f2
--- /dev/null
+++ b/scripts/build/plugin_resources.js
@@ -0,0 +1,13 @@
+const { execSync } = require("child_process");
+const path = require("path");
+const fs = require("fs");
+const { argv, stdout, exit } = require("process");
+const { execIn, parts, getDirs, walk, sanitizeVarName } = require("../utils");
+
+module.exports = function (config) {
+ console.log(`==> Copying all plugin resources...`);
+ let pluginFiles = walk(config.pluginDir).filter((x) => !x.endsWith(".ts"));
+ pluginFiles.forEach((x) => {
+ fs.copyFileSync(x, x.replace("src", "dist"));
+ });
+};
diff --git a/scripts/build/remap_imports.js b/scripts/build/remap_imports.js
new file mode 100644
index 00000000..cdcd571a
--- /dev/null
+++ b/scripts/build/remap_imports.js
@@ -0,0 +1,15 @@
+const { execSync } = require("child_process");
+const path = require("path");
+const fs = require("fs");
+const { argv, stdout, exit } = require("process");
+const { execIn, parts, getDirs, walk, sanitizeVarName } = require("../utils");
+
+module.exports = function (config) {
+ console.log(`==> Remapping module imports...`);
+ let files = walk(config.distDir).filter((x) => x.endsWith(".js"));
+ files.forEach((x) => {
+ let fc = fs.readFileSync(x).toString();
+ fc = fc.replaceAll("@fosscord/", "#");
+ fs.writeFileSync(x, fc);
+ });
+};
diff --git a/scripts/build_new.js b/scripts/build_new.js
new file mode 100644
index 00000000..6a56e7f7
--- /dev/null
+++ b/scripts/build_new.js
@@ -0,0 +1,31 @@
+const { execSync } = require("child_process");
+const path = require("path");
+const fs = require("fs");
+const { argv, stdout, exit } = require("process");
+const { execIn, parts, getDirs, walk, sanitizeVarName } = require("./utils");
+
+//file paths
+const rootDir = path.join(__dirname, "..");
+const srcDir = path.join(rootDir, "src");
+const distDir = path.join(rootDir, "dist");
+const scriptsDir = path.join(rootDir, "scripts");
+const configPath = path.join(rootDir, "build.json");
+const buildLog = path.join(rootDir, "build.log");
+const buildLogAnsi = path.join(rootDir, "build.log.ansi");
+const pluginDir = path.join(srcDir, "plugins");
+
+//more, dont export
+const buildStepDir = path.join(scriptsDir, "build");
+
+if (!fs.existsSync(configPath)) {
+ if (!fs.existsSync(path.join(configPath + ".default"))) {
+ console.log("build.json.default not found! Exiting!");
+ exit(1);
+ }
+ fs.copyFileSync(configPath + ".default", configPath);
+}
+let config = { rootDir, srcDir, distDir, configPath, buildLog, buildLogAnsi, pluginDir, ...require(configPath) };
+
+config.steps.pre.forEach((step) => require(path.join(buildStepDir, step))(config));
+require(path.join(buildStepDir, "compile_" + config.compiler))(config);
+config.steps.post.forEach((step) => require(path.join(buildStepDir, step))(config));
diff --git a/scripts/code_quality.js b/scripts/code_quality.js
new file mode 100644
index 00000000..aca01d24
--- /dev/null
+++ b/scripts/code_quality.js
@@ -0,0 +1,75 @@
+const path = require("path");
+const fs = require("fs").promises;
+const { execIn, getLines, walk, projectRoot } = require("./utils");
+
+let printTodos = process.argv.includes("TODOS");
+
+let root = path.resolve(path.join(__dirname, "..", "src"));
+let files = walk(root);
+let _files = [];
+let errors = 0,
+ warnings = 0,
+ todos = 0;
+
+Promise.all(files.map(getFile)).then((f) => {
+ Promise.all(Object.keys(_files).map(checkFile));
+ console.log(`\n${errors} errors, ${warnings} warnings, ${todos} TODOs.`);
+
+ let loc = 0;
+ Object.values(_files).forEach((x) => {
+ loc += x.length;
+ });
+ console.log("\nStats:\n");
+ console.log(`Lines of code: ${loc} lines in ${Object.values(_files).length} files.`);
+
+ debugger;
+});
+
+async function getFile(name) {
+ let contents = (await fs.readFile(name)).toString().split("\n");
+ _files[name] = contents;
+}
+
+async function checkFile(x) {
+ _files[x].forEach((line) => scanLine(x, line));
+}
+
+function log(file, line, msg) {
+ let lineNum = _files[file].indexOf(line) + 1;
+ console.log(msg, "File:", file.replace(root + "/", "") + ":" + lineNum);
+}
+
+function scanLine(x, line) {
+ if (/import/.test(line)) {
+ if (/import {?.*}? from '.*'/.test(line)) {
+ log(x, line, `[WARN] Inconsistent import syntax, please use double quotes!`);
+ warnings++;
+ }
+ } else {
+ if (line.trim().endsWith("TODO:")) {
+ log(x, line, `[ERRO] Empty TODO!`);
+ errors++;
+ } else if (/\/\/\s{0,3}TODO:/.test(line)) {
+ if (printTodos) log(x, line, `[TODO] Found a TODO: ${line.split("TODO:")[1].trim()}.`);
+ todos++;
+ }
+ if (/(:|=)/.test(line)) {
+ if (/(:|=) {2,}/.test(line)) {
+ log(x, line, `[WARN] Multiple spaces in assignment!`);
+ warnings++;
+ }
+ if (/(:|=)\t'/.test(line)) {
+ log(x, line, `[WARN] Tab in assignment!`);
+ warnings++;
+ }
+ if (/(:|=)\w'/.test(line)) {
+ log(x, line, `[WARN] Missing space in assignment!`);
+ warnings++;
+ }
+ if (/(:|=) undefined/.test(line) && !/(:|=){2,} undefined/.test(line)) {
+ log(x, line, `[WARN] Use of undefined!`);
+ warnings++;
+ }
+ }
+ }
+}
diff --git a/scripts/depcheck.js b/scripts/depcheck.js
index 08df156c..44ac2bb6 100644
--- a/scripts/depcheck.js
+++ b/scripts/depcheck.js
@@ -9,22 +9,22 @@ const { execIn, getLines } = require("./utils");
let npmi_extra_flags = "";
const resolveminor = argv.includes("resolveminor");
-if(argv.includes("nobuild")) npmi_extra_flags += "--ignore-scripts ";
+if (argv.includes("nobuild")) npmi_extra_flags += "--ignore-scripts ";
parts.forEach((part) => {
let partDir = path.join(__dirname, "..", "..", part);
let distDir = path.join(partDir, "dist");
console.log(`Checking updates for ${part} (${partDir})`);
- if(part == "bundle") {
- execIn(`npm run syncdeps`, partDir)
+ if (part == "bundle") {
+ execIn(`npm run syncdeps`, partDir);
}
- if(resolveminor) {
- fs.rmSync(path.join(partDir, "node_modules"), {
+ if (resolveminor) {
+ fs.rmSync(path.join(partDir, "node_modules"), {
recursive: true,
- force: true,
+ force: true
});
- execIn(`npm i --save --no-fund --no-audit --no-package-lock ${npmi_extra_flags}`, partDir)
- }
+ execIn(`npm i --save --no-fund --no-audit --no-package-lock ${npmi_extra_flags}`, partDir);
+ }
let x = [
[
"pkg",
@@ -33,24 +33,18 @@ parts.forEach((part) => {
wanted: "2.0",
latest: "2.0",
dependent: "cdn",
- location: "/usr/src/fosscord/bundle/node_packages/pkg",
- },
- ],
+ location: "/usr/src/fosscord/bundle/node_packages/pkg"
+ }
+ ]
];
- x = Object.entries(
- JSON.parse(execIn("npm outdated --json", partDir))
- );
+ x = Object.entries(JSON.parse(execIn("npm outdated --json", partDir)));
x.forEach((a) => {
- let pkgname = a[0];
- let pkginfo = a[1];
- if(!pkginfo.current)
- console.log(`MISSING ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted} (latest: ${pkginfo.latest})`);
- else if(pkginfo.latest != pkginfo.wanted){
- if(pkginfo.current != pkginfo.wanted)
- console.log(`MINOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted}`);
- console.log(`MAJOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.latest}`);
- }
- else
- console.log(`MINOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted}`);
+ let pkgname = a[0];
+ let pkginfo = a[1];
+ if (!pkginfo.current) console.log(`MISSING ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted} (latest: ${pkginfo.latest})`);
+ else if (pkginfo.latest != pkginfo.wanted) {
+ if (pkginfo.current != pkginfo.wanted) console.log(`MINOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted}`);
+ console.log(`MAJOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.latest}`);
+ } else console.log(`MINOR ${pkgname}: ${pkginfo.current} -> ${pkginfo.wanted}`);
});
});
diff --git a/scripts/depclean.js b/scripts/depclean.js
index 333f5aa0..5a402331 100644
--- a/scripts/depclean.js
+++ b/scripts/depclean.js
@@ -3,8 +3,7 @@ const fs = require("fs");
const { env } = require("process");
const { execSync } = require("child_process");
const { argv, stdout, exit } = require("process");
-
-const { execIn, getLines } = require('./utils');
+const { execIn, getLines } = require("./utils");
const bundleRequired = ["@ovos-media/ts-transform-paths"];
const removeModules = argv.includes("cleanup");
@@ -15,13 +14,11 @@ execIn("npm i", path.join(__dirname, ".."));
let partDir = path.join(__dirname, "..");
let distDir = path.join(partDir, "dist");
let start = 0;
-start = getLines(
- execIn("npm ls --parseable --package-lock-only -a", partDir)
-);
+start = getLines(execIn("npm ls --parseable --package-lock-only -a", partDir));
if (fs.existsSync(distDir))
fs.rmSync(distDir, {
recursive: true,
- force: true,
+ force: true
});
let x = {
dependencies: [],
@@ -29,17 +26,13 @@ let x = {
invalidDirs: [],
invalidFiles: [],
missing: [],
- using: [],
+ using: []
};
let dcproc = execIn("npx depcheck --json", partDir);
-if(dcproc.stdout) x = JSON.parse(dcproc.stdout);
+if (dcproc.stdout) x = JSON.parse(dcproc.stdout);
else x = JSON.parse(dcproc);
-fs.writeFileSync(
- path.join(__dirname, "..", `depclean.out.json`),
- JSON.stringify(x, null, "\t"),
- { encoding: "utf8" }
-);
+fs.writeFileSync(path.join(__dirname, "..", `depclean.out.json`), JSON.stringify(x, null, "\t"), { encoding: "utf8" });
let depsToRemove = x.dependencies.join(" ");
if (depsToRemove) execIn(`npm r --save ${depsToRemove}`, partDir);
@@ -50,11 +43,9 @@ if (depsToRemove) execIn(`npm r --save --dev ${depsToRemove}`, partDir);
if (removeModules && fs.existsSync(path.join(partDir, "node_modules")))
fs.rmSync(path.join(partDir, "node_modules"), {
recursive: true,
- force: true,
+ force: true
});
-let end = getLines(
- execIn("npm ls --parseable --package-lock-only -a", partDir)
-);
+let end = getLines(execIn("npm ls --parseable --package-lock-only -a", partDir));
console.log(`${part}: ${start} -> ${end} (diff: ${start - end})`);
console.log("Installing required packages for bundle...");
diff --git a/scripts/first_setup.js b/scripts/first_setup.js
new file mode 100644
index 00000000..24088eee
--- /dev/null
+++ b/scripts/first_setup.js
@@ -0,0 +1,185 @@
+const path = require("path");
+const fs = require("fs");
+const { stdout, exit } = require("process");
+const readline = require("readline");
+
+const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
+const data = { env: [], config: { register: {} } };
+let rights = [];
+
+console.log("Welcome to Fosscord!");
+console.log("Please remember this is pre-release software!");
+console.log("We will guide you through some important setup steps.");
+console.log();
+
+async function main() {
+ printTitle("Step 1: Database setup");
+ console.log("1. PostgreSQL (recommended)");
+ console.log("2. MariaDB/MySQL");
+ console.log("3. SQLite (not recommended, but good for a simple test)");
+
+ while (!data.db) {
+ let answer = await ask("Please select a database type: ");
+ if (answer == "1") {
+ data.db = "postgres";
+ } else if (answer == "2") {
+ data.db = "mariadb";
+ } else if (answer == "3") {
+ data.db = "sqlite";
+ } else {
+ console.log("Invalid choice!");
+ }
+ }
+
+ printTitle("Step 2: Database credentials");
+ if (data.db != "sqlite") {
+ console.log("Please enter your database credentials.");
+ console.log("You can leave the password field empty if you don't want to set a password.");
+ console.log();
+ while (!data.db_host) {
+ data.db_host = await ask("Host: ");
+ }
+ while (!data.db_port) {
+ data.db_port = await ask("Port: ");
+ }
+ while (!data.db_user) {
+ data.db_user = await ask("Username: ");
+ }
+ while (!data.db_pass) {
+ data.db_pass = await ask("Password: ");
+ }
+ while (!data.db_name) {
+ data.db_name = await ask("Database name: ");
+ }
+ } else {
+ console.log("SQLite does not use credentials...");
+ }
+
+ printTitle("Step 3: Domain setup");
+ console.log("Please enter your domain.");
+ console.log("You can leave the port field empty if you don't want to set a port.");
+ console.log();
+
+ data.domain = await ask("Domain (default=localhost): ");
+ if (!data.domain) data.domain = "localhost";
+ else data.ssl = /y?/i.test(await ask("SSL/HTTPS (Y/n): ")).toLowerCase();
+
+ data.port = await ask("Port (default=3001): ");
+ if (!data.port) data.port = "3001";
+
+ if (data.db != "sqlite")
+ data.env.push(`DATABASE=${data.db}://${data.db_user}:${data.db_pass}@${data.db_host}:${data.db_port}/${data.db_name}`);
+ data.env.push(`PORT=${data.port}`);
+
+ printTitle("Step 4: Default rights");
+ console.log("Please enter the default rights for new users.");
+ console.log("Valid rights are: none, discord, full, custom.");
+ console.log();
+ let lines = fs.readFileSync(path.join(__dirname, "..", "src", "util", "util", "Rights.ts")).toString();
+ let lines2 = lines.split("\n");
+ let lines3 = lines2.filter((y) => y.includes(": BitFlag("));
+ let lines4 = lines3.map((x) => x.split("//")[0].trim());
+
+ let maxRights = 0n;
+ lines4.forEach((x) => {
+ maxRights += eval(`rights.${x.replace(":", " = ").replace(",", ";")}`);
+ });
+ discordRights = maxRights;
+ discordRights -= rights.SEND_BACKDATED_EVENTS;
+ discordRights -= rights.MANAGE_GUILD_DIRECTORY;
+ discordRights -= rights.CREDITABLE;
+ discordRights -= rights.BYPASS_RATE_LIMITS;
+ discordRights -= rights.ADD_MEMBERS;
+ discordRights -= rights.MANAGE_RATE_LIMITS;
+ discordRights -= rights.OPERATOR;
+
+ data.default_rights = await ask("Rights (default=none): ");
+ if (!data.default_rights || data.defaultRights == "none") data.config.register.defaultRights = "0";
+ else if (data.default_rights == "discord") data.config.register.defaultRights = discordRights.toString();
+ else if (data.default_rights == "full") data.config.register.defaultRights = maxRights.toString();
+ else if (data.default_rights == "custom") data.config.register.defaultRights = (await askRights()).toString();
+
+ if (data.domain != "localhost")
+ data.config = {
+ cdn: {
+ endpointPrivate: `http://localhost:${data.port}`,
+ endpointPublic: `${data.ssl ? "https" : "http"}://${data.domain}:${data.port}`
+ },
+ gateway: {
+ endpointPrivate: `ws://localhost:${data.port}`,
+ endpointPublic: `${data.ssl ? "wss" : "ws"}://${data.domain}:${data.port}`
+ },
+ ...data.config
+ };
+ //save
+ fs.writeFileSync(".env", data.env.join("\n"));
+ fs.writeFileSync("initial.json", JSON.stringify(data.config, (space = 4)));
+ exit(0);
+}
+main();
+
+async function askRights() {
+ let w = 0;
+ let brights = { ...eval(`rights`) };
+ Object.keys(rights).forEach((x) => {
+ brights[x] = false;
+ let str = `[x] ${Object.keys(rights).length}: ${x}`;
+ if (str.length > w) w = str.length;
+ });
+
+ let resp = "";
+ let selectedRights = 0n;
+ while (resp != "q") {
+ selectedRights = 0n;
+ Object.keys(brights).forEach((x) => {
+ if (brights[x]) selectedRights += rights[x];
+ });
+ console.clear();
+ printTitle("Step 4: Default rights");
+ printTitle(`Current rights: ${selectedRights} (0b${selectedRights.toString(2)}, 0x${selectedRights.toString(16)})`);
+ let xpos = 0;
+ Object.keys(rights).forEach((x) => {
+ let str = `[${brights[x] ? "X" : " "}] ${Object.keys(rights).indexOf(x)}: ${x}`.padEnd(w + 1, " ");
+ if (xpos + str.length > stdout.columns) {
+ console.log();
+ xpos = 0;
+ }
+ stdout.write(str);
+ xpos += str.length;
+ });
+
+ console.log();
+ resp = await ask("Enter an option, or q to exit: ");
+ if (/\d{1,}/.test(resp) && resp < Object.keys(rights).length && resp > -1) {
+ brights[Object.keys(brights)[parseInt(resp)]] ^= true;
+ }
+ }
+ return selectedRights;
+}
+
+async function askRight(right) {
+ let answer = await ask(`${right}: `);
+ if (answer == "y") return true;
+ else if (answer == "n") return false;
+ else return askRight(right);
+}
+
+function printTitle(input) {
+ let width = stdout.columns / 2 - 1; //40
+ console.log();
+ console.log("-".repeat(width - input.length / 2), input, "-".repeat(width - input.length / 2));
+ console.log();
+}
+async function ask(question) {
+ return new Promise((resolve, reject) => {
+ return rl.question(question, (answer) => {
+ resolve(answer);
+ });
+ }).catch((err) => {
+ console.log(err);
+ });
+}
+
+function BitFlag(int) {
+ return 1n << BigInt(int);
+}
diff --git a/scripts/gen_index.js b/scripts/gen_index.js
index 71c64a9f..8a3c7eb8 100644
--- a/scripts/gen_index.js
+++ b/scripts/gen_index.js
@@ -1,34 +1,37 @@
const path = require("path");
const fs = require("fs");
-const { execIn, getLines, parts } = require('./utils');
+const { execIn, getLines } = require("./utils");
if (!process.argv[2] || !fs.existsSync(process.argv[2])) {
- console.log("Please pass a directory that exists!");
- process.exit(1);
+ console.log("Please pass a directory that exists!");
+ process.exit(1);
}
-console.log(`// ${process.argv[2]}/index.ts`)
-const recurse = process.argv.includes("--recursive")
+console.log(`// ${process.argv[2]}/index.ts`);
+const recurse = process.argv.includes("--recursive");
-const files = fs.readdirSync(process.argv[2]).filter(x => x.endsWith('.ts') && x != 'index.ts');
+const files = fs.readdirSync(process.argv[2]).filter((x) => x.endsWith(".ts") && x != "index.ts");
-let output = '';
+let output = "";
-files.forEach(x => output += `export * from "./${x.replaceAll('.ts','')}";\n`)
+files.forEach((x) => (output += `export * from "./${x.replaceAll(".ts", "")}";\n`));
-const dirs = fs.readdirSync(process.argv[2]).filter(x => {
- try {
- fs.readdirSync(path.join(process.argv[2], x));
- return true;
- } catch (e) {
- return false;
- }
+const dirs = fs.readdirSync(process.argv[2]).filter((x) => {
+ try {
+ fs.readdirSync(path.join(process.argv[2], x));
+ return true;
+ } catch (e) {
+ return false;
+ }
+});
+dirs.forEach((x) => {
+ output += `export * from "./${x}/index";\n`;
});
-dirs.forEach(x => {
- output += `export * from "./${x}/index";\n`
-})
console.log(output);
-fs.writeFileSync(path.join(process.argv[2], "index.ts"), output)
+fs.writeFileSync(path.join(process.argv[2], "index.ts"), output);
-dirs.forEach(x => {
- if(recurse) console.log(execIn([process.argv[0], process.argv[1], `"${path.join(process.argv[2], x)}"`, "--recursive"].join(' '), process.cwd()))
-})
\ No newline at end of file
+dirs.forEach((x) => {
+ if (recurse)
+ console.log(
+ execIn([process.argv[0], process.argv[1], `"${path.join(process.argv[2], x)}"`, "--recursive"].join(" "), process.cwd())
+ );
+});
diff --git a/scripts/generate_schema.js b/scripts/generate_schema.js
index 6925df5d..e4bdd0c4 100644
--- a/scripts/generate_schema.js
+++ b/scripts/generate_schema.js
@@ -36,7 +36,7 @@ const Excluded = [
"UncheckedPropertiesSchema",
"PropertiesSchema",
"AsyncSchema",
- "AnySchema",
+ "AnySchema"
];
function modify(obj) {
@@ -48,13 +48,8 @@ function modify(obj) {
}
function main() {
- const files = [
- ...walk(path.join(__dirname, "..", "src", "util", "schemas")),
- ];
- const program = TJS.getProgramFromFiles(
- files,
- compilerOptions
- );
+ const files = [...walk(path.join(__dirname, "..", "src", "util", "schemas"))];
+ const program = TJS.getProgramFromFiles(files, compilerOptions);
const generator = TJS.buildGenerator(program, settings);
if (!generator || !program) return;
diff --git a/scripts/migrate_db_engine.js b/scripts/migrate_db_engine.js
index 79e9d86f..b5b8008b 100644
--- a/scripts/migrate_db_engine.js
+++ b/scripts/migrate_db_engine.js
@@ -25,7 +25,7 @@ const {
Template,
User,
VoiceState,
- Webhook,
+ Webhook
} = require("../../dist/entities/index");
async function main() {
@@ -54,7 +54,7 @@ async function main() {
VoiceState,
Webhook,
Message,
- Attachment,
+ Attachment
];
const oldDB = await initDatabase();
@@ -69,7 +69,7 @@ async function main() {
database: isSqlite ? process.env.TO : undefined,
entities,
name: "new",
- synchronize: true,
+ synchronize: true
});
let i = 0;
diff --git a/scripts/rights.js b/scripts/rights.js
index 20fd139c..5ae576ef 100644
--- a/scripts/rights.js
+++ b/scripts/rights.js
@@ -6,20 +6,20 @@ const { argv, stdout, exit } = require("process");
const { execIn, getLines, parts } = require("./utils");
-let lines = fs.readFileSync(path.join(__dirname, "..", "src", "util", "util","Rights.ts")).toString()
+let lines = fs.readFileSync(path.join(__dirname, "..", "src", "util", "util", "Rights.ts")).toString();
let lines2 = lines.split("\n");
-let lines3 = lines2.filter(y=>y.includes(": BitFlag("));
-let lines4 = lines3.map(x=>x.split("//")[0].trim())
+let lines3 = lines2.filter((y) => y.includes(": BitFlag("));
+let lines4 = lines3.map((x) => x.split("//")[0].trim());
function BitFlag(int) {
- return 1n << eval(`${int}n`);
+ return 1n << BigInt(int);
}
-let rights = []
+let rights = [];
let maxRights = 0n;
-lines4.forEach(x=>{
- maxRights += eval(`rights.${x.replace(':'," = ").replace(",",";")}`)
-})
+lines4.forEach((x) => {
+ maxRights += eval(`rights.${x.replace(":", " = ").replace(",", ";")}`);
+});
//max rights...
console.log(`Maximum rights: ${maxRights}`);
//discord rights...
@@ -31,4 +31,4 @@ discordRights -= rights.BYPASS_RATE_LIMITS;
discordRights -= rights.ADD_MEMBERS;
discordRights -= rights.MANAGE_RATE_LIMITS;
discordRights -= rights.OPERATOR;
-console.log(`Discord-like rights: ${discordRights}`);
\ No newline at end of file
+console.log(`Discord-like rights: ${discordRights}`);
diff --git a/scripts/update_schemas.js b/scripts/update_schemas.js
index 361bedc1..151b52d2 100644
--- a/scripts/update_schemas.js
+++ b/scripts/update_schemas.js
@@ -6,4 +6,4 @@ const { argv, stdout, exit } = require("process");
const { execIn, getLines, parts } = require("./utils");
-execIn("node scripts/generate_schema.js", path.join('.'));
\ No newline at end of file
+execIn("node scripts/generate_schema.js", path.join("."));
diff --git a/scripts/utils.js b/scripts/utils.js
index 84aaeed6..b679392b 100644
--- a/scripts/utils.js
+++ b/scripts/utils.js
@@ -4,6 +4,8 @@ const { env } = require("process");
const { execSync } = require("child_process");
const { argv, stdout, exit } = require("process");
+const projectRoot = path.resolve(path.join(__dirname, ".."));
+
function copyRecursiveSync(src, dest) {
//if (verbose) console.log(`cpsync: ${src} -> ${dest}`);
let exists = fs.existsSync(src);
@@ -16,10 +18,7 @@ function copyRecursiveSync(src, dest) {
if (isDirectory) {
fs.mkdirSync(dest, { recursive: true });
fs.readdirSync(src).forEach(function (childItemName) {
- copyRecursiveSync(
- path.join(src, childItemName),
- path.join(dest, childItemName)
- );
+ copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
});
} else {
fs.copyFileSync(src, dest);
@@ -44,8 +43,45 @@ function getLines(output) {
return output.split("\n").length;
}
-module.exports = {
+function getDirs(dir) {
+ return fs.readdirSync(dir).filter((x) => {
+ try {
+ fs.readdirSync(dir.join(dir, x));
+ return true;
+ } catch (e) {
+ return false;
+ }
+ });
+}
+
+function walk(dir) {
+ let results = [];
+ let list = fs.readdirSync(dir);
+ list.forEach(function (file) {
+ file = dir + "/" + file;
+ let stat = fs.statSync(file);
+ if (stat && stat.isDirectory()) {
+ /* Recurse into a subdirectory */
+ results = results.concat(walk(file));
+ } else {
+ results.push(file);
+ }
+ });
+ return results;
+}
+
+function sanitizeVarName(str) {
+ return str.replace("-", "_").replace(/[^\w\s]/gi, "");
+}
+
+module.exports = {
//consts
+ projectRoot,
//functions
- copyRecursiveSync, execIn, getLines
+ copyRecursiveSync,
+ execIn,
+ getLines,
+ getDirs,
+ walk,
+ sanitizeVarName
};
diff --git a/tests/cdn_endpoints.test.js b/tests/cdn_endpoints.test.js
index 5a543e54..5627bf40 100644
--- a/tests/cdn_endpoints.test.js
+++ b/tests/cdn_endpoints.test.js
@@ -11,17 +11,12 @@ if (!process.env.STORAGE_PROVIDER) process.env.STORAGE_PROVIDER = "file";
if (process.env.STORAGE_PROVIDER === "file") {
if (process.env.STORAGE_LOCATION) {
if (!process.env.STORAGE_LOCATION.startsWith("/")) {
- process.env.STORAGE_LOCATION = path.join(
- __dirname,
- "..",
- process.env.STORAGE_LOCATION,
- "/"
- );
+ process.env.STORAGE_LOCATION = path.join(__dirname, "..", process.env.STORAGE_LOCATION, "/");
}
} else {
process.env.STORAGE_LOCATION = path.join(__dirname, "..", "files", "/");
}
- if(!fs.existsSync(process.env.STORAGE_LOCATION)) fs.mkdirSync(process.env.STORAGE_LOCATION, {recursive:true});
+ if (!fs.existsSync(process.env.STORAGE_LOCATION)) fs.mkdirSync(process.env.STORAGE_LOCATION, { recursive: true });
}
const { CDNServer } = require("../dist/Server");
const { Config } = require("@fosscord/util");
@@ -59,9 +54,7 @@ describe("/attachments", () => {
});
describe("with signature specified, without file specified", () => {
test("route should respond with 400", async () => {
- const response = await request
- .post("/attachments/123456789")
- .set({ signature: Config.get().security.requestSignature });
+ const response = await request.post("/attachments/123456789").set({ signature: Config.get().security.requestSignature });
expect(response.statusCode).toBe(400);
});
});
@@ -72,9 +65,7 @@ describe("/attachments", () => {
.set({ signature: Config.get().security.requestSignature })
.attach("file", __dirname + "/antman.jpg");
expect(response.statusCode).toBe(200);
- expect(response.headers["content-type"]).toEqual(
- expect.stringContaining("json")
- );
+ expect(response.headers["content-type"]).toEqual(expect.stringContaining("json"));
expect(response.body.url).toBeDefined();
});
});
@@ -86,11 +77,9 @@ describe("/attachments", () => {
.post("/attachments/123456789")
.set({ signature: Config.get().security.requestSignature })
.attach("file", __dirname + "/antman.jpg");
- request
- .get(response.body.url.replace("http://localhost:3003", ""))
- .then((x) => {
- expect(x.statusCode).toBe(200);
- });
+ request.get(response.body.url.replace("http://localhost:3003", "")).then((x) => {
+ expect(x.statusCode).toBe(200);
+ });
});
});
});
@@ -101,13 +90,9 @@ describe("/attachments", () => {
.post("/attachments/123456789")
.set({ signature: Config.get().security.requestSignature })
.attach("file", __dirname + "/antman.jpg");
- request
- .delete(
- response.body.url.replace("http://localhost:3003", "")
- )
- .then((x) => {
- expect(x.body.success).toBeDefined();
- });
+ request.delete(response.body.url.replace("http://localhost:3003", "")).then((x) => {
+ expect(x.body.success).toBeDefined();
+ });
});
});
});
@@ -123,9 +108,7 @@ describe("/avatars", () => {
});
describe("with signature specified, without file specified", () => {
test("route should respond with 400", async () => {
- const response = await request
- .post("/avatars/123456789")
- .set({ signature: Config.get().security.requestSignature });
+ const response = await request.post("/avatars/123456789").set({ signature: Config.get().security.requestSignature });
expect(response.statusCode).toBe(400);
});
});
@@ -136,9 +119,7 @@ describe("/avatars", () => {
.set({ signature: Config.get().security.requestSignature })
.attach("file", __dirname + "/antman.jpg");
expect(response.statusCode).toBe(200);
- expect(response.headers["content-type"]).toEqual(
- expect.stringContaining("json")
- );
+ expect(response.headers["content-type"]).toEqual(expect.stringContaining("json"));
expect(response.body.url).toBeDefined();
});
});
@@ -150,11 +131,9 @@ describe("/avatars", () => {
.post("/avatars/123456789")
.set({ signature: Config.get().security.requestSignature })
.attach("file", __dirname + "/antman.jpg");
- request
- .get(response.body.url.replace("http://localhost:3003", ""))
- .then((x) => {
- expect(x.statusCode).toBe(200);
- });
+ request.get(response.body.url.replace("http://localhost:3003", "")).then((x) => {
+ expect(x.statusCode).toBe(200);
+ });
});
});
});
@@ -165,13 +144,9 @@ describe("/avatars", () => {
.post("/avatars/123456789")
.set({ signature: Config.get().security.requestSignature })
.attach("file", __dirname + "/antman.jpg");
- request
- .delete(
- response.body.url.replace("http://localhost:3003", "")
- )
- .then((x) => {
- expect(x.body.success).toBeDefined();
- });
+ request.delete(response.body.url.replace("http://localhost:3003", "")).then((x) => {
+ expect(x.body.success).toBeDefined();
+ });
});
});
});
@@ -187,35 +162,25 @@ describe("/external", () => {
});
describe("with signature specified, without file specified", () => {
test("route should respond with 400", async () => {
- const response = await request
- .post("/external")
- .set({ signature: Config.get().security.requestSignature });
+ const response = await request.post("/external").set({ signature: Config.get().security.requestSignature });
expect(response.statusCode).toBe(400);
});
});
describe("with signature specified, with file specified ", () => {
test("route should respond with Content-type: application/json, 200 and res.body.url", async () => {
- const response = await request
- .post("/external")
- .set({ signature: Config.get().security.requestSignature })
- .send({
- url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp",
- });
+ const response = await request.post("/external").set({ signature: Config.get().security.requestSignature }).send({
+ url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp"
+ });
expect(response.statusCode).toBe(200);
- expect(response.headers["content-type"]).toEqual(
- expect.stringContaining("json")
- );
+ expect(response.headers["content-type"]).toEqual(expect.stringContaining("json"));
expect(response.body.id).toBeDefined();
});
});
describe("with signature specified, with falsy url specified ", () => {
test("route should respond with 400", async () => {
- const response = await request
- .post("/external")
- .set({ signature: Config.get().security.requestSignature })
- .send({
- url: "notavalidurl.123",
- });
+ const response = await request.post("/external").set({ signature: Config.get().security.requestSignature }).send({
+ url: "notavalidurl.123"
+ });
expect(response.statusCode).toBe(400);
});
});
@@ -223,12 +188,9 @@ describe("/external", () => {
describe("GET", () => {
describe("getting uploaded image by url returned by POST /avatars", () => {
test("route should respond with 200", async () => {
- let response = await request
- .post("/external")
- .set({ signature: Config.get().security.requestSignature })
- .send({
- url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp",
- });
+ let response = await request.post("/external").set({ signature: Config.get().security.requestSignature }).send({
+ url: "https://i.ytimg.com/vi_webp/TiXzhQr5AUc/mqdefault.webp"
+ });
request.get(`external/${response.body.id}`).then((x) => {
expect(x.statusCode).toBe(200);
});
diff --git a/tests/routes.test.ts b/tests/routes.test.ts
index c915fab9..51c068b5 100644
--- a/tests/routes.test.ts
+++ b/tests/routes.test.ts
@@ -1,13 +1,13 @@
// TODO: check every route based on route() parameters: https://github.com/fosscord/fosscord-server/issues/308
// TODO: check every route with different database engine
-import getRouteDescriptions from "../jest/getRouteDescriptions";
-import { join } from "path";
-import fs from "fs";
+import { Channel, Event, events, Guild, User } from "@fosscord/util";
import Ajv from "ajv";
import addFormats from "ajv-formats";
+import fs from "fs";
import fetch from "node-fetch";
-import { Event, User, events, Guild, Channel } from "@fosscord/util";
+import { join } from "path";
+import getRouteDescriptions from "../jest/getRouteDescriptions";
const SchemaPath = join(__dirname, "..", "assets", "schemas.json");
const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
diff --git a/tests/setupJest.js b/tests/setupJest.js
index 378d72d5..bb52525f 100644
--- a/tests/setupJest.js
+++ b/tests/setupJest.js
@@ -17,7 +17,7 @@ global.expect.extend({
return {
pass: time < target && !error,
- message: () => error || `${func.name} took ${time}ms of maximum ${target}`,
+ message: () => error || `${func.name} took ${time}ms of maximum ${target}`
};
- },
+ }
});
diff --git a/tsconfig.json b/tsconfig.json
index b9e17f29..eb3399aa 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,85 +1,79 @@
-{
- "include": ["src/**/*.ts"],
- "exclude": [],
- "compilerOptions": {
-
- /* Basic Options */
- "incremental": false /* Enable incremental compilation */,
- "target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
- "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
- "lib": [
- "ESNext"
- ] /* Specify library files to be included in the compilation. */,
- "allowJs": true /* Allow javascript files to be compiled. */,
- "checkJs": true /* Report errors in .js files. */,
- // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
- "declaration": false /* Generates corresponding '.d.ts' file. */,
- "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */,
- "sourceMap": true /* Generates corresponding '.map' file. */,
- // "outFile": "./", /* Concatenate and emit output to single file. */
- "outDir": "./dist/" /* Redirect output structure to the directory. */,
- "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
- // "composite": true, /* Enable project compilation */
- // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
- // "removeComments": true, /* Do not emit comments to output. */
- // "noEmit": true, /* Do not emit outputs. */
- // "importHelpers": true, /* Import emit helpers from 'tslib'. */
- // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
- // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
-
- /* Strict Type-Checking Options */
- "strict": true /* Enable all strict type-checking options. */,
- "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
- "strictNullChecks": true /* Enable strict null checks. */,
- // "strictFunctionTypes": true, /* Enable strict checking of function types. */
- // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
- "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */,
- // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
- "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
-
- /* Additional Checks */
- // "noUnusedLocals": true, /* Report errors on unused locals. */
- // "noUnusedParameters": true, /* Report errors on unused parameters. */
- // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
- // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
-
- /* Module Resolution Options */
- "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
- // "typeRoots": [], /* List of folders to include type definitions from. */
- "types": [
- "node"
- ] /* Type declaration files to be included in compilation. */,
- // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
- "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
- // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
-
- /* Source Map Options */
- // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
- // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
-
- /* Experimental Options */
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
-
- /* Advanced Options */
- "skipLibCheck": true /* Skip type checking of declaration files. */,
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "resolveJsonModule": true,
- "baseUrl": "./src/",
- "paths": {
- "@fosscord/api": ["./api/index"],
- "@fosscord/gateway": ["./gateway/index"],
- "@fosscord/cdn": ["./cdn/index"],
- "@fosscord/util": ["./util/index"]
- },
- "plugins": [{ "transform": "@ovos-media/ts-transform-paths" }],
- "noEmitHelpers": true,
- "importHelpers": true
- }
-}
+{
+ "include": ["src/**/*.ts"],
+ "exclude": [],
+ "compilerOptions": {
+ /* Basic Options */
+ "incremental": false /* Enable incremental compilation */,
+ "target": "ESNext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
+ "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
+ "lib": ["ESNext"] /* Specify library files to be included in the compilation. */,
+ "allowJs": true /* Allow javascript files to be compiled. */,
+ "checkJs": true /* Report errors in .js files. */,
+ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
+ "declaration": false /* Generates corresponding '.d.ts' file. */,
+ "declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */,
+ "sourceMap": true /* Generates corresponding '.map' file. */,
+ // "outFile": "./", /* Concatenate and emit output to single file. */
+ "outDir": "./dist/" /* Redirect output structure to the directory. */,
+ "rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
+ // "composite": true, /* Enable project compilation */
+ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
+ // "removeComments": true, /* Do not emit comments to output. */
+ // "noEmit": true, /* Do not emit outputs. */
+ // "importHelpers": true, /* Import emit helpers from 'tslib'. */
+ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
+ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
+
+ /* Strict Type-Checking Options */
+ "strict": true /* Enable all strict type-checking options. */,
+ "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
+ "strictNullChecks": true /* Enable strict null checks. */,
+ // "strictFunctionTypes": true, /* Enable strict checking of function types. */
+ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
+ "strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */,
+ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
+ "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
+
+ /* Additional Checks */
+ // "noUnusedLocals": true, /* Report errors on unused locals. */
+ // "noUnusedParameters": true, /* Report errors on unused parameters. */
+ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
+ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
+
+ /* Module Resolution Options */
+ "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
+ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
+ // "typeRoots": [], /* List of folders to include type definitions from. */
+ "types": ["node"] /* Type declaration files to be included in compilation. */,
+ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
+ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
+ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+
+ /* Source Map Options */
+ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
+ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
+
+ /* Experimental Options */
+ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
+ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
+
+ /* Advanced Options */
+ "skipLibCheck": true /* Skip type checking of declaration files. */,
+ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "resolveJsonModule": true,
+ "baseUrl": "./src/",
+ "paths": {
+ "@fosscord/api": ["./api/index"],
+ "@fosscord/gateway": ["./gateway/index"],
+ "@fosscord/cdn": ["./cdn/index"],
+ "@fosscord/util": ["./util/index"]
+ },
+ "noEmitHelpers": true,
+ "importHelpers": true
+ }
+}
|