cleanup rtc
This commit is contained in:
parent
90d5307a56
commit
0a08938d18
1268
rtc/package-lock.json
generated
1268
rtc/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@fosscord/server-util",
|
|
||||||
"version": "1.3.52",
|
|
||||||
"description": "Utility functions for the all server repositories",
|
|
||||||
"main": "dist/index.js",
|
|
||||||
"types": "dist/index.d.ts",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
|
||||||
"build": "tsc -b .",
|
|
||||||
"prepublish": "npm run build"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/fosscord/fosscord-server-util.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"discord",
|
|
||||||
"fosscord",
|
|
||||||
"fosscord-server-util",
|
|
||||||
"discord open source",
|
|
||||||
"discord-open-source"
|
|
||||||
],
|
|
||||||
"author": "Fosscord",
|
|
||||||
"license": "GPLV3",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/fosscord/fosscord-server-util/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://docs.fosscord.com/",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/jsonwebtoken": "^8.5.0",
|
|
||||||
"@types/mongoose-autopopulate": "^0.10.1",
|
|
||||||
"@types/mongoose-lean-virtuals": "^0.5.1",
|
|
||||||
"@types/node": "^14.14.25",
|
|
||||||
"ajv": "^8.5.0",
|
|
||||||
"amqplib": "^0.8.0",
|
|
||||||
"dot-prop": "^6.0.1",
|
|
||||||
"env-paths": "^2.2.1",
|
|
||||||
"jsonwebtoken": "^8.5.1",
|
|
||||||
"missing-native-js-functions": "^1.2.2",
|
|
||||||
"mongodb": "^3.6.9",
|
|
||||||
"mongoose": "^5.12.3",
|
|
||||||
"mongoose-autopopulate": "^0.12.3",
|
|
||||||
"typescript": "^4.1.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/amqplib": "^0.8.1"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
export * from "./util/checkToken";
|
|
||||||
|
|
||||||
export * as Constants from "./util/Constants";
|
|
||||||
export * from "./models/index";
|
|
||||||
export * from "./util/index";
|
|
||||||
|
|
||||||
import Config from "./util/Config";
|
|
||||||
import db, { MongooseCache, toObject } from "./util/Database";
|
|
||||||
|
|
||||||
export { Config, db, MongooseCache, toObject };
|
|
@ -1,132 +0,0 @@
|
|||||||
import { User } from "..";
|
|
||||||
import { ClientStatus, Status } from "./Status";
|
|
||||||
import { Schema, model, Types, Document } from "mongoose";
|
|
||||||
import toBigInt from "../util/toBigInt";
|
|
||||||
|
|
||||||
export interface Presence {
|
|
||||||
user: User;
|
|
||||||
guild_id?: string;
|
|
||||||
status: Status;
|
|
||||||
activities: Activity[];
|
|
||||||
client_status: ClientStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Activity {
|
|
||||||
name: string;
|
|
||||||
type: ActivityType;
|
|
||||||
url?: string;
|
|
||||||
created_at?: Date;
|
|
||||||
timestamps?: {
|
|
||||||
start?: number;
|
|
||||||
end?: number;
|
|
||||||
}[];
|
|
||||||
application_id?: string;
|
|
||||||
details?: string;
|
|
||||||
state?: string;
|
|
||||||
emoji?: {
|
|
||||||
name: string;
|
|
||||||
id?: string;
|
|
||||||
amimated?: boolean;
|
|
||||||
};
|
|
||||||
party?: {
|
|
||||||
id?: string;
|
|
||||||
size?: [number, number];
|
|
||||||
};
|
|
||||||
assets?: {
|
|
||||||
large_image?: string;
|
|
||||||
large_text?: string;
|
|
||||||
small_image?: string;
|
|
||||||
small_text?: string;
|
|
||||||
};
|
|
||||||
secrets?: {
|
|
||||||
join?: string;
|
|
||||||
spectate?: string;
|
|
||||||
match?: string;
|
|
||||||
};
|
|
||||||
instance?: boolean;
|
|
||||||
flags?: bigint;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ActivitySchema = {
|
|
||||||
name: { type: String, required: true },
|
|
||||||
type: { type: Number, required: true },
|
|
||||||
url: String,
|
|
||||||
created_at: Date,
|
|
||||||
timestamps: [
|
|
||||||
{
|
|
||||||
start: Number,
|
|
||||||
end: Number,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
application_id: String,
|
|
||||||
details: String,
|
|
||||||
state: String,
|
|
||||||
emoji: {
|
|
||||||
name: String,
|
|
||||||
id: String,
|
|
||||||
amimated: Boolean,
|
|
||||||
},
|
|
||||||
party: {
|
|
||||||
id: String,
|
|
||||||
size: [Number, Number],
|
|
||||||
},
|
|
||||||
assets: {
|
|
||||||
large_image: String,
|
|
||||||
large_text: String,
|
|
||||||
small_image: String,
|
|
||||||
small_text: String,
|
|
||||||
},
|
|
||||||
secrets: {
|
|
||||||
join: String,
|
|
||||||
spectate: String,
|
|
||||||
match: String,
|
|
||||||
},
|
|
||||||
instance: Boolean,
|
|
||||||
flags: { type: String, get: toBigInt },
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ActivityBodySchema = {
|
|
||||||
name: String,
|
|
||||||
type: Number,
|
|
||||||
$url: String,
|
|
||||||
$created_at: Date,
|
|
||||||
$timestamps: [
|
|
||||||
{
|
|
||||||
$start: Number,
|
|
||||||
$end: Number,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
$application_id: String,
|
|
||||||
$details: String,
|
|
||||||
$state: String,
|
|
||||||
$emoji: {
|
|
||||||
$name: String,
|
|
||||||
$id: String,
|
|
||||||
$amimated: Boolean,
|
|
||||||
},
|
|
||||||
$party: {
|
|
||||||
$id: String,
|
|
||||||
$size: [Number, Number],
|
|
||||||
},
|
|
||||||
$assets: {
|
|
||||||
$large_image: String,
|
|
||||||
$large_text: String,
|
|
||||||
$small_image: String,
|
|
||||||
$small_text: String,
|
|
||||||
},
|
|
||||||
$secrets: {
|
|
||||||
$join: String,
|
|
||||||
$spectate: String,
|
|
||||||
$match: String,
|
|
||||||
},
|
|
||||||
$instance: Boolean,
|
|
||||||
$flags: BigInt,
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum ActivityType {
|
|
||||||
GAME = 0,
|
|
||||||
STREAMING = 1,
|
|
||||||
LISTENING = 2,
|
|
||||||
CUSTOM = 4,
|
|
||||||
COMPETING = 5,
|
|
||||||
}
|
|
@ -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,109 +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,
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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,540 +0,0 @@
|
|||||||
import { ConnectedAccount, PublicUser, Relationship, User, UserSettings } from "./User";
|
|
||||||
import { DMChannel, Channel } from "./Channel";
|
|
||||||
import { Guild } from "./Guild";
|
|
||||||
import { Member, PublicMember, UserGuildSettings } from "./Member";
|
|
||||||
import { Emoji } from "./Emoji";
|
|
||||||
import { Presence } from "./Activity";
|
|
||||||
import { Role } from "./Role";
|
|
||||||
import { Invite } from "./Invite";
|
|
||||||
import { Message, PartialEmoji } from "./Message";
|
|
||||||
import { VoiceState } from "./VoiceState";
|
|
||||||
import { ApplicationCommand } from "./Application";
|
|
||||||
import { Interaction } from "./Interaction";
|
|
||||||
import { Schema, model, Types, Document } from "mongoose";
|
|
||||||
import db from "../util/Database";
|
|
||||||
|
|
||||||
export interface Event {
|
|
||||||
guild_id?: string;
|
|
||||||
user_id?: string;
|
|
||||||
channel_id?: string;
|
|
||||||
created_at?: Date;
|
|
||||||
event: EVENT;
|
|
||||||
data?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EventDocument extends Event, Document {}
|
|
||||||
|
|
||||||
export const EventSchema = new Schema({
|
|
||||||
guild_id: String,
|
|
||||||
user_id: String,
|
|
||||||
channel_id: String,
|
|
||||||
created_at: { type: Date, required: true },
|
|
||||||
event: { type: String, required: true },
|
|
||||||
data: Object,
|
|
||||||
});
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
export const EventModel = db.model<EventDocument>("Event", EventSchema, "events");
|
|
||||||
|
|
||||||
// ! Custom Events that shouldn't get sent to the client but processed by the server
|
|
||||||
|
|
||||||
export interface InvalidatedEvent extends Event {
|
|
||||||
event: "INVALIDATED";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ! END Custom Events that shouldn't get sent to the client but processed by the server
|
|
||||||
|
|
||||||
export interface ReadyEventData {
|
|
||||||
v: number;
|
|
||||||
user: PublicUser & {
|
|
||||||
mobile: boolean;
|
|
||||||
desktop: boolean;
|
|
||||||
email: string | null;
|
|
||||||
flags: bigint;
|
|
||||||
mfa_enabled: boolean;
|
|
||||||
nsfw_allowed: boolean;
|
|
||||||
phone: string | null;
|
|
||||||
premium: boolean;
|
|
||||||
premium_type: number;
|
|
||||||
verified: boolean;
|
|
||||||
bot: boolean;
|
|
||||||
};
|
|
||||||
private_channels: DMChannel[]; // this will be empty for bots
|
|
||||||
session_id: string; // resuming
|
|
||||||
guilds: Guild[];
|
|
||||||
analytics_token?: string;
|
|
||||||
connected_accounts?: ConnectedAccount[];
|
|
||||||
consents?: {
|
|
||||||
personalization?: {
|
|
||||||
consented?: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
country_code?: string; // e.g. DE
|
|
||||||
friend_suggestion_count?: number;
|
|
||||||
geo_ordered_rtc_regions?: string[]; // ["europe","russie","india","us-east","us-central"]
|
|
||||||
experiments?: [number, number, number, number, number][];
|
|
||||||
guild_experiments?: [
|
|
||||||
// ? what are guild_experiments?
|
|
||||||
// this is the structure of it:
|
|
||||||
number,
|
|
||||||
null,
|
|
||||||
number,
|
|
||||||
[[number, { e: number; s: number }[]]],
|
|
||||||
[number, [[number, [number, number]]]],
|
|
||||||
{ b: number; k: bigint[] }[]
|
|
||||||
][];
|
|
||||||
guild_join_requests?: []; // ? what is this? this is new
|
|
||||||
shard?: [number, number];
|
|
||||||
user_settings?: UserSettings;
|
|
||||||
relationships?: Relationship[]; // TODO
|
|
||||||
read_state: {
|
|
||||||
entries: []; // TODO
|
|
||||||
partial: boolean;
|
|
||||||
version: number;
|
|
||||||
};
|
|
||||||
user_guild_settings?: {
|
|
||||||
entries: UserGuildSettings[];
|
|
||||||
version: number;
|
|
||||||
partial: boolean;
|
|
||||||
};
|
|
||||||
application?: {
|
|
||||||
id: string;
|
|
||||||
flags: bigint;
|
|
||||||
};
|
|
||||||
merged_members?: Omit<Member, "settings" | "user">[][];
|
|
||||||
// probably all users who the user is in contact with
|
|
||||||
users?: {
|
|
||||||
avatar: string | null;
|
|
||||||
discriminator: string;
|
|
||||||
id: string;
|
|
||||||
username: string;
|
|
||||||
bot: boolean;
|
|
||||||
public_flags: bigint;
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ReadyEvent extends Event {
|
|
||||||
event: "READY";
|
|
||||||
data: ReadyEventData;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ChannelCreateEvent extends Event {
|
|
||||||
event: "CHANNEL_CREATE";
|
|
||||||
data: Channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ChannelUpdateEvent extends Event {
|
|
||||||
event: "CHANNEL_UPDATE";
|
|
||||||
data: Channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ChannelDeleteEvent extends Event {
|
|
||||||
event: "CHANNEL_DELETE";
|
|
||||||
data: Channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ChannelPinsUpdateEvent extends Event {
|
|
||||||
event: "CHANNEL_PINS_UPDATE";
|
|
||||||
data: {
|
|
||||||
guild_id?: string;
|
|
||||||
channel_id: string;
|
|
||||||
last_pin_timestamp?: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildCreateEvent extends Event {
|
|
||||||
event: "GUILD_CREATE";
|
|
||||||
data: Guild;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildUpdateEvent extends Event {
|
|
||||||
event: "GUILD_UPDATE";
|
|
||||||
data: Guild;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildDeleteEvent extends Event {
|
|
||||||
event: "GUILD_DELETE";
|
|
||||||
data: {
|
|
||||||
id: string;
|
|
||||||
unavailable?: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildBanAddEvent extends Event {
|
|
||||||
event: "GUILD_BAN_ADD";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
user: User;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildBanRemoveEvent extends Event {
|
|
||||||
event: "GUILD_BAN_REMOVE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
user: User;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildEmojiUpdateEvent extends Event {
|
|
||||||
event: "GUILD_EMOJI_UPDATE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
emojis: Emoji[];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildIntegrationUpdateEvent extends Event {
|
|
||||||
event: "GUILD_INTEGRATIONS_UPDATE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildMemberAddEvent extends Event {
|
|
||||||
event: "GUILD_MEMBER_ADD";
|
|
||||||
data: PublicMember & {
|
|
||||||
guild_id: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildMemberRemoveEvent extends Event {
|
|
||||||
event: "GUILD_MEMBER_REMOVE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
user: User;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildMemberUpdateEvent extends Event {
|
|
||||||
event: "GUILD_MEMBER_UPDATE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
roles: string[];
|
|
||||||
user: User;
|
|
||||||
nick?: string;
|
|
||||||
joined_at?: Date;
|
|
||||||
premium_since?: number;
|
|
||||||
pending?: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildMembersChunkEvent extends Event {
|
|
||||||
event: "GUILD_MEMBERS_CHUNK";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
members: PublicMember[];
|
|
||||||
chunk_index: number;
|
|
||||||
chunk_count: number;
|
|
||||||
not_found: string[];
|
|
||||||
presences: Presence[];
|
|
||||||
nonce?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildRoleCreateEvent extends Event {
|
|
||||||
event: "GUILD_ROLE_CREATE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
role: Role;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildRoleUpdateEvent extends Event {
|
|
||||||
event: "GUILD_ROLE_UPDATE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
role: Role;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GuildRoleDeleteEvent extends Event {
|
|
||||||
event: "GUILD_ROLE_DELETE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
role_id: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InviteCreateEvent extends Event {
|
|
||||||
event: "INVITE_CREATE";
|
|
||||||
data: Omit<Invite, "guild" | "channel"> & {
|
|
||||||
channel_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InviteDeleteEvent extends Event {
|
|
||||||
event: "INVITE_DELETE";
|
|
||||||
data: {
|
|
||||||
channel_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
code: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export type MessagePayload = Omit<Message, "author_id"> & {
|
|
||||||
channel_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
author: PublicUser;
|
|
||||||
member: PublicMember;
|
|
||||||
mentions: (PublicUser & { member: PublicMember })[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface MessageCreateEvent extends Event {
|
|
||||||
event: "MESSAGE_CREATE";
|
|
||||||
data: MessagePayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageUpdateEvent extends Event {
|
|
||||||
event: "MESSAGE_UPDATE";
|
|
||||||
data: MessagePayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageDeleteEvent extends Event {
|
|
||||||
event: "MESSAGE_DELETE";
|
|
||||||
data: {
|
|
||||||
id: string;
|
|
||||||
channel_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageDeleteBulkEvent extends Event {
|
|
||||||
event: "MESSAGE_DELETE_BULK";
|
|
||||||
data: {
|
|
||||||
ids: string[];
|
|
||||||
channel_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageReactionAddEvent extends Event {
|
|
||||||
event: "MESSAGE_REACTION_ADD";
|
|
||||||
data: {
|
|
||||||
user_id: string;
|
|
||||||
channel_id: string;
|
|
||||||
message_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
member?: PublicMember;
|
|
||||||
emoji: PartialEmoji;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageReactionRemoveEvent extends Event {
|
|
||||||
event: "MESSAGE_REACTION_REMOVE";
|
|
||||||
data: {
|
|
||||||
user_id: string;
|
|
||||||
channel_id: string;
|
|
||||||
message_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
emoji: PartialEmoji;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageReactionRemoveAllEvent extends Event {
|
|
||||||
event: "MESSAGE_REACTION_REMOVE_ALL";
|
|
||||||
data: {
|
|
||||||
channel_id: string;
|
|
||||||
message_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageReactionRemoveEmojiEvent extends Event {
|
|
||||||
event: "MESSAGE_REACTION_REMOVE_EMOJI";
|
|
||||||
data: {
|
|
||||||
channel_id: string;
|
|
||||||
message_id: string;
|
|
||||||
guild_id?: string;
|
|
||||||
emoji: PartialEmoji;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PresenceUpdateEvent extends Event {
|
|
||||||
event: "PRESENCE_UPDATE";
|
|
||||||
data: Presence;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TypingStartEvent extends Event {
|
|
||||||
event: "TYPING_START";
|
|
||||||
data: {
|
|
||||||
channel_id: string;
|
|
||||||
user_id: string;
|
|
||||||
timestamp: number;
|
|
||||||
guild_id?: string;
|
|
||||||
member?: PublicMember;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserUpdateEvent extends Event {
|
|
||||||
event: "USER_UPDATE";
|
|
||||||
data: User;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VoiceStateUpdateEvent extends Event {
|
|
||||||
event: "VOICE_STATE_UPDATE";
|
|
||||||
data: VoiceState & {
|
|
||||||
member: PublicMember;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VoiceServerUpdateEvent extends Event {
|
|
||||||
event: "VOICE_SERVER_UPDATE";
|
|
||||||
data: {
|
|
||||||
token: string;
|
|
||||||
guild_id: string;
|
|
||||||
endpoint: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WebhooksUpdateEvent extends Event {
|
|
||||||
event: "WEBHOOKS_UPDATE";
|
|
||||||
data: {
|
|
||||||
guild_id: string;
|
|
||||||
channel_id: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ApplicationCommandPayload = ApplicationCommand & {
|
|
||||||
guild_id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface ApplicationCommandCreateEvent extends Event {
|
|
||||||
event: "APPLICATION_COMMAND_CREATE";
|
|
||||||
data: ApplicationCommandPayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ApplicationCommandUpdateEvent extends Event {
|
|
||||||
event: "APPLICATION_COMMAND_UPDATE";
|
|
||||||
data: ApplicationCommandPayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ApplicationCommandDeleteEvent extends Event {
|
|
||||||
event: "APPLICATION_COMMAND_DELETE";
|
|
||||||
data: ApplicationCommandPayload;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InteractionCreateEvent extends Event {
|
|
||||||
event: "INTERACTION_CREATE";
|
|
||||||
data: Interaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MessageAckEvent extends Event {
|
|
||||||
event: "MESSAGE_ACK";
|
|
||||||
data: {
|
|
||||||
channel_id: string;
|
|
||||||
message_id: string;
|
|
||||||
version?: number;
|
|
||||||
manual?: boolean;
|
|
||||||
mention_count?: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RelationshipAddEvent extends Event {
|
|
||||||
event: "RELATIONSHIP_ADD";
|
|
||||||
data: Relationship & {
|
|
||||||
should_notify?: boolean;
|
|
||||||
user: PublicUser;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RelationshipRemoveEvent extends Event {
|
|
||||||
event: "RELATIONSHIP_REMOVE";
|
|
||||||
data: Omit<Relationship, "nickname">;
|
|
||||||
}
|
|
||||||
|
|
||||||
// located in collection events
|
|
||||||
|
|
||||||
export enum EVENTEnum {
|
|
||||||
Ready = "READY",
|
|
||||||
ChannelCreate = "CHANNEL_CREATE",
|
|
||||||
ChannelUpdate = "CHANNEL_UPDATE",
|
|
||||||
ChannelDelete = "CHANNEL_DELETE",
|
|
||||||
ChannelPinsUpdate = "CHANNEL_PINS_UPDATE",
|
|
||||||
GuildCreate = "GUILD_CREATE",
|
|
||||||
GuildUpdate = "GUILD_UPDATE",
|
|
||||||
GuildDelete = "GUILD_DELETE",
|
|
||||||
GuildBanAdd = "GUILD_BAN_ADD",
|
|
||||||
GuildBanRemove = "GUILD_BAN_REMOVE",
|
|
||||||
GuildEmojUpdate = "GUILD_EMOJI_UPDATE",
|
|
||||||
GuildIntegrationsUpdate = "GUILD_INTEGRATIONS_UPDATE",
|
|
||||||
GuildMemberAdd = "GUILD_MEMBER_ADD",
|
|
||||||
GuildMemberRempve = "GUILD_MEMBER_REMOVE",
|
|
||||||
GuildMemberUpdate = "GUILD_MEMBER_UPDATE",
|
|
||||||
GuildMemberSpeaking = "GUILD_MEMBER_SPEAKING",
|
|
||||||
GuildMembersChunk = "GUILD_MEMBERS_CHUNK",
|
|
||||||
GuildRoleCreate = "GUILD_ROLE_CREATE",
|
|
||||||
GuildRoleDelete = "GUILD_ROLE_DELETE",
|
|
||||||
GuildRoleUpdate = "GUILD_ROLE_UPDATE",
|
|
||||||
InviteCreate = "INVITE_CREATE",
|
|
||||||
InviteDelete = "INVITE_DELETE",
|
|
||||||
MessageCreate = "MESSAGE_CREATE",
|
|
||||||
MessageUpdate = "MESSAGE_UPDATE",
|
|
||||||
MessageDelete = "MESSAGE_DELETE",
|
|
||||||
MessageDeleteBulk = "MESSAGE_DELETE_BULK",
|
|
||||||
MessageReactionAdd = "MESSAGE_REACTION_ADD",
|
|
||||||
MessageReactionRemove = "MESSAGE_REACTION_REMOVE",
|
|
||||||
MessageReactionRemoveAll = "MESSAGE_REACTION_REMOVE_ALL",
|
|
||||||
MessageReactionRemoveEmoji = "MESSAGE_REACTION_REMOVE_EMOJI",
|
|
||||||
PresenceUpdate = "PRESENCE_UPDATE",
|
|
||||||
TypingStart = "TYPING_START",
|
|
||||||
UserUpdate = "USER_UPDATE",
|
|
||||||
WebhooksUpdate = "WEBHOOKS_UPDATE",
|
|
||||||
InteractionCreate = "INTERACTION_CREATE",
|
|
||||||
VoiceStateUpdate = "VOICE_STATE_UPDATE",
|
|
||||||
VoiceServerUpdate = "VOICE_SERVER_UPDATE",
|
|
||||||
ApplicationCommandCreate = "APPLICATION_COMMAND_CREATE",
|
|
||||||
ApplicationCommandUpdate = "APPLICATION_COMMAND_UPDATE",
|
|
||||||
ApplicationCommandDelete = "APPLICATION_COMMAND_DELETE",
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EVENT =
|
|
||||||
| "READY"
|
|
||||||
| "CHANNEL_CREATE"
|
|
||||||
| "CHANNEL_UPDATE"
|
|
||||||
| "CHANNEL_DELETE"
|
|
||||||
| "CHANNEL_PINS_UPDATE"
|
|
||||||
| "GUILD_CREATE"
|
|
||||||
| "GUILD_UPDATE"
|
|
||||||
| "GUILD_DELETE"
|
|
||||||
| "GUILD_BAN_ADD"
|
|
||||||
| "GUILD_BAN_REMOVE"
|
|
||||||
| "GUILD_EMOJI_UPDATE"
|
|
||||||
| "GUILD_INTEGRATIONS_UPDATE"
|
|
||||||
| "GUILD_MEMBER_ADD"
|
|
||||||
| "GUILD_MEMBER_REMOVE"
|
|
||||||
| "GUILD_MEMBER_UPDATE"
|
|
||||||
| "GUILD_MEMBER_SPEAKING"
|
|
||||||
| "GUILD_MEMBERS_CHUNK"
|
|
||||||
| "GUILD_ROLE_CREATE"
|
|
||||||
| "GUILD_ROLE_DELETE"
|
|
||||||
| "GUILD_ROLE_UPDATE"
|
|
||||||
| "INVITE_CREATE"
|
|
||||||
| "INVITE_DELETE"
|
|
||||||
| "MESSAGE_CREATE"
|
|
||||||
| "MESSAGE_UPDATE"
|
|
||||||
| "MESSAGE_DELETE"
|
|
||||||
| "MESSAGE_DELETE_BULK"
|
|
||||||
| "MESSAGE_REACTION_ADD"
|
|
||||||
// TODO: add a new event: bulk add reaction:
|
|
||||||
// | "MESSAGE_REACTION_BULK_ADD"
|
|
||||||
| "MESSAGE_REACTION_REMOVE"
|
|
||||||
| "MESSAGE_REACTION_REMOVE_ALL"
|
|
||||||
| "MESSAGE_REACTION_REMOVE_EMOJI"
|
|
||||||
| "PRESENCE_UPDATE"
|
|
||||||
| "TYPING_START"
|
|
||||||
| "USER_UPDATE"
|
|
||||||
| "WEBHOOKS_UPDATE"
|
|
||||||
| "INTERACTION_CREATE"
|
|
||||||
| "VOICE_STATE_UPDATE"
|
|
||||||
| "VOICE_SERVER_UPDATE"
|
|
||||||
| "APPLICATION_COMMAND_CREATE"
|
|
||||||
| "APPLICATION_COMMAND_UPDATE"
|
|
||||||
| "APPLICATION_COMMAND_DELETE"
|
|
||||||
| "MESSAGE_ACK"
|
|
||||||
| "RELATIONSHIP_ADD"
|
|
||||||
| "RELATIONSHIP_REMOVE"
|
|
||||||
| CUSTOMEVENTS;
|
|
||||||
|
|
||||||
export type CUSTOMEVENTS = "INVALIDATED";
|
|
@ -1,161 +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;
|
|
||||||
uses: number;
|
|
||||||
};
|
|
||||||
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,
|
|
||||||
uses: Number
|
|
||||||
},
|
|
||||||
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,32 +0,0 @@
|
|||||||
import { AllowedMentions, Embed } from "./Message";
|
|
||||||
|
|
||||||
export interface Interaction {
|
|
||||||
id: string;
|
|
||||||
type: InteractionType;
|
|
||||||
data?: {};
|
|
||||||
guild_id: string;
|
|
||||||
channel_id: string;
|
|
||||||
member_id: string;
|
|
||||||
token: string;
|
|
||||||
version: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum InteractionType {
|
|
||||||
Ping = 1,
|
|
||||||
ApplicationCommand = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum InteractionResponseType {
|
|
||||||
Pong = 1,
|
|
||||||
Acknowledge = 2,
|
|
||||||
ChannelMessage = 3,
|
|
||||||
ChannelMessageWithSource = 4,
|
|
||||||
AcknowledgeWithSource = 5,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InteractionApplicationCommandCallbackData {
|
|
||||||
tts?: boolean;
|
|
||||||
content: string;
|
|
||||||
embeds?: Embed[];
|
|
||||||
allowed_mentions?: AllowedMentions;
|
|
||||||
}
|
|
@ -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,13 +0,0 @@
|
|||||||
export type Status = "idle" | "dnd" | "online" | "offline";
|
|
||||||
|
|
||||||
export interface ClientStatus {
|
|
||||||
desktop?: string; // e.g. Windows/Linux/Mac
|
|
||||||
mobile?: string; // e.g. iOS/Android
|
|
||||||
web?: string; // e.g. browser, bot account
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ClientStatus = {
|
|
||||||
desktop: String,
|
|
||||||
mobile: String,
|
|
||||||
web: String,
|
|
||||||
};
|
|
@ -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,252 +0,0 @@
|
|||||||
import { Activity, ActivitySchema } from "./Activity";
|
|
||||||
import { ClientStatus, Status } from "./Status";
|
|
||||||
import { Schema, Types, Document } from "mongoose";
|
|
||||||
import db from "../util/Database";
|
|
||||||
import toBigInt from "../util/toBigInt";
|
|
||||||
|
|
||||||
export const PublicUserProjection = {
|
|
||||||
username: true,
|
|
||||||
discriminator: true,
|
|
||||||
id: true,
|
|
||||||
public_flags: true,
|
|
||||||
avatar: true,
|
|
||||||
accent_color: true,
|
|
||||||
banner: true,
|
|
||||||
bio: true,
|
|
||||||
bot: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface User {
|
|
||||||
id: string;
|
|
||||||
username: string; // username max length 32, min 2
|
|
||||||
discriminator: string; // #0001 4 digit long string from #0001 - #9999
|
|
||||||
avatar: string | null; // hash of the user avatar
|
|
||||||
accent_color: number | null; // banner color of user
|
|
||||||
banner: string | null;
|
|
||||||
phone: string | null; // phone number of the user
|
|
||||||
desktop: boolean; // if the user has desktop app installed
|
|
||||||
mobile: boolean; // if the user has mobile app installed
|
|
||||||
premium: boolean; // if user bought nitro
|
|
||||||
premium_type: number; // nitro level
|
|
||||||
bot: boolean; // if user is bot
|
|
||||||
bio: string; // short description of the user (max 190 chars)
|
|
||||||
system: boolean; // shouldn't be used, the api sents this field type true, if the genetaed message comes from a system generated author
|
|
||||||
nsfw_allowed: boolean; // if the user is older than 18 (resp. Config)
|
|
||||||
mfa_enabled: boolean; // if multi factor authentication is enabled
|
|
||||||
created_at: Date; // registration date
|
|
||||||
verified: boolean; // if the user is offically verified
|
|
||||||
disabled: boolean; // if the account is disabled
|
|
||||||
deleted: boolean; // if the user was deleted
|
|
||||||
email: string | null; // email of the user
|
|
||||||
flags: bigint; // UserFlags
|
|
||||||
public_flags: bigint;
|
|
||||||
user_settings: UserSettings;
|
|
||||||
guilds: string[]; // array of guild ids the user is part of
|
|
||||||
user_data: UserData;
|
|
||||||
presence: {
|
|
||||||
status: Status;
|
|
||||||
activities: Activity[];
|
|
||||||
client_status: ClientStatus;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private user data:
|
|
||||||
export interface UserData {
|
|
||||||
valid_tokens_since: Date; // all tokens with a previous issue date are invalid
|
|
||||||
relationships: Relationship[];
|
|
||||||
connected_accounts: ConnectedAccount[];
|
|
||||||
hash: string; // hash of the password, salt is saved in password (bcrypt)
|
|
||||||
fingerprints: string[]; // array of fingerprints -> used to prevent multiple accounts
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserDocument extends User, Document {
|
|
||||||
id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PublicUser {
|
|
||||||
id: string;
|
|
||||||
discriminator: string;
|
|
||||||
username: string;
|
|
||||||
avatar: string | null;
|
|
||||||
accent_color: number;
|
|
||||||
banner: string | null;
|
|
||||||
public_flags: bigint;
|
|
||||||
bot: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ConnectedAccount {
|
|
||||||
access_token: string;
|
|
||||||
friend_sync: boolean;
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
revoked: boolean;
|
|
||||||
show_activity: boolean;
|
|
||||||
type: string;
|
|
||||||
verifie: boolean;
|
|
||||||
visibility: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Relationship {
|
|
||||||
id: string;
|
|
||||||
nickname?: string;
|
|
||||||
type: RelationshipType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum RelationshipType {
|
|
||||||
outgoing = 4,
|
|
||||||
incoming = 3,
|
|
||||||
blocked = 2,
|
|
||||||
friends = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserSettings {
|
|
||||||
afk_timeout: number;
|
|
||||||
allow_accessibility_detection: boolean;
|
|
||||||
animate_emoji: boolean;
|
|
||||||
animate_stickers: number;
|
|
||||||
contact_sync_enabled: boolean;
|
|
||||||
convert_emoticons: boolean;
|
|
||||||
custom_status: {
|
|
||||||
emoji_id: string | null;
|
|
||||||
emoji_name: string | null;
|
|
||||||
expires_at: number | null;
|
|
||||||
text: string | null;
|
|
||||||
};
|
|
||||||
default_guilds_restricted: boolean;
|
|
||||||
detect_platform_accounts: boolean;
|
|
||||||
developer_mode: boolean;
|
|
||||||
disable_games_tab: boolean;
|
|
||||||
enable_tts_command: boolean;
|
|
||||||
explicit_content_filter: number;
|
|
||||||
friend_source_flags: { all: boolean };
|
|
||||||
gateway_connected: boolean;
|
|
||||||
gif_auto_play: boolean;
|
|
||||||
guild_folders: // every top guild is displayed as a "folder"
|
|
||||||
{
|
|
||||||
color: number;
|
|
||||||
guild_ids: string[];
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
}[];
|
|
||||||
guild_positions: string[]; // guild ids ordered by position
|
|
||||||
inline_attachment_media: boolean;
|
|
||||||
inline_embed_media: boolean;
|
|
||||||
locale: string; // en_US
|
|
||||||
message_display_compact: boolean;
|
|
||||||
native_phone_integration_enabled: boolean;
|
|
||||||
render_embeds: boolean;
|
|
||||||
render_reactions: boolean;
|
|
||||||
restricted_guilds: string[];
|
|
||||||
show_current_game: boolean;
|
|
||||||
status: "online" | "offline" | "dnd" | "idle";
|
|
||||||
stream_notifications_enabled: boolean;
|
|
||||||
theme: "dark" | "white"; // dark
|
|
||||||
timezone_offset: number; // e.g -60
|
|
||||||
}
|
|
||||||
|
|
||||||
export const UserSchema = new Schema({
|
|
||||||
id: String,
|
|
||||||
username: String,
|
|
||||||
discriminator: String,
|
|
||||||
avatar: String,
|
|
||||||
accent_color: Number,
|
|
||||||
banner: String,
|
|
||||||
phone: String,
|
|
||||||
desktop: Boolean,
|
|
||||||
mobile: Boolean,
|
|
||||||
premium: Boolean,
|
|
||||||
premium_type: Number,
|
|
||||||
bot: Boolean,
|
|
||||||
bio: String,
|
|
||||||
system: Boolean,
|
|
||||||
nsfw_allowed: Boolean,
|
|
||||||
mfa_enabled: Boolean,
|
|
||||||
created_at: Date,
|
|
||||||
verified: Boolean,
|
|
||||||
disabled: Boolean,
|
|
||||||
deleted: Boolean,
|
|
||||||
email: String,
|
|
||||||
flags: { type: String, get: toBigInt }, // TODO: automatically convert Types.Long to BitField of UserFlags
|
|
||||||
public_flags: { type: String, get: toBigInt },
|
|
||||||
guilds: [String], // array of guild ids the user is part of
|
|
||||||
user_data: {
|
|
||||||
fingerprints: [String],
|
|
||||||
hash: String, // hash of the password, salt is saved in password (bcrypt)
|
|
||||||
valid_tokens_since: Date, // all tokens with a previous issue date are invalid
|
|
||||||
relationships: [
|
|
||||||
{
|
|
||||||
id: { type: String, required: true },
|
|
||||||
nickname: String,
|
|
||||||
type: { type: Number },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
connected_accounts: [
|
|
||||||
{
|
|
||||||
access_token: String,
|
|
||||||
friend_sync: Boolean,
|
|
||||||
id: String,
|
|
||||||
name: String,
|
|
||||||
revoked: Boolean,
|
|
||||||
show_activity: Boolean,
|
|
||||||
type: { type: String },
|
|
||||||
verifie: Boolean,
|
|
||||||
visibility: Number,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
user_settings: {
|
|
||||||
afk_timeout: Number,
|
|
||||||
allow_accessibility_detection: Boolean,
|
|
||||||
animate_emoji: Boolean,
|
|
||||||
animate_stickers: Number,
|
|
||||||
contact_sync_enabled: Boolean,
|
|
||||||
convert_emoticons: Boolean,
|
|
||||||
custom_status: {
|
|
||||||
emoji_id: String,
|
|
||||||
emoji_name: String,
|
|
||||||
expires_at: Number,
|
|
||||||
text: String,
|
|
||||||
},
|
|
||||||
default_guilds_restricted: Boolean,
|
|
||||||
detect_platform_accounts: Boolean,
|
|
||||||
developer_mode: Boolean,
|
|
||||||
disable_games_tab: Boolean,
|
|
||||||
enable_tts_command: Boolean,
|
|
||||||
explicit_content_filter: Number,
|
|
||||||
friend_source_flags: { all: Boolean },
|
|
||||||
gateway_connected: Boolean,
|
|
||||||
gif_auto_play: Boolean,
|
|
||||||
// every top guild is displayed as a "folder"
|
|
||||||
guild_folders: [
|
|
||||||
{
|
|
||||||
color: Number,
|
|
||||||
guild_ids: [String],
|
|
||||||
id: Number,
|
|
||||||
name: String,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
guild_positions: [String], // guild ids ordered by position
|
|
||||||
inline_attachment_media: Boolean,
|
|
||||||
inline_embed_media: Boolean,
|
|
||||||
locale: String, // en_US
|
|
||||||
message_display_compact: Boolean,
|
|
||||||
native_phone_integration_enabled: Boolean,
|
|
||||||
render_embeds: Boolean,
|
|
||||||
render_reactions: Boolean,
|
|
||||||
restricted_guilds: [String],
|
|
||||||
show_current_game: Boolean,
|
|
||||||
status: String,
|
|
||||||
stream_notifications_enabled: Boolean,
|
|
||||||
theme: String, // dark
|
|
||||||
timezone_offset: Number, // e.g -60,
|
|
||||||
},
|
|
||||||
|
|
||||||
presence: {
|
|
||||||
status: String,
|
|
||||||
activities: [ActivitySchema],
|
|
||||||
client_status: ClientStatus,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
export const UserModel = db.model<UserDocument>("User", UserSchema, "users");
|
|
@ -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,89 +0,0 @@
|
|||||||
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 Model<T, TQueryHelpers = {}, TMethods = {}> {
|
|
||||||
// removed null -> always return document -> throw error if it doesn't exist
|
|
||||||
findOne(
|
|
||||||
filter?: FilterQuery<T>,
|
|
||||||
projection?: any | null,
|
|
||||||
options?: QueryOptions | null,
|
|
||||||
callback?: (err: CallbackError, doc: EnforceDocument<T, TMethods>) => void
|
|
||||||
): QueryWithHelpers<EnforceDocument<T, TMethods>, EnforceDocument<T, TMethods>, TQueryHelpers>;
|
|
||||||
findOneAndUpdate(
|
|
||||||
filter?: FilterQuery<T>,
|
|
||||||
update?: UpdateQuery<T> | UpdateWithAggregationPipeline,
|
|
||||||
options?: QueryOptions | null,
|
|
||||||
callback?: (err: any, doc: EnforceDocument<T, TMethods> | null, res: any) => void
|
|
||||||
): QueryWithHelpers<EnforceDocument<T, TMethods>, EnforceDocument<T, TMethods>, TQueryHelpers>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var HTTPError: any;
|
|
||||||
|
|
||||||
try {
|
|
||||||
HTTPError = require("lambert-server").HTTPError;
|
|
||||||
} catch (e) {
|
|
||||||
HTTPError = Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
mongoose.plugin(mongooseAutoPopulate);
|
|
||||||
|
|
||||||
mongoose.plugin((schema: Schema, opts: any) => {
|
|
||||||
schema.set("toObject", {
|
|
||||||
virtuals: true,
|
|
||||||
versionKey: false,
|
|
||||||
transform(doc: any, ret: any) {
|
|
||||||
delete ret._id;
|
|
||||||
delete ret.__v;
|
|
||||||
const props = schema.get("removeResponse") || [];
|
|
||||||
props.forEach((prop: string) => {
|
|
||||||
delete ret[prop];
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
schema.post("findOne", function (doc, next) {
|
|
||||||
try {
|
|
||||||
// @ts-ignore
|
|
||||||
const isExistsQuery = JSON.stringify(this._userProvidedFields) === JSON.stringify({ _id: 1 });
|
|
||||||
if (!doc && !isExistsQuery) {
|
|
||||||
// @ts-ignore
|
|
||||||
return next(new HTTPError(`${this?.mongooseCollection?.name}.${this?._conditions?.id} not found`, 400));
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
return next();
|
|
||||||
} catch (error) {
|
|
||||||
// @ts-ignore
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
export * from "./Activity";
|
|
||||||
export * from "./Application";
|
|
||||||
export * from "./Ban";
|
|
||||||
export * from "./Channel";
|
|
||||||
export * from "./Emoji";
|
|
||||||
export * from "./Event";
|
|
||||||
export * from "./Template";
|
|
||||||
export * from "./Guild";
|
|
||||||
export * from "./Invite";
|
|
||||||
export * from "./Interaction";
|
|
||||||
export * from "./Member";
|
|
||||||
export * from "./Message";
|
|
||||||
export * from "./Status";
|
|
||||||
export * from "./Role";
|
|
||||||
export * from "./User";
|
|
||||||
export * from "./VoiceState";
|
|
||||||
export * from "./ReadState";
|
|
||||||
export * from "./RateLimit";
|
|
@ -1,143 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
// https://github.com/discordjs/discord.js/blob/master/src/util/BitField.js
|
|
||||||
// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah
|
|
||||||
|
|
||||||
export type BitFieldResolvable = number | BigInt | BitField | string | BitFieldResolvable[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data structure that makes it easy to interact with a bitfield.
|
|
||||||
*/
|
|
||||||
export class BitField {
|
|
||||||
public bitfield: bigint = BigInt(0);
|
|
||||||
|
|
||||||
public static FLAGS: Record<string, bigint> = {};
|
|
||||||
|
|
||||||
constructor(bits: BitFieldResolvable = 0) {
|
|
||||||
this.bitfield = BitField.resolve.call(this, bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this bitfield equals another
|
|
||||||
*/
|
|
||||||
equals(bit: BitFieldResolvable): boolean {
|
|
||||||
return this.bitfield === BitField.resolve.call(this, bit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the bitfield has a bit, or multiple bits.
|
|
||||||
*/
|
|
||||||
has(bit: BitFieldResolvable): boolean {
|
|
||||||
if (Array.isArray(bit)) return bit.every((p) => this.has(p));
|
|
||||||
const BIT = BitField.resolve.call(this, bit);
|
|
||||||
return (this.bitfield & BIT) === BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all given bits that are missing from the bitfield.
|
|
||||||
*/
|
|
||||||
missing(bits: BitFieldResolvable) {
|
|
||||||
if (!Array.isArray(bits)) bits = new BitField(bits).toArray();
|
|
||||||
return bits.filter((p) => !this.has(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Freezes these bits, making them immutable.
|
|
||||||
*/
|
|
||||||
freeze(): Readonly<BitField> {
|
|
||||||
return Object.freeze(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds bits to these ones.
|
|
||||||
* @param {...BitFieldResolvable} [bits] Bits to add
|
|
||||||
* @returns {BitField} These bits or new BitField if the instance is frozen.
|
|
||||||
*/
|
|
||||||
add(...bits: BitFieldResolvable[]): BitField {
|
|
||||||
let total = 0n;
|
|
||||||
for (const bit of bits) {
|
|
||||||
total |= BitField.resolve.call(this, bit);
|
|
||||||
}
|
|
||||||
if (Object.isFrozen(this)) return new BitField(this.bitfield | total);
|
|
||||||
this.bitfield |= total;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes bits from these.
|
|
||||||
* @param {...BitFieldResolvable} [bits] Bits to remove
|
|
||||||
*/
|
|
||||||
remove(...bits: BitFieldResolvable[]) {
|
|
||||||
let total = 0n;
|
|
||||||
for (const bit of bits) {
|
|
||||||
total |= BitField.resolve.call(this, bit);
|
|
||||||
}
|
|
||||||
if (Object.isFrozen(this)) return new BitField(this.bitfield & ~total);
|
|
||||||
this.bitfield &= ~total;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets an object mapping field names to a {@link boolean} indicating whether the
|
|
||||||
* bit is available.
|
|
||||||
* @param {...*} hasParams Additional parameters for the has method, if any
|
|
||||||
*/
|
|
||||||
serialize() {
|
|
||||||
const serialized: Record<string, boolean> = {};
|
|
||||||
for (const [flag, bit] of Object.entries(BitField.FLAGS)) serialized[flag] = this.has(bit);
|
|
||||||
return serialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets an {@link Array} of bitfield names based on the bits available.
|
|
||||||
*/
|
|
||||||
toArray(): string[] {
|
|
||||||
return Object.keys(BitField.FLAGS).filter((bit) => this.has(bit));
|
|
||||||
}
|
|
||||||
|
|
||||||
toJSON() {
|
|
||||||
return this.bitfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
valueOf() {
|
|
||||||
return this.bitfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
*[Symbol.iterator]() {
|
|
||||||
yield* this.toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Data that can be resolved to give a bitfield. This can be:
|
|
||||||
* * A bit number (this can be a number literal or a value taken from {@link BitField.FLAGS})
|
|
||||||
* * An instance of BitField
|
|
||||||
* * An Array of BitFieldResolvable
|
|
||||||
* @typedef {number|BitField|BitFieldResolvable[]} BitFieldResolvable
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves bitfields to their numeric form.
|
|
||||||
* @param {BitFieldResolvable} [bit=0] - bit(s) to resolve
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
static resolve(bit: BitFieldResolvable = 0n): bigint {
|
|
||||||
// @ts-ignore
|
|
||||||
const FLAGS = this.FLAGS || this.constructor?.FLAGS;
|
|
||||||
if ((typeof bit === "number" || typeof bit === "bigint") && bit >= 0n) 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);
|
|
||||||
}
|
|
||||||
if (typeof bit === "string" && typeof FLAGS[bit] !== "undefined") return FLAGS[bit];
|
|
||||||
throw new RangeError("BITFIELD_INVALID: " + bit);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,284 +0,0 @@
|
|||||||
import { Schema, model, Types, Document } from "mongoose";
|
|
||||||
import "missing-native-js-functions";
|
|
||||||
import db, { MongooseCache } from "./Database";
|
|
||||||
import { Snowflake } from "./Snowflake";
|
|
||||||
import crypto from "crypto";
|
|
||||||
|
|
||||||
var config: any;
|
|
||||||
|
|
||||||
export default {
|
|
||||||
init: async function init(defaultOpts: any = DefaultOptions) {
|
|
||||||
config = await db.collection("config").findOne({});
|
|
||||||
return this.set((config || {}).merge(defaultOpts));
|
|
||||||
},
|
|
||||||
get: function get() {
|
|
||||||
return config as DefaultOptions;
|
|
||||||
},
|
|
||||||
set: function set(val: any) {
|
|
||||||
return db.collection("config").updateOne({}, { $set: val }, { upsert: true });
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface RateLimitOptions {
|
|
||||||
bot?: number;
|
|
||||||
count: number;
|
|
||||||
window: number;
|
|
||||||
onyIp?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Region {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
vip: boolean;
|
|
||||||
custom: boolean;
|
|
||||||
deprecated: boolean;
|
|
||||||
optimal: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface KafkaBroker {
|
|
||||||
ip: string;
|
|
||||||
port: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DefaultOptions {
|
|
||||||
gateway: {
|
|
||||||
endpoint: string | null;
|
|
||||||
};
|
|
||||||
cdn: {
|
|
||||||
endpoint: string | null;
|
|
||||||
};
|
|
||||||
general: {
|
|
||||||
instance_id: string;
|
|
||||||
};
|
|
||||||
permissions: {
|
|
||||||
user: {
|
|
||||||
createGuilds: boolean;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
limits: {
|
|
||||||
user: {
|
|
||||||
maxGuilds: number;
|
|
||||||
maxUsername: number;
|
|
||||||
maxFriends: number;
|
|
||||||
};
|
|
||||||
guild: {
|
|
||||||
maxRoles: number;
|
|
||||||
maxMembers: number;
|
|
||||||
maxChannels: number;
|
|
||||||
maxChannelsInCategory: number;
|
|
||||||
hideOfflineMember: number;
|
|
||||||
};
|
|
||||||
message: {
|
|
||||||
maxCharacters: number;
|
|
||||||
maxTTSCharacters: number;
|
|
||||||
maxReactions: number;
|
|
||||||
maxAttachmentSize: number;
|
|
||||||
maxBulkDelete: number;
|
|
||||||
};
|
|
||||||
channel: {
|
|
||||||
maxPins: number;
|
|
||||||
maxTopic: number;
|
|
||||||
};
|
|
||||||
rate: {
|
|
||||||
ip: Omit<RateLimitOptions, "bot_count">;
|
|
||||||
global: RateLimitOptions;
|
|
||||||
error: RateLimitOptions;
|
|
||||||
routes: {
|
|
||||||
guild: RateLimitOptions;
|
|
||||||
webhook: RateLimitOptions;
|
|
||||||
channel: RateLimitOptions;
|
|
||||||
auth: {
|
|
||||||
login: RateLimitOptions;
|
|
||||||
register: RateLimitOptions;
|
|
||||||
};
|
|
||||||
// TODO: rate limit configuration for all routes
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
security: {
|
|
||||||
requestSignature: string;
|
|
||||||
jwtSecret: string;
|
|
||||||
forwadedFor: string | null; // header to get the real user ip address
|
|
||||||
captcha: {
|
|
||||||
enabled: boolean;
|
|
||||||
service: "recaptcha" | "hcaptcha" | null; // TODO: hcaptcha, custom
|
|
||||||
sitekey: string | null;
|
|
||||||
secret: string | null;
|
|
||||||
};
|
|
||||||
ipdataApiKey: string | null;
|
|
||||||
};
|
|
||||||
login: {
|
|
||||||
requireCaptcha: boolean;
|
|
||||||
};
|
|
||||||
register: {
|
|
||||||
email: {
|
|
||||||
necessary: boolean; // we have to use necessary instead of required as the cli tool uses json schema and can't use required
|
|
||||||
allowlist: boolean;
|
|
||||||
blocklist: boolean;
|
|
||||||
domains: string[];
|
|
||||||
};
|
|
||||||
dateOfBirth: {
|
|
||||||
necessary: boolean;
|
|
||||||
minimum: number; // in years
|
|
||||||
};
|
|
||||||
requireCaptcha: boolean;
|
|
||||||
requireInvite: boolean;
|
|
||||||
allowNewRegistration: boolean;
|
|
||||||
allowMultipleAccounts: boolean;
|
|
||||||
blockProxies: boolean;
|
|
||||||
password: {
|
|
||||||
minLength: number;
|
|
||||||
minNumbers: number;
|
|
||||||
minUpperCase: number;
|
|
||||||
minSymbols: number;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
regions: {
|
|
||||||
default: string;
|
|
||||||
available: Region[];
|
|
||||||
};
|
|
||||||
rabbitmq: {
|
|
||||||
host: string | null;
|
|
||||||
};
|
|
||||||
kafka: {
|
|
||||||
brokers: KafkaBroker[] | null;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const DefaultOptions: DefaultOptions = {
|
|
||||||
gateway: {
|
|
||||||
endpoint: null,
|
|
||||||
},
|
|
||||||
cdn: {
|
|
||||||
endpoint: null,
|
|
||||||
},
|
|
||||||
general: {
|
|
||||||
instance_id: Snowflake.generate(),
|
|
||||||
},
|
|
||||||
permissions: {
|
|
||||||
user: {
|
|
||||||
createGuilds: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
limits: {
|
|
||||||
user: {
|
|
||||||
maxGuilds: 100,
|
|
||||||
maxUsername: 32,
|
|
||||||
maxFriends: 1000,
|
|
||||||
},
|
|
||||||
guild: {
|
|
||||||
maxRoles: 250,
|
|
||||||
maxMembers: 250000,
|
|
||||||
maxChannels: 500,
|
|
||||||
maxChannelsInCategory: 50,
|
|
||||||
hideOfflineMember: 1000,
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
maxCharacters: 2000,
|
|
||||||
maxTTSCharacters: 200,
|
|
||||||
maxReactions: 20,
|
|
||||||
maxAttachmentSize: 8388608,
|
|
||||||
maxBulkDelete: 100,
|
|
||||||
},
|
|
||||||
channel: {
|
|
||||||
maxPins: 50,
|
|
||||||
maxTopic: 1024,
|
|
||||||
},
|
|
||||||
rate: {
|
|
||||||
ip: {
|
|
||||||
count: 500,
|
|
||||||
window: 5,
|
|
||||||
},
|
|
||||||
global: {
|
|
||||||
count: 20,
|
|
||||||
window: 5,
|
|
||||||
bot: 250,
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
count: 10,
|
|
||||||
window: 5,
|
|
||||||
},
|
|
||||||
routes: {
|
|
||||||
guild: {
|
|
||||||
count: 5,
|
|
||||||
window: 5,
|
|
||||||
},
|
|
||||||
webhook: {
|
|
||||||
count: 5,
|
|
||||||
window: 5,
|
|
||||||
},
|
|
||||||
channel: {
|
|
||||||
count: 5,
|
|
||||||
window: 5,
|
|
||||||
},
|
|
||||||
auth: {
|
|
||||||
login: {
|
|
||||||
count: 5,
|
|
||||||
window: 60,
|
|
||||||
},
|
|
||||||
register: {
|
|
||||||
count: 2,
|
|
||||||
window: 60 * 60 * 12,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
security: {
|
|
||||||
requestSignature: crypto.randomBytes(32).toString("base64"),
|
|
||||||
jwtSecret: crypto.randomBytes(256).toString("base64"),
|
|
||||||
forwadedFor: null,
|
|
||||||
// forwadedFor: "X-Forwarded-For" // nginx/reverse proxy
|
|
||||||
// forwadedFor: "CF-Connecting-IP" // cloudflare:
|
|
||||||
captcha: {
|
|
||||||
enabled: false,
|
|
||||||
service: null,
|
|
||||||
sitekey: null,
|
|
||||||
secret: null,
|
|
||||||
},
|
|
||||||
ipdataApiKey: "eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9",
|
|
||||||
},
|
|
||||||
login: {
|
|
||||||
requireCaptcha: false,
|
|
||||||
},
|
|
||||||
register: {
|
|
||||||
email: {
|
|
||||||
necessary: true,
|
|
||||||
allowlist: false,
|
|
||||||
blocklist: true,
|
|
||||||
domains: [], // TODO: efficiently save domain blocklist in database
|
|
||||||
// domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"),
|
|
||||||
},
|
|
||||||
dateOfBirth: {
|
|
||||||
necessary: true,
|
|
||||||
minimum: 13,
|
|
||||||
},
|
|
||||||
requireInvite: false,
|
|
||||||
requireCaptcha: true,
|
|
||||||
allowNewRegistration: true,
|
|
||||||
allowMultipleAccounts: true,
|
|
||||||
blockProxies: true,
|
|
||||||
password: {
|
|
||||||
minLength: 8,
|
|
||||||
minNumbers: 2,
|
|
||||||
minUpperCase: 2,
|
|
||||||
minSymbols: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
regions: {
|
|
||||||
default: "fosscord",
|
|
||||||
available: [{ id: "fosscord", name: "Fosscord", vip: false, custom: false, deprecated: false, optimal: false }],
|
|
||||||
},
|
|
||||||
rabbitmq: {
|
|
||||||
host: null,
|
|
||||||
},
|
|
||||||
kafka: {
|
|
||||||
brokers: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ConfigSchema = new Schema({}, { strict: false });
|
|
||||||
|
|
||||||
export interface DefaultOptionsDocument extends DefaultOptions, Document {}
|
|
||||||
|
|
||||||
export const ConfigModel = model<DefaultOptionsDocument>("Config", ConfigSchema, "config");
|
|
@ -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,
|
|
||||||
}
|
|
@ -1,151 +0,0 @@
|
|||||||
import "./MongoBigInt";
|
|
||||||
import mongoose, { Collection, Connection, LeanDocument } from "mongoose";
|
|
||||||
import { ChangeStream, ChangeEvent, Long } from "mongodb";
|
|
||||||
import EventEmitter from "events";
|
|
||||||
const uri = process.env.MONGO_URL || "mongodb://localhost:27017/fosscord?readPreference=secondaryPreferred";
|
|
||||||
import { URL } from "url";
|
|
||||||
|
|
||||||
const url = new URL(uri.replace("mongodb://", "http://"));
|
|
||||||
|
|
||||||
const connection = mongoose.createConnection(uri, {
|
|
||||||
autoIndex: true,
|
|
||||||
useNewUrlParser: true,
|
|
||||||
useUnifiedTopology: true,
|
|
||||||
useFindAndModify: false,
|
|
||||||
});
|
|
||||||
console.log(`[Database] connect: mongodb://${url.username}@${url.host}${url.pathname}${url.search}`);
|
|
||||||
|
|
||||||
export default <Connection>connection;
|
|
||||||
|
|
||||||
function transform<T>(document: T) {
|
|
||||||
// @ts-ignore
|
|
||||||
if (!document || !document.toObject) {
|
|
||||||
try {
|
|
||||||
// @ts-ignore
|
|
||||||
delete document._id;
|
|
||||||
// @ts-ignore
|
|
||||||
delete document.__v;
|
|
||||||
} catch (error) {}
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
|
||||||
return document.toObject({ virtuals: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toObject<T>(document: T): LeanDocument<T> {
|
|
||||||
// @ts-ignore
|
|
||||||
return Array.isArray(document) ? document.map((x) => transform<T>(x)) : transform(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MongooseCache {
|
|
||||||
on(event: "delete", listener: (id: string) => void): this;
|
|
||||||
on(event: "change", listener: (data: any) => void): this;
|
|
||||||
on(event: "insert", listener: (data: any) => void): this;
|
|
||||||
on(event: "close", listener: () => void): this;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class MongooseCache extends EventEmitter {
|
|
||||||
public stream: ChangeStream;
|
|
||||||
public data: any;
|
|
||||||
public initalizing?: Promise<void>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public collection: Collection,
|
|
||||||
public pipeline: Array<Record<string, unknown>>,
|
|
||||||
public opts: {
|
|
||||||
onlyEvents: boolean;
|
|
||||||
array?: boolean;
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
if (this.opts.array == null) this.opts.array = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
init = () => {
|
|
||||||
if (this.initalizing) return this.initalizing;
|
|
||||||
this.initalizing = new Promise(async (resolve, reject) => {
|
|
||||||
// @ts-ignore
|
|
||||||
this.stream = this.collection.watch(this.pipeline, { fullDocument: "updateLookup" });
|
|
||||||
|
|
||||||
this.stream.on("change", this.change);
|
|
||||||
this.stream.on("close", this.destroy);
|
|
||||||
this.stream.on("error", console.error);
|
|
||||||
|
|
||||||
if (!this.opts.onlyEvents) {
|
|
||||||
const arr = await this.collection.aggregate(this.pipeline).toArray();
|
|
||||||
if (this.opts.array) this.data = arr || [];
|
|
||||||
else this.data = arr?.[0];
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
return this.initalizing;
|
|
||||||
};
|
|
||||||
|
|
||||||
changeStream = (pipeline: any) => {
|
|
||||||
this.pipeline = pipeline;
|
|
||||||
this.destroy();
|
|
||||||
this.init();
|
|
||||||
};
|
|
||||||
|
|
||||||
convertResult = (obj: any) => {
|
|
||||||
if (obj instanceof Long) return BigInt(obj.toString());
|
|
||||||
if (typeof obj === "object") {
|
|
||||||
Object.keys(obj).forEach((key) => {
|
|
||||||
obj[key] = this.convertResult(obj[key]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
change = (doc: ChangeEvent) => {
|
|
||||||
try {
|
|
||||||
switch (doc.operationType) {
|
|
||||||
case "dropDatabase":
|
|
||||||
return this.destroy();
|
|
||||||
case "drop":
|
|
||||||
return this.destroy();
|
|
||||||
case "delete":
|
|
||||||
if (!this.opts.onlyEvents) {
|
|
||||||
if (this.opts.array) {
|
|
||||||
this.data = this.data.filter((x: any) => doc.documentKey?._id?.equals(x._id));
|
|
||||||
} else this.data = null;
|
|
||||||
}
|
|
||||||
return this.emit("delete", doc.documentKey._id.toHexString());
|
|
||||||
case "insert":
|
|
||||||
if (!this.opts.onlyEvents) {
|
|
||||||
if (this.opts.array) this.data.push(doc.fullDocument);
|
|
||||||
else this.data = doc.fullDocument;
|
|
||||||
}
|
|
||||||
return this.emit("insert", doc.fullDocument);
|
|
||||||
case "update":
|
|
||||||
case "replace":
|
|
||||||
if (!this.opts.onlyEvents) {
|
|
||||||
if (this.opts.array) {
|
|
||||||
const i = this.data.findIndex((x: any) => doc.fullDocument?._id?.equals(x._id));
|
|
||||||
if (i == -1) this.data.push(doc.fullDocument);
|
|
||||||
else this.data[i] = doc.fullDocument;
|
|
||||||
} else this.data = doc.fullDocument;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.emit("change", doc.fullDocument);
|
|
||||||
case "invalidate":
|
|
||||||
return this.destroy();
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.emit("error", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
destroy = () => {
|
|
||||||
this.data = null;
|
|
||||||
this.stream?.off("change", this.change);
|
|
||||||
this.emit("close");
|
|
||||||
|
|
||||||
if (this.stream.isClosed()) return;
|
|
||||||
|
|
||||||
return this.stream.close();
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import { BitField } from "./BitField";
|
|
||||||
|
|
||||||
export class Intents extends BitField {
|
|
||||||
static FLAGS = {
|
|
||||||
GUILDS: BigInt(1) << BigInt(0),
|
|
||||||
GUILD_MEMBERS: BigInt(1) << BigInt(1),
|
|
||||||
GUILD_BANS: BigInt(1) << BigInt(2),
|
|
||||||
GUILD_EMOJIS: BigInt(1) << BigInt(3),
|
|
||||||
GUILD_INTEGRATIONS: BigInt(1) << BigInt(4),
|
|
||||||
GUILD_WEBHOOKS: BigInt(1) << BigInt(5),
|
|
||||||
GUILD_INVITES: BigInt(1) << BigInt(6),
|
|
||||||
GUILD_VOICE_STATES: BigInt(1) << BigInt(7),
|
|
||||||
GUILD_PRESENCES: BigInt(1) << BigInt(8),
|
|
||||||
GUILD_MESSAGES: BigInt(1) << BigInt(9),
|
|
||||||
GUILD_MESSAGE_REACTIONS: BigInt(1) << BigInt(10),
|
|
||||||
GUILD_MESSAGE_TYPING: BigInt(1) << BigInt(11),
|
|
||||||
DIRECT_MESSAGES: BigInt(1) << BigInt(12),
|
|
||||||
DIRECT_MESSAGE_REACTIONS: BigInt(1) << BigInt(13),
|
|
||||||
DIRECT_MESSAGE_TYPING: BigInt(1) << BigInt(14),
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
// https://github.com/discordjs/discord.js/blob/master/src/util/MessageFlags.js
|
|
||||||
// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah
|
|
||||||
|
|
||||||
import { BitField } from "./BitField";
|
|
||||||
|
|
||||||
export class MessageFlags extends BitField {
|
|
||||||
static FLAGS = {
|
|
||||||
CROSSPOSTED: BigInt(1) << BigInt(0),
|
|
||||||
IS_CROSSPOST: BigInt(1) << BigInt(1),
|
|
||||||
SUPPRESS_EMBEDS: BigInt(1) << BigInt(2),
|
|
||||||
SOURCE_MESSAGE_DELETED: BigInt(1) << BigInt(3),
|
|
||||||
URGENT: BigInt(1) << BigInt(4),
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
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);
|
|
||||||
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;
|
|
@ -1,262 +0,0 @@
|
|||||||
// 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 { BitField } from "./BitField";
|
|
||||||
import { GuildDocument, GuildModel } from "../models/Guild";
|
|
||||||
// TODO: check role hierarchy permission
|
|
||||||
|
|
||||||
var HTTPError: any;
|
|
||||||
|
|
||||||
try {
|
|
||||||
HTTPError = require("lambert-server").HTTPError;
|
|
||||||
} catch (e) {
|
|
||||||
HTTPError = Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PermissionResolvable = bigint | number | Permissions | PermissionResolvable[] | PermissionString;
|
|
||||||
|
|
||||||
type PermissionString =
|
|
||||||
| "CREATE_INSTANT_INVITE"
|
|
||||||
| "KICK_MEMBERS"
|
|
||||||
| "BAN_MEMBERS"
|
|
||||||
| "ADMINISTRATOR"
|
|
||||||
| "MANAGE_CHANNELS"
|
|
||||||
| "MANAGE_GUILD"
|
|
||||||
| "ADD_REACTIONS"
|
|
||||||
| "VIEW_AUDIT_LOG"
|
|
||||||
| "PRIORITY_SPEAKER"
|
|
||||||
| "STREAM"
|
|
||||||
| "VIEW_CHANNEL"
|
|
||||||
| "SEND_MESSAGES"
|
|
||||||
| "SEND_TTS_MESSAGES"
|
|
||||||
| "MANAGE_MESSAGES"
|
|
||||||
| "EMBED_LINKS"
|
|
||||||
| "ATTACH_FILES"
|
|
||||||
| "READ_MESSAGE_HISTORY"
|
|
||||||
| "MENTION_EVERYONE"
|
|
||||||
| "USE_EXTERNAL_EMOJIS"
|
|
||||||
| "VIEW_GUILD_INSIGHTS"
|
|
||||||
| "CONNECT"
|
|
||||||
| "SPEAK"
|
|
||||||
| "MUTE_MEMBERS"
|
|
||||||
| "DEAFEN_MEMBERS"
|
|
||||||
| "MOVE_MEMBERS"
|
|
||||||
| "USE_VAD"
|
|
||||||
| "CHANGE_NICKNAME"
|
|
||||||
| "MANAGE_NICKNAMES"
|
|
||||||
| "MANAGE_ROLES"
|
|
||||||
| "MANAGE_WEBHOOKS"
|
|
||||||
| "MANAGE_EMOJIS";
|
|
||||||
|
|
||||||
const CUSTOM_PERMISSION_OFFSET = BigInt(1) << BigInt(48); // 16 free custom permission bits, and 16 for discord to add new ones
|
|
||||||
|
|
||||||
export class Permissions extends BitField {
|
|
||||||
cache: PermissionCache = {};
|
|
||||||
|
|
||||||
static FLAGS = {
|
|
||||||
CREATE_INSTANT_INVITE: BigInt(1) << BigInt(0),
|
|
||||||
KICK_MEMBERS: BigInt(1) << BigInt(1),
|
|
||||||
BAN_MEMBERS: BigInt(1) << BigInt(2),
|
|
||||||
ADMINISTRATOR: BigInt(1) << BigInt(3),
|
|
||||||
MANAGE_CHANNELS: BigInt(1) << BigInt(4),
|
|
||||||
MANAGE_GUILD: BigInt(1) << BigInt(5),
|
|
||||||
ADD_REACTIONS: BigInt(1) << BigInt(6),
|
|
||||||
VIEW_AUDIT_LOG: BigInt(1) << BigInt(7),
|
|
||||||
PRIORITY_SPEAKER: BigInt(1) << BigInt(8),
|
|
||||||
STREAM: BigInt(1) << BigInt(9),
|
|
||||||
VIEW_CHANNEL: BigInt(1) << BigInt(10),
|
|
||||||
SEND_MESSAGES: BigInt(1) << BigInt(11),
|
|
||||||
SEND_TTS_MESSAGES: BigInt(1) << BigInt(12),
|
|
||||||
MANAGE_MESSAGES: BigInt(1) << BigInt(13),
|
|
||||||
EMBED_LINKS: BigInt(1) << BigInt(14),
|
|
||||||
ATTACH_FILES: BigInt(1) << BigInt(15),
|
|
||||||
READ_MESSAGE_HISTORY: BigInt(1) << BigInt(16),
|
|
||||||
MENTION_EVERYONE: BigInt(1) << BigInt(17),
|
|
||||||
USE_EXTERNAL_EMOJIS: BigInt(1) << BigInt(18),
|
|
||||||
VIEW_GUILD_INSIGHTS: BigInt(1) << BigInt(19),
|
|
||||||
CONNECT: BigInt(1) << BigInt(20),
|
|
||||||
SPEAK: BigInt(1) << BigInt(21),
|
|
||||||
MUTE_MEMBERS: BigInt(1) << BigInt(22),
|
|
||||||
DEAFEN_MEMBERS: BigInt(1) << BigInt(23),
|
|
||||||
MOVE_MEMBERS: BigInt(1) << BigInt(24),
|
|
||||||
USE_VAD: BigInt(1) << BigInt(25),
|
|
||||||
CHANGE_NICKNAME: BigInt(1) << BigInt(26),
|
|
||||||
MANAGE_NICKNAMES: BigInt(1) << BigInt(27),
|
|
||||||
MANAGE_ROLES: BigInt(1) << BigInt(28),
|
|
||||||
MANAGE_WEBHOOKS: BigInt(1) << BigInt(29),
|
|
||||||
MANAGE_EMOJIS: BigInt(1) << BigInt(30),
|
|
||||||
/**
|
|
||||||
* CUSTOM PERMISSIONS ideas:
|
|
||||||
* - allow user to dm members
|
|
||||||
* - allow user to pin messages (without MANAGE_MESSAGES)
|
|
||||||
* - allow user to publish messages (without MANAGE_MESSAGES)
|
|
||||||
*/
|
|
||||||
// CUSTOM_PERMISSION: BigInt(1) << BigInt(0) + CUSTOM_PERMISSION_OFFSET
|
|
||||||
};
|
|
||||||
|
|
||||||
any(permission: PermissionResolvable, checkAdmin = true) {
|
|
||||||
return (checkAdmin && super.any(Permissions.FLAGS.ADMINISTRATOR)) || super.any(permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the bitfield has a permission, or multiple permissions.
|
|
||||||
*/
|
|
||||||
has(permission: PermissionResolvable, checkAdmin = true) {
|
|
||||||
return (checkAdmin && super.has(Permissions.FLAGS.ADMINISTRATOR)) || super.has(permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the bitfield has a permission, or multiple permissions, but throws an Error if user fails to match auth criteria.
|
|
||||||
*/
|
|
||||||
hasThrow(permission: PermissionResolvable) {
|
|
||||||
if (this.has(permission) && this.has("VIEW_CHANNEL")) return true;
|
|
||||||
// @ts-ignore
|
|
||||||
throw new HTTPError(`You are missing the following permissions ${permission}`, 403);
|
|
||||||
}
|
|
||||||
|
|
||||||
overwriteChannel(overwrites: ChannelPermissionOverwrite[]) {
|
|
||||||
if (!this.cache) throw new Error("permission chache not available");
|
|
||||||
overwrites = overwrites.filter((x) => {
|
|
||||||
if (x.type === 0 && this.cache.roles?.some((r) => r.id === x.id)) return true;
|
|
||||||
if (x.type === 1 && x.id == this.cache.user_id) return true;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
return new Permissions(Permissions.channelPermission(overwrites, this.bitfield));
|
|
||||||
}
|
|
||||||
|
|
||||||
static channelPermission(overwrites: ChannelPermissionOverwrite[], init?: bigint) {
|
|
||||||
// TODO: do not deny any permissions if admin
|
|
||||||
return overwrites.reduce((permission, overwrite) => {
|
|
||||||
// apply disallowed permission
|
|
||||||
// * permission: current calculated permission (e.g. 010)
|
|
||||||
// * deny contains all denied permissions (e.g. 011)
|
|
||||||
// * allow contains all explicitly allowed permisions (e.g. 100)
|
|
||||||
return (permission & ~BigInt(overwrite.deny)) | BigInt(overwrite.allow);
|
|
||||||
// ~ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static rolePermission(roles: Role[]) {
|
|
||||||
// adds all permissions of all roles together (Bit OR)
|
|
||||||
return roles.reduce((permission, role) => permission | BigInt(role.permissions), 0n);
|
|
||||||
}
|
|
||||||
|
|
||||||
static finalPermission({
|
|
||||||
user,
|
|
||||||
guild,
|
|
||||||
channel,
|
|
||||||
}: {
|
|
||||||
user: { id: string; roles: string[] };
|
|
||||||
guild: { roles: Role[] };
|
|
||||||
channel?: {
|
|
||||||
overwrites?: ChannelPermissionOverwrite[];
|
|
||||||
recipient_ids?: string[] | null;
|
|
||||||
owner_id?: string;
|
|
||||||
};
|
|
||||||
}) {
|
|
||||||
if (user.id === "0") return new Permissions("ADMINISTRATOR"); // system user id
|
|
||||||
|
|
||||||
let roles = guild.roles.filter((x) => user.roles.includes(x.id));
|
|
||||||
let permission = Permissions.rolePermission(roles);
|
|
||||||
|
|
||||||
if (channel?.overwrites) {
|
|
||||||
let overwrites = channel.overwrites.filter((x) => {
|
|
||||||
if (x.type === 0 && user.roles.includes(x.id)) return true;
|
|
||||||
if (x.type === 1 && x.id == user.id) return true;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
permission = Permissions.channelPermission(overwrites, permission);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel?.recipient_ids) {
|
|
||||||
if (channel?.owner_id === user.id) return new Permissions("ADMINISTRATOR");
|
|
||||||
if (channel.recipient_ids.includes(user.id)) {
|
|
||||||
// Default dm permissions
|
|
||||||
return new Permissions([
|
|
||||||
"VIEW_CHANNEL",
|
|
||||||
"SEND_MESSAGES",
|
|
||||||
"STREAM",
|
|
||||||
"ADD_REACTIONS",
|
|
||||||
"EMBED_LINKS",
|
|
||||||
"ATTACH_FILES",
|
|
||||||
"READ_MESSAGE_HISTORY",
|
|
||||||
"MENTION_EVERYONE",
|
|
||||||
"USE_EXTERNAL_EMOJIS",
|
|
||||||
"CONNECT",
|
|
||||||
"SPEAK",
|
|
||||||
"MANAGE_CHANNELS",
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Permissions();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Permissions(permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PermissionCache = {
|
|
||||||
channel?: ChannelDocument | null;
|
|
||||||
member?: MemberDocument | null;
|
|
||||||
guild?: GuildDocument | null;
|
|
||||||
roles?: RoleDocument[] | null;
|
|
||||||
user_id?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function getPermission(
|
|
||||||
user_id?: string,
|
|
||||||
guild_id?: string,
|
|
||||||
channel_id?: string,
|
|
||||||
cache: PermissionCache = {}
|
|
||||||
) {
|
|
||||||
var { channel, member, guild, roles } = cache;
|
|
||||||
|
|
||||||
if (!user_id) throw new HTTPError("User not found");
|
|
||||||
|
|
||||||
if (channel_id && !channel) {
|
|
||||||
channel = await ChannelModel.findOne(
|
|
||||||
{ id: channel_id },
|
|
||||||
{ permission_overwrites: true, recipient_ids: true, owner_id: true, guild_id: true }
|
|
||||||
).exec();
|
|
||||||
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) 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) throw new HTTPError("Member not found");
|
|
||||||
|
|
||||||
if (!roles) roles = await RoleModel.find({ guild_id, id: { $in: member.roles } }).exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
var permission = Permissions.finalPermission({
|
|
||||||
user: {
|
|
||||||
id: user_id,
|
|
||||||
roles: member?.roles || [],
|
|
||||||
},
|
|
||||||
guild: {
|
|
||||||
roles: roles || [],
|
|
||||||
},
|
|
||||||
channel: {
|
|
||||||
overwrites: channel?.permission_overwrites,
|
|
||||||
owner_id: channel?.owner_id,
|
|
||||||
recipient_ids: channel?.recipient_ids,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const obj = new Permissions(permission);
|
|
||||||
|
|
||||||
// pass cache to permission for possible future getPermission calls
|
|
||||||
obj.cache = { guild, member, channel, roles, user_id };
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
import amqp, { Connection, Channel } from "amqplib";
|
|
||||||
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`);
|
|
||||||
},
|
|
||||||
};
|
|
@ -1,3 +0,0 @@
|
|||||||
export const DOUBLE_WHITE_SPACE = /\s\s+/g;
|
|
||||||
export const SPECIAL_CHAR = /[@#`:\r\n\t\f\v\p{C}]/gu;
|
|
||||||
export const CHANNEL_MENTION = /<#(\d+)>/g;
|
|
@ -1,127 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import cluster from "cluster";
|
|
||||||
|
|
||||||
// https://github.com/discordjs/discord.js/blob/master/src/util/Snowflake.js
|
|
||||||
// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah
|
|
||||||
("use strict");
|
|
||||||
|
|
||||||
// Discord epoch (2015-01-01T00:00:00.000Z)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A container for useful snowflake-related methods.
|
|
||||||
*/
|
|
||||||
export class Snowflake {
|
|
||||||
static readonly EPOCH = 1420070400000;
|
|
||||||
static INCREMENT = 0n; // max 4095
|
|
||||||
static processId = BigInt(process.pid % 31); // max 31
|
|
||||||
static workerId = BigInt((cluster.worker?.id || 0) % 31); // max 31
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Twitter snowflake, except the epoch is 2015-01-01T00:00:00.000Z
|
|
||||||
* ```
|
|
||||||
* If we have a snowflake '266241948824764416' we can represent it as binary:
|
|
||||||
*
|
|
||||||
* 64 22 17 12 0
|
|
||||||
* 000000111011000111100001101001000101000000 00001 00000 000000000000
|
|
||||||
* number of ms since Discord epoch worker pid increment
|
|
||||||
* ```
|
|
||||||
* @typedef {string} Snowflake
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a snowflake from a decimal string to a bit string.
|
|
||||||
* @param {Snowflake} num Snowflake to be transformed
|
|
||||||
* @returns {string}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
static idToBinary(num) {
|
|
||||||
let bin = "";
|
|
||||||
let high = parseInt(num.slice(0, -10)) || 0;
|
|
||||||
let low = parseInt(num.slice(-10));
|
|
||||||
while (low > 0 || high > 0) {
|
|
||||||
bin = String(low & 1) + bin;
|
|
||||||
low = Math.floor(low / 2);
|
|
||||||
if (high > 0) {
|
|
||||||
low += 5000000000 * (high % 2);
|
|
||||||
high = Math.floor(high / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transforms a snowflake from a bit string to a decimal string.
|
|
||||||
* @param {string} num Bit string to be transformed
|
|
||||||
* @returns {Snowflake}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
static binaryToID(num) {
|
|
||||||
let dec = "";
|
|
||||||
|
|
||||||
while (num.length > 50) {
|
|
||||||
const high = parseInt(num.slice(0, -32), 2);
|
|
||||||
const low = parseInt((high % 10).toString(2) + num.slice(-32), 2);
|
|
||||||
|
|
||||||
dec = (low % 10).toString() + dec;
|
|
||||||
num =
|
|
||||||
Math.floor(high / 10).toString(2) +
|
|
||||||
Math.floor(low / 10)
|
|
||||||
.toString(2)
|
|
||||||
.padStart(32, "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
num = parseInt(num, 2);
|
|
||||||
while (num > 0) {
|
|
||||||
dec = (num % 10).toString() + dec;
|
|
||||||
num = Math.floor(num / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
static generate() {
|
|
||||||
var time = BigInt(Date.now() - Snowflake.EPOCH) << 22n;
|
|
||||||
var worker = Snowflake.workerId << 17n;
|
|
||||||
var process = Snowflake.processId << 12n;
|
|
||||||
var increment = Snowflake.INCREMENT++;
|
|
||||||
return (time | worker | process | increment).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A deconstructed snowflake.
|
|
||||||
* @typedef {Object} DeconstructedSnowflake
|
|
||||||
* @property {number} timestamp Timestamp the snowflake was created
|
|
||||||
* @property {Date} date Date the snowflake was created
|
|
||||||
* @property {number} workerID Worker ID in the snowflake
|
|
||||||
* @property {number} processID Process ID in the snowflake
|
|
||||||
* @property {number} increment Increment in the snowflake
|
|
||||||
* @property {string} binary Binary representation of the snowflake
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deconstructs a Discord snowflake.
|
|
||||||
* @param {Snowflake} snowflake Snowflake to deconstruct
|
|
||||||
* @returns {DeconstructedSnowflake} Deconstructed snowflake
|
|
||||||
*/
|
|
||||||
static deconstruct(snowflake) {
|
|
||||||
const BINARY = Snowflake.idToBinary(snowflake).toString(2).padStart(64, "0");
|
|
||||||
const res = {
|
|
||||||
timestamp: parseInt(BINARY.substring(0, 42), 2) + Snowflake.EPOCH,
|
|
||||||
workerID: parseInt(BINARY.substring(42, 47), 2),
|
|
||||||
processID: parseInt(BINARY.substring(47, 52), 2),
|
|
||||||
increment: parseInt(BINARY.substring(52, 64), 2),
|
|
||||||
binary: BINARY,
|
|
||||||
};
|
|
||||||
Object.defineProperty(res, "date", {
|
|
||||||
get: function get() {
|
|
||||||
return new Date(this.timestamp);
|
|
||||||
},
|
|
||||||
enumerable: true,
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
import { SPECIAL_CHAR } from "./Regex";
|
|
||||||
|
|
||||||
export function trimSpecial(str?: string): string {
|
|
||||||
// @ts-ignore
|
|
||||||
if (!str) return;
|
|
||||||
return str.replace(SPECIAL_CHAR, "").trim();
|
|
||||||
}
|
|
@ -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,24 +0,0 @@
|
|||||||
import { JWTOptions } from "./Constants";
|
|
||||||
import jwt from "jsonwebtoken";
|
|
||||||
import { UserModel } from "../models";
|
|
||||||
|
|
||||||
export function checkToken(token: string, jwtSecret: string): Promise<any> {
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
token = token.replace("Bot ", ""); // TODO: proper bot support
|
|
||||||
jwt.verify(token, jwtSecret, JWTOptions, async (err, decoded: any) => {
|
|
||||||
if (err || !decoded) return rej("Invalid Token");
|
|
||||||
|
|
||||||
const user = await UserModel.findOne(
|
|
||||||
{ id: decoded.id },
|
|
||||||
{ "user_data.valid_tokens_since": true, bot: true, disabled: true, deleted: true }
|
|
||||||
).exec();
|
|
||||||
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");
|
|
||||||
if (user.disabled) return rej("User disabled");
|
|
||||||
if (user.deleted) return rej("User not found");
|
|
||||||
|
|
||||||
return res({ decoded, user });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
export * from "./String";
|
|
||||||
export * from "./BitField";
|
|
||||||
export * from "./Intents";
|
|
||||||
export * from "./MessageFlags";
|
|
||||||
export * from "./Permissions";
|
|
||||||
export * from "./Snowflake";
|
|
||||||
export * from "./UserFlags";
|
|
||||||
export * from "./toBigInt";
|
|
||||||
export * from "./RabbitMQ";
|
|
@ -1,3 +0,0 @@
|
|||||||
export default function toBigInt(string: String): BigInt {
|
|
||||||
return BigInt(string);
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
{
|
|
||||||
"include": ["src/**/*.ts"],
|
|
||||||
"compilerOptions": {
|
|
||||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
|
||||||
|
|
||||||
/* Basic Options */
|
|
||||||
// "incremental": true, /* Enable incremental compilation */
|
|
||||||
"target": "ES2020" /* 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. */,
|
|
||||||
"checkJs": true /* Report errors in .js files. */,
|
|
||||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
|
||||||
"declaration": true /* Generates corresponding '.d.ts' file. */,
|
|
||||||
"declarationMap": false /* Generates a sourcemap for each corresponding '.d.ts' file. */,
|
|
||||||
"sourceMap": true /* Generates corresponding '.map' file. */,
|
|
||||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
|
||||||
"outDir": "./dist/" /* Redirect output structure to the directory. */,
|
|
||||||
"rootDir": "./src/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
|
||||||
// "composite": true, /* Enable project compilation */
|
|
||||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
|
||||||
// "removeComments": true, /* Do not emit comments to output. */
|
|
||||||
// "noEmit": true, /* Do not emit outputs. */
|
|
||||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
|
||||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
|
||||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
|
||||||
|
|
||||||
/* Strict Type-Checking Options */
|
|
||||||
"strict": true /* Enable all strict type-checking options. */,
|
|
||||||
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
|
|
||||||
"strictNullChecks": true /* Enable strict null checks. */,
|
|
||||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
|
||||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
|
||||||
"strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */,
|
|
||||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
|
||||||
"alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
|
|
||||||
|
|
||||||
/* Additional Checks */
|
|
||||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
|
||||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
|
||||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
|
||||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
|
||||||
|
|
||||||
/* Module Resolution Options */
|
|
||||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
|
||||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
|
||||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
|
||||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
|
||||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
|
||||||
"types": ["node"] /* Type declaration files to be included in compilation. */,
|
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
|
||||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
|
||||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
||||||
|
|
||||||
/* Source Map Options */
|
|
||||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
|
||||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
||||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
|
||||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
|
||||||
|
|
||||||
/* Experimental Options */
|
|
||||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
|
||||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
|
||||||
|
|
||||||
/* Advanced Options */
|
|
||||||
"skipLibCheck": true /* Skip type checking of declaration files. */,
|
|
||||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,6 +4,7 @@
|
|||||||
"description": "A javascript fosscord webrtc server for voice and video communication",
|
"description": "A javascript fosscord webrtc server for voice and video communication",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"postinstall": "npm link @fosscord/util",
|
||||||
"test": "npm run build && node dist/test.js",
|
"test": "npm run build && node dist/test.js",
|
||||||
"build": "tsc -b .",
|
"build": "tsc -b .",
|
||||||
"start": "npm run build && node dist/start.js"
|
"start": "npm run build && node dist/start.js"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Server as WebSocketServer } from "ws";
|
import { Server as WebSocketServer } from "ws";
|
||||||
import { Config, db } from "@fosscord/server-util";
|
import { Config, db } from "@fosscord/util";
|
||||||
import mediasoup from "mediasoup"
|
import mediasoup from "mediasoup";
|
||||||
|
|
||||||
var port = Number(process.env.PORT);
|
var port = Number(process.env.PORT);
|
||||||
if (isNaN(port)) port = 3004;
|
if (isNaN(port)) port = 3004;
|
||||||
@ -30,7 +30,6 @@ export class Server {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async listen(): Promise<void> {
|
async listen(): Promise<void> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user