From 9071cbdc25e97153086ac48bd389b04c43e56458 Mon Sep 17 00:00:00 2001 From: TheArcaneBrony Date: Fri, 19 Aug 2022 18:53:25 +0200 Subject: Updates scripts and tests from dev/plugins --- .githooks/pre-commit | 55 + .gitignore | 5 +- .prettierrc | 6 +- assets/checkLocale.js | 90 +- assets/developers.html | 76 +- assets/fosscord-login.css | 12 +- assets/fosscord.css | 68 +- assets/index.html | 154 +-- assets/schemas.json | 2740 +++++++++++++++++-------------------- assets/user.css | 2 +- build.json.default | 16 + docker-compose.cfg.yml | 7 +- docker-compose.yml | 41 +- env-vars.md | 32 +- fosscord-server.code-workspace | 19 +- package.json | 28 +- scripts/benchmark.js | 6 +- scripts/benchmark/connections.js | 6 +- scripts/benchmark/users.js | 4 +- scripts/build.js | 116 +- scripts/build/clean.js | 18 + scripts/build/compile_tsc.js | 48 + scripts/build/plugin_prepare.js | 31 + scripts/build/plugin_resources.js | 13 + scripts/build/remap_imports.js | 15 + scripts/build_new.js | 31 + scripts/code_quality.js | 75 + scripts/depcheck.js | 44 +- scripts/depclean.js | 25 +- scripts/first_setup.js | 185 +++ scripts/gen_index.js | 47 +- scripts/generate_schema.js | 11 +- scripts/migrate_db_engine.js | 6 +- scripts/rights.js | 18 +- scripts/update_schemas.js | 2 +- scripts/utils.js | 48 +- tests/cdn_endpoints.test.js | 96 +- tests/routes.test.ts | 8 +- tests/setupJest.js | 4 +- tsconfig.json | 164 ++- 40 files changed, 2370 insertions(+), 2002 deletions(-) create mode 100755 .githooks/pre-commit create mode 100644 build.json.default create mode 100644 scripts/build/clean.js create mode 100644 scripts/build/compile_tsc.js create mode 100644 scripts/build/plugin_prepare.js create mode 100644 scripts/build/plugin_resources.js create mode 100644 scripts/build/remap_imports.js create mode 100644 scripts/build_new.js create mode 100644 scripts/code_quality.js create mode 100644 scripts/first_setup.js 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 @@ + + + - - - + + + Discord Test Client Developer Portal + + - - - Discord Test Client Developer Portal - - + +
+ - - - - - - \ 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}` + ); + + + + + + 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 @@ + + + + Discord Test Client + + + + + + - - - - Discord Test Client - - - - - - + +
+ - - - - - - - - - \ 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)); + } + + + + + + + + + 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 + } +} -- cgit 1.4.1