✨ mongoose Schemas
This commit is contained in:
parent
f572c7142b
commit
8595646b72
3
package-lock.json
generated
3
package-lock.json
generated
@ -11,7 +11,8 @@
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lambert-db": "^1.1.7",
|
||||
"missing-native-js-functions": "^1.2.2"
|
||||
"missing-native-js-functions": "^1.2.2",
|
||||
"mongodb": "^3.6.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
|
@ -22,7 +22,8 @@
|
||||
"dependencies": {
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lambert-db": "^1.1.7",
|
||||
"missing-native-js-functions": "^1.2.2"
|
||||
"missing-native-js-functions": "^1.2.2",
|
||||
"mongodb": "^3.6.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { User } from "..";
|
||||
import { ClientStatus, Status } from "./Status";
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface Presence {
|
||||
user: User;
|
||||
@ -45,6 +46,44 @@ export interface Activity {
|
||||
flags?: bigint;
|
||||
}
|
||||
|
||||
export const Activity = {
|
||||
name: String,
|
||||
type: Number,
|
||||
url: String,
|
||||
created_at: Number,
|
||||
timestamps: [
|
||||
{
|
||||
start: Number,
|
||||
end: Number,
|
||||
},
|
||||
],
|
||||
application_id: Types.Long,
|
||||
details: String,
|
||||
state: String,
|
||||
emoji: {
|
||||
name: String,
|
||||
id: Types.Long,
|
||||
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: Types.Long,
|
||||
};
|
||||
|
||||
export enum ActivityType {
|
||||
GAME = 0,
|
||||
STREAMING = 1,
|
||||
|
@ -1,19 +1,44 @@
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface ChannelDocument extends Channel, DMChannel, TextChannel, VoiceChannel, Document {
|
||||
id: bigint;
|
||||
}
|
||||
|
||||
export const ChannelSchema = new Schema({
|
||||
id: Types.Long,
|
||||
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],
|
||||
position: Number,
|
||||
last_message_id: Types.Long,
|
||||
last_pin_timestamp: Date,
|
||||
nsfw: Boolean,
|
||||
rate_limit_per_user: Number,
|
||||
topic: String,
|
||||
permission_overwrites: [
|
||||
{
|
||||
allow: Types.Long,
|
||||
deny: Types.Long,
|
||||
id: Types.Long,
|
||||
type: Number,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const ChannelModel = model<ChannelDocument>("Channel", ChannelSchema, "channels");
|
||||
|
||||
export interface Channel {
|
||||
id: bigint;
|
||||
created_at: number;
|
||||
name: string;
|
||||
type: number;
|
||||
read_state: ReadState[];
|
||||
}
|
||||
|
||||
export interface ReadState {
|
||||
last_message_id: bigint;
|
||||
last_pin_timestamp: number;
|
||||
mention_count: number;
|
||||
}
|
||||
|
||||
export interface TextBasedChannel {
|
||||
messages: any[];
|
||||
last_message_id?: bigint;
|
||||
last_pin_timestamp?: number;
|
||||
}
|
||||
|
@ -1,12 +1,27 @@
|
||||
export interface Emoji {
|
||||
allNamesString: string; // e.g. :thonk:
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface Emoji extends Document {
|
||||
id: bigint;
|
||||
animated: boolean;
|
||||
available: boolean;
|
||||
guildId: bigint;
|
||||
id: bigint;
|
||||
guild_id: bigint;
|
||||
managed: boolean;
|
||||
name: string;
|
||||
require_colons: boolean;
|
||||
url: string;
|
||||
roles: [];
|
||||
roles: bigint[]; // roles this emoji is whitelisted to
|
||||
}
|
||||
|
||||
export const EmojiSchema = new Schema({
|
||||
id: Types.Long,
|
||||
animated: Boolean,
|
||||
available: Boolean,
|
||||
guild_id: Types.Long,
|
||||
managed: Boolean,
|
||||
name: String,
|
||||
require_colons: Boolean,
|
||||
url: String,
|
||||
roles: [Types.Long],
|
||||
});
|
||||
|
||||
export const EmojiModel = model<Emoji>("Emoji", EmojiSchema, "emojis");
|
||||
|
@ -10,8 +10,9 @@ import { Message, PartialEmoji } from "./Message";
|
||||
import { VoiceState } from "./VoiceState";
|
||||
import { ApplicationCommand } from "./Application";
|
||||
import { Interaction } from "./Interaction";
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface Event {
|
||||
export interface Event extends Document {
|
||||
guild_id?: bigint;
|
||||
user_id?: bigint;
|
||||
channel_id?: bigint;
|
||||
@ -20,6 +21,17 @@ export interface Event {
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export const EventSchema = new Schema({
|
||||
guild_id: Types.Long,
|
||||
user_id: Types.Long,
|
||||
channel_id: Types.Long,
|
||||
created_at: { type: Number, required: true },
|
||||
event: { type: String, required: true },
|
||||
data: Object,
|
||||
});
|
||||
|
||||
export const EventModel = model<Event>("Event", EventSchema, "events");
|
||||
|
||||
// ! Custom Events that shouldn't get sent to the client but processed by the server
|
||||
|
||||
export interface InvalidatedEvent extends Event {
|
||||
@ -120,7 +132,10 @@ export interface GuildUpdateEvent extends Event {
|
||||
|
||||
export interface GuildDeleteEvent extends Event {
|
||||
event: "GUILD_DELETE";
|
||||
data: Guild;
|
||||
data: {
|
||||
id: bigint;
|
||||
unavailable?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GuildBanAddEvent extends Event {
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { GuildChannel } from "./Channel";
|
||||
import { Emoji } from "./Emoji";
|
||||
import { Member } from "./Member";
|
||||
import { Role } from "./Role";
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface Guild {
|
||||
export interface Guild extends Document {
|
||||
id: bigint;
|
||||
afk_channel_id?: bigint;
|
||||
afk_timeout?: number;
|
||||
application_id?: bigint;
|
||||
@ -11,12 +9,9 @@ export interface Guild {
|
||||
default_message_notifications?: number;
|
||||
description?: string;
|
||||
discovery_splash?: string;
|
||||
emojis: Emoji[];
|
||||
explicit_content_filter?: number;
|
||||
features: string[];
|
||||
icon?: string;
|
||||
id: bigint;
|
||||
// joined_at?: number; \n // owner?: boolean; // ! member specific should be removed
|
||||
large?: boolean;
|
||||
max_members?: number; // e.g. default 100.000
|
||||
max_presences?: number;
|
||||
@ -24,8 +19,9 @@ export interface Guild {
|
||||
member_count?: number;
|
||||
presence_count?: number; // users online
|
||||
// members?: Member[]; // * Members are stored in a seperate collection
|
||||
// roles: Role[]; // * Role are stroed in a seperate collection
|
||||
// channels: GuildChannel[]; // * Channels are stroed 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
|
||||
mfa_level?: number;
|
||||
name: string;
|
||||
owner_id: bigint;
|
||||
@ -46,3 +42,44 @@ export interface Guild {
|
||||
widget_channel_id?: bigint;
|
||||
widget_enabled?: boolean;
|
||||
}
|
||||
|
||||
export const GuildSchema = new Schema({
|
||||
afk_channel_id: Types.Long,
|
||||
afk_timeout: Number,
|
||||
application_id: Types.Long,
|
||||
banner: String,
|
||||
default_message_notifications: Number,
|
||||
description: String,
|
||||
discovery_splash: String,
|
||||
explicit_content_filter: Number,
|
||||
features: { type: [String], default: [] },
|
||||
icon: String,
|
||||
id: { type: Types.Long, required: true },
|
||||
large: Boolean,
|
||||
max_members: { type: Number, default: 100000 },
|
||||
max_presences: Number,
|
||||
max_video_channel_users: { type: Number, default: 25 },
|
||||
member_count: Number,
|
||||
presence_count: Number,
|
||||
mfa_level: Number,
|
||||
name: { type: String, required: true },
|
||||
owner_id: { type: Types.Long, required: true },
|
||||
preferred_locale: String,
|
||||
premium_subscription_count: Number,
|
||||
premium_tier: Number,
|
||||
public_updates_channel_id: Types.Long,
|
||||
region: String,
|
||||
rules_channel_id: Types.Long,
|
||||
splash: String,
|
||||
system_channel_flags: Number,
|
||||
system_channel_id: Types.Long,
|
||||
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_enabled: Boolean,
|
||||
});
|
||||
|
||||
export const GuildModel = model<Guild>("Guild", GuildSchema, "guilds");
|
||||
|
@ -1,4 +1,6 @@
|
||||
export interface Invite {
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface Invite extends Document {
|
||||
code: string;
|
||||
temporary: boolean;
|
||||
uses: number;
|
||||
@ -19,7 +21,6 @@ export interface Invite {
|
||||
name: string;
|
||||
type: number;
|
||||
};
|
||||
|
||||
inviter: {
|
||||
id: bigint;
|
||||
username: string;
|
||||
@ -34,3 +35,42 @@ export interface Invite {
|
||||
};
|
||||
target_user_type: number;
|
||||
}
|
||||
|
||||
export const InviteSchema = new Schema({
|
||||
code: String,
|
||||
temporary: Boolean,
|
||||
uses: Number,
|
||||
max_uses: Number,
|
||||
max_age: Number,
|
||||
created_at: Number,
|
||||
guild: {
|
||||
id: Types.Long,
|
||||
name: String,
|
||||
splash: String,
|
||||
description: String,
|
||||
icon: String,
|
||||
features: Object,
|
||||
verification_level: Number,
|
||||
},
|
||||
channel: {
|
||||
id: Types.Long,
|
||||
name: String,
|
||||
type: Number,
|
||||
},
|
||||
|
||||
inviter: {
|
||||
id: Types.Long,
|
||||
username: String,
|
||||
avatar: String,
|
||||
discriminator: Number,
|
||||
},
|
||||
target_user: {
|
||||
id: Types.Long,
|
||||
username: String,
|
||||
avatar: String,
|
||||
discriminator: Number,
|
||||
},
|
||||
target_user_type: Number,
|
||||
});
|
||||
|
||||
export const InviteModel = model<Invite>("Invite", InviteSchema, "invites");
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { PublicUser } from "./User";
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface Member {
|
||||
export interface Member extends Document {
|
||||
id: bigint;
|
||||
nick?: string;
|
||||
roles: bigint[];
|
||||
@ -13,10 +14,6 @@ export interface Member {
|
||||
settings: UserGuildSettings;
|
||||
}
|
||||
|
||||
export interface PublicMember extends Omit<Member, "settings" | "id"> {
|
||||
user: PublicUser;
|
||||
}
|
||||
|
||||
export interface UserGuildSettings {
|
||||
channel_overrides: {
|
||||
channel_id: bigint;
|
||||
@ -37,3 +34,43 @@ 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: Types.Long,
|
||||
nick: String,
|
||||
roles: [Types.Long],
|
||||
joined_at: Number,
|
||||
premium_since: Number,
|
||||
deaf: Boolean,
|
||||
mute: Boolean,
|
||||
pending: Boolean,
|
||||
permissions: Types.Long,
|
||||
settings: {
|
||||
channel_overrides: [
|
||||
{
|
||||
channel_id: Types.Long,
|
||||
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 const MemberModel = model<Member>("Member", MemberSchema, "members");
|
||||
|
||||
export interface PublicMember extends Omit<Member, "settings" | "id"> {
|
||||
user: PublicUser;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
import { ChannelType } from "./Channel";
|
||||
|
||||
export interface Message {
|
||||
export interface Message extends Document {
|
||||
id: bigint;
|
||||
author_id?: bigint;
|
||||
webhook_id?: bigint;
|
||||
@ -27,7 +28,7 @@ export interface Message {
|
||||
activity?: {
|
||||
type: number;
|
||||
party_id: string;
|
||||
}[];
|
||||
};
|
||||
flags?: bigint;
|
||||
stickers?: [];
|
||||
message_reference?: {
|
||||
@ -124,3 +125,104 @@ export interface AllowedMentions {
|
||||
users?: bigint[];
|
||||
replied_user?: boolean;
|
||||
}
|
||||
|
||||
const Attachment = {
|
||||
id: Types.Long, // 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)
|
||||
};
|
||||
|
||||
const EmbedImage = {
|
||||
url: String,
|
||||
proxy_url: String,
|
||||
height: Number,
|
||||
width: Number,
|
||||
};
|
||||
|
||||
const Reaction = {
|
||||
count: Number,
|
||||
emoji: {
|
||||
id: Types.Long,
|
||||
name: String,
|
||||
animated: Boolean,
|
||||
},
|
||||
};
|
||||
|
||||
const Embed = {
|
||||
title: String, //title of embed
|
||||
type: String, // type of embed (always "rich" for webhook embeds)
|
||||
description: String, // description of embed
|
||||
url: String, // url of embed
|
||||
timestamp: Number, // 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: Types.Long,
|
||||
author_id: Types.Long,
|
||||
webhook_id: Types.Long,
|
||||
application_id: Types.Long,
|
||||
content: String,
|
||||
timestamp: Number,
|
||||
edited_timestamp: Number,
|
||||
tts: Boolean,
|
||||
mention_everyone: Boolean,
|
||||
mentions: [Types.Long],
|
||||
mention_roles: [Types.Long],
|
||||
mention_channels: [
|
||||
{
|
||||
id: Types.Long,
|
||||
guild_id: Types.Long,
|
||||
type: ChannelType,
|
||||
name: String,
|
||||
},
|
||||
],
|
||||
attachments: [Attachment],
|
||||
embeds: [Embed],
|
||||
reactions: [Reaction],
|
||||
nonce: Schema.Types.Mixed, // can be a long or a string
|
||||
pinned: Boolean,
|
||||
type: MessageType,
|
||||
activity: {
|
||||
type: Number,
|
||||
party_id: String,
|
||||
},
|
||||
flags: Types.Long,
|
||||
stickers: [],
|
||||
message_reference: {
|
||||
message_id: Types.Long,
|
||||
channel_id: Types.Long,
|
||||
guild_id: Types.Long,
|
||||
},
|
||||
});
|
||||
|
||||
export const MessageModel = model<Message>("Message", MessageSchema, "messages");
|
||||
|
@ -1,4 +1,6 @@
|
||||
export interface Role {
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface Role extends Document {
|
||||
id: bigint;
|
||||
color: number;
|
||||
hoist: boolean;
|
||||
@ -11,3 +13,19 @@ export interface Role {
|
||||
bot_id?: bigint;
|
||||
};
|
||||
}
|
||||
|
||||
export const RoleSchema = new Schema({
|
||||
id: Types.Long,
|
||||
color: Number,
|
||||
hoist: Boolean,
|
||||
managed: Boolean,
|
||||
mentionable: Boolean,
|
||||
name: String,
|
||||
permissions: Types.Long,
|
||||
position: Number,
|
||||
tags: {
|
||||
bot_id: Types.Long,
|
||||
},
|
||||
});
|
||||
|
||||
export const RoleModel = model<Role>("Role", RoleSchema, "roles");
|
||||
|
@ -5,3 +5,9 @@ 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,
|
||||
};
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Activity } from "./Activity";
|
||||
import { ClientStatus, Status } from "./Status";
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface User {
|
||||
export interface User extends Document {
|
||||
id: bigint;
|
||||
username: string;
|
||||
discriminator: string;
|
||||
@ -103,3 +104,100 @@ export interface UserSettings {
|
||||
theme: "dark" | "white"; // dark
|
||||
timezone_offset: number; // e.g -60
|
||||
}
|
||||
|
||||
export const UserSchema = new Schema({
|
||||
id: Types.Long,
|
||||
username: String,
|
||||
discriminator: String,
|
||||
avatar: String,
|
||||
phone: String,
|
||||
desktop: Boolean,
|
||||
mobile: Boolean,
|
||||
premium: Boolean,
|
||||
premium_type: Number,
|
||||
bot: Boolean,
|
||||
system: Boolean,
|
||||
nsfw_allowed: Boolean,
|
||||
mfa_enabled: Boolean,
|
||||
created_at: Number,
|
||||
verified: Boolean,
|
||||
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: Number, // all tokens with a previous issue date are invalid
|
||||
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: Types.Long,
|
||||
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 },
|
||||
gif_auto_play: Boolean,
|
||||
// every top guild is displayed as a "folder"
|
||||
guild_folders: [
|
||||
{
|
||||
color: Number,
|
||||
guild_ids: [Types.Long],
|
||||
id: Number,
|
||||
name: String,
|
||||
},
|
||||
],
|
||||
guild_positions: [Types.Long], // 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: [Types.Long],
|
||||
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],
|
||||
client_status: ClientStatus,
|
||||
},
|
||||
});
|
||||
|
||||
export const UserModel = model<User>("User", UserSchema, "users");
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { PublicMember } from "./Member";
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
|
||||
export interface VoiceState {
|
||||
export interface VoiceState extends Document {
|
||||
guild_id?: bigint;
|
||||
channel_id: bigint;
|
||||
user_id: bigint;
|
||||
@ -13,3 +14,19 @@ export interface VoiceState {
|
||||
self_video: boolean;
|
||||
suppress: boolean; // whether this user is muted by the current user
|
||||
}
|
||||
|
||||
export const VoiceSateSchema = new Schema({
|
||||
guild_id: Types.Long,
|
||||
channel_id: Types.Long,
|
||||
user_id: Types.Long,
|
||||
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 VoiceStateModel = model<VoiceState>("VoiceState", VoiceSateSchema, "voicestates");
|
||||
|
@ -5,6 +5,7 @@ var Config: ProviderCache;
|
||||
|
||||
export default {
|
||||
init: async function init(opts: DefaultOptions = DefaultOptions) {
|
||||
await db.collection("config").findOne({});
|
||||
Config = await db.data.config({}).cache();
|
||||
await Config.init();
|
||||
await Config.set(opts.merge(Config.cache || {}));
|
||||
|
@ -1,9 +1,89 @@
|
||||
import { MongoDatabase } from "lambert-db";
|
||||
import "./MongoBigInt";
|
||||
import mongoose, { Collection } from "mongoose";
|
||||
import { ChangeStream, ChangeEvent, Long } from "mongodb";
|
||||
import EventEmitter from "events";
|
||||
const uri = process.env.MONGO_URL || "mongodb://localhost:27017/fosscord?readPreference=secondaryPreferred";
|
||||
|
||||
// TODO: load url from config
|
||||
const db = new MongoDatabase("mongodb://127.0.0.1:27017/lambert?readPreference=secondaryPreferred", {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: false,
|
||||
});
|
||||
const connection = mongoose.createConnection(uri, { autoIndex: true });
|
||||
|
||||
export default db;
|
||||
export default connection;
|
||||
|
||||
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;
|
||||
|
||||
constructor(
|
||||
public collection: Collection,
|
||||
public pipeline: Array<Record<string, unknown>>,
|
||||
public opts: {
|
||||
onlyEvents: boolean;
|
||||
}
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async init() {
|
||||
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) {
|
||||
this.data = await this.collection.aggregate(this.pipeline).toArray();
|
||||
}
|
||||
}
|
||||
|
||||
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) => {
|
||||
// @ts-ignore
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
destroy() {
|
||||
this.stream.off("change", this.change);
|
||||
this.emit("close");
|
||||
|
||||
if (this.stream.isClosed()) return;
|
||||
|
||||
return this.stream.close();
|
||||
}
|
||||
}
|
||||
|
76
src/util/MongoBigInt.ts
Normal file
76
src/util/MongoBigInt.ts
Normal file
@ -0,0 +1,76 @@
|
||||
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);
|
||||
}
|
||||
|
||||
handleArray(val: any) {
|
||||
var self = this;
|
||||
return val.map(function (m: any) {
|
||||
return self.cast(m);
|
||||
});
|
||||
}
|
||||
|
||||
checkRequired(val: any) {
|
||||
return null != val;
|
||||
}
|
||||
|
||||
cast(val: any, scope?: any, init?: any) {
|
||||
if (null === val) return val;
|
||||
if ("" === val) return null;
|
||||
|
||||
if (val instanceof mongoose.mongo.Long) return BigInt(val.toString());
|
||||
if (val instanceof Number || "number" == typeof val) return BigInt(val);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
Loading…
x
Reference in New Issue
Block a user