summary refs log tree commit diff
path: root/util/src
diff options
context:
space:
mode:
Diffstat (limited to 'util/src')
-rw-r--r--util/src/entities/Application.ts111
-rw-r--r--util/src/entities/AuditLog.ts (renamed from util/src/models/AuditLog.ts)203
-rw-r--r--util/src/entities/Ban.ts34
-rw-r--r--util/src/entities/BaseClass.ts61
-rw-r--r--util/src/entities/Channel.ts104
-rw-r--r--util/src/entities/ConnectedAccount.ts29
-rw-r--r--util/src/entities/Emoji.ts39
-rw-r--r--util/src/entities/Guild.ts179
-rw-r--r--util/src/entities/Invite.ts60
-rw-r--r--util/src/entities/Member.ts87
-rw-r--r--util/src/entities/Message.ts260
-rw-r--r--util/src/entities/RateLimit.ts25
-rw-r--r--util/src/entities/ReadState.ts35
-rw-r--r--util/src/entities/Relationship.ts26
-rw-r--r--util/src/entities/Role.ts41
-rw-r--r--util/src/entities/Team.ts27
-rw-r--r--util/src/entities/TeamMember.ts31
-rw-r--r--util/src/entities/Template.ts33
-rw-r--r--util/src/entities/User.ts188
-rw-r--r--util/src/entities/VoiceState.ts44
-rw-r--r--util/src/entities/Webhook.ts40
-rw-r--r--util/src/entities/index.ts21
-rw-r--r--util/src/entities/schema.json5725
-rw-r--r--util/src/index.ts14
-rw-r--r--util/src/interfaces/Activity.ts43
-rw-r--r--util/src/interfaces/Event.ts (renamed from util/src/models/Event.ts)30
-rw-r--r--util/src/interfaces/Interaction.ts (renamed from util/src/models/Interaction.ts)2
-rw-r--r--util/src/interfaces/Presence.ts10
-rw-r--r--util/src/interfaces/Status.ts (renamed from util/src/models/Status.ts)6
-rw-r--r--util/src/interfaces/index.ts5
-rw-r--r--util/src/models/Activity.ts132
-rw-r--r--util/src/models/Application.ts67
-rw-r--r--util/src/models/Ban.ts32
-rw-r--r--util/src/models/Channel.ts111
-rw-r--r--util/src/models/Emoji.ts29
-rw-r--r--util/src/models/Guild.ts159
-rw-r--r--util/src/models/Invite.ts95
-rw-r--r--util/src/models/Member.ts109
-rw-r--r--util/src/models/Message.ts368
-rw-r--r--util/src/models/RateLimit.ts25
-rw-r--r--util/src/models/ReadState.ts26
-rw-r--r--util/src/models/Role.ts42
-rw-r--r--util/src/models/Team.ts17
-rw-r--r--util/src/models/Template.ts51
-rw-r--r--util/src/models/User.ts252
-rw-r--r--util/src/models/VoiceState.ts34
-rw-r--r--util/src/models/Webhook.ts84
-rw-r--r--util/src/models/index.ts93
-rw-r--r--util/src/util/BitField.ts12
-rw-r--r--util/src/util/Config.ts291
-rw-r--r--util/src/util/Constants.ts28
-rw-r--r--util/src/util/Database.ts170
-rw-r--r--util/src/util/Event.ts2
-rw-r--r--util/src/util/MongoBigInt.ts83
-rw-r--r--util/src/util/Permissions.ts31
-rw-r--r--util/src/util/RabbitMQ.ts21
-rw-r--r--util/src/util/UserFlags.ts22
-rw-r--r--util/src/util/checkToken.ts13
-rw-r--r--util/src/util/index.ts3
59 files changed, 7407 insertions, 2508 deletions
diff --git a/util/src/entities/Application.ts b/util/src/entities/Application.ts
new file mode 100644

