mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-22 10:22:39 +01:00
✨ util
This commit is contained in:
parent
271e439b1a
commit
62b6ba4002
3
util/.gitignore
vendored
3
util/.gitignore
vendored
@ -104,4 +104,5 @@ typings/
|
||||
.DS_Store
|
||||
|
||||
# Compiled TypeScript code
|
||||
dist/
|
||||
dist/
|
||||
database.db
|
@ -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[];
|
||||
}
|
@ -1,220 +0,0 @@
|
||||
import { Schema, Document, Types } from "mongoose";
|
||||
import db from "../util/Database";
|
||||
import { ChannelPermissionOverwrite } from "./Channel";
|
||||
import { PublicUser } from "./User";
|
||||
|
||||
export interface AuditLogResponse {
|
||||
webhooks: []; // TODO:
|
||||
users: PublicUser[];
|
||||
audit_log_entries: AuditLogEntries[];
|
||||
integrations: []; // TODO:
|
||||
}
|
||||
|
||||
export interface AuditLogEntries {
|
||||
target_id?: string;
|
||||
user_id: string;
|
||||
id: string;
|
||||
action_type: AuditLogEvents;
|
||||
options?: {
|
||||
delete_member_days?: string;
|
||||
members_removed?: string;
|
||||
channel_id?: string;
|
||||
messaged_id?: string;
|
||||
count?: string;
|
||||
id?: string;
|
||||
type?: string;
|
||||
role_name?: string;
|
||||
};
|
||||
changes: AuditLogChange[];
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export interface AuditLogChange {
|
||||
new_value?: AuditLogChangeValue;
|
||||
old_value?: AuditLogChangeValue;
|
||||
key: string;
|
||||
}
|
||||
|
||||
export interface AuditLogChangeValue {
|
||||
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?: ChannelPermissionOverwrite[];
|
||||
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 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,
|
||||
}
|
@ -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");
|
@ -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
|
||||
}
|
@ -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");
|
@ -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");
|
@ -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");
|
@ -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;
|
||||
}
|
@ -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");
|
@ -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");
|
@ -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");
|
@ -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");
|
@ -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,
|
||||
}
|
@ -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");
|
@ -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");
|
@ -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");
|
@ -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 "../models/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 "../models/Status";
|
||||
export * from "./Role";
|
||||
export * from "./User";
|
||||
export * from "./VoiceState";
|
||||
export * from "./ReadState";
|
||||
export * from "./RateLimit";
|
7846
util/package-lock.json
generated
7846
util/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
19501
util/schema.json
19501
util/schema.json
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,10 @@
|
||||
import "reflect-metadata";
|
||||
|
||||
// export * as Constants from "../util/Constants";
|
||||
export * from "./models/index";
|
||||
// export * from "../util/index";
|
||||
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";
|
||||
|
@ -1,14 +1,3 @@
|
||||
import { User } from "./User";
|
||||
import { ClientStatus, Status } from "./Status";
|
||||
|
||||
export interface Presence {
|
||||
user: User;
|
||||
guild_id?: string;
|
||||
status: Status;
|
||||
activities: Activity[];
|
||||
client_status: ClientStatus;
|
||||
}
|
||||
|
||||
export interface Activity {
|
||||
name: string;
|
||||
type: ActivityType;
|
@ -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 "../models/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;
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
import { AllowedMentions, Embed } from "./Message";
|
||||
import { AllowedMentions, Embed } from "../entities/Message";
|
||||
|
||||
export interface Interaction {
|
||||
id: string;
|
10
util/src/interfaces/Presence.ts
Normal file
10
util/src/interfaces/Presence.ts
Normal file
@ -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;
|
||||
}
|
5
util/src/interfaces/index.ts
Normal file
5
util/src/interfaces/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export * from "./Activity";
|
||||
export * from "./Presence";
|
||||
export * from "./Interaction";
|
||||
export * from "./Event";
|
||||
export * from "./Status";
|
@ -1,30 +0,0 @@
|
||||
import "reflect-metadata";
|
||||
import { BaseEntity, BeforeInsert, BeforeUpdate, Column, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { Snowflake } from "../util/Snowflake";
|
||||
import { IsString, validateOrReject } from "class-validator";
|
||||
|
||||
export class BaseClass extends BaseEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
@Column()
|
||||
@IsString()
|
||||
id: string;
|
||||
|
||||
constructor(props?: any, opts: { id?: string } = {}) {
|
||||
super();
|
||||
this.id = opts.id || Snowflake.generate();
|
||||
Object.defineProperties(this, props);
|
||||
}
|
||||
|
||||
@BeforeUpdate()
|
||||
@BeforeInsert()
|
||||
async validate() {
|
||||
await validateOrReject(this, {});
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
global.BaseClass = BaseClass;
|
||||
|
||||
var test = new BaseClass({});
|
||||
|
||||
setTimeout(() => {}, 10000 * 1000);
|
@ -1,209 +0,0 @@
|
||||
import { Column, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
|
||||
import { Activity } from "./Activity";
|
||||
import { BaseClass } from "./BaseClass";
|
||||
import { ClientStatus, Status } from "./Status";
|
||||
import { validateOrReject, IsInt, IsEmail, IsPhoneNumber, IsBoolean, IsString, ValidateNested } from "class-validator";
|
||||
|
||||
export const PublicUserProjection = {
|
||||
username: true,
|
||||
discriminator: true,
|
||||
id: true,
|
||||
public_flags: true,
|
||||
avatar: true,
|
||||
accent_color: true,
|
||||
banner: true,
|
||||
bio: true,
|
||||
bot: true,
|
||||
};
|
||||
|
||||
export class User extends BaseClass {
|
||||
@Column()
|
||||
@IsString()
|
||||
username: string; // username max length 32, min 2 (should be configurable)
|
||||
|
||||
@Column()
|
||||
@IsInt()
|
||||
discriminator: string; // #0001 4 digit long string from #0001 - #9999
|
||||
|
||||
@Column()
|
||||
@IsString()
|
||||
avatar: string | null; // hash of the user avatar
|
||||
|
||||
@Column()
|
||||
@IsInt()
|
||||
accent_color: number | null; // banner color of user
|
||||
|
||||
@Column()
|
||||
banner: string | null; // hash of the user banner
|
||||
|
||||
@Column()
|
||||
@IsPhoneNumber()
|
||||
phone: string | null; // phone number of the user
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
desktop: boolean; // if the user has desktop app installed
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
mobile: boolean; // if the user has mobile app installed
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
premium: boolean; // if user bought nitro
|
||||
|
||||
@Column()
|
||||
premium_type: number; // nitro level
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
bot: boolean; // if user is bot
|
||||
|
||||
@Column()
|
||||
bio: string; // short description of the user (max 190 chars -> should be configurable)
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
system: boolean; // shouldn't be used, the api sents this field type true, if the generated message comes from a system generated author
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
nsfw_allowed: boolean; // if the user is older than 18 (resp. Config)
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
mfa_enabled: boolean; // if multi factor authentication is enabled
|
||||
|
||||
@Column()
|
||||
created_at: Date; // registration date
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
verified: boolean; // if the user is offically verified
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
disabled: boolean; // if the account is disabled
|
||||
|
||||
@Column()
|
||||
@IsBoolean()
|
||||
deleted: boolean; // if the user was deleted
|
||||
|
||||
@Column()
|
||||
@IsEmail()
|
||||
email: string | null; // email of the user
|
||||
|
||||
@Column()
|
||||
flags: bigint; // UserFlags
|
||||
|
||||
@Column()
|
||||
public_flags: bigint;
|
||||
|
||||
@Column("simple-array") // string in simple-array must not contain commas
|
||||
@IsString({ each: true })
|
||||
guilds: string[]; // array of guild ids the user is part of
|
||||
|
||||
@Column("simple-json")
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
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")
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
presence: {
|
||||
status: Status;
|
||||
activities: Activity[];
|
||||
client_status: ClientStatus;
|
||||
};
|
||||
|
||||
@Column("simple-json")
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
relationships: {
|
||||
id: string;
|
||||
nickname?: string;
|
||||
type: RelationshipType;
|
||||
}[];
|
||||
|
||||
@Column("simple-json")
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
connected_accounts: {
|
||||
access_token: string;
|
||||
friend_sync: boolean;
|
||||
id: string;
|
||||
name: string;
|
||||
revoked: boolean;
|
||||
show_activity: boolean;
|
||||
type: string;
|
||||
verifie: boolean;
|
||||
visibility: number;
|
||||
}[];
|
||||
|
||||
@Column("simple-json")
|
||||
@ValidateNested() // TODO: https://github.com/typestack/class-validator#validating-nested-objects
|
||||
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 | 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
|
||||
};
|
||||
}
|
||||
|
||||
// Private user data that should never get sent to the client
|
||||
export interface PublicUser {
|
||||
id: string;
|
||||
discriminator: string;
|
||||
username: string;
|
||||
avatar: string | null;
|
||||
accent_color: number;
|
||||
banner: string | null;
|
||||
public_flags: bigint;
|
||||
bot: boolean;
|
||||
}
|
||||
|
||||
export enum RelationshipType {
|
||||
outgoing = 4,
|
||||
incoming = 3,
|
||||
blocked = 2,
|
||||
friends = 1,
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
export * from "./Activity";
|
||||
export * from "./BaseClass";
|
||||
export * from "./Status";
|
||||
export * from "./User";
|
@ -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);
|
||||
|
@ -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,
|
||||
}
|
25
util/src/util/Database.ts
Normal file
25
util/src/util/Database.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import "reflect-metadata";
|
||||
import { createConnection } from "typeorm";
|
||||
import * as Models from "../entities";
|
||||
|
||||
// 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
|
||||
|
||||
var promise: Promise<any>;
|
||||
|
||||
export function initDatabase() {
|
||||
if (promise) return promise; // prevent initalizing multiple times
|
||||
|
||||
// @ts-ignore
|
||||
promise = createConnection({
|
||||
type: "sqlite",
|
||||
database: "database.db",
|
||||
entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"),
|
||||
synchronize: true,
|
||||
logging: false,
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
initDatabase();
|
@ -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">) {
|
@ -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({
|
||||
|
@ -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`);
|
||||
},
|
||||
};
|
||||
|
@ -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),
|
||||
};
|
||||
}
|
@ -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");
|
||||
|
@ -1,11 +1,11 @@
|
||||
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";
|
@ -5,7 +5,7 @@
|
||||
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"target": "ES6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||
"lib": ["ES2020"] /* Specify library files to be included in the compilation. */,
|
||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||
@ -68,6 +68,7 @@
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"resolveJsonModule": true,
|
||||
"plugins": [
|
||||
{
|
||||
"transform": "ts-transform-json-schema",
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Schema, model, Types, Document } from "mongoose";
|
||||
import "missing-native-js-functions";
|
||||
import db from "./Database";
|
||||
import { Snowflake } from "./Snowflake";
|
||||
import crypto from "crypto";
|
||||
|
||||
@ -8,7 +7,7 @@ var config: any;
|
||||
|
||||
export default {
|
||||
init: async function init(defaultOpts: any = DefaultOptions) {
|
||||
config = await db.collection("config").findOne({});
|
||||
config = await db.collection("config").findOneOrFail({});
|
||||
return this.set((config || {}).merge(defaultOpts));
|
||||
},
|
||||
get: function get() {
|
||||
@ -16,7 +15,7 @@ export default {
|
||||
},
|
||||
set: function set(val: any) {
|
||||
config = val.merge(config);
|
||||
return db.collection("config").updateOne({}, { $set: val }, { upsert: true });
|
||||
return db.collection("config").update({}, { $set: val }, { upsert: true });
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
import "reflect-metadata";
|
||||
import { createConnection } from "typeorm";
|
||||
|
||||
// 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
|
||||
|
||||
createConnection({ type: "sqlite", database: "database.db", entities: [], synchronize: true, logging: true });
|
@ -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;
|
Loading…
Reference in New Issue
Block a user