diff --git a/api/src/index.ts b/api/src/index.ts
index 0bba7f5..fe59310 100644
--- a/api/src/index.ts
+++ b/api/src/index.ts
@@ -5,7 +5,6 @@
export * from "./schema/Guild";
export * from "./schema/Invite";
export * from "./schema/Message";
-export * from "./util/Constants";
export * from "./util/instanceOf";
export * from "./util/instanceOf";
export * from "./util/RandomInviteID";
diff --git a/api/src/middlewares/ErrorHandler.ts b/api/src/middlewares/ErrorHandler.ts
index 179c599..be2586c 100644
--- a/api/src/middlewares/ErrorHandler.ts
+++ b/api/src/middlewares/ErrorHandler.ts
@@ -2,9 +2,8 @@
import { HTTPError } from "lambert-server";
import { EntityNotFoundError } from "typeorm";
import { FieldError } from "../util/instanceOf";
-import { ApiError } from "../util/ApiError";
+import { ApiError } from "@fosscord/util";
-// TODO: update with new body/typorm validation
export function ErrorHandler(error: Error, req: Request, res: Response, next: NextFunction) {
if (!error) return next();
@@ -20,7 +19,7 @@
message = error.message;
httpcode = error.httpStatus;
} else if (error instanceof EntityNotFoundError) {
- message = `${(error as any).stringifyTarget} could not be found`;
+ message = `${(error as any).stringifyTarget || "Item"} could not be found`;
code = 404;
} else if (error instanceof FieldError) {
code = Number(error.code);
diff --git "a/api/src/routes/channels/\043channel_id/pins.ts" "b/api/src/routes/channels/\043channel_id/pins.ts"
index fafb789..33309c8 100644
--- "a/api/src/routes/channels/\043channel_id/pins.ts"
+++ "b/api/src/routes/channels/\043channel_id/pins.ts"
@@ -1,7 +1,7 @@
import { Channel, ChannelPinsUpdateEvent, Config, emitEvent, getPermission, Message, MessageUpdateEvent } from "@fosscord/util";
import { Router, Request, Response } from "express";
import { HTTPError } from "lambert-server";
-import { DiscordApiErrors } from "../../../util/Constants";
+import { DiscordApiErrors } from "@fosscord/util";
const router: Router = Router();
diff --git "a/api/src/routes/channels/\043channel_id/webhooks.ts" "b/api/src/routes/channels/\043channel_id/webhooks.ts"
index d2a4b9a..e412587 100644
--- "a/api/src/routes/channels/\043channel_id/webhooks.ts"
+++ "b/api/src/routes/channels/\043channel_id/webhooks.ts"
@@ -3,7 +3,7 @@
import { Channel, Config, getPermission, trimSpecial, Webhook } from "@fosscord/util";
import { HTTPError } from "lambert-server";
import { isTextChannel } from "./messages/index";
-import { DiscordApiErrors } from "../../../util/Constants";
+import { DiscordApiErrors } from "@fosscord/util";
const router: Router = Router();
// TODO: webhooks
diff --git a/api/src/routes/discoverable-guilds.ts b/api/src/routes/discoverable-guilds.ts
new file mode 100644
index 0000000..0808727
--- /dev/null
+++ b/api/src/routes/discoverable-guilds.ts
@@ -0,0 +1,17 @@
+import { Guild } from "@fosscord/util";
+import { Router, Request, Response } from "express";
+import { In } from "typeorm";
+
+const router = Router();
+
+router.get("/", async (req: Request, res: Response) => {
+ const { limit } = req.params;
+
+ // ! this only works using SQL querys
+ // TODO: implement this with default typeorm query
+ // const guilds = await Guild.find({ where: { features: "DISCOVERABLE" } }); //, take: Math.abs(Number(limit)) });
+ const guilds = await Guild.find({ where: `"features" LIKE 'COMMUNITY'`, take: Math.abs(Number(limit)) });
+ res.send({ guilds: guilds });
+});
+
+export default router;
diff --git "a/api/src/routes/guilds/\043guild_id/members/\043member_id/index.ts" "b/api/src/routes/guilds/\043guild_id/members/\043member_id/index.ts"
index 51bb010..0d62e55 100644
--- "a/api/src/routes/guilds/\043guild_id/members/\043member_id/index.ts"
+++ "b/api/src/routes/guilds/\043guild_id/members/\043member_id/index.ts"
@@ -50,7 +50,8 @@
});
router.put("/", async (req: Request, res: Response) => {
- const { guild_id, member_id } = req.params;
+ let { guild_id, member_id } = req.params;
+ if (member_id === "@me") member_id = req.user_id;
throw new HTTPError("Maintenance: Currently you can't add a member", 403);
// TODO: only for oauth2 applications
diff --git "a/api/src/routes/guilds/\043guild_id/roles.ts" "b/api/src/routes/guilds/\043guild_id/roles.ts"
index bdfc370..6a31868 100644
--- "a/api/src/routes/guilds/\043guild_id/roles.ts"
+++ "b/api/src/routes/guilds/\043guild_id/roles.ts"
@@ -14,7 +14,7 @@
import { check } from "../../../util/instanceOf";
import { RoleModifySchema, RolePositionUpdateSchema } from "../../../schema/Roles";
-import { DiscordApiErrors } from "../../../util/Constants";
+import { DiscordApiErrors } from "@fosscord/util";
import { In } from "typeorm";
const router: Router = Router();
diff --git a/api/src/routes/guilds/index.ts b/api/src/routes/guilds/index.ts
index 7c0b7ab..e583064 100644
--- a/api/src/routes/guilds/index.ts
+++ b/api/src/routes/guilds/index.ts
@@ -3,7 +3,7 @@
import { HTTPError } from "lambert-server";
import { check } from "./../../util/instanceOf";
import { GuildCreateSchema } from "../../schema/Guild";
-import { DiscordApiErrors } from "../../util/Constants";
+import { DiscordApiErrors } from "@fosscord/util";
const router: Router = Router();
diff --git a/api/src/routes/guilds/templates/index.ts b/api/src/routes/guilds/templates/index.ts
index 3a61927..58201f6 100644
--- a/api/src/routes/guilds/templates/index.ts
+++ b/api/src/routes/guilds/templates/index.ts
@@ -4,7 +4,7 @@
import { HTTPError } from "lambert-server";
import { GuildTemplateCreateSchema } from "../../../schema/Guild";
import { check } from "../../../util/instanceOf";
-import { DiscordApiErrors } from "../../../util/Constants";
+import { DiscordApiErrors } from "@fosscord/util";
router.get("/:code", async (req: Request, res: Response) => {
const { code } = req.params;
diff --git a/api/src/routes/template.ts.disabled b/api/src/routes/template.ts.disabled
new file mode 100644
index 0000000..ad785f1
--- /dev/null
+++ b/api/src/routes/template.ts.disabled
@@ -0,0 +1,10 @@
+//TODO: this is a template for a generic route
+
+import { Router, Request, Response } from "express";
+const router = Router();
+
+router.get("/", async (req: Request, res: Response) => {
+ res.send({});
+});
+
+export default router;
diff --git a/api/src/routes/users/@me/relationships.ts b/api/src/routes/users/@me/relationships.ts
index 2bd9c81..8d6d8c9 100644
--- a/api/src/routes/users/@me/relationships.ts
+++ b/api/src/routes/users/@me/relationships.ts
@@ -10,7 +10,7 @@
} from "@fosscord/util";
import { Router, Response, Request } from "express";
import { HTTPError } from "lambert-server";
-import { DiscordApiErrors } from "../../../util/Constants";
+import { DiscordApiErrors } from "@fosscord/util";
import { check, Length } from "../../../util/instanceOf";
diff --git a/api/src/util/ApiError.ts b/api/src/util/ApiError.ts
deleted file mode 100644
index c133e6e..0000000
--- a/api/src/util/ApiError.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-export class ApiError extends Error {
- constructor(
- readonly message: string,
- public readonly code: number,
- public readonly httpStatus: number = 400,
- public readonly defaultParams?: string[]
- ) {
- super(message);
- }
-
- withDefaultParams(): ApiError {
- if (this.defaultParams) return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
- return this;
- }
-
- withParams(...params: (string | number)[]): ApiError {
- return new ApiError(applyParamsToString(this.message, params), this.code, this.httpStatus);
- }
-}
-
-export function applyParamsToString(s: string, params: (string | number)[]): string {
- let newString = s;
- params.forEach((a) => {
- newString = newString.replace("{}", "" + a);
- });
- return newString;
-}
diff --git a/api/src/util/Constants.ts b/api/src/util/Constants.ts
deleted file mode 100644
index f06b3d5..0000000
--- a/api/src/util/Constants.ts
+++ /dev/null
@@ -1,712 +0,0 @@
-import { ApiError } from "./ApiError";
-
-export const WSCodes = {
- 1000: "WS_CLOSE_REQUESTED",
- 4004: "TOKEN_INVALID",
- 4010: "SHARDING_INVALID",
- 4011: "SHARDING_REQUIRED",
- 4013: "INVALID_INTENTS",
- 4014: "DISALLOWED_INTENTS"
-};
-
-/**
- * The current status of the client. Here are the available statuses:
- * * READY: 0
- * * CONNECTING: 1
- * * RECONNECTING: 2
- * * IDLE: 3
- * * NEARLY: 4
- * * DISCONNECTED: 5
- * * WAITING_FOR_GUILDS: 6
- * * IDENTIFYING: 7
- * * RESUMING: 8
- * @typedef {number} Status
- */
-export const Status = {
- READY: 0,
- CONNECTING: 1,
- RECONNECTING: 2,
- IDLE: 3,
- NEARLY: 4,
- DISCONNECTED: 5,
- WAITING_FOR_GUILDS: 6,
- IDENTIFYING: 7,
- RESUMING: 8
-};
-
-/**
- * The current status of a voice connection. Here are the available statuses:
- * * CONNECTED: 0
- * * CONNECTING: 1
- * * AUTHENTICATING: 2
- * * RECONNECTING: 3
- * * DISCONNECTED: 4
- * @typedef {number} VoiceStatus
- */
-export const VoiceStatus = {
- CONNECTED: 0,
- CONNECTING: 1,
- AUTHENTICATING: 2,
- RECONNECTING: 3,
- DISCONNECTED: 4
-};
-
-export const OPCodes = {
- DISPATCH: 0,
- HEARTBEAT: 1,
- IDENTIFY: 2,
- STATUS_UPDATE: 3,
- VOICE_STATE_UPDATE: 4,
- VOICE_GUILD_PING: 5,
- RESUME: 6,
- RECONNECT: 7,
- REQUEST_GUILD_MEMBERS: 8,
- INVALID_SESSION: 9,
- HELLO: 10,
- HEARTBEAT_ACK: 11
-};
-
-export const VoiceOPCodes = {
- IDENTIFY: 0,
- SELECT_PROTOCOL: 1,
- READY: 2,
- HEARTBEAT: 3,
- SESSION_DESCRIPTION: 4,
- SPEAKING: 5,
- HELLO: 8,
- CLIENT_CONNECT: 12,
- CLIENT_DISCONNECT: 13
-};
-
-export const Events = {
- RATE_LIMIT: "rateLimit",
- CLIENT_READY: "ready",
- GUILD_CREATE: "guildCreate",
- GUILD_DELETE: "guildDelete",
- GUILD_UPDATE: "guildUpdate",
- GUILD_UNAVAILABLE: "guildUnavailable",
- GUILD_AVAILABLE: "guildAvailable",
- GUILD_MEMBER_ADD: "guildMemberAdd",
- GUILD_MEMBER_REMOVE: "guildMemberRemove",
- GUILD_MEMBER_UPDATE: "guildMemberUpdate",
- GUILD_MEMBER_AVAILABLE: "guildMemberAvailable",
- GUILD_MEMBER_SPEAKING: "guildMemberSpeaking",
- GUILD_MEMBERS_CHUNK: "guildMembersChunk",
- GUILD_INTEGRATIONS_UPDATE: "guildIntegrationsUpdate",
- GUILD_ROLE_CREATE: "roleCreate",
- GUILD_ROLE_DELETE: "roleDelete",
- INVITE_CREATE: "inviteCreate",
- INVITE_DELETE: "inviteDelete",
- GUILD_ROLE_UPDATE: "roleUpdate",
- GUILD_EMOJI_CREATE: "emojiCreate",
- GUILD_EMOJI_DELETE: "emojiDelete",
- GUILD_EMOJI_UPDATE: "emojiUpdate",
- GUILD_BAN_ADD: "guildBanAdd",
- GUILD_BAN_REMOVE: "guildBanRemove",
- CHANNEL_CREATE: "channelCreate",
- CHANNEL_DELETE: "channelDelete",
- CHANNEL_UPDATE: "channelUpdate",
- CHANNEL_PINS_UPDATE: "channelPinsUpdate",
- MESSAGE_CREATE: "message",
- MESSAGE_DELETE: "messageDelete",
- MESSAGE_UPDATE: "messageUpdate",
- MESSAGE_BULK_DELETE: "messageDeleteBulk",
- MESSAGE_REACTION_ADD: "messageReactionAdd",
- MESSAGE_REACTION_REMOVE: "messageReactionRemove",
- MESSAGE_REACTION_REMOVE_ALL: "messageReactionRemoveAll",
- MESSAGE_REACTION_REMOVE_EMOJI: "messageReactionRemoveEmoji",
- USER_UPDATE: "userUpdate",
- PRESENCE_UPDATE: "presenceUpdate",
- VOICE_SERVER_UPDATE: "voiceServerUpdate",
- VOICE_STATE_UPDATE: "voiceStateUpdate",
- VOICE_BROADCAST_SUBSCRIBE: "subscribe",
- VOICE_BROADCAST_UNSUBSCRIBE: "unsubscribe",
- TYPING_START: "typingStart",
- TYPING_STOP: "typingStop",
- WEBHOOKS_UPDATE: "webhookUpdate",
- ERROR: "error",
- WARN: "warn",
- DEBUG: "debug",
- SHARD_DISCONNECT: "shardDisconnect",
- SHARD_ERROR: "shardError",
- SHARD_RECONNECTING: "shardReconnecting",
- SHARD_READY: "shardReady",
- SHARD_RESUME: "shardResume",
- INVALIDATED: "invalidated",
- RAW: "raw"
-};
-
-export const ShardEvents = {
- CLOSE: "close",
- DESTROYED: "destroyed",
- INVALID_SESSION: "invalidSession",
- READY: "ready",
- RESUMED: "resumed",
- ALL_READY: "allReady"
-};
-
-/**
- * The type of Structure allowed to be a partial:
- * * USER
- * * CHANNEL (only affects DMChannels)
- * * GUILD_MEMBER
- * * MESSAGE
- * * REACTION
- * Partials require you to put checks in place when handling data, read the Partials topic listed in the
- * sidebar for more information.
- * @typedef {string} PartialType
- */
-export const PartialTypes = keyMirror(["USER", "CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION"]);
-
-/**
- * The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events:
- * * READY
- * * RESUMED
- * * GUILD_CREATE
- * * GUILD_DELETE
- * * GUILD_UPDATE
- * * INVITE_CREATE
- * * INVITE_DELETE
- * * GUILD_MEMBER_ADD
- * * GUILD_MEMBER_REMOVE
- * * GUILD_MEMBER_UPDATE
- * * GUILD_MEMBERS_CHUNK
- * * GUILD_INTEGRATIONS_UPDATE
- * * GUILD_ROLE_CREATE
- * * GUILD_ROLE_DELETE
- * * GUILD_ROLE_UPDATE
- * * GUILD_BAN_ADD
- * * GUILD_BAN_REMOVE
- * * GUILD_EMOJIS_UPDATE
- * * CHANNEL_CREATE
- * * CHANNEL_DELETE
- * * CHANNEL_UPDATE
- * * CHANNEL_PINS_UPDATE
- * * MESSAGE_CREATE
- * * MESSAGE_DELETE
- * * MESSAGE_UPDATE
- * * MESSAGE_DELETE_BULK
- * * MESSAGE_REACTION_ADD
- * * MESSAGE_REACTION_REMOVE
- * * MESSAGE_REACTION_REMOVE_ALL
- * * MESSAGE_REACTION_REMOVE_EMOJI
- * * USER_UPDATE
- * * PRESENCE_UPDATE
- * * TYPING_START
- * * VOICE_STATE_UPDATE
- * * VOICE_SERVER_UPDATE
- * * WEBHOOKS_UPDATE
- * @typedef {string} WSEventType
- */
-export const WSEvents = keyMirror([
- "READY",
- "RESUMED",
- "GUILD_CREATE",
- "GUILD_DELETE",
- "GUILD_UPDATE",
- "INVITE_CREATE",
- "INVITE_DELETE",
- "GUILD_MEMBER_ADD",
- "GUILD_MEMBER_REMOVE",
- "GUILD_MEMBER_UPDATE",
- "GUILD_MEMBERS_CHUNK",
- "GUILD_INTEGRATIONS_UPDATE",
- "GUILD_ROLE_CREATE",
- "GUILD_ROLE_DELETE",
- "GUILD_ROLE_UPDATE",
- "GUILD_BAN_ADD",
- "GUILD_BAN_REMOVE",
- "GUILD_EMOJIS_UPDATE",
- "CHANNEL_CREATE",
- "CHANNEL_DELETE",
- "CHANNEL_UPDATE",
- "CHANNEL_PINS_UPDATE",
- "MESSAGE_CREATE",
- "MESSAGE_DELETE",
- "MESSAGE_UPDATE",
- "MESSAGE_DELETE_BULK",
- "MESSAGE_REACTION_ADD",
- "MESSAGE_REACTION_REMOVE",
- "MESSAGE_REACTION_REMOVE_ALL",
- "MESSAGE_REACTION_REMOVE_EMOJI",
- "USER_UPDATE",
- "PRESENCE_UPDATE",
- "TYPING_START",
- "VOICE_STATE_UPDATE",
- "VOICE_SERVER_UPDATE",
- "WEBHOOKS_UPDATE"
-]);
-
-/**
- * The type of a message, e.g. `DEFAULT`. Here are the available types:
- * * DEFAULT
- * * RECIPIENT_ADD
- * * RECIPIENT_REMOVE
- * * CALL
- * * CHANNEL_NAME_CHANGE
- * * CHANNEL_ICON_CHANGE
- * * PINS_ADD
- * * GUILD_MEMBER_JOIN
- * * USER_PREMIUM_GUILD_SUBSCRIPTION
- * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1
- * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2
- * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3
- * * CHANNEL_FOLLOW_ADD
- * * GUILD_DISCOVERY_DISQUALIFIED
- * * GUILD_DISCOVERY_REQUALIFIED
- * * REPLY
- * @typedef {string} MessageType
- */
-export const MessageTypes = [
- "DEFAULT",
- "RECIPIENT_ADD",
- "RECIPIENT_REMOVE",
- "CALL",
- "CHANNEL_NAME_CHANGE",
- "CHANNEL_ICON_CHANGE",
- "PINS_ADD",
- "GUILD_MEMBER_JOIN",
- "USER_PREMIUM_GUILD_SUBSCRIPTION",
- "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1",
- "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2",
- "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3",
- "CHANNEL_FOLLOW_ADD",
- null,
- "GUILD_DISCOVERY_DISQUALIFIED",
- "GUILD_DISCOVERY_REQUALIFIED",
- null,
- null,
- null,
- "REPLY"
-];
-
-/**
- * The types of messages that are `System`. The available types are `MessageTypes` excluding:
- * * DEFAULT
- * * REPLY
- * @typedef {string} SystemMessageType
- */
-export const SystemMessageTypes = MessageTypes.filter((type: string | null) => type && type !== "DEFAULT" && type !== "REPLY");
-
-/**
- * Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users
- * The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types:
- * * PLAYING
- * * STREAMING
- * * LISTENING
- * * WATCHING
- * * CUSTOM_STATUS
- * * COMPETING
- * @typedef {string} ActivityType
- */
-export const ActivityTypes = ["PLAYING", "STREAMING", "LISTENING", "WATCHING", "CUSTOM_STATUS", "COMPETING"];
-
-export const ChannelTypes = {
- TEXT: 0,
- DM: 1,
- VOICE: 2,
- GROUP: 3,
- CATEGORY: 4,
- NEWS: 5,
- STORE: 6
-};
-
-export const ClientApplicationAssetTypes = {
- SMALL: 1,
- BIG: 2
-};
-
-export const Colors = {
- DEFAULT: 0x000000,
- WHITE: 0xffffff,
- AQUA: 0x1abc9c,
- GREEN: 0x2ecc71,
- BLUE: 0x3498db,
- YELLOW: 0xffff00,
- PURPLE: 0x9b59b6,
- LUMINOUS_VIVID_PINK: 0xe91e63,
- GOLD: 0xf1c40f,
- ORANGE: 0xe67e22,
- RED: 0xe74c3c,
- GREY: 0x95a5a6,
- NAVY: 0x34495e,
- DARK_AQUA: 0x11806a,
- DARK_GREEN: 0x1f8b4c,
- DARK_BLUE: 0x206694,
- DARK_PURPLE: 0x71368a,
- DARK_VIVID_PINK: 0xad1457,
- DARK_GOLD: 0xc27c0e,
- DARK_ORANGE: 0xa84300,
- DARK_RED: 0x992d22,
- DARK_GREY: 0x979c9f,
- DARKER_GREY: 0x7f8c8d,
- LIGHT_GREY: 0xbcc0c0,
- DARK_NAVY: 0x2c3e50,
- BLURPLE: 0x7289da,
- GREYPLE: 0x99aab5,
- DARK_BUT_NOT_BLACK: 0x2c2f33,
- NOT_QUITE_BLACK: 0x23272a
-};
-
-/**
- * The value set for the explicit content filter levels for a guild:
- * * DISABLED
- * * MEMBERS_WITHOUT_ROLES
- * * ALL_MEMBERS
- * @typedef {string} ExplicitContentFilterLevel
- */
-export const ExplicitContentFilterLevels = ["DISABLED", "MEMBERS_WITHOUT_ROLES", "ALL_MEMBERS"];
-
-/**
- * The value set for the verification levels for a guild:
- * * NONE
- * * LOW
- * * MEDIUM
- * * HIGH
- * * VERY_HIGH
- * @typedef {string} VerificationLevel
- */
-export const VerificationLevels = ["NONE", "LOW", "MEDIUM", "HIGH", "VERY_HIGH"];
-
-/**
- * An error encountered while performing an API request. Here are the potential errors:
- * * GENERAL_ERROR
- * * UNKNOWN_ACCOUNT
- * * UNKNOWN_APPLICATION
- * * UNKNOWN_CHANNEL
- * * UNKNOWN_GUILD
- * * UNKNOWN_INTEGRATION
- * * UNKNOWN_INVITE
- * * UNKNOWN_MEMBER
- * * UNKNOWN_MESSAGE
- * * UNKNOWN_OVERWRITE
- * * UNKNOWN_PROVIDER
- * * UNKNOWN_ROLE
- * * UNKNOWN_TOKEN
- * * UNKNOWN_USER
- * * UNKNOWN_EMOJI
- * * UNKNOWN_WEBHOOK
- * * UNKNOWN_WEBHOOK_SERVICE
- * * UNKNOWN_SESSION
- * * UNKNOWN_BAN
- * * UNKNOWN_SKU
- * * UNKNOWN_STORE_LISTING
- * * UNKNOWN_ENTITLEMENT
- * * UNKNOWN_BUILD
- * * UNKNOWN_LOBBY
- * * UNKNOWN_BRANCH
- * * UNKNOWN_STORE_DIRECTORY_LAYOUT
- * * UNKNOWN_REDISTRIBUTABLE
- * * UNKNOWN_GIFT_CODE
- * * UNKNOWN_STREAM
- * * UNKNOWN_PREMIUM_SERVER_SUBSCRIBE_COOLDOWN
- * * UNKNOWN_GUILD_TEMPLATE
- * * UNKNOWN_DISCOVERABLE_SERVER_CATEGORY
- * * UNKNOWN_STICKER
- * * UNKNOWN_INTERACTION
- * * UNKNOWN_APPLICATION_COMMAND
- * * UNKNOWN_APPLICATION_COMMAND_PERMISSIONS
- * * UNKNOWN_STAGE_INSTANCE
- * * UNKNOWN_GUILD_MEMBER_VERIFICATION_FORM
- * * UNKNOWN_GUILD_WELCOME_SCREEN
- * * UNKNOWN_GUILD_SCHEDULED_EVENT
- * * UNKNOWN_GUILD_SCHEDULED_EVENT_USER
- * * BOT_PROHIBITED_ENDPOINT
- * * BOT_ONLY_ENDPOINT
- * * EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT
- * * ACTION_NOT_AUTHORIZED_ON_APPLICATION
- * * SLOWMODE_RATE_LIMIT
- * * ONLY_OWNER
- * * ANNOUNCEMENT_RATE_LIMITS
- * * CHANNEL_WRITE_RATELIMIT
- * * WORDS_NOT_ALLOWED
- * * GUILD_PREMIUM_LEVEL_TOO_LOW
- * * MAXIMUM_GUILDS
- * * MAXIMUM_FRIENDS
- * * MAXIMUM_PINS
- * * MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED
- * * MAXIMUM_ROLES
- * * MAXIMUM_WEBHOOKS
- * * MAXIMUM_NUMBER_OF_EMOJIS_REACHED
- * * MAXIMUM_REACTIONS
- * * MAXIMUM_CHANNELS
- * * MAXIMUM_ATTACHMENTS
- * * MAXIMUM_INVITES
- * * MAXIMUM_ANIMATED_EMOJIS
- * * MAXIMUM_SERVER_MEMBERS
- * * MAXIMUM_SERVER_CATEGORIES
- * * GUILD_ALREADY_HAS_TEMPLATE
- * * MAXIMUM_THREAD_PARTICIPANTS
- * * MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS
- * * MAXIMUM_BANS_FETCHES
- * * MAXIMUM_STICKERS
- * * MAXIMUM_PRUNE_REQUESTS
- * * UNAUTHORIZED
- * * ACCOUNT_VERIFICATION_REQUIRED
- * * OPENING_DIRECT_MESSAGES_TOO_FAST
- * * REQUEST_ENTITY_TOO_LARGE
- * * FEATURE_TEMPORARILY_DISABLED
- * * USER_BANNED
- * * TARGET_USER_IS_NOT_CONNECTED_TO_VOICE
- * * ALREADY_CROSSPOSTED
- * * APPLICATION_COMMAND_ALREADY_EXISTS
- * * MISSING_ACCESS
- * * INVALID_ACCOUNT_TYPE
- * * CANNOT_EXECUTE_ON_DM
- * * EMBED_DISABLED
- * * CANNOT_EDIT_MESSAGE_BY_OTHER
- * * CANNOT_SEND_EMPTY_MESSAGE
- * * CANNOT_MESSAGE_USER
- * * CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL
- * * CHANNEL_VERIFICATION_LEVEL_TOO_HIGH
- * * OAUTH2_APPLICATION_BOT_ABSENT
- * * MAXIMUM_OAUTH2_APPLICATIONS
- * * INVALID_OAUTH_STATE
- * * MISSING_PERMISSIONS
- * * INVALID_AUTHENTICATION_TOKEN
- * * NOTE_TOO_LONG
- * * INVALID_BULK_DELETE_QUANTITY
- * * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL
- * * INVALID_OR_TAKEN_INVITE_CODE
- * * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE
- * * CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE
- * * INVALID_OAUTH_TOKEN
- * * MISSING_REQUIRED_OAUTH2_SCOPE
- * * INVALID_WEBHOOK_TOKEN_PROVIDED
- * * INVALID_ROLE
- * * INVALID_RECIPIENT
- * * BULK_DELETE_MESSAGE_TOO_OLD
- * * INVALID_FORM_BODY
- * * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT
- * * INVALID_API_VERSION
- * * FILE_EXCEEDS_MAXIMUM_SIZE
- * * INVALID_FILE_UPLOADED
- * * CANNOT_SELF_REDEEM_GIFT
- * * PAYMENT_SOURCE_REQUIRED
- * * CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL
- * * INVALID_STICKER_SENT
- * * CANNOT_EDIT_ARCHIVED_THREAD
- * * INVALID_THREAD_NOTIFICATION_SETTINGS
- * * BEFORE_EARLIER_THAN_THREAD_CREATION_DATE
- * * SERVER_NOT_AVAILABLE_IN_YOUR_LOCATION
- * * SERVER_NEEDS_MONETIZATION_ENABLED
- * * TWO_FACTOR_REQUIRED
- * * NO_USERS_WITH_DISCORDTAG_EXIST
- * * REACTION_BLOCKED
- * * RESOURCE_OVERLOADED
- * * STAGE_ALREADY_OPEN
- * * THREAD_ALREADY_CREATED_FOR_THIS_MESSAGE
- * * THREAD_IS_LOCKED
- * * MAXIMUM_NUMBER_OF_ACTIVE_THREADS
- * * MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS
- * * INVALID_JSON_FOR_UPLOADED_LOTTIE_FILE
- * * LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES
- * * STICKER_MAXIMUM_FRAMERATE
- * * STICKER_MAXIMUM_FRAME_COUNT
- * * LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS
- * * STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE
- * * STICKER_ANIMATION_DURATION_MAXIMUM
- * * UNKNOWN_VOICE_STATE
- * @typedef {string} APIError
- */
-export const DiscordApiErrors = {
- //https://discord.com/developers/docs/topics/opcodes-and-status-codes#json-json-error-codes
- GENERAL_ERROR: new ApiError("General error (such as a malformed request body, amongst other things)", 0),
- UNKNOWN_ACCOUNT: new ApiError("Unknown account", 10001),
- UNKNOWN_APPLICATION: new ApiError("Unknown application", 10002),
- UNKNOWN_CHANNEL: new ApiError("Unknown channel", 10003),
- UNKNOWN_GUILD: new ApiError("Unknown guild", 10004),
- UNKNOWN_INTEGRATION: new ApiError("Unknown integration", 10005),
- UNKNOWN_INVITE: new ApiError("Unknown invite", 10006),
- UNKNOWN_MEMBER: new ApiError("Unknown member", 10007),
- UNKNOWN_MESSAGE: new ApiError("Unknown message", 10008),
- UNKNOWN_OVERWRITE: new ApiError("Unknown permission overwrite", 10009),
- UNKNOWN_PROVIDER: new ApiError("Unknown provider", 10010),
- UNKNOWN_ROLE: new ApiError("Unknown role", 10011),
- UNKNOWN_TOKEN: new ApiError("Unknown token", 10012),
- UNKNOWN_USER: new ApiError("Unknown user", 10013),
- UNKNOWN_EMOJI: new ApiError("Unknown emoji", 10014),
- UNKNOWN_WEBHOOK: new ApiError("Unknown webhook", 10015),
- UNKNOWN_WEBHOOK_SERVICE: new ApiError("Unknown webhook service", 10016),
- UNKNOWN_SESSION: new ApiError("Unknown session", 10020),
- UNKNOWN_BAN: new ApiError("Unknown ban", 10026),
- UNKNOWN_SKU: new ApiError("Unknown SKU", 10027),
- UNKNOWN_STORE_LISTING: new ApiError("Unknown Store Listing", 10028),
- UNKNOWN_ENTITLEMENT: new ApiError("Unknown entitlement", 10029),
- UNKNOWN_BUILD: new ApiError("Unknown build", 10030),
- UNKNOWN_LOBBY: new ApiError("Unknown lobby", 10031),
- UNKNOWN_BRANCH: new ApiError("Unknown branch", 10032),
- UNKNOWN_STORE_DIRECTORY_LAYOUT: new ApiError("Unknown store directory layout", 10033),
- UNKNOWN_REDISTRIBUTABLE: new ApiError("Unknown redistributable", 10036),
- UNKNOWN_GIFT_CODE: new ApiError("Unknown gift code", 10038),
- UNKNOWN_STREAM: new ApiError("Unknown stream", 10049),
- UNKNOWN_PREMIUM_SERVER_SUBSCRIBE_COOLDOWN: new ApiError("Unknown premium server subscribe cooldown", 10050),
- UNKNOWN_GUILD_TEMPLATE: new ApiError("Unknown guild template", 10057),
- UNKNOWN_DISCOVERABLE_SERVER_CATEGORY: new ApiError("Unknown discoverable server category", 10059),
- UNKNOWN_STICKER: new ApiError("Unknown sticker", 10060),
- UNKNOWN_INTERACTION: new ApiError("Unknown interaction", 10062),
- UNKNOWN_APPLICATION_COMMAND: new ApiError("Unknown application command", 10063),
- UNKNOWN_APPLICATION_COMMAND_PERMISSIONS: new ApiError("Unknown application command permissions", 10066),
- UNKNOWN_STAGE_INSTANCE: new ApiError("Unknown Stage Instance", 10067),
- UNKNOWN_GUILD_MEMBER_VERIFICATION_FORM: new ApiError("Unknown Guild Member Verification Form", 10068),
- UNKNOWN_GUILD_WELCOME_SCREEN: new ApiError("Unknown Guild Welcome Screen", 10069),
- UNKNOWN_GUILD_SCHEDULED_EVENT: new ApiError("Unknown Guild Scheduled Event", 10070),
- UNKNOWN_GUILD_SCHEDULED_EVENT_USER: new ApiError("Unknown Guild Scheduled Event User", 10071),
- BOT_PROHIBITED_ENDPOINT: new ApiError("Bots cannot use this endpoint", 20001),
- BOT_ONLY_ENDPOINT: new ApiError("Only bots can use this endpoint", 20002),
- EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT: new ApiError("Explicit content cannot be sent to the desired recipient(s)", 20009),
- ACTION_NOT_AUTHORIZED_ON_APPLICATION: new ApiError("You are not authorized to perform this action on this application", 20012),
- SLOWMODE_RATE_LIMIT: new ApiError("This action cannot be performed due to slowmode rate limit", 20016),
- ONLY_OWNER: new ApiError("Only the owner of this account can perform this action", 20018),
- ANNOUNCEMENT_RATE_LIMITS: new ApiError("This message cannot be edited due to announcement rate limits", 20022),
- CHANNEL_WRITE_RATELIMIT: new ApiError("The channel you are writing has hit the write rate limit", 20028),
- WORDS_NOT_ALLOWED: new ApiError(
- "Your Stage topic, server name, server description, or channel names contain words that are not allowed",
- 20031
- ),
- GUILD_PREMIUM_LEVEL_TOO_LOW: new ApiError("Guild premium subscription level too low", 20035),
- MAXIMUM_GUILDS: new ApiError("Maximum number of guilds reached ({})", 30001, undefined, ["100"]),
- MAXIMUM_FRIENDS: new ApiError("Maximum number of friends reached ({})", 30002, undefined, ["1000"]),
- MAXIMUM_PINS: new ApiError("Maximum number of pins reached for the channel ({})", 30003, undefined, ["50"]),
- MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED: new ApiError("Maximum number of recipients reached ({})", 30004, undefined, ["10"]),
- MAXIMUM_ROLES: new ApiError("Maximum number of guild roles reached ({})", 30005, undefined, ["250"]),
- MAXIMUM_WEBHOOKS: new ApiError("Maximum number of webhooks reached ({})", 30007, undefined, ["10"]),
- MAXIMUM_NUMBER_OF_EMOJIS_REACHED: new ApiError("Maximum number of emojis reached", 30008),
- MAXIMUM_REACTIONS: new ApiError("Maximum number of reactions reached ({})", 30010, undefined, ["20"]),
- MAXIMUM_CHANNELS: new ApiError("Maximum number of guild channels reached ({})", 30013, undefined, ["500"]),
- MAXIMUM_ATTACHMENTS: new ApiError("Maximum number of attachments in a message reached ({})", 30015, undefined, ["10"]),
- MAXIMUM_INVITES: new ApiError("Maximum number of invites reached ({})", 30016, undefined, ["1000"]),
- MAXIMUM_ANIMATED_EMOJIS: new ApiError("Maximum number of animated emojis reached", 30018),
- MAXIMUM_SERVER_MEMBERS: new ApiError("Maximum number of server members reached", 30019),
- MAXIMUM_SERVER_CATEGORIES: new ApiError("Maximum number of server categories has been reached ({})", 30030, undefined, ["5"]),
- GUILD_ALREADY_HAS_TEMPLATE: new ApiError("Guild already has a template", 30031),
- MAXIMUM_THREAD_PARTICIPANTS: new ApiError("Max number of thread participants has been reached", 30033),
- MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS: new ApiError("Maximum number of bans for non-guild members have been exceeded", 30035),
- MAXIMUM_BANS_FETCHES: new ApiError("Maximum number of bans fetches has been reached", 30037),
- MAXIMUM_STICKERS: new ApiError("Maximum number of stickers reached", 30039),
- MAXIMUM_PRUNE_REQUESTS: new ApiError("Maximum number of prune requests has been reached. Try again later", 30040),
- UNAUTHORIZED: new ApiError("Unauthorized. Provide a valid token and try again", 40001),
- ACCOUNT_VERIFICATION_REQUIRED: new ApiError("You need to verify your account in order to perform this action", 40002),
- OPENING_DIRECT_MESSAGES_TOO_FAST: new ApiError("You are opening direct messages too fast", 40003),
- REQUEST_ENTITY_TOO_LARGE: new ApiError("Request entity too large. Try sending something smaller in size", 40005),
- FEATURE_TEMPORARILY_DISABLED: new ApiError("This feature has been temporarily disabled server-side", 40006),
- USER_BANNED: new ApiError("The user is banned from this guild", 40007),
- TARGET_USER_IS_NOT_CONNECTED_TO_VOICE: new ApiError("Target user is not connected to voice", 40032),
- ALREADY_CROSSPOSTED: new ApiError("This message has already been crossposted", 40033),
- APPLICATION_COMMAND_ALREADY_EXISTS: new ApiError("An application command with that name already exists", 40041),
- MISSING_ACCESS: new ApiError("Missing access", 50001),
- INVALID_ACCOUNT_TYPE: new ApiError("Invalid account type", 50002),
- CANNOT_EXECUTE_ON_DM: new ApiError("Cannot execute action on a DM channel", 50003),
- EMBED_DISABLED: new ApiError("Guild widget disabled", 50004),
- CANNOT_EDIT_MESSAGE_BY_OTHER: new ApiError("Cannot edit a message authored by another user", 50005),
- CANNOT_SEND_EMPTY_MESSAGE: new ApiError("Cannot send an empty message", 50006),
- CANNOT_MESSAGE_USER: new ApiError("Cannot send messages to this user", 50007),
- CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: new ApiError("Cannot send messages in a voice channel", 50008),
- CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: new ApiError("Channel verification level is too high for you to gain access", 50009),
- OAUTH2_APPLICATION_BOT_ABSENT: new ApiError("OAuth2 application does not have a bot", 50010),
- MAXIMUM_OAUTH2_APPLICATIONS: new ApiError("OAuth2 application limit reached", 50011),
- INVALID_OAUTH_STATE: new ApiError("Invalid OAuth2 state", 50012),
- MISSING_PERMISSIONS: new ApiError("You lack permissions to perform that action", 50013),
- INVALID_AUTHENTICATION_TOKEN: new ApiError("Invalid authentication token provided", 50014),
- NOTE_TOO_LONG: new ApiError("Note was too long", 50015),
- INVALID_BULK_DELETE_QUANTITY: new ApiError(
- "Provided too few or too many messages to delete. Must provide at least {} and fewer than {} messages to delete",
- 50016,
- undefined,
- ["2", "100"]
- ),
- CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: new ApiError("A message can only be pinned to the channel it was sent in", 50019),
- INVALID_OR_TAKEN_INVITE_CODE: new ApiError("Invite code was either invalid or taken", 50020),
- CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: new ApiError("Cannot execute action on a system message", 50021),
- CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE: new ApiError("Cannot execute action on this channel type", 50024),
- INVALID_OAUTH_TOKEN: new ApiError("Invalid OAuth2 access token provided", 50025),
- MISSING_REQUIRED_OAUTH2_SCOPE: new ApiError("Missing required OAuth2 scope", 50026),
- INVALID_WEBHOOK_TOKEN_PROVIDED: new ApiError("Invalid webhook token provided", 50027),
- INVALID_ROLE: new ApiError("Invalid role", 50028),
- INVALID_RECIPIENT: new ApiError("Invalid Recipient(s)", 50033),
- BULK_DELETE_MESSAGE_TOO_OLD: new ApiError("A message provided was too old to bulk delete", 50034),
- INVALID_FORM_BODY: new ApiError(
- "Invalid form body (returned for both application/json and multipart/form-data bodies), or invalid Content-Type provided",
- 50035
- ),
- INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: new ApiError("An invite was accepted to a guild the application's bot is not in", 50036),
- INVALID_API_VERSION: new ApiError("Invalid API version provided", 50041),
- FILE_EXCEEDS_MAXIMUM_SIZE: new ApiError("File uploaded exceeds the maximum size", 50045),
- INVALID_FILE_UPLOADED: new ApiError("Invalid file uploaded", 50046),
- CANNOT_SELF_REDEEM_GIFT: new ApiError("Cannot self-redeem this gift", 50054),
- PAYMENT_SOURCE_REQUIRED: new ApiError("Payment source required to redeem gift", 50070),
- CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: new ApiError("Cannot delete a channel required for Community guilds", 50074),
- INVALID_STICKER_SENT: new ApiError("Invalid sticker sent", 50081),
- CANNOT_EDIT_ARCHIVED_THREAD: new ApiError(
- "Tried to perform an operation on an archived thread, such as editing a message or adding a user to the thread",
- 50083
- ),
- INVALID_THREAD_NOTIFICATION_SETTINGS: new ApiError("Invalid thread notification settings", 50084),
- BEFORE_EARLIER_THAN_THREAD_CREATION_DATE: new ApiError("before value is earlier than the thread creation date", 50085),
- SERVER_NOT_AVAILABLE_IN_YOUR_LOCATION: new ApiError("This server is not available in your location", 50095),
- SERVER_NEEDS_MONETIZATION_ENABLED: new ApiError("This server needs monetization enabled in order to perform this action", 50097),
- TWO_FACTOR_REQUIRED: new ApiError("Two factor is required for this operation", 60003),
- NO_USERS_WITH_DISCORDTAG_EXIST: new ApiError("No users with DiscordTag exist", 80004),
- REACTION_BLOCKED: new ApiError("Reaction was blocked", 90001),
- RESOURCE_OVERLOADED: new ApiError("API resource is currently overloaded. Try again a little later", 130000),
- STAGE_ALREADY_OPEN: new ApiError("The Stage is already open", 150006),
- THREAD_ALREADY_CREATED_FOR_THIS_MESSAGE: new ApiError("A thread has already been created for this message", 160004),
- THREAD_IS_LOCKED: new ApiError("Thread is locked", 160005),
- MAXIMUM_NUMBER_OF_ACTIVE_THREADS: new ApiError("Maximum number of active threads reached", 160006),
- MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS: new ApiError("Maximum number of active announcement threads reached", 160007),
- INVALID_JSON_FOR_UPLOADED_LOTTIE_FILE: new ApiError("Invalid JSON for uploaded Lottie file", 170001),
- LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES: new ApiError("Uploaded Lotties cannot contain rasterized images such as PNG or JPEG", 170002),
- STICKER_MAXIMUM_FRAMERATE: new ApiError("Sticker maximum framerate exceeded", 170003),
- STICKER_MAXIMUM_FRAME_COUNT: new ApiError("Sticker frame count exceeds maximum of {} frames", 170004, undefined, ["1000"]),
- LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS: new ApiError("Lottie animation maximum dimensions exceeded", 170005),
- STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE: new ApiError("Sticker frame rate is either too small or too large", 170006),
- STICKER_ANIMATION_DURATION_MAXIMUM: new ApiError("Sticker animation duration exceeds maximum of {} seconds", 170007, undefined, ["5"]),
-
- //Other errors
- UNKNOWN_VOICE_STATE: new ApiError("Unknown Voice State", 10065, 404)
-};
-
-/**
- * An error encountered while performing an API request (Fosscord only). Here are the potential errors:
- */
-export const FosscordApiErrors = {};
-
-/**
- * The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types:
- * * ALL
- * * MENTIONS
- * @typedef {string} DefaultMessageNotifications
- */
-export const DefaultMessageNotifications = ["ALL", "MENTIONS"];
-
-/**
- * The value set for a team members's membership state:
- * * INVITED
- * * ACCEPTED
- * @typedef {string} MembershipStates
- */
-export const MembershipStates = [
- // They start at 1
- null,
- "INVITED",
- "ACCEPTED"
-];
-
-/**
- * The value set for a webhook's type:
- * * Incoming
- * * Channel Follower
- * @typedef {string} WebhookTypes
- */
-export const WebhookTypes = [
- // They start at 1
- null,
- "Incoming",
- "Channel Follower"
-];
-
-function keyMirror(arr: string[]) {
- let tmp = Object.create(null);
- for (const value of arr) tmp[value] = value;
- return tmp;
-}
diff --git a/util/src/entities/Guild.ts b/util/src/entities/Guild.ts
index c569d53..029a1b0 100644
--- a/util/src/entities/Guild.ts
+++ b/util/src/entities/Guild.ts
@@ -16,6 +16,42 @@
// TODO: guild_scheduled_events
// TODO: stage_instances
// TODO: threads
+// TODO: description
+// TODO: categories:
+// [{
+// "id": 16,
+// "name": {
+// "default": "Anime & Manga",
+// "localizations": {
+// "de": "Anime & Manga",
+// "fr": "Anim\u00e9s et mangas",
+// "ru": "\u0410\u043d\u0438\u043c\u0435 \u0438 \u043c\u0430\u043d\u0433\u0430"
+// }
+// },
+// "is_primary": false
+// }]
+// TODO:
+// primary_category :{
+// id: 1,
+// name: {
+// default: "Gaming",
+// localizations: { de: "Gaming", fr: "Gaming", ru: "\u0418\u0433\u0440\u044b" },
+// is_primary: true,
+// },
+// };
+// TODO:
+// "keywords": [
+// "Genshin Impact",
+// "Paimon",
+// "Honkai Impact",
+// "ARPG",
+// "Open-World",
+// "Waifu",
+// "Anime",
+// "Genshin",
+// "miHoYo",
+// "Gacha"
+// ],
export const PublicGuildRelations = [
"channels",
@@ -66,6 +102,7 @@
@Column({ type: "simple-array" })
features: string[]; //TODO use enum
+ //TODO: https://discord.com/developers/docs/resources/guild#guild-object-guild-features
@Column({ nullable: true })
icon?: string;
diff --git a/util/src/entities/Member.ts b/util/src/entities/Member.ts
index 3835289..66f5d9a 100644
--- a/util/src/entities/Member.ts
+++ b/util/src/entities/Member.ts
@@ -25,7 +25,8 @@
import { HTTPError } from "lambert-server";
import { Role } from "./Role";
import { BaseClassWithoutId } from "./BaseClass";
-import { PublicGuildRelations } from ".";
+import { Ban, PublicGuildRelations } from ".";
+import { DiscordApiErrors } from "../util/Constants";
@Entity("members")
@Index(["id", "guild_id"], { unique: true })
@@ -198,7 +199,10 @@
static async addToGuild(user_id: string, guild_id: string) {
const user = await User.getPublicUser(user_id);
-
+ const isBanned = await Ban.count({ where: { guild_id, user_id } });
+ if (isBanned) {
+ throw DiscordApiErrors.USER_BANNED;
+ }
const { maxGuilds } = Config.get().limits.user;
const guild_count = await Member.count({ id: user_id });
if (guild_count >= maxGuilds) {
diff --git a/util/src/util/ApiError.ts b/util/src/util/ApiError.ts
new file mode 100644
index 0000000..c133e6e
--- /dev/null
+++ b/util/src/util/ApiError.ts
@@ -0,0 +1,27 @@
+export class ApiError extends Error {
+ constructor(
+ readonly message: string,
+ public readonly code: number,
+ public readonly httpStatus: number = 400,
+ public readonly defaultParams?: string[]
+ ) {
+ super(message);
+ }
+
+ withDefaultParams(): ApiError {
+ if (this.defaultParams) return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
+ return this;
+ }
+
+ withParams(...params: (string | number)[]): ApiError {
+ return new ApiError(applyParamsToString(this.message, params), this.code, this.httpStatus);
+ }
+}
+
+export function applyParamsToString(s: string, params: (string | number)[]): string {
+ let newString = s;
+ params.forEach((a) => {
+ newString = newString.replace("{}", "" + a);
+ });
+ return newString;
+}
diff --git a/util/src/util/Constants.ts b/util/src/util/Constants.ts
new file mode 100644
index 0000000..713d59d
--- /dev/null
+++ b/util/src/util/Constants.ts
@@ -0,0 +1,769 @@
+import { ApiError } from "./ApiError";
+
+export const WSCodes = {
+ 1000: "WS_CLOSE_REQUESTED",
+ 4004: "TOKEN_INVALID",
+ 4010: "SHARDING_INVALID",
+ 4011: "SHARDING_REQUIRED",
+ 4013: "INVALID_INTENTS",
+ 4014: "DISALLOWED_INTENTS",
+};
+
+/**
+ * The current status of the client. Here are the available statuses:
+ * * READY: 0
+ * * CONNECTING: 1
+ * * RECONNECTING: 2
+ * * IDLE: 3
+ * * NEARLY: 4
+ * * DISCONNECTED: 5
+ * * WAITING_FOR_GUILDS: 6
+ * * IDENTIFYING: 7
+ * * RESUMING: 8
+ * @typedef {number} Status
+ */
+export const WsStatus = {
+ READY: 0,
+ CONNECTING: 1,
+ RECONNECTING: 2,
+ IDLE: 3,
+ NEARLY: 4,
+ DISCONNECTED: 5,
+ WAITING_FOR_GUILDS: 6,
+ IDENTIFYING: 7,
+ RESUMING: 8,
+};
+
+/**
+ * The current status of a voice connection. Here are the available statuses:
+ * * CONNECTED: 0
+ * * CONNECTING: 1
+ * * AUTHENTICATING: 2
+ * * RECONNECTING: 3
+ * * DISCONNECTED: 4
+ * @typedef {number} VoiceStatus
+ */
+export const VoiceStatus = {
+ CONNECTED: 0,
+ CONNECTING: 1,
+ AUTHENTICATING: 2,
+ RECONNECTING: 3,
+ DISCONNECTED: 4,
+};
+
+export const OPCodes = {
+ DISPATCH: 0,
+ HEARTBEAT: 1,
+ IDENTIFY: 2,
+ STATUS_UPDATE: 3,
+ VOICE_STATE_UPDATE: 4,
+ VOICE_GUILD_PING: 5,
+ RESUME: 6,
+ RECONNECT: 7,
+ REQUEST_GUILD_MEMBERS: 8,
+ INVALID_SESSION: 9,
+ HELLO: 10,
+ HEARTBEAT_ACK: 11,
+};
+
+export const VoiceOPCodes = {
+ IDENTIFY: 0,
+ SELECT_PROTOCOL: 1,
+ READY: 2,
+ HEARTBEAT: 3,
+ SESSION_DESCRIPTION: 4,
+ SPEAKING: 5,
+ HELLO: 8,
+ CLIENT_CONNECT: 12,
+ CLIENT_DISCONNECT: 13,
+};
+
+export const Events = {
+ RATE_LIMIT: "rateLimit",
+ CLIENT_READY: "ready",
+ GUILD_CREATE: "guildCreate",
+ GUILD_DELETE: "guildDelete",
+ GUILD_UPDATE: "guildUpdate",
+ GUILD_UNAVAILABLE: "guildUnavailable",
+ GUILD_AVAILABLE: "guildAvailable",
+ GUILD_MEMBER_ADD: "guildMemberAdd",
+ GUILD_MEMBER_REMOVE: "guildMemberRemove",
+ GUILD_MEMBER_UPDATE: "guildMemberUpdate",
+ GUILD_MEMBER_AVAILABLE: "guildMemberAvailable",
+ GUILD_MEMBER_SPEAKING: "guildMemberSpeaking",
+ GUILD_MEMBERS_CHUNK: "guildMembersChunk",
+ GUILD_INTEGRATIONS_UPDATE: "guildIntegrationsUpdate",
+ GUILD_ROLE_CREATE: "roleCreate",
+ GUILD_ROLE_DELETE: "roleDelete",
+ INVITE_CREATE: "inviteCreate",
+ INVITE_DELETE: "inviteDelete",
+ GUILD_ROLE_UPDATE: "roleUpdate",
+ GUILD_EMOJI_CREATE: "emojiCreate",
+ GUILD_EMOJI_DELETE: "emojiDelete",
+ GUILD_EMOJI_UPDATE: "emojiUpdate",
+ GUILD_BAN_ADD: "guildBanAdd",
+ GUILD_BAN_REMOVE: "guildBanRemove",
+ CHANNEL_CREATE: "channelCreate",
+ CHANNEL_DELETE: "channelDelete",
+ CHANNEL_UPDATE: "channelUpdate",
+ CHANNEL_PINS_UPDATE: "channelPinsUpdate",
+ MESSAGE_CREATE: "message",
+ MESSAGE_DELETE: "messageDelete",
+ MESSAGE_UPDATE: "messageUpdate",
+ MESSAGE_BULK_DELETE: "messageDeleteBulk",
+ MESSAGE_REACTION_ADD: "messageReactionAdd",
+ MESSAGE_REACTION_REMOVE: "messageReactionRemove",
+ MESSAGE_REACTION_REMOVE_ALL: "messageReactionRemoveAll",
+ MESSAGE_REACTION_REMOVE_EMOJI: "messageReactionRemoveEmoji",
+ USER_UPDATE: "userUpdate",
+ PRESENCE_UPDATE: "presenceUpdate",
+ VOICE_SERVER_UPDATE: "voiceServerUpdate",
+ VOICE_STATE_UPDATE: "voiceStateUpdate",
+ VOICE_BROADCAST_SUBSCRIBE: "subscribe",
+ VOICE_BROADCAST_UNSUBSCRIBE: "unsubscribe",
+ TYPING_START: "typingStart",
+ TYPING_STOP: "typingStop",
+ WEBHOOKS_UPDATE: "webhookUpdate",
+ ERROR: "error",
+ WARN: "warn",
+ DEBUG: "debug",
+ SHARD_DISCONNECT: "shardDisconnect",
+ SHARD_ERROR: "shardError",
+ SHARD_RECONNECTING: "shardReconnecting",
+ SHARD_READY: "shardReady",
+ SHARD_RESUME: "shardResume",
+ INVALIDATED: "invalidated",
+ RAW: "raw",
+};
+
+export const ShardEvents = {
+ CLOSE: "close",
+ DESTROYED: "destroyed",
+ INVALID_SESSION: "invalidSession",
+ READY: "ready",
+ RESUMED: "resumed",
+ ALL_READY: "allReady",
+};
+
+/**
+ * The type of Structure allowed to be a partial:
+ * * USER
+ * * CHANNEL (only affects DMChannels)
+ * * GUILD_MEMBER
+ * * MESSAGE
+ * * REACTION
+ * Partials require you to put checks in place when handling data, read the Partials topic listed in the
+ * sidebar for more information.
+ * @typedef {string} PartialType
+ */
+export const PartialTypes = keyMirror(["USER", "CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION"]);
+
+/**
+ * The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events:
+ * * READY
+ * * RESUMED
+ * * GUILD_CREATE
+ * * GUILD_DELETE
+ * * GUILD_UPDATE
+ * * INVITE_CREATE
+ * * INVITE_DELETE
+ * * GUILD_MEMBER_ADD
+ * * GUILD_MEMBER_REMOVE
+ * * GUILD_MEMBER_UPDATE
+ * * GUILD_MEMBERS_CHUNK
+ * * GUILD_INTEGRATIONS_UPDATE
+ * * GUILD_ROLE_CREATE
+ * * GUILD_ROLE_DELETE
+ * * GUILD_ROLE_UPDATE
+ * * GUILD_BAN_ADD
+ * * GUILD_BAN_REMOVE
+ * * GUILD_EMOJIS_UPDATE
+ * * CHANNEL_CREATE
+ * * CHANNEL_DELETE
+ * * CHANNEL_UPDATE
+ * * CHANNEL_PINS_UPDATE
+ * * MESSAGE_CREATE
+ * * MESSAGE_DELETE
+ * * MESSAGE_UPDATE
+ * * MESSAGE_DELETE_BULK
+ * * MESSAGE_REACTION_ADD
+ * * MESSAGE_REACTION_REMOVE
+ * * MESSAGE_REACTION_REMOVE_ALL
+ * * MESSAGE_REACTION_REMOVE_EMOJI
+ * * USER_UPDATE
+ * * PRESENCE_UPDATE
+ * * TYPING_START
+ * * VOICE_STATE_UPDATE
+ * * VOICE_SERVER_UPDATE
+ * * WEBHOOKS_UPDATE
+ * @typedef {string} WSEventType
+ */
+export const WSEvents = keyMirror([
+ "READY",
+ "RESUMED",
+ "GUILD_CREATE",
+ "GUILD_DELETE",
+ "GUILD_UPDATE",
+ "INVITE_CREATE",
+ "INVITE_DELETE",
+ "GUILD_MEMBER_ADD",
+ "GUILD_MEMBER_REMOVE",
+ "GUILD_MEMBER_UPDATE",
+ "GUILD_MEMBERS_CHUNK",
+ "GUILD_INTEGRATIONS_UPDATE",
+ "GUILD_ROLE_CREATE",
+ "GUILD_ROLE_DELETE",
+ "GUILD_ROLE_UPDATE",
+ "GUILD_BAN_ADD",
+ "GUILD_BAN_REMOVE",
+ "GUILD_EMOJIS_UPDATE",
+ "CHANNEL_CREATE",
+ "CHANNEL_DELETE",
+ "CHANNEL_UPDATE",
+ "CHANNEL_PINS_UPDATE",
+ "MESSAGE_CREATE",
+ "MESSAGE_DELETE",
+ "MESSAGE_UPDATE",
+ "MESSAGE_DELETE_BULK",
+ "MESSAGE_REACTION_ADD",
+ "MESSAGE_REACTION_REMOVE",
+ "MESSAGE_REACTION_REMOVE_ALL",
+ "MESSAGE_REACTION_REMOVE_EMOJI",
+ "USER_UPDATE",
+ "PRESENCE_UPDATE",
+ "TYPING_START",
+ "VOICE_STATE_UPDATE",
+ "VOICE_SERVER_UPDATE",
+ "WEBHOOKS_UPDATE",
+]);
+
+/**
+ * The type of a message, e.g. `DEFAULT`. Here are the available types:
+ * * DEFAULT
+ * * RECIPIENT_ADD
+ * * RECIPIENT_REMOVE
+ * * CALL
+ * * CHANNEL_NAME_CHANGE
+ * * CHANNEL_ICON_CHANGE
+ * * PINS_ADD
+ * * GUILD_MEMBER_JOIN
+ * * USER_PREMIUM_GUILD_SUBSCRIPTION
+ * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1
+ * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2
+ * * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3
+ * * CHANNEL_FOLLOW_ADD
+ * * GUILD_DISCOVERY_DISQUALIFIED
+ * * GUILD_DISCOVERY_REQUALIFIED
+ * * REPLY
+ * @typedef {string} MessageType
+ */
+export const MessageTypes = [
+ "DEFAULT",
+ "RECIPIENT_ADD",
+ "RECIPIENT_REMOVE",
+ "CALL",
+ "CHANNEL_NAME_CHANGE",
+ "CHANNEL_ICON_CHANGE",
+ "PINS_ADD",
+ "GUILD_MEMBER_JOIN",
+ "USER_PREMIUM_GUILD_SUBSCRIPTION",
+ "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1",
+ "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2",
+ "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3",
+ "CHANNEL_FOLLOW_ADD",
+ null,
+ "GUILD_DISCOVERY_DISQUALIFIED",
+ "GUILD_DISCOVERY_REQUALIFIED",
+ null,
+ null,
+ null,
+ "REPLY",
+];
+
+/**
+ * The types of messages that are `System`. The available types are `MessageTypes` excluding:
+ * * DEFAULT
+ * * REPLY
+ * @typedef {string} SystemMessageType
+ */
+export const SystemMessageTypes = MessageTypes.filter(
+ (type: string | null) => type && type !== "DEFAULT" && type !== "REPLY"
+);
+
+/**
+ * Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users
+ * The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types:
+ * * PLAYING
+ * * STREAMING
+ * * LISTENING
+ * * WATCHING
+ * * CUSTOM_STATUS
+ * * COMPETING
+ * @typedef {string} ActivityType
+ */
+export const ActivityTypes = ["PLAYING", "STREAMING", "LISTENING", "WATCHING", "CUSTOM_STATUS", "COMPETING"];
+
+export const ChannelTypes = {
+ TEXT: 0,
+ DM: 1,
+ VOICE: 2,
+ GROUP: 3,
+ CATEGORY: 4,
+ NEWS: 5,
+ STORE: 6,
+};
+
+export const ClientApplicationAssetTypes = {
+ SMALL: 1,
+ BIG: 2,
+};
+
+export const Colors = {
+ DEFAULT: 0x000000,
+ WHITE: 0xffffff,
+ AQUA: 0x1abc9c,
+ GREEN: 0x2ecc71,
+ BLUE: 0x3498db,
+ YELLOW: 0xffff00,
+ PURPLE: 0x9b59b6,
+ LUMINOUS_VIVID_PINK: 0xe91e63,
+ GOLD: 0xf1c40f,
+ ORANGE: 0xe67e22,
+ RED: 0xe74c3c,
+ GREY: 0x95a5a6,
+ NAVY: 0x34495e,
+ DARK_AQUA: 0x11806a,
+ DARK_GREEN: 0x1f8b4c,
+ DARK_BLUE: 0x206694,
+ DARK_PURPLE: 0x71368a,
+ DARK_VIVID_PINK: 0xad1457,
+ DARK_GOLD: 0xc27c0e,
+ DARK_ORANGE: 0xa84300,
+ DARK_RED: 0x992d22,
+ DARK_GREY: 0x979c9f,
+ DARKER_GREY: 0x7f8c8d,
+ LIGHT_GREY: 0xbcc0c0,
+ DARK_NAVY: 0x2c3e50,
+ BLURPLE: 0x7289da,
+ GREYPLE: 0x99aab5,
+ DARK_BUT_NOT_BLACK: 0x2c2f33,
+ NOT_QUITE_BLACK: 0x23272a,
+};
+
+/**
+ * The value set for the explicit content filter levels for a guild:
+ * * DISABLED
+ * * MEMBERS_WITHOUT_ROLES
+ * * ALL_MEMBERS
+ * @typedef {string} ExplicitContentFilterLevel
+ */
+export const ExplicitContentFilterLevels = ["DISABLED", "MEMBERS_WITHOUT_ROLES", "ALL_MEMBERS"];
+
+/**
+ * The value set for the verification levels for a guild:
+ * * NONE
+ * * LOW
+ * * MEDIUM
+ * * HIGH
+ * * VERY_HIGH
+ * @typedef {string} VerificationLevel
+ */
+export const VerificationLevels = ["NONE", "LOW", "MEDIUM", "HIGH", "VERY_HIGH"];
+
+/**
+ * An error encountered while performing an API request. Here are the potential errors:
+ * * GENERAL_ERROR
+ * * UNKNOWN_ACCOUNT
+ * * UNKNOWN_APPLICATION
+ * * UNKNOWN_CHANNEL
+ * * UNKNOWN_GUILD
+ * * UNKNOWN_INTEGRATION
+ * * UNKNOWN_INVITE
+ * * UNKNOWN_MEMBER
+ * * UNKNOWN_MESSAGE
+ * * UNKNOWN_OVERWRITE
+ * * UNKNOWN_PROVIDER
+ * * UNKNOWN_ROLE
+ * * UNKNOWN_TOKEN
+ * * UNKNOWN_USER
+ * * UNKNOWN_EMOJI
+ * * UNKNOWN_WEBHOOK
+ * * UNKNOWN_WEBHOOK_SERVICE
+ * * UNKNOWN_SESSION
+ * * UNKNOWN_BAN
+ * * UNKNOWN_SKU
+ * * UNKNOWN_STORE_LISTING
+ * * UNKNOWN_ENTITLEMENT
+ * * UNKNOWN_BUILD
+ * * UNKNOWN_LOBBY
+ * * UNKNOWN_BRANCH
+ * * UNKNOWN_STORE_DIRECTORY_LAYOUT
+ * * UNKNOWN_REDISTRIBUTABLE
+ * * UNKNOWN_GIFT_CODE
+ * * UNKNOWN_STREAM
+ * * UNKNOWN_PREMIUM_SERVER_SUBSCRIBE_COOLDOWN
+ * * UNKNOWN_GUILD_TEMPLATE
+ * * UNKNOWN_DISCOVERABLE_SERVER_CATEGORY
+ * * UNKNOWN_STICKER
+ * * UNKNOWN_INTERACTION
+ * * UNKNOWN_APPLICATION_COMMAND
+ * * UNKNOWN_APPLICATION_COMMAND_PERMISSIONS
+ * * UNKNOWN_STAGE_INSTANCE
+ * * UNKNOWN_GUILD_MEMBER_VERIFICATION_FORM
+ * * UNKNOWN_GUILD_WELCOME_SCREEN
+ * * UNKNOWN_GUILD_SCHEDULED_EVENT
+ * * UNKNOWN_GUILD_SCHEDULED_EVENT_USER
+ * * BOT_PROHIBITED_ENDPOINT
+ * * BOT_ONLY_ENDPOINT
+ * * EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT
+ * * ACTION_NOT_AUTHORIZED_ON_APPLICATION
+ * * SLOWMODE_RATE_LIMIT
+ * * ONLY_OWNER
+ * * ANNOUNCEMENT_RATE_LIMITS
+ * * CHANNEL_WRITE_RATELIMIT
+ * * WORDS_NOT_ALLOWED
+ * * GUILD_PREMIUM_LEVEL_TOO_LOW
+ * * MAXIMUM_GUILDS
+ * * MAXIMUM_FRIENDS
+ * * MAXIMUM_PINS
+ * * MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED
+ * * MAXIMUM_ROLES
+ * * MAXIMUM_WEBHOOKS
+ * * MAXIMUM_NUMBER_OF_EMOJIS_REACHED
+ * * MAXIMUM_REACTIONS
+ * * MAXIMUM_CHANNELS
+ * * MAXIMUM_ATTACHMENTS
+ * * MAXIMUM_INVITES
+ * * MAXIMUM_ANIMATED_EMOJIS
+ * * MAXIMUM_SERVER_MEMBERS
+ * * MAXIMUM_SERVER_CATEGORIES
+ * * GUILD_ALREADY_HAS_TEMPLATE
+ * * MAXIMUM_THREAD_PARTICIPANTS
+ * * MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS
+ * * MAXIMUM_BANS_FETCHES
+ * * MAXIMUM_STICKERS
+ * * MAXIMUM_PRUNE_REQUESTS
+ * * UNAUTHORIZED
+ * * ACCOUNT_VERIFICATION_REQUIRED
+ * * OPENING_DIRECT_MESSAGES_TOO_FAST
+ * * REQUEST_ENTITY_TOO_LARGE
+ * * FEATURE_TEMPORARILY_DISABLED
+ * * USER_BANNED
+ * * TARGET_USER_IS_NOT_CONNECTED_TO_VOICE
+ * * ALREADY_CROSSPOSTED
+ * * APPLICATION_COMMAND_ALREADY_EXISTS
+ * * MISSING_ACCESS
+ * * INVALID_ACCOUNT_TYPE
+ * * CANNOT_EXECUTE_ON_DM
+ * * EMBED_DISABLED
+ * * CANNOT_EDIT_MESSAGE_BY_OTHER
+ * * CANNOT_SEND_EMPTY_MESSAGE
+ * * CANNOT_MESSAGE_USER
+ * * CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL
+ * * CHANNEL_VERIFICATION_LEVEL_TOO_HIGH
+ * * OAUTH2_APPLICATION_BOT_ABSENT
+ * * MAXIMUM_OAUTH2_APPLICATIONS
+ * * INVALID_OAUTH_STATE
+ * * MISSING_PERMISSIONS
+ * * INVALID_AUTHENTICATION_TOKEN
+ * * NOTE_TOO_LONG
+ * * INVALID_BULK_DELETE_QUANTITY
+ * * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL
+ * * INVALID_OR_TAKEN_INVITE_CODE
+ * * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE
+ * * CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE
+ * * INVALID_OAUTH_TOKEN
+ * * MISSING_REQUIRED_OAUTH2_SCOPE
+ * * INVALID_WEBHOOK_TOKEN_PROVIDED
+ * * INVALID_ROLE
+ * * INVALID_RECIPIENT
+ * * BULK_DELETE_MESSAGE_TOO_OLD
+ * * INVALID_FORM_BODY
+ * * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT
+ * * INVALID_API_VERSION
+ * * FILE_EXCEEDS_MAXIMUM_SIZE
+ * * INVALID_FILE_UPLOADED
+ * * CANNOT_SELF_REDEEM_GIFT
+ * * PAYMENT_SOURCE_REQUIRED
+ * * CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL
+ * * INVALID_STICKER_SENT
+ * * CANNOT_EDIT_ARCHIVED_THREAD
+ * * INVALID_THREAD_NOTIFICATION_SETTINGS
+ * * BEFORE_EARLIER_THAN_THREAD_CREATION_DATE
+ * * SERVER_NOT_AVAILABLE_IN_YOUR_LOCATION
+ * * SERVER_NEEDS_MONETIZATION_ENABLED
+ * * TWO_FACTOR_REQUIRED
+ * * NO_USERS_WITH_DISCORDTAG_EXIST
+ * * REACTION_BLOCKED
+ * * RESOURCE_OVERLOADED
+ * * STAGE_ALREADY_OPEN
+ * * THREAD_ALREADY_CREATED_FOR_THIS_MESSAGE
+ * * THREAD_IS_LOCKED
+ * * MAXIMUM_NUMBER_OF_ACTIVE_THREADS
+ * * MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS
+ * * INVALID_JSON_FOR_UPLOADED_LOTTIE_FILE
+ * * LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES
+ * * STICKER_MAXIMUM_FRAMERATE
+ * * STICKER_MAXIMUM_FRAME_COUNT
+ * * LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS
+ * * STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE
+ * * STICKER_ANIMATION_DURATION_MAXIMUM
+ * * UNKNOWN_VOICE_STATE
+ * @typedef {string} APIError
+ */
+export const DiscordApiErrors = {
+ //https://discord.com/developers/docs/topics/opcodes-and-status-codes#json-json-error-codes
+ GENERAL_ERROR: new ApiError("General error (such as a malformed request body, amongst other things)", 0),
+ UNKNOWN_ACCOUNT: new ApiError("Unknown account", 10001),
+ UNKNOWN_APPLICATION: new ApiError("Unknown application", 10002),
+ UNKNOWN_CHANNEL: new ApiError("Unknown channel", 10003),
+ UNKNOWN_GUILD: new ApiError("Unknown guild", 10004),
+ UNKNOWN_INTEGRATION: new ApiError("Unknown integration", 10005),
+ UNKNOWN_INVITE: new ApiError("Unknown invite", 10006),
+ UNKNOWN_MEMBER: new ApiError("Unknown member", 10007),
+ UNKNOWN_MESSAGE: new ApiError("Unknown message", 10008),
+ UNKNOWN_OVERWRITE: new ApiError("Unknown permission overwrite", 10009),
+ UNKNOWN_PROVIDER: new ApiError("Unknown provider", 10010),
+ UNKNOWN_ROLE: new ApiError("Unknown role", 10011),
+ UNKNOWN_TOKEN: new ApiError("Unknown token", 10012),
+ UNKNOWN_USER: new ApiError("Unknown user", 10013),
+ UNKNOWN_EMOJI: new ApiError("Unknown emoji", 10014),
+ UNKNOWN_WEBHOOK: new ApiError("Unknown webhook", 10015),
+ UNKNOWN_WEBHOOK_SERVICE: new ApiError("Unknown webhook service", 10016),
+ UNKNOWN_SESSION: new ApiError("Unknown session", 10020),
+ UNKNOWN_BAN: new ApiError("Unknown ban", 10026),
+ UNKNOWN_SKU: new ApiError("Unknown SKU", 10027),
+ UNKNOWN_STORE_LISTING: new ApiError("Unknown Store Listing", 10028),
+ UNKNOWN_ENTITLEMENT: new ApiError("Unknown entitlement", 10029),
+ UNKNOWN_BUILD: new ApiError("Unknown build", 10030),
+ UNKNOWN_LOBBY: new ApiError("Unknown lobby", 10031),
+ UNKNOWN_BRANCH: new ApiError("Unknown branch", 10032),
+ UNKNOWN_STORE_DIRECTORY_LAYOUT: new ApiError("Unknown store directory layout", 10033),
+ UNKNOWN_REDISTRIBUTABLE: new ApiError("Unknown redistributable", 10036),
+ UNKNOWN_GIFT_CODE: new ApiError("Unknown gift code", 10038),
+ UNKNOWN_STREAM: new ApiError("Unknown stream", 10049),
+ UNKNOWN_PREMIUM_SERVER_SUBSCRIBE_COOLDOWN: new ApiError("Unknown premium server subscribe cooldown", 10050),
+ UNKNOWN_GUILD_TEMPLATE: new ApiError("Unknown guild template", 10057),
+ UNKNOWN_DISCOVERABLE_SERVER_CATEGORY: new ApiError("Unknown discoverable server category", 10059),
+ UNKNOWN_STICKER: new ApiError("Unknown sticker", 10060),
+ UNKNOWN_INTERACTION: new ApiError("Unknown interaction", 10062),
+ UNKNOWN_APPLICATION_COMMAND: new ApiError("Unknown application command", 10063),
+ UNKNOWN_APPLICATION_COMMAND_PERMISSIONS: new ApiError("Unknown application command permissions", 10066),
+ UNKNOWN_STAGE_INSTANCE: new ApiError("Unknown Stage Instance", 10067),
+ UNKNOWN_GUILD_MEMBER_VERIFICATION_FORM: new ApiError("Unknown Guild Member Verification Form", 10068),
+ UNKNOWN_GUILD_WELCOME_SCREEN: new ApiError("Unknown Guild Welcome Screen", 10069),
+ UNKNOWN_GUILD_SCHEDULED_EVENT: new ApiError("Unknown Guild Scheduled Event", 10070),
+ UNKNOWN_GUILD_SCHEDULED_EVENT_USER: new ApiError("Unknown Guild Scheduled Event User", 10071),
+ BOT_PROHIBITED_ENDPOINT: new ApiError("Bots cannot use this endpoint", 20001),
+ BOT_ONLY_ENDPOINT: new ApiError("Only bots can use this endpoint", 20002),
+ EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT: new ApiError(
+ "Explicit content cannot be sent to the desired recipient(s)",
+ 20009
+ ),
+ ACTION_NOT_AUTHORIZED_ON_APPLICATION: new ApiError(
+ "You are not authorized to perform this action on this application",
+ 20012
+ ),
+ SLOWMODE_RATE_LIMIT: new ApiError("This action cannot be performed due to slowmode rate limit", 20016),
+ ONLY_OWNER: new ApiError("Only the owner of this account can perform this action", 20018),
+ ANNOUNCEMENT_RATE_LIMITS: new ApiError("This message cannot be edited due to announcement rate limits", 20022),
+ CHANNEL_WRITE_RATELIMIT: new ApiError("The channel you are writing has hit the write rate limit", 20028),
+ WORDS_NOT_ALLOWED: new ApiError(
+ "Your Stage topic, server name, server description, or channel names contain words that are not allowed",
+ 20031
+ ),
+ GUILD_PREMIUM_LEVEL_TOO_LOW: new ApiError("Guild premium subscription level too low", 20035),
+ MAXIMUM_GUILDS: new ApiError("Maximum number of guilds reached ({})", 30001, undefined, ["100"]),
+ MAXIMUM_FRIENDS: new ApiError("Maximum number of friends reached ({})", 30002, undefined, ["1000"]),
+ MAXIMUM_PINS: new ApiError("Maximum number of pins reached for the channel ({})", 30003, undefined, ["50"]),
+ MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED: new ApiError("Maximum number of recipients reached ({})", 30004, undefined, [
+ "10",
+ ]),
+ MAXIMUM_ROLES: new ApiError("Maximum number of guild roles reached ({})", 30005, undefined, ["250"]),
+ MAXIMUM_WEBHOOKS: new ApiError("Maximum number of webhooks reached ({})", 30007, undefined, ["10"]),
+ MAXIMUM_NUMBER_OF_EMOJIS_REACHED: new ApiError("Maximum number of emojis reached", 30008),
+ MAXIMUM_REACTIONS: new ApiError("Maximum number of reactions reached ({})", 30010, undefined, ["20"]),
+ MAXIMUM_CHANNELS: new ApiError("Maximum number of guild channels reached ({})", 30013, undefined, ["500"]),
+ MAXIMUM_ATTACHMENTS: new ApiError("Maximum number of attachments in a message reached ({})", 30015, undefined, [
+ "10",
+ ]),
+ MAXIMUM_INVITES: new ApiError("Maximum number of invites reached ({})", 30016, undefined, ["1000"]),
+ MAXIMUM_ANIMATED_EMOJIS: new ApiError("Maximum number of animated emojis reached", 30018),
+ MAXIMUM_SERVER_MEMBERS: new ApiError("Maximum number of server members reached", 30019),
+ MAXIMUM_SERVER_CATEGORIES: new ApiError(
+ "Maximum number of server categories has been reached ({})",
+ 30030,
+ undefined,
+ ["5"]
+ ),
+ GUILD_ALREADY_HAS_TEMPLATE: new ApiError("Guild already has a template", 30031),
+ MAXIMUM_THREAD_PARTICIPANTS: new ApiError("Max number of thread participants has been reached", 30033),
+ MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS: new ApiError(
+ "Maximum number of bans for non-guild members have been exceeded",
+ 30035
+ ),
+ MAXIMUM_BANS_FETCHES: new ApiError("Maximum number of bans fetches has been reached", 30037),
+ MAXIMUM_STICKERS: new ApiError("Maximum number of stickers reached", 30039),
+ MAXIMUM_PRUNE_REQUESTS: new ApiError("Maximum number of prune requests has been reached. Try again later", 30040),
+ UNAUTHORIZED: new ApiError("Unauthorized. Provide a valid token and try again", 40001),
+ ACCOUNT_VERIFICATION_REQUIRED: new ApiError(
+ "You need to verify your account in order to perform this action",
+ 40002
+ ),
+ OPENING_DIRECT_MESSAGES_TOO_FAST: new ApiError("You are opening direct messages too fast", 40003),
+ REQUEST_ENTITY_TOO_LARGE: new ApiError("Request entity too large. Try sending something smaller in size", 40005),
+ FEATURE_TEMPORARILY_DISABLED: new ApiError("This feature has been temporarily disabled server-side", 40006),
+ USER_BANNED: new ApiError("The user is banned from this guild", 40007),
+ TARGET_USER_IS_NOT_CONNECTED_TO_VOICE: new ApiError("Target user is not connected to voice", 40032),
+ ALREADY_CROSSPOSTED: new ApiError("This message has already been crossposted", 40033),
+ APPLICATION_COMMAND_ALREADY_EXISTS: new ApiError("An application command with that name already exists", 40041),
+ MISSING_ACCESS: new ApiError("Missing access", 50001),
+ INVALID_ACCOUNT_TYPE: new ApiError("Invalid account type", 50002),
+ CANNOT_EXECUTE_ON_DM: new ApiError("Cannot execute action on a DM channel", 50003),
+ EMBED_DISABLED: new ApiError("Guild widget disabled", 50004),
+ CANNOT_EDIT_MESSAGE_BY_OTHER: new ApiError("Cannot edit a message authored by another user", 50005),
+ CANNOT_SEND_EMPTY_MESSAGE: new ApiError("Cannot send an empty message", 50006),
+ CANNOT_MESSAGE_USER: new ApiError("Cannot send messages to this user", 50007),
+ CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: new ApiError("Cannot send messages in a voice channel", 50008),
+ CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: new ApiError(
+ "Channel verification level is too high for you to gain access",
+ 50009
+ ),
+ OAUTH2_APPLICATION_BOT_ABSENT: new ApiError("OAuth2 application does not have a bot", 50010),
+ MAXIMUM_OAUTH2_APPLICATIONS: new ApiError("OAuth2 application limit reached", 50011),
+ INVALID_OAUTH_STATE: new ApiError("Invalid OAuth2 state", 50012),
+ MISSING_PERMISSIONS: new ApiError("You lack permissions to perform that action", 50013),
+ INVALID_AUTHENTICATION_TOKEN: new ApiError("Invalid authentication token provided", 50014),
+ NOTE_TOO_LONG: new ApiError("Note was too long", 50015),
+ INVALID_BULK_DELETE_QUANTITY: new ApiError(
+ "Provided too few or too many messages to delete. Must provide at least {} and fewer than {} messages to delete",
+ 50016,
+ undefined,
+ ["2", "100"]
+ ),
+ CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: new ApiError(
+ "A message can only be pinned to the channel it was sent in",
+ 50019
+ ),
+ INVALID_OR_TAKEN_INVITE_CODE: new ApiError("Invite code was either invalid or taken", 50020),
+ CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: new ApiError("Cannot execute action on a system message", 50021),
+ CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE: new ApiError("Cannot execute action on this channel type", 50024),
+ INVALID_OAUTH_TOKEN: new ApiError("Invalid OAuth2 access token provided", 50025),
+ MISSING_REQUIRED_OAUTH2_SCOPE: new ApiError("Missing required OAuth2 scope", 50026),
+ INVALID_WEBHOOK_TOKEN_PROVIDED: new ApiError("Invalid webhook token provided", 50027),
+ INVALID_ROLE: new ApiError("Invalid role", 50028),
+ INVALID_RECIPIENT: new ApiError("Invalid Recipient(s)", 50033),
+ BULK_DELETE_MESSAGE_TOO_OLD: new ApiError("A message provided was too old to bulk delete", 50034),
+ INVALID_FORM_BODY: new ApiError(
+ "Invalid form body (returned for both application/json and multipart/form-data bodies), or invalid Content-Type provided",
+ 50035
+ ),
+ INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: new ApiError(
+ "An invite was accepted to a guild the application's bot is not in",
+ 50036
+ ),
+ INVALID_API_VERSION: new ApiError("Invalid API version provided", 50041),
+ FILE_EXCEEDS_MAXIMUM_SIZE: new ApiError("File uploaded exceeds the maximum size", 50045),
+ INVALID_FILE_UPLOADED: new ApiError("Invalid file uploaded", 50046),
+ CANNOT_SELF_REDEEM_GIFT: new ApiError("Cannot self-redeem this gift", 50054),
+ PAYMENT_SOURCE_REQUIRED: new ApiError("Payment source required to redeem gift", 50070),
+ CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: new ApiError(
+ "Cannot delete a channel required for Community guilds",
+ 50074
+ ),
+ INVALID_STICKER_SENT: new ApiError("Invalid sticker sent", 50081),
+ CANNOT_EDIT_ARCHIVED_THREAD: new ApiError(
+ "Tried to perform an operation on an archived thread, such as editing a message or adding a user to the thread",
+ 50083
+ ),
+ INVALID_THREAD_NOTIFICATION_SETTINGS: new ApiError("Invalid thread notification settings", 50084),
+ BEFORE_EARLIER_THAN_THREAD_CREATION_DATE: new ApiError(
+ "before value is earlier than the thread creation date",
+ 50085
+ ),
+ SERVER_NOT_AVAILABLE_IN_YOUR_LOCATION: new ApiError("This server is not available in your location", 50095),
+ SERVER_NEEDS_MONETIZATION_ENABLED: new ApiError(
+ "This server needs monetization enabled in order to perform this action",
+ 50097
+ ),
+ TWO_FACTOR_REQUIRED: new ApiError("Two factor is required for this operation", 60003),
+ NO_USERS_WITH_DISCORDTAG_EXIST: new ApiError("No users with DiscordTag exist", 80004),
+ REACTION_BLOCKED: new ApiError("Reaction was blocked", 90001),
+ RESOURCE_OVERLOADED: new ApiError("API resource is currently overloaded. Try again a little later", 130000),
+ STAGE_ALREADY_OPEN: new ApiError("The Stage is already open", 150006),
+ THREAD_ALREADY_CREATED_FOR_THIS_MESSAGE: new ApiError("A thread has already been created for this message", 160004),
+ THREAD_IS_LOCKED: new ApiError("Thread is locked", 160005),
+ MAXIMUM_NUMBER_OF_ACTIVE_THREADS: new ApiError("Maximum number of active threads reached", 160006),
+ MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS: new ApiError(
+ "Maximum number of active announcement threads reached",
+ 160007
+ ),
+ INVALID_JSON_FOR_UPLOADED_LOTTIE_FILE: new ApiError("Invalid JSON for uploaded Lottie file", 170001),
+ LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES: new ApiError(
+ "Uploaded Lotties cannot contain rasterized images such as PNG or JPEG",
+ 170002
+ ),
+ STICKER_MAXIMUM_FRAMERATE: new ApiError("Sticker maximum framerate exceeded", 170003),
+ STICKER_MAXIMUM_FRAME_COUNT: new ApiError("Sticker frame count exceeds maximum of {} frames", 170004, undefined, [
+ "1000",
+ ]),
+ LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS: new ApiError("Lottie animation maximum dimensions exceeded", 170005),
+ STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE: new ApiError(
+ "Sticker frame rate is either too small or too large",
+ 170006
+ ),
+ STICKER_ANIMATION_DURATION_MAXIMUM: new ApiError(
+ "Sticker animation duration exceeds maximum of {} seconds",
+ 170007,
+ undefined,
+ ["5"]
+ ),
+
+ //Other errors
+ UNKNOWN_VOICE_STATE: new ApiError("Unknown Voice State", 10065, 404),
+};
+
+/**
+ * An error encountered while performing an API request (Fosscord only). Here are the potential errors:
+ */
+export const FosscordApiErrors = {};
+
+/**
+ * The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types:
+ * * ALL
+ * * MENTIONS
+ * @typedef {string} DefaultMessageNotifications
+ */
+export const DefaultMessageNotifications = ["ALL", "MENTIONS"];
+
+/**
+ * The value set for a team members's membership state:
+ * * INVITED
+ * * ACCEPTED
+ * @typedef {string} MembershipStates
+ */
+export const MembershipStates = [
+ // They start at 1
+ null,
+ "INVITED",
+ "ACCEPTED",
+];
+
+/**
+ * The value set for a webhook's type:
+ * * Incoming
+ * * Channel Follower
+ * @typedef {string} WebhookTypes
+ */
+export const WebhookTypes = [
+ // They start at 1
+ null,
+ "Incoming",
+ "Channel Follower",
+];
+
+function keyMirror(arr: string[]) {
+ let tmp = Object.create(null);
+ for (const value of arr) tmp[value] = value;
+ return tmp;
+}
diff --git a/util/src/util/index.ts b/util/src/util/index.ts
index 16b98ca..4e92f01 100644
--- a/util/src/util/index.ts
+++ b/util/src/util/index.ts
@@ -1,13 +1,14 @@
-export * from "./Database";
-
+export * from "./ApiError";
export * from "./BitField";
-export * from "./Config";
export * from "./checkToken";
+export * from "./Config";
+export * from "./Constants";
+export * from "./Database";
export * from "./Event";
export * from "./Intents";
export * from "./MessageFlags";
export * from "./Permissions";
-export * from "./Snowflake";
export * from "./RabbitMQ";
export * from "./Regex";
+export * from "./Snowflake";
export * from "./String";