diff --git a/README.md b/README.md index 05454c9e..3a2b1492 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,26 @@ # A fork. A fork. We're a fork. -Installing is the same as the Vencord devs laid out: [(Install)](https://docs.vencord.dev/installing/) -* Beyond that, be sure to clone *this* repository instead of their upstream one. - * `git clone https://git.dorkbutt.lol/dorkbutt/vencord` -* After completing the steps, go to Settings > Vencord > Plugins and search for -"FORKED - usrbg" and enable it. Be sure to tweak its settings! - # Vencord -![](https://img.shields.io/github/package-json/v/Vendicated/Vencord?style=for-the-badge&logo=github&logoColor=d3869b&label=&color=1d2021&labelColor=282828) [![Codeberg Mirror](https://img.shields.io/static/v1?style=for-the-badge&label=Codeberg%20Mirror&message=codeberg.org/Vee/cord&color=2185D0&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABmJLR0QA/wD/AP+gvaeTAAAKbUlEQVR4nNVae3AV5RX/nW/3Pva+b24e5HHzIICQKGoiYiW8NFBFgohaa6ctglpbFSujSGurzUinohWsOij/gGX6R2fqOK0d1FYTEZXaTrWCBbEikJCEyCvkeXNvkrunf+zdkJDkPnex/c3cmd29+53v/M6e73znnF2Cydj4Tntldzi6qrN/qKqzf2jy6b7BnL4B1dI7oMp9AyoRAIdVsNMqhlxWMZjtspzyK/Jhr036OMsm//bh2vzPzNSPzBD6xFutd7R0Dq758ky4orkjYuc05RCAkixbeEq2/UCJ1/LczxcX/c5IPfU5DMHmxpbCpu7o1k/b+xc1n43YjJI7EqV+W2RmvuPt0oDjB2vn5bQbITNjAzzdeKK8qTO0bU9T77zucNQUjzofHrvENWWu3aUBZfW6+ZOOZiIrbYXrmUXo9daX3v6i667O/iGRiRLpwqtIvKDc+0efJ3hb/UIaSkdGWgZ4sqGt9r2m3lc/P9HvSWe80ZiRp3TPL/UsX1+bvyvVsSkb4NE3WjbuPNj5SM8Fcvdk4bAKrqvwv7DxhuCPUxmXNIn6XSy3nWr6R8OhrqrU1btwqJ3m/bgwu/SqZJdEUgbYsuuka09b9/4Pm3tLMlPvwuAbpe6m+RcplfdcURBKdG9CA2zZddLV2Nx1+JO2vlxj1LswqCpynlxc6SxLZIS40bueWfy9vXvv/xt5APhXa1/u7v+EPqvfxXK8++IaoO2Vpn9+cLS33FjVLhw+bOotOX7q6N/i3TOhAX7y+rHN/+sBLxm8fah71k93tjw/0f/jGuDJxtZrdh7setA8tS4sdn7eef+v3mmfP95/Ywxw6x9Yev9I35/6Iubv83WVfl5a6Uu3VkoavZEo7TnS/Vo98xi+Yy6UKC3bDp7sd5ut1OWFDjyzNMib6oq5Oug0ezp8dqLfG3r92Nbzr48ywNONJ8obDnV/z2xlAk4ZW1aUqhaJIAvCb5YVqwFn3GBtCBoO9dz5TOPxUbnMKAM0dYa2d5lc2AgCNi8r5klui3aBgWynjE11QZbI3FV3NjQkjnYNbB+lj36wubGlcE9T71xTNQDw0Px8nlvmHl73GmfCrKCL19Tkmh4P9jT1LHz2vVP5+vmwAZq71a1m1/PXTPXwD68eS5KIEVUZd1yZwwumeEw1Qld/lJrPhF7Sz4cNsO+rUK2ZExd6rfj10iCPZ2GJCCoAZuCJxQUc9FvNVAX72kPX6ccC0Hp4zR0Ru1kT2mTCSzeXqn5l/EAniMAqoDLDYZWwqa5EVSzmhaKmsxHbLxvbbgdiBmjpHFxj2mwANlxXxBdPUib8nwgQgqAyEFUZxT4L1i/MN3UpHDsTWQvEDHDoTLjCrIluuyzAt8zMSkhGFhp5hrYUFk3z8IqZftOMcKRj4GIAEM80tFccM8n9Z+Qq+MXigqRIWCQCMzQvYIbKwH1X53FFnjkr88iZsLKpoXWa6BiIrjbDzF67hK23lKp2Obm1LAstPEZVjTwDkAio/2ZQ9dolw/VjAB0DfKfoCg9WGy2cADy1NMhBX2rR3CIRGICq8rAhAg4Jj9UWsDBhg+4MR6vF2VC0zGjB99fk8eJp3pQdyyrRMHF9KURVxswCB6+alWO4o3b2RyeLU32D2UYKnVPm5gfm5qWlrF0Wo4hzbCmoDNw0089XlboNNcLpvsFc0RtRDXuNle+x4Lkbi9PO6WWJIBFGEY+qjGjswtq5eVzosRilLnoiUavoH1INiTCyIDy/vETNcmRW1dl0L4gRVxmx3YFhlwnrry1QrZIxASE0yJIIDaiGSHt8UQFXF2Ve1zusYgzxkXGhyGvFvePUE+mgfyAqhGqAqKWVPv5udbYhSjmtkpYWq6OJqzFjqCpjTpmbl1Rk3klSGRBWmTISNC3Hjo1LgoYFJ0GA1aIVR+cTVxlQoS2Pb18a4PLszMKXzSJYuCySmq4Al03CiytKVYfBhYvLKk1IXE+XLRLhwZp81WlNf26HTFHhd0jhdAYTgKduCPLkgPHfQjitYkLiAIEZBDBlu2R6aF7euCV2Mgg45bDw2qWOdAavnp3D109PPdlJBvpTnYg4kVY3MDMuylVw62WJi63x4LHLZ0TAIR9OdWBVodPUclUQwWmT4hLXfgCIUDfDi6oiR8rzBJzyl8LnkD9KZVCOU8aLN5eoshnJ+Qh4bFJC4gztmEjgrtk5anaKnWWfXfpIuBTLjmSpSILw/E0laq7LuGxsIngVCYmIa96hLRG3TaZ1C/KTfjAEQLFIO8TPFk7aH/RZI8kMWrdgEs8udqXLKSUoMkEW4ETEQTRsoHyPlVZfmVw+Uuy3hR9bVHBQAMD0XPu/Ew24dqqH777K/La1DiKCxyYlRRzQymgG4+oyDxZOTdxZnp5r3wvEWmJ5btuL8W4uzbJh87LitLebdOFVpKSJx4IlwIzbL81CcYLO8iSX/IImGQCYae6Wg/2tXQNjNnW7LPDKyilqZd7ETU2zEBlifNTSS4i9PNFIx44x4jh2nZlBsUr0dN8QP/6XVhEaHJvnlfhtkXd/NF0BUextKRFXFznfGk+JDdcX8tdBHtDa6YpFsB4I9ac88omf8wbEgqa2XAIOme6bM35foqrQ+QZIKwGG80ifVbrXZZNGDfhOVYBvviS9JMMoaP3AEcQpPnHdOxiMGXkKbrx4dGfZY5c4T8H9+vmwAeqXFLXOKXW9r59fWuDA44sKv1byAOBzyCkTH+kdS2f4MLPgXJI0p9T17vrFxcf181GVxEUB+0qfIqt+RcKWFSWGNR4ygd4RTpW4HiCJgFWzstmnSPA7ZLU827pypPwxDB/687GXl1X6Vs6bbGz/LRN80hZCT+yLFZ0cgHED4egACeiXm89GsP9EePuzy4rvGil7jAGYmQDsBjDHUBYZ4GhHBMfORigd4rpnyIS9u6d4rqgnGrUtjCmmSYuOqwB0GcwjbWh9xviurpNnxnDA1IspMPe6bOL755MHJvhKjIgOA7jbJD4pw22Thj+kSIW47h2KRaydVezeP57sCdspRPQqgGeNJJIuBAE+ReJUiOv32mXaXjPZs21C2QnmXgdghyEsMoRfkVMiDgCywF/by9z3xJMb1wCxeHAPgDczZpAh/Iq+HSYmDjCsstgThmf5t4ii8eQm7CgS0SCA5QBezoRApnBaBSyCEhIHCLJEb4ZUd+2SqZSwzE+qpUpEQ9CC4qb01M8cRIQsh8zxiKsMtsn08nvlnrpkyAPj5AGJwMw3AtgGwJ/q2ExxvHsQB74KxfKBMblAyGmTHq4pc4/5GjQeUm6qE9FrAK4E8H6ie41GlkN/jTk6F5Ak2ueUpNmpkgfSMAAAENERAAsB3AHgZDoy0oFdFnBYpXPEBfU4beLRD6Z4qmumug+kIzPjaoeZfQDWAHgAQFam8hLh4MkwWjsHemyS2OF08IYrCjynzZ4zKTCzi5nXMvOnzBw16bevIxR95JOj7DNKb1PqXWa+HMDtAGoBXII0lxq0N2OfAmgA8Hsi2muMhudgesHPzNkA5gKoADADwFRoS8UHQO+x9wLoBNAB4AsAnwM4AOADIjLVxf8L9kdXUOE0IskAAAAASUVORK5CYII=)](https://codeberg.org/Vee/cord) The cutest Discord client mod -![](https://github.com/user-attachments/assets/3fac98c0-c411-4d2a-97a3-13b7da8687a2) +| ![image](https://github.com/Vendicated/Vencord/assets/45497981/706722b1-32de-4d99-bee9-93993b504334) | +| :--------------------------------------------------------------------------------------------------: | +| A screenshot of vencord showcasing the [vencord-theme](https://github.com/synqat/vencord-theme) | ## Features -- Easy to install -- [100+ built in plugins](https://vencord.dev/plugins) +- Super easy to install (Download Installer, open, click install button, done) +- 100+ plugins built in: [See a list](https://vencord.dev/plugins) + - Some highlights: SpotifyControls, MessageLogger, Experiments, GameActivityToggle, Translate, NoTrack, QuickReply, Free Emotes/Stickers, PermissionsViewer, CustomCommands, ShowHiddenChannels, PronounDB - Fairly lightweight despite the many inbuilt plugins - Excellent Browser Support: Run Vencord in your Browser via extension or UserScript -- Works on any Discord branch: Stable, Canary or PTB all work +- Works on any Discord branch: Stable, Canary or PTB all work (though for the best experience I recommend stable!) - Custom CSS and Themes: Inbuilt css editor with support to import any css files (including BetterDiscord themes) -- Privacy friendly: blocks Discord analytics & crash reporting out of the box and has no telemetry +- Privacy friendly, blocks Discord analytics & crash reporting out of the box and has no telemetry - Maintained very actively, broken plugins are usually fixed within 12 hours - Settings sync: Keep your plugins and their settings synchronised between devices / apps (optional) diff --git a/browser/VencordNativeStub.ts b/browser/VencordNativeStub.ts index c99c176c..79f0f2cd 100644 --- a/browser/VencordNativeStub.ts +++ b/browser/VencordNativeStub.ts @@ -20,13 +20,16 @@ /// import monacoHtmlLocal from "file://monacoWin.html?minify"; +import monacoHtmlCdn from "file://../src/main/monacoWin.html?minify"; import * as DataStore from "../src/api/DataStore"; -import { debounce, localStorage } from "../src/utils"; +import { debounce } from "../src/utils"; import { EXTENSION_BASE_URL } from "../src/utils/web-metadata"; import { getTheme, Theme } from "../src/utils/discord"; import { getThemeInfo } from "../src/main/themes"; import { Settings } from "../src/Vencord"; -import { getStylusWebStoreUrl } from "@utils/web"; + +// Discord deletes this so need to store in variable +const { localStorage } = window; // listeners for ipc.on const cssListeners = new Set<(css: string) => void>(); @@ -42,13 +45,12 @@ window.VencordNative = { themes: { uploadTheme: (fileName: string, fileData: string) => DataStore.set(fileName, fileData, themeStore), deleteTheme: (fileName: string) => DataStore.del(fileName, themeStore), + getThemesDir: async () => "", getThemesList: () => DataStore.entries(themeStore).then(entries => entries.map(([name, css]) => getThemeInfo(css, name.toString())) ), getThemeData: (fileName: string) => DataStore.get(fileName, themeStore), getSystemValues: async () => ({}), - - openFolder: async () => Promise.reject("themes:openFolder is not supported on web"), }, native: { @@ -75,14 +77,6 @@ window.VencordNative = { addThemeChangeListener: NOOP, openFile: NOOP_ASYNC, async openEditor() { - if (IS_USERSCRIPT) { - const shouldOpenWebStore = confirm("QuickCSS is not supported on the Userscript. You can instead use the Stylus extension.\n\nDo you want to open the Stylus web store page?"); - if (shouldOpenWebStore) { - window.open(getStylusWebStoreUrl(), "_blank"); - } - return; - } - const features = `popup,width=${Math.min(window.innerWidth, 1000)},height=${Math.min(window.innerHeight, 1000)}`; const win = open("about:blank", "VencordQuickCss", features); if (!win) { @@ -98,7 +92,7 @@ window.VencordNative = { ? "vs-light" : "vs-dark"; - win.document.write(monacoHtmlLocal); + win.document.write(IS_EXTENSION ? monacoHtmlLocal : monacoHtmlCdn); }, }, @@ -112,9 +106,8 @@ window.VencordNative = { } }, set: async (s: Settings) => localStorage.setItem("VencordSettings", JSON.stringify(s)), - openFolder: async () => Promise.reject("settings:openFolder is not supported on web"), + getSettingsDir: async () => "LocalStorage" }, pluginHelpers: {} as any, - csp: {} as any, }; diff --git a/package.json b/package.json index 577bf39d..4c6d5023 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.12.6", + "version": "1.12.2", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { @@ -53,8 +53,8 @@ "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", "@types/yazl": "^2.4.5", - "@vencord/discord-types": "link:packages/discord-types", "diff": "^7.0.0", + "discord-types": "^1.3.26", "esbuild": "^0.25.1", "eslint": "9.20.1", "eslint-import-resolver-alias": "^1.1.2", diff --git a/packages/discord-types/LICENSE b/packages/discord-types/LICENSE deleted file mode 100644 index 0a041280..00000000 --- a/packages/discord-types/LICENSE +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/packages/discord-types/README.md b/packages/discord-types/README.md deleted file mode 100644 index 82a98dd8..00000000 --- a/packages/discord-types/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Discord Types - -This package provides TypeScript types for the Webpack modules of Discord's web app. - -While it was primarily created for Vencord, other client mods could also benefit from this, so it is published as a standalone package! - -## Installation - -```bash -npm install -D @vencord/discord-types -yarn add -D @vencord/discord-types -pnpm add -D @vencord/discord-types -``` - -## Example Usage - -```ts -import type { UserStore } from "@vencord/discord-types"; - -const userStore: UserStore = findStore("UserStore"); // findStore is up to you to implement, this library only provides types and no runtime code -``` - -## Enums - -This library also exports some const enums that you can use from Typescript code: -```ts -import { ApplicationCommandType } from "@vencord/discord-types/enums"; - -console.log(ApplicationCommandType.CHAT_INPUT); // 1 -``` - -### License - -This package is licensed under the [LGPL-3.0](./LICENSE) (or later) license. - -A very short summary of the license is that you can use this package as a library in both open source and closed source projects, -similar to an MIT-licensed project. -However, if you modify the code of this package, you must release source code of your modified version under the same license. - -### Credit - -This package was inspired by Swishilicous' [discord-types](https://www.npmjs.com/package/discord-types) package. diff --git a/packages/discord-types/enums/commands.ts b/packages/discord-types/enums/commands.ts deleted file mode 100644 index 298f9b7a..00000000 --- a/packages/discord-types/enums/commands.ts +++ /dev/null @@ -1,32 +0,0 @@ -export const enum ApplicationCommandOptionType { - SUB_COMMAND = 1, - SUB_COMMAND_GROUP = 2, - STRING = 3, - INTEGER = 4, - BOOLEAN = 5, - USER = 6, - CHANNEL = 7, - ROLE = 8, - MENTIONABLE = 9, - NUMBER = 10, - ATTACHMENT = 11, -} - -export const enum ApplicationCommandInputType { - BUILT_IN = 0, - BUILT_IN_TEXT = 1, - BUILT_IN_INTEGRATION = 2, - BOT = 3, - PLACEHOLDER = 4, -} - -export const enum ApplicationCommandType { - CHAT_INPUT = 1, - USER = 2, - MESSAGE = 3, -} - -export const enum ApplicationIntegrationType { - GUILD_INSTALL = 0, - USER_INSTALL = 1 -} diff --git a/packages/discord-types/enums/index.ts b/packages/discord-types/enums/index.ts deleted file mode 100644 index 62074d46..00000000 --- a/packages/discord-types/enums/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./commands"; diff --git a/packages/discord-types/package.json b/packages/discord-types/package.json deleted file mode 100644 index 7b8726fd..00000000 --- a/packages/discord-types/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "@vencord/discord-types", - "author": "Vencord Contributors", - "description": "Typescript definitions for the webpack modules of the Discord Web app", - "version": "1.0.0", - "license": "LGPL-3.0-or-later", - "types": "src/index.d.ts", - "type": "module", - "repository": { - "type": "git", - "url": "git+https://github.com/Vendicated/Vencord.git", - "directory": "packages/discord-types" - }, - "dependencies": { - "@types/react": "^19.0.10", - "moment": "^2.22.2", - "type-fest": "^4.41.0" - } -} diff --git a/packages/discord-types/src/classes.d.ts b/packages/discord-types/src/classes.d.ts deleted file mode 100644 index 752ba3f0..00000000 --- a/packages/discord-types/src/classes.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -export interface ImageModalClasses { - image: string, - modal: string, -} - -export interface ButtonWrapperClasses { - hoverScale: string; - buttonWrapper: string; - button: string; - iconMask: string; - buttonContent: string; - icon: string; - pulseIcon: string; - pulseButton: string; - notificationDot: string; - sparkleContainer: string; - sparkleStar: string; - sparklePlus: string; - sparkle: string; - active: string; -} diff --git a/packages/discord-types/src/common/Application.d.ts b/packages/discord-types/src/common/Application.d.ts deleted file mode 100644 index d2ec1e7e..00000000 --- a/packages/discord-types/src/common/Application.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { User } from "./User"; - -export interface Application { - id: string; - name: string; - description?: string | null; - type: number | null; - icon: string | null | undefined; - is_discoverable: boolean; - is_monetized: boolean; - is_verified: boolean; - bot?: User; - deeplink_uri?: string; - flags?: number; - privacy_policy_url?: string; - terms_of_service_url?: string; - install_params?: ApplicationInstallParams; -} - -export interface ApplicationInstallParams { - permissions: string | null; - scopes: string[]; -} diff --git a/packages/discord-types/src/common/Channel.d.ts b/packages/discord-types/src/common/Channel.d.ts deleted file mode 100644 index 7ad5ce53..00000000 --- a/packages/discord-types/src/common/Channel.d.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { DiscordRecord } from "./Record"; - -export class Channel extends DiscordRecord { - constructor(channel: object); - application_id: number | undefined; - bitrate: number; - defaultAutoArchiveDuration: number | undefined; - flags: number; - guild_id: string; - icon: string; - id: string; - lastMessageId: string; - lastPinTimestamp: string | undefined; - member: unknown; - memberCount: number | undefined; - memberIdsPreview: string[] | undefined; - memberListId: unknown; - messageCount: number | undefined; - name: string; - nicks: Record; - nsfw: boolean; - originChannelId: unknown; - ownerId: string; - parent_id: string; - permissionOverwrites: { - [role: string]: { - id: string; - type: number; - deny: bigint; - allow: bigint; - }; - }; - position: number; - rateLimitPerUser: number; - rawRecipients: { - id: string; - avatar: string; - username: string; - public_flags: number; - discriminator: string; - }[]; - recipients: string[]; - rtcRegion: string; - threadMetadata: { - locked: boolean; - archived: boolean; - invitable: boolean; - createTimestamp: string | undefined; - autoArchiveDuration: number; - archiveTimestamp: string | undefined; - }; - topic: string; - type: number; - userLimit: number; - videoQualityMode: undefined; - - get accessPermissions(): bigint; - get lastActiveTimestamp(): number; - - computeLurkerPermissionsAllowList(): unknown; - getApplicationId(): unknown; - getGuildId(): string; - getRecipientId(): unknown; - hasFlag(flag: number): boolean; - isActiveThread(): boolean; - isArchivedThread(): boolean; - isCategory(): boolean; - isDM(): boolean; - isDirectory(): boolean; - isForumChannel(): boolean; - isGroupDM(): boolean; - isGuildStageVoice(): boolean; - isGuildVoice(): boolean; - isListenModeCapable(): boolean; - isManaged(): boolean; - isMultiUserDM(): boolean; - isNSFW(): boolean; - isOwner(): boolean; - isPrivate(): boolean; - isSystemDM(): boolean; - isThread(): boolean; - isVocal(): boolean; -} diff --git a/packages/discord-types/src/common/Guild.d.ts b/packages/discord-types/src/common/Guild.d.ts deleted file mode 100644 index 5b5c3c74..00000000 --- a/packages/discord-types/src/common/Guild.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Role } from './Role'; -import { DiscordRecord } from './Record'; - -// copy(Object.keys(findByProps("CREATOR_MONETIZABLE")).map(JSON.stringify).join("|")) -export type GuildFeatures = - "INVITE_SPLASH" | "VIP_REGIONS" | "VANITY_URL" | "MORE_EMOJI" | "MORE_STICKERS" | "MORE_SOUNDBOARD" | "VERIFIED" | "COMMERCE" | "DISCOVERABLE" | "COMMUNITY" | "FEATURABLE" | "NEWS" | "HUB" | "PARTNERED" | "ANIMATED_ICON" | "BANNER" | "ENABLED_DISCOVERABLE_BEFORE" | "WELCOME_SCREEN_ENABLED" | "MEMBER_VERIFICATION_GATE_ENABLED" | "PREVIEW_ENABLED" | "ROLE_SUBSCRIPTIONS_ENABLED" | "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE" | "CREATOR_MONETIZABLE" | "CREATOR_MONETIZABLE_PROVISIONAL" | "CREATOR_MONETIZABLE_WHITEGLOVE" | "CREATOR_MONETIZABLE_DISABLED" | "CREATOR_MONETIZABLE_RESTRICTED" | "CREATOR_STORE_PAGE" | "CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING" | "PRODUCTS_AVAILABLE_FOR_PURCHASE" | "GUILD_WEB_PAGE_VANITY_URL" | "THREADS_ENABLED" | "THREADS_ENABLED_TESTING" | "NEW_THREAD_PERMISSIONS" | "ROLE_ICONS" | "TEXT_IN_STAGE_ENABLED" | "TEXT_IN_VOICE_ENABLED" | "HAS_DIRECTORY_ENTRY" | "ANIMATED_BANNER" | "LINKED_TO_HUB" | "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT" | "GUILD_HOME_DEPRECATION_OVERRIDE" | "GUILD_HOME_TEST" | "GUILD_HOME_OVERRIDE" | "GUILD_ONBOARDING" | "GUILD_ONBOARDING_EVER_ENABLED" | "GUILD_ONBOARDING_HAS_PROMPTS" | "GUILD_SERVER_GUIDE" | "INTERNAL_EMPLOYEE_ONLY" | "AUTO_MODERATION" | "INVITES_DISABLED" | "BURST_REACTIONS" | "SOUNDBOARD" | "SHARD" | "ACTIVITY_FEED_ENABLED_BY_USER" | "ACTIVITY_FEED_DISABLED_BY_USER" | "SUMMARIES_ENABLED_GA" | "LEADERBOARD_ENABLED" | "SUMMARIES_ENABLED_BY_USER" | "SUMMARIES_OPT_OUT_EXPERIENCE" | "CHANNEL_ICON_EMOJIS_GENERATED" | "NON_COMMUNITY_RAID_ALERTS" | "RAID_ALERTS_DISABLED" | "AUTOMOD_TRIGGER_USER_PROFILE" | "ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY" | "GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE" | "CLAN" | "MEMBER_VERIFICATION_MANUAL_APPROVAL" | "FORWARDING_DISABLED" | "MEMBER_VERIFICATION_ROLLOUT_TEST" | "AUDIO_BITRATE_128_KBPS" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS" | "VIDEO_BITRATE_ENHANCED" | "MAX_FILE_SIZE_50_MB" | "MAX_FILE_SIZE_100_MB" | "GUILD_TAGS" | "ENHANCED_ROLE_COLORS" | "PREMIUM_TIER_3_OVERRIDE" | "REPORT_TO_MOD_PILOT" | "TIERLESS_BOOSTING_SYSTEM_MESSAGE"; -export type GuildPremiumFeatures = - "ANIMATED_ICON" | "STAGE_CHANNEL_VIEWERS_150" | "ROLE_ICONS" | "GUILD_TAGS" | "BANNER" | "MAX_FILE_SIZE_50_MB" | "VIDEO_QUALITY_720_60FPS" | "STAGE_CHANNEL_VIEWERS_50" | "VIDEO_QUALITY_1080_60FPS" | "MAX_FILE_SIZE_100_MB" | "VANITY_URL" | "VIDEO_BITRATE_ENHANCED" | "STAGE_CHANNEL_VIEWERS_300" | "AUDIO_BITRATE_128_KBPS" | "ANIMATED_BANNER" | "TIERLESS_BOOSTING" | "ENHANCED_ROLE_COLORS" | "INVITE_SPLASH" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS"; - -export class Guild extends DiscordRecord { - constructor(guild: object); - afkChannelId: string | undefined; - afkTimeout: number; - applicationCommandCounts: { - 0: number; - 1: number; - 2: number; - }; - application_id: unknown; - banner: string | undefined; - defaultMessageNotifications: number; - description: string | undefined; - discoverySplash: string | undefined; - explicitContentFilter: number; - features: Set; - homeHeader: string | undefined; - hubType: unknown; - icon: string | undefined; - id: string; - joinedAt: Date; - latestOnboardingQuestionId: string | undefined; - maxMembers: number; - maxStageVideoChannelUsers: number; - maxVideoChannelUsers: number; - mfaLevel: number; - moderatorReporting: unknown; - name: string; - nsfwLevel: number; - ownerConfiguredContentLevel: number; - ownerId: string; - preferredLocale: string; - premiumFeatures: { - additionalEmojiSlots: number; - additionalSoundSlots: number; - additionalStickerSlots: number; - features: Array; - }; - premiumProgressBarEnabled: boolean; - premiumSubscriberCount: number; - premiumTier: number; - profile: { - badge: string | undefined; - tag: string | undefined; - } | undefined; - publicUpdatesChannelId: string | undefined; - roles: Record; - rulesChannelId: string | undefined; - safetyAlertsChannelId: string | undefined; - splash: string | undefined; - systemChannelFlags: number; - systemChannelId: string | undefined; - vanityURLCode: string | undefined; - verificationLevel: number; -} diff --git a/packages/discord-types/src/common/GuildMember.d.ts b/packages/discord-types/src/common/GuildMember.d.ts deleted file mode 100644 index 5cd47682..00000000 --- a/packages/discord-types/src/common/GuildMember.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -export interface GuildMember { - avatar: string | undefined; - avatarDecoration: string | undefined; - banner: string | undefined; - bio: string; - colorRoleId: string | undefined; - colorString: string; - colorStrings: { - primaryColor: string | undefined; - secondaryColor: string | undefined; - tertiaryColor: string | undefined; - }; - communicationDisabledUntil: string | undefined; - flags: number; - fullProfileLoadedTimestamp: number; - guildId: string; - highestRoleId: string; - hoistRoleId: string; - iconRoleId: string; - isPending: boolean | undefined; - joinedAt: string | undefined; - nick: string | undefined; - premiumSince: string | undefined; - roles: string[]; - userId: string; -} diff --git a/packages/discord-types/src/common/Record.d.ts b/packages/discord-types/src/common/Record.d.ts deleted file mode 100644 index 8f033058..00000000 --- a/packages/discord-types/src/common/Record.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -type Updater = (value: any) => any; - -/** - * Common Record class extended by various Discord data structures, like User, Channel, Guild, etc. - */ -export class DiscordRecord { - toJS(): Record; - - set(key: string, value: any): this; - merge(data: Record): this; - update(key: string, defaultValueOrUpdater: Updater | any, updater?: Updater): this; -} diff --git a/packages/discord-types/src/common/Role.d.ts b/packages/discord-types/src/common/Role.d.ts deleted file mode 100644 index 7b038984..00000000 --- a/packages/discord-types/src/common/Role.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -export interface Role { - color: number; - colorString: string | undefined; - colorStrings: { - primaryColor: string | undefined; - secondaryColor: string | undefined; - tertiaryColor: string | undefined; - }; - colors: { - primary_color: number | undefined; - secondary_color: number | undefined; - tertiary_color: number | undefined; - }; - flags: number; - hoist: boolean; - icon: string | undefined; - id: string; - managed: boolean; - mentionable: boolean; - name: string; - originalPosition: number; - permissions: bigint; - position: number; - /** - * probably incomplete - */ - tags: { - bot_id: string; - integration_id: string; - premium_subscriber: unknown; - } | undefined; - unicodeEmoji: string | undefined; -} diff --git a/packages/discord-types/src/common/User.d.ts b/packages/discord-types/src/common/User.d.ts deleted file mode 100644 index 07eb4718..00000000 --- a/packages/discord-types/src/common/User.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -// TODO: a lot of optional params can also be null, not just undef - -import { DiscordRecord } from "./Record"; - -export class User extends DiscordRecord { - constructor(user: object); - accentColor: number; - avatar: string; - banner: string | null | undefined; - bio: string; - bot: boolean; - desktop: boolean; - discriminator: string; - email: string | undefined; - flags: number; - globalName: string | undefined; - guildMemberAvatars: Record; - id: string; - mfaEnabled: boolean; - mobile: boolean; - nsfwAllowed: boolean | undefined; - phone: string | undefined; - premiumType: number | undefined; - premiumUsageFlags: number; - publicFlags: number; - purchasedFlags: number; - system: boolean; - username: string; - verified: boolean; - - get createdAt(): Date; - get hasPremiumPerks(): boolean; - get tag(): string; - get usernameNormalized(): string; - - addGuildAvatarHash(guildId: string, avatarHash: string): User; - getAvatarSource(guildId: string, canAnimate?: boolean): { uri: string; }; - getAvatarURL(guildId?: string | null, t?: unknown, canAnimate?: boolean): string; - hasAvatarForGuild(guildId: string): boolean; - hasDisabledPremium(): boolean; - hasFlag(flag: number): boolean; - hasFreePremium(): boolean; - hasHadSKU(e: unknown): boolean; - hasPremiumUsageFlag(flag: number): boolean; - hasPurchasedFlag(flag: number): boolean; - hasUrgentMessages(): boolean; - isClaimed(): boolean; - isLocalBot(): boolean; - isNonUserBot(): boolean; - isPhoneVerified(): boolean; - isStaff(): boolean; - isSystemUser(): boolean; - isVerifiedBot(): boolean; - removeGuildAvatarHash(guildId: string): User; - toString(): string; -} - -export interface UserJSON { - avatar: string; - avatarDecoration: unknown | undefined; - discriminator: string; - id: string; - publicFlags: number; - username: string; -} diff --git a/packages/discord-types/src/common/index.d.ts b/packages/discord-types/src/common/index.d.ts deleted file mode 100644 index 5e50e96e..00000000 --- a/packages/discord-types/src/common/index.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from "./Application"; -export * from "./Channel"; -export * from "./Guild"; -export * from "./GuildMember"; -export * from "./messages"; -export * from "./Role"; -export * from "./User"; -export * from "./Record"; diff --git a/packages/discord-types/src/common/messages/Commands.d.ts b/packages/discord-types/src/common/messages/Commands.d.ts deleted file mode 100644 index 8dc9f9a7..00000000 --- a/packages/discord-types/src/common/messages/Commands.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Channel } from "../Channel"; -import { Guild } from "../Guild"; -import { Promisable } from "type-fest"; -import { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType } from "../../../enums"; - -export interface CommandContext { - channel: Channel; - guild?: Guild; -} - -export interface CommandOption { - name: string; - displayName?: string; - type: ApplicationCommandOptionType; - description: string; - displayDescription?: string; - required?: boolean; - options?: CommandOption[]; - choices?: Array; -} - -export interface ChoicesOption { - label: string; - value: string; - name: string; - displayName?: string; -} - -export interface CommandReturnValue { - content: string; - // TODO: implement - // cancel?: boolean; -} - -export interface CommandArgument { - type: ApplicationCommandOptionType; - name: string; - value: string; - focused: undefined; - options: CommandArgument[]; -} - -export interface Command { - id?: string; - applicationId?: string; - type?: ApplicationCommandType; - inputType?: ApplicationCommandInputType; - plugin?: string; - - name: string; - untranslatedName?: string; - displayName?: string; - description: string; - untranslatedDescription?: string; - displayDescription?: string; - - options?: CommandOption[]; - predicate?(ctx: CommandContext): boolean; - - execute(args: CommandArgument[], ctx: CommandContext): Promisable; -} diff --git a/packages/discord-types/src/common/messages/Embed.d.ts b/packages/discord-types/src/common/messages/Embed.d.ts deleted file mode 100644 index 4edd9ced..00000000 --- a/packages/discord-types/src/common/messages/Embed.d.ts +++ /dev/null @@ -1,70 +0,0 @@ -export interface Embed { - author?: { - name: string; - url: string; - iconURL: string | undefined; - iconProxyURL: string | undefined; - }; - color: string; - fields: []; - id: string; - image?: { - height: number; - width: number; - url: string; - proxyURL: string; - }; - provider?: { - name: string; - url: string | undefined; - }; - rawDescription: string; - rawTitle: string; - referenceId: unknown; - timestamp: string; - thumbnail?: { - height: number; - proxyURL: string | undefined; - url: string; - width: number; - }; - type: string; - url: string | undefined; - video?: { - height: number; - width: number; - url: string; - proxyURL: string | undefined; - }; -} - -export interface EmbedJSON { - author?: { - name: string; - url: string; - icon_url: string; - proxy_icon_url: string; - }; - title: string; - color: string; - description: string; - type: string; - url: string | undefined; - provider?: { - name: string; - url: string; - }; - timestamp: string; - thumbnail?: { - height: number; - width: number; - url: string; - proxy_url: string | undefined; - }; - video?: { - height: number; - width: number; - url: string; - proxy_url: string | undefined; - }; -} diff --git a/packages/discord-types/src/common/messages/Emoji.d.ts b/packages/discord-types/src/common/messages/Emoji.d.ts deleted file mode 100644 index 793e90f8..00000000 --- a/packages/discord-types/src/common/messages/Emoji.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -export type Emoji = CustomEmoji | UnicodeEmoji; - -export interface CustomEmoji { - type: 1; - allNamesString: string; - animated: boolean; - available: boolean; - guildId: string; - id: string; - managed: boolean; - name: string; - originalName?: string; - require_colons: boolean; - roles: string[]; -} - -export interface UnicodeEmoji { - type: 0; - diversityChildren: Record; - emojiObject: { - names: string[]; - surrogates: string; - unicodeVersion: number; - }; - index: number; - surrogates: string; - uniqueName: string; - useSpriteSheet: boolean; - get allNamesString(): string; - get animated(): boolean; - get defaultDiversityChild(): any; - get hasDiversity(): boolean | undefined; - get hasDiversityParent(): boolean | undefined; - get hasMultiDiversity(): boolean | undefined; - get hasMultiDiversityParent(): boolean | undefined; - get managed(): boolean; - get name(): string; - get names(): string[]; - get optionallyDiverseSequence(): string | undefined; - get unicodeVersion(): number; - get url(): string; -} diff --git a/packages/discord-types/src/common/messages/Message.d.ts b/packages/discord-types/src/common/messages/Message.d.ts deleted file mode 100644 index 38010caf..00000000 --- a/packages/discord-types/src/common/messages/Message.d.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { CommandOption } from './Commands'; -import { User, UserJSON } from '../User'; -import { Embed, EmbedJSON } from './Embed'; -import { DiscordRecord } from "../Record"; - -/** - * TODO: looks like discord has moved over to Date instead of Moment; - */ -export class Message extends DiscordRecord { - constructor(message: object); - activity: unknown; - application: unknown; - applicationId: string | unknown; - attachments: MessageAttachment[]; - author: User; - blocked: boolean; - bot: boolean; - call: { - duration: moment.Duration; - endedTimestamp: moment.Moment; - participants: string[]; - }; - channel_id: string; - /** - * NOTE: not fully typed - */ - codedLinks: { - code?: string; - type: string; - }[]; - colorString: unknown; - components: unknown[]; - content: string; - customRenderedContent: unknown; - editedTimestamp: Date; - embeds: Embed[]; - flags: number; - giftCodes: string[]; - id: string; - interaction: { - id: string; - name: string; - type: number; - user: User; - }[] | undefined; - interactionData: { - application_command: { - application_id: string; - default_member_permissions: unknown; - default_permission: boolean; - description: string; - dm_permission: unknown; - id: string; - name: string; - options: CommandOption[]; - permissions: unknown[]; - type: number; - version: string; - }; - attachments: MessageAttachment[]; - guild_id: string | undefined; - id: string; - name: string; - options: { - focused: unknown; - name: string; - type: number; - value: string; - }[]; - type: number; - version: string; - }[]; - interactionError: unknown[]; - isSearchHit: boolean; - loggingName: unknown; - mentionChannels: string[]; - mentionEveryone: boolean; - mentionRoles: string[]; - mentioned: boolean; - mentions: string[]; - messageReference: { - guild_id?: string; - channel_id: string; - message_id: string; - } | undefined; - nick: unknown; // probably a string - nonce: string | undefined; - pinned: boolean; - reactions: MessageReaction[]; - state: string; - stickerItems: { - format_type: number; - id: string; - name: string; - }[]; - stickers: unknown[]; - timestamp: moment.Moment; - tts: boolean; - type: number; - webhookId: string | undefined; - - /** - * Doesn't actually update the original message; it just returns a new message instance with the added reaction. - */ - addReaction(emoji: ReactionEmoji, fromCurrentUser: boolean): Message; - /** - * Searches each reaction and if the provided string has an index above -1 it'll return the reaction object. - */ - getReaction(name: string): MessageReaction; - /** - * Doesn't actually update the original message; it just returns the message instance without the reaction searched with the provided emoji object. - */ - removeReactionsForEmoji(emoji: ReactionEmoji): Message; - /** - * Doesn't actually update the original message; it just returns the message instance without the reaction. - */ - removeReaction(emoji: ReactionEmoji, fromCurrentUser: boolean): Message; - - getChannelId(): string; - hasFlag(flag: number): boolean; - isCommandType(): boolean; - isEdited(): boolean; - isSystemDM(): boolean; -} - -/** A smaller Message object found in FluxDispatcher and elsewhere. */ -export interface MessageJSON { - attachments: MessageAttachment[]; - author: UserJSON; - channel_id: string; - components: unknown[]; - content: string; - edited_timestamp: string; - embeds: EmbedJSON[]; - flags: number; - guild_id: string | undefined; - id: string; - loggingName: unknown; - member: { - avatar: string | undefined; - communication_disabled_until: string | undefined; - deaf: boolean; - hoisted_role: string | undefined; - is_pending: boolean; - joined_at: string; - mute: boolean; - nick: string | boolean; - pending: boolean; - premium_since: string | undefined; - roles: string[]; - } | undefined; - mention_everyone: boolean; - mention_roles: string[]; - mentions: UserJSON[]; - message_reference: { - guild_id?: string; - channel_id: string; - message_id: string; - } | undefined; - nonce: string | undefined; - pinned: boolean; - referenced_message: MessageJSON | undefined; - state: string; - timestamp: string; - tts: boolean; - type: number; -} - -export interface MessageAttachment { - filename: string; - id: string; - proxy_url: string; - size: number; - spoiler: boolean; - url: string; - content_type?: string; - width?: number; - height?: number; -} - -export interface ReactionEmoji { - id: string | undefined; - name: string; - animated: boolean; -} - -export interface MessageReaction { - count: number; - emoji: ReactionEmoji; - me: boolean; -} diff --git a/packages/discord-types/src/common/messages/index.d.ts b/packages/discord-types/src/common/messages/index.d.ts deleted file mode 100644 index 245e971e..00000000 --- a/packages/discord-types/src/common/messages/index.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./Commands"; -export * from "./Message"; -export * from "./Embed"; -export * from "./Emoji"; diff --git a/packages/discord-types/src/flux.d.ts b/packages/discord-types/src/flux.d.ts deleted file mode 100644 index bb5600dd..00000000 --- a/packages/discord-types/src/flux.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { FluxStore } from "./stores/FluxStore"; - -export class FluxEmitter { - constructor(); - - changeSentinel: number; - changedStores: Set; - isBatchEmitting: boolean; - isDispatching: boolean; - isPaused: boolean; - pauseTimer: NodeJS.Timeout | null; - reactChangedStores: Set; - - batched(batch: (...args: any[]) => void): void; - destroy(): void; - emit(): void; - emitNonReactOnce(): void; - emitReactOnce(): void; - getChangeSentinel(): number; - getIsPaused(): boolean; - injectBatchEmitChanges(batch: (...args: any[]) => void): void; - markChanged(store: FluxStore): void; - pause(): void; - resume(): void; -} - -export interface Flux { - Store: typeof FluxStore; - Emitter: FluxEmitter; -} diff --git a/packages/discord-types/src/fluxEvents.d.ts b/packages/discord-types/src/fluxEvents.d.ts deleted file mode 100644 index c210f4b9..00000000 --- a/packages/discord-types/src/fluxEvents.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* -function makeFluxEventList() { - // prefill MESSAGE_CREATE so that typescript infers this is a String Set - // without explicitly typing so that this function is also valid javascript - const events = new Set(["MESSAGE_CREATE"]); - - const { nodes } = Vencord.Webpack.Common.FluxDispatcher._actionHandlers._dependencyGraph; - for (const nodeId in nodes) { - for (const event in nodes[nodeId].actionHandler) { - events.add(event); - } - } - for (const event in Vencord.Webpack.Common.FluxDispatcher._subscriptions) { - events.add(event); - } - - return Array.from(events, e => JSON.stringify(e)).sort().join("|"); -} -copy(makeFluxEventList()) -*/ - -export type FluxEvents = "ACCESSIBILITY_COLORBLIND_TOGGLE" | "ACCESSIBILITY_DARK_SIDEBAR_TOGGLE" | "ACCESSIBILITY_DESATURATE_ROLES_TOGGLE" | "ACCESSIBILITY_FORCED_COLORS_MODAL_SEEN" | "ACCESSIBILITY_KEYBOARD_MODE_DISABLE" | "ACCESSIBILITY_KEYBOARD_MODE_ENABLE" | "ACCESSIBILITY_LOW_CONTRAST_TOGGLE" | "ACCESSIBILITY_RESET_TO_DEFAULT" | "ACCESSIBILITY_SET_ALWAYS_SHOW_LINK_DECORATIONS" | "ACCESSIBILITY_SET_CONTRAST" | "ACCESSIBILITY_SET_FONT_SIZE" | "ACCESSIBILITY_SET_MESSAGE_GROUP_SPACING" | "ACCESSIBILITY_SET_PREFERS_REDUCED_MOTION" | "ACCESSIBILITY_SET_ROLE_STYLE" | "ACCESSIBILITY_SET_SATURATION" | "ACCESSIBILITY_SET_SYNC_FORCED_COLORS" | "ACCESSIBILITY_SET_ZOOM" | "ACCESSIBILITY_SUBMIT_BUTTON_TOGGLE" | "ACCESSIBILITY_SYNC_PROFILE_THEME_WITH_USER_THEME_TOGGLE" | "ACCESSIBILITY_SYSTEM_COLOR_PREFERENCES_CHANGED" | "ACCESSIBILITY_SYSTEM_PREFERS_CONTRAST_CHANGED" | "ACCESSIBILITY_SYSTEM_PREFERS_CROSSFADES_CHANGED" | "ACCESSIBILITY_SYSTEM_PREFERS_REDUCED_MOTION_CHANGED" | "ACKNOWLEDGE_CHANNEL_SAFETY_WARNING_TOOLTIP" | "ACK_APPROVED_GUILD_JOIN_REQUEST" | "ACTIVE_AV_ERRORS_CHANGED" | "ACTIVE_BOGO_PROMOTION_FETCH" | "ACTIVE_BOGO_PROMOTION_FETCH_FAIL" | "ACTIVE_BOGO_PROMOTION_FETCH_SUCCESS" | "ACTIVE_CHANNELS_FETCH_FAILURE" | "ACTIVE_CHANNELS_FETCH_START" | "ACTIVE_CHANNELS_FETCH_SUCCESS" | "ACTIVE_OUTBOUND_PROMOTIONS_FETCH" | "ACTIVE_OUTBOUND_PROMOTIONS_FETCH_FAIL" | "ACTIVE_OUTBOUND_PROMOTIONS_FETCH_SUCCESS" | "ACTIVITY_INVITE_EDUCATION_DISMISS" | "ACTIVITY_INVITE_MODAL_CLOSE" | "ACTIVITY_INVITE_MODAL_OPEN" | "ACTIVITY_INVITE_MODAL_QUERY" | "ACTIVITY_INVITE_MODAL_SEND" | "ACTIVITY_JOIN" | "ACTIVITY_JOIN_FAILED" | "ACTIVITY_JOIN_LOADING" | "ACTIVITY_LAUNCH_FAIL" | "ACTIVITY_LAYOUT_MODE_UPDATE" | "ACTIVITY_METADATA_UPDATE" | "ACTIVITY_PLAY" | "ACTIVITY_POPOUT_WINDOW_OPEN" | "ACTIVITY_SCREEN_ORIENTATION_UPDATE" | "ACTIVITY_START" | "ACTIVITY_SYNC" | "ACTIVITY_SYNC_STOP" | "ACTIVITY_UPDATE_FAIL" | "ACTIVITY_UPDATE_START" | "ACTIVITY_UPDATE_SUCCESS" | "ADD_STICKER_PREVIEW" | "ADMIN_ONBOARDING_GUIDE_HIDE" | "ADYEN_CASH_APP_PAY_SUBMIT_SUCCESS" | "ADYEN_CREATE_CASH_APP_PAY_COMPONENT_SUCCESS" | "ADYEN_CREATE_CLIENT_SUCCESS" | "ADYEN_TEARDOWN_CLIENT" | "AFK" | "AGE_GATE_FAILURE_MODAL_OPEN" | "AGE_GATE_LOGOUT_UNDERAGE_NEW_USER" | "AGE_GATE_MODAL_CLOSE" | "AGE_GATE_MODAL_OPEN" | "AGE_GATE_SUCCESS_MODAL_OPEN" | "APEX_EXPERIMENT_CLEAR_SERVER_ASSIGNMENTS" | "APEX_EXPERIMENT_OVERRIDE_CLEAR" | "APEX_EXPERIMENT_OVERRIDE_CREATE" | "APEX_EXPERIMENT_OVERRIDE_DELETE" | "APPLICATIONS_FETCH" | "APPLICATIONS_FETCH_FAIL" | "APPLICATIONS_FETCH_SUCCESS" | "APPLICATION_ACTIVITY_STATISTICS_FETCH_FAIL" | "APPLICATION_ACTIVITY_STATISTICS_FETCH_START" | "APPLICATION_ACTIVITY_STATISTICS_FETCH_SUCCESS" | "APPLICATION_ASSETS_FETCH" | "APPLICATION_ASSETS_FETCH_SUCCESS" | "APPLICATION_ASSETS_UPDATE" | "APPLICATION_BRANCHES_FETCH_FAIL" | "APPLICATION_BRANCHES_FETCH_SUCCESS" | "APPLICATION_BUILD_FETCH_START" | "APPLICATION_BUILD_FETCH_SUCCESS" | "APPLICATION_BUILD_NOT_FOUND" | "APPLICATION_BUILD_SIZE_FETCH_FAIL" | "APPLICATION_BUILD_SIZE_FETCH_START" | "APPLICATION_BUILD_SIZE_FETCH_SUCCESS" | "APPLICATION_COMMAND_AUTOCOMPLETE_REQUEST" | "APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE" | "APPLICATION_COMMAND_EXECUTE_BAD_VERSION" | "APPLICATION_COMMAND_INDEX_FETCH_FAILURE" | "APPLICATION_COMMAND_INDEX_FETCH_REQUEST" | "APPLICATION_COMMAND_INDEX_FETCH_SUCCESS" | "APPLICATION_COMMAND_SET_ACTIVE_COMMAND" | "APPLICATION_COMMAND_SET_PREFERRED_COMMAND" | "APPLICATION_COMMAND_UPDATE_CHANNEL_STATE" | "APPLICATION_COMMAND_UPDATE_OPTIONS" | "APPLICATION_COMMAND_USED" | "APPLICATION_DIRECTORY_FETCH_APPLICATION" | "APPLICATION_DIRECTORY_FETCH_APPLICATION_FAILURE" | "APPLICATION_DIRECTORY_FETCH_APPLICATION_SUCCESS" | "APPLICATION_DIRECTORY_FETCH_CATEGORIES_SUCCESS" | "APPLICATION_DIRECTORY_FETCH_COLLECTIONS" | "APPLICATION_DIRECTORY_FETCH_COLLECTIONS_FAILURE" | "APPLICATION_DIRECTORY_FETCH_COLLECTIONS_SUCCESS" | "APPLICATION_DIRECTORY_FETCH_SEARCH" | "APPLICATION_DIRECTORY_FETCH_SEARCH_FAILURE" | "APPLICATION_DIRECTORY_FETCH_SEARCH_SUCCESS" | "APPLICATION_DIRECTORY_FETCH_SIMILAR_APPLICATIONS" | "APPLICATION_DIRECTORY_FETCH_SIMILAR_APPLICATIONS_FAILURE" | "APPLICATION_DIRECTORY_FETCH_SIMILAR_APPLICATIONS_SUCCESS" | "APPLICATION_FETCH" | "APPLICATION_FETCH_FAIL" | "APPLICATION_FETCH_SUCCESS" | "APPLICATION_STORE_ACCEPT_EULA" | "APPLICATION_STORE_ACCEPT_STORE_TERMS" | "APPLICATION_STORE_CLEAR_DATA" | "APPLICATION_STORE_DIRECTORY_LAYOUT_FETCHING" | "APPLICATION_STORE_DIRECTORY_LAYOUT_FETCH_FAILED" | "APPLICATION_STORE_DIRECTORY_LAYOUT_FETCH_SUCCESS" | "APPLICATION_STORE_LOCATION_CHANGE" | "APPLICATION_STORE_MATURE_AGREE" | "APPLICATION_STORE_RESET_NAVIGATION" | "APPLICATION_SUBSCRIPTIONS_CHANNEL_NOTICE_DISMISSED" | "APPLICATION_SUBSCRIPTIONS_FETCH_ENTITLEMENTS" | "APPLICATION_SUBSCRIPTIONS_FETCH_ENTITLEMENTS_FAILURE" | "APPLICATION_SUBSCRIPTIONS_FETCH_ENTITLEMENTS_SUCCESS" | "APPLICATION_SUBSCRIPTIONS_FETCH_LISTINGS" | "APPLICATION_SUBSCRIPTIONS_FETCH_LISTINGS_FAILURE" | "APPLICATION_SUBSCRIPTIONS_FETCH_LISTINGS_SUCCESS" | "APPLICATION_SUBSCRIPTIONS_FETCH_LISTING_FOR_PLAN_SUCCESS" | "APPLICATION_UPDATE" | "APPLIED_BOOSTS_COOLDOWN_FETCH_SUCCESS" | "APPLIED_GUILD_BOOST_COUNT_RESET" | "APPLIED_GUILD_BOOST_COUNT_UPDATE" | "APP_DM_OPEN" | "APP_ICON_EDITOR_RESET" | "APP_ICON_TRACK_IMPRESSION" | "APP_ICON_UPDATED" | "APP_LAUNCHER_ADD_FAILED_APP_DM_LOAD" | "APP_LAUNCHER_DISMISS" | "APP_LAUNCHER_REMOVE_FAILED_APP_DM_LOAD" | "APP_LAUNCHER_SET_ACTIVE_COMMAND" | "APP_LAUNCHER_SHOW" | "APP_RECOMMENDATIONS_FETCH_RECOMMENDATIONS" | "APP_RECOMMENDATIONS_FETCH_RECOMMENDATIONS_FAILURE" | "APP_RECOMMENDATIONS_FETCH_RECOMMENDATIONS_SUCCESS" | "APP_STATE_UPDATE" | "APP_VIEW_SET_HOME_LINK" | "AUDIO_INPUT_DETECTED" | "AUDIO_RESET" | "AUDIO_SET_ACTIVE_INPUT_PROFILE" | "AUDIO_SET_ATTENUATION" | "AUDIO_SET_AUTOMATIC_GAIN_CONTROL" | "AUDIO_SET_BYPASS_SYSTEM_INPUT_PROCESSING" | "AUDIO_SET_DEBUG_LOGGING" | "AUDIO_SET_DISPLAY_SILENCE_WARNING" | "AUDIO_SET_ECHO_CANCELLATION" | "AUDIO_SET_INPUT_DEVICE" | "AUDIO_SET_INPUT_VOLUME" | "AUDIO_SET_KRISP_MODEL_OVERRIDE" | "AUDIO_SET_KRISP_SUPPRESSION_LEVEL" | "AUDIO_SET_LOCAL_PAN" | "AUDIO_SET_LOCAL_VIDEO_DISABLED" | "AUDIO_SET_LOCAL_VOLUME" | "AUDIO_SET_LOOPBACK" | "AUDIO_SET_MODE" | "AUDIO_SET_NOISE_CANCELLATION" | "AUDIO_SET_NOISE_SUPPRESSION" | "AUDIO_SET_OUTPUT_DEVICE" | "AUDIO_SET_OUTPUT_VOLUME" | "AUDIO_SET_QOS" | "AUDIO_SET_SELF_MUTE" | "AUDIO_SET_SIDECHAIN_COMPRESSION" | "AUDIO_SET_SIDECHAIN_COMPRESSION_STRENGTH" | "AUDIO_SET_SUBSYSTEM" | "AUDIO_SET_TEMPORARY_SELF_MUTE" | "AUDIO_TOGGLE_LOCAL_MUTE" | "AUDIO_TOGGLE_LOCAL_SOUNDBOARD_MUTE" | "AUDIO_TOGGLE_SELF_DEAF" | "AUDIO_TOGGLE_SELF_MUTE" | "AUDIO_VOLUME_CHANGE" | "AUDIT_LOG_FETCH_FAIL" | "AUDIT_LOG_FETCH_NEXT_PAGE_FAIL" | "AUDIT_LOG_FETCH_NEXT_PAGE_START" | "AUDIT_LOG_FETCH_NEXT_PAGE_SUCCESS" | "AUDIT_LOG_FETCH_START" | "AUDIT_LOG_FETCH_SUCCESS" | "AUDIT_LOG_FILTER_BY_ACTION" | "AUDIT_LOG_FILTER_BY_TARGET" | "AUDIT_LOG_FILTER_BY_USER" | "AUTHENTICATOR_CREATE" | "AUTHENTICATOR_DELETE" | "AUTHENTICATOR_UPDATE" | "AUTH_INVITE_UPDATE" | "AUTH_SESSION_CHANGE" | "AUTO_MODERATION_MENTION_RAID_DETECTION" | "AUTO_MODERATION_MENTION_RAID_NOTICE_DISMISS" | "AUTO_UPDATER_QUIT_AND_INSTALL" | "BACKGROUND_SYNC" | "BACKGROUND_SYNC_CHANNEL_MESSAGES" | "BASIC_GUILD_FETCH" | "BASIC_GUILD_FETCH_FAILURE" | "BASIC_GUILD_FETCH_SUCCESS" | "BILLING_CREATE_REFERRAL_SUCCESS" | "BILLING_IP_COUNTRY_CODE_FAILURE" | "BILLING_IP_COUNTRY_CODE_FETCH_START" | "BILLING_IP_LOCATION_FAILURE" | "BILLING_IP_LOCATION_FETCH_START" | "BILLING_LOCALIZED_PRICING_PROMO_FAILURE" | "BILLING_MOST_RECENT_SUBSCRIPTION_FETCH_SUCCESS" | "BILLING_NITRO_AFFINITY_FETCHED" | "BILLING_NITRO_AFFINITY_FETCH_SUCCEEDED" | "BILLING_PAYMENTS_FETCH_SUCCESS" | "BILLING_PAYMENT_FETCH_SUCCESS" | "BILLING_PAYMENT_SOURCES_FETCH_FAIL" | "BILLING_PAYMENT_SOURCES_FETCH_START" | "BILLING_PAYMENT_SOURCES_FETCH_SUCCESS" | "BILLING_PAYMENT_SOURCE_CREATE_FAIL" | "BILLING_PAYMENT_SOURCE_CREATE_START" | "BILLING_PAYMENT_SOURCE_CREATE_SUCCESS" | "BILLING_PAYMENT_SOURCE_FETCH_SUCCESS" | "BILLING_PAYMENT_SOURCE_REMOVE_CLEAR_ERROR" | "BILLING_PAYMENT_SOURCE_REMOVE_FAIL" | "BILLING_PAYMENT_SOURCE_REMOVE_START" | "BILLING_PAYMENT_SOURCE_REMOVE_SUCCESS" | "BILLING_PAYMENT_SOURCE_UPDATE_CLEAR_ERROR" | "BILLING_PAYMENT_SOURCE_UPDATE_FAIL" | "BILLING_PAYMENT_SOURCE_UPDATE_START" | "BILLING_PAYMENT_SOURCE_UPDATE_SUCCESS" | "BILLING_POPUP_BRIDGE_CALLBACK" | "BILLING_POPUP_BRIDGE_STATE_UPDATE" | "BILLING_PREVIOUS_PREMIUM_SUBSCRIPTION_FETCH_SUCCESS" | "BILLING_PURCHASE_TOKEN_AUTH_CLEAR_STATE" | "BILLING_REFERRALS_REMAINING_FETCH_FAIL" | "BILLING_REFERRALS_REMAINING_FETCH_START" | "BILLING_REFERRALS_REMAINING_FETCH_SUCCESS" | "BILLING_REFERRAL_RESOLVE_FAIL" | "BILLING_REFERRAL_RESOLVE_SUCCESS" | "BILLING_REFERRAL_TRIAL_OFFER_UPDATE" | "BILLING_SET_IP_COUNTRY_CODE" | "BILLING_SET_IP_LOCATION" | "BILLING_SET_LOCALIZED_PRICING_PROMO" | "BILLING_SUBSCRIPTION_CANCEL_FAIL" | "BILLING_SUBSCRIPTION_CANCEL_START" | "BILLING_SUBSCRIPTION_CANCEL_SUCCESS" | "BILLING_SUBSCRIPTION_FETCH_FAIL" | "BILLING_SUBSCRIPTION_FETCH_START" | "BILLING_SUBSCRIPTION_FETCH_SUCCESS" | "BILLING_SUBSCRIPTION_RESET" | "BILLING_SUBSCRIPTION_REWARD_ELIGIBILITY_FETCH_FAILURE" | "BILLING_SUBSCRIPTION_REWARD_ELIGIBILITY_FETCH_START" | "BILLING_SUBSCRIPTION_REWARD_ELIGIBILITY_FETCH_SUCCESS" | "BILLING_SUBSCRIPTION_UPDATE_FAIL" | "BILLING_SUBSCRIPTION_UPDATE_START" | "BILLING_SUBSCRIPTION_UPDATE_SUCCESS" | "BILLING_USER_OFFER_ACKNOWLEDGED_SUCCESS" | "BILLING_USER_OFFER_FETCH_FAIL" | "BILLING_USER_OFFER_FETCH_START" | "BILLING_USER_OFFER_FETCH_SUCCESS" | "BILLING_USER_TRIAL_OFFER_ACKNOWLEDGED_SUCCESS" | "BILLING_USER_TRIAL_OFFER_FETCH_SUCCESS" | "BOOSTED_GUILD_GRACE_PERIOD_NOTICE_DISMISS" | "BRAINTREE_CREATE_CLIENT_SUCCESS" | "BRAINTREE_CREATE_PAYPAL_CLIENT_SUCCESS" | "BRAINTREE_CREATE_VENMO_CLIENT_SUCCESS" | "BRAINTREE_TEARDOWN_PAYPAL_CLIENT" | "BRAINTREE_TEARDOWN_VENMO_CLIENT" | "BRAINTREE_TOKENIZE_PAYPAL_FAIL" | "BRAINTREE_TOKENIZE_PAYPAL_START" | "BRAINTREE_TOKENIZE_PAYPAL_SUCCESS" | "BRAINTREE_TOKENIZE_VENMO_FAIL" | "BRAINTREE_TOKENIZE_VENMO_START" | "BRAINTREE_TOKENIZE_VENMO_SUCCESS" | "BROWSER_HANDOFF_BEGIN" | "BROWSER_HANDOFF_FROM_APP" | "BROWSER_HANDOFF_SET_USER" | "BROWSER_HANDOFF_UNAVAILABLE" | "BUILD_OVERRIDE_RESOLVED" | "BULK_ACK" | "BULK_CLEAR_RECENTS" | "BURST_REACTION_ANIMATION_ADD" | "BURST_REACTION_EFFECT_CLEAR" | "BURST_REACTION_EFFECT_PLAY" | "BURST_REACTION_PICKER_ANIMATION_ADD" | "BURST_REACTION_PICKER_ANIMATION_CLEAR" | "CACHED_EMOJIS_LOADED" | "CACHED_STICKERS_LOADED" | "CACHE_LOADED" | "CACHE_LOADED_LAZY" | "CACHE_LOADED_LAZY_NO_CACHE" | "CALL_CHAT_TOASTS_SET_ENABLED" | "CALL_CONNECT" | "CALL_CONNECT_MULTIPLE" | "CALL_CREATE" | "CALL_DELETE" | "CALL_ENQUEUE_RING" | "CALL_UPDATE" | "CANDIDATE_GAMES_CHANGE" | "CATEGORY_COLLAPSE" | "CATEGORY_COLLAPSE_ALL" | "CATEGORY_EXPAND" | "CATEGORY_EXPAND_ALL" | "CERTIFIED_DEVICES_SET" | "CHANGE_LOG_FETCH_FAILED" | "CHANGE_LOG_FETCH_SUCCESS" | "CHANGE_LOG_LOCK" | "CHANGE_LOG_MARK_SEEN" | "CHANGE_LOG_RESOLVED" | "CHANGE_LOG_SET_CONFIG" | "CHANGE_LOG_SET_OVERRIDE" | "CHANGE_LOG_UNLOCK" | "CHANNEL_ACK" | "CHANNEL_CALL_POPOUT_WINDOW_OPEN" | "CHANNEL_COLLAPSE" | "CHANNEL_CREATE" | "CHANNEL_DELETE" | "CHANNEL_FOLLOWER_CREATED" | "CHANNEL_FOLLOWER_STATS_FETCH_FAILURE" | "CHANNEL_FOLLOWER_STATS_FETCH_SUCCESS" | "CHANNEL_FOLLOWING_PUBLISH_BUMP_DISMISSED" | "CHANNEL_FOLLOWING_PUBLISH_BUMP_HIDE_PERMANENTLY" | "CHANNEL_LOCAL_ACK" | "CHANNEL_MEMBER_COUNT_UPDATE" | "CHANNEL_MUTE_EXPIRED" | "CHANNEL_PERMISSIONS_DELETE_OVERWRITE_SUCCESS" | "CHANNEL_PERMISSIONS_PUT_OVERWRITE_SUCCESS" | "CHANNEL_PINS_ACK" | "CHANNEL_PINS_UPDATE" | "CHANNEL_PRELOAD" | "CHANNEL_RECIPIENT_ADD" | "CHANNEL_RECIPIENT_REMOVE" | "CHANNEL_RTC_ACTIVE_CHANNELS" | "CHANNEL_RTC_JUMP_TO_VOICE_CHANNEL_MESSAGE" | "CHANNEL_RTC_SELECT_PARTICIPANT" | "CHANNEL_RTC_UPDATE_CHAT_OPEN" | "CHANNEL_RTC_UPDATE_LAYOUT" | "CHANNEL_RTC_UPDATE_PARTCIPANTS_LIST_OPEN" | "CHANNEL_RTC_UPDATE_PARTICIPANTS_OPEN" | "CHANNEL_RTC_UPDATE_STAGE_STREAM_SIZE" | "CHANNEL_RTC_UPDATE_STAGE_VIDEO_LIMIT_BOOST_UPSELL_DISMISSED" | "CHANNEL_RTC_UPDATE_VOICE_PARTICIPANTS_HIDDEN" | "CHANNEL_SAFETY_WARNING_FEEDBACK" | "CHANNEL_SELECT" | "CHANNEL_SETTINGS_CLOSE" | "CHANNEL_SETTINGS_INIT" | "CHANNEL_SETTINGS_LOADED_INVITES" | "CHANNEL_SETTINGS_OVERWRITE_SELECT" | "CHANNEL_SETTINGS_PERMISSIONS_INIT" | "CHANNEL_SETTINGS_PERMISSIONS_SAVE_SUCCESS" | "CHANNEL_SETTINGS_PERMISSIONS_SELECT_PERMISSION" | "CHANNEL_SETTINGS_PERMISSIONS_SET_ADVANCED_MODE" | "CHANNEL_SETTINGS_PERMISSIONS_SUBMITTING" | "CHANNEL_SETTINGS_PERMISSIONS_UPDATE_PERMISSION" | "CHANNEL_SETTINGS_SET_SECTION" | "CHANNEL_SETTINGS_SUBMIT" | "CHANNEL_SETTINGS_SUBMIT_FAILURE" | "CHANNEL_SETTINGS_SUBMIT_SUCCESS" | "CHANNEL_SETTINGS_UPDATE" | "CHANNEL_STATUSES" | "CHANNEL_TOGGLE_MEMBERS_SECTION" | "CHANNEL_TOGGLE_SUMMARIES_SECTION" | "CHANNEL_UPDATES" | "CHECKING_FOR_UPDATES" | "CHECKOUT_RECOVERY_STATUS_FETCH" | "CHECKOUT_RECOVERY_STATUS_FETCH_FAILURE" | "CHECKOUT_RECOVERY_STATUS_FETCH_SUCCESS" | "CHECK_LAUNCHABLE_GAME" | "CLEAR_CACHES" | "CLEAR_CHANNEL_SAFETY_WARNINGS" | "CLEAR_CONSUMED_ENTITLEMENT" | "CLEAR_CONVERSATION_SUMMARIES" | "CLEAR_INTERACTION_MODAL_STATE" | "CLEAR_LAST_SESSION_VOICE_CHANNEL_ID" | "CLEAR_MENTIONS" | "CLEAR_MESSAGES" | "CLEAR_OLDEST_UNREAD_MESSAGE" | "CLEAR_PENDING_CHANNEL_AND_ROLE_UPDATES" | "CLEAR_REMOTE_DISCONNECT_VOICE_CHANNEL_ID" | "CLEAR_STICKER_PREVIEW" | "CLEAR_THEME_OVERRIDE" | "CLEAR_VIDEO_STREAM_READY_TIMEOUT" | "CLICKER_GAME_ADD_POINTS" | "CLICKER_GAME_PURCHASE_ITEM" | "CLICKER_GAME_PURCHASE_ITEM_UPGRADE" | "CLICKER_GAME_REDEEM_PRIZE_FAIL" | "CLICKER_GAME_REDEEM_PRIZE_START" | "CLICKER_GAME_REDEEM_PRIZE_SUCCESS" | "CLICKER_GAME_RESET" | "CLICKER_GAME_SET_MUTED" | "CLICKER_GAME_SET_VOLUME" | "CLICKER_GAME_UNLOCK_ACHIEVEMENT" | "CLICKER_GAME_UPDATE_ITEM_METADATA" | "CLIENT_THEMES_EDITOR_CLOSE" | "CLIPS_ALLOW_VOICE_RECORDING_UPDATE" | "CLIPS_CLASSIFY_HARDWARE" | "CLIPS_CLEAR_CLIPS_SESSION" | "CLIPS_CLEAR_NEW_CLIP_IDS" | "CLIPS_DELETE_CLIP" | "CLIPS_DISMISS_EDUCATION" | "CLIPS_INIT" | "CLIPS_INIT_FAILURE" | "CLIPS_LOAD_DIRECTORY_SUCCESS" | "CLIPS_RESTART" | "CLIPS_SAVE_ANIMATION_END" | "CLIPS_SAVE_CLIP" | "CLIPS_SAVE_CLIP_ERROR" | "CLIPS_SAVE_CLIP_PLACEHOLDER" | "CLIPS_SAVE_CLIP_PLACEHOLDER_ERROR" | "CLIPS_SAVE_CLIP_START" | "CLIPS_SETTINGS_UPDATE" | "CLIPS_SHOW_CALL_WARNING" | "CLIPS_UPDATE_METADATA" | "CLOSE_AGE_VERIFICATION_MODAL" | "CLOSE_SUSPENDED_USER" | "COLLECTIBLES_CATEGORIES_FETCH" | "COLLECTIBLES_CATEGORIES_FETCH_FAILURE" | "COLLECTIBLES_CATEGORIES_FETCH_SUCCESS" | "COLLECTIBLES_CLAIM" | "COLLECTIBLES_CLAIM_FAILURE" | "COLLECTIBLES_CLAIM_SUCCESS" | "COLLECTIBLES_MARKETING_FETCH" | "COLLECTIBLES_MARKETING_FETCH_SUCCESS" | "COLLECTIBLES_PRODUCT_DETAILS_OPEN" | "COLLECTIBLES_PRODUCT_FETCH" | "COLLECTIBLES_PRODUCT_FETCH_FAILURE" | "COLLECTIBLES_PRODUCT_FETCH_SUCCESS" | "COLLECTIBLES_PURCHASES_FETCH" | "COLLECTIBLES_PURCHASES_FETCH_FAILURE" | "COLLECTIBLES_PURCHASES_FETCH_SUCCESS" | "COLLECTIBLES_SET_SHOP_HOME_CONFIG_OVERRIDE" | "COLLECTIBLES_SHOP_CLOSE" | "COLLECTIBLES_SHOP_HOME_FETCH" | "COLLECTIBLES_SHOP_HOME_FETCH_FAILURE" | "COLLECTIBLES_SHOP_HOME_FETCH_SUCCESS" | "COLLECTIBLES_SHOP_OPEN" | "COLLECTIBLES_SKIP_NUM_CATEGORIES" | "COMMANDS_MIGRATION_NOTICE_DISMISSED" | "COMMANDS_MIGRATION_OVERVIEW_TOOLTIP_DISMISSED" | "COMMANDS_MIGRATION_TOGGLE_TOOLTIP_DISMISSED" | "COMMANDS_MIGRATION_UPDATE_SUCCESS" | "COMPLETE_NEW_MEMBER_ACTION" | "CONNECTED_DEVICE_DONT_SWITCH" | "CONNECTED_DEVICE_IGNORE" | "CONNECTED_DEVICE_NEVER_SHOW_MODAL" | "CONNECTED_DEVICE_SWITCH" | "CONNECTIONS_GRID_MODAL_HIDE" | "CONNECTIONS_GRID_MODAL_SHOW" | "CONNECTION_CLOSED" | "CONNECTION_OPEN" | "CONNECTION_OPEN_STATE_UPDATE" | "CONNECTION_OPEN_SUPPLEMENTAL" | "CONNECTION_RESUMED" | "CONSOLE_COMMAND_UPDATE" | "CONSUMABLES_CLEAR_ERROR" | "CONSUMABLES_ENTITLEMENT_FETCH_COMPLETED" | "CONSUMABLES_ENTITLEMENT_FETCH_FAILED" | "CONSUMABLES_ENTITLEMENT_FETCH_STARTED" | "CONSUMABLES_PRICE_FETCH_FAILED" | "CONSUMABLES_PRICE_FETCH_STARTED" | "CONSUMABLES_PRICE_FETCH_SUCCEEDED" | "CONTENT_INVENTORY_CLEAR_DELETE_HISTORY_ERROR" | "CONTENT_INVENTORY_CLEAR_FEED" | "CONTENT_INVENTORY_DEBUG_CLEAR_IMPRESSIONS" | "CONTENT_INVENTORY_DEBUG_LOG_IMPRESSIONS" | "CONTENT_INVENTORY_DEBUG_TOGGLE_FAST_IMPRESSION_CAPPING" | "CONTENT_INVENTORY_DEBUG_TOGGLE_IMPRESSION_CAPPING" | "CONTENT_INVENTORY_DELETE_OUTBOX_ENTRY_FAILURE" | "CONTENT_INVENTORY_DELETE_OUTBOX_ENTRY_START" | "CONTENT_INVENTORY_DELETE_OUTBOX_ENTRY_SUCCESS" | "CONTENT_INVENTORY_FETCH_OUTBOX_FAILURE" | "CONTENT_INVENTORY_FETCH_OUTBOX_START" | "CONTENT_INVENTORY_FETCH_OUTBOX_SUCCESS" | "CONTENT_INVENTORY_FORCE_SHOW_GAME_SHARING" | "CONTENT_INVENTORY_INBOX_STALE" | "CONTENT_INVENTORY_MANUAL_REFRESH" | "CONTENT_INVENTORY_SET_FEED" | "CONTENT_INVENTORY_SET_FEED_STATE" | "CONTENT_INVENTORY_SET_FILTERS" | "CONTENT_INVENTORY_TOGGLE_FEED_HIDDEN" | "CONTENT_INVENTORY_TRACK_ITEM_IMPRESSIONS" | "CONTEXT_MENU_CLOSE" | "CONTEXT_MENU_OPEN" | "CONVERSATION_SUMMARY_UPDATE" | "CREATE_PENDING_REPLY" | "CREATE_PENDING_SCHEDULED_MESSAGE" | "CREATE_REFERRALS_SUCCESS" | "CREATE_SHALLOW_PENDING_REPLY" | "CREATOR_MONETIZATION_NAG_ACTIVATE_ELIGIBLITY_FETCH_SUCCESS" | "CREATOR_MONETIZATION_PRICE_TIERS_FETCH" | "CREATOR_MONETIZATION_PRICE_TIERS_FETCH_FAILURE" | "CREATOR_MONETIZATION_PRICE_TIERS_FETCH_SUCCESS" | "CURRENT_BUILD_OVERRIDE_RESOLVED" | "CURRENT_USER_UPDATE" | "CUSTOM_ACTIVITY_LINK_FETCH_SUCCESS" | "DCF_DAILY_CAP_OVERRIDE" | "DCF_EVENT_LOGGED" | "DCF_HANDLE_DC_DISMISSED" | "DCF_HANDLE_DC_SHOWN" | "DCF_NEW_USER_MIN_AGE_REQUIRED_OVERRIDE" | "DCF_OVERRIDE_LAST_DC_DISMISSED" | "DCF_RESET" | "DECAY_READ_STATES" | "DELETED_ENTITY_IDS" | "DELETE_PENDING_REPLY" | "DELETE_PENDING_SCHEDULED_MESSAGE" | "DELETE_SUMMARY" | "DETECTABLE_GAME_SUPPLEMENTAL_FETCH" | "DETECTABLE_GAME_SUPPLEMENTAL_FETCH_FAILURE" | "DETECTABLE_GAME_SUPPLEMENTAL_FETCH_SUCCESS" | "DETECTED_OFF_PLATFORM_PREMIUM_PERKS_DISMISS" | "DEVELOPER_ACTIVITY_SHELF_FETCH_FAIL" | "DEVELOPER_ACTIVITY_SHELF_FETCH_START" | "DEVELOPER_ACTIVITY_SHELF_FETCH_SUCCESS" | "DEVELOPER_ACTIVITY_SHELF_MARK_ACTIVITY_USED" | "DEVELOPER_ACTIVITY_SHELF_SET_ACTIVITY_URL_OVERRIDE" | "DEVELOPER_ACTIVITY_SHELF_TOGGLE_USE_ACTIVITY_URL_OVERRIDE" | "DEVELOPER_ACTIVITY_SHELF_UPDATE_FILTER" | "DEVELOPER_OPTIONS_UPDATE_SETTINGS" | "DEVELOPER_TEST_MODE_AUTHORIZATION_FAIL" | "DEVELOPER_TEST_MODE_AUTHORIZATION_START" | "DEVELOPER_TEST_MODE_AUTHORIZATION_SUCCESS" | "DEVELOPER_TEST_MODE_RESET" | "DEVELOPER_TEST_MODE_RESET_ERROR" | "DEV_TOOLS_DESIGN_TOGGLE_SET" | "DEV_TOOLS_DESIGN_TOGGLE_WEB_SET" | "DEV_TOOLS_DEV_SETTING_SET" | "DEV_TOOLS_FRIENDS_LIST_GIFT_INTENTS_SHOWN_RESET" | "DEV_TOOLS_FRIENDS_TAB_BADGE_COOLDOWN_RESET" | "DEV_TOOLS_GIFT_MESSAGE_COOLDOWN_RESET" | "DEV_TOOLS_SETTINGS_UPDATE" | "DEV_TOOLS_SET_FRIEND_ANNIVERSARY_COUNT" | "DISABLE_AUTOMATIC_ACK" | "DISCOVER_CHECKLIST_FETCH_FAILURE" | "DISCOVER_CHECKLIST_FETCH_START" | "DISCOVER_CHECKLIST_FETCH_SUCCESS" | "DISMISS_CHANNEL_SAFETY_WARNINGS" | "DISMISS_FAVORITE_SUGGESTION" | "DISMISS_MEDIA_POST_SHARE_PROMPT" | "DISPATCH_APPLICATION_ADD_TO_INSTALLATIONS" | "DISPATCH_APPLICATION_CANCEL" | "DISPATCH_APPLICATION_ERROR" | "DISPATCH_APPLICATION_INSTALL" | "DISPATCH_APPLICATION_INSTALL_SCRIPTS_PROGRESS_UPDATE" | "DISPATCH_APPLICATION_LAUNCH_SETUP_COMPLETE" | "DISPATCH_APPLICATION_LAUNCH_SETUP_START" | "DISPATCH_APPLICATION_MOVE_UP" | "DISPATCH_APPLICATION_REMOVE_FINISHED" | "DISPATCH_APPLICATION_REPAIR" | "DISPATCH_APPLICATION_STATE_UPDATE" | "DISPATCH_APPLICATION_UNINSTALL" | "DISPATCH_APPLICATION_UPDATE" | "DISPLAYED_INVITE_SHOW" | "DOMAIN_MIGRATION_FAILURE" | "DOMAIN_MIGRATION_SKIP" | "DOMAIN_MIGRATION_START" | "DRAFT_CHANGE" | "DRAFT_CLEAR" | "DRAFT_SAVE" | "EMAIL_SETTINGS_FETCH_SUCCESS" | "EMAIL_SETTINGS_UPDATE" | "EMAIL_SETTINGS_UPDATE_SUCCESS" | "EMBEDDED_ACTIVITY_CLOSE" | "EMBEDDED_ACTIVITY_DEFERRED_OPEN" | "EMBEDDED_ACTIVITY_FETCH_SHELF" | "EMBEDDED_ACTIVITY_FETCH_SHELF_FAIL" | "EMBEDDED_ACTIVITY_FETCH_SHELF_SUCCESS" | "EMBEDDED_ACTIVITY_LAUNCH_FAIL" | "EMBEDDED_ACTIVITY_LAUNCH_START" | "EMBEDDED_ACTIVITY_LAUNCH_SUCCESS" | "EMBEDDED_ACTIVITY_OPEN" | "EMBEDDED_ACTIVITY_SET_CONFIG" | "EMBEDDED_ACTIVITY_SET_FOCUSED_LAYOUT" | "EMBEDDED_ACTIVITY_SET_ORIENTATION_LOCK_STATE" | "EMBEDDED_ACTIVITY_SET_PANEL_MODE" | "EMBEDDED_ACTIVITY_UPDATE" | "EMBEDDED_ACTIVITY_UPDATE_POPOUT_WINDOW_LAYOUT" | "EMBEDDED_ACTIVITY_UPDATE_V2" | "EMOJI_AUTOSUGGESTION_UPDATE" | "EMOJI_DELETE" | "EMOJI_FETCH_FAILURE" | "EMOJI_FETCH_SUCCESS" | "EMOJI_INTERACTION_INITIATED" | "EMOJI_TRACK_USAGE" | "EMOJI_UPLOAD_START" | "EMOJI_UPLOAD_STOP" | "ENABLE_AUTOMATIC_ACK" | "ENTITLEMENTS_FETCH_FOR_USER_FAIL" | "ENTITLEMENTS_FETCH_FOR_USER_START" | "ENTITLEMENTS_FETCH_FOR_USER_SUCCESS" | "ENTITLEMENTS_GIFTABLE_FETCH_SUCCESS" | "ENTITLEMENT_CREATE" | "ENTITLEMENT_DELETE" | "ENTITLEMENT_FETCH_APPLICATION_FAIL" | "ENTITLEMENT_FETCH_APPLICATION_START" | "ENTITLEMENT_FETCH_APPLICATION_SUCCESS" | "ENTITLEMENT_UPDATE" | "EVENT_DIRECTORY_FETCH_FAILURE" | "EVENT_DIRECTORY_FETCH_START" | "EVENT_DIRECTORY_FETCH_SUCCESS" | "EXPERIMENTS_FETCH" | "EXPERIMENTS_FETCH_FAILURE" | "EXPERIMENTS_FETCH_SUCCESS" | "EXPERIMENT_OVERRIDE_BUCKET" | "FAMILY_CENTER_FETCH_START" | "FAMILY_CENTER_HANDLE_TAB_SELECT" | "FAMILY_CENTER_INITIAL_LOAD" | "FAMILY_CENTER_LINKED_USERS_FETCH_SUCCESS" | "FAMILY_CENTER_LINK_CODE_FETCH_SUCCESS" | "FAMILY_CENTER_REQUEST_LINK_REMOVE_SUCCESS" | "FAMILY_CENTER_REQUEST_LINK_SUCCESS" | "FAMILY_CENTER_REQUEST_LINK_UPDATE_SUCCESS" | "FAMILY_CENTER_TEEN_ACTIVITY_FETCH_SUCCESS" | "FAMILY_CENTER_TEEN_ACTIVITY_MORE_FETCH_SUCCESS" | "FEEDBACK_OVERRIDE_CLEAR" | "FEEDBACK_OVERRIDE_SET" | "FETCH_AUTH_SESSIONS_SUCCESS" | "FETCH_CHAT_WALLPAPERS_FAILURE" | "FETCH_CHAT_WALLPAPERS_START" | "FETCH_CHAT_WALLPAPERS_SUCCESS" | "FETCH_GUILD_EVENT" | "FETCH_GUILD_EVENTS_FOR_GUILD" | "FETCH_GUILD_MEMBER_SUPPLEMENTAL_SUCCESS" | "FETCH_INTEGRATION_APPLICATION_IDS_FOR_MY_GUILDS" | "FETCH_INTEGRATION_APPLICATION_IDS_FOR_MY_GUILDS_FAILURE" | "FETCH_INTEGRATION_APPLICATION_IDS_FOR_MY_GUILDS_SUCCESS" | "FETCH_SCHEDULED_MESSAGES" | "FETCH_SCHEDULED_MESSAGES_FAILURE" | "FETCH_SCHEDULED_MESSAGES_SUCCESS" | "FINGERPRINT" | "FORCE_INVISIBLE" | "FORGOT_PASSWORD_REQUEST" | "FORGOT_PASSWORD_SENT" | "FORUM_SEARCH_CLEAR" | "FORUM_SEARCH_FAILURE" | "FORUM_SEARCH_QUERY_UPDATED" | "FORUM_SEARCH_START" | "FORUM_SEARCH_SUCCESS" | "FORUM_UNREADS" | "FRIENDS_LIST_GIFT_INTENTS_SHOWN" | "FRIENDS_SET_INITIAL_SECTION" | "FRIENDS_SET_SECTION" | "FRIENDS_TAB_BADGE_DISMISS" | "FRIEND_INVITES_FETCH_REQUEST" | "FRIEND_INVITES_FETCH_RESPONSE" | "FRIEND_INVITE_CREATE_FAILURE" | "FRIEND_INVITE_CREATE_REQUEST" | "FRIEND_INVITE_CREATE_SUCCESS" | "FRIEND_INVITE_REVOKE_REQUEST" | "FRIEND_INVITE_REVOKE_SUCCESS" | "FRIEND_SUGGESTION_CREATE" | "FRIEND_SUGGESTION_DELETE" | "GAMES_DATABASE_FETCH" | "GAMES_DATABASE_FETCH_FAIL" | "GAMES_DATABASE_UPDATE" | "GAME_CLOUD_SYNC_COMPLETE" | "GAME_CLOUD_SYNC_CONFLICT" | "GAME_CLOUD_SYNC_ERROR" | "GAME_CLOUD_SYNC_START" | "GAME_CLOUD_SYNC_UPDATE" | "GAME_CONSOLE_FETCH_DEVICES_FAIL" | "GAME_CONSOLE_FETCH_DEVICES_START" | "GAME_CONSOLE_FETCH_DEVICES_SUCCESS" | "GAME_CONSOLE_SELECT_DEVICE" | "GAME_DETECTION_DEBUGGING_START" | "GAME_DETECTION_DEBUGGING_STOP" | "GAME_DETECTION_DEBUGGING_TICK" | "GAME_DETECTION_WATCH_CANDIDATE_GAMES_START" | "GAME_ICON_UPDATE" | "GAME_INVITE_CLEAR_UNSEEN" | "GAME_INVITE_CREATE" | "GAME_INVITE_DELETE" | "GAME_INVITE_DELETE_MANY" | "GAME_INVITE_UPDATE_STATUS" | "GAME_LAUNCHABLE_UPDATE" | "GAME_LAUNCH_FAIL" | "GAME_LAUNCH_START" | "GAME_LAUNCH_SUCCESS" | "GAME_PROFILE_OPEN" | "GAME_RELATIONSHIP_ADD" | "GAME_RELATIONSHIP_REMOVE" | "GENERIC_PUSH_NOTIFICATION_SENT" | "GIFT_CODES_FETCH" | "GIFT_CODES_FETCH_FAILURE" | "GIFT_CODES_FETCH_SUCCESS" | "GIFT_CODE_CREATE" | "GIFT_CODE_CREATE_SUCCESS" | "GIFT_CODE_REDEEM" | "GIFT_CODE_REDEEM_FAILURE" | "GIFT_CODE_REDEEM_SUCCESS" | "GIFT_CODE_RESOLVE" | "GIFT_CODE_RESOLVE_FAILURE" | "GIFT_CODE_RESOLVE_SUCCESS" | "GIFT_CODE_REVOKE_SUCCESS" | "GIFT_CODE_UPDATE" | "GIFT_INTENT_FLOW_PURCHASED_GIFT" | "GIF_PICKER_INITIALIZE" | "GIF_PICKER_QUERY" | "GIF_PICKER_QUERY_FAILURE" | "GIF_PICKER_QUERY_SUCCESS" | "GIF_PICKER_SUGGESTIONS_SUCCESS" | "GIF_PICKER_TRENDING_FETCH_SUCCESS" | "GIF_PICKER_TRENDING_SEARCH_TERMS_SUCCESS" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_CLEAR" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_COUNT_FAILURE" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_COUNT_START" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_COUNT_SUCCESS" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_FAILURE" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_LAYOUT_RESET" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_START" | "GLOBAL_DISCOVERY_SERVERS_SEARCH_SUCCESS" | "GUILD_ACK" | "GUILD_ANALYTICS_ENGAGEMENT_OVERVIEW_FETCH_FAILURE" | "GUILD_ANALYTICS_ENGAGEMENT_OVERVIEW_FETCH_SUCCESS" | "GUILD_ANALYTICS_GROWTH_ACTIVATION_OVERVIEW_FETCH_FAILURE" | "GUILD_ANALYTICS_GROWTH_ACTIVATION_OVERVIEW_FETCH_SUCCESS" | "GUILD_ANALYTICS_GROWTH_ACTIVATION_RETENTION_FETCH_FAILURE" | "GUILD_ANALYTICS_GROWTH_ACTIVATION_RETENTION_FETCH_SUCCESS" | "GUILD_APPLICATIONS_FETCH_SUCCESS" | "GUILD_APPLICATION_COMMAND_INDEX_UPDATE" | "GUILD_APPLIED_BOOSTS_FETCH_SUCCESS" | "GUILD_APPLIED_BOOSTS_UPDATE" | "GUILD_APPLY_BOOST_FAIL" | "GUILD_APPLY_BOOST_START" | "GUILD_APPLY_BOOST_SUCCESS" | "GUILD_BAN_ADD" | "GUILD_BAN_REMOVE" | "GUILD_BOOST_SLOTS_FETCH" | "GUILD_BOOST_SLOTS_FETCH_SUCCESS" | "GUILD_BOOST_SLOT_CREATE" | "GUILD_BOOST_SLOT_UPDATE" | "GUILD_BOOST_SLOT_UPDATE_SUCCESS" | "GUILD_CREATE" | "GUILD_DELETE" | "GUILD_DIRECTORY_ADMIN_ENTRIES_FETCH_SUCCESS" | "GUILD_DIRECTORY_CACHED_SEARCH" | "GUILD_DIRECTORY_CATEGORY_SELECT" | "GUILD_DIRECTORY_COUNTS_FETCH_SUCCESS" | "GUILD_DIRECTORY_ENTRY_CREATE" | "GUILD_DIRECTORY_ENTRY_DELETE" | "GUILD_DIRECTORY_ENTRY_UPDATE" | "GUILD_DIRECTORY_FETCH_FAILURE" | "GUILD_DIRECTORY_FETCH_START" | "GUILD_DIRECTORY_FETCH_SUCCESS" | "GUILD_DIRECTORY_SEARCH_CLEAR" | "GUILD_DIRECTORY_SEARCH_FAILURE" | "GUILD_DIRECTORY_SEARCH_START" | "GUILD_DIRECTORY_SEARCH_SUCCESS" | "GUILD_DISCOVERY_CATEGORY_ADD" | "GUILD_DISCOVERY_CATEGORY_DELETE" | "GUILD_DISCOVERY_CATEGORY_FETCH_SUCCESS" | "GUILD_DISCOVERY_CATEGORY_UPDATE_FAIL" | "GUILD_DISCOVERY_METADATA_FETCH_FAIL" | "GUILD_DISCOVERY_SLUG_FETCH_FAIL" | "GUILD_DISCOVERY_SLUG_FETCH_SUCCESS" | "GUILD_EMOJIS_UPDATE" | "GUILD_FEATURE_ACK" | "GUILD_FOLDER_COLLAPSE" | "GUILD_FOLDER_CREATE_LOCAL" | "GUILD_FOLDER_DELETE_LOCAL" | "GUILD_FOLDER_EDIT_LOCAL" | "GUILD_GEO_RESTRICTED" | "GUILD_HOME_SETTINGS_FETCH_FAIL" | "GUILD_HOME_SETTINGS_FETCH_START" | "GUILD_HOME_SETTINGS_FETCH_SUCCESS" | "GUILD_HOME_SETTINGS_TOGGLE_ENABLED" | "GUILD_HOME_SETTINGS_UPDATE_FAIL" | "GUILD_HOME_SETTINGS_UPDATE_START" | "GUILD_HOME_SETTINGS_UPDATE_SUCCESS" | "GUILD_IDENTITY_SETTINGS_CLEAR_ERRORS" | "GUILD_IDENTITY_SETTINGS_INIT" | "GUILD_IDENTITY_SETTINGS_RESET_ALL_PENDING" | "GUILD_IDENTITY_SETTINGS_RESET_AND_CLOSE_FORM" | "GUILD_IDENTITY_SETTINGS_RESET_PENDING_MEMBER_CHANGES" | "GUILD_IDENTITY_SETTINGS_RESET_PENDING_PROFILE_CHANGES" | "GUILD_IDENTITY_SETTINGS_SET_GUILD" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_AVATAR" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_AVATAR_DECORATION" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_BANNER" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_BIO" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_NICKNAME" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_PROFILE_EFFECT_ID" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_PRONOUNS" | "GUILD_IDENTITY_SETTINGS_SET_PENDING_THEME_COLORS" | "GUILD_IDENTITY_SETTINGS_SUBMIT" | "GUILD_IDENTITY_SETTINGS_SUBMIT_FAILURE" | "GUILD_IDENTITY_SETTINGS_SUBMIT_SUCCESS" | "GUILD_INTEGRATIONS_UPDATE" | "GUILD_JOIN" | "GUILD_JOIN_REQUESTS_BULK_ACTION" | "GUILD_JOIN_REQUESTS_FETCH_FAILURE" | "GUILD_JOIN_REQUESTS_FETCH_START" | "GUILD_JOIN_REQUESTS_FETCH_SUCCESS" | "GUILD_JOIN_REQUESTS_SET_APPLICATION_TAB" | "GUILD_JOIN_REQUESTS_SET_SELECTED" | "GUILD_JOIN_REQUESTS_SET_SORT_ORDER" | "GUILD_JOIN_REQUEST_BY_ID_FETCH_SUCCESS" | "GUILD_JOIN_REQUEST_CREATE" | "GUILD_JOIN_REQUEST_DELETE" | "GUILD_JOIN_REQUEST_UPDATE" | "GUILD_LOCAL_RING_START" | "GUILD_MEMBERS_CHUNK_BATCH" | "GUILD_MEMBERS_REQUEST" | "GUILD_MEMBER_ADD" | "GUILD_MEMBER_LIST_UPDATE" | "GUILD_MEMBER_PROFILE_UPDATE" | "GUILD_MEMBER_REMOVE" | "GUILD_MEMBER_REMOVE_LOCAL" | "GUILD_MEMBER_UPDATE" | "GUILD_MEMBER_UPDATE_LOCAL" | "GUILD_MOVE_BY_ID" | "GUILD_MUTE_EXPIRED" | "GUILD_NEW_MEMBER_ACTIONS_DELETE_SUCCESS" | "GUILD_NEW_MEMBER_ACTIONS_FETCH_FAIL" | "GUILD_NEW_MEMBER_ACTIONS_FETCH_START" | "GUILD_NEW_MEMBER_ACTIONS_FETCH_SUCCESS" | "GUILD_NEW_MEMBER_ACTION_UPDATE_SUCCESS" | "GUILD_NSFW_AGREE" | "GUILD_ONBOARDING_COMPLETE" | "GUILD_ONBOARDING_PROMPTS_FETCH_FAILURE" | "GUILD_ONBOARDING_PROMPTS_FETCH_START" | "GUILD_ONBOARDING_PROMPTS_FETCH_SUCCESS" | "GUILD_ONBOARDING_PROMPTS_LOCAL_UPDATE" | "GUILD_ONBOARDING_SELECT_OPTION" | "GUILD_ONBOARDING_SET_STEP" | "GUILD_ONBOARDING_START" | "GUILD_ONBOARDING_UPDATE_RESPONSES_SUCCESS" | "GUILD_POWERUPS_ACK_NOTIFICATION" | "GUILD_POWERUPS_RESET_NOTIFICATIONS" | "GUILD_POWERUP_CATALOG_FETCH_SUCCESS" | "GUILD_POWERUP_ENTITLEMENTS_CREATE" | "GUILD_POWERUP_ENTITLEMENTS_DELETE" | "GUILD_PRODUCTS_FETCH" | "GUILD_PRODUCTS_FETCH_FAILURE" | "GUILD_PRODUCTS_FETCH_SUCCESS" | "GUILD_PRODUCT_CREATE" | "GUILD_PRODUCT_DELETE" | "GUILD_PRODUCT_FETCH" | "GUILD_PRODUCT_FETCH_FAILURE" | "GUILD_PRODUCT_FETCH_SUCCESS" | "GUILD_PRODUCT_UPDATE" | "GUILD_PROFILE_FETCH" | "GUILD_PROFILE_FETCH_FAILURE" | "GUILD_PROFILE_FETCH_SUCCESS" | "GUILD_PROFILE_UPDATE" | "GUILD_PROFILE_UPDATE_FAILURE" | "GUILD_PROFILE_UPDATE_SUCCESS" | "GUILD_PROFILE_UPDATE_VISIBILITY" | "GUILD_PROFILE_UPDATE_VISIBILITY_FAILURE" | "GUILD_PROFILE_UPDATE_VISIBILITY_SUCCESS" | "GUILD_PROGRESS_COMPLETED_SEEN" | "GUILD_PROGRESS_DISMISS" | "GUILD_PROGRESS_INITIALIZE" | "GUILD_PROMPT_VIEWED" | "GUILD_RESOURCE_CHANNEL_UPDATE_SUCCESS" | "GUILD_RING_START" | "GUILD_RING_STOP" | "GUILD_ROLE_CONNECTIONS_CONFIGURATIONS_FETCH_SUCCESS" | "GUILD_ROLE_CONNECTIONS_MODAL_SHOW" | "GUILD_ROLE_CONNECTION_ELIGIBILITY_FETCH_SUCCESS" | "GUILD_ROLE_CREATE" | "GUILD_ROLE_DELETE" | "GUILD_ROLE_MEMBER_ADD" | "GUILD_ROLE_MEMBER_BULK_ADD" | "GUILD_ROLE_MEMBER_COUNT_FETCH_SUCCESS" | "GUILD_ROLE_MEMBER_COUNT_UPDATE" | "GUILD_ROLE_MEMBER_REMOVE" | "GUILD_ROLE_SUBSCRIPTIONS_CREATE_LISTING" | "GUILD_ROLE_SUBSCRIPTIONS_DELETE_GROUP_LISTING" | "GUILD_ROLE_SUBSCRIPTIONS_DELETE_LISTING" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_LISTINGS" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_LISTINGS_FAILURE" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_LISTINGS_SUCCESS" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_LISTING_FOR_PLAN" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_LISTING_FOR_PLAN_SUCCESS" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_RESTRICTIONS" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_RESTRICTIONS_ABORTED" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_RESTRICTIONS_FAILURE" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_RESTRICTIONS_SUCCESS" | "GUILD_ROLE_SUBSCRIPTIONS_FETCH_TEMPLATES" | "GUILD_ROLE_SUBSCRIPTIONS_STASH_TEMPLATE_CHANNELS" | "GUILD_ROLE_SUBSCRIPTIONS_UPDATE_GROUP_LISTING" | "GUILD_ROLE_SUBSCRIPTIONS_UPDATE_LISTING" | "GUILD_ROLE_SUBSCRIPTIONS_UPDATE_SUBSCRIPTIONS_SETTINGS" | "GUILD_ROLE_SUBSCRIPTIONS_UPDATE_SUBSCRIPTION_TRIAL" | "GUILD_ROLE_UPDATE" | "GUILD_SCHEDULED_EVENT_CREATE" | "GUILD_SCHEDULED_EVENT_DELETE" | "GUILD_SCHEDULED_EVENT_EXCEPTIONS_DELETE" | "GUILD_SCHEDULED_EVENT_EXCEPTION_CREATE" | "GUILD_SCHEDULED_EVENT_EXCEPTION_DELETE" | "GUILD_SCHEDULED_EVENT_EXCEPTION_UPDATE" | "GUILD_SCHEDULED_EVENT_RSVPS_FETCH_SUCESS" | "GUILD_SCHEDULED_EVENT_UPDATE" | "GUILD_SCHEDULED_EVENT_USERS_FETCH_SUCCESS" | "GUILD_SCHEDULED_EVENT_USER_ADD" | "GUILD_SCHEDULED_EVENT_USER_COUNTS_FETCH_SUCCESS" | "GUILD_SCHEDULED_EVENT_USER_REMOVE" | "GUILD_SEARCH_RECENT_MEMBERS" | "GUILD_SETTINGS_CANCEL_CHANGES" | "GUILD_SETTINGS_CLOSE" | "GUILD_SETTINGS_DEFAULT_CHANNELS_RESET" | "GUILD_SETTINGS_DEFAULT_CHANNELS_SAVE_FAILED" | "GUILD_SETTINGS_DEFAULT_CHANNELS_SAVE_SUCCESS" | "GUILD_SETTINGS_DEFAULT_CHANNELS_SUBMIT" | "GUILD_SETTINGS_DEFAULT_CHANNELS_TOGGLE" | "GUILD_SETTINGS_INIT" | "GUILD_SETTINGS_JOIN_RULES_APPLY_SET_PENDING_FORM_FIELDS" | "GUILD_SETTINGS_JOIN_RULES_INVITE_SET_PENDING_RULES" | "GUILD_SETTINGS_JOIN_RULES_SET_CONTENT_LEVEL" | "GUILD_SETTINGS_JOIN_RULES_SET_SELECTED_TYPE" | "GUILD_SETTINGS_LOADED_BANS" | "GUILD_SETTINGS_LOADED_BANS_BATCH" | "GUILD_SETTINGS_LOADED_INTEGRATIONS" | "GUILD_SETTINGS_LOADED_INVITES" | "GUILD_SETTINGS_ONBOARDING_ADD_NEW_MEMBER_ACTION" | "GUILD_SETTINGS_ONBOARDING_ADD_RESOURCE_CHANNEL" | "GUILD_SETTINGS_ONBOARDING_DELETE_NEW_MEMBER_ACTION" | "GUILD_SETTINGS_ONBOARDING_DELETE_RESOURCE_CHANNEL" | "GUILD_SETTINGS_ONBOARDING_DISMISS_RESOURCE_CHANNEL_SUGGESTION" | "GUILD_SETTINGS_ONBOARDING_EDUCATION_UPSELL_DISMISSED" | "GUILD_SETTINGS_ONBOARDING_HOME_SETTINGS_RESET" | "GUILD_SETTINGS_ONBOARDING_PROMPTS_EDIT" | "GUILD_SETTINGS_ONBOARDING_PROMPTS_ERRORS" | "GUILD_SETTINGS_ONBOARDING_PROMPTS_RESET" | "GUILD_SETTINGS_ONBOARDING_PROMPTS_SAVE_FAILED" | "GUILD_SETTINGS_ONBOARDING_PROMPTS_SAVE_SUCCESS" | "GUILD_SETTINGS_ONBOARDING_PROMPTS_SUBMIT" | "GUILD_SETTINGS_ONBOARDING_REORDER_NEW_MEMBER_ACTION" | "GUILD_SETTINGS_ONBOARDING_REORDER_RESOURCE_CHANNEL" | "GUILD_SETTINGS_ONBOARDING_SET_MODE" | "GUILD_SETTINGS_ONBOARDING_STEP" | "GUILD_SETTINGS_ONBOARDING_UPDATE_NEW_MEMBER_ACTION" | "GUILD_SETTINGS_ONBOARDING_UPDATE_RESOURCE_CHANNEL" | "GUILD_SETTINGS_ONBOARDING_UPDATE_WELCOME_MESSAGE" | "GUILD_SETTINGS_OPEN" | "GUILD_SETTINGS_PROFILE_UPDATE" | "GUILD_SETTINGS_ROLES_CLEAR_PERMISSIONS" | "GUILD_SETTINGS_ROLES_INIT" | "GUILD_SETTINGS_ROLES_ROLE_STYLE_UPDATE" | "GUILD_SETTINGS_ROLES_SAVE_FAIL" | "GUILD_SETTINGS_ROLES_SAVE_SUCCESS" | "GUILD_SETTINGS_ROLES_SORT_UPDATE" | "GUILD_SETTINGS_ROLES_SUBMITTING" | "GUILD_SETTINGS_ROLES_UPDATE_COLOR" | "GUILD_SETTINGS_ROLES_UPDATE_COLORS" | "GUILD_SETTINGS_ROLES_UPDATE_DESCRIPTION" | "GUILD_SETTINGS_ROLES_UPDATE_NAME" | "GUILD_SETTINGS_ROLES_UPDATE_PERMISSIONS" | "GUILD_SETTINGS_ROLES_UPDATE_PERMISSION_SET" | "GUILD_SETTINGS_ROLES_UPDATE_ROLE_CONNECTION_CONFIGURATIONS" | "GUILD_SETTINGS_ROLES_UPDATE_ROLE_ICON" | "GUILD_SETTINGS_ROLES_UPDATE_SETTINGS" | "GUILD_SETTINGS_ROLE_SELECT" | "GUILD_SETTINGS_SAFETY_PAGE" | "GUILD_SETTINGS_SAFETY_SET_SUBSECTION" | "GUILD_SETTINGS_SAVE_ROUTE_STACK" | "GUILD_SETTINGS_SET_MFA_SUCCESS" | "GUILD_SETTINGS_SET_SEARCH_QUERY" | "GUILD_SETTINGS_SET_SECTION" | "GUILD_SETTINGS_SET_VANITY_URL" | "GUILD_SETTINGS_SET_WIDGET" | "GUILD_SETTINGS_SUBMIT" | "GUILD_SETTINGS_SUBMIT_FAILURE" | "GUILD_SETTINGS_SUBMIT_SUCCESS" | "GUILD_SETTINGS_UPDATE" | "GUILD_SETTINGS_VANITY_URL_ERROR" | "GUILD_SETTINGS_VANITY_URL_RESET" | "GUILD_SETTINGS_VANITY_URL_SET" | "GUILD_SETTINGS_WIDGET_UPDATE" | "GUILD_SOUNDBOARD_FETCH" | "GUILD_SOUNDBOARD_SOUNDS_UPDATE" | "GUILD_SOUNDBOARD_SOUND_CREATE" | "GUILD_SOUNDBOARD_SOUND_DELETE" | "GUILD_SOUNDBOARD_SOUND_PLAY_END" | "GUILD_SOUNDBOARD_SOUND_PLAY_LOCALLY" | "GUILD_SOUNDBOARD_SOUND_PLAY_START" | "GUILD_SOUNDBOARD_SOUND_UPDATE" | "GUILD_STICKERS_CREATE_SUCCESS" | "GUILD_STICKERS_FETCH_SUCCESS" | "GUILD_STICKERS_UPDATE" | "GUILD_STOP_LURKING" | "GUILD_STOP_LURKING_FAILURE" | "GUILD_SUBSCRIPTIONS" | "GUILD_SUBSCRIPTIONS_ADD_MEMBER_UPDATES" | "GUILD_SUBSCRIPTIONS_CHANNEL" | "GUILD_SUBSCRIPTIONS_FLUSH" | "GUILD_SUBSCRIPTIONS_MEMBERS_ADD" | "GUILD_SUBSCRIPTIONS_MEMBERS_REMOVE" | "GUILD_SUBSCRIPTIONS_REMOVE_MEMBER_UPDATES" | "GUILD_TAG_CHANGED_COACHMARK_SEEN" | "GUILD_TEMPLATE_ACCEPT" | "GUILD_TEMPLATE_ACCEPT_FAILURE" | "GUILD_TEMPLATE_ACCEPT_SUCCESS" | "GUILD_TEMPLATE_CREATE_SUCCESS" | "GUILD_TEMPLATE_DELETE_SUCCESS" | "GUILD_TEMPLATE_DIRTY_TOOLTIP_HIDE" | "GUILD_TEMPLATE_DIRTY_TOOLTIP_REFRESH" | "GUILD_TEMPLATE_LOAD_FOR_GUILD_SUCCESS" | "GUILD_TEMPLATE_MODAL_HIDE" | "GUILD_TEMPLATE_MODAL_SHOW" | "GUILD_TEMPLATE_PROMOTION_TOOLTIP_HIDE" | "GUILD_TEMPLATE_RESOLVE" | "GUILD_TEMPLATE_RESOLVE_FAILURE" | "GUILD_TEMPLATE_RESOLVE_SUCCESS" | "GUILD_TEMPLATE_SYNC_SUCCESS" | "GUILD_TOGGLE_COLLAPSE_MUTED" | "GUILD_TOP_READ_CHANNELS_FETCH_SUCCESS" | "GUILD_UNAPPLY_BOOST_FAIL" | "GUILD_UNAPPLY_BOOST_START" | "GUILD_UNAPPLY_BOOST_SUCCESS" | "GUILD_UNAVAILABLE" | "GUILD_UNLOCKED_POWERUPS_FETCH_SUCCESS" | "GUILD_UPDATE" | "GUILD_UPDATE_DISCOVERY_METADATA" | "GUILD_UPDATE_DISCOVERY_METADATA_FAIL" | "GUILD_UPDATE_DISCOVERY_METADATA_FROM_SERVER" | "GUILD_VERIFICATION_CHECK" | "HABITUAL_DND_CLEAR" | "HIDE_ACTION_SHEET" | "HIDE_ACTION_SHEET_QUICK_SWITCHER" | "HIDE_KEYBOARD_SHORTCUTS" | "HIGH_FIVE_COMPLETE" | "HIGH_FIVE_COMPLETE_CLEAR" | "HIGH_FIVE_QUEUE" | "HIGH_FIVE_REMOVE" | "HIGH_FIVE_SET_ENABLED" | "HOTSPOT_HIDE" | "HOTSPOT_OVERRIDE_CLEAR" | "HOTSPOT_OVERRIDE_SET" | "HYPESQUAD_ONLINE_MEMBERSHIP_JOIN_SUCCESS" | "HYPESQUAD_ONLINE_MEMBERSHIP_LEAVE_SUCCESS" | "IDLE" | "IMPERSONATE_STOP" | "IMPERSONATE_UPDATE" | "INBOX_OPEN" | "INCOMING_CALL_MOVE" | "INITIALIZE_MEMBER_SAFETY_STORE" | "INITIATE_AGE_VERIFICATION" | "INSTALLATION_LOCATION_ADD" | "INSTALLATION_LOCATION_FETCH_METADATA" | "INSTALLATION_LOCATION_REMOVE" | "INSTALLATION_LOCATION_UPDATE" | "INSTANT_INVITE_CLEAR" | "INSTANT_INVITE_CREATE" | "INSTANT_INVITE_CREATE_FAILURE" | "INSTANT_INVITE_CREATE_SUCCESS" | "INSTANT_INVITE_REVOKE_SUCCESS" | "INTEGRATION_CREATE" | "INTEGRATION_DELETE" | "INTEGRATION_PERMISSION_SETTINGS_APPLICATION_PERMISSIONS_FETCH_FAILURE" | "INTEGRATION_PERMISSION_SETTINGS_CLEAR" | "INTEGRATION_PERMISSION_SETTINGS_COMMANDS_FETCH_FAILURE" | "INTEGRATION_PERMISSION_SETTINGS_COMMANDS_FETCH_SUCCESS" | "INTEGRATION_PERMISSION_SETTINGS_COMMAND_UPDATE" | "INTEGRATION_PERMISSION_SETTINGS_EDIT" | "INTEGRATION_PERMISSION_SETTINGS_INIT" | "INTEGRATION_PERMISSION_SETTINGS_RESET" | "INTEGRATION_QUERY" | "INTEGRATION_QUERY_FAILURE" | "INTEGRATION_QUERY_SUCCESS" | "INTEGRATION_SETTINGS_INIT" | "INTEGRATION_SETTINGS_SAVE_FAILURE" | "INTEGRATION_SETTINGS_SAVE_SUCCESS" | "INTEGRATION_SETTINGS_SET_SECTION" | "INTEGRATION_SETTINGS_START_EDITING_COMMAND" | "INTEGRATION_SETTINGS_START_EDITING_INTEGRATION" | "INTEGRATION_SETTINGS_START_EDITING_WEBHOOK" | "INTEGRATION_SETTINGS_STOP_EDITING_COMMAND" | "INTEGRATION_SETTINGS_STOP_EDITING_INTEGRATION" | "INTEGRATION_SETTINGS_STOP_EDITING_WEBHOOK" | "INTEGRATION_SETTINGS_SUBMITTING" | "INTEGRATION_SETTINGS_UPDATE_INTEGRATION" | "INTEGRATION_SETTINGS_UPDATE_WEBHOOK" | "INTERACTION_CREATE" | "INTERACTION_FAILURE" | "INTERACTION_IFRAME_MODAL_CLOSE" | "INTERACTION_IFRAME_MODAL_CREATE" | "INTERACTION_IFRAME_MODAL_KEY_CREATE" | "INTERACTION_MODAL_CREATE" | "INTERACTION_QUEUE" | "INTERACTION_SUCCESS" | "INVITE_ACCEPT" | "INVITE_ACCEPT_FAILURE" | "INVITE_ACCEPT_SUCCESS" | "INVITE_APP_NOT_OPENED" | "INVITE_APP_OPENED" | "INVITE_APP_OPENING" | "INVITE_MODAL_CLOSE" | "INVITE_MODAL_ERROR" | "INVITE_MODAL_OPEN" | "INVITE_RESOLVE" | "INVITE_RESOLVE_FAILURE" | "INVITE_RESOLVE_SUCCESS" | "INVITE_SUGGESTIONS_SEARCH" | "KEYBINDS_ADD_KEYBIND" | "KEYBINDS_DELETE_KEYBIND" | "KEYBINDS_ENABLE_ALL_KEYBINDS" | "KEYBINDS_REGISTER_GLOBAL_KEYBIND_ACTIONS" | "KEYBINDS_SET_KEYBIND" | "KEYBOARD_NAVIGATION_EXPLAINER_MODAL_SEEN" | "LAB_FEATURE_TOGGLE" | "LAYER_POP" | "LAYER_POP_ALL" | "LAYER_PUSH" | "LAYOUT_CREATE" | "LAYOUT_CREATE_WIDGETS" | "LAYOUT_DELETE_ALL_WIDGETS" | "LAYOUT_DELETE_WIDGET" | "LAYOUT_SET_PINNED" | "LAYOUT_SET_TOP_WIDGET" | "LAYOUT_SET_WIDGET_META" | "LAYOUT_UPDATE_WIDGET" | "LIBRARY_APPLICATIONS_TEST_MODE_ENABLED" | "LIBRARY_APPLICATION_ACTIVE_BRANCH_UPDATE" | "LIBRARY_APPLICATION_ACTIVE_LAUNCH_OPTION_UPDATE" | "LIBRARY_APPLICATION_FILTER_UPDATE" | "LIBRARY_APPLICATION_FLAGS_UPDATE_START" | "LIBRARY_APPLICATION_FLAGS_UPDATE_SUCCESS" | "LIBRARY_APPLICATION_UPDATE" | "LIBRARY_FETCH_SUCCESS" | "LIBRARY_TABLE_ACTIVE_ROW_ID_UPDATE" | "LIBRARY_TABLE_SORT_UPDATE" | "LIVE_CHANNEL_NOTICE_HIDE" | "LOAD_ARCHIVED_THREADS" | "LOAD_ARCHIVED_THREADS_FAIL" | "LOAD_ARCHIVED_THREADS_SUCCESS" | "LOAD_CHANNELS" | "LOAD_DATA_HARVEST_TYPE_FAILURE" | "LOAD_DATA_HARVEST_TYPE_START" | "LOAD_FORUM_POSTS" | "LOAD_FRIEND_SUGGESTIONS_FAILURE" | "LOAD_FRIEND_SUGGESTIONS_SUCCESS" | "LOAD_GUILD_AFFINITIES_SUCCESS" | "LOAD_ICYMI_HYDRATED" | "LOAD_INVITE_SUGGESTIONS" | "LOAD_MESSAGES" | "LOAD_MESSAGES_AROUND_SUCCESS" | "LOAD_MESSAGES_FAILURE" | "LOAD_MESSAGES_SUCCESS" | "LOAD_MESSAGES_SUCCESS_CACHED" | "LOAD_MESSAGE_INTERACTION_DATA_SUCCESS" | "LOAD_MESSAGE_REQUESTS_SUPPLEMENTAL_DATA_ERROR" | "LOAD_MESSAGE_REQUESTS_SUPPLEMENTAL_DATA_SUCCESS" | "LOAD_NOTIFICATION_CENTER_ITEMS" | "LOAD_NOTIFICATION_CENTER_ITEMS_FAILURE" | "LOAD_NOTIFICATION_CENTER_ITEMS_SUCCESS" | "LOAD_PINNED_MESSAGES" | "LOAD_PINNED_MESSAGES_FAILURE" | "LOAD_PINNED_MESSAGES_SUCCESS" | "LOAD_RECENT_MENTIONS" | "LOAD_RECENT_MENTIONS_FAILURE" | "LOAD_RECENT_MENTIONS_SUCCESS" | "LOAD_REGIONS" | "LOAD_RELATIONSHIPS_FAILURE" | "LOAD_RELATIONSHIPS_SUCCESS" | "LOAD_THREADS_SUCCESS" | "LOAD_USER_AFFINITIES_V2" | "LOAD_USER_AFFINITIES_V2_FAILURE" | "LOAD_USER_AFFINITIES_V2_SUCCESS" | "LOCAL_ACTIVITY_UPDATE" | "LOCAL_MESSAGES_LOADED" | "LOCAL_MESSAGE_CREATE" | "LOGIN" | "LOGIN_ACCOUNT_DISABLED" | "LOGIN_ACCOUNT_SCHEDULED_FOR_DELETION" | "LOGIN_ATTEMPTED" | "LOGIN_FAILURE" | "LOGIN_MFA" | "LOGIN_MFA_STEP" | "LOGIN_PASSWORD_RECOVERY_PHONE_VERIFICATION" | "LOGIN_PHONE_IP_AUTHORIZATION_REQUIRED" | "LOGIN_RESET" | "LOGIN_STATUS_RESET" | "LOGIN_SUCCESS" | "LOGIN_SUSPENDED_USER" | "LOGOUT" | "LOGOUT_AUTH_SESSIONS_SUCCESS" | "MASKED_LINK_ADD_TRUSTED_DOMAIN" | "MASKED_LINK_ADD_TRUSTED_PROTOCOL" | "MAX_MEMBER_COUNT_NOTICE_DISMISS" | "MEDIA_ENGINE_APPLY_MEDIA_FILTER_SETTINGS" | "MEDIA_ENGINE_APPLY_MEDIA_FILTER_SETTINGS_ERROR" | "MEDIA_ENGINE_APPLY_MEDIA_FILTER_SETTINGS_START" | "MEDIA_ENGINE_CONNECTION_STATS" | "MEDIA_ENGINE_CONNECTION_STATS_HISTORY_RESET" | "MEDIA_ENGINE_DEVICES" | "MEDIA_ENGINE_INTERACTION_REQUIRED" | "MEDIA_ENGINE_NOISE_CANCELLATION_ERROR" | "MEDIA_ENGINE_NOISE_CANCELLATION_ERROR_RESET" | "MEDIA_ENGINE_PERMISSION" | "MEDIA_ENGINE_SET_AEC_DUMP" | "MEDIA_ENGINE_SET_AUDIO_ENABLED" | "MEDIA_ENGINE_SET_ENABLE_HARDWARE_MUTE_NOTICE" | "MEDIA_ENGINE_SET_EXPERIMENTAL_ENCODERS" | "MEDIA_ENGINE_SET_EXPERIMENTAL_SOUNDSHARE" | "MEDIA_ENGINE_SET_GO_LIVE_SOURCE" | "MEDIA_ENGINE_SET_HARDWARE_ENCODING" | "MEDIA_ENGINE_SET_OPEN_H264" | "MEDIA_ENGINE_SET_USE_SYSTEM_SCREENSHARE_PICKER" | "MEDIA_ENGINE_SET_VIDEO_DEVICE" | "MEDIA_ENGINE_SET_VIDEO_ENABLED" | "MEDIA_ENGINE_SET_VIDEO_HOOK" | "MEDIA_ENGINE_SOUNDSHARE_FAILED" | "MEDIA_ENGINE_SOUNDSHARE_TRANSMITTING" | "MEDIA_ENGINE_VIDEO_SOURCE_QUALITY_CHANGED" | "MEDIA_ENGINE_VIDEO_STATE_CHANGED" | "MEDIA_ENGINE_VOICE_ACTIVITY_DETECTION_ERROR" | "MEDIA_PLAYBACK_POSITION_UPDATE" | "MEDIA_PLAYBACK_RATE_UPDATE" | "MEDIA_POST_EMBED_FETCH" | "MEDIA_POST_EMBED_FETCH_FAILURE" | "MEDIA_POST_EMBED_FETCH_SUCCESS" | "MEDIA_SESSION_JOINED" | "MEMBER_SAFETY_GUILD_MEMBER_SEARCH_SUCCESS" | "MEMBER_SAFETY_GUILD_MEMBER_UPDATE_BATCH" | "MEMBER_SAFETY_NEW_MEMBER_TIMESTAMP_REFRESH" | "MEMBER_SAFETY_PAGINATION_TOKEN_UPDATE" | "MEMBER_SAFETY_PAGINATION_UPDATE" | "MEMBER_SAFETY_SEARCH_STATE_UPDATE" | "MEMBER_VERIFICATION_FORM_FETCH_FAIL" | "MEMBER_VERIFICATION_FORM_UPDATE" | "MESSAGE_ACK" | "MESSAGE_ACKED" | "MESSAGE_CREATE" | "MESSAGE_DELETE" | "MESSAGE_DELETE_BULK" | "MESSAGE_EDIT_FAILED_AUTOMOD" | "MESSAGE_END_EDIT" | "MESSAGE_EXPLICIT_CONTENT_FP_CREATE" | "MESSAGE_EXPLICIT_CONTENT_FP_SUBMIT" | "MESSAGE_EXPLICIT_CONTENT_SCAN_TIMEOUT" | "MESSAGE_GIFT_INTENT_SHOWN" | "MESSAGE_LENGTH_UPSELL" | "MESSAGE_NOTIFICATION_SHOWN" | "MESSAGE_PREVIEWS_LOADED" | "MESSAGE_PREVIEWS_LOCALLY_LOADED" | "MESSAGE_REACTION_ADD" | "MESSAGE_REACTION_ADD_MANY" | "MESSAGE_REACTION_ADD_USERS" | "MESSAGE_REACTION_REMOVE" | "MESSAGE_REACTION_REMOVE_ALL" | "MESSAGE_REACTION_REMOVE_EMOJI" | "MESSAGE_REMINDER_DUE" | "MESSAGE_REQUEST_ACCEPT_OPTIMISTIC" | "MESSAGE_REQUEST_ACK" | "MESSAGE_REQUEST_CLEAR_ACK" | "MESSAGE_REVEAL" | "MESSAGE_SEND_FAILED" | "MESSAGE_SEND_FAILED_AUTOMOD" | "MESSAGE_START_EDIT" | "MESSAGE_UPDATE" | "MESSAGE_UPDATE_EDIT" | "MFA_CLEAR_BACKUP_CODES" | "MFA_DISABLE_SUCCESS" | "MFA_ENABLE_SUCCESS" | "MFA_SEEN_BACKUP_CODE_PROMPT" | "MFA_SEND_VERIFICATION_KEY" | "MFA_SMS_TOGGLE" | "MFA_SMS_TOGGLE_COMPLETE" | "MFA_VIEW_BACKUP_CODES" | "MFA_WEBAUTHN_CREDENTIALS_LOADED" | "MOBILE_NATIVE_UPDATE_CHECK_FINISHED" | "MOBILE_WEB_SIDEBAR_CLOSE" | "MOBILE_WEB_SIDEBAR_OPEN" | "MODAL_POP" | "MODAL_PUSH" | "MOD_VIEW_SEARCH_FINISH" | "MULTI_ACCOUNT_INVALIDATE_PUSH_SYNC_TOKENS" | "MULTI_ACCOUNT_MOBILE_EXPERIMENT_UPDATE" | "MULTI_ACCOUNT_MOVE_ACCOUNT" | "MULTI_ACCOUNT_REMOVE_ACCOUNT" | "MULTI_ACCOUNT_UPDATE_PUSH_SYNC_TOKEN" | "MULTI_ACCOUNT_VALIDATE_TOKEN_FAILURE" | "MULTI_ACCOUNT_VALIDATE_TOKEN_REQUEST" | "MULTI_ACCOUNT_VALIDATE_TOKEN_SUCCESS" | "MUTUAL_FRIENDS_FETCH_FAILURE" | "MUTUAL_FRIENDS_FETCH_START" | "MUTUAL_FRIENDS_FETCH_SUCCESS" | "NATIVE_APP_MODAL_OPENED" | "NATIVE_APP_MODAL_OPENING" | "NATIVE_APP_MODAL_OPEN_FAILED" | "NATIVE_SCREEN_SHARE_PICKER_CANCEL" | "NATIVE_SCREEN_SHARE_PICKER_ERROR" | "NATIVE_SCREEN_SHARE_PICKER_PRESENT" | "NATIVE_SCREEN_SHARE_PICKER_RELEASE" | "NATIVE_SCREEN_SHARE_PICKER_UPDATE" | "NEWLY_ADDED_EMOJI_SEEN_ACKNOWLEDGED" | "NEWLY_ADDED_EMOJI_SEEN_PENDING" | "NEWLY_ADDED_EMOJI_SEEN_UPDATED" | "NEW_PAYMENT_SOURCE_ADDRESS_INFO_UPDATE" | "NEW_PAYMENT_SOURCE_CARD_INFO_UPDATE" | "NEW_PAYMENT_SOURCE_CLEAR_ERROR" | "NEW_PAYMENT_SOURCE_STRIPE_PAYMENT_REQUEST_UPDATE" | "NOTICE_DISABLE" | "NOTICE_DISMISS" | "NOTICE_SHOW" | "NOTIFICATIONS_SET_DESKTOP_TYPE" | "NOTIFICATIONS_SET_DISABLED_SOUNDS" | "NOTIFICATIONS_SET_DISABLE_UNREAD_BADGE" | "NOTIFICATIONS_SET_NOTIFY_MESSAGES_IN_SELECTED_CHANNEL" | "NOTIFICATIONS_SET_PERMISSION_STATE" | "NOTIFICATIONS_SET_TASKBAR_FLASH" | "NOTIFICATIONS_SET_TTS_TYPE" | "NOTIFICATIONS_TOGGLE_ALL_DISABLED" | "NOTIFICATION_CENTER_CLEAR_GUILD_MENTIONS" | "NOTIFICATION_CENTER_ITEMS_ACK" | "NOTIFICATION_CENTER_ITEMS_ACK_FAILURE" | "NOTIFICATION_CENTER_ITEMS_LOCAL_ACK" | "NOTIFICATION_CENTER_ITEM_COMPLETED" | "NOTIFICATION_CENTER_ITEM_CREATE" | "NOTIFICATION_CENTER_ITEM_DELETE" | "NOTIFICATION_CENTER_ITEM_DELETE_FAILURE" | "NOTIFICATION_CENTER_REFRESH" | "NOTIFICATION_CENTER_SET_ACTIVE" | "NOTIFICATION_CENTER_SET_TAB" | "NOTIFICATION_CENTER_TAB_FOCUSED" | "NOTIFICATION_CLICK" | "NOTIFICATION_CREATE" | "NOTIFICATION_SETTINGS_UPDATE" | "NOW_PLAYING_MOUNTED" | "NOW_PLAYING_UNMOUNTED" | "NUF_COMPLETE" | "NUF_NEW_USER" | "OAUTH2_TOKEN_REVOKE" | "ONLINE_GUILD_MEMBER_COUNT_UPDATE" | "OUTBOUND_PROMOTIONS_SEEN" | "OUTBOUND_PROMOTION_NOTICE_DISMISS" | "OVERLAY_ACTIVATE_REGION" | "OVERLAY_CALL_PRIVATE_CHANNEL" | "OVERLAY_CRASHED" | "OVERLAY_DEACTIVATE_ALL_REGIONS" | "OVERLAY_DISABLE_EXTERNAL_LINK_ALERT" | "OVERLAY_FOCUSED" | "OVERLAY_FORCE_RENDER_MODE" | "OVERLAY_INCOMPATIBLE_APP" | "OVERLAY_INITIALIZE" | "OVERLAY_JOIN_GAME" | "OVERLAY_MESSAGE_EVENT_ACTION" | "OVERLAY_NOTIFICATION_EVENT" | "OVERLAY_READY" | "OVERLAY_RELOAD" | "OVERLAY_RENDER_DEBUG_CLEAR_TRACKED_PIDS" | "OVERLAY_RENDER_DEBUG_MODE" | "OVERLAY_SELECT_CALL" | "OVERLAY_SELECT_CHANNEL" | "OVERLAY_SET_ASSOCIATED_GAME" | "OVERLAY_SET_AVATAR_SIZE_MODE" | "OVERLAY_SET_CLICK_ZONES" | "OVERLAY_SET_DISABLE_CLICKABLE_REGIONS" | "OVERLAY_SET_DISPLAY_NAME_MODE" | "OVERLAY_SET_DISPLAY_USER_MODE" | "OVERLAY_SET_ENABLED" | "OVERLAY_SET_GAME_INVITE_NOTIFICATION" | "OVERLAY_SET_GPU_BOOST_REQUESTED" | "OVERLAY_SET_INPUT_LOCKED" | "OVERLAY_SET_INVITE_MESSAGE" | "OVERLAY_SET_LIMITED_INTERACTION_OVERRIDE" | "OVERLAY_SET_NOTIFICATION_DISABLED_SETTING" | "OVERLAY_SET_NOTIFICATION_POSITION_MODE" | "OVERLAY_SET_NOT_IDLE" | "OVERLAY_SET_PREVIEW_IN_GAME_MODE" | "OVERLAY_SET_SHOW_KEYBIND_INDICATORS" | "OVERLAY_SET_TEXT_WIDGET_OPACITY" | "OVERLAY_SOUNDBOARD_SOUNDS_FETCH_REQUEST" | "OVERLAY_START_SESSION" | "OVERLAY_SUCCESSFULLY_SHOWN" | "OVERLAY_UPDATE_OVERLAY_METHOD" | "OVERLAY_UPDATE_OVERLAY_STATE" | "OVERLAY_WIDGET_CHANGED" | "PASSIVE_UPDATE_V2" | "PASSWORDLESS_FAILURE" | "PASSWORDLESS_START" | "PASSWORD_UPDATED" | "PAYMENT_AUTHENTICATION_CLEAR_ERROR" | "PAYMENT_AUTHENTICATION_ERROR" | "PAYMENT_UPDATE" | "PERMISSION_CLEAR_ELEVATED_PROCESS" | "PERMISSION_CLEAR_PTT_ADMIN_WARNING" | "PERMISSION_CLEAR_SUPPRESS_WARNING" | "PERMISSION_CLEAR_VAD_WARNING" | "PERMISSION_CONTINUE_NONELEVATED_PROCESS" | "PERMISSION_REQUEST_ELEVATED_PROCESS" | "PHONE_SET_COUNTRY_CODE" | "PICTURE_IN_PICTURE_CLOSE" | "PICTURE_IN_PICTURE_HIDE" | "PICTURE_IN_PICTURE_MOVE" | "PICTURE_IN_PICTURE_OPEN" | "PICTURE_IN_PICTURE_RESIZE" | "PICTURE_IN_PICTURE_SHOW" | "PICTURE_IN_PICTURE_UPDATE_RECT" | "PICTURE_IN_PICTURE_UPDATE_SELECTED_WINDOW" | "POGGERMODE_ACHIEVEMENT_UNLOCK" | "POGGERMODE_SETTINGS_UPDATE" | "POGGERMODE_TEMPORARILY_DISABLED" | "POGGERMODE_UPDATE_COMBO" | "POGGERMODE_UPDATE_MESSAGE_COMBO" | "POPOUT_WINDOW_ADD_STYLESHEET" | "POPOUT_WINDOW_CLOSE" | "POPOUT_WINDOW_OPEN" | "POPOUT_WINDOW_SET_ALWAYS_ON_TOP" | "POST_CONNECTION_OPEN" | "POTIONS_SET_CONFETTI_MODE" | "POTIONS_TRIGGER_MESSAGE_CONFETTI" | "PREMIUM_MARKETING_DATA_READY" | "PREMIUM_MARKETING_PREVIEW" | "PREMIUM_PAYMENT_ERROR_CLEAR" | "PREMIUM_PAYMENT_MODAL_CLOSE" | "PREMIUM_PAYMENT_MODAL_OPEN" | "PREMIUM_PAYMENT_SUBSCRIBE_FAIL" | "PREMIUM_PAYMENT_SUBSCRIBE_START" | "PREMIUM_PAYMENT_SUBSCRIBE_SUCCESS" | "PREMIUM_PAYMENT_UPDATE_FAIL" | "PREMIUM_PAYMENT_UPDATE_SUCCESS" | "PREMIUM_REQUIRED_MODAL_CLOSE" | "PREMIUM_REQUIRED_MODAL_OPEN" | "PRESENCES_REPLACE" | "PRESENCE_SUBSCRIPTIONS_ADD" | "PRESENCE_UPDATES" | "PRIVATE_CHANNEL_RECIPIENTS_ADD_USER" | "PRIVATE_CHANNEL_RECIPIENTS_INVITE_CLOSE" | "PRIVATE_CHANNEL_RECIPIENTS_INVITE_OPEN" | "PRIVATE_CHANNEL_RECIPIENTS_INVITE_QUERY" | "PRIVATE_CHANNEL_RECIPIENTS_INVITE_SELECT" | "PRIVATE_CHANNEL_RECIPIENTS_REMOVE_USER" | "PROFILE_CUSTOMIZATION_OPEN_PREVIEW_MODAL" | "PROFILE_EFFECTS_SET_TRY_IT_OUT" | "PROXY_BLOCKED_REQUEST" | "PUBLIC_UPSELL_NOTICE_DISMISS" | "PURCHASED_ITEMS_FESTIVITY_FETCH_WOW_MOMENT_MEDIA_FAILURE" | "PURCHASED_ITEMS_FESTIVITY_FETCH_WOW_MOMENT_MEDIA_SUCCESS" | "PURCHASED_ITEMS_FESTIVITY_IS_FETCHING_WOW_MOMENT_MEDIA" | "PURCHASED_ITEMS_FESTIVITY_SET_CAN_PLAY_WOW_MOMENT" | "PUSH_NOTIFICATION_CLICK" | "QUESTS_CLAIM_REWARD_BEGIN" | "QUESTS_CLAIM_REWARD_FAILURE" | "QUESTS_CLAIM_REWARD_SUCCESS" | "QUESTS_DELIVERY_OVERRIDE" | "QUESTS_DISMISS_CONTENT_BEGIN" | "QUESTS_DISMISS_CONTENT_FAILURE" | "QUESTS_DISMISS_CONTENT_SUCCESS" | "QUESTS_DISMISS_PROGRESS_TRACKING_FAILURE_NOTICE" | "QUESTS_ENROLL_BEGIN" | "QUESTS_ENROLL_FAILURE" | "QUESTS_ENROLL_SUCCESS" | "QUESTS_FETCH_CLAIMED_QUESTS_BEGIN" | "QUESTS_FETCH_CLAIMED_QUESTS_FAILURE" | "QUESTS_FETCH_CLAIMED_QUESTS_SUCCESS" | "QUESTS_FETCH_CURRENT_QUESTS_BEGIN" | "QUESTS_FETCH_CURRENT_QUESTS_FAILURE" | "QUESTS_FETCH_CURRENT_QUESTS_SUCCESS" | "QUESTS_FETCH_QUEST_TO_DELIVER_BEGIN" | "QUESTS_FETCH_QUEST_TO_DELIVER_FAILURE" | "QUESTS_FETCH_QUEST_TO_DELIVER_SUCCESS" | "QUESTS_FETCH_REWARD_CODE_BEGIN" | "QUESTS_FETCH_REWARD_CODE_FAILURE" | "QUESTS_FETCH_REWARD_CODE_SUCCESS" | "QUESTS_PREVIEW_UPDATE_SUCCESS" | "QUESTS_SELECT_TASK_PLATFORM" | "QUESTS_SEND_HEARTBEAT_FAILURE" | "QUESTS_SEND_HEARTBEAT_SUCCESS" | "QUESTS_UPDATE_OPTIMISTIC_PROGRESS" | "QUESTS_USER_COMPLETION_UPDATE" | "QUESTS_USER_STATUS_UPDATE" | "QUEUE_INTERACTION_COMPONENT_STATE" | "QUICKSWITCHER_HIDE" | "QUICKSWITCHER_SEARCH" | "QUICKSWITCHER_SELECT" | "QUICKSWITCHER_SHOW" | "QUICKSWITCHER_SWITCH_TO" | "RECEIVE_CHANNEL_AFFINITIES" | "RECEIVE_CHANNEL_SUMMARIES" | "RECEIVE_CHANNEL_SUMMARIES_BULK" | "RECEIVE_CHANNEL_SUMMARY" | "RECENT_MENTION_DELETE" | "RECOMPUTE_READ_STATES" | "REFERRALS_FETCH_ELIGIBLE_USER_FAIL" | "REFERRALS_FETCH_ELIGIBLE_USER_START" | "REFERRALS_FETCH_ELIGIBLE_USER_SUCCESS" | "REGISTER" | "REGISTER_SUCCESS" | "RELATIONSHIP_ADD" | "RELATIONSHIP_IGNORE_USER_SUCCESS" | "RELATIONSHIP_PENDING_INCOMING_REMOVED" | "RELATIONSHIP_REMOVE" | "RELATIONSHIP_UPDATE" | "REMOTE_COMMAND" | "REMOTE_SESSION_CONNECT" | "REMOTE_SESSION_DISCONNECT" | "REMOVE_AUTOMOD_MESSAGE_NOTICE" | "REPORT_AV_ERROR" | "REPORT_TO_MOD_REPORT_MESSAGE_SUCCESS" | "REQUEST_CHANNEL_AFFINITIES" | "REQUEST_CHANNEL_SUMMARIES" | "REQUEST_CHANNEL_SUMMARIES_BULK" | "REQUEST_CHANNEL_SUMMARY" | "REQUEST_FORUM_UNREADS" | "REQUEST_SOUNDBOARD_SOUNDS" | "RESET_NOTIFICATION_CENTER" | "RESET_PAYMENT_ID" | "RESET_PREVIEW_CLIENT_THEME" | "RESET_SOCKET" | "RESORT_THREADS" | "RPC_APP_AUTHENTICATED" | "RPC_APP_CONNECTED" | "RPC_APP_DISCONNECTED" | "RPC_NOTIFICATION_CREATE" | "RPC_SERVER_READY" | "RTC_CONNECTION_CLIENT_CONNECT" | "RTC_CONNECTION_CLIENT_DISCONNECT" | "RTC_CONNECTION_FLAGS" | "RTC_CONNECTION_LOSS_RATE" | "RTC_CONNECTION_PING" | "RTC_CONNECTION_PLATFORM" | "RTC_CONNECTION_REMOTE_VIDEO_SINK_WANTS" | "RTC_CONNECTION_ROSTER_MAP_UPDATE" | "RTC_CONNECTION_SECURE_FRAMES_UPDATE" | "RTC_CONNECTION_STATE" | "RTC_CONNECTION_UPDATE_ID" | "RTC_CONNECTION_USERS_MERGED" | "RTC_CONNECTION_VIDEO" | "RTC_DEBUG_MODAL_CLOSE" | "RTC_DEBUG_MODAL_OPEN" | "RTC_DEBUG_MODAL_OPEN_REPLAY" | "RTC_DEBUG_MODAL_OPEN_REPLAY_AT_PATH" | "RTC_DEBUG_MODAL_SET_SECTION" | "RTC_DEBUG_MODAL_UPDATE_VIDEO_OUTPUT" | "RTC_DEBUG_POPOUT_WINDOW_OPEN" | "RTC_DEBUG_SET_RECORDING_FLAG" | "RTC_DEBUG_SET_SIMULCAST_OVERRIDE" | "RTC_LATENCY_TEST_COMPLETE" | "RUNNING_GAMES_CHANGE" | "RUNNING_GAME_ADD_OVERRIDE" | "RUNNING_GAME_DELETE_ENTRY" | "RUNNING_GAME_EDIT_NAME" | "RUNNING_GAME_TOGGLE_DETECTION" | "RUNNING_GAME_TOGGLE_OVERLAY" | "RUNNING_STREAMER_TOOLS_CHANGE" | "SAFETY_HUB_APPEAL_CLOSE" | "SAFETY_HUB_APPEAL_OPEN" | "SAFETY_HUB_APPEAL_SIGNAL_CUSTOM_INPUT_CHANGE" | "SAFETY_HUB_APPEAL_SIGNAL_SELECT" | "SAFETY_HUB_AUTOMATED_UNDERAGE_APPEAL_MODAL_CLOSE" | "SAFETY_HUB_AUTOMATED_UNDERAGE_APPEAL_MODAL_OPEN" | "SAFETY_HUB_AUTOMATED_UNDERAGE_APPEAL_START_POLL" | "SAFETY_HUB_AUTOMATED_UNDERAGE_APPEAL_SUBMIT_SUCCESS" | "SAFETY_HUB_CHECK_AUTOMATED_UNDERAGE_APPEAL_FAILURE" | "SAFETY_HUB_CHECK_AUTOMATED_UNDERAGE_APPEAL_START" | "SAFETY_HUB_CHECK_AUTOMATED_UNDERAGE_APPEAL_SUCCESS" | "SAFETY_HUB_FETCH_CLASSIFICATION_FAILURE" | "SAFETY_HUB_FETCH_CLASSIFICATION_START" | "SAFETY_HUB_FETCH_CLASSIFICATION_SUCCESS" | "SAFETY_HUB_FETCH_FAILURE" | "SAFETY_HUB_FETCH_START" | "SAFETY_HUB_FETCH_SUCCESS" | "SAFETY_HUB_REQUEST_AUTOMATED_UNDERAGE_APPEAL_FAILURE" | "SAFETY_HUB_REQUEST_AUTOMATED_UNDERAGE_APPEAL_START" | "SAFETY_HUB_REQUEST_AUTOMATED_UNDERAGE_APPEAL_SUCCESS" | "SAFETY_HUB_REQUEST_REVIEW_FAILURE" | "SAFETY_HUB_REQUEST_REVIEW_START" | "SAFETY_HUB_REQUEST_REVIEW_SUCCESS" | "SAVED_MESSAGES_UPDATE" | "SAVED_MESSAGE_CREATE" | "SAVED_MESSAGE_DELETE" | "SAVE_LAST_NON_VOICE_ROUTE" | "SAVE_LAST_ROUTE" | "SCHEDULED_MESSAGES_CREATE_SUCCESS" | "SCHEDULED_MESSAGES_DELETE_FAILURE" | "SCHEDULED_MESSAGES_DELETE_START" | "SCHEDULED_MESSAGES_DELETE_SUCCESS" | "SEARCH_ADD_HISTORY" | "SEARCH_AUTOCOMPLETE_QUERY_UPDATE" | "SEARCH_CLEAR_HISTORY" | "SEARCH_EDITOR_STATE_CHANGE" | "SEARCH_EDITOR_STATE_CLEAR" | "SEARCH_ENSURE_SEARCH_STATE" | "SEARCH_FINISH" | "SEARCH_INDEXING" | "SEARCH_MESSAGES_CLEAR_ALL" | "SEARCH_MESSAGES_FAILURE" | "SEARCH_MESSAGES_INDEXING" | "SEARCH_MESSAGES_START" | "SEARCH_MESSAGES_SUCCESS" | "SEARCH_RECENT_MESSAGES_CLEAR" | "SEARCH_REMOVE_HISTORY" | "SEARCH_RESULTS_QUERY_UPDATE" | "SEARCH_SCREEN_OPEN" | "SEARCH_SET_SHOW_BLOCKED_RESULTS" | "SEARCH_SET_SHOW_NO_RESULTS_ALT" | "SEARCH_START" | "SECURE_FRAMES_SETTINGS_UPDATE" | "SECURE_FRAMES_TRANSIENT_KEY_CREATE" | "SECURE_FRAMES_TRANSIENT_KEY_DELETE" | "SECURE_FRAMES_UPLOADED_KEY_VERSION_ADD" | "SECURE_FRAMES_UPLOADED_KEY_VERSION_CLEAR" | "SECURE_FRAMES_USER_VERIFIED_KEYS_DELETE" | "SECURE_FRAMES_VERIFIED_KEY_CREATE" | "SECURE_FRAMES_VERIFIED_KEY_DELETE" | "SELECTIVELY_SYNCED_USER_SETTINGS_UPDATE" | "SELECT_HOME_RESOURCE_CHANNEL" | "SELECT_NEW_MEMBER_ACTION_CHANNEL" | "SELF_PRESENCE_STORE_UPDATE" | "SESSIONS_REPLACE" | "SET_CHANNEL_BITRATE" | "SET_CHANNEL_VIDEO_QUALITY_MODE" | "SET_CONSENT_REQUIRED" | "SET_CREATED_AT_OVERRIDE" | "SET_GUILD_FOLDER_EXPANDED" | "SET_GUILD_LEADERBOARD" | "SET_HIGHLIGHTED_SUMMARY" | "SET_INTERACTION_COMPONENT_STATE" | "SET_LOCATION_METADATA" | "SET_NATIVE_PERMISSION" | "SET_PENDING_REPLY_SHOULD_MENTION" | "SET_PREMIUM_TYPE_OVERRIDE" | "SET_PREVIOUS_GO_LIVE_SETTINGS" | "SET_RECENTLY_ACTIVE_COLLAPSED" | "SET_RECENT_MENTIONS_FILTER" | "SET_RECENT_MENTIONS_STALE" | "SET_RPC_NOTIFICATION_SETTINGS" | "SET_SELECTED_SUMMARY" | "SET_SOUNDPACK" | "SET_STREAM_APP_INTENT" | "SET_SUMMARY_FEEDBACK" | "SET_THEME_OVERRIDE" | "SET_TTS_SPEECH_RATE" | "SET_USER_LEADERBOARD_LAST_UPDATE_REQUESTED" | "SET_VAD_PERMISSION" | "SHARED_CANVAS_CLEAR_DRAWABLES" | "SHARED_CANVAS_DRAW_LINE_POINT" | "SHARED_CANVAS_SET_DRAW_MODE" | "SHARED_CANVAS_UPDATE_EMOJI_HOSE" | "SHARED_CANVAS_UPDATE_LINE_POINTS" | "SHOW_ACTION_SHEET" | "SHOW_ACTION_SHEET_QUICK_SWITCHER" | "SHOW_KEYBOARD_SHORTCUTS" | "SIDEBAR_CLOSE" | "SIDEBAR_CLOSE_GUILD" | "SIDEBAR_CREATE_THREAD" | "SIDEBAR_VIEW_CHANNEL" | "SIDEBAR_VIEW_GUILD" | "SKUS_FETCH_SUCCESS" | "SKU_FETCH_FAIL" | "SKU_FETCH_START" | "SKU_FETCH_SUCCESS" | "SKU_PURCHASE_AWAIT_CONFIRMATION" | "SKU_PURCHASE_CLEAR_ERROR" | "SKU_PURCHASE_FAIL" | "SKU_PURCHASE_MODAL_CLOSE" | "SKU_PURCHASE_MODAL_OPEN" | "SKU_PURCHASE_PREVIEW_FETCH" | "SKU_PURCHASE_PREVIEW_FETCH_FAILURE" | "SKU_PURCHASE_PREVIEW_FETCH_SUCCESS" | "SKU_PURCHASE_SHOW_CONFIRMATION_STEP" | "SKU_PURCHASE_START" | "SKU_PURCHASE_SUCCESS" | "SKU_PURCHASE_UPDATE_IS_GIFT" | "SLOWMODE_RESET_COOLDOWN" | "SLOWMODE_SET_COOLDOWN" | "SOUNDBOARD_FETCH_DEFAULT_SOUNDS" | "SOUNDBOARD_FETCH_DEFAULT_SOUNDS_SUCCESS" | "SOUNDBOARD_MUTE_JOIN_SOUND" | "SOUNDBOARD_SET_OVERLAY_ENABLED" | "SOUNDBOARD_SOUNDS_RECEIVED" | "SPEAKING" | "SPEAKING_MESSAGE" | "SPEAK_MESSAGE" | "SPEAK_TEXT" | "SPELLCHECK_LEARN_WORD" | "SPELLCHECK_TOGGLE" | "SPELLCHECK_UNLEARN_WORD" | "SPOTIFY_ACCOUNT_ACCESS_TOKEN" | "SPOTIFY_ACCOUNT_ACCESS_TOKEN_REVOKE" | "SPOTIFY_NEW_TRACK" | "SPOTIFY_PLAYER_PAUSE" | "SPOTIFY_PLAYER_PLAY" | "SPOTIFY_PLAYER_STATE" | "SPOTIFY_PROFILE_UPDATE" | "SPOTIFY_SET_ACTIVE_DEVICE" | "SPOTIFY_SET_DEVICES" | "SPOTIFY_SET_PROTOCOL_REGISTERED" | "STAGE_INSTANCE_CREATE" | "STAGE_INSTANCE_DELETE" | "STAGE_INSTANCE_UPDATE" | "STAGE_MUSIC_MUTE" | "STAGE_MUSIC_PLAY" | "START_SESSION" | "STATUS_PAGE_INCIDENT" | "STATUS_PAGE_SCHEDULED_MAINTENANCE" | "STATUS_PAGE_SCHEDULED_MAINTENANCE_ACK" | "STICKER_FETCH_SUCCESS" | "STICKER_PACKS_FETCH_START" | "STICKER_PACKS_FETCH_SUCCESS" | "STICKER_PACK_FETCH_SUCCESS" | "STICKER_TRACK_USAGE" | "STOP_SPEAKING" | "STORE_LISTINGS_FETCH_FAIL" | "STORE_LISTINGS_FETCH_START" | "STORE_LISTINGS_FETCH_SUCCESS" | "STORE_LISTING_FETCH_SUCCESS" | "STREAMER_MODE_UPDATE" | "STREAMING_UPDATE" | "STREAM_CLOSE" | "STREAM_CREATE" | "STREAM_DELETE" | "STREAM_LAYOUT_UPDATE" | "STREAM_PREVIEW_FETCH_FAIL" | "STREAM_PREVIEW_FETCH_START" | "STREAM_PREVIEW_FETCH_SUCCESS" | "STREAM_SERVER_UPDATE" | "STREAM_SET_PAUSED" | "STREAM_START" | "STREAM_STOP" | "STREAM_TIMED_OUT" | "STREAM_UPDATE" | "STREAM_UPDATE_SELF_HIDDEN" | "STREAM_UPDATE_SETTINGS" | "STREAM_WATCH" | "STRIPE_TOKEN_FAILURE" | "SUBSCRIPTION_PLANS_FETCH" | "SUBSCRIPTION_PLANS_FETCH_FAILURE" | "SUBSCRIPTION_PLANS_FETCH_SUCCESS" | "SUBSCRIPTION_PLANS_RESET" | "SURVEY_FETCHED" | "SURVEY_HIDE" | "SURVEY_OVERRIDE" | "SURVEY_SEEN" | "SYSTEM_THEME_CHANGE" | "THERMAL_STATE_CHANGE" | "THREAD_CREATE" | "THREAD_CREATE_LOCAL" | "THREAD_DELETE" | "THREAD_LIST_SYNC" | "THREAD_MEMBERS_UPDATE" | "THREAD_MEMBER_LIST_UPDATE" | "THREAD_MEMBER_LOCAL_UPDATE" | "THREAD_MEMBER_UPDATE" | "THREAD_SETTINGS_DRAFT_CHANGE" | "THREAD_UPDATE" | "TOGGLE_GUILD_EXPANDED_STATE" | "TOGGLE_GUILD_FOLDER_EXPAND" | "TOGGLE_OVERLAY_CANVAS" | "TOGGLE_TOPICS_BAR" | "TOP_EMOJIS_FETCH" | "TOP_EMOJIS_FETCH_SUCCESS" | "TRUNCATE_MENTIONS" | "TRUNCATE_MESSAGES" | "TRY_ACK" | "TUTORIAL_INDICATOR_DISMISS" | "TUTORIAL_INDICATOR_HIDE" | "TUTORIAL_INDICATOR_SHOW" | "TUTORIAL_INDICATOR_SUPPRESS_ALL" | "TYPING_START" | "TYPING_START_LOCAL" | "TYPING_STOP" | "TYPING_STOP_LOCAL" | "UNSYNCED_USER_SETTINGS_UPDATE" | "UNVERIFIED_GAME_UPDATE" | "UPCOMING_GUILD_EVENT_NOTICE_HIDE" | "UPCOMING_GUILD_EVENT_NOTICE_SEEN" | "UPDATE_AVAILABLE" | "UPDATE_BACKGROUND_GRADIENT_PRESET" | "UPDATE_CHANNEL_DIMENSIONS" | "UPDATE_CHANNEL_LIST_DIMENSIONS" | "UPDATE_CHANNEL_LIST_SUBTITLES" | "UPDATE_CHAT_WALLPAPER_FLAG_COMPLETE" | "UPDATE_CHAT_WALLPAPER_FLAG_START" | "UPDATE_CHAT_WALLPAPER_OVERRIDES" | "UPDATE_CLIENT_PREMIUM_TYPE" | "UPDATE_CONSENTS" | "UPDATE_DATA_HARVEST_TYPE" | "UPDATE_DOWNLOADED" | "UPDATE_ERROR" | "UPDATE_GUILD_LIST_DIMENSIONS" | "UPDATE_MANUALLY" | "UPDATE_MOBILE_PENDING_THEME_INDEX" | "UPDATE_NOT_AVAILABLE" | "UPDATE_STRANGER_STATUS" | "UPDATE_THEME_PREFERENCES" | "UPDATE_TOKEN" | "UPDATE_VISIBLE_MESSAGES" | "UPLOAD_ATTACHMENT_ADD_FILES" | "UPLOAD_ATTACHMENT_CLEAR_ALL_FILES" | "UPLOAD_ATTACHMENT_POP_FILE" | "UPLOAD_ATTACHMENT_REMOVE_FILE" | "UPLOAD_ATTACHMENT_REMOVE_FILES" | "UPLOAD_ATTACHMENT_SET_FILE" | "UPLOAD_ATTACHMENT_SET_UPLOADS" | "UPLOAD_ATTACHMENT_UPDATE_FILE" | "UPLOAD_CANCEL_REQUEST" | "UPLOAD_COMPLETE" | "UPLOAD_COMPRESSION_PROGRESS" | "UPLOAD_FAIL" | "UPLOAD_FILE_UPDATE" | "UPLOAD_ITEM_CANCEL_REQUEST" | "UPLOAD_PROGRESS" | "UPLOAD_RESTORE_FAILED_UPLOAD" | "UPLOAD_START" | "USER_ACTIVITY_STATISTICS_FETCH_SUCCESS" | "USER_APPLICATION_REMOVE" | "USER_APPLICATION_UPDATE" | "USER_APPLIED_BOOSTS_FETCH_START" | "USER_APPLIED_BOOSTS_FETCH_SUCCESS" | "USER_AUTHORIZED_APPS_REQUEST" | "USER_AUTHORIZED_APPS_UPDATE" | "USER_CONNECTIONS_CALLBACK" | "USER_CONNECTIONS_INTEGRATION_JOINING" | "USER_CONNECTIONS_INTEGRATION_JOINING_ERROR" | "USER_CONNECTIONS_UPDATE" | "USER_CONNECTION_UPDATE" | "USER_GUILD_JOIN_REQUEST_COACHMARK_CLEAR" | "USER_GUILD_JOIN_REQUEST_COACHMARK_SHOW" | "USER_GUILD_JOIN_REQUEST_COOLDOWN_FETCH" | "USER_GUILD_JOIN_REQUEST_UPDATE" | "USER_GUILD_SETTINGS_CHANNEL_UPDATE" | "USER_GUILD_SETTINGS_CHANNEL_UPDATE_BULK" | "USER_GUILD_SETTINGS_FULL_UPDATE" | "USER_GUILD_SETTINGS_GUILD_AND_CHANNELS_UPDATE" | "USER_GUILD_SETTINGS_GUILD_UPDATE" | "USER_GUILD_SETTINGS_REMOVE_PENDING_CHANNEL_UPDATES" | "USER_JOIN_REQUEST_GUILDS_FETCH" | "USER_NON_CHANNEL_ACK" | "USER_NOTE_LOAD_START" | "USER_NOTE_UPDATE" | "USER_PAYMENT_BROWSER_CHECKOUT_DONE" | "USER_PAYMENT_BROWSER_CHECKOUT_STARTED" | "USER_PAYMENT_CLIENT_ADD" | "USER_PROFILE_EFFECTS_FETCH" | "USER_PROFILE_EFFECTS_FETCH_FAILURE" | "USER_PROFILE_EFFECTS_FETCH_SUCCESS" | "USER_PROFILE_FETCH_FAILURE" | "USER_PROFILE_FETCH_START" | "USER_PROFILE_FETCH_SUCCESS" | "USER_PROFILE_MODAL_CLOSE" | "USER_PROFILE_MODAL_OPEN" | "USER_PROFILE_PIN_BADGES_ON_CLIENT" | "USER_PROFILE_SIDEBAR_TOGGLE_SECTION" | "USER_PROFILE_UPDATE_FAILURE" | "USER_PROFILE_UPDATE_START" | "USER_PROFILE_UPDATE_SUCCESS" | "USER_REQUIRED_ACTION_UPDATE" | "USER_SETTINGS_ACCOUNT_CLOSE" | "USER_SETTINGS_ACCOUNT_INIT" | "USER_SETTINGS_ACCOUNT_RESET_AND_CLOSE_FORM" | "USER_SETTINGS_ACCOUNT_RESET_PENDING_LEGACY_USERNAME_DISABLED" | "USER_SETTINGS_ACCOUNT_SET_PENDING_ACCENT_COLOR" | "USER_SETTINGS_ACCOUNT_SET_PENDING_AVATAR" | "USER_SETTINGS_ACCOUNT_SET_PENDING_AVATAR_DECORATION" | "USER_SETTINGS_ACCOUNT_SET_PENDING_BANNER" | "USER_SETTINGS_ACCOUNT_SET_PENDING_BIO" | "USER_SETTINGS_ACCOUNT_SET_PENDING_GLOBAL_NAME" | "USER_SETTINGS_ACCOUNT_SET_PENDING_LEGACY_USERNAME_DISABLED" | "USER_SETTINGS_ACCOUNT_SET_PENDING_NAMEPLATE" | "USER_SETTINGS_ACCOUNT_SET_PENDING_PROFILE_EFFECT_ID" | "USER_SETTINGS_ACCOUNT_SET_PENDING_PRONOUNS" | "USER_SETTINGS_ACCOUNT_SET_PENDING_THEME_COLORS" | "USER_SETTINGS_ACCOUNT_SET_SINGLE_TRY_IT_OUT_COLLECTIBLES_ITEM" | "USER_SETTINGS_ACCOUNT_SET_TRY_IT_OUT_AVATAR" | "USER_SETTINGS_ACCOUNT_SET_TRY_IT_OUT_AVATAR_DECORATION" | "USER_SETTINGS_ACCOUNT_SET_TRY_IT_OUT_BANNER" | "USER_SETTINGS_ACCOUNT_SET_TRY_IT_OUT_PRESET" | "USER_SETTINGS_ACCOUNT_SET_TRY_IT_OUT_PROFILE_EFFECT_ID" | "USER_SETTINGS_ACCOUNT_SET_TRY_IT_OUT_THEME_COLORS" | "USER_SETTINGS_ACCOUNT_SUBMIT" | "USER_SETTINGS_ACCOUNT_SUBMIT_FAILURE" | "USER_SETTINGS_ACCOUNT_SUBMIT_SUCCESS" | "USER_SETTINGS_CLEAR_ERRORS" | "USER_SETTINGS_LOCALE_OVERRIDE" | "USER_SETTINGS_MODAL_CLEAR_SCROLL_POSITION" | "USER_SETTINGS_MODAL_CLEAR_SUBSECTION" | "USER_SETTINGS_MODAL_CLOSE" | "USER_SETTINGS_MODAL_INIT" | "USER_SETTINGS_MODAL_OPEN" | "USER_SETTINGS_MODAL_RESET" | "USER_SETTINGS_MODAL_SET_SECTION" | "USER_SETTINGS_MODAL_SUBMIT" | "USER_SETTINGS_MODAL_SUBMIT_COMPLETE" | "USER_SETTINGS_MODAL_SUBMIT_FAILURE" | "USER_SETTINGS_MODAL_UPDATE_ACCOUNT" | "USER_SETTINGS_OVERRIDE_APPLY" | "USER_SETTINGS_OVERRIDE_CLEAR" | "USER_SETTINGS_PROTO_ENQUEUE_UPDATE" | "USER_SETTINGS_PROTO_LOAD_IF_NECESSARY" | "USER_SETTINGS_PROTO_UPDATE" | "USER_SETTINGS_PROTO_UPDATE_EDIT_INFO" | "USER_SETTINGS_RESET_ALL_PENDING" | "USER_SETTINGS_RESET_ALL_TRY_IT_OUT" | "USER_SETTINGS_RESET_PENDING_ACCOUNT_CHANGES" | "USER_SETTINGS_RESET_PENDING_AVATAR_DECORATION" | "USER_SETTINGS_RESET_PENDING_PRIMARY_GUILD_CHANGES" | "USER_SETTINGS_RESET_PENDING_PROFILE_CHANGES" | "USER_SETTINGS_SET_PENDING_PRIMARY_GUILD_ID" | "USER_SOUNDBOARD_SET_VOLUME" | "USER_UPDATE" | "VIDEO_FILTER_ASSETS_FETCH_SUCCESS" | "VIDEO_FILTER_ASSET_DELETE_SUCCESS" | "VIDEO_FILTER_ASSET_UPLOAD_SUCCESS" | "VIDEO_SAVE_LAST_USED_BACKGROUND_OPTION" | "VIDEO_SIZE_UPDATE" | "VIDEO_STREAM_READY_TIMEOUT" | "VIEW_HISTORY_MARK_VIEW" | "VIRTUAL_CURRENCY_BALANCE_FETCH" | "VIRTUAL_CURRENCY_BALANCE_FETCH_FAIL" | "VIRTUAL_CURRENCY_BALANCE_FETCH_SUCCESS" | "VIRTUAL_CURRENCY_BALANCE_UPDATE" | "VIRTUAL_CURRENCY_EARNED_ORBS_COACHMARK_CLOSE" | "VIRTUAL_CURRENCY_EARNED_ORBS_COACHMARK_OPEN" | "VIRTUAL_CURRENCY_ONBOARDING_MODAL_OPEN" | "VIRTUAL_CURRENCY_ONBOARDING_MODAL_RESET" | "VIRTUAL_CURRENCY_REDEEM_FAIL" | "VIRTUAL_CURRENCY_REDEEM_START" | "VIRTUAL_CURRENCY_REDEEM_SUCCESS" | "VIRTUAL_CURRENCY_SET_BALANCE_PILL_OVERLAY" | "VOICE_CATEGORY_COLLAPSE" | "VOICE_CATEGORY_EXPAND" | "VOICE_CHANNEL_EFFECT_CLEAR" | "VOICE_CHANNEL_EFFECT_RECENT_EMOJI" | "VOICE_CHANNEL_EFFECT_SEND" | "VOICE_CHANNEL_EFFECT_SENT_LOCAL" | "VOICE_CHANNEL_EFFECT_TOGGLE_ANIMATION_TYPE" | "VOICE_CHANNEL_EFFECT_UPDATE_TIME_STAMP" | "VOICE_CHANNEL_SELECT" | "VOICE_CHANNEL_STATUS_UPDATE" | "VOICE_FILTER_APPLIED" | "VOICE_FILTER_APPLY_FAILED" | "VOICE_FILTER_CATALOG_FETCH_FAILED" | "VOICE_FILTER_CATALOG_FETCH_SUCCESS" | "VOICE_FILTER_DEV_TOOLS_SET_UPDATE_TIME" | "VOICE_FILTER_DOWNLOAD_FAILED" | "VOICE_FILTER_DOWNLOAD_PROGRESS" | "VOICE_FILTER_DOWNLOAD_STARTED" | "VOICE_FILTER_FILE_READY" | "VOICE_FILTER_LAGGING" | "VOICE_FILTER_LOOPBACK_TOGGLE" | "VOICE_FILTER_NATIVE_MODULE_STATE_CHANGE" | "VOICE_FILTER_REQUEST_SWITCH" | "VOICE_FILTER_UPDATE_LIMITED_TIME_VOICES" | "VOICE_SERVER_UPDATE" | "VOICE_STATE_UPDATES" | "WAIT_FOR_REMOTE_SESSION" | "WEBHOOKS_FETCHING" | "WEBHOOKS_UPDATE" | "WEBHOOK_CREATE" | "WEBHOOK_DELETE" | "WEBHOOK_UPDATE" | "WELCOME_SCREEN_FETCH_FAIL" | "WELCOME_SCREEN_FETCH_START" | "WELCOME_SCREEN_FETCH_SUCCESS" | "WELCOME_SCREEN_SETTINGS_CLEAR" | "WELCOME_SCREEN_SETTINGS_RESET" | "WELCOME_SCREEN_SETTINGS_UPDATE" | "WELCOME_SCREEN_SUBMIT" | "WELCOME_SCREEN_SUBMIT_FAILURE" | "WELCOME_SCREEN_SUBMIT_SUCCESS" | "WELCOME_SCREEN_UPDATE" | "WELCOME_SCREEN_VIEW" | "WINDOW_FOCUS" | "WINDOW_FULLSCREEN_CHANGE" | "WINDOW_HIDDEN" | "WINDOW_INIT" | "WINDOW_RESIZED" | "WINDOW_UNLOAD" | "WINDOW_VISIBILITY_CHANGE" | "WRITE_CACHES"; diff --git a/packages/discord-types/src/index.d.ts b/packages/discord-types/src/index.d.ts deleted file mode 100644 index 6d9356b4..00000000 --- a/packages/discord-types/src/index.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from "./common"; -export * from "./classes"; -export * from "./components"; -export * from "./flux"; -export * from "./fluxEvents"; -export * from "./menu"; -export * from "./stores"; -export * from "./utils"; -export * as Webpack from "../webpack"; diff --git a/packages/discord-types/src/stores/ChannelStore.d.ts b/packages/discord-types/src/stores/ChannelStore.d.ts deleted file mode 100644 index 1507ba5e..00000000 --- a/packages/discord-types/src/stores/ChannelStore.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Channel, FluxStore } from ".."; - -export class ChannelStore extends FluxStore { - getChannel(channelId: string): Channel; - getBasicChannel(channelId: string): Channel | undefined; - hasChannel(channelId: string): boolean; - - getChannelIds(guildId?: string | null): string[]; - getMutableBasicGuildChannelsForGuild(guildId: string): Record; - getMutableGuildChannelsForGuild(guildId: string): Record; - getAllThreadsForGuild(guildId: string): Channel[]; - getAllThreadsForParent(channelId: string): Channel[]; - - getDMFromUserId(userId: string): string; - getDMChannelFromUserId(userId: string): Channel | undefined; - getDMUserIds(): string[]; - getMutableDMsByUserIds(): Record; - getMutablePrivateChannels(): Record; - getSortedPrivateChannels(): Channel[]; - - getGuildChannelsVersion(guildId: string): number; - getPrivateChannelsVersion(): number; - getInitialOverlayState(): Record; -} diff --git a/packages/discord-types/src/stores/DraftStore.d.ts b/packages/discord-types/src/stores/DraftStore.d.ts deleted file mode 100644 index 98b34cdf..00000000 --- a/packages/discord-types/src/stores/DraftStore.d.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { FluxStore } from ".."; - -export enum DraftType { - ChannelMessage = 0, - ThreadSettings = 1, - FirstThreadMessage = 2, - ApplicationLauncherCommand = 3, - Poll = 4, - SlashCommand = 5, - ForwardContextMessage = 6 -} - -export interface Draft { - timestamp: number; - draft: string; -} - -export interface ThreadSettingsDraft { - timestamp: number; - parentMessageId?: string; - name?: string; - isPrivate?: boolean; - parentChannelId?: string; - location?: string; -} - -export type ChannelDrafts = { - [DraftType.ThreadSettings]: ThreadSettingsDraft; -} & { - [key in Exclude]: Draft; -}; - -export type UserDrafts = Partial>; -export type DraftState = Partial>; - -export class DraftStore extends FluxStore { - getState(): DraftState; - getRecentlyEditedDrafts(type: DraftType): Array; - getDraft(channelId: string, type: DraftType): string; - - getThreadSettings(channelId: string): ThreadSettingsDraft | null | undefined; - getThreadDraftWithParentMessageId(parentMessageId: string): ThreadSettingsDraft | null | undefined; -} diff --git a/packages/discord-types/src/stores/EmojiStore.d.ts b/packages/discord-types/src/stores/EmojiStore.d.ts deleted file mode 100644 index 93161b2f..00000000 --- a/packages/discord-types/src/stores/EmojiStore.d.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Channel, CustomEmoji, Emoji, FluxStore } from ".."; - -export class EmojiStore extends FluxStore { - getCustomEmojiById(id?: string | null): CustomEmoji | undefined; - getUsableCustomEmojiById(id?: string | null): CustomEmoji | undefined; - getGuilds(): Record; - getGuildEmoji(guildId?: string | null): CustomEmoji[]; - getNewlyAddedEmoji(guildId?: string | null): CustomEmoji[]; - getTopEmoji(guildId?: string | null): CustomEmoji[]; - getTopEmojisMetadata(guildId?: string | null): { - emojiIds: string[]; - topEmojisTTL: number; - }; - hasPendingUsage(): boolean; - hasUsableEmojiInAnyGuild(): boolean; - searchWithoutFetchingLatest(data: any): any; - getSearchResultsOrder(...args: any[]): any; - getState(): { - pendingUsages: { key: string, timestamp: number; }[]; - }; - searchWithoutFetchingLatest(data: { - channel: Channel; - query: string; - count?: number; - intention: number; - includeExternalGuilds?: boolean; - matchComparator?(name: string): boolean; - }): Record<"locked" | "unlocked", Emoji[]>; - - getDisambiguatedEmojiContext(): { - backfillTopEmojis: Record; - customEmojis: Record; - emojisById: Record; - emojisByName: Record; - emoticonRegex: RegExp | null; - emoticonsByName: Record; - escapedEmoticonNames: string; - favoriteNamesAndIds?: any; - favorites?: any; - frequentlyUsed?: any; - groupedCustomEmojis: Record; - guildId?: string; - isFavoriteEmojiWithoutFetchingLatest(e: Emoji): boolean; - newlyAddedEmoji: Record; - topEmojis?: any; - unicodeAliases: Record; - get favoriteEmojisWithoutFetchingLatest(): Emoji[]; - }; -} diff --git a/packages/discord-types/src/stores/FluxStore.d.ts b/packages/discord-types/src/stores/FluxStore.d.ts deleted file mode 100644 index da55ac0b..00000000 --- a/packages/discord-types/src/stores/FluxStore.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { FluxDispatcher, FluxEvents } from ".."; - -type Callback = () => void; - -/* - For some reason, this causes type errors when you try to destructure it: - ```ts - interface FluxEvent { - type: FluxEvents; - [key: string]: any; - } - ``` - */ -export type FluxEvent = any; - -export type ActionHandler = (event: FluxEvent) => void; -export type ActionHandlers = Partial>; - -export class FluxStore { - constructor(dispatcher: FluxDispatcher, actionHandlers?: ActionHandlers); - - getName(): string; - - addChangeListener(callback: Callback): void; - /** Listener will be removed once the callback returns false. */ - addConditionalChangeListener(callback: () => boolean, preemptive?: boolean): void; - addReactChangeListener(callback: Callback): void; - removeChangeListener(callback: Callback): void; - removeReactChangeListener(callback: Callback): void; - - doEmitChanges(event: FluxEvent): void; - emitChange(): void; - - getDispatchToken(): string; - initialize(): void; - initializeIfNeeded(): void; - /** this is a setter */ - mustEmitChanges(actionHandler: ActionHandler | undefined): void; - registerActionHandlers(actionHandlers: ActionHandlers): void; - syncWith(stores: FluxStore[], callback: Callback, timeout?: number): void; - waitFor(...stores: FluxStore[]): void; - - static getAll(): FluxStore[]; -} diff --git a/packages/discord-types/src/stores/GuildMemberStore.d.ts b/packages/discord-types/src/stores/GuildMemberStore.d.ts deleted file mode 100644 index 9dec139a..00000000 --- a/packages/discord-types/src/stores/GuildMemberStore.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { FluxStore, GuildMember } from ".."; - -export class GuildMemberStore extends FluxStore { - /** @returns Format: [guildId-userId: Timestamp (string)] */ - getCommunicationDisabledUserMap(): Record; - getCommunicationDisabledVersion(): number; - - getMutableAllGuildsAndMembers(): Record>; - - getMember(guildId: string, userId: string): GuildMember | null; - getTrueMember(guildId: string, userId: string): GuildMember | null; - getMemberIds(guildId: string): string[]; - getMembers(guildId: string): GuildMember[]; - - getCachedSelfMember(guildId: string): GuildMember | null; - getSelfMember(guildId: string): GuildMember | null; - getSelfMemberJoinedAt(guildId: string): Date | null; - - getNick(guildId: string, userId: string): string | null; - getNicknameGuildsMapping(userId: string): Record; - getNicknames(userId: string): string[]; - - isMember(guildId: string, userId: string): boolean; - isMember(guildId: string, userId: string): boolean; - isGuestOrLurker(guildId: string, userId: string): boolean; - isCurrentUserGuest(guildId: string): boolean; -} diff --git a/packages/discord-types/src/stores/GuildRoleStore.d.ts b/packages/discord-types/src/stores/GuildRoleStore.d.ts deleted file mode 100644 index bf0d4042..00000000 --- a/packages/discord-types/src/stores/GuildRoleStore.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { FluxStore, Role } from ".."; - -export class GuildRoleStore extends FluxStore { - getRole(guildId: string, roleId: string): Role; - getRoles(guildId: string): Record; - getAllGuildRoles(): Record>; -} diff --git a/packages/discord-types/src/stores/GuildStore.d.ts b/packages/discord-types/src/stores/GuildStore.d.ts deleted file mode 100644 index d1a3b9b3..00000000 --- a/packages/discord-types/src/stores/GuildStore.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Guild, FluxStore } from ".."; - -export class GuildStore extends FluxStore { - getGuild(guildId: string): Guild; - getGuildCount(): number; - getGuilds(): Record; - getGuildIds(): string[]; -} diff --git a/packages/discord-types/src/stores/MessageStore.d.ts b/packages/discord-types/src/stores/MessageStore.d.ts deleted file mode 100644 index d4823fc8..00000000 --- a/packages/discord-types/src/stores/MessageStore.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { MessageJSON, FluxStore, Message } from ".."; - -export class MessageStore extends FluxStore { - getMessage(channelId: string, messageId: string): Message; - /** @returns This return object is fucking huge; I'll type it later. */ - getMessages(channelId: string): unknown; - getRawMessages(channelId: string): Record; - hasCurrentUserSentMessage(channelId: string): boolean; - hasPresent(channelId: string): boolean; - isLoadingMessages(channelId: string): boolean; - jumpedMessageId(channelId: string): string | undefined; - whenReady(channelId: string, callback: () => void): void; -} diff --git a/packages/discord-types/src/stores/RelationshipStore.d.ts b/packages/discord-types/src/stores/RelationshipStore.d.ts deleted file mode 100644 index 5d1a08af..00000000 --- a/packages/discord-types/src/stores/RelationshipStore.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { FluxStore } from ".."; - -export class RelationshipStore extends FluxStore { - getFriendIDs(): string[]; - getIgnoredIDs(): string[]; - getBlockedIDs(): string[]; - - getPendingCount(): number; - getRelationshipCount(): number; - - /** Related to friend nicknames. */ - getNickname(userId: string): string; - /** @returns Enum value from constants.RelationshipTypes */ - getRelationshipType(userId: string): number; - isFriend(userId: string): boolean; - isBlocked(userId: string): boolean; - isIgnored(userId: string): boolean; - getSince(userId: string): string; - - getMutableRelationships(): Map; -} diff --git a/packages/discord-types/src/stores/SelectedChannelStore.d.ts b/packages/discord-types/src/stores/SelectedChannelStore.d.ts deleted file mode 100644 index 13ac98ac..00000000 --- a/packages/discord-types/src/stores/SelectedChannelStore.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { FluxStore } from ".."; - -export class SelectedChannelStore extends FluxStore { - getChannelId(guildId?: string | null): string; - getVoiceChannelId(): string | undefined; - getCurrentlySelectedChannelId(guildId?: string): string | undefined; - getMostRecentSelectedTextChannelId(guildId: string): string | undefined; - getLastSelectedChannelId(guildId?: string): string; - // yes this returns a string - getLastSelectedChannels(guildId?: string): string; - - /** If you follow an announcement channel, this will return whichever channel you chose as destination */ - getLastChannelFollowingDestination(): { guildId?: string; channelId?: string; } | undefined; -} diff --git a/packages/discord-types/src/stores/SelectedGuildStore.d.ts b/packages/discord-types/src/stores/SelectedGuildStore.d.ts deleted file mode 100644 index 0ee9c207..00000000 --- a/packages/discord-types/src/stores/SelectedGuildStore.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { FluxStore } from ".."; - -export interface SelectedGuildState { - selectedGuildTimestampMillis: Record; - selectedGuildId: string | null; - lastSelectedGuildId: string | null; -} - -export class SelectedGuildStore extends FluxStore { - getGuildId(): string | null; - getLastSelectedGuildId(): string | null; - getLastSelectedTimestamp(guildId: string): number | null; - getState(): SelectedGuildState | undefined; -} diff --git a/packages/discord-types/src/stores/ThemeStore.d.ts b/packages/discord-types/src/stores/ThemeStore.d.ts deleted file mode 100644 index 2900f7f6..00000000 --- a/packages/discord-types/src/stores/ThemeStore.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { FluxStore } from ".."; - -export type ThemePreference = "dark" | "light" | "unknown"; -export type SystemTheme = "dark" | "light"; -export type Theme = "light" | "dark" | "darker" | "midnight"; - -export interface ThemeState { - theme: Theme; - status: 0 | 1; - preferences: Record; -} -export class ThemeStore extends FluxStore { - get theme(): Theme; - get darkSidebar(): boolean; - get systemTheme(): SystemTheme; - themePreferenceForSystemTheme(preference: ThemePreference): Theme; - getState(): ThemeState; -} diff --git a/packages/discord-types/src/stores/UserProfileStore.d.ts b/packages/discord-types/src/stores/UserProfileStore.d.ts deleted file mode 100644 index d9efc47b..00000000 --- a/packages/discord-types/src/stores/UserProfileStore.d.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { FluxStore, Guild, User, Application, ApplicationInstallParams } from ".."; -import { ApplicationIntegrationType } from "../../enums"; - -export interface MutualFriend { - /** - * the userid of the mutual friend - */ - key: string; - /** - * the status of the mutual friend - */ - status: "online" | "offline" | "idle" | "dnd"; - /** - * the user object of the mutual friend - */ - user: User; -} - -export interface MutualGuild { - /** - * the guild object of the mutual guild - */ - guild: Guild; - /** - * the user's nickname in the guild, if any - */ - nick: string | null; - -} - -export interface ProfileBadge { - id: string; - description: string; - icon: string; - link?: string; -} - -export interface ConnectedAccount { - type: "twitch" | "youtube" | "skype" | "steam" | "leagueoflegends" | "battlenet" | "bluesky" | "bungie" | "reddit" | "twitter" | "twitter_legacy" | "spotify" | "facebook" | "xbox" | "samsung" | "contacts" | "instagram" | "mastodon" | "soundcloud" | "github" | "playstation" | "playstation-stg" | "epicgames" | "riotgames" | "roblox" | "paypal" | "ebay" | "tiktok" | "crunchyroll" | "domain" | "amazon-music"; - /** - * underlying id of connected account - * eg. account uuid - */ - id: string; - /** - * display name of connected account - */ - name: string; - verified: boolean; - metadata?: Record; -} - -export interface ProfileApplication { - id: string; - customInstallUrl: string | undefined; - installParams: ApplicationInstallParams | undefined; - flags: number; - popularApplicationCommandIds?: string[]; - integrationTypesConfig: Record>; - primarySkuId: string | undefined; - storefront_available: boolean; -} - -export interface UserProfileBase extends Pick { - accentColor: number | null; - /** - * often empty for guild profiles, get the user profile for badges - */ - badges: ProfileBadge[]; - bio: string | undefined; - popoutAnimationParticleType: string | null; - profileEffectExpiresAt: number | Date | undefined; - profileEffectId: undefined | string; - /** - * often an empty string when not set - */ - pronouns: string | "" | undefined; - themeColors: [number, number] | undefined; - userId: string; -} - -export interface ApplicationRoleConnection { - application: Application; - application_metadata: Record; - metadata: Record; - platform_name: string; - platform_username: string; -} - -export interface UserProfile extends UserProfileBase, Pick { - /** If this is a bot user profile, this will be its application */ - application: ProfileApplication | null; - applicationRoleConnections: ApplicationRoleConnection[] | undefined; - connectedAccounts: ConnectedAccount[] | undefined; - fetchStartedAt: number; - fetchEndedAt: number; - legacyUsername: string | undefined; - premiumGuildSince: Date | null; - premiumSince: Date | null; -} - -export class UserProfileStore extends FluxStore { - /** - * @param userId the user ID of the profile being fetched. - * @param guildId the guild ID to of the profile being fetched. - * defaults to the internal symbol `NO GUILD ID` if nullish - * - * @returns true if the profile is being fetched, false otherwise. - */ - isFetchingProfile(userId: string, guildId?: string): boolean; - /** - * Check if mutual friends for {@link userId} are currently being fetched. - * - * @param userId the user ID of the mutual friends being fetched. - * - * @returns true if mutual friends are being fetched, false otherwise. - */ - isFetchingFriends(userId: string): boolean; - - get isSubmitting(): boolean; - - getUserProfile(userId: string): UserProfile | undefined; - - getGuildMemberProfile(userId: string, guildId: string | undefined): UserProfileBase | null; - /** - * Get the mutual friends of a user. - * - * @param userId the user ID of the user to get the mutual friends of. - * - * @returns an array of mutual friends, or undefined if the user has no mutual friends - */ - getMutualFriends(userId: string): MutualFriend[] | undefined; - /** - * Get the count of mutual friends for a user. - * - * @param userId the user ID of the user to get the mutual friends count of. - * - * @returns the count of mutual friends, or undefined if the user has no mutual friends - */ - getMutualFriendsCount(userId: string): number | undefined; - /** - * Get the mutual guilds of a user. - * - * @param userId the user ID of the user to get the mutual guilds of. - * - * @returns an array of mutual guilds, or undefined if the user has no mutual guilds - */ - getMutualGuilds(userId: string): MutualGuild[] | undefined; -} diff --git a/packages/discord-types/src/stores/UserStore.d.ts b/packages/discord-types/src/stores/UserStore.d.ts deleted file mode 100644 index 323a1df0..00000000 --- a/packages/discord-types/src/stores/UserStore.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { FluxStore, User } from ".."; - -export class UserStore extends FluxStore { - filter(filter: (user: User) => boolean, sort?: boolean): Record; - findByTag(username: string, discriminator: string): User; - forEach(action: (user: User) => void): void; - getCurrentUser(): User; - getUser(userId: string): User; - getUsers(): Record; -} diff --git a/packages/discord-types/src/stores/WindowStore.d.ts b/packages/discord-types/src/stores/WindowStore.d.ts deleted file mode 100644 index 53a40e96..00000000 --- a/packages/discord-types/src/stores/WindowStore.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { FluxStore } from ".."; - -export class WindowStore extends FluxStore { - isElementFullScreen(): boolean; - isFocused(): boolean; - windowSize(): Record<"width" | "height", number>; -} diff --git a/packages/discord-types/src/stores/index.d.ts b/packages/discord-types/src/stores/index.d.ts deleted file mode 100644 index 23045832..00000000 --- a/packages/discord-types/src/stores/index.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -// please keep in alphabetical order -export * from "./ChannelStore"; -export * from "./DraftStore"; -export * from "./EmojiStore"; -export * from "./FluxStore"; -export * from "./GuildMemberStore"; -export * from "./GuildRoleStore"; -export * from "./GuildStore"; -export * from "./MessageStore"; -export * from "./RelationshipStore"; -export * from "./SelectedChannelStore"; -export * from "./SelectedGuildStore"; -export * from "./ThemeStore"; -export * from "./UserProfileStore"; -export * from "./UserStore"; -export * from "./WindowStore"; - -/** - * React hook that returns stateful data for one or more stores - * You might need a custom comparator (4th argument) if your store data is an object - * @param stores The stores to listen to - * @param mapper A function that returns the data you need - * @param dependencies An array of reactive values which the hook depends on. Use this if your mapper or equality function depends on the value of another hook - * @param isEqual A custom comparator for the data returned by mapper - * - * @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id); - */ -export type useStateFromStores = ( - stores: any[], - mapper: () => T, - dependencies?: any, - isEqual?: (old: T, newer: T) => boolean -) => T; diff --git a/packages/vencord-types/package.json b/packages/vencord-types/package.json index 64586919..b3bbe315 100644 --- a/packages/vencord-types/package.json +++ b/packages/vencord-types/package.json @@ -21,6 +21,7 @@ "@types/node": "^22.13.4", "@types/react": "18.3.1", "@types/react-dom": "18.3.1", + "discord-types": "^1.3.26", "standalone-electron-types": "^34.2.0", "type-fest": "^4.35.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cde57a1f..2e493972 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,12 +65,12 @@ importers: '@types/yazl': specifier: ^2.4.5 version: 2.4.6 - '@vencord/discord-types': - specifier: link:packages/discord-types - version: link:packages/discord-types diff: specifier: ^7.0.0 version: 7.0.0 + discord-types: + specifier: ^1.3.26 + version: 1.3.26 esbuild: specifier: ^0.25.1 version: 0.25.1 @@ -141,18 +141,6 @@ importers: specifier: ^0.3.5 version: 0.3.5 - packages/discord-types: - dependencies: - '@types/react': - specifier: ^19.0.10 - version: 19.0.12 - moment: - specifier: ^2.22.2 - version: 2.30.1 - type-fest: - specifier: ^4.41.0 - version: 4.41.0 - packages/vencord-types: dependencies: '@types/lodash': @@ -167,6 +155,9 @@ importers: '@types/react-dom': specifier: 18.3.1 version: 18.3.1 + discord-types: + specifier: ^1.3.26 + version: 1.3.26 standalone-electron-types: specifier: ^34.2.0 version: 34.2.0 @@ -531,6 +522,9 @@ packages: peerDependencies: '@types/react': ^19.0.0 + '@types/react@17.0.2': + resolution: {integrity: sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA==} + '@types/react@18.3.1': resolution: {integrity: sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==} @@ -962,6 +956,9 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + discord-types@1.3.26: + resolution: {integrity: sha512-ToG51AOCH+JTQf7b+8vuYQe5Iqwz7nZ7StpECAZ/VZcI1ZhQk13pvt9KkRTfRv1xNvwJ2qib4e3+RifQlo8VPQ==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -2331,10 +2328,6 @@ packages: resolution: {integrity: sha512-2dBz5D5ycHIoliLYLi0Q2V7KRaDlH0uWIvmk7TYlAg5slqwiPv1ezJdZm1QEM0xgk29oYWMCbIG7E6gHpvChlg==} engines: {node: '>=16'} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -2771,6 +2764,11 @@ snapshots: dependencies: '@types/react': 19.0.12 + '@types/react@17.0.2': + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + '@types/react@18.3.1': dependencies: '@types/prop-types': 15.7.14 @@ -3257,6 +3255,11 @@ snapshots: dependencies: path-type: 4.0.0 + discord-types@1.3.26: + dependencies: + '@types/react': 17.0.2 + moment: 2.30.1 + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -4920,8 +4923,6 @@ snapshots: type-fest@4.38.0: {} - type-fest@4.41.0: {} - typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 diff --git a/scripts/build/build.mjs b/scripts/build/build.mjs index db0a1ce0..7d21cd24 100755 --- a/scripts/build/build.mjs +++ b/scripts/build/build.mjs @@ -31,7 +31,6 @@ const defines = stringifyValues({ IS_UPDATER_DISABLED, IS_WEB: false, IS_EXTENSION: false, - IS_USERSCRIPT: false, VERSION, BUILD_TIMESTAMP }); @@ -51,7 +50,7 @@ const nodeCommonOpts = { format: "cjs", platform: "node", target: ["esnext"], - // @ts-expect-error this is never undefined + // @ts-ignore this is never undefined external: ["electron", "original-fs", "~pluginNatives", ...commonOpts.external] }; diff --git a/scripts/build/buildWeb.mjs b/scripts/build/buildWeb.mjs index b22df8ab..824194cf 100644 --- a/scripts/build/buildWeb.mjs +++ b/scripts/build/buildWeb.mjs @@ -43,7 +43,6 @@ const commonOptions = { define: stringifyValues({ IS_WEB: true, IS_EXTENSION: false, - IS_USERSCRIPT: false, IS_STANDALONE: true, IS_DEV, IS_REPORTER, @@ -99,7 +98,6 @@ const buildConfigs = [ inject: ["browser/GMPolyfill.js", ...(commonOptions?.inject || [])], define: { ...commonOptions.define, - IS_USERSCRIPT: "true", window: "unsafeWindow", }, outfile: "dist/Vencord.user.js", diff --git a/scripts/build/common.mjs b/scripts/build/common.mjs index 516f6a1b..5c1732aa 100644 --- a/scripts/build/common.mjs +++ b/scripts/build/common.mjs @@ -363,6 +363,6 @@ export const commonRendererPlugins = [ banImportPlugin(/^react$/, "Cannot import from react. React and hooks should be imported from @webpack/common"), banImportPlugin(/^electron(\/.*)?$/, "Cannot import electron in browser code. You need to use a native.ts file"), banImportPlugin(/^ts-pattern$/, "Cannot import from ts-pattern. match and P should be imported from @webpack/common"), - // @ts-expect-error this is never undefined + // @ts-ignore this is never undefined ...commonOpts.plugins ]; diff --git a/src/Vencord.ts b/src/Vencord.ts index f18c7347..48ecce97 100644 --- a/src/Vencord.ts +++ b/src/Vencord.ts @@ -134,11 +134,7 @@ async function init() { if (!IS_WEB && !IS_UPDATER_DISABLED) { runUpdateCheck(); - - // this tends to get really annoying, so only do this if the user has auto-update without notification enabled - if (Settings.autoUpdate && !Settings.autoUpdateNotification) { - setInterval(runUpdateCheck, 1000 * 60 * 30); // 30 minutes - } + setInterval(runUpdateCheck, 1000 * 60 * 30); // 30 minutes } if (IS_DEV) { diff --git a/src/VencordNative.ts b/src/VencordNative.ts index 048b30c7..3bed5a59 100644 --- a/src/VencordNative.ts +++ b/src/VencordNative.ts @@ -5,7 +5,6 @@ */ import type { Settings } from "@api/Settings"; -import { CspRequestResult } from "@main/csp/manager"; import { PluginIpcMappings } from "@main/ipcPlugins"; import type { UserThemeHeader } from "@main/themes"; import { IpcEvents } from "@shared/IpcEvents"; @@ -34,11 +33,10 @@ export default { themes: { uploadTheme: (fileName: string, fileData: string) => invoke(IpcEvents.UPLOAD_THEME, fileName, fileData), deleteTheme: (fileName: string) => invoke(IpcEvents.DELETE_THEME, fileName), + getThemesDir: () => invoke(IpcEvents.GET_THEMES_DIR), getThemesList: () => invoke>(IpcEvents.GET_THEMES_LIST), getThemeData: (fileName: string) => invoke(IpcEvents.GET_THEME_DATA, fileName), getSystemValues: () => invoke>(IpcEvents.GET_THEME_SYSTEM_VALUES), - - openFolder: () => invoke(IpcEvents.OPEN_THEMES_FOLDER), }, updater: { @@ -51,8 +49,7 @@ export default { settings: { get: () => sendSync(IpcEvents.GET_SETTINGS), set: (settings: Settings, pathToNotify?: string) => invoke(IpcEvents.SET_SETTINGS, settings, pathToNotify), - - openFolder: () => invoke(IpcEvents.OPEN_SETTINGS_FOLDER), + getSettingsDir: () => invoke(IpcEvents.GET_SETTINGS_DIR), }, quickCss: { @@ -76,17 +73,5 @@ export default { openExternal: (url: string) => invoke(IpcEvents.OPEN_EXTERNAL, url) }, - csp: { - /** - * Note: Only supports full explicit matches, not wildcards. - * - * If `*.example.com` is allowed, `isDomainAllowed("https://sub.example.com")` will return false. - */ - isDomainAllowed: (url: string, directives: string[]) => invoke(IpcEvents.CSP_IS_DOMAIN_ALLOWED, url, directives), - removeOverride: (url: string) => invoke(IpcEvents.CSP_REMOVE_OVERRIDE, url), - requestAddOverride: (url: string, directives: string[], callerName: string) => - invoke(IpcEvents.CSP_REQUEST_ADD_OVERRIDE, url, directives, callerName), - }, - pluginHelpers: PluginHelpers }; diff --git a/src/api/ChatButtons.tsx b/src/api/ChatButtons.tsx index 1cacd06b..6f4285ff 100644 --- a/src/api/ChatButtons.tsx +++ b/src/api/ChatButtons.tsx @@ -8,9 +8,9 @@ import "./ChatButton.css"; import ErrorBoundary from "@components/ErrorBoundary"; import { Logger } from "@utils/Logger"; -import { Channel } from "@vencord/discord-types"; import { waitFor } from "@webpack"; import { Button, ButtonWrapperClasses, Tooltip } from "@webpack/common"; +import { Channel } from "discord-types/general"; import { HTMLProps, JSX, MouseEventHandler, ReactNode } from "react"; let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>; diff --git a/src/api/Commands/commandHelpers.ts b/src/api/Commands/commandHelpers.ts index 8ec23135..ac1dafc9 100644 --- a/src/api/Commands/commandHelpers.ts +++ b/src/api/Commands/commandHelpers.ts @@ -17,11 +17,13 @@ */ import { mergeDefaults } from "@utils/mergeDefaults"; -import { CommandArgument, Message } from "@vencord/discord-types"; import { findByCodeLazy } from "@webpack"; import { MessageActions, SnowflakeUtils } from "@webpack/common"; +import { Message } from "discord-types/general"; import type { PartialDeep } from "type-fest"; +import { Argument } from "./types"; + const createBotMessage = findByCodeLazy('username:"Clyde"'); export function generateId() { @@ -49,8 +51,8 @@ export function sendBotMessage(channelId: string, message: PartialDeep) * @param fallbackValue Fallback value in case this option wasn't passed * @returns Value */ -export function findOption(args: CommandArgument[], name: string): T & {} | undefined; -export function findOption(args: CommandArgument[], name: string, fallbackValue: T): T & {}; -export function findOption(args: CommandArgument[], name: string, fallbackValue?: any) { +export function findOption(args: Argument[], name: string): T & {} | undefined; +export function findOption(args: Argument[], name: string, fallbackValue: T): T & {}; +export function findOption(args: Argument[], name: string, fallbackValue?: any) { return (args.find(a => a.name === name)?.value ?? fallbackValue) as any; } diff --git a/src/api/Commands/index.ts b/src/api/Commands/index.ts index 231b3daf..af6a6fdf 100644 --- a/src/api/Commands/index.ts +++ b/src/api/Commands/index.ts @@ -18,39 +18,38 @@ import { Logger } from "@utils/Logger"; import { makeCodeblock } from "@utils/text"; -import { CommandArgument, CommandContext, CommandOption } from "@vencord/discord-types"; import { sendBotMessage } from "./commandHelpers"; -import { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType, VencordCommand } from "./types"; +import { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType, Argument, Command, CommandContext, Option } from "./types"; export * from "./commandHelpers"; export * from "./types"; -export let BUILT_IN: VencordCommand[]; -export const commands = {} as Record; +export let BUILT_IN: Command[]; +export const commands = {} as Record; // hack for plugins being evaluated before we can grab these from webpack -const OptPlaceholder = Symbol("OptionalMessageOption") as any as CommandOption; -const ReqPlaceholder = Symbol("RequiredMessageOption") as any as CommandOption; +const OptPlaceholder = Symbol("OptionalMessageOption") as any as Option; +const ReqPlaceholder = Symbol("RequiredMessageOption") as any as Option; /** * Optional message option named "message" you can use in commands. * Used in "tableflip" or "shrug" * @see {@link RequiredMessageOption} */ -export let OptionalMessageOption: CommandOption = OptPlaceholder; +export let OptionalMessageOption: Option = OptPlaceholder; /** * Required message option named "message" you can use in commands. * Used in "me" * @see {@link OptionalMessageOption} */ -export let RequiredMessageOption: CommandOption = ReqPlaceholder; +export let RequiredMessageOption: Option = ReqPlaceholder; // Discord's command list has random gaps for some reason, which can cause issues while rendering the commands // Add this offset to every added command to keep them unique let commandIdOffset: number; -export const _init = function (cmds: VencordCommand[]) { +export const _init = function (cmds: Command[]) { try { BUILT_IN = cmds; OptionalMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "shrug")!.options![0]; @@ -62,7 +61,7 @@ export const _init = function (cmds: VencordCommand[]) { return cmds; } as never; -export const _handleCommand = function (cmd: VencordCommand, args: CommandArgument[], ctx: CommandContext) { +export const _handleCommand = function (cmd: Command, args: Argument[], ctx: CommandContext) { if (!cmd.isVencordCommand) return cmd.execute(args, ctx); @@ -93,7 +92,7 @@ export const _handleCommand = function (cmd: VencordCommand, args: CommandArgume * Prepare a Command Option for Discord by filling missing fields * @param opt */ -export function prepareOption(opt: O): O { +export function prepareOption(opt: O): O { opt.displayName ||= opt.name; opt.displayDescription ||= opt.description; opt.options?.forEach((opt, i, opts) => { @@ -110,7 +109,7 @@ export function prepareOption(opt: O): // Yes, Discord registers individual commands for each subcommand // TODO: This probably doesn't support nested subcommands. If that is ever needed, // investigate -function registerSubCommands(cmd: VencordCommand, plugin: string) { +function registerSubCommands(cmd: Command, plugin: string) { cmd.options?.forEach(o => { if (o.type !== ApplicationCommandOptionType.SUB_COMMAND) throw new Error("When specifying sub-command options, all options must be sub-commands."); @@ -133,7 +132,7 @@ function registerSubCommands(cmd: VencordCommand, plugin: string) { }); } -export function registerCommand(command: C, plugin: string) { +export function registerCommand(command: C, plugin: string) { if (!BUILT_IN) { console.warn( "[CommandsAPI]", diff --git a/src/api/Commands/types.ts b/src/api/Commands/types.ts index c5ecb35e..70b73775 100644 --- a/src/api/Commands/types.ts +++ b/src/api/Commands/types.ts @@ -1,12 +1,106 @@ /* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2022 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ -import { Command } from "@vencord/discord-types"; -export { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType } from "@vencord/discord-types/enums"; +import { Channel, Guild } from "discord-types/general"; +import { Promisable } from "type-fest"; -export interface VencordCommand extends Command { - isVencordCommand?: boolean; +export interface CommandContext { + channel: Channel; + guild?: Guild; +} + +export const enum ApplicationCommandOptionType { + SUB_COMMAND = 1, + SUB_COMMAND_GROUP = 2, + STRING = 3, + INTEGER = 4, + BOOLEAN = 5, + USER = 6, + CHANNEL = 7, + ROLE = 8, + MENTIONABLE = 9, + NUMBER = 10, + ATTACHMENT = 11, +} + +export const enum ApplicationCommandInputType { + BUILT_IN = 0, + BUILT_IN_TEXT = 1, + BUILT_IN_INTEGRATION = 2, + BOT = 3, + PLACEHOLDER = 4, +} + +export interface Option { + name: string; + displayName?: string; + type: ApplicationCommandOptionType; + description: string; + displayDescription?: string; + required?: boolean; + options?: Option[]; + choices?: Array; +} + +export interface ChoicesOption { + label: string; + value: string; + name: string; + displayName?: string; +} + +export const enum ApplicationCommandType { + CHAT_INPUT = 1, + USER = 2, + MESSAGE = 3, +} + +export interface CommandReturnValue { + content: string; + /** TODO: implement */ + cancel?: boolean; +} + +export interface Argument { + type: ApplicationCommandOptionType; + name: string; + value: string; + focused: undefined; + options: Argument[]; +} + +export interface Command { + id?: string; + applicationId?: string; + type?: ApplicationCommandType; + inputType?: ApplicationCommandInputType; + plugin?: string; + isVencordCommand?: boolean; + + name: string; + untranslatedName?: string; + displayName?: string; + description: string; + untranslatedDescription?: string; + displayDescription?: string; + + options?: Option[]; + predicate?(ctx: CommandContext): boolean; + + execute(args: Argument[], ctx: CommandContext): Promisable; } diff --git a/src/api/DataStore/index.ts b/src/api/DataStore/index.ts index 80ebb065..47ae39db 100644 --- a/src/api/DataStore/index.ts +++ b/src/api/DataStore/index.ts @@ -22,9 +22,9 @@ export function promisifyRequest( request: IDBRequest | IDBTransaction, ): Promise { return new Promise((resolve, reject) => { - // @ts-expect-error - file size hacks + // @ts-ignore - file size hacks request.oncomplete = request.onsuccess = () => resolve(request.result); - // @ts-expect-error - file size hacks + // @ts-ignore - file size hacks request.onabort = request.onerror = () => reject(request.error); }); } diff --git a/src/api/MemberListDecorators.tsx b/src/api/MemberListDecorators.tsx index 2367e4cf..ada60776 100644 --- a/src/api/MemberListDecorators.tsx +++ b/src/api/MemberListDecorators.tsx @@ -17,7 +17,7 @@ */ import ErrorBoundary from "@components/ErrorBoundary"; -import { Channel, User } from "@vencord/discord-types"; +import { Channel, User } from "discord-types/general/index.js"; import { JSX } from "react"; interface DecoratorProps { diff --git a/src/api/MessageAccessories.tsx b/src/api/MessageAccessories.tsx index d2bc081e..71664e93 100644 --- a/src/api/MessageAccessories.tsx +++ b/src/api/MessageAccessories.tsx @@ -48,7 +48,7 @@ export function _modifyAccessories( ) { for (const [key, accessory] of accessories.entries()) { const res = ( - + ); diff --git a/src/api/MessageDecorations.tsx b/src/api/MessageDecorations.tsx index 8cf492c7..1b94c18d 100644 --- a/src/api/MessageDecorations.tsx +++ b/src/api/MessageDecorations.tsx @@ -17,7 +17,7 @@ */ import ErrorBoundary from "@components/ErrorBoundary"; -import { Channel, Message } from "@vencord/discord-types"; +import { Channel, Message } from "discord-types/general/index.js"; import { JSX } from "react"; export interface MessageDecorationProps { diff --git a/src/api/MessageEvents.ts b/src/api/MessageEvents.ts index 8b1d9e78..1b55ff34 100644 --- a/src/api/MessageEvents.ts +++ b/src/api/MessageEvents.ts @@ -17,8 +17,9 @@ */ import { Logger } from "@utils/Logger"; -import type { Channel, CustomEmoji, Message } from "@vencord/discord-types"; import { MessageStore } from "@webpack/common"; +import { CustomEmoji } from "@webpack/types"; +import type { Channel, Message } from "discord-types/general"; import type { Promisable } from "type-fest"; const MessageEventsLogger = new Logger("MessageEvents", "#e5c890"); diff --git a/src/api/MessagePopover.tsx b/src/api/MessagePopover.tsx index c7b2a090..71787954 100644 --- a/src/api/MessagePopover.tsx +++ b/src/api/MessagePopover.tsx @@ -18,7 +18,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Logger } from "@utils/Logger"; -import { Channel, Message } from "@vencord/discord-types"; +import { Channel, Message } from "discord-types/general"; import type { ComponentType, MouseEventHandler } from "react"; const logger = new Logger("MessagePopover"); diff --git a/src/api/MessageUpdater.ts b/src/api/MessageUpdater.ts index 7c4b3d5c..284a2088 100644 --- a/src/api/MessageUpdater.ts +++ b/src/api/MessageUpdater.ts @@ -4,8 +4,9 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import { FluxStore, Message } from "@vencord/discord-types"; import { MessageCache, MessageStore } from "@webpack/common"; +import { FluxStore } from "@webpack/types"; +import { Message } from "discord-types/general"; /** * Update and re-render a message diff --git a/src/api/Notifications/styles.css b/src/api/Notifications/styles.css index 10d3c0cf..ad5c9cbc 100644 --- a/src/api/Notifications/styles.css +++ b/src/api/Notifications/styles.css @@ -3,8 +3,8 @@ all: unset; display: flex; flex-direction: column; - color: var(--text-default); - background-color: var(--background-base-lower-alt); + color: var(--text-normal); + background-color: var(--background-secondary-alt); border-radius: 6px; overflow: hidden; cursor: pointer; @@ -12,7 +12,7 @@ } .visual-refresh .vc-notification-root { - background-color: var(--background-base-low); + background-color: var(--bg-overlay-floating, var(--background-base-low)); } .vc-notification-root:not(.vc-notification-log-wrapper > .vc-notification-root) { diff --git a/src/api/Settings.ts b/src/api/Settings.ts index 5c8965bf..08d2f8ca 100644 --- a/src/api/Settings.ts +++ b/src/api/Settings.ts @@ -268,7 +268,7 @@ type ResolveUseSettings = { [Key in keyof T]: Key extends string ? T[Key] extends Record - // @ts-expect-error "Type instantiation is excessively deep and possibly infinite" + // @ts-ignore "Type instantiation is excessively deep and possibly infinite" ? UseSettings extends string ? `${Key}.${UseSettings}` : never : Key : never; diff --git a/src/components/DonateButton.tsx b/src/components/DonateButton.tsx index 92af9831..ee2f3ed3 100644 --- a/src/components/DonateButton.tsx +++ b/src/components/DonateButton.tsx @@ -16,8 +16,8 @@ * along with this program. If not, see . */ -import { ButtonProps } from "@vencord/discord-types"; import { Button } from "@webpack/common"; +import { ButtonProps } from "@webpack/types"; import { Heart } from "./Heart"; diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx index 7058b5fd..0ca20440 100644 --- a/src/components/ErrorBoundary.tsx +++ b/src/components/ErrorBoundary.tsx @@ -75,15 +75,10 @@ const ErrorBoundary = LazyComponent(() => { logger.error(`${this.props.message || "A component threw an Error"}\n`, error, errorInfo.componentStack); } - get isNoop() { - if (IS_DEV) return false; - return this.props.noop; - } - render() { if (this.state.error === NO_ERROR) return this.props.children; - if (this.isNoop) return null; + if (this.props.noop) return null; if (this.props.fallback) return ( diff --git a/src/components/ErrorCard.css b/src/components/ErrorCard.css index 2eea2f06..5146aa03 100644 --- a/src/components/ErrorCard.css +++ b/src/components/ErrorCard.css @@ -3,9 +3,5 @@ background-color: #e7828430; border: 1px solid #e78284; border-radius: 5px; - color: var(--text-default, white); - - & a:hover { - text-decoration: underline; - } + color: var(--text-normal, white); } diff --git a/src/components/Link.tsx b/src/components/Link.tsx index 2eb7ab00..0f4eb07d 100644 --- a/src/components/Link.tsx +++ b/src/components/Link.tsx @@ -28,9 +28,6 @@ export function Link(props: React.PropsWithChildren) { props.style.pointerEvents = "none"; props["aria-disabled"] = true; } - - props.rel ??= "noreferrer"; - return ( {props.children} diff --git a/src/components/PluginSettings/ContributorModal.tsx b/src/components/PluginSettings/ContributorModal.tsx index 378ee34c..fe0e987c 100644 --- a/src/components/PluginSettings/ContributorModal.tsx +++ b/src/components/PluginSettings/ContributorModal.tsx @@ -14,8 +14,8 @@ import { DevsById } from "@utils/constants"; import { fetchUserProfile } from "@utils/discord"; import { classes, pluralise } from "@utils/misc"; import { ModalContent, ModalRoot, openModal } from "@utils/modal"; -import { User } from "@vencord/discord-types"; import { Forms, showToast, useEffect, useMemo, UserProfileStore, useStateFromStores } from "@webpack/common"; +import { User } from "discord-types/general"; import Plugins from "~plugins"; diff --git a/src/components/PluginSettings/PluginModal.tsx b/src/components/PluginSettings/PluginModal.tsx index ddbcf8b8..7baeba08 100644 --- a/src/components/PluginSettings/PluginModal.tsx +++ b/src/components/PluginSettings/PluginModal.tsx @@ -26,12 +26,12 @@ import { Flex } from "@components/Flex"; import { gitRemote } from "@shared/vencordUserAgent"; import { proxyLazy } from "@utils/lazy"; import { Margins } from "@utils/margins"; -import { isObjectEmpty } from "@utils/misc"; +import { classes, isObjectEmpty } from "@utils/misc"; import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { OptionType, Plugin } from "@utils/types"; -import { User } from "@vencord/discord-types"; import { findByPropsLazy, findComponentByCodeLazy } from "@webpack"; import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common"; +import { User } from "discord-types/general"; import { Constructor } from "type-fest"; import { PluginMeta } from "~plugins"; @@ -212,7 +212,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti const pluginMeta = PluginMeta[plugin.name]; return ( - + {plugin.name} @@ -268,9 +268,9 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti {!!plugin.settingsAboutComponent && ( -
+
- + diff --git a/src/components/PluginSettings/index.tsx b/src/components/PluginSettings/index.tsx index acfb0609..27eb10a3 100644 --- a/src/components/PluginSettings/index.tsx +++ b/src/components/PluginSettings/index.tsx @@ -45,7 +45,7 @@ const { startDependenciesRecursive, startPlugin, stopPlugin } = proxyLazy(() => const cl = classNameFactory("vc-plugins-"); const logger = new Logger("PluginSettings", "#a6d189"); -const InputStyles = findByPropsLazy("inputWrapper", "inputError", "error"); +const InputStyles = findByPropsLazy("inputWrapper", "inputDefault", "error"); const ButtonClasses = findByPropsLazy("button", "disabled", "enabled"); @@ -62,7 +62,7 @@ function showErrorToast(message: string) { function ReloadRequiredCard({ required }: { required: boolean; }) { return ( - + {required ? ( <> Restart required! @@ -349,7 +349,7 @@ export default function PluginSettings() { select={onStatusChange} isSelected={v => v === searchValue.status} closeOnSelect={true} - className={InputStyles.input} + className={InputStyles.inputDefault} />
diff --git a/src/components/PluginSettings/styles.css b/src/components/PluginSettings/styles.css index c3d97051..a4f9aeee 100644 --- a/src/components/PluginSettings/styles.css +++ b/src/components/PluginSettings/styles.css @@ -66,6 +66,13 @@ gap: 0.25em; } +.vc-plugins-restart-card { + padding: 1em; + background: var(--info-warning-background); + border: 1px solid var(--info-warning-foreground); + color: var(--info-warning-text); +} + .vc-plugins-restart-button { margin-top: 0.5em; background: var(--info-warning-foreground) !important; diff --git a/src/components/VencordSettings/CloudTab.tsx b/src/components/VencordSettings/CloudTab.tsx index 809d4062..a13c3f6c 100644 --- a/src/components/VencordSettings/CloudTab.tsx +++ b/src/components/VencordSettings/CloudTab.tsx @@ -21,7 +21,7 @@ import { Settings, useSettings } from "@api/Settings"; import { CheckedTextInput } from "@components/CheckedTextInput"; import { Grid } from "@components/Grid"; import { Link } from "@components/Link"; -import { authorizeCloud, checkCloudUrlCsp, cloudLogger, deauthorizeCloud, getCloudAuth, getCloudUrl } from "@utils/cloud"; +import { authorizeCloud, cloudLogger, deauthorizeCloud, getCloudAuth, getCloudUrl } from "@utils/cloud"; import { Margins } from "@utils/margins"; import { deleteCloudSettings, getCloudSettings, putCloudSettings } from "@utils/settingsSync"; import { Alerts, Button, Forms, Switch, Tooltip } from "@webpack/common"; @@ -38,8 +38,6 @@ function validateUrl(url: string) { } async function eraseAllData() { - if (!await checkCloudUrlCsp()) return; - const res = await fetch(new URL("/v1/", getCloudUrl()), { method: "DELETE", headers: { Authorization: await getCloudAuth() } diff --git a/src/components/VencordSettings/PatchHelperTab.tsx b/src/components/VencordSettings/PatchHelperTab.tsx index 83364d19..55822069 100644 --- a/src/components/VencordSettings/PatchHelperTab.tsx +++ b/src/components/VencordSettings/PatchHelperTab.tsx @@ -148,7 +148,7 @@ function ReplacementComponent({ module, match, replacement, setReplacementError )} {compileResult && - + {compileResult[1]} } @@ -194,7 +194,7 @@ function ReplacementInput({ replacement, setReplacement, replacementError }) { error={error ?? replacementError} /> {!isFunc && ( -
+
Cheat Sheet {Object.entries({ "\\i": "Special regex escape sequence that matches identifiers (varnames, classnames, etc.)", diff --git a/src/components/VencordSettings/ThemesTab.tsx b/src/components/VencordSettings/ThemesTab.tsx index 6d41ab86..f718ab11 100644 --- a/src/components/VencordSettings/ThemesTab.tsx +++ b/src/components/VencordSettings/ThemesTab.tsx @@ -18,21 +18,17 @@ import { Settings, useSettings } from "@api/Settings"; import { classNameFactory } from "@api/Styles"; -import { ErrorCard } from "@components/ErrorCard"; import { Flex } from "@components/Flex"; import { DeleteIcon, FolderIcon, PaintbrushIcon, PencilIcon, PlusIcon, RestartIcon } from "@components/Icons"; import { Link } from "@components/Link"; import { openPluginModal } from "@components/PluginSettings/PluginModal"; import type { UserThemeHeader } from "@main/themes"; -import { CspBlockedUrls, useCspErrors } from "@utils/cspViolations"; import { openInviteModal } from "@utils/discord"; import { Margins } from "@utils/margins"; -import { classes } from "@utils/misc"; -import { relaunch } from "@utils/native"; -import { useForceUpdater } from "@utils/react"; -import { getStylusWebStoreUrl } from "@utils/web"; +import { showItemInFolder } from "@utils/native"; +import { useAwaiter } from "@utils/react"; import { findLazy } from "@webpack"; -import { Alerts, Button, Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common"; +import { Card, Forms, React, showToast, TabBar, TextArea, useEffect, useRef, useState } from "@webpack/common"; import type { ComponentType, Ref, SyntheticEvent } from "react"; import Plugins from "~plugins"; @@ -52,6 +48,62 @@ const FileInput: FileInput = findLazy(m => m.prototype?.activateUploadDialogue & const cl = classNameFactory("vc-settings-theme-"); +function Validator({ link }: { link: string; }) { + const [res, err, pending] = useAwaiter(() => fetch(link).then(res => { + if (res.status > 300) throw `${res.status} ${res.statusText}`; + const contentType = res.headers.get("Content-Type"); + if (!contentType?.startsWith("text/css") && !contentType?.startsWith("text/plain")) + throw "Not a CSS file. Remember to use the raw link!"; + + return "Okay!"; + })); + + const text = pending + ? "Checking..." + : err + ? `Error: ${err instanceof Error ? err.message : String(err)}` + : "Valid!"; + + return {text}; +} + +function Validators({ themeLinks }: { themeLinks: string[]; }) { + if (!themeLinks.length) return null; + + return ( + <> + Validator + This section will tell you whether your themes can successfully be loaded +
+ {themeLinks.map(rawLink => { + const { label, link } = (() => { + const match = /^@(light|dark) (.*)/.exec(rawLink); + if (!match) return { label: rawLink, link: rawLink }; + + const [, mode, link] = match; + return { label: `[${mode} mode only] ${link}`, link }; + })(); + + return + + {label} + + + ; + })} +
+ + ); +} + interface ThemeCardProps { theme: UserThemeHeader; enabled: boolean; @@ -107,6 +159,7 @@ function ThemesTab() { const [currentTab, setCurrentTab] = useState(ThemeTab.LOCAL); const [themeText, setThemeText] = useState(settings.themeLinks.join("\n")); const [userThemes, setUserThemes] = useState(null); + const [themeDir, , themeDirPending] = useAwaiter(VencordNative.themes.getThemesDir); useEffect(() => { refreshLocalThemes(); @@ -166,12 +219,6 @@ function ThemesTab() { If using the BD site, click on "Download" and place the downloaded .theme.css file into your themes folder. - - External Resources - For security reasons, loading resources (styles, fonts, images, ...) from most sites is blocked. - Make sure all your assets are hosted on GitHub, GitLab, Codeberg, Imgur, Discord or Google Fonts. - - <> @@ -194,7 +241,8 @@ function ThemesTab() { ) : ( VencordNative.themes.openFolder()} + action={() => showItemInFolder(themeDir!)} + disabled={themeDirPending} Icon={FolderIcon} /> )} @@ -253,13 +301,7 @@ function ThemesTab() { function renderOnlineThemes() { return ( <> - - - This section is for advanced users. If you are having difficulties using it, use the - Local Themes tab instead. - - - + Paste links to css files here One link per line You can prefix lines with @light or @dark to toggle them based on your Discord theme @@ -271,11 +313,12 @@ function ThemesTab() { value={themeText} onChange={setThemeText} className={"vc-settings-theme-links"} - placeholder="Enter Theme Links..." + placeholder="Theme Links" spellCheck={false} onBlur={onBlur} rows={10} /> + ); @@ -304,99 +347,10 @@ function ThemesTab() { - {currentTab === ThemeTab.LOCAL && renderLocalThemes()} {currentTab === ThemeTab.ONLINE && renderOnlineThemes()} ); } -export function CspErrorCard() { - if (IS_WEB) return null; - - const errors = useCspErrors(); - const forceUpdate = useForceUpdater(); - - if (!errors.length) return null; - - const isImgurHtmlDomain = (url: string) => url.startsWith("https://imgur.com/"); - - const allowUrl = async (url: string) => { - const { origin: baseUrl, host } = new URL(url); - - const result = await VencordNative.csp.requestAddOverride(baseUrl, ["connect-src", "img-src", "style-src", "font-src"], "Vencord Themes"); - if (result !== "ok") return; - - CspBlockedUrls.forEach(url => { - if (new URL(url).host === host) { - CspBlockedUrls.delete(url); - } - }); - - forceUpdate(); - - Alerts.show({ - title: "Restart Required", - body: "A restart is required to apply this change", - confirmText: "Restart now", - cancelText: "Later!", - onConfirm: relaunch - }); - }; - - const hasImgurHtmlDomain = errors.some(isImgurHtmlDomain); - - return ( - - Blocked Resources - Some images, styles, or fonts were blocked because they come from disallowed domains. - It is highly recommended to move them to GitHub or Imgur. But you may also allow domains if you fully trust them. - - After allowing a domain, you have to fully close (from tray / task manager) and restart {IS_DISCORD_DESKTOP ? "Discord" : "Vesktop"} to apply the change. - - - Blocked URLs -
- {errors.map((url, i) => ( -
- {i !== 0 && } -
- {url} - -
-
- ))} -
- - {hasImgurHtmlDomain && ( - <> - - - Imgur links should be direct links in the form of https://i.imgur.com/... - - To obtain a direct link, right-click the image and select "Copy image address". - - )} -
- ); -} - -function UserscriptThemesTab() { - return ( - - - Themes are not supported on the Userscript! - - - You can instead install themes with the Stylus extension! - - - - ); -} - -export default IS_USERSCRIPT - ? wrapTab(UserscriptThemesTab, "Themes") - : wrapTab(ThemesTab, "Themes"); +export default wrapTab(ThemesTab, "Themes"); diff --git a/src/components/VencordSettings/UpdaterTab.tsx b/src/components/VencordSettings/UpdaterTab.tsx index f5e3d4b2..e29d7dfd 100644 --- a/src/components/VencordSettings/UpdaterTab.tsx +++ b/src/components/VencordSettings/UpdaterTab.tsx @@ -94,7 +94,7 @@ function Changes({ updates, repo, repoPending }: CommonProps & { updates: typeof {message} - {author}
))} @@ -225,7 +225,7 @@ function Updater() { Repo - + {repoPending ? repo : err diff --git a/src/components/VencordSettings/VencordTab.tsx b/src/components/VencordSettings/VencordTab.tsx index 047ba17d..54da5a3f 100644 --- a/src/components/VencordSettings/VencordTab.tsx +++ b/src/components/VencordSettings/VencordTab.tsx @@ -26,7 +26,8 @@ import { gitRemote } from "@shared/vencordUserAgent"; import { DONOR_ROLE_ID, VENCORD_GUILD_ID } from "@utils/constants"; import { Margins } from "@utils/margins"; import { identity, isPluginDev } from "@utils/misc"; -import { relaunch } from "@utils/native"; +import { relaunch, showItemInFolder } from "@utils/native"; +import { useAwaiter } from "@utils/react"; import { Button, Forms, GuildMemberStore, React, Select, Switch, UserStore } from "@webpack/common"; import BadgeAPI from "../../plugins/_api/badges"; @@ -52,6 +53,9 @@ type KeysOfType = { }[keyof Object]; function VencordSettings() { + const [settingsDir, , settingsDirPending] = useAwaiter(VencordNative.settings.getSettingsDir, { + fallbackValue: "Loading..." + }); const settings = useSettings(); const donateImage = React.useMemo(() => Math.random() > 0.5 ? DEFAULT_DONATE_IMAGE : SHIGGY_DONATE_IMAGE, []); @@ -167,7 +171,7 @@ function VencordSettings() { VencordNative.settings.openFolder()} + action={() => showItemInFolder(settingsDir)} /> )} ; - -export const ConnectSrc = ["connect-src"]; -export const ImageSrc = [...ConnectSrc, "img-src"]; -export const CssSrc = ["style-src", "font-src"]; -export const ImageAndCssSrc = [...ImageSrc, ...CssSrc]; -export const ImageScriptsAndCssSrc = [...ImageAndCssSrc, "script-src", "worker-src"]; - -// Plugins can whitelist their own domains by importing this object in their native.ts -// script and just adding to it. But generally, you should just edit this file instead - -export const CspPolicies: PolicyMap = { - "http://localhost:*": ImageAndCssSrc, - "http://127.0.0.1:*": ImageAndCssSrc, - "localhost:*": ImageAndCssSrc, - "127.0.0.1:*": ImageAndCssSrc, - - "*.github.io": ImageAndCssSrc, // GitHub pages, used by most themes - "github.com": ImageAndCssSrc, // GitHub content (stuff uploaded to markdown forms), used by most themes - "raw.githubusercontent.com": ImageAndCssSrc, // GitHub raw, used by some themes - "*.gitlab.io": ImageAndCssSrc, // GitLab pages, used by some themes - "gitlab.com": ImageAndCssSrc, // GitLab raw, used by some themes - "*.codeberg.page": ImageAndCssSrc, // Codeberg pages, used by some themes - "codeberg.org": ImageAndCssSrc, // Codeberg raw, used by some themes - - "*.githack.com": ImageAndCssSrc, // githack (namely raw.githack.com), used by some themes - "jsdelivr.net": ImageAndCssSrc, // jsDelivr, used by very few themes - - "fonts.googleapis.com": CssSrc, // Google Fonts, used by many themes - - "i.imgur.com": ImageSrc, // Imgur, used by some themes - "i.ibb.co": ImageSrc, // ImgBB, used by some themes - "i.pinimg.com": ImageSrc, // Pinterest, used by some themes - "*.tenor.com": ImageSrc, // Tenor, used by some themes - "files.catbox.moe": ImageAndCssSrc, // Catbox, used by some themes - - "cdn.discordapp.com": ImageAndCssSrc, // Discord CDN, used by Vencord and some themes to load media - "media.discordapp.net": ImageSrc, // Discord media CDN, possible alternative to Discord CDN - - // CDNs used for some things by Vencord. - // FIXME: we really should not be using CDNs anymore - "cdnjs.cloudflare.com": ImageScriptsAndCssSrc, - "cdn.jsdelivr.net": ImageScriptsAndCssSrc, - - // Function Specific - "api.github.com": ConnectSrc, // used for updating Vencord itself - "ws.audioscrobbler.com": ConnectSrc, // Last.fm API - "translate-pa.googleapis.com": ConnectSrc, // Google Translate API - "*.vencord.dev": ImageSrc, // VenCloud (api.vencord.dev) and Badges (badges.vencord.dev) - "manti.vendicated.dev": ImageSrc, // ReviewDB API - "decor.fieryflames.dev": ConnectSrc, // Decor API - "ugc.decor.fieryflames.dev": ImageSrc, // Decor CDN - "sponsor.ajay.app": ConnectSrc, // Dearrow API - "dearrow-thumb.ajay.app": ImageSrc, // Dearrow Thumbnail CDN - "usrbg.is-hardly.online": ImageSrc, // USRBG API - "icons.duckduckgo.com": ImageSrc, // DuckDuckGo Favicon API (Reverse Image Search) - - // forked addition - "*.dorkbutt.lol": ImageAndCssSrc, -}; - -const findHeader = (headers: PolicyMap, headerName: Lowercase) => { - return Object.keys(headers).find(h => h.toLowerCase() === headerName); -}; - -const parsePolicy = (policy: string): PolicyMap => { - const result: PolicyMap = {}; - policy.split(";").forEach(directive => { - const [directiveKey, ...directiveValue] = directive.trim().split(/\s+/g); - if (directiveKey && !Object.prototype.hasOwnProperty.call(result, directiveKey)) { - result[directiveKey] = directiveValue; - } - }); - - return result; -}; - -const stringifyPolicy = (policy: PolicyMap): string => - Object.entries(policy) - .filter(([, values]) => values?.length) - .map(directive => directive.flat().join(" ")) - .join("; "); - - -const patchCsp = (headers: PolicyMap) => { - const reportOnlyHeader = findHeader(headers, "content-security-policy-report-only"); - if (reportOnlyHeader) - delete headers[reportOnlyHeader]; - - const header = findHeader(headers, "content-security-policy"); - - if (header) { - const csp = parsePolicy(headers[header][0]); - - const pushDirective = (directive: string, ...values: string[]) => { - csp[directive] ??= [...(csp["default-src"] ?? [])]; - csp[directive].push(...values); - }; - - pushDirective("style-src", "'unsafe-inline'"); - // we could make unsafe-inline safe by using strict-dynamic with a random nonce on our Vencord loader script https://content-security-policy.com/strict-dynamic/ - // HOWEVER, at the time of writing (24 Jan 2025), Discord is INSANE and also uses unsafe-inline - // Once they stop using it, we also should - pushDirective("script-src", "'unsafe-inline'", "'unsafe-eval'"); - - for (const directive of ["style-src", "connect-src", "img-src", "font-src", "media-src", "worker-src"]) { - pushDirective(directive, "blob:", "data:", "vencord:"); - } - - for (const [host, directives] of Object.entries(NativeSettings.store.customCspRules)) { - for (const directive of directives) { - pushDirective(directive, host); - } - } - - for (const [host, directives] of Object.entries(CspPolicies)) { - for (const directive of directives) { - pushDirective(directive, host); - } - } - - headers[header] = [stringifyPolicy(csp)]; - } -}; - -export function initCsp() { - session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders, resourceType }, cb) => { - if (responseHeaders) { - if (resourceType === "mainFrame") - patchCsp(responseHeaders); - - // Fix hosts that don't properly set the css content type, such as - // raw.githubusercontent.com - if (resourceType === "stylesheet") { - const header = findHeader(responseHeaders, "content-type"); - if (header) - responseHeaders[header] = ["text/css"]; - } - } - - cb({ cancel: false, responseHeaders }); - }); - - // assign a noop to onHeadersReceived to prevent other mods from adding their own incompatible ones. - // For instance, OpenAsar adds their own that doesn't fix content-type for stylesheets which makes it - // impossible to load css from github raw despite our fix above - session.defaultSession.webRequest.onHeadersReceived = () => { }; -} diff --git a/src/main/csp/manager.ts b/src/main/csp/manager.ts deleted file mode 100644 index e6b1a0e3..00000000 --- a/src/main/csp/manager.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2025 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { NativeSettings } from "@main/settings"; -import { IpcEvents } from "@shared/IpcEvents"; -import { dialog, ipcMain, IpcMainInvokeEvent } from "electron"; - -import { CspPolicies, ImageAndCssSrc } from "."; - -export type CspRequestResult = "invalid" | "cancelled" | "unchecked" | "ok" | "conflict"; - -export function registerCspIpcHandlers() { - ipcMain.handle(IpcEvents.CSP_REMOVE_OVERRIDE, removeCspRule); - ipcMain.handle(IpcEvents.CSP_REQUEST_ADD_OVERRIDE, addCspRule); - ipcMain.handle(IpcEvents.CSP_IS_DOMAIN_ALLOWED, isDomainAllowed); -} - -function validate(url: string, directives: string[]) { - try { - const { host } = new URL(url); - - if (/[;'"\\]/.test(host)) return false; - } catch { - return false; - } - - if (directives.length === 0) return false; - if (directives.some(d => !ImageAndCssSrc.includes(d))) return false; - - return true; -} - -function getMessage(url: string, directives: string[], callerName: string) { - const domain = new URL(url).host; - - const message = `${callerName} wants to allow connections to ${domain}`; - - let detail = - `Unless you recognise and fully trust ${domain}, you should cancel this request!\n\n` + - `You will have to fully close and restart ${IS_DISCORD_DESKTOP ? "Discord" : "Vesktop"} for the changes to take effect.`; - - if (directives.length === 1 && directives[0] === "connect-src") { - return { message, detail }; - } - - const contentTypes = directives - .filter(type => type !== "connect-src") - .map(type => { - switch (type) { - case "img-src": - return "Images"; - case "style-src": - return "CSS & Themes"; - case "font-src": - return "Fonts"; - default: - throw new Error(`Illegal CSP directive: ${type}`); - } - }) - .sort() - .join(", "); - - detail = `The following types of content will be allowed to load from ${domain}:\n${contentTypes}\n\n${detail}`; - - return { message, detail }; -} - -async function addCspRule(_: IpcMainInvokeEvent, url: string, directives: string[], callerName: string): Promise { - if (!validate(url, directives)) { - return "invalid"; - } - - const domain = new URL(url).host; - - if (domain in NativeSettings.store.customCspRules) { - return "conflict"; - } - - const { checkboxChecked, response } = await dialog.showMessageBox({ - ...getMessage(url, directives, callerName), - type: callerName ? "info" : "warning", - title: "Vencord Host Permissions", - buttons: ["Cancel", "Allow"], - defaultId: 0, - cancelId: 0, - checkboxLabel: `I fully trust ${domain} and understand the risks of allowing connections to it.`, - checkboxChecked: false, - }); - - if (response !== 1) { - return "cancelled"; - } - - if (!checkboxChecked) { - return "unchecked"; - } - - NativeSettings.store.customCspRules[domain] = directives; - return "ok"; -} - -function removeCspRule(_: IpcMainInvokeEvent, domain: string) { - if (domain in NativeSettings.store.customCspRules) { - delete NativeSettings.store.customCspRules[domain]; - return true; - } - - return false; -} - -function isDomainAllowed(_: IpcMainInvokeEvent, url: string, directives: string[]) { - try { - const domain = new URL(url).host; - - const ruleForDomain = CspPolicies[domain] ?? NativeSettings.store.customCspRules[domain]; - if (!ruleForDomain) return false; - - return directives.every(d => ruleForDomain.includes(d)); - } catch (e) { - return false; - } -} diff --git a/src/main/index.ts b/src/main/index.ts index 95301ff7..4cc2e0db 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -16,11 +16,9 @@ * along with this program. If not, see . */ -import { app, net, protocol } from "electron"; +import { app, protocol, session } from "electron"; import { join } from "path"; -import { pathToFileURL } from "url"; -import { initCsp } from "./csp"; import { ensureSafePath } from "./ipcMain"; import { RendererSettings } from "./settings"; import { IS_VANILLA, THEMES_DIR } from "./utils/constants"; @@ -28,27 +26,21 @@ import { installExt } from "./utils/extensions"; if (IS_VESKTOP || !IS_VANILLA) { app.whenReady().then(() => { - protocol.handle("vencord", ({ url: unsafeUrl }) => { - let url = decodeURI(unsafeUrl).slice("vencord://".length).replace(/\?v=\d+$/, ""); - + // Source Maps! Maybe there's a better way but since the renderer is executed + // from a string I don't think any other form of sourcemaps would work + protocol.registerFileProtocol("vencord", ({ url: unsafeUrl }, cb) => { + let url = unsafeUrl.slice("vencord://".length); if (url.endsWith("/")) url = url.slice(0, -1); - if (url.startsWith("/themes/")) { const theme = url.slice("/themes/".length); - const safeUrl = ensureSafePath(THEMES_DIR, theme); if (!safeUrl) { - return new Response(null, { - status: 404 - }); + cb({ statusCode: 403 }); + return; } - - return net.fetch(pathToFileURL(safeUrl).toString()); + cb(safeUrl.replace(/\?v=\d+$/, "")); + return; } - - // Source Maps! Maybe there's a better way but since the renderer is executed - // from a string I don't think any other form of sourcemaps would work - switch (url) { case "renderer.js.map": case "vencordDesktopRenderer.js.map": @@ -56,11 +48,10 @@ if (IS_VESKTOP || !IS_VANILLA) { case "vencordDesktopPreload.js.map": case "patcher.js.map": case "vencordDesktopMain.js.map": - return net.fetch(pathToFileURL(join(__dirname, url)).toString()); + cb(join(__dirname, url)); + break; default: - return new Response(null, { - status: 404 - }); + cb({ statusCode: 403 }); } }); @@ -72,7 +63,70 @@ if (IS_VESKTOP || !IS_VANILLA) { } catch { } - initCsp(); + const findHeader = (headers: Record, headerName: Lowercase) => { + return Object.keys(headers).find(h => h.toLowerCase() === headerName); + }; + + // Remove CSP + type PolicyResult = Record; + + const parsePolicy = (policy: string): PolicyResult => { + const result: PolicyResult = {}; + policy.split(";").forEach(directive => { + const [directiveKey, ...directiveValue] = directive.trim().split(/\s+/g); + if (directiveKey && !Object.prototype.hasOwnProperty.call(result, directiveKey)) { + result[directiveKey] = directiveValue; + } + }); + + return result; + }; + const stringifyPolicy = (policy: PolicyResult): string => + Object.entries(policy) + .filter(([, values]) => values?.length) + .map(directive => directive.flat().join(" ")) + .join("; "); + + const patchCsp = (headers: Record) => { + const header = findHeader(headers, "content-security-policy"); + + if (header) { + const csp = parsePolicy(headers[header][0]); + + for (const directive of ["style-src", "connect-src", "img-src", "font-src", "media-src", "worker-src"]) { + csp[directive] ??= []; + csp[directive].push("*", "blob:", "data:", "vencord:", "'unsafe-inline'"); + } + + // TODO: Restrict this to only imported packages with fixed version. + // Perhaps auto generate with esbuild + csp["script-src"] ??= []; + csp["script-src"].push("'unsafe-eval'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com"); + headers[header] = [stringifyPolicy(csp)]; + } + }; + + session.defaultSession.webRequest.onHeadersReceived(({ responseHeaders, resourceType }, cb) => { + if (responseHeaders) { + if (resourceType === "mainFrame") + patchCsp(responseHeaders); + + // Fix hosts that don't properly set the css content type, such as + // raw.githubusercontent.com + if (resourceType === "stylesheet") { + const header = findHeader(responseHeaders, "content-type"); + if (header) + responseHeaders[header] = ["text/css"]; + } + } + + cb({ cancel: false, responseHeaders }); + }); + + // assign a noop to onHeadersReceived to prevent other mods from adding their own incompatible ones. + // For instance, OpenAsar adds their own that doesn't fix content-type for stylesheets which makes it + // impossible to load css from github raw despite our fix above + session.defaultSession.webRequest.onHeadersReceived = () => { }; }); } diff --git a/src/main/ipcMain.ts b/src/main/ipcMain.ts index 6990cea9..62785867 100644 --- a/src/main/ipcMain.ts +++ b/src/main/ipcMain.ts @@ -28,17 +28,14 @@ import { FSWatcher, mkdirSync, watch, writeFileSync } from "fs"; import { open, readdir, readFile } from "fs/promises"; import { join, normalize } from "path"; -import { registerCspIpcHandlers } from "./csp/manager"; import { getThemeInfo, stripBOM, UserThemeHeader } from "./themes"; -import { ALLOWED_PROTOCOLS, QUICKCSS_PATH, SETTINGS_DIR, THEMES_DIR } from "./utils/constants"; +import { ALLOWED_PROTOCOLS, QUICKCSS_PATH, THEMES_DIR } from "./utils/constants"; import { makeLinksOpenExternally } from "./utils/externalLinks"; mkdirSync(THEMES_DIR, { recursive: true }); -registerCspIpcHandlers(); - export function ensureSafePath(basePath: string, path: string) { - const normalizedBasePath = normalize(basePath + "/"); + const normalizedBasePath = normalize(basePath); const newPath = join(basePath, path); const normalizedPath = normalize(newPath); return normalizedPath.startsWith(normalizedBasePath) ? normalizedPath : null; @@ -92,6 +89,7 @@ ipcMain.handle(IpcEvents.SET_QUICK_CSS, (_, css) => writeFileSync(QUICKCSS_PATH, css) ); +ipcMain.handle(IpcEvents.GET_THEMES_DIR, () => THEMES_DIR); ipcMain.handle(IpcEvents.GET_THEMES_LIST, () => listThemes()); ipcMain.handle(IpcEvents.GET_THEME_DATA, (_, fileName) => getThemeData(fileName)); ipcMain.handle(IpcEvents.GET_THEME_SYSTEM_VALUES, () => ({ @@ -99,8 +97,6 @@ ipcMain.handle(IpcEvents.GET_THEME_SYSTEM_VALUES, () => ({ "os-accent-color": `#${systemPreferences.getAccentColor?.() || ""}` })); -ipcMain.handle(IpcEvents.OPEN_THEMES_FOLDER, () => shell.openPath(THEMES_DIR)); -ipcMain.handle(IpcEvents.OPEN_SETTINGS_FOLDER, () => shell.openPath(SETTINGS_DIR)); export function initIpc(mainWindow: BrowserWindow) { let quickCssWatcher: FSWatcher | undefined; diff --git a/src/main/patcher.ts b/src/main/patcher.ts index 8868caa7..60b169af 100644 --- a/src/main/patcher.ts +++ b/src/main/patcher.ts @@ -38,7 +38,7 @@ const asarPath = join(dirname(injectorPath), "..", asarName); const discordPkg = require(join(asarPath, "package.json")); require.main!.filename = join(asarPath, discordPkg.main); -// @ts-expect-error Untyped method? Dies from cringe +// @ts-ignore Untyped method? Dies from cringe app.setAppPath(asarPath); if (!IS_VANILLA) { diff --git a/src/main/settings.ts b/src/main/settings.ts index 962bbaa7..3d367a94 100644 --- a/src/main/settings.ts +++ b/src/main/settings.ts @@ -36,6 +36,7 @@ RendererSettings.addGlobalChangeListener(() => { } }); +ipcMain.handle(IpcEvents.GET_SETTINGS_DIR, () => SETTINGS_DIR); ipcMain.on(IpcEvents.GET_SETTINGS, e => e.returnValue = RendererSettings.plain); ipcMain.handle(IpcEvents.SET_SETTINGS, (_, data: Settings, pathToNotify?: string) => { @@ -48,18 +49,16 @@ export interface NativeSettings { [setting: string]: any; }; }; - customCspRules: Record; } const DefaultNativeSettings: NativeSettings = { - plugins: {}, - customCspRules: {} + plugins: {} }; const nativeSettings = readSettings("native", NATIVE_SETTINGS_FILE); mergeDefaults(nativeSettings, DefaultNativeSettings); -export const NativeSettings = new SettingsStore(nativeSettings as NativeSettings); +export const NativeSettings = new SettingsStore(nativeSettings); NativeSettings.addGlobalChangeListener(() => { try { diff --git a/src/main/updater/common.ts b/src/main/updater/common.ts index 1a0b8da9..41b9837c 100644 --- a/src/main/updater/common.ts +++ b/src/main/updater/common.ts @@ -35,10 +35,7 @@ export function serializeErrors(func: (...args: any[]) => any) { ok: false, error: e instanceof Error ? { // prototypes get lost, so turn error into plain object - ...e, - message: e.message, - name: e.name, - stack: e.stack + ...e } : e }; } diff --git a/src/main/updater/http.ts b/src/main/updater/http.ts index a112dde3..9d42b5c6 100644 --- a/src/main/updater/http.ts +++ b/src/main/updater/http.ts @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { fetchBuffer, fetchJson } from "@main/utils/http"; +import { get } from "@main/utils/simpleGet"; import { IpcEvents } from "@shared/IpcEvents"; import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent"; import { ipcMain } from "electron"; @@ -31,8 +31,8 @@ import { serializeErrors, VENCORD_FILES } from "./common"; const API_BASE = `https://api.github.com/repos/${gitRemote}`; let PendingUpdates = [] as [string, string][]; -async function githubGet(endpoint: string) { - return fetchJson(API_BASE + endpoint, { +async function githubGet(endpoint: string) { + return get(API_BASE + endpoint, { headers: { Accept: "application/vnd.github+json", // "All API requests MUST include a valid User-Agent header. @@ -46,8 +46,9 @@ async function calculateGitChanges() { const isOutdated = await fetchUpdates(); if (!isOutdated) return []; - const data = await githubGet(`/compare/${gitHash}...HEAD`); + const res = await githubGet(`/compare/${gitHash}...HEAD`); + const data = JSON.parse(res.toString("utf-8")); return data.commits.map((c: any) => ({ // github api only sends the long sha hash: c.sha.slice(0, 7), @@ -57,8 +58,9 @@ async function calculateGitChanges() { } async function fetchUpdates() { - const data = await githubGet("/releases/latest"); + const release = await githubGet("/releases/latest"); + const data = JSON.parse(release.toString()); const hash = data.name.slice(data.name.lastIndexOf(" ") + 1); if (hash === gitHash) return false; @@ -68,20 +70,16 @@ async function fetchUpdates() { PendingUpdates.push([name, browser_download_url]); } }); - return true; } async function applyUpdates() { - const fileContents = await Promise.all(PendingUpdates.map(async ([name, url]) => { - const contents = await fetchBuffer(url); - return [join(__dirname, name), contents] as const; - })); - - await Promise.all(fileContents.map(async ([filename, contents]) => - writeFile(filename, contents)) - ); - + await Promise.all(PendingUpdates.map( + async ([name, data]) => writeFile( + join(__dirname, name), + await get(data) + ) + )); PendingUpdates = []; return true; } diff --git a/src/main/utils/extensions.ts b/src/main/utils/extensions.ts index 1d7559fb..1323bd37 100644 --- a/src/main/utils/extensions.ts +++ b/src/main/utils/extensions.ts @@ -24,7 +24,7 @@ import { join } from "path"; import { DATA_DIR } from "./constants"; import { crxToZip } from "./crxToZip"; -import { fetchBuffer } from "./http"; +import { get } from "./simpleGet"; const extensionCacheDir = join(DATA_DIR, "ExtensionCache"); @@ -69,14 +69,13 @@ export async function installExt(id: string) { } catch (err) { const url = `https://clients2.google.com/service/update2/crx?response=redirect&acceptformat=crx2,crx3&x=id%3D${id}%26uc&prodversion=${process.versions.chrome}`; - const buf = await fetchBuffer(url, { + const buf = await get(url, { headers: { "User-Agent": `Electron ${process.versions.electron} ~ Vencord (https://github.com/Vendicated/Vencord)` } }); - await extract(crxToZip(buf), extDir) - .catch(err => console.error(`Failed to extract extension ${id}`, err)); + await extract(crxToZip(buf), extDir).catch(console.error); } session.defaultSession.loadExtension(extDir); diff --git a/src/main/utils/http.ts b/src/main/utils/http.ts deleted file mode 100644 index 05dbca40..00000000 --- a/src/main/utils/http.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2022 Vendicated and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -import { createWriteStream } from "original-fs"; -import { Readable } from "stream"; -import { finished } from "stream/promises"; - -type Url = string | URL; - -export async function checkedFetch(url: Url, options?: RequestInit) { - try { - var res = await fetch(url, options); - } catch (err) { - if (err instanceof Error && err.cause) { - err = err.cause; - } - - throw new Error(`${options?.method ?? "GET"} ${url} failed: ${err}`); - } - - if (res.ok) { - return res; - } - - let message = `${options?.method ?? "GET"} ${url}: ${res.status} ${res.statusText}`; - try { - const reason = await res.text(); - message += `\n${reason}`; - } catch { } - - throw new Error(message); -} - -export async function fetchJson(url: Url, options?: RequestInit) { - const res = await checkedFetch(url, options); - return res.json() as Promise; -} - -export async function fetchBuffer(url: Url, options?: RequestInit) { - const res = await checkedFetch(url, options); - const buf = await res.arrayBuffer(); - - return Buffer.from(buf); -} - -export async function downloadToFile(url: Url, path: string, options?: RequestInit) { - const res = await checkedFetch(url, options); - if (!res.body) { - throw new Error(`Download ${url}: response body is empty`); - } - - // @ts-expect-error weird type conflict - const body = Readable.fromWeb(res.body); - await finished(body.pipe(createWriteStream(path))); -} diff --git a/src/main/utils/simpleGet.ts b/src/main/utils/simpleGet.ts new file mode 100644 index 00000000..1a8302c0 --- /dev/null +++ b/src/main/utils/simpleGet.ts @@ -0,0 +1,37 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2022 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +import https from "https"; + +export function get(url: string, options: https.RequestOptions = {}) { + return new Promise((resolve, reject) => { + https.get(url, options, res => { + const { statusCode, statusMessage, headers } = res; + if (statusCode! >= 400) + return void reject(`${statusCode}: ${statusMessage} - ${url}`); + if (statusCode! >= 300) + return void resolve(get(headers.location!, options)); + + const chunks = [] as Buffer[]; + res.on("error", reject); + + res.on("data", chunk => chunks.push(chunk)); + res.once("end", () => resolve(Buffer.concat(chunks))); + }); + }); +} diff --git a/src/plugins/_api/badges/index.tsx b/src/plugins/_api/badges/index.tsx index 8011e331..8745584e 100644 --- a/src/plugins/_api/badges/index.tsx +++ b/src/plugins/_api/badges/index.tsx @@ -30,10 +30,10 @@ import { Margins } from "@utils/margins"; import { shouldShowContributorBadge } from "@utils/misc"; import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal"; import definePlugin from "@utils/types"; -import { User } from "@vencord/discord-types"; import { Forms, Toasts, UserStore } from "@webpack/common"; +import { User } from "discord-types/general"; -const CONTRIBUTOR_BADGE = "https://cdn.discordapp.com/emojis/1092089799109775453.png?size=64"; +const CONTRIBUTOR_BADGE = "https://vencord.dev/assets/favicon.png"; const ContributorBadge: ProfileBadge = { description: "Vencord Contributor", diff --git a/src/plugins/_api/messagePopover.ts b/src/plugins/_api/messagePopover.ts index a49658fb..3d55f62e 100644 --- a/src/plugins/_api/messagePopover.ts +++ b/src/plugins/_api/messagePopover.ts @@ -27,7 +27,7 @@ export default definePlugin({ { find: "#{intl::MESSAGE_UTILITIES_A11Y_LABEL}", replacement: { - match: /(?<=:null),(.{0,40}togglePopout:.+?}\)),(.+?)\]}\):null,(?<=\((\i\.\i),{label:.+?:null,(\i)\?\(0,\i\.jsxs?\)\(\i\.Fragment.+?message:(\i).+?)/, + match: /(?<=:null),(.{0,40}togglePopout:.+?}\)),(.+?)\]}\):null,(?<=\((\i\.\i),{label:.+?:null,(\i&&!\i)\?\(0,\i\.jsxs?\)\(\i\.Fragment.+?message:(\i).+?)/, replace: (_, ReactButton, PotionButton, ButtonComponent, showReactButton, message) => "" + `]}):null,Vencord.Api.MessagePopover._buildPopoverElements(${ButtonComponent},${message}),${showReactButton}?${ReactButton}:null,${showReactButton}&&${PotionButton},` } diff --git a/src/plugins/_core/noTrack.ts b/src/plugins/_core/noTrack.ts index ad1f255b..30920a06 100644 --- a/src/plugins/_core/noTrack.ts +++ b/src/plugins/_core/noTrack.ts @@ -20,7 +20,7 @@ import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import definePlugin, { OptionType, StartAt } from "@utils/types"; -import { WebpackRequire } from "@vencord/discord-types/webpack"; +import { WebpackRequire } from "@webpack/wreq.d"; const settings = definePluginSettings({ disableAnalytics: { diff --git a/src/plugins/_core/settings.tsx b/src/plugins/_core/settings.tsx index 0eb8e13c..a9e34f78 100644 --- a/src/plugins/_core/settings.tsx +++ b/src/plugins/_core/settings.tsx @@ -213,7 +213,7 @@ export default definePlugin({ get chromiumVersion() { try { return VencordNative.native.getVersions().chrome - // @ts-expect-error Typescript will add userAgentData IMMEDIATELY + // @ts-ignore Typescript will add userAgentData IMMEDIATELY || navigator.userAgentData?.brands?.find(b => b.brand === "Chromium" || b.brand === "Google Chrome")?.version || null; } catch { // inb4 some stupid browser throws unsupported error for navigator.userAgentData, it's only in chromium diff --git a/src/plugins/_core/supportHelper.tsx b/src/plugins/_core/supportHelper.tsx index 82e09b88..825bbc20 100644 --- a/src/plugins/_core/supportHelper.tsx +++ b/src/plugins/_core/supportHelper.tsx @@ -32,8 +32,8 @@ import { onlyOnce } from "@utils/onlyOnce"; import { makeCodeblock } from "@utils/text"; import definePlugin from "@utils/types"; import { checkForUpdates, isOutdated, update } from "@utils/updater"; -import { Channel } from "@vencord/discord-types"; import { Alerts, Button, Card, ChannelStore, Forms, GuildMemberStore, Parser, PermissionsBits, PermissionStore, RelationshipStore, showToast, Text, Toasts, UserStore } from "@webpack/common"; +import { Channel } from "discord-types/general"; import { JSX } from "react"; import gitHash from "~git-hash"; @@ -196,6 +196,7 @@ export default definePlugin({ } } + // @ts-ignore outdated type const roles = GuildMemberStore.getSelfMember(VENCORD_GUILD_ID)?.roles; if (!roles || TrustedRolesIds.some(id => roles.includes(id))) return; @@ -318,7 +319,7 @@ export default definePlugin({ if (RelationshipStore.isFriend(userId) || isPluginDev(UserStore.getCurrentUser()?.id)) return null; return ( - + Please do not private message Vencord plugin developers for support!
Instead, use the Vencord support channel: {Parser.parse("https://discord.com/channels/1015060230222131221/1026515880080842772")} diff --git a/src/plugins/accountPanelServerProfile/index.tsx b/src/plugins/accountPanelServerProfile/index.tsx index ce9f6b51..f871b8ee 100644 --- a/src/plugins/accountPanelServerProfile/index.tsx +++ b/src/plugins/accountPanelServerProfile/index.tsx @@ -9,9 +9,9 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import { getCurrentChannel } from "@utils/discord"; import definePlugin, { OptionType } from "@utils/types"; -import { User } from "@vencord/discord-types"; import { findComponentByCodeLazy } from "@webpack"; import { ContextMenuApi, Menu, useEffect, useRef } from "@webpack/common"; +import { User } from "discord-types/general"; interface UserProfileProps { popoutProps: Record; diff --git a/src/plugins/anonymiseFileNames/index.tsx b/src/plugins/anonymiseFileNames/index.tsx index 8237be8b..d24de222 100644 --- a/src/plugins/anonymiseFileNames/index.tsx +++ b/src/plugins/anonymiseFileNames/index.tsx @@ -75,7 +75,11 @@ export default definePlugin({ find: "async uploadFiles(", replacement: [ { - match: /async uploadFiles\((\i)\){/, + match: /async uploadFiles\((\i),\i\){/, + replace: "$&$1.forEach($self.anonymise);" + }, + { + match: /async uploadFilesSimple\((\i)\){/, replace: "$&$1.forEach($self.anonymise);" } ], diff --git a/src/plugins/appleMusic.desktop/native.ts b/src/plugins/appleMusic.desktop/native.ts index c7dd40d2..5a547997 100644 --- a/src/plugins/appleMusic.desktop/native.ts +++ b/src/plugins/appleMusic.desktop/native.ts @@ -27,7 +27,7 @@ interface RemoteData { let cachedRemoteData: { id: string, data: RemoteData; } | { id: string, failures: number; } | null = null; const APPLE_MUSIC_BUNDLE_REGEX = /