diff options
author | xnacly <matteogropp@gmail.com> | 2021-04-08 15:56:11 +0200 |
---|---|---|
committer | xnacly <matteogropp@gmail.com> | 2021-04-08 15:56:11 +0200 |
commit | f01fe1ba3ac22d33ecf61659d1f65c5ac1ba4e17 (patch) | |
tree | 1a3361f31dbbf700efb84513c95388cfbfb2e58f /src | |
parent | added hasThrow (diff) | |
parent | :bug: move dev dependencies to normal (diff) | |
download | server-f01fe1ba3ac22d33ecf61659d1f65c5ac1ba4e17.tar.xz |
Merge branch 'main' of https://github.com/fosscord/fosscord-server-util
Diffstat (limited to 'src')
-rw-r--r-- | src/index.ts | 29 | ||||
-rw-r--r-- | src/models/Activity.ts | 72 | ||||
-rw-r--r-- | src/models/Application.ts | 6 | ||||
-rw-r--r-- | src/models/AuditLog.ts | 66 | ||||
-rw-r--r-- | src/models/Ban.ts | 12 | ||||
-rw-r--r-- | src/models/Channel.ts | 34 | ||||
-rw-r--r-- | src/models/Emoji.ts | 12 | ||||
-rw-r--r-- | src/models/Event.ts | 281 | ||||
-rw-r--r-- | src/models/Guild.ts | 78 | ||||
-rw-r--r-- | src/models/Interaction.ts | 8 | ||||
-rw-r--r-- | src/models/Invite.ts | 22 | ||||
-rw-r--r-- | src/models/Member.ts | 35 | ||||
-rw-r--r-- | src/models/Message.ts | 97 | ||||
-rw-r--r-- | src/models/Role.ts | 15 | ||||
-rw-r--r-- | src/models/User.ts | 106 | ||||
-rw-r--r-- | src/models/VoiceState.ts | 12 | ||||
-rw-r--r-- | src/models/index.ts | 36 | ||||
-rw-r--r-- | src/util/Database.ts | 76 | ||||
-rw-r--r-- | src/util/Permissions.ts | 22 | ||||
-rw-r--r-- | src/util/Snowflake.ts | 2 | ||||
-rw-r--r-- | src/util/index.ts | 7 |
21 files changed, 611 insertions, 417 deletions
diff --git a/src/index.ts b/src/index.ts index 8484565a..343a7496 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,31 +1,10 @@ export * from "./util/checkToken"; export * as Constants from "./util/Constants"; -export * from "./models/Ban"; -export * from "./models/Channel"; -export * from "./models/Emoji"; -export * from "./models/Guild"; -export * from "./models/Invite"; -export * from "./models/Member"; -export * from "./models/Role"; -export * from "./models/User"; -export * from "./models/Activity"; -export * from "./models/Application"; -export * from "./models/Interaction"; -export * from "./models/Message"; -export * from "./models/Status"; -export * from "./models/VoiceState"; - -export * from "./util/String"; -export * from "./util/BitField"; -export * from "./util/Intents"; -export * from "./util/MessageFlags"; -export * from "./util/Permissions"; -export * from "./util/Snowflake"; -export * from "./util/UserFlags"; -export * from "./models/Event"; +export * from "./models/index"; +export * from "./util/index"; import Config, { DefaultOptions } from "./util/Config"; -import db, { MongooseCache } from "./util/Database"; +import db, { MongooseCache, toObject } from "./util/Database"; -export { Config, db, DefaultOptions, MongooseCache }; +export { Config, db, DefaultOptions, MongooseCache, toObject }; diff --git a/src/models/Activity.ts b/src/models/Activity.ts index beaa43e8..340590c4 100644 --- a/src/models/Activity.ts +++ b/src/models/Activity.ts @@ -4,7 +4,7 @@ import { Schema, model, Types, Document } from "mongoose"; export interface Presence { user: User; - guild_id?: bigint; + guild_id?: string; status: Status; activities: Activity[]; client_status: ClientStatus; @@ -14,17 +14,17 @@ export interface Activity { name: string; type: ActivityType; url?: string; - created_at: Date; + created_at?: Date; timestamps?: { - start: number; - end: number; + start?: number; + end?: number; }[]; - application_id?: bigint; + application_id?: string; details?: string; state?: string; emoji?: { name: string; - id?: bigint; + id?: string; amimated?: boolean; }; party?: { @@ -32,10 +32,10 @@ export interface Activity { size?: [number, number]; }; assets?: { - large_image: string; - large_text: string; - small_image: string; - small_text: string; + large_image?: string; + large_text?: string; + small_image?: string; + small_text?: string; }; secrets?: { join?: string; @@ -49,39 +49,39 @@ export interface Activity { export const Activity = { name: String, type: Number, - url: String, - created_at: Date, - timestamps: [ + $url: String, + $created_at: Date, + $timestamps: [ { - start: Number, - end: Number, + $start: Number, + $end: Number, }, ], - application_id: Types.Long, - details: String, - state: String, - emoji: { - name: String, - id: Types.Long, - amimated: Boolean, + $application_id: String, + $details: String, + $state: String, + $emoji: { + $name: String, + $id: String, + $amimated: Boolean, }, - party: { - id: String, - size: [Number, Number], + $party: { + $id: String, + $size: [Number, Number], }, - assets: { - large_image: String, - large_text: String, - small_image: String, - small_text: String, + $assets: { + $large_image: String, + $large_text: String, + $small_image: String, + $small_text: String, }, - secrets: { - join: String, - spectate: String, - match: String, + $secrets: { + $join: String, + $spectate: String, + $match: String, }, - instance: Boolean, - flags: Types.Long, + $instance: Boolean, + $flags: Types.Long, }; export enum ActivityType { diff --git a/src/models/Application.ts b/src/models/Application.ts index ea443dc9..4c519ff2 100644 --- a/src/models/Application.ts +++ b/src/models/Application.ts @@ -1,6 +1,6 @@ export interface ApplicationCommand { - id: bigint; - application_id: bigint; + id: string; + application_id: string; name: string; description: string; options?: ApplicationCommandOption[]; @@ -32,7 +32,7 @@ export enum ApplicationCommandOptionType { } export interface ApplicationCommandInteractionData { - id: bigint; + id: string; name: string; options?: ApplicationCommandInteractionDataOption[]; } diff --git a/src/models/AuditLog.ts b/src/models/AuditLog.ts index a0f91a82..c1f83c13 100644 --- a/src/models/AuditLog.ts +++ b/src/models/AuditLog.ts @@ -11,17 +11,17 @@ export interface AuditLogResponse { } export interface AuditLogEntries { - target_id?: bigint; - user_id: bigint; - id: bigint; + target_id?: string; + user_id: string; + id: string; action_type: AuditLogEvents; options?: { delete_member_days?: string; members_removed?: string; - channel_id?: bigint; - messaged_id?: bigint; + channel_id?: string; + messaged_id?: string; count?: string; - id?: bigint; + id?: string; type?: string; role_name?: string; }; @@ -42,13 +42,13 @@ export interface AuditLogChangeValue { splash_hash?: string; discovery_splash_hash?: string; banner_hash?: string; - owner_id?: bigint; + owner_id?: string; region?: string; preferred_locale?: string; - afk_channel_id?: bigint; + afk_channel_id?: string; afk_timeout?: number; - rules_channel_id?: bigint; - public_updates_channel_id?: bigint; + rules_channel_id?: string; + public_updates_channel_id?: string; mfa_level?: number; verification_level?: number; explicit_content_filter?: number; @@ -58,14 +58,14 @@ export interface AuditLogChangeValue { $remove?: {}[]; prune_delete_days?: number; widget_enabled?: boolean; - widget_channel_id?: bigint; - system_channel_id?: bigint; + widget_channel_id?: string; + system_channel_id?: string; position?: number; topic?: string; bitrate?: number; permission_overwrites?: ChannelPermissionOverwrite[]; nsfw?: boolean; - application_id?: bigint; + application_id?: string; rate_limit_per_user?: number; permissions?: string; color?: number; @@ -74,8 +74,8 @@ export interface AuditLogChangeValue { allow?: string; deny?: string; code?: string; - channel_id?: bigint; - inviter_id?: bigint; + channel_id?: string; + inviter_id?: string; max_uses?: number; uses?: number; max_age?: number; @@ -84,7 +84,7 @@ export interface AuditLogChangeValue { mute?: boolean; nick?: string; avatar_hash?: string; - id?: bigint; + id?: string; type?: number; enable_emoticons?: boolean; expire_behavior?: number; @@ -93,7 +93,7 @@ export interface AuditLogChangeValue { } export interface AuditLogEntriesDocument extends Document, AuditLogEntries { - id: bigint; + id: string; } export const AuditLogChanges = { @@ -103,13 +103,13 @@ export const AuditLogChanges = { splash_hash: String, discovery_splash_hash: String, banner_hash: String, - owner_id: Types.Long, + owner_id: String, region: String, preferred_locale: String, - afk_channel_id: Types.Long, + afk_channel_id: String, afk_timeout: Number, - rules_channel_id: Types.Long, - public_updates_channel_id: Types.Long, + rules_channel_id: String, + public_updates_channel_id: String, mfa_level: Number, verification_level: Number, explicit_content_filter: Number, @@ -119,14 +119,14 @@ export const AuditLogChanges = { $remove: [{}], prune_delete_days: Number, widget_enabled: Boolean, - widget_channel_id: Types.Long, - system_channel_id: Types.Long, + widget_channel_id: String, + system_channel_id: String, position: Number, topic: String, bitrate: Number, permission_overwrites: [{}], nsfw: Boolean, - application_id: Types.Long, + application_id: String, rate_limit_per_user: Number, permissions: String, color: Number, @@ -135,8 +135,8 @@ export const AuditLogChanges = { allow: String, deny: String, code: String, - channel_id: Types.Long, - inviter_id: Types.Long, + channel_id: String, + inviter_id: String, max_uses: Number, uses: Number, max_age: Number, @@ -145,7 +145,7 @@ export const AuditLogChanges = { mute: Boolean, nick: String, avatar_hash: String, - id: Types.Long, + id: String, type: Number, enable_emoticons: Boolean, expire_behavior: Number, @@ -154,17 +154,17 @@ export const AuditLogChanges = { }; export const AuditLogSchema = new Schema({ - target_id: Types.Long, - user_id: { type: Types.Long, required: true }, - id: { type: Types.Long, required: true }, + 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: Types.Long, - messaged_id: Types.Long, + channel_id: String, + messaged_id: String, count: String, - id: Types.Long, + id: String, type: String, role_name: String, }, diff --git a/src/models/Ban.ts b/src/models/Ban.ts index 8fc3b124..27893029 100644 --- a/src/models/Ban.ts +++ b/src/models/Ban.ts @@ -2,17 +2,17 @@ import { Schema, model, Types, Document } from "mongoose"; import db from "../util/Database"; export interface Ban extends Document { - user_id: bigint; - guild_id: bigint; - executor_id: bigint; + user_id: string; + guild_id: string; + executor_id: string; ip: string; reason?: string; } export const BanSchema = new Schema({ - user_id: { type: Types.Long, required: true }, - guild_id: { type: Types.Long, required: true }, - executor_id: { type: Types.Long, required: true }, + 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? }); diff --git a/src/models/Channel.ts b/src/models/Channel.ts index bf03c939..82ad2999 100644 --- a/src/models/Channel.ts +++ b/src/models/Channel.ts @@ -4,20 +4,20 @@ import db from "../util/Database"; export interface AnyChannel extends Channel, DMChannel, TextChannel, VoiceChannel {} export interface ChannelDocument extends Document, AnyChannel { - id: bigint; + id: string; } export const ChannelSchema = new Schema({ - id: Types.Long, + id: String, created_at: { type: Schema.Types.Date, required: true }, name: { type: String, required: true }, type: { type: Number, required: true }, - guild_id: Types.Long, - owner_id: Types.Long, - parent_id: Types.Long, - recipients: [Types.Long], + guild_id: String, + owner_id: String, + parent_id: String, + recipients: [String], position: Number, - last_message_id: Types.Long, + last_message_id: String, last_pin_timestamp: Date, nsfw: Boolean, rate_limit_per_user: Number, @@ -26,7 +26,7 @@ export const ChannelSchema = new Schema({ { allow: Types.Long, deny: Types.Long, - id: Types.Long, + id: String, type: Number, }, ], @@ -36,28 +36,28 @@ export const ChannelSchema = new Schema({ export const ChannelModel = db.model<ChannelDocument>("Channel", ChannelSchema, "channels"); export interface Channel { - id: bigint; + id: string; created_at: Date; name: string; type: number; } export interface TextBasedChannel { - last_message_id?: bigint; + last_message_id?: string; last_pin_timestamp?: number; } export interface GuildChannel extends Channel { - guild_id: bigint; + guild_id: string; position: number; - parent_id?: bigint; + parent_id?: string; permission_overwrites: ChannelPermissionOverwrite[]; } export interface ChannelPermissionOverwrite { - allow: bigint; - deny: bigint; - id: bigint; + allow: bigint; // for bitfields we use bigints + deny: bigint; // for bitfields we use bigints + id: string; type: ChannelPermissionOverwriteType; } @@ -75,8 +75,8 @@ export interface TextChannel extends GuildChannel, TextBasedChannel { } export interface DMChannel extends Channel, TextBasedChannel { - owner_id: bigint; - recipients: bigint[]; + owner_id: string; + recipients: string[]; } export enum ChannelType { diff --git a/src/models/Emoji.ts b/src/models/Emoji.ts index 530c2cc7..3e5cad53 100644 --- a/src/models/Emoji.ts +++ b/src/models/Emoji.ts @@ -2,27 +2,27 @@ import { Schema, model, Types, Document } from "mongoose"; import db from "../util/Database"; export interface Emoji extends Document { - id: bigint; + id: string; animated: boolean; available: boolean; - guild_id: bigint; + guild_id: string; managed: boolean; name: string; require_colons: boolean; url: string; - roles: bigint[]; // roles this emoji is whitelisted to + roles: string[]; // roles this emoji is whitelisted to (new discord feature?) } export const EmojiSchema = new Schema({ - id: { type: Types.Long, required: true }, + id: { type: String, required: true }, animated: Boolean, available: Boolean, - guild_id: Types.Long, + guild_id: String, managed: Boolean, name: String, require_colons: Boolean, url: String, - roles: [Types.Long], + roles: [String], }); // @ts-ignore diff --git a/src/models/Event.ts b/src/models/Event.ts index 40cbcb20..9a5b5283 100644 --- a/src/models/Event.ts +++ b/src/models/Event.ts @@ -1,7 +1,7 @@ -import { ConnectedAccount, User, UserSettings } from "./User"; +import { ConnectedAccount, PublicUser, User, UserSettings } from "./User"; import { DMChannel, Channel } from "./Channel"; import { Guild } from "./Guild"; -import { PublicMember, UserGuildSettings } from "./Member"; +import { Member, PublicMember, UserGuildSettings } from "./Member"; import { Emoji } from "./Emoji"; import { Presence } from "./Activity"; import { Role } from "./Role"; @@ -14,9 +14,9 @@ import { Schema, model, Types, Document } from "mongoose"; import db from "../util/Database"; export interface Event { - guild_id?: bigint; - user_id?: bigint; - channel_id?: bigint; + guild_id?: string; + user_id?: string; + channel_id?: string; created_at?: Date; event: EVENT; data?: any; @@ -25,9 +25,9 @@ export interface Event { export interface EventDocument extends Event, Document {} export const EventSchema = new Schema({ - guild_id: Types.Long, - user_id: Types.Long, - channel_id: Types.Long, + guild_id: String, + user_id: String, + channel_id: String, created_at: { type: Date, required: true }, event: { type: String, required: true }, data: Object, @@ -44,60 +44,78 @@ export interface InvalidatedEvent extends Event { // ! END Custom Events that shouldn't get sent to the client but processed by the server -export interface ReadyEvent extends Event { - event: "READY"; - data: { - v: number; - user: Omit<User, "guilds" | "user_settings" | "valid_tokens_since" | "connected_accounts" | "relationships">; - private_channels: DMChannel[]; // this will be empty for bots - session_id: string; // resuming - guilds: Guild[]; - analytics_token?: string; - connected_accounts?: ConnectedAccount[]; - consents?: { - personalization?: { - consented?: boolean; - }; - }; - country_code?: string; // e.g. DE - friend_suggestion_count?: number; - geo_ordered_rtc_regions?: string[]; // ["europe","russie","india","us-east","us-central"] - experiments?: [number, number, number, number, number][]; - guild_experiments?: [ - // ? what are guild_experiments? - // this is the structure of it: - number, - null, - number, - [[number, { e: number; s: number }[]]], - [number, [[number, [number, number]]]], - { b: number; k: bigint[] }[] - ][]; - guild_join_requests?: []; // ? what is this? this is new - shard?: [number, number]; - user_settings?: UserSettings; - relationships?: []; - user_guild_settings?: { - entries: UserGuildSettings[]; - version: number; - partial: boolean; - }; - application?: { - id: bigint; - flags: bigint; +export interface ReadyEventData { + v: number; + user: PublicUser & { + mobile: boolean; + desktop: boolean; + email: string; + flags: bigint; + mfa_enabled: boolean; + nsfw_allowed: boolean; + phone: string; + premium: boolean; + premium_type: number; + verified: boolean; + bot: boolean; + }; + private_channels: DMChannel[]; // this will be empty for bots + session_id: string; // resuming + guilds: Guild[]; + analytics_token?: string; + connected_accounts?: ConnectedAccount[]; + consents?: { + personalization?: { + consented?: boolean; }; - - merged_members?: PublicMember[][]; // every guild member object for the current user - // probably all users who the user is in contact with - users?: { - avatar?: string; - discriminator: string; - id: bigint; - username: string; - bot: boolean; - public_flags: bigint; - }[]; }; + country_code?: string; // e.g. DE + friend_suggestion_count?: number; + geo_ordered_rtc_regions?: string[]; // ["europe","russie","india","us-east","us-central"] + experiments?: [number, number, number, number, number][]; + guild_experiments?: [ + // ? what are guild_experiments? + // this is the structure of it: + number, + null, + number, + [[number, { e: number; s: number }[]]], + [number, [[number, [number, number]]]], + { b: number; k: bigint[] }[] + ][]; + guild_join_requests?: []; // ? what is this? this is new + shard?: [number, number]; + user_settings?: UserSettings; + relationships?: []; // TODO + read_state: { + entries: []; // TODO + partial: boolean; + version: number; + }; + user_guild_settings?: { + entries: UserGuildSettings[]; + version: number; + partial: boolean; + }; + application?: { + id: string; + flags: bigint; + }; + merged_members?: Omit<Member, "settings" | "user">[][]; + // probably all users who the user is in contact with + users?: { + avatar?: string; + discriminator: string; + id: string; + username: string; + bot: boolean; + public_flags: bigint; + }[]; +} + +export interface ReadyEvent extends Event { + event: "READY"; + data: ReadyEventData; } export interface ChannelCreateEvent extends Event { @@ -118,8 +136,8 @@ export interface ChannelDeleteEvent extends Event { export interface ChannelPinsUpdateEvent extends Event { event: "CHANNEL_PINS_UPDATE"; data: { - guild_id?: bigint; - channel_id: bigint; + guild_id?: string; + channel_id: string; last_pin_timestamp: number; }; } @@ -137,7 +155,7 @@ export interface GuildUpdateEvent extends Event { export interface GuildDeleteEvent extends Event { event: "GUILD_DELETE"; data: { - id: bigint; + id: string; unavailable?: boolean; }; } @@ -145,7 +163,7 @@ export interface GuildDeleteEvent extends Event { export interface GuildBanAddEvent extends Event { event: "GUILD_BAN_ADD"; data: { - guild_id: bigint; + guild_id: string; user: User; }; } @@ -153,7 +171,7 @@ export interface GuildBanAddEvent extends Event { export interface GuildBanRemoveEvent extends Event { event: "GUILD_BAN_REMOVE"; data: { - guild_id: bigint; + guild_id: string; user: User; }; } @@ -161,7 +179,7 @@ export interface GuildBanRemoveEvent extends Event { export interface GuildEmojiUpdateEvent extends Event { event: "GUILD_EMOJI_UPDATE"; data: { - guild_id: bigint; + guild_id: string; emojis: Emoji[]; }; } @@ -169,21 +187,21 @@ export interface GuildEmojiUpdateEvent extends Event { export interface GuildIntegrationUpdateEvent extends Event { event: "GUILD_INTEGRATIONS_UPDATE"; data: { - guild_id: bigint; + guild_id: string; }; } export interface GuildMemberAddEvent extends Event { event: "GUILD_MEMBER_ADD"; data: PublicMember & { - guild_id: bigint; + guild_id: string; }; } export interface GuildMemberRemoveEvent extends Event { event: "GUILD_MEMBER_REMOVE"; data: { - guild_id: bigint; + guild_id: string; user: User; }; } @@ -191,8 +209,8 @@ export interface GuildMemberRemoveEvent extends Event { export interface GuildMemberUpdateEvent extends Event { event: "GUILD_MEMBER_UPDATE"; data: { - guild_id: bigint; - roles: bigint[]; + guild_id: string; + roles: string[]; user: User; nick?: string; joined_at: Date; @@ -204,11 +222,11 @@ export interface GuildMemberUpdateEvent extends Event { export interface GuildMembersChunkEvent extends Event { event: "GUILD_MEMBERS_CHUNK"; data: { - guild_id: bigint; + guild_id: string; members: PublicMember[]; chunk_index: number; chunk_count: number; - not_found: bigint[]; + not_found: string[]; presences: Presence[]; nonce?: string; }; @@ -217,7 +235,7 @@ export interface GuildMembersChunkEvent extends Event { export interface GuildRoleCreateEvent extends Event { event: "GUILD_ROLE_CREATE"; data: { - guild_id: bigint; + guild_id: string; role: Role; }; } @@ -225,7 +243,7 @@ export interface GuildRoleCreateEvent extends Event { export interface GuildRoleUpdateEvent extends Event { event: "GUILD_ROLE_UPDATE"; data: { - guild_id: bigint; + guild_id: string; role: Role; }; } @@ -233,31 +251,31 @@ export interface GuildRoleUpdateEvent extends Event { export interface GuildRoleDeleteEvent extends Event { event: "GUILD_ROLE_DELETE"; data: { - guild_id: bigint; - role_id: bigint; + guild_id: string; + role_id: string; }; } export interface InviteCreateEvent extends Event { event: "INVITE_CREATE"; data: Omit<Invite, "guild" | "channel"> & { - channel_id: bigint; - guild_id?: bigint; + channel_id: string; + guild_id?: string; }; } export interface InviteDeleteEvent extends Event { event: "INVITE_DELETE"; data: { - channel_id: bigint; - guild_id?: bigint; + channel_id: string; + guild_id?: string; code: string; }; } export type MessagePayload = Omit<Message, "author_id"> & { - channel_id: bigint; - guild_id?: bigint; + channel_id: string; + guild_id?: string; author: User; member: PublicMember; mentions: (User & { member: PublicMember })[]; @@ -276,28 +294,28 @@ export interface MessageUpdateEvent extends Event { export interface MessageDeleteEvent extends Event { event: "MESSAGE_DELETE"; data: { - id: bigint; - channel_id: bigint; - guild_id?: bigint; + id: string; + channel_id: string; + guild_id?: string; }; } export interface MessageDeleteBulkEvent extends Event { event: "MESSAGE_DELETE_BULK"; data: { - ids: bigint[]; - channel_id: bigint; - guild_id?: bigint; + ids: string[]; + channel_id: string; + guild_id?: string; }; } export interface MessageReactionAddEvent extends Event { event: "MESSAGE_REACTION_ADD"; data: { - user_id: bigint; - channel_id: bigint; - message_id: bigint; - guild_id?: bigint; + user_id: string; + channel_id: string; + message_id: string; + guild_id?: string; member?: PublicMember; emoji: PartialEmoji; }; @@ -306,10 +324,10 @@ export interface MessageReactionAddEvent extends Event { export interface MessageReactionRemoveEvent extends Event { event: "MESSAGE_REACTION_REMOVE"; data: { - user_id: bigint; - channel_id: bigint; - message_id: bigint; - guild_id?: bigint; + user_id: string; + channel_id: string; + message_id: string; + guild_id?: string; emoji: PartialEmoji; }; } @@ -317,18 +335,18 @@ export interface MessageReactionRemoveEvent extends Event { export interface MessageReactionRemoveAllEvent extends Event { event: "MESSAGE_REACTION_REMOVE_ALL"; data: { - channel_id: bigint; - message_id: bigint; - guild_id?: bigint; + channel_id: string; + message_id: string; + guild_id?: string; }; } export interface MessageReactionRemoveEmojiEvent extends Event { event: "MESSAGE_REACTION_REMOVE_EMOJI"; data: { - channel_id: bigint; - message_id: bigint; - guild_id?: bigint; + channel_id: string; + message_id: string; + guild_id?: string; emoji: PartialEmoji; }; } @@ -341,10 +359,10 @@ export interface PresenceUpdateEvent extends Event { export interface TypingStartEvent extends Event { event: "TYPING_START"; data: { - channel_id: bigint; - user_id: bigint; + channel_id: string; + user_id: string; timestamp: number; - guild_id?: bigint; + guild_id?: string; member?: PublicMember; }; } @@ -365,7 +383,7 @@ export interface VoiceServerUpdateEvent extends Event { event: "VOICE_SERVER_UPDATE"; data: { token: string; - guild_id: bigint; + guild_id: string; endpoint: string; }; } @@ -373,13 +391,13 @@ export interface VoiceServerUpdateEvent extends Event { export interface WebhooksUpdateEvent extends Event { event: "WEBHOOKS_UPDATE"; data: { - guild_id: bigint; - channel_id: bigint; + guild_id: string; + channel_id: string; }; } export type ApplicationCommandPayload = ApplicationCommand & { - guild_id: bigint; + guild_id: string; }; export interface ApplicationCommandCreateEvent extends Event { @@ -404,6 +422,49 @@ export interface InteractionCreateEvent extends Event { // located in collection events +export enum EVENTEnum { + Ready = "READY", + ChannelCreate = "CHANNEL_CREATE", + ChannelUpdate = "CHANNEL_UPDATE", + ChannelDelete = "CHANNEL_DELETE", + ChannelPinsUpdate = "CHANNEL_PINS_UPDATE", + GuildCreate = "GUILD_CREATE", + GuildUpdate = "GUILD_UPDATE", + GuildDelete = "GUILD_DELETE", + GuildBanAdd = "GUILD_BAN_ADD", + GuildBanRemove = "GUILD_BAN_REMOVE", + GuildEmojUpdate = "GUILD_EMOJI_UPDATE", + GuildIntegrationsUpdate = "GUILD_INTEGRATIONS_UPDATE", + GuildMemberAdd = "GUILD_MEMBER_ADD", + GuildMemberRempve = "GUILD_MEMBER_REMOVE", + GuildMemberUpdate = "GUILD_MEMBER_UPDATE", + GuildMemberSpeaking = "GUILD_MEMBER_SPEAKING", + GuildMembersChunk = "GUILD_MEMBERS_CHUNK", + GuildRoleCreate = "GUILD_ROLE_CREATE", + GuildRoleDelete = "GUILD_ROLE_DELETE", + GuildRoleUpdate = "GUILD_ROLE_UPDATE", + InviteCreate = "INVITE_CREATE", + InviteDelete = "INVITE_DELETE", + MessageCreate = "MESSAGE_CREATE", + MessageUpdate = "MESSAGE_UPDATE", + MessageDelete = "MESSAGE_DELETE", + MessageDeleteBulk = "MESSAGE_DELETE_BULK", + MessageReactionAdd = "MESSAGE_REACTION_ADD", + MessageReactionRemove = "MESSAGE_REACTION_REMOVE", + MessageReactionRemoveAll = "MESSAGE_REACTION_REMOVE_ALL", + MessageReactionRemoveEmoji = "MESSAGE_REACTION_REMOVE_EMOJI", + PresenceUpdate = "PRESENCE_UPDATE", + TypingStart = "TYPING_START", + UserUpdate = "USER_UPDATE", + WebhooksUpdate = "WEBHOOKS_UPDATE", + InteractionCreate = "INTERACTION_CREATE", + VoiceStateUpdate = "VOICE_STATE_UPDATE", + VoiceServerUpdate = "VOICE_SERVER_UPDATE", + ApplicationCommandCreate = "APPLICATION_COMMAND_CREATE", + ApplicationCommandUpdate = "APPLICATION_COMMAND_UPDATE", + ApplicationCommandDelete = "APPLICATION_COMMAND_DELETE", +} + export type EVENT = | "READY" | "CHANNEL_CREATE" diff --git a/src/models/Guild.ts b/src/models/Guild.ts index b25be7aa..819ac840 100644 --- a/src/models/Guild.ts +++ b/src/models/Guild.ts @@ -1,15 +1,19 @@ 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: bigint; + id: string; } export interface Guild { - id: bigint; - afk_channel_id?: bigint; + id: string; + afk_channel_id?: string; afk_timeout?: number; - application_id?: bigint; + application_id?: string; banner?: string; default_message_notifications?: number; description?: string; @@ -30,29 +34,29 @@ export interface Guild { // voice_states: []; // * voice_states are stored in a seperate collection mfa_level?: number; name: string; - owner_id: bigint; + 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?: bigint; + public_updates_channel_id?: string; region?: string; - rules_channel_id?: bigint; + rules_channel_id?: string; splash?: string; system_channel_flags?: number; - system_channel_id?: bigint; + system_channel_id?: string; unavailable?: boolean; vanity_url_code?: string; verification_level?: number; welcome_screen: []; // welcome splash screen if a user joins guild - widget_channel_id?: bigint; + widget_channel_id?: string; widget_enabled?: boolean; } export const GuildSchema = new Schema({ - id: { type: Types.Long, required: true }, - afk_channel_id: Types.Long, + id: { type: String, required: true }, + afk_channel_id: String, afk_timeout: Number, - application_id: Types.Long, + application_id: String, banner: String, default_message_notifications: Number, description: String, @@ -68,26 +72,64 @@ export const GuildSchema = new Schema({ presence_count: Number, mfa_level: Number, name: { type: String, required: true }, - owner_id: { type: Types.Long, required: true }, + owner_id: { type: String, required: true }, preferred_locale: String, premium_subscription_count: Number, premium_tier: Number, - public_updates_channel_id: Types.Long, + public_updates_channel_id: String, region: String, - rules_channel_id: Types.Long, + rules_channel_id: String, splash: String, system_channel_flags: Number, - system_channel_id: Types.Long, + system_channel_id: String, unavailable: Boolean, vanity_url_code: String, verification_level: Number, voice_states: { type: [Object], default: [] }, welcome_screen: { type: [Object], default: [] }, - widget_channel_id: Types.Long, + widget_channel_id: String, widget_enabled: Boolean, }); -// GuildSchema.virtual +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/src/models/Interaction.ts b/src/models/Interaction.ts index 6f36c14a..764247a5 100644 --- a/src/models/Interaction.ts +++ b/src/models/Interaction.ts @@ -1,12 +1,12 @@ import { AllowedMentions, Embed } from "./Message"; export interface Interaction { - id: bigint; + id: string; type: InteractionType; data?: {}; - guild_id: bigint; - channel_id: bigint; - member_id: bigint; + guild_id: string; + channel_id: string; + member_id: string; token: string; version: number; } diff --git a/src/models/Invite.ts b/src/models/Invite.ts index fc60b93c..590a4598 100644 --- a/src/models/Invite.ts +++ b/src/models/Invite.ts @@ -8,14 +8,13 @@ export interface Invite extends Document { max_uses: number; max_age: number; created_at: Date; - guild_id: bigint; - channel_id: bigint; - inviter_id: bigint; + guild_id: string; + channel_id: string; + inviter_id: string; - //! What the fucking shit is this - target_user_id?: bigint; + // ? What the fucking shit is this + target_user_id?: string; target_user_type?: number; - // ! } export const InviteSchema = new Schema({ @@ -25,14 +24,13 @@ export const InviteSchema = new Schema({ max_uses: Number, max_age: Number, created_at: Date, - guild_id: Types.Long, - channel_id: Types.Long, - inviter_id: Types.Long, + guild_id: String, + channel_id: String, + inviter_id: String, - //! What the fucking shit is this - target_user_id: Types.Long, + // ? What the fucking shit is this + target_user_id: String, target_user_type: Number, - // ! }); // @ts-ignore diff --git a/src/models/Member.ts b/src/models/Member.ts index 145b5df4..52151235 100644 --- a/src/models/Member.ts +++ b/src/models/Member.ts @@ -1,12 +1,24 @@ -import { PublicUser, User, UserModel } from "./User"; +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: bigint; - guild_id: bigint; + id: string; + guild_id: string; nick?: string; - roles: bigint[]; + roles: string[]; joined_at: Date; premium_since?: number; deaf: boolean; @@ -17,12 +29,12 @@ export interface Member { } export interface MemberDocument extends Member, Document { - id: bigint; + id: string; } export interface UserGuildSettings { channel_overrides: { - channel_id: bigint; + channel_id: string; message_notifications: number; mute_config: MuteConfig; muted: boolean; @@ -47,10 +59,10 @@ const MuteConfig = { }; export const MemberSchema = new Schema({ - id: { type: Types.Long, required: true }, - guild_id: Types.Long, + id: { type: String, required: true }, + guild_id: String, nick: String, - roles: [Types.Long], + roles: [String], joined_at: Date, premium_since: Number, deaf: Boolean, @@ -59,7 +71,7 @@ export const MemberSchema = new Schema({ settings: { channel_overrides: [ { - channel_id: Types.Long, + channel_id: String, message_notifications: Number, mute_config: MuteConfig, muted: Boolean, @@ -80,6 +92,9 @@ MemberSchema.virtual("user", { localField: "id", foreignField: "id", justOne: true, + autopopulate: { + select: PublicUserProjection, + }, }); // @ts-ignore diff --git a/src/models/Message.ts b/src/models/Message.ts index e80ec1f8..15ff57d3 100644 --- a/src/models/Message.ts +++ b/src/models/Message.ts @@ -1,24 +1,25 @@ import { Schema, Types, Document } from "mongoose"; import db from "../util/Database"; -import { UserModel } from "./User"; -import { MemberModel } from "./Member"; -import { RoleModel } from "./Role"; +import { PublicUser, PublicUserProjection, UserModel } from "./User"; +import { MemberModel, PublicMember, PublicMemberProjection } from "./Member"; +import { Role, RoleModel } from "./Role"; +import { Channel } from "./Channel"; export interface Message { - id: bigint; - channel_id: bigint; - guild_id?: bigint; - author_id?: bigint; - webhook_id?: bigint; - application_id?: bigint; + id: string; + channel_id: string; + guild_id?: string; + author_id?: string; + webhook_id?: string; + application_id?: string; content?: string; timestamp: Date; edited_timestamp?: Date; tts?: boolean; mention_everyone?: boolean; - mention_user_ids: bigint[]; - mention_role_ids: bigint[]; - mention_channels_ids: bigint[]; + mention_user_ids: string[]; + mention_role_ids: string[]; + mention_channels_ids: string[]; attachments: Attachment[]; embeds: Embed[]; reactions: Reaction[]; @@ -32,14 +33,20 @@ export interface Message { flags?: bigint; stickers?: []; message_reference?: { - message_id: bigint; - channel_id?: bigint; - guild_id?: bigint; + message_id: string; + channel_id?: string; + guild_id?: string; }; + // mongoose virtuals: + author?: PublicUser; + member?: PublicMember; + mentions?: PublicUser[]; + mention_roles?: Role[]; + mention_channels?: Channel[]; } export interface MessageDocument extends Document, Message { - id: bigint; + id: string; } export enum MessageType { @@ -63,7 +70,7 @@ export enum MessageType { } export interface Attachment { - id: bigint; // attachment id + id: string; // attachment id filename: string; // name of file attached size: number; // size of file in bytes url: string; // source url of file @@ -118,20 +125,20 @@ export interface Reaction { } export interface PartialEmoji { - id?: bigint; + id?: string; name: string; animated?: boolean; } export interface AllowedMentions { parse?: ("users" | "roles" | "everyone")[]; - roles?: bigint[]; - users?: bigint[]; + roles?: string[]; + users?: string[]; replied_user?: boolean; } export const Attachment = { - id: Types.Long, // attachment id + id: String, // attachment id filename: String, // name of file attached size: Number, // size of file in bytes url: String, // source url of file @@ -150,7 +157,7 @@ export const EmbedImage = { const Reaction = { count: Number, emoji: { - id: Types.Long, + id: String, name: String, animated: Boolean, }, @@ -191,20 +198,20 @@ export const Embed = { }; export const MessageSchema = new Schema({ - id: Types.Long, - channel_id: Types.Long, - author_id: Types.Long, - webhook_id: Types.Long, - guild_id: Types.Long, - application_id: Types.Long, + 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: [Types.Long], - mention_role_ids: [Types.Long], - mention_channel_ids: [Types.Long], + mention_user_ids: [String], + mention_role_ids: [String], + mention_channel_ids: [String], attachments: [Attachment], embeds: [Embed], reactions: [Reaction], @@ -218,10 +225,18 @@ export const MessageSchema = new Schema({ flags: Types.Long, stickers: [], message_reference: { - message_id: Types.Long, - channel_id: Types.Long, - guild_id: Types.Long, + message_id: String, + channel_id: String, + guild_id: String, }, + // virtual: + // author: { + // ref: UserModel, + // localField: "author_id", + // foreignField: "id", + // justOne: true, + // autopopulate: { select: { id: true, user_data: false } }, + // }, }); MessageSchema.virtual("author", { @@ -229,6 +244,7 @@ MessageSchema.virtual("author", { localField: "author_id", foreignField: "id", justOne: true, + autopopulate: { select: PublicUserProjection }, }); MessageSchema.virtual("member", { @@ -242,23 +258,28 @@ MessageSchema.virtual("mentions", { ref: UserModel, localField: "mention_user_ids", foreignField: "id", - justOne: true, + justOne: false, + autopopulate: { select: PublicUserProjection }, }); MessageSchema.virtual("mention_roles", { ref: RoleModel, localField: "mention_role_ids", foreignField: "id", - justOne: true, + justOne: false, + autopopulate: true, }); MessageSchema.virtual("mention_channels", { ref: RoleModel, - localField: "mention_role_ids", + localField: "mention_channel_ids", foreignField: "id", - justOne: true, + justOne: false, + autopopulate: { select: { id: true, guild_id: true, type: true, name: true } }, }); +MessageSchema.set("removeResponse", ["mention_channel_ids", "mention_role_ids", "mention_user_ids", "author_id"]); + // TODO: missing Application Model // MessageSchema.virtual("application", { // ref: Application, diff --git a/src/models/Role.ts b/src/models/Role.ts index fe716593..84ad55d0 100644 --- a/src/models/Role.ts +++ b/src/models/Role.ts @@ -2,8 +2,8 @@ import { Schema, model, Types, Document } from "mongoose"; import db from "../util/Database"; export interface Role { - id: bigint; - guild_id: bigint; + id: string; + guild_id: string; color: number; hoist: boolean; managed: boolean; @@ -12,17 +12,17 @@ export interface Role { permissions: bigint; position: number; tags?: { - bot_id?: bigint; + bot_id?: string; }; } export interface RoleDocument extends Document, Role { - id: bigint; + id: string; } export const RoleSchema = new Schema({ - id: Types.Long, - guild_id: Types.Long, + id: String, + guild_id: String, color: Number, hoist: Boolean, managed: Boolean, @@ -31,9 +31,10 @@ export const RoleSchema = new Schema({ permissions: Types.Long, position: Number, tags: { - bot_id: Types.Long, + bot_id: String, }, }); +RoleSchema.set("removeResponse", ["guild_id"]); // @ts-ignore export const RoleModel = db.model<RoleDocument>("Role", RoleSchema, "roles"); diff --git a/src/models/User.ts b/src/models/User.ts index 971e8d20..1f01e837 100644 --- a/src/models/User.ts +++ b/src/models/User.ts @@ -3,12 +3,18 @@ import { ClientStatus, Status } from "./Status"; import { Schema, Types, Document } from "mongoose"; import db from "../util/Database"; +export const PublicUserProjection = { + username: true, + discriminator: true, + id: true, + public_flags: true, + avatar: true, +}; export interface User { - id: bigint; + 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 - fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts phone?: string; // phone number of the user desktop: boolean; // if the user has desktop app installed mobile: boolean; // if the user has mobile app installed @@ -16,7 +22,6 @@ export interface User { premium_type: number; // nitro level bot: boolean; // if user is bot system: boolean; // shouldn't be used, the api sents this field type true, if the genetaed message comes from a system generated author - level: string; // organization permission level (owner, moderator, user) 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 @@ -24,12 +29,9 @@ export interface User { email?: string; // email of the user flags: bigint; // UserFlags public_flags: bigint; - hash: string; // hash of the password, salt is saved in password (bcrypt) - guilds: bigint[]; // array of guild ids the user is part of - valid_tokens_since: Date; // all tokens with a previous issue date are invalid user_settings: UserSettings; - relationships: Relationship[]; - connected_accounts: ConnectedAccount[]; + guilds: string[]; // array of guild ids the user is part of + user_data: UserData; presence: { status: Status; activities: Activity[]; @@ -37,12 +39,21 @@ export interface User { }; } +// Privat 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: bigint; + id: string; } export interface PublicUser { - id: bigint; + id: string; discriminator: string; username: string; avatar?: string; @@ -62,10 +73,10 @@ export interface ConnectedAccount { } export interface Relationship { - id: bigint; + id: string; nickname?: string; type: number; - user_id: bigint; + user_id: string; } export interface UserSettings { @@ -76,7 +87,7 @@ export interface UserSettings { contact_sync_enabled: boolean; convert_emoticons: boolean; custom_status: { - emoji_id: bigint | null; + emoji_id: string | null; emoji_name: string | null; expires_at: number | null; text: string | null; @@ -93,11 +104,11 @@ export interface UserSettings { guild_folders: // every top guild is displayed as a "folder" { color: number; - guild_ids: bigint[]; + guild_ids: string[]; id: number; name: string; }[]; - guild_positions: bigint[]; // guild ids ordered by position + guild_positions: string[]; // guild ids ordered by position inline_attachment_media: boolean; inline_embed_media: boolean; locale: string; // en_US @@ -105,7 +116,7 @@ export interface UserSettings { native_phone_integration_enabled: boolean; render_embeds: boolean; render_reactions: boolean; - restricted_guilds: bigint[]; + restricted_guilds: string[]; show_current_game: boolean; status: "online" | "offline" | "dnd" | "idle"; stream_notifications_enabled: boolean; @@ -114,11 +125,10 @@ export interface UserSettings { } export const UserSchema = new Schema({ - id: Types.Long, + id: String, username: String, discriminator: String, avatar: String, - fingerprints: [String], phone: String, desktop: Boolean, mobile: Boolean, @@ -133,9 +143,33 @@ export const UserSchema = new Schema({ email: String, flags: Types.Long, // TODO: automatically convert Types.Long to BitField of UserFlags public_flags: Types.Long, - hash: String, // hash of the password, salt is saved in password (bcrypt) - guilds: [Types.Long], // array of guild ids the user is part of - valid_tokens_since: Date, // all tokens with a previous issue date are invalid + 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: String, + nickname: String, + type: Number, + user_id: String, + }, + ], + connected_accounts: [ + { + access_token: String, + friend_sync: Boolean, + id: String, + name: String, + revoked: Boolean, + show_activity: Boolean, + type: String, + verifie: Boolean, + visibility: Number, + }, + ], + }, user_settings: { afk_timeout: Number, allow_accessibility_detection: Boolean, @@ -144,7 +178,7 @@ export const UserSchema = new Schema({ contact_sync_enabled: Boolean, convert_emoticons: Boolean, custom_status: { - emoji_id: Types.Long, + emoji_id: String, emoji_name: String, expires_at: Number, text: String, @@ -162,12 +196,12 @@ export const UserSchema = new Schema({ guild_folders: [ { color: Number, - guild_ids: [Types.Long], + guild_ids: [String], id: Number, name: String, }, ], - guild_positions: [Types.Long], // guild ids ordered by position + guild_positions: [String], // guild ids ordered by position inline_attachment_media: Boolean, inline_embed_media: Boolean, locale: String, // en_US @@ -175,34 +209,14 @@ export const UserSchema = new Schema({ native_phone_integration_enabled: Boolean, render_embeds: Boolean, render_reactions: Boolean, - restricted_guilds: [Types.Long], + restricted_guilds: [String], show_current_game: Boolean, status: String, stream_notifications_enabled: Boolean, theme: String, // dark timezone_offset: Number, // e.g -60, }, - relationships: [ - { - id: Types.Long, - nickname: String, - type: Number, - user_id: Types.Long, - }, - ], - connected_accounts: [ - { - access_token: String, - friend_sync: Boolean, - id: String, - name: String, - revoked: Boolean, - show_activity: Boolean, - type: String, - verifie: Boolean, - visibility: Number, - }, - ], + presence: { status: String, activities: [Activity], diff --git a/src/models/VoiceState.ts b/src/models/VoiceState.ts index 30439feb..c1f90edd 100644 --- a/src/models/VoiceState.ts +++ b/src/models/VoiceState.ts @@ -3,9 +3,9 @@ import { Schema, model, Types, Document } from "mongoose"; import db from "../util/Database"; export interface VoiceState extends Document { - guild_id?: bigint; - channel_id: bigint; - user_id: bigint; + guild_id?: string; + channel_id: string; + user_id: string; session_id: string; deaf: boolean; mute: boolean; @@ -17,9 +17,9 @@ export interface VoiceState extends Document { } export const VoiceSateSchema = new Schema({ - guild_id: Types.Long, - channel_id: Types.Long, - user_id: Types.Long, + guild_id: String, + channel_id: String, + user_id: String, session_id: String, deaf: Boolean, mute: Boolean, diff --git a/src/models/index.ts b/src/models/index.ts new file mode 100644 index 00000000..876e5984 --- /dev/null +++ b/src/models/index.ts @@ -0,0 +1,36 @@ +import mongoose from "mongoose"; +import { Schema } from "mongoose"; +import mongooseAutoPopulate from "mongoose-autopopulate"; + +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]; + }); + }, + }); +}); + +export * from "./Ban"; +export * from "./Channel"; +export * from "./Emoji"; +export * from "./Guild"; +export * from "./Invite"; +export * from "./Member"; +export * from "./Role"; +export * from "./User"; +export * from "./Activity"; +export * from "./Application"; +export * from "./Interaction"; +export * from "./Message"; +export * from "./Status"; +export * from "./VoiceState"; +export * from "./Event"; diff --git a/src/util/Database.ts b/src/util/Database.ts index 2304378c..5d9afab9 100644 --- a/src/util/Database.ts +++ b/src/util/Database.ts @@ -1,13 +1,26 @@ import "./MongoBigInt"; -import mongoose, { Collection, Connection } from "mongoose"; +import mongoose, { Collection, Connection, LeanDocument } from "mongoose"; import { ChangeStream, ChangeEvent, Long } from "mongodb"; import EventEmitter from "events"; +import { Document } from "mongoose"; const uri = process.env.MONGO_URL || "mongodb://localhost:27017/fosscord?readPreference=secondaryPreferred"; -const connection = mongoose.createConnection(uri, { autoIndex: true }); +console.log(`[DB] connect: ${uri}`); + +const connection = mongoose.createConnection(uri, { autoIndex: true, useNewUrlParser: true, useUnifiedTopology: true }); export default <Connection>connection; +function transform<T>(document: T) { + // @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); +} + export interface MongooseCache { on(event: "delete", listener: (id: string) => void): this; on(event: "change", listener: (data: any) => void): this; @@ -29,7 +42,8 @@ export class MongooseCache extends EventEmitter { super(); } - async init() { + init = async () => { + // @ts-ignore this.stream = this.collection.watch(this.pipeline, { fullDocument: "updateLookup" }); this.stream.on("change", this.change); @@ -40,9 +54,9 @@ export class MongooseCache extends EventEmitter { const arr = await this.collection.aggregate(this.pipeline).toArray(); this.data = arr.length ? arr[0] : arr; } - } + }; - convertResult(obj: any) { + convertResult = (obj: any) => { if (obj instanceof Long) return BigInt(obj.toString()); if (typeof obj === "object") { Object.keys(obj).forEach((key) => { @@ -51,40 +65,44 @@ export class MongooseCache extends EventEmitter { } return obj; - } + }; change = (doc: ChangeEvent) => { - // @ts-ignore - if (doc.fullDocument) { + try { // @ts-ignore - if (!this.opts.onlyEvents) this.data = doc.fullDocument; - } + if (doc.fullDocument) { + // @ts-ignore + if (!this.opts.onlyEvents) this.data = doc.fullDocument; + } - switch (doc.operationType) { - case "dropDatabase": - return this.destroy(); - case "drop": - return this.destroy(); - case "delete": - return this.emit("delete", doc.documentKey._id.toHexString()); - case "insert": - return this.emit("insert", doc.fullDocument); - case "update": - case "replace": - return this.emit("change", doc.fullDocument); - case "invalidate": - return this.destroy(); - default: - return; + switch (doc.operationType) { + case "dropDatabase": + return this.destroy(); + case "drop": + return this.destroy(); + case "delete": + return this.emit("delete", doc.documentKey._id.toHexString()); + case "insert": + return this.emit("insert", doc.fullDocument); + case "update": + case "replace": + return this.emit("change", doc.fullDocument); + case "invalidate": + return this.destroy(); + default: + return; + } + } catch (error) { + this.emit("error", error); } }; - destroy() { - this.stream.off("change", this.change); + destroy = () => { + this.stream?.off("change", this.change); this.emit("close"); if (this.stream.isClosed()) return; return this.stream.close(); - } + }; } diff --git a/src/util/Permissions.ts b/src/util/Permissions.ts index 88a54954..c7a41594 100644 --- a/src/util/Permissions.ts +++ b/src/util/Permissions.ts @@ -131,7 +131,7 @@ export class Permissions extends BitField { guild, channel, }: { - user: { id: bigint; roles: bigint[] }; + user: { id: string; roles: string[] }; guild: { roles: Role[] }; channel?: { overwrites?: ChannelPermissionOverwrite[]; @@ -154,22 +154,24 @@ export class Permissions extends BitField { } export async function getPermission( - user_id: bigint, - guild_id: bigint, - channel_id?: bigint, - cache?: { channel?: ChannelDocument | null; member?: MemberDocument | null } + user_id: string, + guild_id: string, + channel_id?: string, + cache?: { channel?: ChannelDocument | null; member?: MemberDocument | null; guild?: GuildDocument | null } ) { - var { channel, member } = cache || {}; + var { channel, member, guild } = cache || {}; - const guild = await GuildModel.findOne({ id: guild_id }, { owner_id: true }).exec(); + if (!guild) guild = await GuildModel.findOne({ id: guild_id }, { owner_id: true }).exec(); if (!guild) throw new Error("Guild not found"); if (guild.owner_id === user_id) return new Permissions(Permissions.FLAGS.ADMINISTRATOR); - member = await MemberModel.findOne({ guild_id, id: user_id }, "roles").exec(); + if (!member) member = await MemberModel.findOne({ guild_id, id: user_id }, "roles").exec(); if (!member) throw new Error("Member not found"); - var roles = await RoleModel.find({ guild_id, id: { $in: member.roles } }).exec(); - if (channel_id) { + var roles = await RoleModel.find({ guild_id, id: { $in: member.roles } }) + .lean() + .exec(); + if (channel_id && !channel) { channel = await ChannelModel.findOne({ id: channel_id }, "permission_overwrites").exec(); } diff --git a/src/util/Snowflake.ts b/src/util/Snowflake.ts index 9e94bbd9..1ccae43c 100644 --- a/src/util/Snowflake.ts +++ b/src/util/Snowflake.ts @@ -87,7 +87,7 @@ export class Snowflake { var worker = Snowflake.workerId << 17n; var process = Snowflake.processId << 12n; var increment = Snowflake.INCREMENT++; - return time | worker | process | increment; + return (time | worker | process | increment).toString(); } /** diff --git a/src/util/index.ts b/src/util/index.ts new file mode 100644 index 00000000..b0c7fe62 --- /dev/null +++ b/src/util/index.ts @@ -0,0 +1,7 @@ +export * from "./String"; +export * from "./BitField"; +export * from "./Intents"; +export * from "./MessageFlags"; +export * from "./Permissions"; +export * from "./Snowflake"; +export * from "./UserFlags"; |