index 00000000..64b5d2e2 --- /dev/null +++ b/util/src/entities/Application.ts
@@ -0,0 +1,111 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { Team } from "./Team"; + +@Entity("applications") +export class Application extends BaseClass { + @Column() + name: string; + + @Column() + icon?: string; + + @Column() + description: string; + + @Column("simple-array") + rpc_origins?: string[]; + + @Column() + bot_public: boolean; + + @Column() + bot_require_code_grant: boolean; + + @Column() + terms_of_service_url?: string; + + @Column() + privacy_policy_url?: string; + + @Column() + owner_id: string; + + @Column() + summary?: string; + + @Column() + verify_key: string; + + @Column() + team_id: string; + + @JoinColumn({ name: "team_id" }) + @ManyToOne(() => Team, (team: Team) => team.id) + team?: Team; + + @Column() + guild_id: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; // if this application is a game sold, this field will be the guild to which it has been linked + + @Column() + primary_sku_id?: string; // if this application is a game sold, this field will be the id of the "Game SKU" that is created, + + @Column() + slug?: string; // if this application is a game sold, this field will be the URL slug that links to the store page + + @Column() + cover_image?: string; // the application's default rich presence invite cover image hash + + @Column() + flags: number; // the application's public flags +} + +export interface ApplicationCommand { + id: string; + application_id: string; + name: string; + description: string; + options?: ApplicationCommandOption[]; +} + +export interface ApplicationCommandOption { + type: ApplicationCommandOptionType; + name: string; + description: string; + required?: boolean; + choices?: ApplicationCommandOptionChoice[]; + options?: ApplicationCommandOption[]; +} + +export interface ApplicationCommandOptionChoice { + name: string; + value: string | number; +} + +export enum ApplicationCommandOptionType { + SUB_COMMAND = 1, + SUB_COMMAND_GROUP = 2, + STRING = 3, + INTEGER = 4, + BOOLEAN = 5, + USER = 6, + CHANNEL = 7, + ROLE = 8, +} + +export interface ApplicationCommandInteractionData { + id: string; + name: string; + options?: ApplicationCommandInteractionDataOption[]; +} + +export interface ApplicationCommandInteractionDataOption { + name: string; + value?: any; + options?: ApplicationCommandInteractionDataOption[]; +} diff --git a/util/src/models/AuditLog.ts b/util/src/entities/AuditLog.ts
index 02b2c444..53e99261 100644 --- a/util/src/models/AuditLog.ts +++ b/util/src/entities/AuditLog.ts
@@ -1,20 +1,69 @@ -import { Schema, Document, Types } from "mongoose"; -import db from "../util/Database"; +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; import { ChannelPermissionOverwrite } from "./Channel"; -import { PublicUser } from "./User"; +import { User } from "./User"; -export interface AuditLogResponse { - webhooks: []; // TODO: - users: PublicUser[]; - audit_log_entries: AuditLogEntries[]; - integrations: []; // TODO: +export enum AuditLogEvents { + GUILD_UPDATE = 1, + CHANNEL_CREATE = 10, + CHANNEL_UPDATE = 11, + CHANNEL_DELETE = 12, + CHANNEL_OVERWRITE_CREATE = 13, + CHANNEL_OVERWRITE_UPDATE = 14, + CHANNEL_OVERWRITE_DELETE = 15, + MEMBER_KICK = 20, + MEMBER_PRUNE = 21, + MEMBER_BAN_ADD = 22, + MEMBER_BAN_REMOVE = 23, + MEMBER_UPDATE = 24, + MEMBER_ROLE_UPDATE = 25, + MEMBER_MOVE = 26, + MEMBER_DISCONNECT = 27, + BOT_ADD = 28, + ROLE_CREATE = 30, + ROLE_UPDATE = 31, + ROLE_DELETE = 32, + INVITE_CREATE = 40, + INVITE_UPDATE = 41, + INVITE_DELETE = 42, + WEBHOOK_CREATE = 50, + WEBHOOK_UPDATE = 51, + WEBHOOK_DELETE = 52, + EMOJI_CREATE = 60, + EMOJI_UPDATE = 61, + EMOJI_DELETE = 62, + MESSAGE_DELETE = 72, + MESSAGE_BULK_DELETE = 73, + MESSAGE_PIN = 74, + MESSAGE_UNPIN = 75, + INTEGRATION_CREATE = 80, + INTEGRATION_UPDATE = 81, + INTEGRATION_DELETE = 82, } -export interface AuditLogEntries { - target_id?: string; +@Entity("audit_logs") +export class AuditLogEntry extends BaseClass { + @Column() + target_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + target?: User; + + @Column() user_id: string; - id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; + + @Column({ + type: "simple-enum", + enum: AuditLogEvents, + }) action_type: AuditLogEvents; + + @Column("simple-json") options?: { delete_member_days?: string; members_removed?: string; @@ -25,7 +74,12 @@ export interface AuditLogEntries { type?: string; role_name?: string; }; + + @Column() + @Column("simple-json") changes: AuditLogChange[]; + + @Column() reason?: string; } @@ -91,130 +145,3 @@ export interface AuditLogChangeValue { expire_grace_period?: number; user_limit?: number; } - -export interface AuditLogEntriesDocument extends Document, AuditLogEntries { - id: string; -} - -export const AuditLogChanges = { - name: String, - description: String, - icon_hash: String, - splash_hash: String, - discovery_splash_hash: String, - banner_hash: String, - owner_id: String, - region: String, - preferred_locale: String, - afk_channel_id: String, - afk_timeout: Number, - rules_channel_id: String, - public_updates_channel_id: String, - mfa_level: Number, - verification_level: Number, - explicit_content_filter: Number, - default_message_notifications: Number, - vanity_url_code: String, - $add: [{}], - $remove: [{}], - prune_delete_days: Number, - widget_enabled: Boolean, - widget_channel_id: String, - system_channel_id: String, - position: Number, - topic: String, - bitrate: Number, - permission_overwrites: [{}], - nsfw: Boolean, - application_id: String, - rate_limit_per_user: Number, - permissions: String, - color: Number, - hoist: Boolean, - mentionable: Boolean, - allow: String, - deny: String, - code: String, - channel_id: String, - inviter_id: String, - max_uses: Number, - uses: Number, - max_age: Number, - temporary: Boolean, - deaf: Boolean, - mute: Boolean, - nick: String, - avatar_hash: String, - id: String, - type: Number, - enable_emoticons: Boolean, - expire_behavior: Number, - expire_grace_period: Number, - user_limit: Number, -}; - -export const AuditLogSchema = new Schema({ - target_id: String, - user_id: { type: String, required: true }, - id: { type: String, required: true }, - action_type: { type: Number, required: true }, - options: { - delete_member_days: String, - members_removed: String, - channel_id: String, - messaged_id: String, - count: String, - id: String, - type: { type: Number }, - role_name: String, - }, - changes: [ - { - new_value: AuditLogChanges, - old_value: AuditLogChanges, - key: String, - }, - ], - reason: String, -}); - -// @ts-ignore -export const AuditLogModel = db.model<AuditLogEntries>("AuditLog", AuditLogSchema, "auditlogs"); - -export enum AuditLogEvents { - GUILD_UPDATE = 1, - CHANNEL_CREATE = 10, - CHANNEL_UPDATE = 11, - CHANNEL_DELETE = 12, - CHANNEL_OVERWRITE_CREATE = 13, - CHANNEL_OVERWRITE_UPDATE = 14, - CHANNEL_OVERWRITE_DELETE = 15, - MEMBER_KICK = 20, - MEMBER_PRUNE = 21, - MEMBER_BAN_ADD = 22, - MEMBER_BAN_REMOVE = 23, - MEMBER_UPDATE = 24, - MEMBER_ROLE_UPDATE = 25, - MEMBER_MOVE = 26, - MEMBER_DISCONNECT = 27, - BOT_ADD = 28, - ROLE_CREATE = 30, - ROLE_UPDATE = 31, - ROLE_DELETE = 32, - INVITE_CREATE = 40, - INVITE_UPDATE = 41, - INVITE_DELETE = 42, - WEBHOOK_CREATE = 50, - WEBHOOK_UPDATE = 51, - WEBHOOK_DELETE = 52, - EMOJI_CREATE = 60, - EMOJI_UPDATE = 61, - EMOJI_DELETE = 62, - MESSAGE_DELETE = 72, - MESSAGE_BULK_DELETE = 73, - MESSAGE_PIN = 74, - MESSAGE_UNPIN = 75, - INTEGRATION_CREATE = 80, - INTEGRATION_UPDATE = 81, - INTEGRATION_DELETE = 82, -} diff --git a/util/src/entities/Ban.ts b/util/src/entities/Ban.ts new file mode 100644
index 00000000..ceea4a05 --- /dev/null +++ b/util/src/entities/Ban.ts
@@ -0,0 +1,34 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { User } from "./User"; + +@Entity("bans") +export class Ban extends BaseClass { + @Column() + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; + + @Column() + guild_id: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; + + @Column() + executor_id: string; + + @JoinColumn({ name: "executor_id" }) + @ManyToOne(() => User, (user: User) => user.id) + executor: User; + + @Column() + ip: string; + + @Column() + reason?: string; +} diff --git a/util/src/entities/BaseClass.ts b/util/src/entities/BaseClass.ts new file mode 100644
index 00000000..38f6a71b --- /dev/null +++ b/util/src/entities/BaseClass.ts
@@ -0,0 +1,61 @@ +import "reflect-metadata"; +import { BaseEntity, BeforeInsert, BeforeUpdate, PrimaryColumn } from "typeorm"; +import { Snowflake } from "../util/Snowflake"; +import Ajv, { ValidateFunction } from "ajv"; +import schema from "./schema.json"; + +const ajv = new Ajv({ + removeAdditional: "all", + useDefaults: true, + coerceTypes: true, + validateFormats: false, + allowUnionTypes: true, +}); +// const validator = ajv.compile<BaseClass>(schema); + +export class BaseClass extends BaseEntity { + @PrimaryColumn() + id: string; + + // @ts-ignore + constructor(props?: any, public opts: { id?: string } = {}) { + super(); + this.assign(props); + + if (!this.construct.schema) this.construct.schema = { ...schema, $ref: `#/definitions/${this.construct.name}` }; + } + + get construct(): any { + return this.constructor; + } + + assign(props: any) { + if (!props || typeof props !== "object") return; + + delete props.opts; + + for (const key in props) { + if (this.hasOwnProperty(key)) continue; + + Object.defineProperty(this, key, { value: props[key] }); + } + + this.id = this.opts.id || Snowflake.generate(); + } + + @BeforeUpdate() + @BeforeInsert() + validate() { + const valid = ajv.validate(this.construct.schema, this.toJSON()); + if (!valid) throw ajv.errors; + } + + get metadata() { + return this.construct.getRepository().metadata; + } + + toJSON(): any { + // @ts-ignore + return Object.fromEntries(this.metadata.columns.map((x) => [x.propertyName, this[x.propertyName]])); + } +} diff --git a/util/src/entities/Channel.ts b/util/src/entities/Channel.ts new file mode 100644
index 00000000..5845607a --- /dev/null +++ b/util/src/entities/Channel.ts
@@ -0,0 +1,104 @@ +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { Message } from "./Message"; +import { User } from "./User"; + +export enum ChannelType { + GUILD_TEXT = 0, // a text channel within a server + DM = 1, // a direct message between users + GUILD_VOICE = 2, // a voice channel within a server + GROUP_DM = 3, // a direct message between multiple users + GUILD_CATEGORY = 4, // an organizational category that contains up to 50 channels + GUILD_NEWS = 5, // a channel that users can follow and crosspost into their own server + GUILD_STORE = 6, // a channel in which game developers can sell their game on Discord +} + +@Entity("channels") +export class Channel extends BaseClass { + @Column() + created_at: Date; + + @Column() + name: string; + + @Column({ type: "simple-enum", enum: ChannelType }) + type: ChannelType; + + @Column("simple-array") + recipient_ids: string[]; + + @JoinColumn({ name: "recipient_ids" }) + @ManyToMany(() => User, (user: User) => user.id) + recipients?: User[]; + + @Column() + last_message_id: string; + + @JoinColumn({ name: "last_message_id" }) + @ManyToOne(() => Message, (message: Message) => message.id) + last_message?: Message; + + @Column() + guild_id?: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; + + @Column() + parent_id: string; + + @JoinColumn({ name: "parent_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + parent?: Channel; + + @Column() + owner_id: string; + + @JoinColumn({ name: "owner_id" }) + @ManyToOne(() => User, (user: User) => user.id) + owner: User; + + @Column() + last_pin_timestamp?: number; + + @Column() + default_auto_archive_duration?: number; + + @Column() + position: number; + + @Column("simple-json") + permission_overwrites: ChannelPermissionOverwrite[]; + + @Column() + video_quality_mode?: number; + + @Column() + bitrate?: number; + + @Column() + user_limit?: number; + + @Column() + nsfw: boolean; + + @Column() + rate_limit_per_user: number; + + @Column() + topic?: string; +} + +export interface ChannelPermissionOverwrite { + allow: bigint; // for bitfields we use bigints + deny: bigint; // for bitfields we use bigints + id: string; + type: ChannelPermissionOverwriteType; +} + +export enum ChannelPermissionOverwriteType { + role = 0, + member = 1, +} diff --git a/util/src/entities/ConnectedAccount.ts b/util/src/entities/ConnectedAccount.ts new file mode 100644
index 00000000..6aa2b401 --- /dev/null +++ b/util/src/entities/ConnectedAccount.ts
@@ -0,0 +1,29 @@ +import { Column, Entity } from "typeorm"; +import { BaseClass } from "./BaseClass"; + +@Entity("connected_accounts") +export class ConnectedAccount extends BaseClass { + @Column() + access_token: string; + + @Column() + friend_sync: boolean; + + @Column() + name: string; + + @Column() + revoked: boolean; + + @Column() + show_activity: boolean; + + @Column() + type: string; + + @Column() + verifie: boolean; + + @Column() + visibility: number; +} diff --git a/util/src/entities/Emoji.ts b/util/src/entities/Emoji.ts new file mode 100644
index 00000000..366549db --- /dev/null +++ b/util/src/entities/Emoji.ts
@@ -0,0 +1,39 @@ +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { Role } from "./Role"; + +@Entity("emojis") +export class Emoji extends BaseClass { + @Column() + animated: boolean; + + @Column() + available: boolean; + + @Column() + guild_id: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; + + @Column() + managed: boolean; + + @Column() + name: string; + + @Column() + require_colons: boolean; + + @Column() + url: string; + + @Column("simple-array") + role_ids: string[]; + + @JoinColumn({ name: "role_ids" }) + @ManyToMany(() => Role, (role: Role) => role.id) + roles: Role[]; // roles this emoji is whitelisted to (new discord feature?) +} diff --git a/util/src/entities/Guild.ts b/util/src/entities/Guild.ts new file mode 100644
index 00000000..d46d31bc --- /dev/null +++ b/util/src/entities/Guild.ts
@@ -0,0 +1,179 @@ +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Channel } from "./Channel"; +import { Emoji } from "./Emoji"; +import { Invite } from "./Invite"; +import { Member } from "./Member"; +import { Role } from "./Role"; +import { User } from "./User"; +import { VoiceState } from "./VoiceState"; + +@Entity("guilds") +export class Guild extends BaseClass { + @Column() + afk_channel_id?: string; + + @JoinColumn({ name: "afk_channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + afk_channel?: Channel; + + @Column() + afk_timeout?: number; + + // * commented out -> use owner instead + // application id of the guild creator if it is bot-created + // @Column() + // application?: string; + + @Column() + banner?: string; + + @Column() + default_message_notifications?: number; + + @Column() + description?: string; + + @Column() + discovery_splash?: string; + + @Column() + explicit_content_filter?: number; + + @Column("simple-array") + features: string[]; + + @Column() + icon?: string; + + @Column() + large?: boolean; + + @Column() + max_members?: number; // e.g. default 100.000 + + @Column() + max_presences?: number; + + @Column() + max_video_channel_users?: number; // ? default: 25, is this max 25 streaming or watching + + @Column() + member_count?: number; + + @Column() + presence_count?: number; // users online + + @Column("simple-array") + member_ids: string[]; + + @JoinColumn({ name: "member_ids" }) + @ManyToMany(() => Member, (member: Member) => member.id) + members: Member[]; + + @Column("simple-array") + role_ids: string[]; + + @JoinColumn({ name: "role_ids" }) + @ManyToMany(() => Role, (role: Role) => role.id) + roles: Role[]; + + @Column("simple-array") + channel_ids: string[]; + + @JoinColumn({ name: "channel_ids" }) + @ManyToMany(() => Channel, (channel: Channel) => channel.id) + channels: Channel[]; + + @Column("simple-array") + emoji_ids: string[]; + + @JoinColumn({ name: "emoji_ids" }) + @ManyToMany(() => Emoji, (emoji: Emoji) => emoji.id) + emojis: Emoji[]; + + @Column("simple-array") + voice_state_ids: string[]; + + @JoinColumn({ name: "voice_state_ids" }) + @ManyToMany(() => VoiceState, (voicestate: VoiceState) => voicestate.id) + voice_states: VoiceState[]; + + @Column() + mfa_level?: number; + + @Column() + name: string; + + @Column() + owner_id: string; + + @JoinColumn({ name: "owner_id" }) + @ManyToOne(() => User, (user: User) => user.id) + owner: User; + + @Column() + preferred_locale?: string; // only community guilds can choose this + + @Column() + premium_subscription_count?: number; + + @Column() + premium_tier?: number; // nitro boost level + + @JoinColumn({ name: "public_updates_channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + public_updates_channel?: Channel; + + @Column() + rules_channel_id?: string; + + @JoinColumn({ name: "rules_channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + rules_channel?: string; + + @Column() + region?: string; + + @Column() + splash?: string; + + @Column() + system_channel_id?: string; + + @JoinColumn({ name: "system_channel_id" }) + @ManyToMany(() => Channel, (channel: Channel) => channel.id) + system_channel?: Channel; + + @Column() + system_channel_flags?: number; + + @Column() + unavailable?: boolean; + + @JoinColumn({ name: "vanity_url_code" }) + @OneToOne(() => Invite, (invite: Invite) => invite.code) + vanity_url?: Invite; + + @Column() + verification_level?: number; + + @Column("simple-json") + welcome_screen: { + enabled: boolean; + description: string; + welcome_channels: { + description: string; + emoji_id?: string; + emoji_name: string; + channel_id: string; + }[]; + }; + + @JoinColumn({ name: "widget_channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + widget_channel?: Channel; + + @Column() + widget_enabled?: boolean; +} diff --git a/util/src/entities/Invite.ts b/util/src/entities/Invite.ts new file mode 100644
index 00000000..19f7206a --- /dev/null +++ b/util/src/entities/Invite.ts
@@ -0,0 +1,60 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Channel } from "./Channel"; +import { Guild } from "./Guild"; +import { User } from "./User"; + +@Entity("invites") +export class Invite extends BaseClass { + @Column() + code: string; + + @Column() + temporary: boolean; + + @Column() + uses: number; + + @Column() + max_uses: number; + + @Column() + max_age: number; + + @Column() + created_at: Date; + + @Column() + expires_at: Date; + + @Column() + guild_id: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; + + @Column() + channel_id: string; + + @JoinColumn({ name: "channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + channel: Channel; + + @Column() + inviter_id: string; + + @JoinColumn({ name: "inviter_id" }) + @ManyToOne(() => User, (user: User) => user.id) + inviter: User; + + @Column() + target_usser_id: string; + + @JoinColumn({ name: "target_user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + target_user?: string; // could be used for "User specific invites" https://github.com/fosscord/fosscord/issues/62 + + @Column() + target_user_type?: number; +} diff --git a/util/src/entities/Member.ts b/util/src/entities/Member.ts new file mode 100644
index 00000000..c367755e --- /dev/null +++ b/util/src/entities/Member.ts
@@ -0,0 +1,87 @@ +import { PublicUser, User } from "./User"; +import { BaseClass } from "./BaseClass"; +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { Guild } from "./Guild"; + +@Entity("members") +export class Member extends BaseClass { + @Column() + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; + + @Column() + guild_id: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; + + @Column() + nick?: string; + + @Column("simple-array") + roles: string[]; + + @Column() + joined_at: Date; + + @Column() + premium_since?: number; + + @Column() + deaf: boolean; + + @Column() + mute: boolean; + + @Column() + pending: boolean; + + @Column("simple-json") + settings: UserGuildSettings; + + // TODO: update + @Column("simple-json") + read_state: Record<string, string | null>; +} + +export interface UserGuildSettings { + channel_overrides: { + channel_id: string; + message_notifications: number; + mute_config: MuteConfig; + muted: boolean; + }[]; + message_notifications: number; + mobile_push: boolean; + mute_config: MuteConfig; + muted: boolean; + suppress_everyone: boolean; + suppress_roles: boolean; + version: number; +} + +export interface MuteConfig { + end_time: number; + selected_time_window: number; +} + +// @ts-ignore +export interface PublicMember extends Omit<Member, "settings" | "id" | "read_state"> { + user: PublicUser; +} + +export const PublicMemberProjection = { + id: true, + guild_id: true, + nick: true, + roles: true, + joined_at: true, + pending: true, + deaf: true, + mute: true, + premium_since: true, +}; diff --git a/util/src/entities/Message.ts b/util/src/entities/Message.ts new file mode 100644
index 00000000..2c0918c7 --- /dev/null +++ b/util/src/entities/Message.ts
@@ -0,0 +1,260 @@ +import { User } from "./User"; +import { Member } from "./Member"; +import { Role } from "./Role"; +import { Channel } from "./Channel"; +import { InteractionType } from "../interfaces/Interaction"; +import { Application } from "./Application"; +import { Column, CreateDateColumn, Entity, JoinColumn, ManyToMany, ManyToOne, UpdateDateColumn } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { Webhook } from "./Webhook"; + +export enum MessageType { + DEFAULT = 0, + RECIPIENT_ADD = 1, + RECIPIENT_REMOVE = 2, + CALL = 3, + CHANNEL_NAME_CHANGE = 4, + CHANNEL_ICON_CHANGE = 5, + CHANNEL_PINNED_MESSAGE = 6, + GUILD_MEMBER_JOIN = 7, + USER_PREMIUM_GUILD_SUBSCRIPTION = 8, + USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9, + USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10, + USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11, + CHANNEL_FOLLOW_ADD = 12, + GUILD_DISCOVERY_DISQUALIFIED = 14, + GUILD_DISCOVERY_REQUALIFIED = 15, + REPLY = 19, + APPLICATION_COMMAND = 20, +} + +@Entity("messages") +export class Message extends BaseClass { + @Column() + id: string; + + @Column() + channel_id: string; + + @JoinColumn({ name: "channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + channel: Channel; + + @Column() + guild_id: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild?: Guild; + + @Column() + author_id: string; + + @JoinColumn({ name: "author_id" }) + @ManyToOne(() => User, (user: User) => user.id) + author?: User; + + @Column() + member_id: string; + + @JoinColumn({ name: "member_id" }) + @ManyToOne(() => Member, (member: Member) => member.id) + member?: Member; + + @Column() + webhook_id: string; + + @JoinColumn({ name: "webhook_id" }) + @ManyToOne(() => Webhook, (webhook: Webhook) => webhook.id) + webhook?: Webhook; + + @Column() + application_id: string; + + @JoinColumn({ name: "application_id" }) + @ManyToOne(() => Application, (application: Application) => application.id) + application?: Application; + + @Column() + content?: string; + + @Column() + @CreateDateColumn() + timestamp: Date; + + @Column() + @UpdateDateColumn() + edited_timestamp?: Date; + + @Column() + tts?: boolean; + + @Column() + mention_everyone?: boolean; + + @Column("simple-array") + mention_user_ids: string[]; + + @JoinColumn({ name: "mention_user_ids" }) + @ManyToMany(() => User, (user: User) => user.id) + mention_users: User[]; + + @Column("simple-array") + mention_role_ids: string[]; + + @JoinColumn({ name: "mention_role_ids" }) + @ManyToMany(() => Role, (role: Role) => role.id) + mention_roles: Role[]; + + @Column("simple-array") + mention_channel_ids: string[]; + + @JoinColumn({ name: "mention_channel_ids" }) + @ManyToMany(() => Channel, (channel: Channel) => channel.id) + mention_channels: Channel[]; + + @Column("simple-json") + attachments: Attachment[]; + + @Column("simple-json") + embeds: Embed[]; + + @Column("simple-json") + reactions: Reaction[]; + + @Column({ type: "text" }) + nonce?: string | number; + + @Column() + pinned?: boolean; + + @Column({ type: "simple-enum", enum: MessageType }) + type: MessageType; + + @Column("simple-json") + activity?: { + type: number; + party_id: string; + }; + + @Column({ type: "bigint" }) + flags?: bigint; + + @Column("simple-json") + stickers?: any[]; + + @Column("simple-json") + message_reference?: { + message_id: string; + channel_id?: string; + guild_id?: string; + }; + + @Column("simple-json") + interaction?: { + id: string; + type: InteractionType; + name: string; + user_id: string; // the user who invoked the interaction + // user: User; // TODO: autopopulate user + }; + + @Column("simple-json") + components: MessageComponent[]; +} + +export interface MessageComponent { + type: number; + style?: number; + label?: string; + emoji?: PartialEmoji; + custom_id?: string; + url?: string; + disabled?: boolean; + components: MessageComponent[]; +} + +export enum MessageComponentType { + ActionRow = 1, + Button = 2, +} + +export interface Attachment { + id: string; // attachment id + filename: string; // name of file attached + size: number; // size of file in bytes + url: string; // source url of file + proxy_url: string; // a proxied url of file + height?: number; // height of file (if image) + width?: number; // width of file (if image) + content_type?: string; +} + +export interface Embed { + title?: string; //title of embed + type?: EmbedType; // type of embed (always "rich" for webhook embeds) + description?: string; // description of embed + url?: string; // url of embed + timestamp?: Date; // timestamp of embed content + color?: number; // color code of the embed + footer?: { + text: string; + icon_url?: string; + proxy_icon_url?: string; + }; // footer object footer information + image?: EmbedImage; // image object image information + thumbnail?: EmbedImage; // thumbnail object thumbnail information + video?: EmbedImage; // video object video information + provider?: { + name?: string; + url?: string; + }; // provider object provider information + author?: { + name?: string; + url?: string; + icon_url?: string; + proxy_icon_url?: string; + }; // author object author information + fields?: { + name: string; + value: string; + inline?: boolean; + }[]; +} + +export enum EmbedType { + rich = "rich", + image = "image", + video = "video", + gifv = "gifv", + article = "article", + link = "link", +} + +export interface EmbedImage { + url?: string; + proxy_url?: string; + height?: number; + width?: number; +} + +export interface Reaction { + count: number; + //// not saved in the database // me: boolean; // whether the current user reacted using this emoji + emoji: PartialEmoji; + user_ids: string[]; +} + +export interface PartialEmoji { + id?: string; + name: string; + animated?: boolean; +} + +export interface AllowedMentions { + parse?: ("users" | "roles" | "everyone")[]; + roles?: string[]; + users?: string[]; + replied_user?: boolean; +} diff --git a/util/src/entities/RateLimit.ts b/util/src/entities/RateLimit.ts new file mode 100644
index 00000000..374a0759 --- /dev/null +++ b/util/src/entities/RateLimit.ts
@@ -0,0 +1,25 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { User } from "./User"; + +@Entity("rate_limits") +export class RateLimit extends BaseClass { + @Column() + id: "global" | "error" | string; // channel_239842397 | guild_238927349823 | webhook_238923423498 + + @Column() + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user) => user.id) + user: User; + + @Column() + hits: number; + + @Column() + blocked: boolean; + + @Column() + expires_at: Date; +} diff --git a/util/src/entities/ReadState.ts b/util/src/entities/ReadState.ts new file mode 100644
index 00000000..7c56b6c6 --- /dev/null +++ b/util/src/entities/ReadState.ts
@@ -0,0 +1,35 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Channel } from "./Channel"; +import { Message } from "./Message"; +import { User } from "./User"; + +@Entity("read_states") +export class ReadState extends BaseClass { + @Column() + channel_id: string; + + @JoinColumn({ name: "channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + channel: Channel; + + @Column() + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; + + @JoinColumn({ name: "last_message_id" }) + @ManyToOne(() => Message, (message: Message) => message.id) + last_message?: Message; + + @Column() + last_pin_timestamp?: Date; + + @Column() + mention_count: number; + + @Column() + manual: boolean; +} diff --git a/util/src/entities/Relationship.ts b/util/src/entities/Relationship.ts new file mode 100644
index 00000000..bd5861f0 --- /dev/null +++ b/util/src/entities/Relationship.ts
@@ -0,0 +1,26 @@ +import { Column, Entity, JoinColumn, ManyToOne, OneToMany } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { User } from "./User"; + +export enum RelationshipType { + outgoing = 4, + incoming = 3, + blocked = 2, + friends = 1, +} + +@Entity("relationships") +export class Relationship extends BaseClass { + @Column() + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; + + @Column() + nickname?: string; + + @Column({ type: "simple-enum", enum: RelationshipType }) + type: RelationshipType; +} diff --git a/util/src/entities/Role.ts b/util/src/entities/Role.ts new file mode 100644
index 00000000..7bb144cc --- /dev/null +++ b/util/src/entities/Role.ts
@@ -0,0 +1,41 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; + +@Entity("roles") +export class Role extends BaseClass { + @Column() + guild_id: string; + + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild: Guild; + + @Column() + color: number; + + @Column() + hoist: boolean; + + @Column() + managed: boolean; + + @Column() + mentionable: boolean; + + @Column() + name: string; + + @Column({ type: "bigint" }) + permissions: bigint; + + @Column() + position: number; + + @Column({ type: "simple-json" }) + tags?: { + bot_id?: string; + integration_id?: string; + premium_subscriber?: boolean; + }; +} diff --git a/util/src/entities/Team.ts b/util/src/entities/Team.ts new file mode 100644
index 00000000..5e645650 --- /dev/null +++ b/util/src/entities/Team.ts
@@ -0,0 +1,27 @@ +import { Column, Entity, JoinColumn, ManyToMany, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { TeamMember } from "./TeamMember"; +import { User } from "./User"; + +@Entity("teams") +export class Team extends BaseClass { + @Column() + icon?: string; + + @Column("simple-array") + member_ids: string[]; + + @JoinColumn({ name: "member_ids" }) + @ManyToMany(() => TeamMember, (member: TeamMember) => member.id) + members: TeamMember[]; + + @Column() + name: string; + + @Column() + owner_user_id: string; + + @JoinColumn({ name: "owner_user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + owner_user: User; +} diff --git a/util/src/entities/TeamMember.ts b/util/src/entities/TeamMember.ts new file mode 100644
index 00000000..2b1c76f1 --- /dev/null +++ b/util/src/entities/TeamMember.ts
@@ -0,0 +1,31 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { User } from "./User"; + +export enum TeamMemberState { + INVITED = 1, + ACCEPTED = 2, +} + +@Entity("team_members") +export class TeamMember extends BaseClass { + @Column({ type: "simple-enum", enum: TeamMemberState }) + membership_state: TeamMemberState; + + @Column("simple-array") + permissions: string[]; + + @Column() + team_id: string; + + @JoinColumn({ name: "team_id" }) + @ManyToOne(() => require("./Team").Team, (team: import("./Team").Team) => team.id) + team: import("./Team").Team; + + @Column() + user_id: string; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; +} diff --git a/util/src/entities/Template.ts b/util/src/entities/Template.ts new file mode 100644
index 00000000..5c9a5120 --- /dev/null +++ b/util/src/entities/Template.ts
@@ -0,0 +1,33 @@ +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Guild } from "./Guild"; +import { User } from "./User"; + +@Entity("templates") +export class Template extends BaseClass { + @Column() + code: string; + + @Column() + name: string; + + @Column() + description?: string; + + @Column() + usage_count?: number; + + @JoinColumn({ name: "creator_id" }) + @ManyToOne(() => User, (user: User) => user.id) + creator: User; + + @Column() + created_at: Date; + + @Column() + updated_at: Date; + + @JoinColumn({ name: "source_guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + source_guild: Guild; +} diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts new file mode 100644
index 00000000..073f6217 --- /dev/null +++ b/util/src/entities/User.ts
@@ -0,0 +1,188 @@ +import { Column, Entity, JoinColumn, OneToMany, OneToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { BitField } from "../util/BitField"; +import { Relationship } from "./Relationship"; +import { ConnectedAccount } from "./ConnectedAccount"; + +export const PublicUserProjection = { + username: true, + discriminator: true, + id: true, + public_flags: true, + avatar: true, + accent_color: true, + banner: true, + bio: true, + bot: true, +}; + +@Entity("users") +export class User extends BaseClass { + @Column() + username: string; // username max length 32, min 2 (should be configurable) + + @Column() + discriminator: string; // #0001 4 digit long string from #0001 - #9999 + + @Column() + avatar?: string; // hash of the user avatar + + @Column() + accent_color?: number; // banner color of user + + @Column() + banner?: string; // hash of the user banner + + @Column() + phone?: string; // phone number of the user + + @Column() + desktop: boolean; // if the user has desktop app installed + + @Column() + mobile: boolean; // if the user has mobile app installed + + @Column() + premium: boolean; // if user bought nitro + + @Column() + premium_type: number; // nitro level + + @Column() + bot: boolean; // if user is bot + + @Column() + bio: string; // short description of the user (max 190 chars -> should be configurable) + + @Column() + system: boolean; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author + + @Column() + nsfw_allowed: boolean; // if the user is older than 18 (resp. Config) + + @Column() + mfa_enabled: boolean; // if multi factor authentication is enabled + + @Column() + created_at: Date; // registration date + + @Column() + verified: boolean; // if the user is offically verified + + @Column() + disabled: boolean; // if the account is disabled + + @Column() + deleted: boolean; // if the user was deleted + + @Column() + email?: string; // email of the user + + @Column({ type: "bigint" }) + flags: bigint; // UserFlags + + @Column({ type: "bigint" }) + public_flags: bigint; + + @Column("simple-array") // string in simple-array must not contain commas + guilds: string[]; // array of guild ids the user is part of + + @Column("simple-array") // string in simple-array must not contain commas + relationship_ids: string[]; // array of guild ids the user is part of + + @JoinColumn({ name: "relationship_ids" }) + @OneToMany(() => User, (user: User) => user.id) + relationships: Relationship[]; + + @Column("simple-array") // string in simple-array must not contain commas + connected_account_ids: string[]; // array of guild ids the user is part of + + @JoinColumn({ name: "connected_account_ids" }) + @OneToMany(() => ConnectedAccount, (account: ConnectedAccount) => account.id) + connected_accounts: ConnectedAccount[]; + + @Column({ type: "simple-json", select: false }) + user_data: { + valid_tokens_since: Date; // all tokens with a previous issue date are invalid + hash: string; // hash of the password, salt is saved in password (bcrypt) + fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts + }; + + @Column("simple-json") + settings: UserSettings; +} + +export interface UserSettings { + afk_timeout: number; + allow_accessibility_detection: boolean; + animate_emoji: boolean; + animate_stickers: number; + contact_sync_enabled: boolean; + convert_emoticons: boolean; + custom_status: { + emoji_id?: string; + emoji_name?: string; + expires_at?: number; + text?: string; + }; + default_guilds_restricted: boolean; + detect_platform_accounts: boolean; + developer_mode: boolean; + disable_games_tab: boolean; + enable_tts_command: boolean; + explicit_content_filter: number; + friend_source_flags: { all: boolean }; + gateway_connected: boolean; + gif_auto_play: boolean; + // every top guild is displayed as a "folder" + guild_folders: { + color: number; + guild_ids: string[]; + id: number; + name: string; + }[]; + guild_positions: string[]; // guild ids ordered by position + inline_attachment_media: boolean; + inline_embed_media: boolean; + locale: string; // en_US + message_display_compact: boolean; + native_phone_integration_enabled: boolean; + render_embeds: boolean; + render_reactions: boolean; + restricted_guilds: string[]; + show_current_game: boolean; + status: "online" | "offline" | "dnd" | "idle"; + stream_notifications_enabled: boolean; + theme: "dark" | "white"; // dark + timezone_offset: number; // e.g -60 +} + +// Private user data that should never get sent to the client +export interface PublicUser { + id: string; + discriminator: string; + username: string; + avatar?: string; + accent_color?: number; + banner?: string; + public_flags: bigint; + bot: boolean; +} + +export class UserFlags extends BitField { + static FLAGS = { + DISCORD_EMPLOYEE: BigInt(1) << BigInt(0), + PARTNERED_SERVER_OWNER: BigInt(1) << BigInt(1), + HYPESQUAD_EVENTS: BigInt(1) << BigInt(2), + BUGHUNTER_LEVEL_1: BigInt(1) << BigInt(3), + HOUSE_BRAVERY: BigInt(1) << BigInt(6), + HOUSE_BRILLIANCE: BigInt(1) << BigInt(7), + HOUSE_BALANCE: BigInt(1) << BigInt(8), + EARLY_SUPPORTER: BigInt(1) << BigInt(9), + TEAM_USER: BigInt(1) << BigInt(10), + SYSTEM: BigInt(1) << BigInt(12), + BUGHUNTER_LEVEL_2: BigInt(1) << BigInt(14), + VERIFIED_BOT: BigInt(1) << BigInt(16), + EARLY_VERIFIED_BOT_DEVELOPER: BigInt(1) << BigInt(17), + }; +} diff --git a/util/src/entities/VoiceState.ts b/util/src/entities/VoiceState.ts new file mode 100644
index 00000000..2416c6c0 --- /dev/null +++ b/util/src/entities/VoiceState.ts
@@ -0,0 +1,44 @@ +import { Column, Entity, JoinColumn, ManyToOne, OneToOne } from "typeorm"; +import { BaseClass } from "./BaseClass"; +import { Channel } from "./Channel"; +import { Guild } from "./Guild"; +import { User } from "./User"; + +@Entity("voice_states") +export class VoiceState extends BaseClass { + @JoinColumn({ name: "guild_id" }) + @ManyToOne(() => Guild, (guild: Guild) => guild.id) + guild?: Guild; + + @JoinColumn({ name: "channel_id" }) + @ManyToOne(() => Channel, (channel: Channel) => channel.id) + channel: Channel; + + @JoinColumn({ name: "user_id" }) + @ManyToOne(() => User, (user: User) => user.id) + user: User; + + @Column() + session_id: string; + + @Column() + deaf: boolean; + + @Column() + mute: boolean; + + @Column() + self_deaf: boolean; + + @Column() + self_mute: boolean; + + @Column() + self_stream?: boolean; + + @Column() + self_video: boolean; + + @Column() + suppress: boolean; // whether this user is muted by the current user +} diff --git a/util/src/entities/Webhook.ts b/util/src/entities/Webhook.ts new file mode 100644
index 00000000..54233638 --- /dev/null +++ b/util/src/entities/Webhook.ts
@@ -0,0 +1,40 @@ +import { Column, Entity, JoinColumn } from "typeorm"; +import { BaseClass } from "./BaseClass"; + +export enum WebhookType { + Incoming = 1, + ChannelFollower = 2, +} + +@Entity("webhooks") +export class Webhook extends BaseClass { + @Column() + id: string; + + @Column({ type: "simple-enum", enum: WebhookType }) + type: WebhookType; + + @Column() + name?: string; + + @Column() + avatar?: string; + + @Column() + token?: string; + + @JoinColumn() + guild?: string; + + @JoinColumn() + channel: string; + + @JoinColumn() + application?: string; + + @JoinColumn() + user?: string; + + @JoinColumn() + source_guild: string; +} diff --git a/util/src/entities/index.ts b/util/src/entities/index.ts new file mode 100644
index 00000000..9cb10016 --- /dev/null +++ b/util/src/entities/index.ts
@@ -0,0 +1,21 @@ +export * from "./Application"; +export * from "./AuditLog"; +export * from "./Ban"; +export * from "./BaseClass"; +export * from "./Channel"; +export * from "./ConnectedAccount"; +export * from "./Emoji"; +export * from "./Guild"; +export * from "./Invite"; +export * from "./Member"; +export * from "./Message"; +export * from "./RateLimit"; +export * from "./ReadState"; +export * from "./Relationship"; +export * from "./Role"; +export * from "./Team"; +export * from "./TeamMember"; +export * from "./Template"; +export * from "./User"; +export * from "./VoiceState"; +export * from "./Webhook"; diff --git a/util/src/entities/schema.json b/util/src/entities/schema.json new file mode 100644
index 00000000..ebf66e88 --- /dev/null +++ b/util/src/entities/schema.json
@@ -0,0 +1,5725 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "Activity": { + "properties": { + "application_id": { + "type": "string" + }, + "assets": { + "properties": { + "large_image": { + "type": "string" + }, + "large_text": { + "type": "string" + }, + "small_image": { + "type": "string" + }, + "small_text": { + "type": "string" + } + }, + "type": "object" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "details": { + "type": "string" + }, + "emoji": { + "properties": { + "amimated": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "flags": { + "type": "bigint" + }, + "instance": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "party": { + "properties": { + "id": { + "type": "string" + }, + "size": { + "items": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "maxItems": 2, + "minItems": 2, + "type": "array" + } + }, + "type": "object" + }, + "secrets": { + "properties": { + "join": { + "type": "string" + }, + "match": { + "type": "string" + }, + "spectate": { + "type": "string" + } + }, + "type": "object" + }, + "state": { + "type": "string" + }, + "timestamps": { + "items": { + "properties": { + "end": { + "type": "number" + }, + "start": { + "type": "number" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": { + "$ref": "#/definitions/ActivityType" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "ActivityType": { + "enum": [ + 0, + 1, + 2, + 4, + 5 + ], + "type": "number" + }, + "AllowedMentions": { + "properties": { + "parse": { + "items": { + "enum": [ + "everyone", + "roles", + "users" + ], + "type": "string" + }, + "type": "array" + }, + "replied_user": { + "type": "boolean" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array" + }, + "users": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "Application": { + "properties": { + "bot_public": { + "type": "boolean" + }, + "bot_require_code_grant": { + "type": "boolean" + }, + "construct": { + }, + "cover_image": { + "type": "string" + }, + "description": { + "type": "string" + }, + "flags": { + "type": "number" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "owner_id": { + "type": "string" + }, + "primary_sku_id": { + "type": "string" + }, + "privacy_policy_url": { + "type": "string" + }, + "rpc_origins": { + "items": { + "type": "string" + }, + "type": "array" + }, + "slug": { + "type": "string" + }, + "summary": { + "type": "string" + }, + "team": { + "$ref": "#/definitions/Team" + }, + "team_id": { + "type": "string" + }, + "terms_of_service_url": { + "type": "string" + }, + "verify_key": { + "type": "string" + } + }, + "type": "object" + }, + "ApplicationCommand": { + "properties": { + "application_id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "options": { + "items": { + "$ref": "#/definitions/ApplicationCommandOption" + }, + "type": "array" + } + }, + "type": "object" + }, + "ApplicationCommandCreateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/ApplicationCommand" + }, + { + "properties": { + "guild_id": { + "type": "string" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "APPLICATION_COMMAND_CREATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ApplicationCommandDeleteEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/ApplicationCommand" + }, + { + "properties": { + "guild_id": { + "type": "string" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "APPLICATION_COMMAND_DELETE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ApplicationCommandInteractionData": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "options": { + "items": { + "$ref": "#/definitions/ApplicationCommandInteractionDataOption" + }, + "type": "array" + } + }, + "type": "object" + }, + "ApplicationCommandInteractionDataOption": { + "properties": { + "name": { + "type": "string" + }, + "options": { + "items": { + "$ref": "#/definitions/ApplicationCommandInteractionDataOption" + }, + "type": "array" + }, + "value": { + } + }, + "type": "object" + }, + "ApplicationCommandOption": { + "properties": { + "choices": { + "items": { + "$ref": "#/definitions/ApplicationCommandOptionChoice" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "options": { + "items": { + "$ref": "#/definitions/ApplicationCommandOption" + }, + "type": "array" + }, + "required": { + "type": "boolean" + }, + "type": { + "$ref": "#/definitions/ApplicationCommandOptionType" + } + }, + "type": "object" + }, + "ApplicationCommandOptionChoice": { + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": [ + "string", + "number" + ] + } + }, + "type": "object" + }, + "ApplicationCommandOptionType": { + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8 + ], + "type": "number" + }, + "ApplicationCommandPayload": { + "allOf": [ + { + "$ref": "#/definitions/ApplicationCommand" + }, + { + "properties": { + "guild_id": { + "type": "string" + } + }, + "type": "object" + } + ] + }, + "ApplicationCommandUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/ApplicationCommand" + }, + { + "properties": { + "guild_id": { + "type": "string" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "APPLICATION_COMMAND_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Attachment": { + "properties": { + "content_type": { + "type": "string" + }, + "filename": { + "type": "string" + }, + "height": { + "type": "number" + }, + "id": { + "type": "string" + }, + "proxy_url": { + "type": "string" + }, + "size": { + "type": "number" + }, + "url": { + "type": "string" + }, + "width": { + "type": "number" + } + }, + "type": "object" + }, + "AuditLogChange": { + "properties": { + "key": { + "type": "string" + }, + "new_value": { + "$ref": "#/definitions/AuditLogChangeValue" + }, + "old_value": { + "$ref": "#/definitions/AuditLogChangeValue" + } + }, + "type": "object" + }, + "AuditLogChangeValue": { + "properties": { + "$add": { + "items": { + "properties": { + }, + "type": "object" + }, + "type": "array" + }, + "$remove": { + "items": { + "properties": { + }, + "type": "object" + }, + "type": "array" + }, + "afk_channel_id": { + "type": "string" + }, + "afk_timeout": { + "type": "number" + }, + "allow": { + "type": "string" + }, + "application_id": { + "type": "string" + }, + "avatar_hash": { + "type": "string" + }, + "banner_hash": { + "type": "string" + }, + "bitrate": { + "type": "number" + }, + "channel_id": { + "type": "string" + }, + "code": { + "type": "string" + }, + "color": { + "type": "number" + }, + "deaf": { + "type": "boolean" + }, + "default_message_notifications": { + "type": "number" + }, + "deny": { + "type": "string" + }, + "description": { + "type": "string" + }, + "discovery_splash_hash": { + "type": "string" + }, + "enable_emoticons": { + "type": "boolean" + }, + "expire_behavior": { + "type": "number" + }, + "expire_grace_period": { + "type": "number" + }, + "explicit_content_filter": { + "type": "number" + }, + "hoist": { + "type": "boolean" + }, + "icon_hash": { + "type": "string" + }, + "id": { + "type": "string" + }, + "inviter_id": { + "type": "string" + }, + "max_age": { + "type": "number" + }, + "max_uses": { + "type": "number" + }, + "mentionable": { + "type": "boolean" + }, + "mfa_level": { + "type": "number" + }, + "mute": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "nick": { + "type": "string" + }, + "nsfw": { + "type": "boolean" + }, + "owner_id": { + "type": "string" + }, + "permission_overwrites": { + "items": { + "$ref": "#/definitions/ChannelPermissionOverwrite" + }, + "type": "array" + }, + "permissions": { + "type": "string" + }, + "position": { + "type": "number" + }, + "preferred_locale": { + "type": "string" + }, + "prune_delete_days": { + "type": "number" + }, + "public_updates_channel_id": { + "type": "string" + }, + "rate_limit_per_user": { + "type": "number" + }, + "region": { + "type": "string" + }, + "rules_channel_id": { + "type": "string" + }, + "splash_hash": { + "type": "string" + }, + "system_channel_id": { + "type": "string" + }, + "temporary": { + "type": "boolean" + }, + "topic": { + "type": "string" + }, + "type": { + "type": "number" + }, + "user_limit": { + "type": "number" + }, + "uses": { + "type": "number" + }, + "vanity_url_code": { + "type": "string" + }, + "verification_level": { + "type": "number" + }, + "widget_channel_id": { + "type": "string" + }, + "widget_enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "AuditLogEntry": { + "properties": { + "action_type": { + "$ref": "#/definitions/AuditLogEvents" + }, + "changes": { + "items": { + "$ref": "#/definitions/AuditLogChange" + }, + "type": "array" + }, + "construct": { + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "options": { + "properties": { + "channel_id": { + "type": "string" + }, + "count": { + "type": "string" + }, + "delete_member_days": { + "type": "string" + }, + "id": { + "type": "string" + }, + "members_removed": { + "type": "string" + }, + "messaged_id": { + "type": "string" + }, + "role_name": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "reason": { + "type": "string" + }, + "target": { + "$ref": "#/definitions/User" + }, + "target_id": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "AuditLogEvents": { + "enum": [ + 1, + 10, + 11, + 12, + 13, + 14, + 15, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 30, + 31, + 32, + 40, + 41, + 42, + 50, + 51, + 52, + 60, + 61, + 62, + 72, + 73, + 74, + 75, + 80, + 81, + 82 + ], + "type": "number" + }, + "Ban": { + "properties": { + "construct": { + }, + "executor": { + "$ref": "#/definitions/User" + }, + "executor_id": { + "type": "string" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "reason": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "BaseClass": { + "properties": { + "construct": { + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "BigInt": { + "properties": { + "__@toStringTag": { + "enum": [ + "BigInt" + ], + "type": "string" + } + }, + "type": "object" + }, + "BitField": { + "description": "Data structure that makes it easy to interact with a bitfield.", + "properties": { + "bitfield": { + "type": "bigint" + } + }, + "type": "object" + }, + "BitFieldResolvable": { + "anyOf": [ + { + "$ref": "#/definitions/BigInt" + }, + { + "$ref": "#/definitions/BitField" + }, + { + "items": { + "$ref": "#/definitions/BitFieldResolvable" + }, + "type": "array" + }, + { + "type": [ + "string", + "number" + ] + } + ] + }, + "CUSTOMEVENTS": { + "enum": [ + "INVALIDATED" + ], + "type": "string" + }, + "Channel": { + "properties": { + "bitrate": { + "type": "number" + }, + "construct": { + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "default_auto_archive_duration": { + "type": "number" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "last_message": { + "$ref": "#/definitions/Message" + }, + "last_message_id": { + "type": "string" + }, + "last_pin_timestamp": { + "type": "number" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "nsfw": { + "type": "boolean" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "owner": { + "$ref": "#/definitions/User" + }, + "owner_id": { + "type": "string" + }, + "parent": { + "$ref": "#/definitions/Channel" + }, + "parent_id": { + "type": "string" + }, + "permission_overwrites": { + "items": { + "$ref": "#/definitions/ChannelPermissionOverwrite" + }, + "type": "array" + }, + "position": { + "type": "number" + }, + "rate_limit_per_user": { + "type": "number" + }, + "recipient_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "recipients": { + "items": { + "$ref": "#/definitions/User" + }, + "type": "array" + }, + "topic": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ChannelType" + }, + "user_limit": { + "type": "number" + }, + "video_quality_mode": { + "type": "number" + } + }, + "type": "object" + }, + "ChannelCreateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Channel" + }, + "event": { + "enum": [ + "CHANNEL_CREATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ChannelDeleteEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Channel" + }, + "event": { + "enum": [ + "CHANNEL_DELETE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ChannelPermissionOverwrite": { + "properties": { + "allow": { + "type": "bigint" + }, + "deny": { + "type": "bigint" + }, + "id": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/ChannelPermissionOverwriteType" + } + }, + "type": "object" + }, + "ChannelPermissionOverwriteType": { + "enum": [ + 0, + 1 + ], + "type": "number" + }, + "ChannelPinsUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "last_pin_timestamp": { + "type": "number" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "CHANNEL_PINS_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ChannelType": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "type": "number" + }, + "ChannelUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Channel" + }, + "event": { + "enum": [ + "CHANNEL_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Channel_1": { + "type": "object" + }, + "ClientStatus": { + "properties": { + "desktop": { + "type": "string" + }, + "mobile": { + "type": "string" + }, + "web": { + "type": "string" + } + }, + "type": "object" + }, + "ConnectedAccount": { + "properties": { + "access_token": { + "type": "string" + }, + "construct": { + }, + "friend_sync": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "revoked": { + "type": "boolean" + }, + "show_activity": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "verifie": { + "type": "boolean" + }, + "visibility": { + "type": "number" + } + }, + "type": "object" + }, + "EVENT": { + "enum": [ + "APPLICATION_COMMAND_CREATE", + "APPLICATION_COMMAND_DELETE", + "APPLICATION_COMMAND_UPDATE", + "CHANNEL_CREATE", + "CHANNEL_DELETE", + "CHANNEL_PINS_UPDATE", + "CHANNEL_UPDATE", + "GUILD_BAN_ADD", + "GUILD_BAN_REMOVE", + "GUILD_CREATE", + "GUILD_DELETE", + "GUILD_EMOJI_UPDATE", + "GUILD_INTEGRATIONS_UPDATE", + "GUILD_MEMBERS_CHUNK", + "GUILD_MEMBER_ADD", + "GUILD_MEMBER_REMOVE", + "GUILD_MEMBER_SPEAKING", + "GUILD_MEMBER_UPDATE", + "GUILD_ROLE_CREATE", + "GUILD_ROLE_DELETE", + "GUILD_ROLE_UPDATE", + "GUILD_UPDATE", + "INTERACTION_CREATE", + "INVALIDATED", + "INVITE_CREATE", + "INVITE_DELETE", + "MESSAGE_ACK", + "MESSAGE_CREATE", + "MESSAGE_DELETE", + "MESSAGE_DELETE_BULK", + "MESSAGE_REACTION_ADD", + "MESSAGE_REACTION_REMOVE", + "MESSAGE_REACTION_REMOVE_ALL", + "MESSAGE_REACTION_REMOVE_EMOJI", + "MESSAGE_UPDATE", + "PRESENCE_UPDATE", + "READY", + "RELATIONSHIP_ADD", + "RELATIONSHIP_REMOVE", + "TYPING_START", + "USER_UPDATE", + "VOICE_SERVER_UPDATE", + "VOICE_STATE_UPDATE", + "WEBHOOKS_UPDATE" + ], + "type": "string" + }, + "EVENTEnum": { + "enum": [ + "APPLICATION_COMMAND_CREATE", + "APPLICATION_COMMAND_DELETE", + "APPLICATION_COMMAND_UPDATE", + "CHANNEL_CREATE", + "CHANNEL_DELETE", + "CHANNEL_PINS_UPDATE", + "CHANNEL_UPDATE", + "GUILD_BAN_ADD", + "GUILD_BAN_REMOVE", + "GUILD_CREATE", + "GUILD_DELETE", + "GUILD_EMOJI_UPDATE", + "GUILD_INTEGRATIONS_UPDATE", + "GUILD_MEMBERS_CHUNK", + "GUILD_MEMBER_ADD", + "GUILD_MEMBER_REMOVE", + "GUILD_MEMBER_SPEAKING", + "GUILD_MEMBER_UPDATE", + "GUILD_ROLE_CREATE", + "GUILD_ROLE_DELETE", + "GUILD_ROLE_UPDATE", + "GUILD_UPDATE", + "INTERACTION_CREATE", + "INVITE_CREATE", + "INVITE_DELETE", + "MESSAGE_CREATE", + "MESSAGE_DELETE", + "MESSAGE_DELETE_BULK", + "MESSAGE_REACTION_ADD", + "MESSAGE_REACTION_REMOVE", + "MESSAGE_REACTION_REMOVE_ALL", + "MESSAGE_REACTION_REMOVE_EMOJI", + "MESSAGE_UPDATE", + "PRESENCE_UPDATE", + "READY", + "TYPING_START", + "USER_UPDATE", + "VOICE_SERVER_UPDATE", + "VOICE_STATE_UPDATE", + "WEBHOOKS_UPDATE" + ], + "type": "string" + }, + "Embed": { + "properties": { + "author": { + "properties": { + "icon_url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "color": { + "type": "number" + }, + "description": { + "type": "string" + }, + "fields": { + "items": { + "properties": { + "inline": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "footer": { + "properties": { + "icon_url": { + "type": "string" + }, + "proxy_icon_url": { + "type": "string" + }, + "text": { + "type": "string" + } + }, + "type": "object" + }, + "image": { + "$ref": "#/definitions/EmbedImage" + }, + "provider": { + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "thumbnail": { + "$ref": "#/definitions/EmbedImage" + }, + "timestamp": { + "format": "date-time", + "type": "string" + }, + "title": { + "type": "string" + }, + "type": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "url": { + "type": "string" + }, + "video": { + "$ref": "#/definitions/EmbedImage" + } + }, + "type": "object" + }, + "EmbedImage": { + "properties": { + "height": { + "type": "number" + }, + "proxy_url": { + "type": "string" + }, + "url": { + "type": "string" + }, + "width": { + "type": "number" + } + }, + "type": "object" + }, + "EmbedType": { + "enum": [ + "article", + "gifv", + "image", + "link", + "rich", + "video" + ], + "type": "string" + }, + "Emoji": { + "properties": { + "animated": { + "type": "boolean" + }, + "available": { + "type": "boolean" + }, + "construct": { + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "managed": { + "type": "boolean" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "require_colons": { + "type": "boolean" + }, + "role_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "roles": { + "items": { + "$ref": "#/definitions/Role" + }, + "type": "array" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "Event": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + }, + "event": { + "$ref": "#/definitions/EVENT" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "EventOpts": { + "properties": { + "acknowledge": { + "$ref": "#/definitions/Function" + }, + "cancel": { + "$ref": "#/definitions/Function" + }, + "channel": { + "$ref": "#/definitions/Channel_1" + }, + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + }, + "event": { + "$ref": "#/definitions/EVENT" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Function": { + "properties": { + "arguments": { + }, + "caller": { + "$ref": "#/definitions/Function" + }, + "length": { + "type": "number" + }, + "name": { + "type": "string" + }, + "prototype": { + } + }, + "type": "object" + }, + "Guild": { + "properties": { + "afk_channel": { + "$ref": "#/definitions/Channel" + }, + "afk_channel_id": { + "type": "string" + }, + "afk_timeout": { + "type": "number" + }, + "banner": { + "type": "string" + }, + "channel_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "channels": { + "items": { + "$ref": "#/definitions/Channel" + }, + "type": "array" + }, + "construct": { + }, + "default_message_notifications": { + "type": "number" + }, + "description": { + "type": "string" + }, + "discovery_splash": { + "type": "string" + }, + "emoji_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "emojis": { + "items": { + "$ref": "#/definitions/Emoji" + }, + "type": "array" + }, + "explicit_content_filter": { + "type": "number" + }, + "features": { + "items": { + "type": "string" + }, + "type": "array" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "large": { + "type": "boolean" + }, + "max_members": { + "type": "number" + }, + "max_presences": { + "type": "number" + }, + "max_video_channel_users": { + "type": "number" + }, + "member_count": { + "type": "number" + }, + "member_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "members": { + "items": { + "$ref": "#/definitions/Member" + }, + "type": "array" + }, + "metadata": { + }, + "mfa_level": { + "type": "number" + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "owner": { + "$ref": "#/definitions/User" + }, + "owner_id": { + "type": "string" + }, + "preferred_locale": { + "type": "string" + }, + "premium_subscription_count": { + "type": "number" + }, + "premium_tier": { + "type": "number" + }, + "presence_count": { + "type": "number" + }, + "public_updates_channel": { + "$ref": "#/definitions/Channel" + }, + "region": { + "type": "string" + }, + "role_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "roles": { + "items": { + "$ref": "#/definitions/Role" + }, + "type": "array" + }, + "rules_channel": { + "type": "string" + }, + "rules_channel_id": { + "type": "string" + }, + "splash": { + "type": "string" + }, + "system_channel": { + "$ref": "#/definitions/Channel" + }, + "system_channel_flags": { + "type": "number" + }, + "system_channel_id": { + "type": "string" + }, + "unavailable": { + "type": "boolean" + }, + "vanity_url": { + "$ref": "#/definitions/Invite" + }, + "verification_level": { + "type": "number" + }, + "voice_state_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "voice_states": { + "items": { + "$ref": "#/definitions/VoiceState" + }, + "type": "array" + }, + "welcome_screen": { + "properties": { + "description": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "welcome_channels": { + "items": { + "properties": { + "channel_id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "emoji_id": { + "type": "string" + }, + "emoji_name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "widget_channel": { + "$ref": "#/definitions/Channel" + }, + "widget_enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "GuildBanAddEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_BAN_ADD" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildBanRemoveEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_BAN_REMOVE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildCreateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Guild" + }, + "event": { + "enum": [ + "GUILD_CREATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildDeleteEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "id": { + "type": "string" + }, + "unavailable": { + "type": "boolean" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_DELETE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildEmojiUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "emojis": { + "items": { + "$ref": "#/definitions/Emoji" + }, + "type": "array" + }, + "guild_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_EMOJI_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildIntegrationUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_INTEGRATIONS_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildMemberAddEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/PublicMember" + }, + { + "properties": { + "guild_id": { + "type": "string" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "GUILD_MEMBER_ADD" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildMemberRemoveEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_MEMBER_REMOVE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildMemberUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + }, + "joined_at": { + "format": "date-time", + "type": "string" + }, + "nick": { + "type": "string" + }, + "pending": { + "type": "boolean" + }, + "premium_since": { + "type": "number" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_MEMBER_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildMembersChunkEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "chunk_count": { + "type": "number" + }, + "chunk_index": { + "type": "number" + }, + "guild_id": { + "type": "string" + }, + "members": { + "items": { + "$ref": "#/definitions/PublicMember" + }, + "type": "array" + }, + "nonce": { + "type": "string" + }, + "not_found": { + "items": { + "type": "string" + }, + "type": "array" + }, + "presences": { + "items": { + "$ref": "#/definitions/Presence" + }, + "type": "array" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_MEMBERS_CHUNK" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildRoleCreateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + }, + "role": { + "$ref": "#/definitions/Role" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_ROLE_CREATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildRoleDeleteEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + }, + "role_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_ROLE_DELETE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildRoleUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "guild_id": { + "type": "string" + }, + "role": { + "$ref": "#/definitions/Role" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "GUILD_ROLE_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "GuildUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Guild" + }, + "event": { + "enum": [ + "GUILD_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Intents": { + "properties": { + "bitfield": { + "type": "bigint" + } + }, + "type": "object" + }, + "Interaction": { + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "properties": { + }, + "type": "object" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "member_id": { + "type": "string" + }, + "token": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/InteractionType" + }, + "version": { + "type": "number" + } + }, + "type": "object" + }, + "InteractionApplicationCommandCallbackData": { + "properties": { + "allowed_mentions": { + "$ref": "#/definitions/AllowedMentions" + }, + "content": { + "type": "string" + }, + "embeds": { + "items": { + "$ref": "#/definitions/Embed" + }, + "type": "array" + }, + "tts": { + "type": "boolean" + } + }, + "type": "object" + }, + "InteractionCreateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Interaction" + }, + "event": { + "enum": [ + "INTERACTION_CREATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "InteractionResponseType": { + "enum": [ + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" + }, + "InteractionType": { + "enum": [ + 1, + 2 + ], + "type": "number" + }, + "InvalidatedEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + }, + "event": { + "enum": [ + "INVALIDATED" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Invite": { + "properties": { + "channel": { + "$ref": "#/definitions/Channel" + }, + "channel_id": { + "type": "string" + }, + "code": { + "type": "string" + }, + "construct": { + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "expires_at": { + "format": "date-time", + "type": "string" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "inviter": { + "$ref": "#/definitions/User" + }, + "inviter_id": { + "type": "string" + }, + "max_age": { + "type": "number" + }, + "max_uses": { + "type": "number" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "target_user": { + "type": "string" + }, + "target_user_type": { + "type": "number" + }, + "target_usser_id": { + "type": "string" + }, + "temporary": { + "type": "boolean" + }, + "uses": { + "type": "number" + } + }, + "type": "object" + }, + "InviteCreateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/Omit<Invite,\"guild\"|\"channel\">" + }, + { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "INVITE_CREATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "InviteDeleteEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "code": { + "type": "string" + }, + "guild_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "INVITE_DELETE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ListenEventOpts": { + "properties": { + "acknowledge": { + "type": "boolean" + }, + "channel": { + "$ref": "#/definitions/Channel_1" + } + }, + "type": "object" + }, + "Member": { + "properties": { + "construct": { + }, + "deaf": { + "type": "boolean" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "joined_at": { + "format": "date-time", + "type": "string" + }, + "metadata": { + }, + "mute": { + "type": "boolean" + }, + "nick": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "pending": { + "type": "boolean" + }, + "premium_since": { + "type": "number" + }, + "read_state": { + "$ref": "#/definitions/Record<string,string|null>" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array" + }, + "settings": { + "$ref": "#/definitions/UserGuildSettings" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Message": { + "properties": { + "activity": { + "properties": { + "party_id": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "type": "object" + }, + "application": { + "$ref": "#/definitions/Application" + }, + "application_id": { + "type": "string" + }, + "attachments": { + "items": { + "$ref": "#/definitions/Attachment" + }, + "type": "array" + }, + "author": { + "$ref": "#/definitions/User" + }, + "author_id": { + "type": "string" + }, + "channel": { + "$ref": "#/definitions/Channel" + }, + "channel_id": { + "type": "string" + }, + "components": { + "items": { + "$ref": "#/definitions/MessageComponent" + }, + "type": "array" + }, + "construct": { + }, + "content": { + "type": "string" + }, + "edited_timestamp": { + "format": "date-time", + "type": "string" + }, + "embeds": { + "items": { + "$ref": "#/definitions/Embed" + }, + "type": "array" + }, + "flags": { + "type": "bigint" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "interaction": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/InteractionType" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "member": { + "$ref": "#/definitions/Member" + }, + "member_id": { + "type": "string" + }, + "mention_channel_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mention_channels": { + "items": { + "$ref": "#/definitions/Channel" + }, + "type": "array" + }, + "mention_everyone": { + "type": "boolean" + }, + "mention_role_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mention_roles": { + "items": { + "$ref": "#/definitions/Role" + }, + "type": "array" + }, + "mention_user_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mention_users": { + "items": { + "$ref": "#/definitions/User" + }, + "type": "array" + }, + "message_reference": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "message_id": { + "type": "string" + } + }, + "type": "object" + }, + "metadata": { + }, + "nonce": { + "type": [ + "string", + "number" + ] + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "pinned": { + "type": "boolean" + }, + "reactions": { + "items": { + "$ref": "#/definitions/Reaction" + }, + "type": "array" + }, + "stickers": { + "items": { + }, + "type": "array" + }, + "timestamp": { + "format": "date-time", + "type": "string" + }, + "tts": { + "type": "boolean" + }, + "type": { + "$ref": "#/definitions/MessageType" + }, + "webhook": { + "$ref": "#/definitions/Webhook" + }, + "webhook_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageAckEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "manual": { + "type": "boolean" + }, + "mention_count": { + "type": "number" + }, + "message_id": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "MESSAGE_ACK" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageComponent": { + "properties": { + "components": { + "items": { + "$ref": "#/definitions/MessageComponent" + }, + "type": "array" + }, + "custom_id": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "emoji": { + "$ref": "#/definitions/PartialEmoji" + }, + "label": { + "type": "string" + }, + "style": { + "type": "number" + }, + "type": { + "type": "number" + }, + "url": { + "type": "string" + } + }, + "type": "object" + }, + "MessageComponentType": { + "enum": [ + 1, + 2 + ], + "type": "number" + }, + "MessageCreateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/Omit<Message,\"author_id\">" + }, + { + "properties": { + "author": { + "$ref": "#/definitions/PublicUser" + }, + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "member": { + "$ref": "#/definitions/PublicMember" + }, + "mentions": { + "items": { + "allOf": [ + { + "$ref": "#/definitions/PublicUser" + }, + { + "properties": { + "member": { + "$ref": "#/definitions/PublicMember" + } + }, + "type": "object" + } + ] + }, + "type": "array" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "MESSAGE_CREATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageDeleteBulkEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "ids": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "MESSAGE_DELETE_BULK" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageDeleteEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "MESSAGE_DELETE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageFlags": { + "properties": { + "bitfield": { + "type": "bigint" + } + }, + "type": "object" + }, + "MessagePayload": { + "allOf": [ + { + "$ref": "#/definitions/Omit<Message,\"author_id\">" + }, + { + "properties": { + "author": { + "$ref": "#/definitions/PublicUser" + }, + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "member": { + "$ref": "#/definitions/PublicMember" + }, + "mentions": { + "items": { + "allOf": [ + { + "$ref": "#/definitions/PublicUser" + }, + { + "properties": { + "member": { + "$ref": "#/definitions/PublicMember" + } + }, + "type": "object" + } + ] + }, + "type": "array" + } + }, + "type": "object" + } + ] + }, + "MessageReactionAddEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "emoji": { + "$ref": "#/definitions/PartialEmoji" + }, + "guild_id": { + "type": "string" + }, + "member": { + "$ref": "#/definitions/PublicMember" + }, + "message_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "MESSAGE_REACTION_ADD" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageReactionRemoveAllEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "message_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "MESSAGE_REACTION_REMOVE_ALL" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageReactionRemoveEmojiEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "emoji": { + "$ref": "#/definitions/PartialEmoji" + }, + "guild_id": { + "type": "string" + }, + "message_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "MESSAGE_REACTION_REMOVE_EMOJI" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageReactionRemoveEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "emoji": { + "$ref": "#/definitions/PartialEmoji" + }, + "guild_id": { + "type": "string" + }, + "message_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "MESSAGE_REACTION_REMOVE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MessageType": { + "enum": [ + 0, + 1, + 10, + 11, + 12, + 14, + 15, + 19, + 2, + 20, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "type": "number" + }, + "MessageUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/Omit<Message,\"author_id\">" + }, + { + "properties": { + "author": { + "$ref": "#/definitions/PublicUser" + }, + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "member": { + "$ref": "#/definitions/PublicMember" + }, + "mentions": { + "items": { + "allOf": [ + { + "$ref": "#/definitions/PublicUser" + }, + { + "properties": { + "member": { + "$ref": "#/definitions/PublicMember" + } + }, + "type": "object" + } + ] + }, + "type": "array" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "MESSAGE_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "MuteConfig": { + "properties": { + "end_time": { + "type": "number" + }, + "selected_time_window": { + "type": "number" + } + }, + "type": "object" + }, + "Omit<Invite,\"guild\"|\"channel\">": { + "properties": { + "assign": { + "type": "object" + }, + "channel_id": { + "type": "string" + }, + "code": { + "type": "string" + }, + "construct": { + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "expires_at": { + "format": "date-time", + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "hasId": { + "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", + "type": "object" + }, + "id": { + "type": "string" + }, + "inviter": { + "$ref": "#/definitions/User" + }, + "inviter_id": { + "type": "string" + }, + "max_age": { + "type": "number" + }, + "max_uses": { + "type": "number" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "recover": { + "description": "Recovers a given entity in the database.", + "type": "object" + }, + "reload": { + "description": "Reloads entity data from the database.", + "type": "object" + }, + "remove": { + "description": "Removes current entity from the database.", + "type": "object" + }, + "save": { + "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", + "type": "object" + }, + "softRemove": { + "description": "Records the delete date of current entity.", + "type": "object" + }, + "target_user": { + "type": "string" + }, + "target_user_type": { + "type": "number" + }, + "target_usser_id": { + "type": "string" + }, + "temporary": { + "type": "boolean" + }, + "toJSON": { + "type": "object" + }, + "uses": { + "type": "number" + }, + "validate": { + "type": "object" + } + }, + "type": "object" + }, + "Omit<Member,\"settings\"|\"user\">": { + "properties": { + "assign": { + "type": "object" + }, + "construct": { + }, + "deaf": { + "type": "boolean" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "hasId": { + "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", + "type": "object" + }, + "id": { + "type": "string" + }, + "joined_at": { + "format": "date-time", + "type": "string" + }, + "metadata": { + }, + "mute": { + "type": "boolean" + }, + "nick": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "pending": { + "type": "boolean" + }, + "premium_since": { + "type": "number" + }, + "read_state": { + "$ref": "#/definitions/Record<string,string|null>" + }, + "recover": { + "description": "Recovers a given entity in the database.", + "type": "object" + }, + "reload": { + "description": "Reloads entity data from the database.", + "type": "object" + }, + "remove": { + "description": "Removes current entity from the database.", + "type": "object" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array" + }, + "save": { + "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", + "type": "object" + }, + "softRemove": { + "description": "Records the delete date of current entity.", + "type": "object" + }, + "toJSON": { + "type": "object" + }, + "user_id": { + "type": "string" + }, + "validate": { + "type": "object" + } + }, + "type": "object" + }, + "Omit<Message,\"author_id\">": { + "properties": { + "activity": { + "properties": { + "party_id": { + "type": "string" + }, + "type": { + "type": "number" + } + }, + "type": "object" + }, + "application": { + "$ref": "#/definitions/Application" + }, + "application_id": { + "type": "string" + }, + "assign": { + "type": "object" + }, + "attachments": { + "items": { + "$ref": "#/definitions/Attachment" + }, + "type": "array" + }, + "author": { + "$ref": "#/definitions/User" + }, + "channel": { + "$ref": "#/definitions/Channel" + }, + "channel_id": { + "type": "string" + }, + "components": { + "items": { + "$ref": "#/definitions/MessageComponent" + }, + "type": "array" + }, + "construct": { + }, + "content": { + "type": "string" + }, + "edited_timestamp": { + "format": "date-time", + "type": "string" + }, + "embeds": { + "items": { + "$ref": "#/definitions/Embed" + }, + "type": "array" + }, + "flags": { + "type": "bigint" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "hasId": { + "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", + "type": "object" + }, + "id": { + "type": "string" + }, + "interaction": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/InteractionType" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "member": { + "$ref": "#/definitions/Member" + }, + "member_id": { + "type": "string" + }, + "mention_channel_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mention_channels": { + "items": { + "$ref": "#/definitions/Channel" + }, + "type": "array" + }, + "mention_everyone": { + "type": "boolean" + }, + "mention_role_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mention_roles": { + "items": { + "$ref": "#/definitions/Role" + }, + "type": "array" + }, + "mention_user_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "mention_users": { + "items": { + "$ref": "#/definitions/User" + }, + "type": "array" + }, + "message_reference": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "message_id": { + "type": "string" + } + }, + "type": "object" + }, + "metadata": { + }, + "nonce": { + "type": [ + "string", + "number" + ] + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "pinned": { + "type": "boolean" + }, + "reactions": { + "items": { + "$ref": "#/definitions/Reaction" + }, + "type": "array" + }, + "recover": { + "description": "Recovers a given entity in the database.", + "type": "object" + }, + "reload": { + "description": "Reloads entity data from the database.", + "type": "object" + }, + "remove": { + "description": "Removes current entity from the database.", + "type": "object" + }, + "save": { + "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", + "type": "object" + }, + "softRemove": { + "description": "Records the delete date of current entity.", + "type": "object" + }, + "stickers": { + "items": { + }, + "type": "array" + }, + "timestamp": { + "format": "date-time", + "type": "string" + }, + "toJSON": { + "type": "object" + }, + "tts": { + "type": "boolean" + }, + "type": { + "$ref": "#/definitions/MessageType" + }, + "validate": { + "type": "object" + }, + "webhook": { + "$ref": "#/definitions/Webhook" + }, + "webhook_id": { + "type": "string" + } + }, + "type": "object" + }, + "Omit<Relationship,\"nickname\">": { + "properties": { + "assign": { + "type": "object" + }, + "construct": { + }, + "hasId": { + "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", + "type": "object" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "recover": { + "description": "Recovers a given entity in the database.", + "type": "object" + }, + "reload": { + "description": "Reloads entity data from the database.", + "type": "object" + }, + "remove": { + "description": "Removes current entity from the database.", + "type": "object" + }, + "save": { + "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", + "type": "object" + }, + "softRemove": { + "description": "Records the delete date of current entity.", + "type": "object" + }, + "toJSON": { + "type": "object" + }, + "type": { + "$ref": "#/definitions/RelationshipType" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + }, + "validate": { + "type": "object" + } + }, + "type": "object" + }, + "PartialEmoji": { + "properties": { + "animated": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "PermissionCache": { + "properties": { + "channel": { + "anyOf": [ + { + "$ref": "#/definitions/Channel" + }, + { + "type": "null" + } + ] + }, + "guild": { + "anyOf": [ + { + "$ref": "#/definitions/Guild" + }, + { + "type": "null" + } + ] + }, + "member": { + "anyOf": [ + { + "$ref": "#/definitions/Member" + }, + { + "type": "null" + } + ] + }, + "roles": { + "anyOf": [ + { + "items": { + "$ref": "#/definitions/Role" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "PermissionResolvable": { + "anyOf": [ + { + "$ref": "#/definitions/Permissions" + }, + { + "items": { + "$ref": "#/definitions/PermissionResolvable" + }, + "type": "array" + }, + { + "enum": [ + "ADD_REACTIONS", + "ADMINISTRATOR", + "ATTACH_FILES", + "BAN_MEMBERS", + "CHANGE_NICKNAME", + "CONNECT", + "CREATE_INSTANT_INVITE", + "DEAFEN_MEMBERS", + "EMBED_LINKS", + "KICK_MEMBERS", + "MANAGE_CHANNELS", + "MANAGE_EMOJIS_AND_STICKERS", + "MANAGE_GUILD", + "MANAGE_MESSAGES", + "MANAGE_NICKNAMES", + "MANAGE_ROLES", + "MANAGE_WEBHOOKS", + "MENTION_EVERYONE", + "MOVE_MEMBERS", + "MUTE_MEMBERS", + "PRIORITY_SPEAKER", + "READ_MESSAGE_HISTORY", + "SEND_MESSAGES", + "SEND_TTS_MESSAGES", + "SPEAK", + "STREAM", + "USE_EXTERNAL_EMOJIS", + "USE_VAD", + "VIEW_AUDIT_LOG", + "VIEW_CHANNEL", + "VIEW_GUILD_INSIGHTS" + ], + "type": "string" + }, + { + "type": [ + "number", + "bigint" + ] + } + ] + }, + "PermissionString": { + "enum": [ + "ADD_REACTIONS", + "ADMINISTRATOR", + "ATTACH_FILES", + "BAN_MEMBERS", + "CHANGE_NICKNAME", + "CONNECT", + "CREATE_INSTANT_INVITE", + "DEAFEN_MEMBERS", + "EMBED_LINKS", + "KICK_MEMBERS", + "MANAGE_CHANNELS", + "MANAGE_EMOJIS_AND_STICKERS", + "MANAGE_GUILD", + "MANAGE_MESSAGES", + "MANAGE_NICKNAMES", + "MANAGE_ROLES", + "MANAGE_WEBHOOKS", + "MENTION_EVERYONE", + "MOVE_MEMBERS", + "MUTE_MEMBERS", + "PRIORITY_SPEAKER", + "READ_MESSAGE_HISTORY", + "SEND_MESSAGES", + "SEND_TTS_MESSAGES", + "SPEAK", + "STREAM", + "USE_EXTERNAL_EMOJIS", + "USE_VAD", + "VIEW_AUDIT_LOG", + "VIEW_CHANNEL", + "VIEW_GUILD_INSIGHTS" + ], + "type": "string" + }, + "Permissions": { + "properties": { + "bitfield": { + "type": "bigint" + }, + "cache": { + "properties": { + "channel": { + "anyOf": [ + { + "$ref": "#/definitions/Channel" + }, + { + "type": "null" + } + ] + }, + "guild": { + "anyOf": [ + { + "$ref": "#/definitions/Guild" + }, + { + "type": "null" + } + ] + }, + "member": { + "anyOf": [ + { + "$ref": "#/definitions/Member" + }, + { + "type": "null" + } + ] + }, + "roles": { + "anyOf": [ + { + "items": { + "$ref": "#/definitions/Role" + }, + "type": "array" + }, + { + "type": "null" + } + ] + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "Presence": { + "properties": { + "activities": { + "items": { + "$ref": "#/definitions/Activity" + }, + "type": "array" + }, + "client_status": { + "$ref": "#/definitions/ClientStatus" + }, + "guild_id": { + "type": "string" + }, + "status": { + "$ref": "#/definitions/Status" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "PresenceUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Presence" + }, + "event": { + "enum": [ + "PRESENCE_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "PublicMember": { + "properties": { + "assign": { + "type": "object" + }, + "construct": { + }, + "deaf": { + "type": "boolean" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "hasId": { + "description": "Checks if entity has an id.\nIf entity composite compose ids, it will check them all.", + "type": "object" + }, + "joined_at": { + "format": "date-time", + "type": "string" + }, + "metadata": { + }, + "mute": { + "type": "boolean" + }, + "nick": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "pending": { + "type": "boolean" + }, + "premium_since": { + "type": "number" + }, + "recover": { + "description": "Recovers a given entity in the database.", + "type": "object" + }, + "reload": { + "description": "Reloads entity data from the database.", + "type": "object" + }, + "remove": { + "description": "Removes current entity from the database.", + "type": "object" + }, + "roles": { + "items": { + "type": "string" + }, + "type": "array" + }, + "save": { + "description": "Saves current entity in the database.\nIf entity does not exist in the database then inserts, otherwise updates.", + "type": "object" + }, + "softRemove": { + "description": "Records the delete date of current entity.", + "type": "object" + }, + "toJSON": { + "type": "object" + }, + "user": { + "$ref": "#/definitions/PublicUser" + }, + "user_id": { + "type": "string" + }, + "validate": { + "type": "object" + } + }, + "type": "object" + }, + "PublicUser": { + "properties": { + "accent_color": { + "type": "number" + }, + "avatar": { + "type": "string" + }, + "banner": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "bigint" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "RateLimit": { + "properties": { + "blocked": { + "type": "boolean" + }, + "construct": { + }, + "expires_at": { + "format": "date-time", + "type": "string" + }, + "hits": { + "type": "number" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Reaction": { + "properties": { + "count": { + "type": "number" + }, + "emoji": { + "$ref": "#/definitions/PartialEmoji" + }, + "user_ids": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "ReadState": { + "properties": { + "channel": { + "$ref": "#/definitions/Channel" + }, + "channel_id": { + "type": "string" + }, + "construct": { + }, + "id": { + "type": "string" + }, + "last_message": { + "$ref": "#/definitions/Message" + }, + "last_pin_timestamp": { + "format": "date-time", + "type": "string" + }, + "manual": { + "type": "boolean" + }, + "mention_count": { + "type": "number" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ReadyEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/ReadyEventData" + }, + "event": { + "enum": [ + "READY" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "ReadyEventData": { + "properties": { + "analytics_token": { + "type": "string" + }, + "application": { + "properties": { + "flags": { + "type": "bigint" + }, + "id": { + "type": "string" + } + }, + "type": "object" + }, + "connected_accounts": { + "items": { + "$ref": "#/definitions/ConnectedAccount" + }, + "type": "array" + }, + "consents": { + "properties": { + "personalization": { + "properties": { + "consented": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "country_code": { + "type": "string" + }, + "experiments": { + "items": { + "items": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ], + "maxItems": 5, + "minItems": 5, + "type": "array" + }, + "type": "array" + }, + "friend_suggestion_count": { + "type": "number" + }, + "geo_ordered_rtc_regions": { + "items": { + "type": "string" + }, + "type": "array" + }, + "guild_experiments": { + "items": { + "items": [ + { + "type": "number" + }, + { + "type": "null" + }, + { + "type": "number" + }, + { + "items": [ + { + "items": [ + { + "type": "number" + }, + { + "items": { + "properties": { + "e": { + "type": "number" + }, + "s": { + "type": "number" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ], + "maxItems": 1, + "minItems": 1, + "type": "array" + }, + { + "items": [ + { + "type": "number" + }, + { + "items": [ + { + "items": [ + { + "type": "number" + }, + { + "items": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ], + "maxItems": 2, + "minItems": 2, + "type": "array" + } + ], + "maxItems": 1, + "minItems": 1, + "type": "array" + } + ], + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + { + "items": { + "properties": { + "b": { + "type": "number" + }, + "k": { + "items": { + "type": "bigint" + }, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + ], + "maxItems": 6, + "minItems": 6, + "type": "array" + }, + "type": "array" + }, + "guild_join_requests": { + "items": { + }, + "type": "array" + }, + "guilds": { + "items": { + "$ref": "#/definitions/Guild" + }, + "type": "array" + }, + "merged_members": { + "items": { + "items": { + "$ref": "#/definitions/Omit<Member,\"settings\"|\"user\">" + }, + "type": "array" + }, + "type": "array" + }, + "private_channels": { + "items": { + "$ref": "#/definitions/Channel" + }, + "type": "array" + }, + "read_state": { + "properties": { + "entries": { + "items": { + }, + "type": "array" + }, + "partial": { + "type": "boolean" + }, + "version": { + "type": "number" + } + }, + "type": "object" + }, + "relationships": { + "items": { + "$ref": "#/definitions/Relationship" + }, + "type": "array" + }, + "session_id": { + "type": "string" + }, + "shard": { + "items": [ + { + "type": "number" + }, + { + "type": "number" + } + ], + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "user": { + "allOf": [ + { + "$ref": "#/definitions/PublicUser" + }, + { + "properties": { + "bot": { + "type": "boolean" + }, + "desktop": { + "type": "boolean" + }, + "email": { + "type": [ + "null", + "string" + ] + }, + "flags": { + "type": "bigint" + }, + "mfa_enabled": { + "type": "boolean" + }, + "mobile": { + "type": "boolean" + }, + "nsfw_allowed": { + "type": "boolean" + }, + "phone": { + "type": [ + "null", + "string" + ] + }, + "premium": { + "type": "boolean" + }, + "premium_type": { + "type": "number" + }, + "verified": { + "type": "boolean" + } + }, + "type": "object" + } + ] + }, + "user_guild_settings": { + "properties": { + "entries": { + "items": { + "$ref": "#/definitions/UserGuildSettings" + }, + "type": "array" + }, + "partial": { + "type": "boolean" + }, + "version": { + "type": "number" + } + }, + "type": "object" + }, + "user_settings": { + "$ref": "#/definitions/UserSettings" + }, + "users": { + "items": { + "properties": { + "avatar": { + "type": [ + "null", + "string" + ] + }, + "bot": { + "type": "boolean" + }, + "discriminator": { + "type": "string" + }, + "id": { + "type": "string" + }, + "public_flags": { + "type": "bigint" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "v": { + "type": "number" + } + }, + "type": "object" + }, + "Record<string,string|null>": { + "type": "object" + }, + "Relationship": { + "properties": { + "construct": { + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "nickname": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "type": { + "$ref": "#/definitions/RelationshipType" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "RelationshipAddEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/Relationship" + }, + { + "properties": { + "should_notify": { + "type": "boolean" + }, + "user": { + "$ref": "#/definitions/PublicUser" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "RELATIONSHIP_ADD" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "RelationshipRemoveEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/Omit<Relationship,\"nickname\">" + }, + "event": { + "enum": [ + "RELATIONSHIP_REMOVE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "RelationshipType": { + "enum": [ + 1, + 2, + 3, + 4 + ], + "type": "number" + }, + "Role": { + "properties": { + "color": { + "type": "number" + }, + "construct": { + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "guild_id": { + "type": "string" + }, + "hoist": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "managed": { + "type": "boolean" + }, + "mentionable": { + "type": "boolean" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "type": "bigint" + }, + "position": { + "type": "number" + }, + "tags": { + "properties": { + "bot_id": { + "type": "string" + }, + "integration_id": { + "type": "string" + }, + "premium_subscriber": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "Snowflake": { + "description": "A container for useful snowflake-related methods.", + "type": "object" + }, + "Status": { + "enum": [ + "dnd", + "idle", + "offline", + "online" + ], + "type": "string" + }, + "Team": { + "properties": { + "construct": { + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string" + }, + "member_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "members": { + "items": { + "$ref": "#/definitions/TeamMember" + }, + "type": "array" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "owner_user": { + "$ref": "#/definitions/User" + }, + "owner_user_id": { + "type": "string" + } + }, + "type": "object" + }, + "TeamMember": { + "properties": { + "construct": { + }, + "id": { + "type": "string" + }, + "membership_state": { + "$ref": "#/definitions/TeamMemberState" + }, + "metadata": { + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "items": { + "type": "string" + }, + "type": "array" + }, + "team": { + "$ref": "#/definitions/Team" + }, + "team_id": { + "type": "string" + }, + "user": { + "$ref": "#/definitions/User" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "TeamMemberState": { + "enum": [ + 1, + 2 + ], + "type": "number" + }, + "Template": { + "properties": { + "code": { + "type": "string" + }, + "construct": { + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "creator": { + "$ref": "#/definitions/User" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "source_guild": { + "$ref": "#/definitions/Guild" + }, + "updated_at": { + "format": "date-time", + "type": "string" + }, + "usage_count": { + "type": "number" + } + }, + "type": "object" + }, + "TypingStartEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "member": { + "$ref": "#/definitions/PublicMember" + }, + "timestamp": { + "type": "number" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "TYPING_START" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "User": { + "properties": { + "accent_color": { + "type": "number" + }, + "avatar": { + "type": "string" + }, + "banner": { + "type": "string" + }, + "bio": { + "type": "string" + }, + "bot": { + "type": "boolean" + }, + "connected_account_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "connected_accounts": { + "items": { + "$ref": "#/definitions/ConnectedAccount" + }, + "type": "array" + }, + "construct": { + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "deleted": { + "type": "boolean" + }, + "desktop": { + "type": "boolean" + }, + "disabled": { + "type": "boolean" + }, + "discriminator": { + "type": "string" + }, + "email": { + "type": "string" + }, + "flags": { + "type": "bigint" + }, + "guilds": { + "items": { + "type": "string" + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "mfa_enabled": { + "type": "boolean" + }, + "mobile": { + "type": "boolean" + }, + "nsfw_allowed": { + "type": "boolean" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "phone": { + "type": "string" + }, + "premium": { + "type": "boolean" + }, + "premium_type": { + "type": "number" + }, + "public_flags": { + "type": "bigint" + }, + "relationship_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "relationships": { + "items": { + "$ref": "#/definitions/Relationship" + }, + "type": "array" + }, + "settings": { + "$ref": "#/definitions/UserSettings" + }, + "system": { + "type": "boolean" + }, + "user_data": { + "properties": { + "fingerprints": { + "items": { + "type": "string" + }, + "type": "array" + }, + "hash": { + "type": "string" + }, + "valid_tokens_since": { + "format": "date-time", + "type": "string" + } + }, + "type": "object" + }, + "username": { + "type": "string" + }, + "verified": { + "type": "boolean" + } + }, + "type": "object" + }, + "UserFlags": { + "properties": { + "bitfield": { + "type": "bigint" + } + }, + "type": "object" + }, + "UserGuildSettings": { + "properties": { + "channel_overrides": { + "items": { + "properties": { + "channel_id": { + "type": "string" + }, + "message_notifications": { + "type": "number" + }, + "mute_config": { + "$ref": "#/definitions/MuteConfig" + }, + "muted": { + "type": "boolean" + } + }, + "type": "object" + }, + "type": "array" + }, + "message_notifications": { + "type": "number" + }, + "mobile_push": { + "type": "boolean" + }, + "mute_config": { + "$ref": "#/definitions/MuteConfig" + }, + "muted": { + "type": "boolean" + }, + "suppress_everyone": { + "type": "boolean" + }, + "suppress_roles": { + "type": "boolean" + }, + "version": { + "type": "number" + } + }, + "type": "object" + }, + "UserSettings": { + "properties": { + "afk_timeout": { + "type": "number" + }, + "allow_accessibility_detection": { + "type": "boolean" + }, + "animate_emoji": { + "type": "boolean" + }, + "animate_stickers": { + "type": "number" + }, + "contact_sync_enabled": { + "type": "boolean" + }, + "convert_emoticons": { + "type": "boolean" + }, + "custom_status": { + "properties": { + "emoji_id": { + "type": "string" + }, + "emoji_name": { + "type": "string" + }, + "expires_at": { + "type": "number" + }, + "text": { + "type": "string" + } + }, + "type": "object" + }, + "default_guilds_restricted": { + "type": "boolean" + }, + "detect_platform_accounts": { + "type": "boolean" + }, + "developer_mode": { + "type": "boolean" + }, + "disable_games_tab": { + "type": "boolean" + }, + "enable_tts_command": { + "type": "boolean" + }, + "explicit_content_filter": { + "type": "number" + }, + "friend_source_flags": { + "properties": { + "all": { + "type": "boolean" + } + }, + "type": "object" + }, + "gateway_connected": { + "type": "boolean" + }, + "gif_auto_play": { + "type": "boolean" + }, + "guild_folders": { + "items": { + "properties": { + "color": { + "type": "number" + }, + "guild_ids": { + "items": { + "type": "string" + }, + "type": "array" + }, + "id": { + "type": "number" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "guild_positions": { + "items": { + "type": "string" + }, + "type": "array" + }, + "inline_attachment_media": { + "type": "boolean" + }, + "inline_embed_media": { + "type": "boolean" + }, + "locale": { + "type": "string" + }, + "message_display_compact": { + "type": "boolean" + }, + "native_phone_integration_enabled": { + "type": "boolean" + }, + "render_embeds": { + "type": "boolean" + }, + "render_reactions": { + "type": "boolean" + }, + "restricted_guilds": { + "items": { + "type": "string" + }, + "type": "array" + }, + "show_current_game": { + "type": "boolean" + }, + "status": { + "enum": [ + "dnd", + "idle", + "offline", + "online" + ], + "type": "string" + }, + "stream_notifications_enabled": { + "type": "boolean" + }, + "theme": { + "enum": [ + "dark", + "white" + ], + "type": "string" + }, + "timezone_offset": { + "type": "number" + } + }, + "type": "object" + }, + "UserUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "$ref": "#/definitions/User" + }, + "event": { + "enum": [ + "USER_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "VoiceServerUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "endpoint": { + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "VOICE_SERVER_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "VoiceState": { + "properties": { + "channel": { + "$ref": "#/definitions/Channel" + }, + "construct": { + }, + "deaf": { + "type": "boolean" + }, + "guild": { + "$ref": "#/definitions/Guild" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "mute": { + "type": "boolean" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "self_deaf": { + "type": "boolean" + }, + "self_mute": { + "type": "boolean" + }, + "self_stream": { + "type": "boolean" + }, + "self_video": { + "type": "boolean" + }, + "session_id": { + "type": "string" + }, + "suppress": { + "type": "boolean" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "type": "object" + }, + "VoiceStateUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "allOf": [ + { + "$ref": "#/definitions/VoiceState" + }, + { + "properties": { + "member": { + "$ref": "#/definitions/PublicMember" + } + }, + "type": "object" + } + ] + }, + "event": { + "enum": [ + "VOICE_STATE_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + }, + "Webhook": { + "properties": { + "application": { + "type": "string" + }, + "avatar": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "construct": { + }, + "guild": { + "type": "string" + }, + "id": { + "type": "string" + }, + "metadata": { + }, + "name": { + "type": "string" + }, + "opts": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "source_guild": { + "type": "string" + }, + "token": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/WebhookType" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "WebhookType": { + "enum": [ + 1, + 2 + ], + "type": "number" + }, + "WebhooksUpdateEvent": { + "properties": { + "channel_id": { + "type": "string" + }, + "created_at": { + "format": "date-time", + "type": "string" + }, + "data": { + "properties": { + "channel_id": { + "type": "string" + }, + "guild_id": { + "type": "string" + } + }, + "type": "object" + }, + "event": { + "enum": [ + "WEBHOOKS_UPDATE" + ], + "type": "string" + }, + "guild_id": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "type": "object" + } + } +} + diff --git a/util/src/index.ts b/util/src/index.ts
index 3565fb6b..d66af15b 100644 --- a/util/src/index.ts +++ b/util/src/index.ts
@@ -1,10 +1,12 @@ -export * from "./util/checkToken"; +import "reflect-metadata"; -export * as Constants from "./util/Constants"; -export * from "./models/index"; +// export * as Constants from "../util/Constants"; +export * from "./interfaces/index"; +export * from "./entities/index"; export * from "./util/index"; +import "./test"; -import Config from "./util/Config"; -import db, { MongooseCache, toObject } from "./util/Database"; +// import Config from "../util/Config"; +// import db, { MongooseCache, toObject } from "./util/Database"; -export { Config, db, MongooseCache, toObject }; +// export { Config }; diff --git a/util/src/interfaces/Activity.ts b/util/src/interfaces/Activity.ts new file mode 100644
index 00000000..f5a3c270 --- /dev/null +++ b/util/src/interfaces/Activity.ts
@@ -0,0 +1,43 @@ +export interface Activity { + name: string; + type: ActivityType; + url?: string; + created_at?: Date; + timestamps?: { + start?: number; + end?: number; + }[]; + application_id?: string; + details?: string; + state?: string; + emoji?: { + name: string; + id?: string; + amimated?: boolean; + }; + party?: { + id?: string; + size?: [number, number]; + }; + assets?: { + large_image?: string; + large_text?: string; + small_image?: string; + small_text?: string; + }; + secrets?: { + join?: string; + spectate?: string; + match?: string; + }; + instance?: boolean; + flags?: bigint; +} + +export enum ActivityType { + GAME = 0, + STREAMING = 1, + LISTENING = 2, + CUSTOM = 4, + COMPETING = 5, +} diff --git a/util/src/models/Event.ts b/util/src/interfaces/Event.ts
index 86d0fd00..1897706e 100644 --- a/util/src/models/Event.ts +++ b/util/src/interfaces/Event.ts
@@ -1,15 +1,17 @@ -import { ConnectedAccount, PublicUser, Relationship, User, UserSettings } from "./User"; -import { DMChannel, Channel } from "./Channel"; -import { Guild } from "./Guild"; -import { Member, PublicMember, UserGuildSettings } from "./Member"; -import { Emoji } from "./Emoji"; -import { Presence } from "./Activity"; -import { Role } from "./Role"; -import { Invite } from "./Invite"; -import { Message, PartialEmoji } from "./Message"; -import { VoiceState } from "./VoiceState"; -import { ApplicationCommand } from "./Application"; +import { PublicUser, User, UserSettings } from "../entities/User"; +import { Channel } from "../entities/Channel"; +import { Guild } from "../entities/Guild"; +import { Member, PublicMember, UserGuildSettings } from "../entities/Member"; +import { Emoji } from "../entities/Emoji"; +import { Role } from "../entities/Role"; +import { Invite } from "../entities/Invite"; +import { Message, PartialEmoji } from "../entities/Message"; +import { VoiceState } from "../entities/VoiceState"; +import { ApplicationCommand } from "../entities/Application"; import { Interaction } from "./Interaction"; +import { ConnectedAccount } from "../entities/ConnectedAccount"; +import { Relationship } from "../entities/Relationship"; +import { Presence } from "./Presence"; export interface Event { guild_id?: string; @@ -43,7 +45,7 @@ export interface ReadyEventData { verified: boolean; bot: boolean; }; - private_channels: DMChannel[]; // this will be empty for bots + private_channels: Channel[]; // this will be empty for bots session_id: string; // resuming guilds: Guild[]; analytics_token?: string; @@ -67,12 +69,12 @@ export interface ReadyEventData { [number, [[number, [number, number]]]], { b: number; k: bigint[] }[] ][]; - guild_join_requests?: []; // ? what is this? this is new + guild_join_requests?: any[]; // ? what is this? this is new shard?: [number, number]; user_settings?: UserSettings; relationships?: Relationship[]; // TODO read_state: { - entries: []; // TODO + entries: any[]; // TODO partial: boolean; version: number; }; diff --git a/util/src/models/Interaction.ts b/util/src/interfaces/Interaction.ts
index 764247a5..3cafb2d5 100644 --- a/util/src/models/Interaction.ts +++ b/util/src/interfaces/Interaction.ts
@@ -1,4 +1,4 @@ -import { AllowedMentions, Embed } from "./Message"; +import { AllowedMentions, Embed } from "../entities/Message"; export interface Interaction { id: string; diff --git a/util/src/interfaces/Presence.ts b/util/src/interfaces/Presence.ts new file mode 100644
index 00000000..4a1ff038 --- /dev/null +++ b/util/src/interfaces/Presence.ts
@@ -0,0 +1,10 @@ +import { ClientStatus, Status } from "./Status"; +import { Activity } from "./Activity"; + +export interface Presence { + user_id: string; + guild_id?: string; + status: Status; + activities: Activity[]; + client_status: ClientStatus; +} diff --git a/util/src/models/Status.ts b/util/src/interfaces/Status.ts
index 5a9bf2ca..c4dab586 100644 --- a/util/src/models/Status.ts +++ b/util/src/interfaces/Status.ts
@@ -5,9 +5,3 @@ export interface ClientStatus { mobile?: string; // e.g. iOS/Android web?: string; // e.g. browser, bot account } - -export const ClientStatus = { - desktop: String, - mobile: String, - web: String, -}; diff --git a/util/src/interfaces/index.ts b/util/src/interfaces/index.ts new file mode 100644
index 00000000..ab7fa429 --- /dev/null +++ b/util/src/interfaces/index.ts
@@ -0,0 +1,5 @@ +export * from "./Activity"; +export * from "./Presence"; +export * from "./Interaction"; +export * from "./Event"; +export * from "./Status"; diff --git a/util/src/models/Activity.ts b/util/src/models/Activity.ts deleted file mode 100644
index 17abd1ca..00000000 --- a/util/src/models/Activity.ts +++ /dev/null
@@ -1,132 +0,0 @@ -import { User } from ".."; -import { ClientStatus, Status } from "./Status"; -import { Schema, model, Types, Document } from "mongoose"; -import toBigInt from "../util/toBigInt"; - -export interface Presence { - user: User; - guild_id?: string; - status: Status; - activities: Activity[]; - client_status: ClientStatus; -} - -export interface Activity { - name: string; - type: ActivityType; - url?: string; - created_at?: Date; - timestamps?: { - start?: number; - end?: number; - }[]; - application_id?: string; - details?: string; - state?: string; - emoji?: { - name: string; - id?: string; - amimated?: boolean; - }; - party?: { - id?: string; - size?: [number, number]; - }; - assets?: { - large_image?: string; - large_text?: string; - small_image?: string; - small_text?: string; - }; - secrets?: { - join?: string; - spectate?: string; - match?: string; - }; - instance?: boolean; - flags?: bigint; -} - -export const ActivitySchema = { - name: { type: String, required: true }, - type: { type: Number, required: true }, - url: String, - created_at: Date, - timestamps: [ - { - start: Number, - end: Number, - }, - ], - application_id: String, - details: String, - state: String, - emoji: { - name: String, - id: String, - amimated: Boolean, - }, - party: { - id: String, - size: [Number, Number], - }, - assets: { - large_image: String, - large_text: String, - small_image: String, - small_text: String, - }, - secrets: { - join: String, - spectate: String, - match: String, - }, - instance: Boolean, - flags: { type: String, get: toBigInt }, -}; - -export const ActivityBodySchema = { - name: String, - type: Number, - $url: String, - $created_at: Date, - $timestamps: [ - { - $start: Number, - $end: Number, - }, - ], - $application_id: String, - $details: String, - $state: String, - $emoji: { - $name: String, - $id: String, - $amimated: Boolean, - }, - $party: { - $id: String, - $size: [Number, Number], - }, - $assets: { - $large_image: String, - $large_text: String, - $small_image: String, - $small_text: String, - }, - $secrets: { - $join: String, - $spectate: String, - $match: String, - }, - $instance: Boolean, - $flags: BigInt, -}; - -export enum ActivityType { - GAME = 0, - STREAMING = 1, - LISTENING = 2, - CUSTOM = 4, - COMPETING = 5, -} diff --git a/util/src/models/Application.ts b/util/src/models/Application.ts deleted file mode 100644
index fae6e8db..00000000 --- a/util/src/models/Application.ts +++ /dev/null
@@ -1,67 +0,0 @@ -import { Team } from "./Team"; - -export interface Application { - id: string; - name: string; - icon: string | null; - description: string; - rpc_origins: string[] | null; - bot_public: boolean; - bot_require_code_grant: boolean; - terms_of_service_url: string | null; - privacy_policy_url: string | null; - owner_id: string; - summary: string | null; - verify_key: string; - team: Team | null; - guild_id: string; // if this application is a game sold on Discord, this field will be the guild to which it has been linked - primary_sku_id: string | null; // if this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists - slug: string | null; // if this application is a game sold on Discord, this field will be the URL slug that links to the store page - cover_image: string | null; // the application's default rich presence invite cover image hash - flags: number; // the application's public flags -} - -export interface ApplicationCommand { - id: string; - application_id: string; - name: string; - description: string; - options?: ApplicationCommandOption[]; -} - -export interface ApplicationCommandOption { - type: ApplicationCommandOptionType; - name: string; - description: string; - required?: boolean; - choices?: ApplicationCommandOptionChoice[]; - options?: ApplicationCommandOption[]; -} - -export interface ApplicationCommandOptionChoice { - name: string; - value: string | number; -} - -export enum ApplicationCommandOptionType { - SUB_COMMAND = 1, - SUB_COMMAND_GROUP = 2, - STRING = 3, - INTEGER = 4, - BOOLEAN = 5, - USER = 6, - CHANNEL = 7, - ROLE = 8, -} - -export interface ApplicationCommandInteractionData { - id: string; - name: string; - options?: ApplicationCommandInteractionDataOption[]; -} - -export interface ApplicationCommandInteractionDataOption { - name: string; - value?: any; - options?: ApplicationCommandInteractionDataOption[]; -} diff --git a/util/src/models/Ban.ts b/util/src/models/Ban.ts deleted file mode 100644
index f09950ee..00000000 --- a/util/src/models/Ban.ts +++ /dev/null
@@ -1,32 +0,0 @@ -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; -import { PublicUserProjection, UserModel } from "./User"; - -export interface Ban extends Document { - user_id: string; - guild_id: string; - executor_id: string; - ip: string; - reason?: string; -} - -export const BanSchema = new Schema({ - user_id: { type: String, required: true }, - guild_id: { type: String, required: true }, - executor_id: { type: String, required: true }, - reason: String, - ip: String, // ? Should we store this in here, or in the UserModel? -}); - -BanSchema.virtual("user", { - ref: UserModel, - localField: "user_id", - foreignField: "id", - justOne: true, - autopopulate: { select: PublicUserProjection }, -}); - -BanSchema.set("removeResponse", ["user_id"]); - -// @ts-ignore -export const BanModel = db.model<Ban>("Ban", BanSchema, "bans"); diff --git a/util/src/models/Channel.ts b/util/src/models/Channel.ts deleted file mode 100644
index 2959decd..00000000 --- a/util/src/models/Channel.ts +++ /dev/null
@@ -1,111 +0,0 @@ -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; -import toBigInt from "../util/toBigInt"; -import { PublicUserProjection, UserModel } from "./User"; - -// @ts-ignore -export interface AnyChannel extends Channel, DMChannel, TextChannel, VoiceChannel { - recipient_ids: null | string[]; -} - -export interface ChannelDocument extends Document, AnyChannel { - id: string; -} - -export const ChannelSchema = new Schema({ - id: String, - created_at: { type: Schema.Types.Date, required: true }, - name: String, // can't be required for dm channels - type: { type: Number, required: true }, - guild_id: String, - owner_id: String, - parent_id: String, - recipient_ids: [String], - position: Number, - last_message_id: String, - last_pin_timestamp: Date, - nsfw: Boolean, - rate_limit_per_user: Number, - default_auto_archive_duration: Number, - topic: String, - permission_overwrites: [ - { - allow: { type: String, get: toBigInt }, - deny: { type: String, get: toBigInt }, - id: String, - type: { type: Number }, - }, - ], -}); - -ChannelSchema.virtual("recipients", { - ref: UserModel, - localField: "recipient_ids", - foreignField: "id", - justOne: false, - autopopulate: { select: PublicUserProjection }, -}); - -ChannelSchema.set("removeResponse", ["recipient_ids"]); - -// @ts-ignore -export const ChannelModel = db.model<ChannelDocument>("Channel", ChannelSchema, "channels"); - -export interface Channel { - id: string; - created_at: Date; - name: string; - type: number; -} - -export interface TextBasedChannel { - last_message_id?: string; - last_pin_timestamp?: number; - default_auto_archive_duration?: number; -} - -export interface GuildChannel extends Channel { - guild_id: string; - position: number; - parent_id?: string; - permission_overwrites: ChannelPermissionOverwrite[]; -} - -export interface ChannelPermissionOverwrite { - allow: bigint; // for bitfields we use bigints - deny: bigint; // for bitfields we use bigints - id: string; - type: ChannelPermissionOverwriteType; -} - -export enum ChannelPermissionOverwriteType { - role = 0, - member = 1, -} - -export interface VoiceChannel extends GuildChannel { - video_quality_mode?: number; - bitrate?: number; - user_limit?: number; -} - -export interface TextChannel extends GuildChannel, TextBasedChannel { - nsfw: boolean; - rate_limit_per_user: number; - topic?: string; -} -// @ts-ignore -export interface DMChannel extends Channel, TextBasedChannel { - owner_id: string; - recipient_ids: string[]; -} - -export enum ChannelType { - GUILD_TEXT = 0, // a text channel within a server - DM = 1, // a direct message between users - GUILD_VOICE = 2, // a voice channel within a server - GROUP_DM = 3, // a direct message between multiple users - GUILD_CATEGORY = 4, // an organizational category that contains up to 50 channels - GUILD_NEWS = 5, // a channel that users can follow and crosspost into their own server - GUILD_STORE = 6, // a channel in which game developers can sell their game on Discord -} diff --git a/util/src/models/Emoji.ts b/util/src/models/Emoji.ts deleted file mode 100644
index 3e5cad53..00000000 --- a/util/src/models/Emoji.ts +++ /dev/null
@@ -1,29 +0,0 @@ -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; - -export interface Emoji extends Document { - id: string; - animated: boolean; - available: boolean; - guild_id: string; - managed: boolean; - name: string; - require_colons: boolean; - url: string; - roles: string[]; // roles this emoji is whitelisted to (new discord feature?) -} - -export const EmojiSchema = new Schema({ - id: { type: String, required: true }, - animated: Boolean, - available: Boolean, - guild_id: String, - managed: Boolean, - name: String, - require_colons: Boolean, - url: String, - roles: [String], -}); - -// @ts-ignore -export const EmojiModel = db.model<Emoji>("Emoji", EmojiSchema, "emojis"); diff --git a/util/src/models/Guild.ts b/util/src/models/Guild.ts deleted file mode 100644
index a5dcd8e3..00000000 --- a/util/src/models/Guild.ts +++ /dev/null
@@ -1,159 +0,0 @@ -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; -import { ChannelModel } from "./Channel"; -import { EmojiModel } from "./Emoji"; -import { MemberModel } from "./Member"; -import { RoleModel } from "./Role"; - -export interface GuildDocument extends Document, Guild { - id: string; -} - -export interface Guild { - id: string; - afk_channel_id?: string; - afk_timeout?: number; - application_id?: string; - banner?: string; - default_message_notifications?: number; - description?: string; - discovery_splash?: string; - explicit_content_filter?: number; - features: string[]; - icon?: string; - large?: boolean; - max_members?: number; // e.g. default 100.000 - max_presences?: number; - max_video_channel_users?: number; // ? default: 25, is this max 25 streaming or watching - member_count?: number; - presence_count?: number; // users online - // members?: Member[]; // * Members are stored in a seperate collection - // roles: Role[]; // * Role are stored in a seperate collection - // channels: GuildChannel[]; // * Channels are stored in a seperate collection - // emojis: Emoji[]; // * Emojis are stored in a seperate collection - // voice_states: []; // * voice_states are stored in a seperate collection - //TODO: - presences?: object[]; - mfa_level?: number; - name: string; - owner_id: string; - preferred_locale?: string; // only community guilds can choose this - premium_subscription_count?: number; - premium_tier?: number; // nitro boost level - public_updates_channel_id?: string; - region?: string; - rules_channel_id?: string; - splash?: string; - system_channel_flags?: number; - system_channel_id?: string; - unavailable?: boolean; - vanity_url_code?: string; - verification_level?: number; - welcome_screen: { - enabled: boolean; - description: string; - welcome_channels: { - description: string; - emoji_id?: string; - emoji_name: string; - channel_id: string; - }[]; - }; - widget_channel_id?: string; - widget_enabled?: boolean; -} - -export const GuildSchema = new Schema({ - id: { type: String, required: true }, - afk_channel_id: String, - afk_timeout: Number, - application_id: String, - banner: String, - default_message_notifications: Number, - description: String, - discovery_splash: String, - explicit_content_filter: Number, - features: { type: [String], default: [] }, - icon: String, - large: Boolean, - max_members: { type: Number, default: 100000 }, - max_presences: Number, - max_video_channel_users: { type: Number, default: 25 }, - member_count: Number, - presences: { type: [Object], default: [] }, - presence_count: Number, - mfa_level: Number, - name: { type: String, required: true }, - owner_id: { type: String, required: true }, - preferred_locale: String, - premium_subscription_count: Number, - premium_tier: Number, - public_updates_channel_id: String, - region: String, - rules_channel_id: String, - splash: String, - system_channel_flags: Number, - system_channel_id: String, - unavailable: Boolean, - vanity_url_code: String, - verification_level: Number, - voice_states: { type: [Object], default: [] }, - welcome_screen: { - enabled: Boolean, - description: String, - welcome_channels: [ - { - description: String, - emoji_id: String, - emoji_name: String, - channel_id: String, - }, - ], - }, - widget_channel_id: String, - widget_enabled: Boolean, -}); - -GuildSchema.virtual("channels", { - ref: ChannelModel, - localField: "id", - foreignField: "guild_id", - justOne: false, - autopopulate: true, -}); - -GuildSchema.virtual("roles", { - ref: RoleModel, - localField: "id", - foreignField: "guild_id", - justOne: false, - autopopulate: true, -}); - -// nested populate is needed for member users: https://gist.github.com/yangsu/5312204 -GuildSchema.virtual("members", { - ref: MemberModel, - localField: "id", - foreignField: "guild_id", - justOne: false, -}); - -GuildSchema.virtual("emojis", { - ref: EmojiModel, - localField: "id", - foreignField: "guild_id", - justOne: false, - autopopulate: true, -}); - -GuildSchema.virtual("joined_at", { - ref: MemberModel, - localField: "id", - foreignField: "guild_id", - justOne: true, -}).get((member: any, virtual: any, doc: any) => { - return member?.joined_at; -}); - -// @ts-ignore -export const GuildModel = db.model<GuildDocument>("Guild", GuildSchema, "guilds"); diff --git a/util/src/models/Invite.ts b/util/src/models/Invite.ts deleted file mode 100644
index 01f12003..00000000 --- a/util/src/models/Invite.ts +++ /dev/null
@@ -1,95 +0,0 @@ -import { Schema, Document, Types } from "mongoose"; -import db from "../util/Database"; -import { ChannelModel } from "./Channel"; -import { PublicUserProjection, UserModel } from "./User"; -import { GuildModel } from "./Guild"; - -export interface Invite { - code: string; - temporary: boolean; - uses: number; - max_uses: number; - max_age: number; - created_at: Date; - expires_at: Date; - guild_id: string; - channel_id: string; - inviter_id: string; - - // ? What is this? - target_user_id?: string; - target_user_type?: number; -} - -export interface InviteDocument extends Invite, Document {} - -export const InviteSchema = new Schema({ - code: String, - temporary: Boolean, - uses: Number, - max_uses: Number, - max_age: Number, - created_at: Date, - expires_at: Date, - guild_id: String, - channel_id: String, - inviter_id: String, - - // ? What is this? - target_user_id: String, - target_user_type: Number, -}); - -InviteSchema.virtual("channel", { - ref: ChannelModel, - localField: "channel_id", - foreignField: "id", - justOne: true, - autopopulate: { - select: { - id: true, - name: true, - type: true, - }, - }, -}); - -InviteSchema.virtual("inviter", { - ref: UserModel, - localField: "inviter_id", - foreignField: "id", - justOne: true, - autopopulate: { - select: PublicUserProjection, - }, -}); - -InviteSchema.virtual("guild", { - ref: GuildModel, - localField: "guild_id", - foreignField: "id", - justOne: true, - autopopulate: { - select: { - id: true, - name: true, - splash: true, - banner: true, - description: true, - icon: true, - features: true, - verification_level: true, - vanity_url_code: true, - welcome_screen: true, - nsfw: true, - - // TODO: hide the following entries: - // channels: false, - // roles: false, - // emojis: false, - }, - }, -}); - -// @ts-ignore -export const InviteModel = db.model<InviteDocument>("Invite", InviteSchema, "invites"); diff --git a/util/src/models/Member.ts b/util/src/models/Member.ts deleted file mode 100644
index d1c9ad9b..00000000 --- a/util/src/models/Member.ts +++ /dev/null
@@ -1,109 +0,0 @@ -import { PublicUser, PublicUserProjection, User, UserModel } from "./User"; -import { Schema, Types, Document } from "mongoose"; -import db from "../util/Database"; - -export const PublicMemberProjection = { - id: true, - guild_id: true, - nick: true, - roles: true, - joined_at: true, - pending: true, - deaf: true, - mute: true, - premium_since: true, -}; - -export interface Member { - id: string; - guild_id: string; - nick?: string; - roles: string[]; - joined_at: Date; - premium_since?: number; - deaf: boolean; - mute: boolean; - pending: boolean; - settings: UserGuildSettings; - read_state: Record<string, string | null>; - // virtual - user?: User; -} - -export interface MemberDocument extends Member, Document { - id: string; -} - -export interface UserGuildSettings { - channel_overrides: { - channel_id: string; - message_notifications: number; - mute_config: MuteConfig; - muted: boolean; - }[]; - message_notifications: number; - mobile_push: boolean; - mute_config: MuteConfig; - muted: boolean; - suppress_everyone: boolean; - suppress_roles: boolean; - version: number; -} - -export interface MuteConfig { - end_time: number; - selected_time_window: number; -} - -const MuteConfig = { - end_time: Number, - selected_time_window: Number, -}; - -export const MemberSchema = new Schema({ - id: { type: String, required: true }, - guild_id: String, - nick: String, - roles: [String], - joined_at: Date, - premium_since: Number, - deaf: Boolean, - mute: Boolean, - pending: Boolean, - read_state: Object, - settings: { - channel_overrides: [ - { - channel_id: String, - message_notifications: Number, - mute_config: MuteConfig, - muted: Boolean, - }, - ], - message_notifications: Number, - mobile_push: Boolean, - mute_config: MuteConfig, - muted: Boolean, - suppress_everyone: Boolean, - suppress_roles: Boolean, - version: Number, - }, -}); - -MemberSchema.virtual("user", { - ref: UserModel, - localField: "id", - foreignField: "id", - justOne: true, - autopopulate: { - select: PublicUserProjection, - }, -}); - -// @ts-ignore -export const MemberModel = db.model<MemberDocument>("Member", MemberSchema, "members"); - -// @ts-ignore -export interface PublicMember extends Omit<Member, "settings" | "id" | "read_state"> { - user: PublicUser; -} diff --git a/util/src/models/Message.ts b/util/src/models/Message.ts deleted file mode 100644
index 15a6f40d..00000000 --- a/util/src/models/Message.ts +++ /dev/null
@@ -1,368 +0,0 @@ -import { Schema, Types, Document } from "mongoose"; -import db from "../util/Database"; -import { PublicUser, PublicUserProjection, UserModel } from "./User"; -import { MemberModel, PublicMember } from "./Member"; -import { Role, RoleModel } from "./Role"; -import { Channel } from "./Channel"; -import { Snowflake } from "../util"; -import { InteractionType } from "./Interaction"; - -export interface Message { - id: string; - channel_id: string; - guild_id?: string; - author_id?: string; - webhook_id?: string; - application_id?: string; - content?: string; - timestamp: Date; - edited_timestamp: Date | null; - tts?: boolean; - mention_everyone?: boolean; - mention_user_ids: string[]; - mention_role_ids: string[]; - mention_channels_ids: string[]; - attachments: Attachment[]; - embeds: Embed[]; - reactions: Reaction[]; - nonce?: string | number; - pinned?: boolean; - type: MessageType; - activity?: { - type: number; - party_id: string; - }; - flags?: bigint; - stickers?: any[]; - message_reference?: { - message_id: string; - channel_id?: string; - guild_id?: string; - }; - interaction?: { - id: string; - type: InteractionType; - name: string; - user_id: string; // the user who invoked the interaction - // user: User; // TODO: autopopulate user - }; - components: MessageComponent[]; - - // * mongoose virtuals: - // TODO: - // application: Application; // TODO: auto pouplate application - author?: PublicUser; - member?: PublicMember; - mentions?: (PublicUser & { - member: PublicMember; - })[]; - mention_roles?: Role[]; - mention_channels?: Channel[]; - created_at?: Date; - // thread // TODO -} - -const PartialEmoji = { - id: String, - name: { type: String, required: true }, - animated: { type: Boolean, required: true }, -}; - -const MessageComponent: any = { - type: { type: Number, required: true }, - style: Number, - label: String, - emoji: PartialEmoji, - custom_id: String, - url: String, - disabled: Boolean, - components: [Object], -}; - -export interface MessageComponent { - type: number; - style?: number; - label?: string; - emoji?: PartialEmoji; - custom_id?: string; - url?: string; - disabled?: boolean; - components: MessageComponent[]; -} - -export enum MessageComponentType { - ActionRow = 1, - Button = 2, -} - -export interface MessageDocument extends Document, Message { - id: string; -} - -export enum MessageType { - DEFAULT = 0, - RECIPIENT_ADD = 1, - RECIPIENT_REMOVE = 2, - CALL = 3, - CHANNEL_NAME_CHANGE = 4, - CHANNEL_ICON_CHANGE = 5, - CHANNEL_PINNED_MESSAGE = 6, - GUILD_MEMBER_JOIN = 7, - USER_PREMIUM_GUILD_SUBSCRIPTION = 8, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11, - CHANNEL_FOLLOW_ADD = 12, - GUILD_DISCOVERY_DISQUALIFIED = 14, - GUILD_DISCOVERY_REQUALIFIED = 15, - REPLY = 19, - APPLICATION_COMMAND = 20, -} - -export interface Attachment { - id: string; // attachment id - filename: string; // name of file attached - size: number; // size of file in bytes - url: string; // source url of file - proxy_url: string; // a proxied url of file - height?: number; // height of file (if image) - width?: number; // width of file (if image) - content_type?: string; -} - -export interface Embed { - title?: string; //title of embed - type?: EmbedType; // type of embed (always "rich" for webhook embeds) - description?: string; // description of embed - url?: string; // url of embed - timestamp?: Date; // timestamp of embed content - color?: number; // color code of the embed - footer?: { - text: string; - icon_url?: string; - proxy_icon_url?: string; - }; // footer object footer information - image?: EmbedImage; // image object image information - thumbnail?: EmbedImage; // thumbnail object thumbnail information - video?: EmbedImage; // video object video information - provider?: { - name?: string; - url?: string; - }; // provider object provider information - author?: { - name?: string; - url?: string; - icon_url?: string; - proxy_icon_url?: string; - }; // author object author information - fields?: { - name: string; - value: string; - inline?: boolean; - }[]; -} - -export enum EmbedType { - rich = "rich", - image = "image", - video = "video", - gifv = "gifv", - article = "article", - link = "link", -} - -export interface EmbedImage { - url?: string; - proxy_url?: string; - height?: number; - width?: number; -} - -export interface Reaction { - count: number; - //// not saved in the database // me: boolean; // whether the current user reacted using this emoji - emoji: PartialEmoji; - user_ids: string[]; -} - -export interface PartialEmoji { - id?: string; - name: string; - animated?: boolean; -} - -export interface AllowedMentions { - parse?: ("users" | "roles" | "everyone")[]; - roles?: string[]; - users?: string[]; - replied_user?: boolean; -} - -export const Attachment = { - id: String, // attachment id - filename: String, // name of file attached - size: Number, // size of file in bytes - url: String, // source url of file - proxy_url: String, // a proxied url of file - height: Number, // height of file (if image) - width: Number, // width of file (if image) - content_type: String, -}; - -export const EmbedImage = { - url: String, - proxy_url: String, - height: Number, - width: Number, -}; - -const Reaction = { - count: Number, - user_ids: [String], - emoji: { - id: String, - name: String, - animated: Boolean, - }, -}; - -export const Embed = { - title: String, //title of embed - type: { type: String }, // type of embed (always "rich" for webhook embeds) - description: String, // description of embed - url: String, // url of embed - timestamp: Date, // timestamp of embed content - color: Number, // color code of the embed - footer: { - text: String, - icon_url: String, - proxy_icon_url: String, - }, // footer object footer information - image: EmbedImage, // image object image information - thumbnail: EmbedImage, // thumbnail object thumbnail information - video: EmbedImage, // video object video information - provider: { - name: String, - url: String, - }, // provider object provider information - author: { - name: String, - url: String, - icon_url: String, - proxy_icon_url: String, - }, // author object author information - fields: [ - { - name: String, - value: String, - inline: Boolean, - }, - ], -}; - -export const MessageSchema = new Schema({ - id: String, - channel_id: String, - author_id: String, - webhook_id: String, - guild_id: String, - application_id: String, - content: String, - timestamp: Date, - edited_timestamp: Date, - tts: Boolean, - mention_everyone: Boolean, - mention_user_ids: [String], - mention_role_ids: [String], - mention_channel_ids: [String], - attachments: [Attachment], - embeds: [Embed], - reactions: [Reaction], - nonce: Schema.Types.Mixed, // can be a long or a string - pinned: Boolean, - type: { type: Number }, - activity: { - type: { type: Number }, - party_id: String, - }, - flags: Types.Long, - stickers: [], - message_reference: { - message_id: String, - channel_id: String, - guild_id: String, - }, - components: [MessageComponent], - // virtual: - // author: { - // ref: UserModel, - // localField: "author_id", - // foreignField: "id", - // justOne: true, - // autopopulate: { select: { id: true, user_data: false } }, - // }, -}); - -MessageSchema.virtual("author", { - ref: UserModel, - localField: "author_id", - foreignField: "id", - justOne: true, - autopopulate: { select: PublicUserProjection }, -}); - -MessageSchema.virtual("member", { - ref: MemberModel, - localField: "author_id", - foreignField: "id", - justOne: true, -}); - -MessageSchema.virtual("mentions", { - ref: UserModel, - localField: "mention_user_ids", - foreignField: "id", - justOne: false, - autopopulate: { select: PublicUserProjection }, -}); - -MessageSchema.virtual("mention_roles", { - ref: RoleModel, - localField: "mention_role_ids", - foreignField: "id", - justOne: false, - autopopulate: true, -}); - -MessageSchema.virtual("mention_channels", { - ref: RoleModel, - localField: "mention_channel_ids", - foreignField: "id", - justOne: false, - autopopulate: { select: { id: true, guild_id: true, type: true, name: true } }, -}); - -MessageSchema.virtual("referenced_message", { - ref: "Message", - localField: "message_reference.message_id", - foreignField: "id", - justOne: true, - autopopulate: true, -}); - -MessageSchema.virtual("created_at").get(function (this: MessageDocument) { - return new Date(Snowflake.deconstruct(this.id).timestamp); -}); - -MessageSchema.set("removeResponse", ["mention_channel_ids", "mention_role_ids", "mention_user_ids", "author_id"]); - -// TODO: missing Application Model -// MessageSchema.virtual("application", { -// ref: Application, -// localField: "mention_role_ids", -// foreignField: "id", -// justOne: true, -// }); - -// @ts-ignore -export const MessageModel = db.model<MessageDocument>("Message", MessageSchema, "messages"); diff --git a/util/src/models/RateLimit.ts b/util/src/models/RateLimit.ts deleted file mode 100644
index 6a0e1ffd..00000000 --- a/util/src/models/RateLimit.ts +++ /dev/null
@@ -1,25 +0,0 @@ -import { Schema, Document, Types } from "mongoose"; -import db from "../util/Database"; - -export interface Bucket { - id: "global" | "error" | string; // channel_239842397 | guild_238927349823 | webhook_238923423498 - user_id: string; - hits: number; - blocked: boolean; - expires_at: Date; -} - -export interface BucketDocument extends Bucket, Document { - id: string; -} - -export const BucketSchema = new Schema({ - id: { type: String, required: true }, - user_id: { type: String, required: true }, // bot, user, oauth_application, webhook - hits: { type: Number, required: true }, // Number of times the user hit this bucket - blocked: { type: Boolean, required: true }, - expires_at: { type: Date, required: true }, -}); - -// @ts-ignore -export const BucketModel = db.model<BucketDocument>("Bucket", BucketSchema, "ratelimits"); diff --git a/util/src/models/ReadState.ts b/util/src/models/ReadState.ts deleted file mode 100644
index 9c4fb323..00000000 --- a/util/src/models/ReadState.ts +++ /dev/null
@@ -1,26 +0,0 @@ -import { PublicMember } from "./Member"; -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; - -export interface ReadState extends Document { - message_id: string; - channel_id: string; - user_id: string; - last_message_id?: string; - last_pin_timestamp?: Date; - mention_count: number; - manual: boolean; -} - -export const ReadStateSchema = new Schema({ - message_id: String, - channel_id: String, - user_id: String, - last_message_id: String, - last_pin_timestamp: Date, - mention_count: Number, - manual: Boolean, -}); - -// @ts-ignore -export const ReadStateModel = db.model<ReadState>("ReadState", ReadStateSchema, "readstates"); diff --git a/util/src/models/Role.ts b/util/src/models/Role.ts deleted file mode 100644
index c1111c84..00000000 --- a/util/src/models/Role.ts +++ /dev/null
@@ -1,42 +0,0 @@ -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; -import toBigInt from "../util/toBigInt"; - -export interface Role { - id: string; - guild_id: string; - color: number; - hoist: boolean; - managed: boolean; - mentionable: boolean; - name: string; - permissions: bigint; - position: number; - tags?: { - bot_id?: string; - }; -} - -export interface RoleDocument extends Document, Role { - id: string; -} - -export const RoleSchema = new Schema({ - id: String, - guild_id: String, - color: Number, - hoist: Boolean, - managed: Boolean, - mentionable: Boolean, - name: String, - permissions: { type: String, get: toBigInt }, - position: Number, - tags: { - bot_id: String, - }, -}); - -RoleSchema.set("removeResponse", ["guild_id"]); - -// @ts-ignore -export const RoleModel = db.model<RoleDocument>("Role", RoleSchema, "roles"); diff --git a/util/src/models/Team.ts b/util/src/models/Team.ts deleted file mode 100644
index 795c82d2..00000000 --- a/util/src/models/Team.ts +++ /dev/null
@@ -1,17 +0,0 @@ -export interface Team { - icon: string | null; - id: string; - members: { - membership_state: number; - permissions: string[]; - team_id: string; - user_id: string; - }[]; - name: string; - owner_user_id: string; -} - -export enum TeamMemberState { - INVITED = 1, - ACCEPTED = 2, -} diff --git a/util/src/models/Template.ts b/util/src/models/Template.ts deleted file mode 100644
index ad0f9104..00000000 --- a/util/src/models/Template.ts +++ /dev/null
@@ -1,51 +0,0 @@ -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; -import { PublicUser, User, UserModel, PublicUserProjection } from "./User"; -import { Guild, GuildModel } from "./Guild"; - -export interface Template extends Document { - id: string; - code: string; - name: string; - description?: string; - usage_count?: number; - creator_id: string; - creator: User; - created_at: Date; - updated_at: Date; - source_guild_id: String; - serialized_source_guild: Guild; -} - -export const TemplateSchema = new Schema({ - id: String, - code: String, - name: String, - description: String, - usage_count: Number, - creator_id: String, - created_at: Date, - updated_at: Date, - source_guild_id: String, -}); - -TemplateSchema.virtual("creator", { - ref: UserModel, - localField: "creator_id", - foreignField: "id", - justOne: true, - autopopulate: { - select: PublicUserProjection, - }, -}); - -TemplateSchema.virtual("serialized_source_guild", { - ref: GuildModel, - localField: "source_guild_id", - foreignField: "id", - justOne: true, - autopopulate: true, -}); - -// @ts-ignore -export const TemplateModel = db.model<Template>("Template", TemplateSchema, "templates"); diff --git a/util/src/models/User.ts b/util/src/models/User.ts deleted file mode 100644
index c667e954..00000000 --- a/util/src/models/User.ts +++ /dev/null
@@ -1,252 +0,0 @@ -import { Activity, ActivitySchema } from "./Activity"; -import { ClientStatus, Status } from "./Status"; -import { Schema, Types, Document } from "mongoose"; -import db from "../util/Database"; -import toBigInt from "../util/toBigInt"; - -export const PublicUserProjection = { - username: true, - discriminator: true, - id: true, - public_flags: true, - avatar: true, - accent_color: true, - banner: true, - bio: true, - bot: true, -}; - -export interface User { - id: string; - username: string; // username max length 32, min 2 - discriminator: string; // #0001 4 digit long string from #0001 - #9999 - avatar: string | null; // hash of the user avatar - accent_color: number | null; // banner color of user - banner: string | null; - phone: string | null; // phone number of the user - desktop: boolean; // if the user has desktop app installed - mobile: boolean; // if the user has mobile app installed - premium: boolean; // if user bought nitro - premium_type: number; // nitro level - bot: boolean; // if user is bot - bio: string; // short description of the user (max 190 chars) - system: boolean; // shouldn't be used, the api sents this field type true, if the genetaed message comes from a system generated author - nsfw_allowed: boolean; // if the user is older than 18 (resp. Config) - mfa_enabled: boolean; // if multi factor authentication is enabled - created_at: Date; // registration date - verified: boolean; // if the user is offically verified - disabled: boolean; // if the account is disabled - deleted: boolean; // if the user was deleted - email: string | null; // email of the user - flags: bigint; // UserFlags - public_flags: bigint; - user_settings: UserSettings; - guilds: string[]; // array of guild ids the user is part of - user_data: UserData; - presence: { - status: Status; - activities: Activity[]; - client_status: ClientStatus; - }; -} - -// Private user data: -export interface UserData { - valid_tokens_since: Date; // all tokens with a previous issue date are invalid - relationships: Relationship[]; - connected_accounts: ConnectedAccount[]; - hash: string; // hash of the password, salt is saved in password (bcrypt) - fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts -} - -export interface UserDocument extends User, Document { - id: string; -} - -export interface PublicUser { - id: string; - discriminator: string; - username: string; - avatar: string | null; - accent_color: number; - banner: string | null; - public_flags: bigint; - bot: boolean; -} - -export interface ConnectedAccount { - access_token: string; - friend_sync: boolean; - id: string; - name: string; - revoked: boolean; - show_activity: boolean; - type: string; - verifie: boolean; - visibility: number; -} - -export interface Relationship { - id: string; - nickname?: string; - type: RelationshipType; -} - -export enum RelationshipType { - outgoing = 4, - incoming = 3, - blocked = 2, - friends = 1, -} - -export interface UserSettings { - afk_timeout: number; - allow_accessibility_detection: boolean; - animate_emoji: boolean; - animate_stickers: number; - contact_sync_enabled: boolean; - convert_emoticons: boolean; - custom_status: { - emoji_id: string | null; - emoji_name: string | null; - expires_at: number | null; - text: string | null; - }; - default_guilds_restricted: boolean; - detect_platform_accounts: boolean; - developer_mode: boolean; - disable_games_tab: boolean; - enable_tts_command: boolean; - explicit_content_filter: number; - friend_source_flags: { all: boolean }; - gateway_connected: boolean; - gif_auto_play: boolean; - guild_folders: // every top guild is displayed as a "folder" - { - color: number; - guild_ids: string[]; - id: number; - name: string; - }[]; - guild_positions: string[]; // guild ids ordered by position - inline_attachment_media: boolean; - inline_embed_media: boolean; - locale: string; // en_US - message_display_compact: boolean; - native_phone_integration_enabled: boolean; - render_embeds: boolean; - render_reactions: boolean; - restricted_guilds: string[]; - show_current_game: boolean; - status: "online" | "offline" | "dnd" | "idle"; - stream_notifications_enabled: boolean; - theme: "dark" | "white"; // dark - timezone_offset: number; // e.g -60 -} - -export const UserSchema = new Schema({ - id: String, - username: String, - discriminator: String, - avatar: String, - accent_color: Number, - banner: String, - phone: String, - desktop: Boolean, - mobile: Boolean, - premium: Boolean, - premium_type: Number, - bot: Boolean, - bio: String, - system: Boolean, - nsfw_allowed: Boolean, - mfa_enabled: Boolean, - created_at: Date, - verified: Boolean, - disabled: Boolean, - deleted: Boolean, - email: String, - flags: { type: String, get: toBigInt }, // TODO: automatically convert Types.Long to BitField of UserFlags - public_flags: { type: String, get: toBigInt }, - guilds: [String], // array of guild ids the user is part of - user_data: { - fingerprints: [String], - hash: String, // hash of the password, salt is saved in password (bcrypt) - valid_tokens_since: Date, // all tokens with a previous issue date are invalid - relationships: [ - { - id: { type: String, required: true }, - nickname: String, - type: { type: Number }, - }, - ], - connected_accounts: [ - { - access_token: String, - friend_sync: Boolean, - id: String, - name: String, - revoked: Boolean, - show_activity: Boolean, - type: { type: String }, - verifie: Boolean, - visibility: Number, - }, - ], - }, - user_settings: { - afk_timeout: Number, - allow_accessibility_detection: Boolean, - animate_emoji: Boolean, - animate_stickers: Number, - contact_sync_enabled: Boolean, - convert_emoticons: Boolean, - custom_status: { - emoji_id: String, - emoji_name: String, - expires_at: Number, - text: String, - }, - default_guilds_restricted: Boolean, - detect_platform_accounts: Boolean, - developer_mode: Boolean, - disable_games_tab: Boolean, - enable_tts_command: Boolean, - explicit_content_filter: Number, - friend_source_flags: { all: Boolean }, - gateway_connected: Boolean, - gif_auto_play: Boolean, - // every top guild is displayed as a "folder" - guild_folders: [ - { - color: Number, - guild_ids: [String], - id: Number, - name: String, - }, - ], - guild_positions: [String], // guild ids ordered by position - inline_attachment_media: Boolean, - inline_embed_media: Boolean, - locale: String, // en_US - message_display_compact: Boolean, - native_phone_integration_enabled: Boolean, - render_embeds: Boolean, - render_reactions: Boolean, - restricted_guilds: [String], - show_current_game: Boolean, - status: String, - stream_notifications_enabled: Boolean, - theme: String, // dark - timezone_offset: Number, // e.g -60, - }, - - presence: { - status: String, - activities: [ActivitySchema], - client_status: ClientStatus, - }, -}); - -// @ts-ignore -export const UserModel = db.model<UserDocument>("User", UserSchema, "users"); diff --git a/util/src/models/VoiceState.ts b/util/src/models/VoiceState.ts deleted file mode 100644
index c1f90edd..00000000 --- a/util/src/models/VoiceState.ts +++ /dev/null
@@ -1,34 +0,0 @@ -import { PublicMember } from "./Member"; -import { Schema, model, Types, Document } from "mongoose"; -import db from "../util/Database"; - -export interface VoiceState extends Document { - guild_id?: string; - channel_id: string; - user_id: string; - session_id: string; - deaf: boolean; - mute: boolean; - self_deaf: boolean; - self_mute: boolean; - self_stream?: boolean; - self_video: boolean; - suppress: boolean; // whether this user is muted by the current user -} - -export const VoiceSateSchema = new Schema({ - guild_id: String, - channel_id: String, - user_id: String, - session_id: String, - deaf: Boolean, - mute: Boolean, - self_deaf: Boolean, - self_mute: Boolean, - self_stream: Boolean, - self_video: Boolean, - suppress: Boolean, // whether this user is muted by the current user -}); - -// @ts-ignore -export const VoiceStateModel = db.model<VoiceState>("VoiceState", VoiceSateSchema, "voicestates"); diff --git a/util/src/models/Webhook.ts b/util/src/models/Webhook.ts deleted file mode 100644
index 7379e98f..00000000 --- a/util/src/models/Webhook.ts +++ /dev/null
@@ -1,84 +0,0 @@ -import { Schema, Document, Types } from "mongoose"; -import { transpileModule } from "typescript"; -import db from "../util/Database"; -import { ChannelModel } from "./Channel"; -import { GuildModel } from "./Guild"; - -export interface Webhook {} - -export enum WebhookType { - Incoming = 1, - ChannelFollower = 2, -} - -export interface WebhookDocument extends Document, Webhook { - id: String; - type: number; - guild_id?: string; - channel_id: string; - name?: string; - avatar?: string; - token?: string; - application_id?: string; - user_id?: string; - source_guild_id: string; -} - -export const WebhookSchema = new Schema({ - id: { type: String, required: true }, - type: { type: Number, required: true }, - guild_id: String, - channel_id: String, - name: String, - avatar: String, - token: String, - application_id: String, - user_id: String, - source_guild_id: String, - source_channel_id: String, -}); - -WebhookSchema.virtual("source_guild", { - ref: GuildModel, - localField: "id", - foreignField: "source_guild_id", - justOne: true, - autopopulate: { - select: { - icon: true, - id: true, - name: true, - }, - }, -}); - -WebhookSchema.virtual("source_channel", { - ref: ChannelModel, - localField: "id", - foreignField: "source_channel_id", - justOne: true, - autopopulate: { - select: { - id: true, - name: true, - }, - }, -}); - -WebhookSchema.virtual("source_channel", { - ref: ChannelModel, - localField: "id", - foreignField: "source_channel_id", - justOne: true, - autopopulate: { - select: { - id: true, - name: true, - }, - }, -}); - -WebhookSchema.set("removeResponse", ["source_channel_id", "source_guild_id"]); - -// @ts-ignore -export const WebhookModel = db.model<WebhookDocument>("Webhook", WebhookSchema, "webhooks"); diff --git a/util/src/models/index.ts b/util/src/models/index.ts deleted file mode 100644
index b6100f86..00000000 --- a/util/src/models/index.ts +++ /dev/null
@@ -1,93 +0,0 @@ -// @ts-nocheck -import mongoose, { Schema, Document } from "mongoose"; -import mongooseAutoPopulate from "mongoose-autopopulate"; - -type UpdateWithAggregationPipeline = UpdateAggregationStage[]; -type UpdateAggregationStage = - | { $addFields: any } - | { $set: any } - | { $project: any } - | { $unset: any } - | { $replaceRoot: any } - | { $replaceWith: any }; -type EnforceDocument<T, TMethods> = T extends Document ? T : T & Document & TMethods; - -declare module "mongoose" { - interface SchemaOptions { - removeResponse?: string[]; - } - interface Model<T, TQueryHelpers = {}, TMethods = {}> { - // removed null -> always return document -> throw error if it doesn't exist - findOne( - filter?: FilterQuery<T>, - projection?: any | null, - options?: QueryOptions | null, - callback?: (err: CallbackError, doc: EnforceDocument<T, TMethods>) => void - ): QueryWithHelpers<EnforceDocument<T, TMethods>, EnforceDocument<T, TMethods>, TQueryHelpers>; - findOneAndUpdate( - filter?: FilterQuery<T>, - update?: UpdateQuery<T> | UpdateWithAggregationPipeline, - options?: QueryOptions | null, - callback?: (err: any, doc: EnforceDocument<T, TMethods> | null, res: any) => void - ): QueryWithHelpers<EnforceDocument<T, TMethods>, EnforceDocument<T, TMethods>, TQueryHelpers>; - } -} - -var HTTPError: any; - -try { - HTTPError = require("lambert-server").HTTPError; -} catch (e) { - HTTPError = Error; -} - -mongoose.plugin(mongooseAutoPopulate); - -mongoose.plugin((schema: Schema, opts: any) => { - schema.set("toObject", { - virtuals: true, - versionKey: false, - transform(doc: any, ret: any) { - delete ret._id; - delete ret.__v; - const props = schema.get("removeResponse") || []; - props.forEach((prop: string) => { - delete ret[prop]; - }); - }, - }); - schema.post("findOne", function (doc, next) { - try { - // @ts-ignore - const isExistsQuery = JSON.stringify(this._userProvidedFields) === JSON.stringify({ _id: 1 }); - if (!doc && !isExistsQuery) { - // @ts-ignore - return next(new HTTPError(`${this?.mongooseCollection?.name}.${this?._conditions?.id} not found`, 400)); - } - // @ts-ignore - return next(); - } catch (error) { - // @ts-ignore - next(); - } - }); -}); - -export * from "./Activity"; -export * from "./Application"; -export * from "./Ban"; -export * from "./Channel"; -export * from "./Emoji"; -export * from "./Event"; -export * from "./Template"; -export * from "./Guild"; -export * from "./Invite"; -export * from "./Interaction"; -export * from "./Member"; -export * from "./Message"; -export * from "./Status"; -export * from "./Role"; -export * from "./User"; -export * from "./VoiceState"; -export * from "./ReadState"; -export * from "./RateLimit"; diff --git a/util/src/util/BitField.ts b/util/src/util/BitField.ts
index 728dc632..ac19763e 100644 --- a/util/src/util/BitField.ts +++ b/util/src/util/BitField.ts
@@ -21,7 +21,7 @@ export class BitField { * Checks whether the bitfield has a bit, or any of multiple bits. */ any(bit: BitFieldResolvable): boolean { - return (this.bitfield & BitField.resolve.call(this, bit)) !== 0n; + return (this.bitfield & BitField.resolve.call(this, bit)) !== BigInt(0); } /** @@ -61,7 +61,7 @@ export class BitField { * @returns {BitField} These bits or new BitField if the instance is frozen. */ add(...bits: BitFieldResolvable[]): BitField { - let total = 0n; + let total = BigInt(0); for (const bit of bits) { total |= BitField.resolve.call(this, bit); } @@ -75,7 +75,7 @@ export class BitField { * @param {...BitFieldResolvable} [bits] Bits to remove */ remove(...bits: BitFieldResolvable[]) { - let total = 0n; + let total = BigInt(0); for (const bit of bits) { total |= BitField.resolve.call(this, bit); } @@ -127,15 +127,15 @@ export class BitField { * @param {BitFieldResolvable} [bit=0] - bit(s) to resolve * @returns {number} */ - static resolve(bit: BitFieldResolvable = 0n): bigint { + static resolve(bit: BitFieldResolvable = BigInt(0)): bigint { // @ts-ignore const FLAGS = this.FLAGS || this.constructor?.FLAGS; - if ((typeof bit === "number" || typeof bit === "bigint") && bit >= 0n) return BigInt(bit); + if ((typeof bit === "number" || typeof bit === "bigint") && bit >= BigInt(0)) return BigInt(bit); if (bit instanceof BitField) return bit.bitfield; if (Array.isArray(bit)) { // @ts-ignore const resolve = this.constructor?.resolve || this.resolve; - return bit.map((p) => resolve.call(this, p)).reduce((prev, p) => BigInt(prev) | BigInt(p), 0n); + return bit.map((p) => resolve.call(this, p)).reduce((prev, p) => BigInt(prev) | BigInt(p), BigInt(0)); } if (typeof bit === "string" && typeof FLAGS[bit] !== "undefined") return FLAGS[bit]; throw new RangeError("BITFIELD_INVALID: " + bit); diff --git a/util/src/util/Config.ts b/util/src/util/Config.ts deleted file mode 100644
index a93e1846..00000000 --- a/util/src/util/Config.ts +++ /dev/null
@@ -1,291 +0,0 @@ -import { Schema, model, Types, Document } from "mongoose"; -import "missing-native-js-functions"; -import db from "./Database"; -import { Snowflake } from "./Snowflake"; -import crypto from "crypto"; - -var config: any; - -export default { - init: async function init(defaultOpts: any = DefaultOptions) { - config = await db.collection("config").findOne({}); - return this.set((config || {}).merge(defaultOpts)); - }, - get: function get() { - return config as DefaultOptions; - }, - set: function set(val: any) { - config = val.merge(config); - return db.collection("config").updateOne({}, { $set: val }, { upsert: true }); - }, -}; - -export interface RateLimitOptions { - bot?: number; - count: number; - window: number; - onyIp?: boolean; -} - -export interface Region { - id: string; - name: string; - vip: boolean; - custom: boolean; - deprecated: boolean; - optimal: boolean; -} - -export interface KafkaBroker { - ip: string; - port: number; -} - -export interface DefaultOptions { - gateway: { - endpointClient: string | null; - endpoint: string | null; - }; - cdn: { - endpointClient: string | null; - endpoint: string | null; - }; - general: { - instance_id: string; - }; - permissions: { - user: { - createGuilds: boolean; - }; - }; - limits: { - user: { - maxGuilds: number; - maxUsername: number; - maxFriends: number; - }; - guild: { - maxRoles: number; - maxMembers: number; - maxChannels: number; - maxChannelsInCategory: number; - hideOfflineMember: number; - }; - message: { - maxCharacters: number; - maxTTSCharacters: number; - maxReactions: number; - maxAttachmentSize: number; - maxBulkDelete: number; - }; - channel: { - maxPins: number; - maxTopic: number; - }; - rate: { - ip: Omit<RateLimitOptions, "bot_count">; - global: RateLimitOptions; - error: RateLimitOptions; - routes: { - guild: RateLimitOptions; - webhook: RateLimitOptions; - channel: RateLimitOptions; - auth: { - login: RateLimitOptions; - register: RateLimitOptions; - }; - // TODO: rate limit configuration for all routes - }; - }; - }; - security: { - autoUpdate: boolean | number; - requestSignature: string; - jwtSecret: string; - forwadedFor: string | null; // header to get the real user ip address - captcha: { - enabled: boolean; - service: "recaptcha" | "hcaptcha" | null; // TODO: hcaptcha, custom - sitekey: string | null; - secret: string | null; - }; - ipdataApiKey: string | null; - }; - login: { - requireCaptcha: boolean; - }; - register: { - email: { - necessary: boolean; // we have to use necessary instead of required as the cli tool uses json schema and can't use required - allowlist: boolean; - blocklist: boolean; - domains: string[]; - }; - dateOfBirth: { - necessary: boolean; - minimum: number; // in years - }; - requireCaptcha: boolean; - requireInvite: boolean; - allowNewRegistration: boolean; - allowMultipleAccounts: boolean; - blockProxies: boolean; - password: { - minLength: number; - minNumbers: number; - minUpperCase: number; - minSymbols: number; - }; - }; - regions: { - default: string; - available: Region[]; - }; - rabbitmq: { - host: string | null; - }; - kafka: { - brokers: KafkaBroker[] | null; - }; -} - -export const DefaultOptions: DefaultOptions = { - gateway: { - endpointClient: null, - endpoint: null, - }, - cdn: { - endpointClient: null, - endpoint: null, - }, - general: { - instance_id: Snowflake.generate(), - }, - permissions: { - user: { - createGuilds: true, - }, - }, - limits: { - user: { - maxGuilds: 100, - maxUsername: 32, - maxFriends: 1000, - }, - guild: { - maxRoles: 250, - maxMembers: 250000, - maxChannels: 500, - maxChannelsInCategory: 50, - hideOfflineMember: 1000, - }, - message: { - maxCharacters: 2000, - maxTTSCharacters: 200, - maxReactions: 20, - maxAttachmentSize: 8388608, - maxBulkDelete: 100, - }, - channel: { - maxPins: 50, - maxTopic: 1024, - }, - rate: { - ip: { - count: 500, - window: 5, - }, - global: { - count: 20, - window: 5, - bot: 250, - }, - error: { - count: 10, - window: 5, - }, - routes: { - guild: { - count: 5, - window: 5, - }, - webhook: { - count: 5, - window: 20, - }, - channel: { - count: 5, - window: 20, - }, - auth: { - login: { - count: 5, - window: 60, - }, - register: { - count: 2, - window: 60 * 60 * 12, - }, - }, - }, - }, - }, - security: { - autoUpdate: true, - requestSignature: crypto.randomBytes(32).toString("base64"), - jwtSecret: crypto.randomBytes(256).toString("base64"), - forwadedFor: null, - // forwadedFor: "X-Forwarded-For" // nginx/reverse proxy - // forwadedFor: "CF-Connecting-IP" // cloudflare: - captcha: { - enabled: false, - service: null, - sitekey: null, - secret: null, - }, - ipdataApiKey: "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9", - }, - login: { - requireCaptcha: false, - }, - register: { - email: { - necessary: true, - allowlist: false, - blocklist: true, - domains: [], // TODO: efficiently save domain blocklist in database - // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), - }, - dateOfBirth: { - necessary: true, - minimum: 13, - }, - requireInvite: false, - requireCaptcha: true, - allowNewRegistration: true, - allowMultipleAccounts: true, - blockProxies: true, - password: { - minLength: 8, - minNumbers: 2, - minUpperCase: 2, - minSymbols: 0, - }, - }, - regions: { - default: "fosscord", - available: [{ id: "fosscord", name: "Fosscord", vip: false, custom: false, deprecated: false, optimal: false }], - }, - rabbitmq: { - host: null, - }, - kafka: { - brokers: null, - }, -}; - -export const ConfigSchema = new Schema({}, { strict: false }); - -export interface DefaultOptionsDocument extends DefaultOptions, Document {} - -export const ConfigModel = model<DefaultOptionsDocument>("Config", ConfigSchema, "config"); diff --git a/util/src/util/Constants.ts b/util/src/util/Constants.ts deleted file mode 100644
index a9978c51..00000000 --- a/util/src/util/Constants.ts +++ /dev/null
@@ -1,28 +0,0 @@ -import { VerifyOptions } from "jsonwebtoken"; - -export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] }; - -export enum MessageType { - DEFAULT = 0, - RECIPIENT_ADD = 1, - RECIPIENT_REMOVE = 2, - CALL = 3, - CHANNEL_NAME_CHANGE = 4, - CHANNEL_ICON_CHANGE = 5, - CHANNEL_PINNED_MESSAGE = 6, - GUILD_MEMBER_JOIN = 7, - USER_PREMIUM_GUILD_SUBSCRIPTION = 8, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11, - CHANNEL_FOLLOW_ADD = 12, - GUILD_DISCOVERY_DISQUALIFIED = 14, - GUILD_DISCOVERY_REQUALIFIED = 15, - GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING = 16, - GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING = 17, - THREAD_CREATED = 18, - REPLY = 19, - APPLICATION_COMMAND = 20, - THREAD_STARTER_MESSAGE = 21, - GUILD_INVITE_REMINDER = 22, -} diff --git a/util/src/util/Database.ts b/util/src/util/Database.ts
index ea517234..248e0dcf 100644 --- a/util/src/util/Database.ts +++ b/util/src/util/Database.ts
@@ -1,159 +1,25 @@ -// @ts-nocheck -import "./MongoBigInt"; -import mongoose, { Collection, Connection, LeanDocument } from "mongoose"; -import { ChangeStream, ChangeEvent, Long } from "mongodb"; -import EventEmitter from "events"; -const uri = process.env.MONGO_URL || "mongodb://localhost:27017/fosscord?readPreference=secondaryPreferred"; -import { URL } from "url"; +import "reflect-metadata"; +import { createConnection } from "typeorm"; +import * as Models from "../entities"; -const url = new URL(uri.replace("mongodb://", "http://")); +// UUID extension option is only supported with postgres +// We want to generate all id's with Snowflakes that's why we have our own BaseEntity class -const connection = mongoose.createConnection(uri, { - autoIndex: true, - useNewUrlParser: true, - useUnifiedTopology: true, - useFindAndModify: true, -}); +var promise: Promise<any>; -// this will return the new updated document for findOneAndUpdate -mongoose.set("returnOriginal", false); // https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndUpdate +export function initDatabase() { + if (promise) return promise; // prevent initalizing multiple times -console.log(`[Database] connect: mongodb://${url.username}@${url.host}${url.pathname}${url.search}`); -connection.once("open", () => { - console.log("[Database] connected"); -}); - -export default <Connection>connection; - -function transform<T>(document: T) { - // @ts-ignore - if (!document || !document.toObject) { - try { - // @ts-ignore - delete document._id; - // @ts-ignore - delete document.__v; - } catch (error) {} - return document; - } - // @ts-ignore - return document.toObject({ virtuals: true }); -} - -export function toObject<T>(document: T): LeanDocument<T> { // @ts-ignore - return Array.isArray(document) ? document.map((x) => transform<T>(x)) : transform(document); + promise = createConnection({ + type: "sqlite", + database: "database.db", + entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"), + synchronize: true, + logging: false, + }); + + return promise; } -export interface MongooseCache { - on(event: "delete", listener: (id: string) => void): this; - on(event: "change", listener: (data: any) => void): this; - on(event: "insert", listener: (data: any) => void): this; - on(event: "close", listener: () => void): this; -} - -export class MongooseCache extends EventEmitter { - public stream: ChangeStream; - public data: any; - public initalizing?: Promise<void>; - - constructor( - public collection: Collection, - public pipeline: Array<Record<string, unknown>>, - public opts: { - onlyEvents: boolean; - array?: boolean; - } - ) { - super(); - if (this.opts.array == null) this.opts.array = true; - } - - init = () => { - if (this.initalizing) return this.initalizing; - this.initalizing = new Promise(async (resolve, reject) => { - // @ts-ignore - this.stream = this.collection.watch(this.pipeline, { fullDocument: "updateLookup" }); - - this.stream.on("change", this.change); - this.stream.on("close", this.destroy); - this.stream.on("error", console.error); - - if (!this.opts.onlyEvents) { - const arr = await this.collection.aggregate(this.pipeline).toArray(); - if (this.opts.array) this.data = arr || []; - else this.data = arr?.[0]; - } - resolve(); - }); - return this.initalizing; - }; - - changeStream = (pipeline: any) => { - this.pipeline = pipeline; - this.destroy(); - this.init(); - }; - - convertResult = (obj: any) => { - if (obj instanceof Long) return BigInt(obj.toString()); - if (typeof obj === "object") { - Object.keys(obj).forEach((key) => { - obj[key] = this.convertResult(obj[key]); - }); - } - - return obj; - }; - - change = (doc: ChangeEvent) => { - try { - switch (doc.operationType) { - case "dropDatabase": - return this.destroy(); - case "drop": - return this.destroy(); - case "delete": - if (!this.opts.onlyEvents) { - if (this.opts.array) { - this.data = this.data.filter((x: any) => doc.documentKey?._id?.equals(x._id)); - } else this.data = null; - } - return this.emit("delete", doc.documentKey._id.toHexString()); - case "insert": - if (!this.opts.onlyEvents) { - if (this.opts.array) this.data.push(doc.fullDocument); - else this.data = doc.fullDocument; - } - return this.emit("insert", doc.fullDocument); - case "update": - case "replace": - if (!this.opts.onlyEvents) { - if (this.opts.array) { - const i = this.data.findIndex((x: any) => doc.fullDocument?._id?.equals(x._id)); - if (i == -1) this.data.push(doc.fullDocument); - else this.data[i] = doc.fullDocument; - } else this.data = doc.fullDocument; - } - - return this.emit("change", doc.fullDocument); - case "invalidate": - return this.destroy(); - default: - return; - } - } catch (error) { - this.emit("error", error); - } - }; - - destroy = () => { - this.data = null; - this.stream?.off("change", this.change); - this.emit("close"); - - if (this.stream.isClosed()) return; - - return this.stream.close(); - }; -} +initDatabase(); diff --git a/util/src/util/Event.ts b/util/src/util/Event.ts
index 0dbddc76..765e5fc7 100644 --- a/util/src/util/Event.ts +++ b/util/src/util/Event.ts
@@ -1,7 +1,7 @@ import { Channel } from "amqplib"; -import { EVENT, Event } from "../models"; import { RabbitMQ } from "./RabbitMQ"; import EventEmitter from "events"; +import { EVENT, Event } from "../interfaces"; const events = new EventEmitter(); export async function emitEvent(payload: Omit<Event, "created_at">) { diff --git a/util/src/util/MongoBigInt.ts b/util/src/util/MongoBigInt.ts deleted file mode 100644
index 2ae8b91c..00000000 --- a/util/src/util/MongoBigInt.ts +++ /dev/null
@@ -1,83 +0,0 @@ -// @ts-nocheck -import mongoose from "mongoose"; - -class LongSchema extends mongoose.SchemaType { - public $conditionalHandlers = { - $lt: this.handleSingle, - $lte: this.handleSingle, - $gt: this.handleSingle, - $gte: this.handleSingle, - $ne: this.handleSingle, - $in: this.handleArray, - $nin: this.handleArray, - $mod: this.handleArray, - $all: this.handleArray, - $bitsAnySet: this.handleArray, - $bitsAllSet: this.handleArray, - }; - - handleSingle(val: any) { - return this.cast(val, null, null, "handle"); - } - - handleArray(val: any) { - var self = this; - return val.map(function (m: any) { - return self.cast(m, null, null, "handle"); - }); - } - - checkRequired(val: any) { - return null != val; - } - - cast(val: any, scope?: any, init?: any, type?: string) { - if (null === val) return val; - if ("" === val) return null; - if (typeof val === "bigint") { - return mongoose.mongo.Long.fromString(val.toString()); - } - - if (val instanceof mongoose.mongo.Long) { - if (type === "handle" || init == false) return val; - return BigInt(val.toString()); - } - if (val instanceof Number || "number" == typeof val) return BigInt(val as number); - if (!Array.isArray(val) && val.toString) return BigInt(val.toString()); - - //@ts-ignore - throw new SchemaType.CastError("Long", val); - } - - castForQuery($conditional: string, value: any) { - var handler; - if (2 === arguments.length) { - // @ts-ignore - handler = this.$conditionalHandlers[$conditional]; - if (!handler) { - throw new Error("Can't use " + $conditional + " with Long."); - } - return handler.call(this, value); - } else { - return this.cast($conditional, null, null, "query"); - } - } -} - -LongSchema.cast = mongoose.SchemaType.cast; -LongSchema.set = mongoose.SchemaType.set; -LongSchema.get = mongoose.SchemaType.get; - -declare module "mongoose" { - namespace Types { - class Long extends mongoose.mongo.Long {} - } - namespace Schema { - namespace Types { - class Long extends LongSchema {} - } - } -} - -mongoose.Schema.Types.Long = LongSchema; -mongoose.Types.Long = mongoose.mongo.Long; diff --git a/util/src/util/Permissions.ts b/util/src/util/Permissions.ts
index 63d87e48..630db36f 100644 --- a/util/src/util/Permissions.ts +++ b/util/src/util/Permissions.ts
@@ -1,11 +1,8 @@ // https://github.com/discordjs/discord.js/blob/master/src/util/Permissions.js // Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah -import { MemberDocument, MemberModel } from "../models/Member"; -import { ChannelDocument, ChannelModel } from "../models/Channel"; -import { ChannelPermissionOverwrite } from "../models/Channel"; -import { Role, RoleDocument, RoleModel } from "../models/Role"; +import { In } from "typeorm"; +import { Channel, ChannelPermissionOverwrite, Guild, Member, Role } from "../entities"; import { BitField } from "./BitField"; -import { GuildDocument, GuildModel } from "../models/Guild"; // TODO: check role hierarchy permission var HTTPError: any; @@ -138,12 +135,12 @@ export class Permissions extends BitField { // ~ operator inverts deny (e.g. 011 -> 100) // & operator only allows 1 for both ~deny and permission (e.g. 010 & 100 -> 000) // | operators adds both together (e.g. 000 + 100 -> 100) - }, init || 0n); + }, init || BigInt(0)); } static rolePermission(roles: Role[]) { // adds all permissions of all roles together (Bit OR) - return roles.reduce((permission, role) => permission | BigInt(role.permissions), 0n); + return roles.reduce((permission, role) => permission | BigInt(role.permissions), BigInt(0)); } static finalPermission({ @@ -201,10 +198,10 @@ export class Permissions extends BitField { } export type PermissionCache = { - channel?: ChannelDocument | null; - member?: MemberDocument | null; - guild?: GuildDocument | null; - roles?: RoleDocument[] | null; + channel?: Channel | null; + member?: Member | null; + guild?: Guild | null; + roles?: Role[] | null; user_id?: string; }; @@ -219,23 +216,23 @@ export async function getPermission( if (!user_id) throw new HTTPError("User not found"); if (channel_id && !channel) { - channel = await ChannelModel.findOne( + channel = await Channel.findOneOrFail( { id: channel_id }, - { permission_overwrites: true, recipient_ids: true, owner_id: true, guild_id: true } - ).exec(); + { select: ["permission_overwrites", "recipients", "owner", "guild"] } + ); if (!channel) throw new HTTPError("Channel not found", 404); if (channel.guild_id) guild_id = channel.guild_id; } if (guild_id) { - if (!guild) guild = await GuildModel.findOne({ id: guild_id }, { owner_id: true }).exec(); + if (!guild) guild = await Guild.findOneOrFail({ id: guild_id }, { select: ["owner"] }); if (!guild) throw new HTTPError("Guild not found"); if (guild.owner_id === user_id) return new Permissions(Permissions.FLAGS.ADMINISTRATOR); - if (!member) member = await MemberModel.findOne({ guild_id, id: user_id }, "roles").exec(); + if (!member) member = await Member.findOneOrFail({ guild_id, id: user_id }, { select: ["roles"] }); if (!member) throw new HTTPError("Member not found"); - if (!roles) roles = await RoleModel.find({ guild_id, id: { $in: member.roles } }).exec(); + if (!roles) roles = await Role.find({ guild_id, id: In(member.roles) }); } var permission = Permissions.finalPermission({ diff --git a/util/src/util/RabbitMQ.ts b/util/src/util/RabbitMQ.ts
index 9da41990..0f5eb6aa 100644 --- a/util/src/util/RabbitMQ.ts +++ b/util/src/util/RabbitMQ.ts
@@ -1,18 +1,19 @@ import amqp, { Connection, Channel } from "amqplib"; -import Config from "./Config"; +// import Config from "./Config"; export const RabbitMQ: { connection: Connection | null; channel: Channel | null; init: () => Promise<void> } = { connection: null, channel: null, init: async function () { - const host = Config.get().rabbitmq.host; - if (!host) return; - console.log(`[RabbitMQ] connect: ${host}`); - this.connection = await amqp.connect(host, { - timeout: 1000 * 60, - }); - console.log(`[RabbitMQ] connected`); - this.channel = await this.connection.createChannel(); - console.log(`[RabbitMQ] channel created`); + return; + // const host = Config.get().rabbitmq.host; + // if (!host) return; + // console.log(`[RabbitMQ] connect: ${host}`); + // this.connection = await amqp.connect(host, { + // timeout: 1000 * 60, + // }); + // console.log(`[RabbitMQ] connected`); + // this.channel = await this.connection.createChannel(); + // console.log(`[RabbitMQ] channel created`); }, }; diff --git a/util/src/util/UserFlags.ts b/util/src/util/UserFlags.ts deleted file mode 100644
index 72394eff..00000000 --- a/util/src/util/UserFlags.ts +++ /dev/null
@@ -1,22 +0,0 @@ -// https://github.com/discordjs/discord.js/blob/master/src/util/UserFlags.js -// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah - -import { BitField } from "./BitField"; - -export class UserFlags extends BitField { - static FLAGS = { - DISCORD_EMPLOYEE: BigInt(1) << BigInt(0), - PARTNERED_SERVER_OWNER: BigInt(1) << BigInt(1), - HYPESQUAD_EVENTS: BigInt(1) << BigInt(2), - BUGHUNTER_LEVEL_1: BigInt(1) << BigInt(3), - HOUSE_BRAVERY: BigInt(1) << BigInt(6), - HOUSE_BRILLIANCE: BigInt(1) << BigInt(7), - HOUSE_BALANCE: BigInt(1) << BigInt(8), - EARLY_SUPPORTER: BigInt(1) << BigInt(9), - TEAM_USER: BigInt(1) << BigInt(10), - SYSTEM: BigInt(1) << BigInt(12), - BUGHUNTER_LEVEL_2: BigInt(1) << BigInt(14), - VERIFIED_BOT: BigInt(1) << BigInt(16), - EARLY_VERIFIED_BOT_DEVELOPER: BigInt(1) << BigInt(17), - }; -} diff --git a/util/src/util/checkToken.ts b/util/src/util/checkToken.ts
index 91bf08d5..825ee00c 100644 --- a/util/src/util/checkToken.ts +++ b/util/src/util/checkToken.ts
@@ -1,6 +1,7 @@ -import { JWTOptions } from "./Constants"; -import jwt from "jsonwebtoken"; -import { UserModel } from "../models"; +import jwt, { VerifyOptions } from "jsonwebtoken"; +import { User } from "../entities"; + +export const JWTOptions: VerifyOptions = { algorithms: ["HS256"] }; export function checkToken(token: string, jwtSecret: string): Promise<any> { return new Promise((res, rej) => { @@ -8,10 +9,10 @@ export function checkToken(token: string, jwtSecret: string): Promise<any> { jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => { if (err || !decoded) return rej("Invalid Token"); - const user = await UserModel.findOne( + const user = await User.findOneOrFail( { id: decoded.id }, - { "user_data.valid_tokens_since": true, bot: true, disabled: true, deleted: true } - ).exec(); + { select: ["user_data", "bot", "disabled", "deleted"] } + ); if (!user) return rej("Invalid Token"); // we need to round it to seconds as it saved as seconds in jwt iat and valid_tokens_since is stored in milliseconds if (decoded.iat * 1000 < user.user_data.valid_tokens_since.setSeconds(0, 0)) return rej("Invalid Token"); diff --git a/util/src/util/index.ts b/util/src/util/index.ts
index e52a23b7..886a2390 100644 --- a/util/src/util/index.ts +++ b/util/src/util/index.ts
@@ -1,11 +1,12 @@ export * from "./Regex"; export * from "./String"; export * from "./BitField"; +export * from "./Database"; export * from "./Intents"; export * from "./MessageFlags"; export * from "./Permissions"; export * from "./Snowflake"; -export * from "./UserFlags"; export * from "./toBigInt"; export * from "./RabbitMQ"; export * from "./Event"; +export * from "./checkToken";