mirror of
https://github.com/spacebarchat/server.git
synced 2026-08-29 07:39:00 +00:00
Prettier u7
This commit is contained in:
@@ -12,12 +12,7 @@ export class OrmUtils {
|
||||
return !item.constructor || item.constructor === Object;
|
||||
}
|
||||
|
||||
private static mergeArrayKey(
|
||||
target: any,
|
||||
key: number,
|
||||
value: any,
|
||||
memo: Map<any, any>,
|
||||
) {
|
||||
private static mergeArrayKey(target: any, key: number, value: any, memo: Map<any, any>) {
|
||||
// Have we seen this before? Prevent infinite recursion.
|
||||
if (memo.has(value)) {
|
||||
target[key] = memo.get(value);
|
||||
@@ -46,12 +41,7 @@ export class OrmUtils {
|
||||
memo.delete(value);
|
||||
}
|
||||
|
||||
private static mergeObjectKey(
|
||||
target: any,
|
||||
key: string,
|
||||
value: any,
|
||||
memo: Map<any, any>,
|
||||
) {
|
||||
private static mergeObjectKey(target: any, key: string, value: any, memo: Map<any, any>) {
|
||||
// Have we seen this before? Prevent infinite recursion.
|
||||
if (memo.has(value)) {
|
||||
Object.assign(target, { [key]: memo.get(value) });
|
||||
@@ -80,11 +70,7 @@ export class OrmUtils {
|
||||
memo.delete(value);
|
||||
}
|
||||
|
||||
private static merge(
|
||||
target: any,
|
||||
source: any,
|
||||
memo: Map<any, any> = new Map(),
|
||||
): any {
|
||||
private static merge(target: any, source: any, memo: Map<any, any> = new Map()): any {
|
||||
if (Array.isArray(target) && Array.isArray(source)) {
|
||||
for (let key = 0; key < source.length; key++) {
|
||||
this.mergeArrayKey(target, key, source[key], memo);
|
||||
|
||||
@@ -27,28 +27,16 @@ export class ApiError extends Error {
|
||||
}
|
||||
|
||||
withDefaultParams(): ApiError {
|
||||
if (this.defaultParams)
|
||||
return new ApiError(
|
||||
applyParamsToString(this.message, this.defaultParams),
|
||||
this.code,
|
||||
this.httpStatus,
|
||||
);
|
||||
if (this.defaultParams) return new ApiError(applyParamsToString(this.message, this.defaultParams), this.code, this.httpStatus);
|
||||
return this;
|
||||
}
|
||||
|
||||
withParams(...params: (string | number)[]): ApiError {
|
||||
return new ApiError(
|
||||
applyParamsToString(this.message, params),
|
||||
this.code,
|
||||
this.httpStatus,
|
||||
);
|
||||
return new ApiError(applyParamsToString(this.message, params), this.code, this.httpStatus);
|
||||
}
|
||||
}
|
||||
|
||||
export function applyParamsToString(
|
||||
s: string,
|
||||
params: (string | number)[],
|
||||
): string {
|
||||
export function applyParamsToString(s: string, params: (string | number)[]): string {
|
||||
let newString = s;
|
||||
params.forEach((a) => {
|
||||
newString = newString.replace("{}", "" + a);
|
||||
|
||||
+11
-23
@@ -25,26 +25,17 @@ const rl = readline.createInterface({
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
export function enableAutoUpdate(opts: {
|
||||
checkInterval: number | boolean;
|
||||
packageJsonLink: string;
|
||||
path: string;
|
||||
downloadUrl: string;
|
||||
downloadType?: "zip";
|
||||
}) {
|
||||
export function enableAutoUpdate(opts: { checkInterval: number | boolean; packageJsonLink: string; path: string; downloadUrl: string; downloadType?: "zip" }) {
|
||||
if (!opts.checkInterval) return;
|
||||
const interval = 1000 * 60 * 60 * 24;
|
||||
if (typeof opts.checkInterval === "number")
|
||||
opts.checkInterval = 1000 * interval;
|
||||
if (typeof opts.checkInterval === "number") opts.checkInterval = 1000 * interval;
|
||||
|
||||
const i = setInterval(async () => {
|
||||
const currentVersion = await getCurrentVersion(opts.path);
|
||||
const latestVersion = await getLatestVersion(opts.packageJsonLink);
|
||||
if (currentVersion !== latestVersion) {
|
||||
clearInterval(i);
|
||||
console.log(
|
||||
`[Auto Update] Current version (${currentVersion}) is out of date, updating ...`,
|
||||
);
|
||||
console.log(`[Auto Update] Current version (${currentVersion}) is out of date, updating ...`);
|
||||
await download(opts.downloadUrl, opts.path);
|
||||
}
|
||||
}, interval);
|
||||
@@ -52,17 +43,14 @@ export function enableAutoUpdate(opts: {
|
||||
const currentVersion = await getCurrentVersion(opts.path);
|
||||
const latestVersion = await getLatestVersion(opts.packageJsonLink);
|
||||
if (currentVersion !== latestVersion) {
|
||||
rl.question(
|
||||
`[Auto Update] Current version (${currentVersion}) is out of date, would you like to update? (Y/n)`,
|
||||
(answer) => {
|
||||
if (answer === "" || answer.toLowerCase() === "y") {
|
||||
console.log(`[Auto update] updating ...`);
|
||||
download(opts.downloadUrl, opts.path);
|
||||
} else {
|
||||
console.log(`[Auto update] aborted`);
|
||||
}
|
||||
},
|
||||
);
|
||||
rl.question(`[Auto Update] Current version (${currentVersion}) is out of date, would you like to update? (Y/n)`, (answer) => {
|
||||
if (answer === "" || answer.toLowerCase() === "y") {
|
||||
console.log(`[Auto update] updating ...`);
|
||||
download(opts.downloadUrl, opts.path);
|
||||
} else {
|
||||
console.log(`[Auto update] aborted`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,12 +4,7 @@
|
||||
// Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah
|
||||
// @fc-license-skip
|
||||
|
||||
export type BitFieldResolvable =
|
||||
| number
|
||||
| bigint
|
||||
| BitField
|
||||
| string
|
||||
| BitFieldResolvable[];
|
||||
export type BitFieldResolvable = number | bigint | BitField | string | BitFieldResolvable[];
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a bitfield.
|
||||
@@ -97,8 +92,7 @@ export class BitField {
|
||||
*/
|
||||
serialize() {
|
||||
const serialized: Record<string, boolean> = {};
|
||||
for (const [flag, bit] of Object.entries(BitField.FLAGS))
|
||||
serialized[flag] = this.has(bit);
|
||||
for (const [flag, bit] of Object.entries(BitField.FLAGS)) serialized[flag] = this.has(bit);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
@@ -144,11 +138,7 @@ export class BitField {
|
||||
else bit = BigInt(bit);
|
||||
}
|
||||
|
||||
if (
|
||||
(typeof bit === "number" || typeof bit === "bigint") &&
|
||||
bit >= BigInt(0)
|
||||
)
|
||||
return BigInt(bit);
|
||||
if ((typeof bit === "number" || typeof bit === "bigint") && bit >= BigInt(0)) return BigInt(bit);
|
||||
|
||||
if (bit instanceof BitField) return bit.bitfield;
|
||||
|
||||
@@ -156,9 +146,7 @@ export class BitField {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const resolve = this.constructor?.resolve || this.resolve;
|
||||
return bit
|
||||
.map((p) => resolve.call(this, p))
|
||||
.reduce((prev, p) => BigInt(prev) | BigInt(p), BigInt(0));
|
||||
return bit.map((p) => resolve.call(this, p)).reduce((prev, p) => BigInt(prev) | BigInt(p), BigInt(0));
|
||||
}
|
||||
|
||||
throw new RangeError("BITFIELD_INVALID: " + bit);
|
||||
|
||||
+16
-28
@@ -42,9 +42,7 @@ export class Config {
|
||||
} else {
|
||||
console.log(`[Config] Using CONFIG_PATH rather than database`);
|
||||
if (existsSync(process.env.CONFIG_PATH)) {
|
||||
const file = JSON.parse(
|
||||
(await fs.readFile(process.env.CONFIG_PATH)).toString(),
|
||||
);
|
||||
const file = JSON.parse((await fs.readFile(process.env.CONFIG_PATH)).toString());
|
||||
config = file;
|
||||
} else config = new ConfigValue();
|
||||
pairs = generatePairs(config);
|
||||
@@ -58,7 +56,7 @@ export class Config {
|
||||
await this.set(config);
|
||||
validateFinalConfig(config);
|
||||
return config;
|
||||
};
|
||||
}
|
||||
public static get() {
|
||||
if (!config) {
|
||||
// If we haven't initialised the config yet, return default config.
|
||||
@@ -70,13 +68,13 @@ export class Config {
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
}
|
||||
public static set(val: Partial<ConfigValue>) {
|
||||
if (!config || !val) return;
|
||||
config = OrmUtils.mergeDeep(config);
|
||||
|
||||
return applyConfig(config);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: better types
|
||||
@@ -98,13 +96,12 @@ const generatePairs = (obj: object | null, key = ""): ConfigEntity[] => {
|
||||
|
||||
async function applyConfig(val: ConfigValue) {
|
||||
if (process.env.CONFIG_PATH)
|
||||
if (!process.env.CONFIG_READONLY)
|
||||
await fs.writeFile(overridePath, JSON.stringify(val, null, 4));
|
||||
if (!process.env.CONFIG_READONLY) await fs.writeFile(overridePath, JSON.stringify(val, null, 4));
|
||||
else console.log("[WARNING] JSON config file in use, and writing is disabled! Programmatic config changes will not be persisted, and your config will not get updated!");
|
||||
else {
|
||||
const pairs = generatePairs(val);
|
||||
// keys are sorted to try to influence database order...
|
||||
await Promise.all(pairs.sort((x, y) => x.key > y.key ? 1 : -1).map((pair) => pair.save()));
|
||||
await Promise.all(pairs.sort((x, y) => (x.key > y.key ? 1 : -1)).map((pair) => pair.save()));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
@@ -122,8 +119,7 @@ function pairsToConfig(pairs: ConfigEntity[]) {
|
||||
let i = 0;
|
||||
|
||||
for (const key of keys) {
|
||||
if (!isNaN(Number(key)) && !prevObj[prev]?.length)
|
||||
prevObj[prev] = obj = [];
|
||||
if (!isNaN(Number(key)) && !prevObj[prev]?.length) prevObj[prev] = obj = [];
|
||||
if (i++ === keys.length - 1) obj[key] = p.value;
|
||||
else if (!obj[key]) obj[key] = {};
|
||||
|
||||
@@ -143,7 +139,7 @@ const validateConfig = async () => {
|
||||
|
||||
for (const row in config) {
|
||||
// extension methods...
|
||||
if(typeof config[row] === "function") continue;
|
||||
if (typeof config[row] === "function") continue;
|
||||
|
||||
try {
|
||||
const found = await ConfigEntity.findOne({
|
||||
@@ -152,11 +148,7 @@ const validateConfig = async () => {
|
||||
if (!found) continue;
|
||||
config[row] = found;
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`Config key '${config[row].key}' has invalid JSON value : ${
|
||||
(e as Error)?.message
|
||||
}`,
|
||||
);
|
||||
console.error(`Config key '${config[row].key}' has invalid JSON value : ${(e as Error)?.message}`);
|
||||
hasErrored = true;
|
||||
}
|
||||
}
|
||||
@@ -164,9 +156,7 @@ const validateConfig = async () => {
|
||||
console.log("[Config] Total config load time:", new Date().getTime() - totalStartTime.getTime(), "ms");
|
||||
|
||||
if (hasErrored) {
|
||||
console.error(
|
||||
"[Config] Your config has invalid values. Fix them first https://docs.spacebar.chat/setup/server/configuration",
|
||||
);
|
||||
console.error("[Config] Your config has invalid values. Fix them first https://docs.spacebar.chat/setup/server/configuration");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -194,16 +184,14 @@ function validateFinalConfig(config: ConfigValue) {
|
||||
}
|
||||
}
|
||||
|
||||
assertConfig("api_endpointPublic", v => v != null, "A valid public API endpoint URL, ex. \"http://localhost:3001/api/v9\"");
|
||||
assertConfig("cdn_endpointPublic", v => v != null, "A valid public CDN endpoint URL, ex. \"http://localhost:3003/\"");
|
||||
assertConfig("cdn_endpointPrivate", v => v != null, "A valid private CDN endpoint URL, ex. \"http://localhost:3003/\" - must be routable from the API server!");
|
||||
assertConfig("gateway_endpointPublic", v => v != null, "A valid public gateway endpoint URL, ex. \"ws://localhost:3002/\"");
|
||||
assertConfig("api_endpointPublic", (v) => v != null, 'A valid public API endpoint URL, ex. "http://localhost:3001/api/v9"');
|
||||
assertConfig("cdn_endpointPublic", (v) => v != null, 'A valid public CDN endpoint URL, ex. "http://localhost:3003/"');
|
||||
assertConfig("cdn_endpointPrivate", (v) => v != null, 'A valid private CDN endpoint URL, ex. "http://localhost:3003/" - must be routable from the API server!');
|
||||
assertConfig("gateway_endpointPublic", (v) => v != null, 'A valid public gateway endpoint URL, ex. "ws://localhost:3002/"');
|
||||
|
||||
if (hasErrors) {
|
||||
console.error(
|
||||
"[Config] Your config has invalid values. Fix them first https://docs.spacebar.chat/setup/server/configuration",
|
||||
);
|
||||
console.error("[Config] Your config has invalid values. Fix them first https://docs.spacebar.chat/setup/server/configuration");
|
||||
console.error("[Config] Hint: if you're just testing with bundle (`npm run start`), you can set all endpoint URLs to [proto]://localhost:3001");
|
||||
process.exit(1);
|
||||
} else console.log("[Config] Configuration validated successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
+118
-514
@@ -145,13 +145,7 @@ export const ShardEvents = {
|
||||
* sidebar for more information.</warn>
|
||||
* @typedef {string} PartialType
|
||||
*/
|
||||
export const PartialTypes = keyMirror([
|
||||
"USER",
|
||||
"CHANNEL",
|
||||
"GUILD_MEMBER",
|
||||
"MESSAGE",
|
||||
"REACTION",
|
||||
]);
|
||||
export const PartialTypes = keyMirror(["USER", "CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION"]);
|
||||
|
||||
/**
|
||||
* The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events:
|
||||
@@ -281,9 +275,7 @@ export const MessageTypes = [
|
||||
* * REPLY
|
||||
* @typedef {string} SystemMessageType
|
||||
*/
|
||||
export const SystemMessageTypes = MessageTypes.filter(
|
||||
(type: string | null) => type && type !== "DEFAULT" && type !== "REPLY",
|
||||
);
|
||||
export const SystemMessageTypes = MessageTypes.filter((type: string | null) => type && type !== "DEFAULT" && type !== "REPLY");
|
||||
|
||||
/**
|
||||
* <info>Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users</info>
|
||||
@@ -296,14 +288,7 @@ export const SystemMessageTypes = MessageTypes.filter(
|
||||
* * COMPETING
|
||||
* @typedef {string} ActivityType
|
||||
*/
|
||||
export const ActivityTypes = [
|
||||
"PLAYING",
|
||||
"STREAMING",
|
||||
"LISTENING",
|
||||
"WATCHING",
|
||||
"CUSTOM_STATUS",
|
||||
"COMPETING",
|
||||
];
|
||||
export const ActivityTypes = ["PLAYING", "STREAMING", "LISTENING", "WATCHING", "CUSTOM_STATUS", "COMPETING"];
|
||||
|
||||
export const ChannelTypes = {
|
||||
TEXT: 0,
|
||||
@@ -373,11 +358,7 @@ export const Colors = {
|
||||
* * ALL_MEMBERS
|
||||
* @typedef {string} ExplicitContentFilterLevel
|
||||
*/
|
||||
export const ExplicitContentFilterLevels = [
|
||||
"DISABLED",
|
||||
"MEMBERS_WITHOUT_ROLES",
|
||||
"ALL_MEMBERS",
|
||||
];
|
||||
export const ExplicitContentFilterLevels = ["DISABLED", "MEMBERS_WITHOUT_ROLES", "ALL_MEMBERS"];
|
||||
|
||||
/**
|
||||
* The value set for the verification levels for a guild:
|
||||
@@ -388,13 +369,7 @@ export const ExplicitContentFilterLevels = [
|
||||
* * VERY_HIGH
|
||||
* @typedef {string} VerificationLevel
|
||||
*/
|
||||
export const VerificationLevels = [
|
||||
"NONE",
|
||||
"LOW",
|
||||
"MEDIUM",
|
||||
"HIGH",
|
||||
"VERY_HIGH",
|
||||
];
|
||||
export const VerificationLevels = ["NONE", "LOW", "MEDIUM", "HIGH", "VERY_HIGH"];
|
||||
|
||||
/**
|
||||
* An error encountered while performing an API request. Here are the potential errors:
|
||||
@@ -541,10 +516,7 @@ export const VerificationLevels = [
|
||||
*/
|
||||
export const DiscordApiErrors = {
|
||||
//https://discord.com/developers/docs/topics/opcodes-and-status-codes#json-json-error-codes
|
||||
GENERAL_ERROR: new ApiError(
|
||||
"General error (such as a malformed request body, amongst other things)",
|
||||
0,
|
||||
),
|
||||
GENERAL_ERROR: new ApiError("General error (such as a malformed request body, amongst other things)", 0),
|
||||
UNKNOWN_ACCOUNT: new ApiError("Unknown account", 10001),
|
||||
UNKNOWN_APPLICATION: new ApiError("Unknown application", 10002),
|
||||
UNKNOWN_CHANNEL: new ApiError("Unknown channel", 10003),
|
||||
@@ -570,420 +542,122 @@ export const DiscordApiErrors = {
|
||||
UNKNOWN_BUILD: new ApiError("Unknown build", 10030),
|
||||
UNKNOWN_LOBBY: new ApiError("Unknown lobby", 10031),
|
||||
UNKNOWN_BRANCH: new ApiError("Unknown branch", 10032),
|
||||
UNKNOWN_STORE_DIRECTORY_LAYOUT: new ApiError(
|
||||
"Unknown store directory layout",
|
||||
10033,
|
||||
),
|
||||
UNKNOWN_STORE_DIRECTORY_LAYOUT: new ApiError("Unknown store directory layout", 10033),
|
||||
UNKNOWN_REDISTRIBUTABLE: new ApiError("Unknown redistributable", 10036),
|
||||
UNKNOWN_GIFT_CODE: new ApiError("Unknown gift code", 10038),
|
||||
UNKNOWN_STREAM: new ApiError("Unknown stream", 10049),
|
||||
UNKNOWN_PREMIUM_SERVER_SUBSCRIBE_COOLDOWN: new ApiError(
|
||||
"Unknown premium server subscribe cooldown",
|
||||
10050,
|
||||
),
|
||||
UNKNOWN_PREMIUM_SERVER_SUBSCRIBE_COOLDOWN: new ApiError("Unknown premium server subscribe cooldown", 10050),
|
||||
UNKNOWN_GUILD_TEMPLATE: new ApiError("Unknown guild template", 10057),
|
||||
UNKNOWN_DISCOVERABLE_SERVER_CATEGORY: new ApiError(
|
||||
"Unknown discoverable server category",
|
||||
10059,
|
||||
),
|
||||
UNKNOWN_DISCOVERABLE_SERVER_CATEGORY: new ApiError("Unknown discoverable server category", 10059),
|
||||
UNKNOWN_STICKER: new ApiError("Unknown sticker", 10060),
|
||||
UNKNOWN_INTERACTION: new ApiError("Unknown interaction", 10062),
|
||||
UNKNOWN_APPLICATION_COMMAND: new ApiError(
|
||||
"Unknown application command",
|
||||
10063,
|
||||
),
|
||||
UNKNOWN_APPLICATION_COMMAND_PERMISSIONS: new ApiError(
|
||||
"Unknown application command permissions",
|
||||
10066,
|
||||
),
|
||||
UNKNOWN_APPLICATION_COMMAND: new ApiError("Unknown application command", 10063),
|
||||
UNKNOWN_APPLICATION_COMMAND_PERMISSIONS: new ApiError("Unknown application command permissions", 10066),
|
||||
UNKNOWN_STAGE_INSTANCE: new ApiError("Unknown Stage Instance", 10067),
|
||||
UNKNOWN_GUILD_MEMBER_VERIFICATION_FORM: new ApiError(
|
||||
"Unknown Guild Member Verification Form",
|
||||
10068,
|
||||
),
|
||||
UNKNOWN_GUILD_WELCOME_SCREEN: new ApiError(
|
||||
"Unknown Guild Welcome Screen",
|
||||
10069,
|
||||
),
|
||||
UNKNOWN_GUILD_SCHEDULED_EVENT: new ApiError(
|
||||
"Unknown Guild Scheduled Event",
|
||||
10070,
|
||||
),
|
||||
UNKNOWN_GUILD_SCHEDULED_EVENT_USER: new ApiError(
|
||||
"Unknown Guild Scheduled Event User",
|
||||
10071,
|
||||
),
|
||||
BOT_PROHIBITED_ENDPOINT: new ApiError(
|
||||
"Bots cannot use this endpoint",
|
||||
20001,
|
||||
),
|
||||
UNKNOWN_GUILD_MEMBER_VERIFICATION_FORM: new ApiError("Unknown Guild Member Verification Form", 10068),
|
||||
UNKNOWN_GUILD_WELCOME_SCREEN: new ApiError("Unknown Guild Welcome Screen", 10069),
|
||||
UNKNOWN_GUILD_SCHEDULED_EVENT: new ApiError("Unknown Guild Scheduled Event", 10070),
|
||||
UNKNOWN_GUILD_SCHEDULED_EVENT_USER: new ApiError("Unknown Guild Scheduled Event User", 10071),
|
||||
BOT_PROHIBITED_ENDPOINT: new ApiError("Bots cannot use this endpoint", 20001),
|
||||
BOT_ONLY_ENDPOINT: new ApiError("Only bots can use this endpoint", 20002),
|
||||
EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT: new ApiError(
|
||||
"Explicit content cannot be sent to the desired recipient(s)",
|
||||
20009,
|
||||
),
|
||||
ACTION_NOT_AUTHORIZED_ON_APPLICATION: new ApiError(
|
||||
"You are not authorized to perform this action on this application",
|
||||
20012,
|
||||
),
|
||||
SLOWMODE_RATE_LIMIT: new ApiError(
|
||||
"This action cannot be performed due to slowmode rate limit",
|
||||
20016,
|
||||
),
|
||||
ONLY_OWNER: new ApiError(
|
||||
"Only the owner of this account can perform this action",
|
||||
20018,
|
||||
),
|
||||
ANNOUNCEMENT_RATE_LIMITS: new ApiError(
|
||||
"This message cannot be edited due to announcement rate limits",
|
||||
20022,
|
||||
),
|
||||
CHANNEL_WRITE_RATELIMIT: new ApiError(
|
||||
"The channel you are writing has hit the write rate limit",
|
||||
20028,
|
||||
),
|
||||
WORDS_NOT_ALLOWED: new ApiError(
|
||||
"Your Stage topic, server name, server description, or channel names contain words that are not allowed",
|
||||
20031,
|
||||
),
|
||||
GUILD_PREMIUM_LEVEL_TOO_LOW: new ApiError(
|
||||
"Guild premium subscription level too low",
|
||||
20035,
|
||||
),
|
||||
MAXIMUM_GUILDS: new ApiError(
|
||||
"Maximum number of guilds reached ({})",
|
||||
30001,
|
||||
undefined,
|
||||
["100"],
|
||||
),
|
||||
MAXIMUM_FRIENDS: new ApiError(
|
||||
"Maximum number of friends reached ({})",
|
||||
30002,
|
||||
undefined,
|
||||
["1000"],
|
||||
),
|
||||
MAXIMUM_PINS: new ApiError(
|
||||
"Maximum number of pins reached for the channel ({})",
|
||||
30003,
|
||||
undefined,
|
||||
["50"],
|
||||
),
|
||||
MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED: new ApiError(
|
||||
"Maximum number of recipients reached ({})",
|
||||
30004,
|
||||
undefined,
|
||||
["10"],
|
||||
),
|
||||
MAXIMUM_ROLES: new ApiError(
|
||||
"Maximum number of guild roles reached ({})",
|
||||
30005,
|
||||
undefined,
|
||||
["250"],
|
||||
),
|
||||
MAXIMUM_WEBHOOKS: new ApiError(
|
||||
"Maximum number of webhooks reached ({})",
|
||||
30007,
|
||||
undefined,
|
||||
["10"],
|
||||
),
|
||||
MAXIMUM_NUMBER_OF_EMOJIS_REACHED: new ApiError(
|
||||
"Maximum number of emojis reached",
|
||||
30008,
|
||||
),
|
||||
MAXIMUM_REACTIONS: new ApiError(
|
||||
"Maximum number of reactions reached ({})",
|
||||
30010,
|
||||
undefined,
|
||||
["20"],
|
||||
),
|
||||
MAXIMUM_CHANNELS: new ApiError(
|
||||
"Maximum number of guild channels reached ({})",
|
||||
30013,
|
||||
undefined,
|
||||
["500"],
|
||||
),
|
||||
MAXIMUM_ATTACHMENTS: new ApiError(
|
||||
"Maximum number of attachments in a message reached ({})",
|
||||
30015,
|
||||
undefined,
|
||||
["10"],
|
||||
),
|
||||
MAXIMUM_INVITES: new ApiError(
|
||||
"Maximum number of invites reached ({})",
|
||||
30016,
|
||||
undefined,
|
||||
["1000"],
|
||||
),
|
||||
MAXIMUM_ANIMATED_EMOJIS: new ApiError(
|
||||
"Maximum number of animated emojis reached",
|
||||
30018,
|
||||
),
|
||||
MAXIMUM_SERVER_MEMBERS: new ApiError(
|
||||
"Maximum number of server members reached",
|
||||
30019,
|
||||
),
|
||||
MAXIMUM_SERVER_CATEGORIES: new ApiError(
|
||||
"Maximum number of server categories has been reached ({})",
|
||||
30030,
|
||||
undefined,
|
||||
["5"],
|
||||
),
|
||||
GUILD_ALREADY_HAS_TEMPLATE: new ApiError(
|
||||
"Guild already has a template",
|
||||
30031,
|
||||
),
|
||||
MAXIMUM_THREAD_PARTICIPANTS: new ApiError(
|
||||
"Max number of thread participants has been reached",
|
||||
30033,
|
||||
),
|
||||
MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS: new ApiError(
|
||||
"Maximum number of bans for non-guild members have been exceeded",
|
||||
30035,
|
||||
),
|
||||
MAXIMUM_BANS_FETCHES: new ApiError(
|
||||
"Maximum number of bans fetches has been reached",
|
||||
30037,
|
||||
),
|
||||
EXPLICIT_CONTENT_CANNOT_BE_SENT_TO_RECIPIENT: new ApiError("Explicit content cannot be sent to the desired recipient(s)", 20009),
|
||||
ACTION_NOT_AUTHORIZED_ON_APPLICATION: new ApiError("You are not authorized to perform this action on this application", 20012),
|
||||
SLOWMODE_RATE_LIMIT: new ApiError("This action cannot be performed due to slowmode rate limit", 20016),
|
||||
ONLY_OWNER: new ApiError("Only the owner of this account can perform this action", 20018),
|
||||
ANNOUNCEMENT_RATE_LIMITS: new ApiError("This message cannot be edited due to announcement rate limits", 20022),
|
||||
CHANNEL_WRITE_RATELIMIT: new ApiError("The channel you are writing has hit the write rate limit", 20028),
|
||||
WORDS_NOT_ALLOWED: new ApiError("Your Stage topic, server name, server description, or channel names contain words that are not allowed", 20031),
|
||||
GUILD_PREMIUM_LEVEL_TOO_LOW: new ApiError("Guild premium subscription level too low", 20035),
|
||||
MAXIMUM_GUILDS: new ApiError("Maximum number of guilds reached ({})", 30001, undefined, ["100"]),
|
||||
MAXIMUM_FRIENDS: new ApiError("Maximum number of friends reached ({})", 30002, undefined, ["1000"]),
|
||||
MAXIMUM_PINS: new ApiError("Maximum number of pins reached for the channel ({})", 30003, undefined, ["50"]),
|
||||
MAXIMUM_NUMBER_OF_RECIPIENTS_REACHED: new ApiError("Maximum number of recipients reached ({})", 30004, undefined, ["10"]),
|
||||
MAXIMUM_ROLES: new ApiError("Maximum number of guild roles reached ({})", 30005, undefined, ["250"]),
|
||||
MAXIMUM_WEBHOOKS: new ApiError("Maximum number of webhooks reached ({})", 30007, undefined, ["10"]),
|
||||
MAXIMUM_NUMBER_OF_EMOJIS_REACHED: new ApiError("Maximum number of emojis reached", 30008),
|
||||
MAXIMUM_REACTIONS: new ApiError("Maximum number of reactions reached ({})", 30010, undefined, ["20"]),
|
||||
MAXIMUM_CHANNELS: new ApiError("Maximum number of guild channels reached ({})", 30013, undefined, ["500"]),
|
||||
MAXIMUM_ATTACHMENTS: new ApiError("Maximum number of attachments in a message reached ({})", 30015, undefined, ["10"]),
|
||||
MAXIMUM_INVITES: new ApiError("Maximum number of invites reached ({})", 30016, undefined, ["1000"]),
|
||||
MAXIMUM_ANIMATED_EMOJIS: new ApiError("Maximum number of animated emojis reached", 30018),
|
||||
MAXIMUM_SERVER_MEMBERS: new ApiError("Maximum number of server members reached", 30019),
|
||||
MAXIMUM_SERVER_CATEGORIES: new ApiError("Maximum number of server categories has been reached ({})", 30030, undefined, ["5"]),
|
||||
GUILD_ALREADY_HAS_TEMPLATE: new ApiError("Guild already has a template", 30031),
|
||||
MAXIMUM_THREAD_PARTICIPANTS: new ApiError("Max number of thread participants has been reached", 30033),
|
||||
MAXIMUM_BANS_FOR_NON_GUILD_MEMBERS: new ApiError("Maximum number of bans for non-guild members have been exceeded", 30035),
|
||||
MAXIMUM_BANS_FETCHES: new ApiError("Maximum number of bans fetches has been reached", 30037),
|
||||
MAXIMUM_STICKERS: new ApiError("Maximum number of stickers reached", 30039),
|
||||
MAXIMUM_PRUNE_REQUESTS: new ApiError(
|
||||
"Maximum number of prune requests has been reached. Try again later",
|
||||
30040,
|
||||
),
|
||||
UNAUTHORIZED: new ApiError(
|
||||
"Unauthorized. Provide a valid token and try again",
|
||||
40001,
|
||||
),
|
||||
ACCOUNT_VERIFICATION_REQUIRED: new ApiError(
|
||||
"You need to verify your account in order to perform this action",
|
||||
40002,
|
||||
),
|
||||
OPENING_DIRECT_MESSAGES_TOO_FAST: new ApiError(
|
||||
"You are opening direct messages too fast",
|
||||
40003,
|
||||
),
|
||||
REQUEST_ENTITY_TOO_LARGE: new ApiError(
|
||||
"Request entity too large. Try sending something smaller in size",
|
||||
40005,
|
||||
),
|
||||
FEATURE_TEMPORARILY_DISABLED: new ApiError(
|
||||
"This feature has been temporarily disabled server-side",
|
||||
40006,
|
||||
),
|
||||
MAXIMUM_PRUNE_REQUESTS: new ApiError("Maximum number of prune requests has been reached. Try again later", 30040),
|
||||
UNAUTHORIZED: new ApiError("Unauthorized. Provide a valid token and try again", 40001),
|
||||
ACCOUNT_VERIFICATION_REQUIRED: new ApiError("You need to verify your account in order to perform this action", 40002),
|
||||
OPENING_DIRECT_MESSAGES_TOO_FAST: new ApiError("You are opening direct messages too fast", 40003),
|
||||
REQUEST_ENTITY_TOO_LARGE: new ApiError("Request entity too large. Try sending something smaller in size", 40005),
|
||||
FEATURE_TEMPORARILY_DISABLED: new ApiError("This feature has been temporarily disabled server-side", 40006),
|
||||
USER_BANNED: new ApiError("The user is banned from this guild", 40007),
|
||||
CONNECTION_REVOKED: new ApiError(
|
||||
"The connection has been revoked",
|
||||
40012,
|
||||
400,
|
||||
),
|
||||
TARGET_USER_IS_NOT_CONNECTED_TO_VOICE: new ApiError(
|
||||
"Target user is not connected to voice",
|
||||
40032,
|
||||
),
|
||||
ALREADY_CROSSPOSTED: new ApiError(
|
||||
"This message has already been crossposted",
|
||||
40033,
|
||||
),
|
||||
APPLICATION_COMMAND_ALREADY_EXISTS: new ApiError(
|
||||
"An application command with that name already exists",
|
||||
40041,
|
||||
),
|
||||
CONNECTION_REVOKED: new ApiError("The connection has been revoked", 40012, 400),
|
||||
TARGET_USER_IS_NOT_CONNECTED_TO_VOICE: new ApiError("Target user is not connected to voice", 40032),
|
||||
ALREADY_CROSSPOSTED: new ApiError("This message has already been crossposted", 40033),
|
||||
APPLICATION_COMMAND_ALREADY_EXISTS: new ApiError("An application command with that name already exists", 40041),
|
||||
MISSING_ACCESS: new ApiError("Missing access", 50001),
|
||||
INVALID_ACCOUNT_TYPE: new ApiError("Invalid account type", 50002),
|
||||
CANNOT_EXECUTE_ON_DM: new ApiError(
|
||||
"Cannot execute action on a DM channel",
|
||||
50003,
|
||||
),
|
||||
CANNOT_EXECUTE_ON_DM: new ApiError("Cannot execute action on a DM channel", 50003),
|
||||
EMBED_DISABLED: new ApiError("Widget Disabled", 50004),
|
||||
CANNOT_EDIT_MESSAGE_BY_OTHER: new ApiError(
|
||||
"Cannot edit a message authored by another user",
|
||||
50005,
|
||||
),
|
||||
CANNOT_SEND_EMPTY_MESSAGE: new ApiError(
|
||||
"Cannot send an empty message",
|
||||
50006,
|
||||
),
|
||||
CANNOT_MESSAGE_USER: new ApiError(
|
||||
"Cannot send messages to this user",
|
||||
50007,
|
||||
),
|
||||
CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: new ApiError(
|
||||
"Cannot send messages in a voice channel",
|
||||
50008,
|
||||
),
|
||||
CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: new ApiError(
|
||||
"Channel verification level is too high for you to gain access",
|
||||
50009,
|
||||
),
|
||||
OAUTH2_APPLICATION_BOT_ABSENT: new ApiError(
|
||||
"OAuth2 application does not have a bot",
|
||||
50010,
|
||||
),
|
||||
MAXIMUM_OAUTH2_APPLICATIONS: new ApiError(
|
||||
"OAuth2 application limit reached",
|
||||
50011,
|
||||
),
|
||||
CANNOT_EDIT_MESSAGE_BY_OTHER: new ApiError("Cannot edit a message authored by another user", 50005),
|
||||
CANNOT_SEND_EMPTY_MESSAGE: new ApiError("Cannot send an empty message", 50006),
|
||||
CANNOT_MESSAGE_USER: new ApiError("Cannot send messages to this user", 50007),
|
||||
CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: new ApiError("Cannot send messages in a voice channel", 50008),
|
||||
CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: new ApiError("Channel verification level is too high for you to gain access", 50009),
|
||||
OAUTH2_APPLICATION_BOT_ABSENT: new ApiError("OAuth2 application does not have a bot", 50010),
|
||||
MAXIMUM_OAUTH2_APPLICATIONS: new ApiError("OAuth2 application limit reached", 50011),
|
||||
INVALID_OAUTH_STATE: new ApiError("Invalid OAuth2 state", 50012),
|
||||
MISSING_PERMISSIONS: new ApiError(
|
||||
"You lack permissions to perform that action ({})",
|
||||
50013,
|
||||
undefined,
|
||||
[""],
|
||||
),
|
||||
INVALID_AUTHENTICATION_TOKEN: new ApiError(
|
||||
"Invalid authentication token provided",
|
||||
50014,
|
||||
),
|
||||
MISSING_PERMISSIONS: new ApiError("You lack permissions to perform that action ({})", 50013, undefined, [""]),
|
||||
INVALID_AUTHENTICATION_TOKEN: new ApiError("Invalid authentication token provided", 50014),
|
||||
NOTE_TOO_LONG: new ApiError("Note was too long", 50015),
|
||||
INVALID_BULK_DELETE_QUANTITY: new ApiError(
|
||||
"Provided too few or too many messages to delete. Must provide at least {} and fewer than {} messages to delete",
|
||||
50016,
|
||||
undefined,
|
||||
["2", "100"],
|
||||
),
|
||||
CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: new ApiError(
|
||||
"A message can only be pinned to the channel it was sent in",
|
||||
50019,
|
||||
),
|
||||
INVALID_OR_TAKEN_INVITE_CODE: new ApiError(
|
||||
"Invite code was either invalid or taken",
|
||||
50020,
|
||||
),
|
||||
CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: new ApiError(
|
||||
"Cannot execute action on a system message",
|
||||
50021,
|
||||
),
|
||||
CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE: new ApiError(
|
||||
"Cannot execute action on this channel type",
|
||||
50024,
|
||||
),
|
||||
INVALID_OAUTH_TOKEN: new ApiError(
|
||||
"Invalid OAuth2 access token provided",
|
||||
50025,
|
||||
),
|
||||
MISSING_REQUIRED_OAUTH2_SCOPE: new ApiError(
|
||||
"Missing required OAuth2 scope",
|
||||
50026,
|
||||
),
|
||||
INVALID_WEBHOOK_TOKEN_PROVIDED: new ApiError(
|
||||
"Invalid webhook token provided",
|
||||
50027,
|
||||
),
|
||||
INVALID_BULK_DELETE_QUANTITY: new ApiError("Provided too few or too many messages to delete. Must provide at least {} and fewer than {} messages to delete", 50016, undefined, [
|
||||
"2",
|
||||
"100",
|
||||
]),
|
||||
CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: new ApiError("A message can only be pinned to the channel it was sent in", 50019),
|
||||
INVALID_OR_TAKEN_INVITE_CODE: new ApiError("Invite code was either invalid or taken", 50020),
|
||||
CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: new ApiError("Cannot execute action on a system message", 50021),
|
||||
CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE: new ApiError("Cannot execute action on this channel type", 50024),
|
||||
INVALID_OAUTH_TOKEN: new ApiError("Invalid OAuth2 access token provided", 50025),
|
||||
MISSING_REQUIRED_OAUTH2_SCOPE: new ApiError("Missing required OAuth2 scope", 50026),
|
||||
INVALID_WEBHOOK_TOKEN_PROVIDED: new ApiError("Invalid webhook token provided", 50027),
|
||||
INVALID_ROLE: new ApiError("Invalid role", 50028),
|
||||
INVALID_RECIPIENT: new ApiError("Invalid Recipient(s)", 50033),
|
||||
BULK_DELETE_MESSAGE_TOO_OLD: new ApiError(
|
||||
"A message provided was too old to bulk delete",
|
||||
50034,
|
||||
),
|
||||
INVALID_FORM_BODY: new ApiError(
|
||||
"Invalid form body (returned for both application/json and multipart/form-data bodies), or invalid Content-Type provided",
|
||||
50035,
|
||||
),
|
||||
INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: new ApiError(
|
||||
"An invite was accepted to a guild the application's bot is not in",
|
||||
50036,
|
||||
),
|
||||
BULK_DELETE_MESSAGE_TOO_OLD: new ApiError("A message provided was too old to bulk delete", 50034),
|
||||
INVALID_FORM_BODY: new ApiError("Invalid form body (returned for both application/json and multipart/form-data bodies), or invalid Content-Type provided", 50035),
|
||||
INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: new ApiError("An invite was accepted to a guild the application's bot is not in", 50036),
|
||||
INVALID_API_VERSION: new ApiError("Invalid API version provided", 50041),
|
||||
FILE_EXCEEDS_MAXIMUM_SIZE: new ApiError(
|
||||
"File uploaded exceeds the maximum size",
|
||||
50045,
|
||||
),
|
||||
FILE_EXCEEDS_MAXIMUM_SIZE: new ApiError("File uploaded exceeds the maximum size", 50045),
|
||||
INVALID_FILE_UPLOADED: new ApiError("Invalid file uploaded", 50046),
|
||||
CANNOT_SELF_REDEEM_GIFT: new ApiError(
|
||||
"Cannot self-redeem this gift",
|
||||
50054,
|
||||
),
|
||||
PAYMENT_SOURCE_REQUIRED: new ApiError(
|
||||
"Payment source required to redeem gift",
|
||||
50070,
|
||||
),
|
||||
CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: new ApiError(
|
||||
"Cannot delete a channel required for Community guilds",
|
||||
50074,
|
||||
),
|
||||
CANNOT_SELF_REDEEM_GIFT: new ApiError("Cannot self-redeem this gift", 50054),
|
||||
PAYMENT_SOURCE_REQUIRED: new ApiError("Payment source required to redeem gift", 50070),
|
||||
CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: new ApiError("Cannot delete a channel required for Community guilds", 50074),
|
||||
INVALID_STICKER_SENT: new ApiError("Invalid sticker sent", 50081),
|
||||
CANNOT_EDIT_ARCHIVED_THREAD: new ApiError(
|
||||
"Tried to perform an operation on an archived thread, such as editing a message or adding a user to the thread",
|
||||
50083,
|
||||
),
|
||||
INVALID_THREAD_NOTIFICATION_SETTINGS: new ApiError(
|
||||
"Invalid thread notification settings",
|
||||
50084,
|
||||
),
|
||||
BEFORE_EARLIER_THAN_THREAD_CREATION_DATE: new ApiError(
|
||||
"before value is earlier than the thread creation date",
|
||||
50085,
|
||||
),
|
||||
SERVER_NOT_AVAILABLE_IN_YOUR_LOCATION: new ApiError(
|
||||
"This server is not available in your location",
|
||||
50095,
|
||||
),
|
||||
SERVER_NEEDS_MONETIZATION_ENABLED: new ApiError(
|
||||
"This server needs monetization enabled in order to perform this action",
|
||||
50097,
|
||||
),
|
||||
TWO_FACTOR_REQUIRED: new ApiError(
|
||||
"Two factor is required for this operation",
|
||||
60003,
|
||||
),
|
||||
NO_USERS_WITH_DISCORDTAG_EXIST: new ApiError(
|
||||
"No users with DiscordTag exist",
|
||||
80004,
|
||||
),
|
||||
CANNOT_EDIT_ARCHIVED_THREAD: new ApiError("Tried to perform an operation on an archived thread, such as editing a message or adding a user to the thread", 50083),
|
||||
INVALID_THREAD_NOTIFICATION_SETTINGS: new ApiError("Invalid thread notification settings", 50084),
|
||||
BEFORE_EARLIER_THAN_THREAD_CREATION_DATE: new ApiError("before value is earlier than the thread creation date", 50085),
|
||||
SERVER_NOT_AVAILABLE_IN_YOUR_LOCATION: new ApiError("This server is not available in your location", 50095),
|
||||
SERVER_NEEDS_MONETIZATION_ENABLED: new ApiError("This server needs monetization enabled in order to perform this action", 50097),
|
||||
TWO_FACTOR_REQUIRED: new ApiError("Two factor is required for this operation", 60003),
|
||||
NO_USERS_WITH_DISCORDTAG_EXIST: new ApiError("No users with DiscordTag exist", 80004),
|
||||
REACTION_BLOCKED: new ApiError("Reaction was blocked", 90001),
|
||||
RESOURCE_OVERLOADED: new ApiError(
|
||||
"API resource is currently overloaded. Try again a little later",
|
||||
130000,
|
||||
),
|
||||
RESOURCE_OVERLOADED: new ApiError("API resource is currently overloaded. Try again a little later", 130000),
|
||||
STAGE_ALREADY_OPEN: new ApiError("The Stage is already open", 150006),
|
||||
THREAD_ALREADY_CREATED_FOR_THIS_MESSAGE: new ApiError(
|
||||
"A thread has already been created for this message",
|
||||
160004,
|
||||
),
|
||||
THREAD_ALREADY_CREATED_FOR_THIS_MESSAGE: new ApiError("A thread has already been created for this message", 160004),
|
||||
THREAD_IS_LOCKED: new ApiError("Thread is locked", 160005),
|
||||
MAXIMUM_NUMBER_OF_ACTIVE_THREADS: new ApiError(
|
||||
"Maximum number of active threads reached",
|
||||
160006,
|
||||
),
|
||||
MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS: new ApiError(
|
||||
"Maximum number of active announcement threads reached",
|
||||
160007,
|
||||
),
|
||||
INVALID_JSON_FOR_UPLOADED_LOTTIE_FILE: new ApiError(
|
||||
"Invalid JSON for uploaded Lottie file",
|
||||
170001,
|
||||
),
|
||||
LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES: new ApiError(
|
||||
"Uploaded Lotties cannot contain rasterized images such as PNG or JPEG",
|
||||
170002,
|
||||
),
|
||||
STICKER_MAXIMUM_FRAMERATE: new ApiError(
|
||||
"Sticker maximum framerate exceeded",
|
||||
170003,
|
||||
),
|
||||
STICKER_MAXIMUM_FRAME_COUNT: new ApiError(
|
||||
"Sticker frame count exceeds maximum of {} frames",
|
||||
170004,
|
||||
undefined,
|
||||
["1000"],
|
||||
),
|
||||
LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS: new ApiError(
|
||||
"Lottie animation maximum dimensions exceeded",
|
||||
170005,
|
||||
),
|
||||
STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE: new ApiError(
|
||||
"Sticker frame rate is either too small or too large",
|
||||
170006,
|
||||
),
|
||||
STICKER_ANIMATION_DURATION_MAXIMUM: new ApiError(
|
||||
"Sticker animation duration exceeds maximum of {} seconds",
|
||||
170007,
|
||||
undefined,
|
||||
["5"],
|
||||
),
|
||||
AUTOMODERATOR_BLOCK: new ApiError(
|
||||
"Message was blocked by automatic moderation",
|
||||
200000,
|
||||
),
|
||||
MAXIMUM_NUMBER_OF_ACTIVE_THREADS: new ApiError("Maximum number of active threads reached", 160006),
|
||||
MAXIMUM_NUMBER_OF_ACTIVE_ANNOUNCEMENT_THREADS: new ApiError("Maximum number of active announcement threads reached", 160007),
|
||||
INVALID_JSON_FOR_UPLOADED_LOTTIE_FILE: new ApiError("Invalid JSON for uploaded Lottie file", 170001),
|
||||
LOTTIES_CANNOT_CONTAIN_RASTERIZED_IMAGES: new ApiError("Uploaded Lotties cannot contain rasterized images such as PNG or JPEG", 170002),
|
||||
STICKER_MAXIMUM_FRAMERATE: new ApiError("Sticker maximum framerate exceeded", 170003),
|
||||
STICKER_MAXIMUM_FRAME_COUNT: new ApiError("Sticker frame count exceeds maximum of {} frames", 170004, undefined, ["1000"]),
|
||||
LOTTIE_ANIMATION_MAXIMUM_DIMENSIONS: new ApiError("Lottie animation maximum dimensions exceeded", 170005),
|
||||
STICKER_FRAME_RATE_TOO_SMALL_OR_TOO_LARGE: new ApiError("Sticker frame rate is either too small or too large", 170006),
|
||||
STICKER_ANIMATION_DURATION_MAXIMUM: new ApiError("Sticker animation duration exceeds maximum of {} seconds", 170007, undefined, ["5"]),
|
||||
AUTOMODERATOR_BLOCK: new ApiError("Message was blocked by automatic moderation", 200000),
|
||||
BULK_BAN_FAILED: new ApiError("Failed to ban users", 500000),
|
||||
|
||||
//Other errors
|
||||
@@ -994,97 +668,27 @@ export const DiscordApiErrors = {
|
||||
* An error encountered while performing an API request (Spacebar only). Here are the potential errors:
|
||||
*/
|
||||
export const SpacebarApiErrors = {
|
||||
MANUALLY_TRIGGERED_ERROR: new ApiError(
|
||||
"This is an artificial error",
|
||||
1,
|
||||
500,
|
||||
),
|
||||
PREMIUM_DISABLED_FOR_GUILD: new ApiError(
|
||||
"This guild cannot be boosted",
|
||||
25001,
|
||||
),
|
||||
NO_FURTHER_PREMIUM: new ApiError(
|
||||
"This guild does not receive further boosts",
|
||||
25002,
|
||||
),
|
||||
GUILD_PREMIUM_DISABLED_FOR_YOU: new ApiError(
|
||||
"This guild cannot be boosted by you",
|
||||
25003,
|
||||
403,
|
||||
),
|
||||
MANUALLY_TRIGGERED_ERROR: new ApiError("This is an artificial error", 1, 500),
|
||||
PREMIUM_DISABLED_FOR_GUILD: new ApiError("This guild cannot be boosted", 25001),
|
||||
NO_FURTHER_PREMIUM: new ApiError("This guild does not receive further boosts", 25002),
|
||||
GUILD_PREMIUM_DISABLED_FOR_YOU: new ApiError("This guild cannot be boosted by you", 25003, 403),
|
||||
CANNOT_FRIEND_SELF: new ApiError("Cannot friend oneself", 25009),
|
||||
USER_SPECIFIC_INVITE_WRONG_RECIPIENT: new ApiError(
|
||||
"This invite is not meant for you",
|
||||
25010,
|
||||
),
|
||||
USER_SPECIFIC_INVITE_WRONG_RECIPIENT: new ApiError("This invite is not meant for you", 25010),
|
||||
USER_SPECIFIC_INVITE_FAILED: new ApiError("Failed to invite user", 25011),
|
||||
CANNOT_MODIFY_USER_GROUP: new ApiError(
|
||||
"This user cannot manipulate this group",
|
||||
25050,
|
||||
403,
|
||||
),
|
||||
CANNOT_REMOVE_SELF_FROM_GROUP: new ApiError(
|
||||
"This user cannot remove oneself from user group",
|
||||
25051,
|
||||
),
|
||||
CANNOT_BAN_OPERATOR: new ApiError(
|
||||
"Non-OPERATOR cannot ban OPERATOR from instance",
|
||||
25052,
|
||||
),
|
||||
CANNOT_LEAVE_GUILD: new ApiError(
|
||||
"You are not allowed to leave guilds that you joined by yourself",
|
||||
25059,
|
||||
403,
|
||||
),
|
||||
EDITS_DISABLED: new ApiError(
|
||||
"You are not allowed to edit your own messages",
|
||||
25060,
|
||||
403,
|
||||
),
|
||||
DELETE_MESSAGE_DISABLED: new ApiError(
|
||||
"You are not allowed to delete your own messages",
|
||||
25061,
|
||||
403,
|
||||
),
|
||||
FEATURE_PERMANENTLY_DISABLED: new ApiError(
|
||||
"This feature has been disabled server-side",
|
||||
45006,
|
||||
501,
|
||||
),
|
||||
FEATURE_IS_IMMUTABLE: new ApiError(
|
||||
"The feature ({}) cannot be edited.",
|
||||
45007,
|
||||
403,
|
||||
),
|
||||
MISSING_RIGHTS: new ApiError(
|
||||
"You lack rights to perform that action ({})",
|
||||
50013,
|
||||
undefined,
|
||||
[""],
|
||||
),
|
||||
CANNOT_REPLACE_BY_BACKFILL: new ApiError(
|
||||
"Cannot backfill to message ID that already exists",
|
||||
55002,
|
||||
409,
|
||||
),
|
||||
CANNOT_BACKFILL_TO_THE_FUTURE: new ApiError(
|
||||
"You cannot backfill messages in the future",
|
||||
55003,
|
||||
),
|
||||
CANNOT_GRANT_PERMISSIONS_EXCEEDING_RIGHTS: new ApiError(
|
||||
"You cannot grant permissions exceeding your own rights",
|
||||
50050,
|
||||
),
|
||||
ROUTES_LOOPING: new ApiError(
|
||||
"Loops in the route definition ({})",
|
||||
50060,
|
||||
undefined,
|
||||
[""],
|
||||
),
|
||||
CANNOT_REMOVE_ROUTE: new ApiError(
|
||||
"Cannot remove message route while it is in effect and being used",
|
||||
50061,
|
||||
),
|
||||
CANNOT_MODIFY_USER_GROUP: new ApiError("This user cannot manipulate this group", 25050, 403),
|
||||
CANNOT_REMOVE_SELF_FROM_GROUP: new ApiError("This user cannot remove oneself from user group", 25051),
|
||||
CANNOT_BAN_OPERATOR: new ApiError("Non-OPERATOR cannot ban OPERATOR from instance", 25052),
|
||||
CANNOT_LEAVE_GUILD: new ApiError("You are not allowed to leave guilds that you joined by yourself", 25059, 403),
|
||||
EDITS_DISABLED: new ApiError("You are not allowed to edit your own messages", 25060, 403),
|
||||
DELETE_MESSAGE_DISABLED: new ApiError("You are not allowed to delete your own messages", 25061, 403),
|
||||
FEATURE_PERMANENTLY_DISABLED: new ApiError("This feature has been disabled server-side", 45006, 501),
|
||||
FEATURE_IS_IMMUTABLE: new ApiError("The feature ({}) cannot be edited.", 45007, 403),
|
||||
MISSING_RIGHTS: new ApiError("You lack rights to perform that action ({})", 50013, undefined, [""]),
|
||||
CANNOT_REPLACE_BY_BACKFILL: new ApiError("Cannot backfill to message ID that already exists", 55002, 409),
|
||||
CANNOT_BACKFILL_TO_THE_FUTURE: new ApiError("You cannot backfill messages in the future", 55003),
|
||||
CANNOT_GRANT_PERMISSIONS_EXCEEDING_RIGHTS: new ApiError("You cannot grant permissions exceeding your own rights", 50050),
|
||||
ROUTES_LOOPING: new ApiError("Loops in the route definition ({})", 50060, undefined, [""]),
|
||||
CANNOT_REMOVE_ROUTE: new ApiError("Cannot remove message route while it is in effect and being used", 50061),
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,22 +52,14 @@ export class Intents extends BitField {
|
||||
INSTANCE_USER_UPDATES: BigInt(1) << BigInt(63), // all instance user updates
|
||||
};
|
||||
|
||||
static PRIVILEGED_FLAGS: BitField = new Intents(
|
||||
Intents.FLAGS.GUILD_PRESENCES |
|
||||
Intents.FLAGS.GUILD_MEMBERS |
|
||||
Intents.FLAGS.GUILD_MESSAGES_CONTENT,
|
||||
);
|
||||
static PRIVILEGED_FLAGS: BitField = new Intents(Intents.FLAGS.GUILD_PRESENCES | Intents.FLAGS.GUILD_MEMBERS | Intents.FLAGS.GUILD_MESSAGES_CONTENT);
|
||||
|
||||
static INTENT_TO_EVENTS_MAP = {
|
||||
// MESSAGE_CONTENT
|
||||
15: [],
|
||||
// TODO: aren't these guild specific?
|
||||
// AUTO_MODERATION_CONFIGURATION
|
||||
20: [
|
||||
"AUTO_MODERATION_RULE_CREATE",
|
||||
"AUTO_MODERATION_RULE_UPDATE",
|
||||
"AUTO_MODERATION_RULE_DELETE",
|
||||
],
|
||||
20: ["AUTO_MODERATION_RULE_CREATE", "AUTO_MODERATION_RULE_UPDATE", "AUTO_MODERATION_RULE_DELETE"],
|
||||
// AUTO_MODERATION_EXECUTION
|
||||
21: ["AUTO_MODERATION_ACTION_EXECUTION"],
|
||||
};
|
||||
@@ -103,11 +95,7 @@ export class Intents extends BitField {
|
||||
"THREAD_MEMBERS_UPDATE ", // *
|
||||
],
|
||||
// GUILD_BANS
|
||||
2: [
|
||||
"GUILD_AUDIT_LOG_ENTRY_CREATE",
|
||||
"GUILD_BAN_ADD",
|
||||
"GUILD_BAN_REMOVE",
|
||||
],
|
||||
2: ["GUILD_AUDIT_LOG_ENTRY_CREATE", "GUILD_BAN_ADD", "GUILD_BAN_REMOVE"],
|
||||
// GUILD_EXPRESSIONS
|
||||
3: [
|
||||
"GUILD_EMOJIS_UPDATE",
|
||||
@@ -118,12 +106,7 @@ export class Intents extends BitField {
|
||||
"GUILD_SOUNDBOARD_SOUNDS_UPDATE",
|
||||
],
|
||||
// GUILD_INTEGRATIONS
|
||||
4: [
|
||||
"GUILD_INTEGRATIONS_UPDATE",
|
||||
"INTEGRATION_CREATE",
|
||||
"INTEGRATION_UPDATE",
|
||||
"INTEGRATION_DELETE",
|
||||
],
|
||||
4: ["GUILD_INTEGRATIONS_UPDATE", "INTEGRATION_CREATE", "INTEGRATION_UPDATE", "INTEGRATION_DELETE"],
|
||||
// GUILD_WEBHOOKS
|
||||
5: ["WEBHOOKS_UPDATE"],
|
||||
// GUILD_INVITES
|
||||
@@ -133,47 +116,21 @@ export class Intents extends BitField {
|
||||
// GUILD_PRESENCES
|
||||
8: ["PRESENCE_UPDATE"],
|
||||
// GUILD_MESSAGES
|
||||
9: [
|
||||
"MESSAGE_CREATE",
|
||||
"MESSAGE_UPDATE",
|
||||
"MESSAGE_DELETE",
|
||||
"MESSAGE_DELETE_BULK",
|
||||
],
|
||||
9: ["MESSAGE_CREATE", "MESSAGE_UPDATE", "MESSAGE_DELETE", "MESSAGE_DELETE_BULK"],
|
||||
// GUILD_MESSAGE_REACTIONS
|
||||
10: [
|
||||
"MESSAGE_REACTION_ADD",
|
||||
"MESSAGE_REACTION_REMOVE",
|
||||
"MESSAGE_REACTION_REMOVE_ALL",
|
||||
"MESSAGE_REACTION_REMOVE_EMOJI",
|
||||
],
|
||||
10: ["MESSAGE_REACTION_ADD", "MESSAGE_REACTION_REMOVE", "MESSAGE_REACTION_REMOVE_ALL", "MESSAGE_REACTION_REMOVE_EMOJI"],
|
||||
// GUILD_MESSAGE_TYPING
|
||||
11: ["TYPING_START"],
|
||||
// GUILD_SCHEDULED_EVENTS
|
||||
16: [
|
||||
"GUILD_SCHEDULED_EVENT_CREATE",
|
||||
"GUILD_SCHEDULED_EVENT_UPDATE",
|
||||
"GUILD_SCHEDULED_EVENT_DELETE",
|
||||
"GUILD_SCHEDULED_EVENT_USER_ADD",
|
||||
"GUILD_SCHEDULED_EVENT_USER_REMOVE",
|
||||
],
|
||||
16: ["GUILD_SCHEDULED_EVENT_CREATE", "GUILD_SCHEDULED_EVENT_UPDATE", "GUILD_SCHEDULED_EVENT_DELETE", "GUILD_SCHEDULED_EVENT_USER_ADD", "GUILD_SCHEDULED_EVENT_USER_REMOVE"],
|
||||
// GUILD_MESSAGE_POLLS
|
||||
24: ["MESSAGE_POLL_VOTE_ADD", "MESSAGE_POLL_VOTE_REMOVE"],
|
||||
};
|
||||
static DM_INTENT_TO_EVENTS_MAP = {
|
||||
// DIRECT_MESSAGES
|
||||
12: [
|
||||
"MESSAGE_CREATE",
|
||||
"MESSAGE_UPDATE",
|
||||
"MESSAGE_DELETE",
|
||||
"CHANNEL_PINS_UPDATE",
|
||||
],
|
||||
12: ["MESSAGE_CREATE", "MESSAGE_UPDATE", "MESSAGE_DELETE", "CHANNEL_PINS_UPDATE"],
|
||||
// DIRECT_MESSAGE_REACTIONS
|
||||
13: [
|
||||
"MESSAGE_REACTION_ADD",
|
||||
"MESSAGE_REACTION_REMOVE",
|
||||
"MESSAGE_REACTION_REMOVE_ALL",
|
||||
"MESSAGE_REACTION_REMOVE_EMOJI",
|
||||
],
|
||||
13: ["MESSAGE_REACTION_ADD", "MESSAGE_REACTION_REMOVE", "MESSAGE_REACTION_REMOVE_ALL", "MESSAGE_REACTION_REMOVE_EMOJI"],
|
||||
// DIRECT_MESSAGE_TYPING
|
||||
14: ["TYPING_START"],
|
||||
// DIRECT_MESSAGE_POLLS
|
||||
|
||||
+5
-22
@@ -21,12 +21,7 @@ import { BitFieldResolvable, BitFlag } from "./BitField";
|
||||
import { User } from "../entities";
|
||||
import { HTTPError } from "lambert-server";
|
||||
|
||||
export type RightResolvable =
|
||||
| bigint
|
||||
| number
|
||||
| Rights
|
||||
| RightResolvable[]
|
||||
| RightString;
|
||||
export type RightResolvable = bigint | number | Rights | RightResolvable[] | RightString;
|
||||
|
||||
type RightString = keyof typeof Rights.FLAGS;
|
||||
// TODO: just like roles for members, users should have priviliges which combine multiple rights into one and make it easy to assign
|
||||
@@ -97,32 +92,20 @@ export class Rights extends BitField {
|
||||
};
|
||||
|
||||
any(permission: RightResolvable, checkOperator = true) {
|
||||
return (
|
||||
(checkOperator && super.any(Rights.FLAGS.OPERATOR)) ||
|
||||
super.any(permission)
|
||||
);
|
||||
return (checkOperator && super.any(Rights.FLAGS.OPERATOR)) || super.any(permission);
|
||||
}
|
||||
|
||||
has(permission: RightResolvable, checkOperator = true) {
|
||||
return (
|
||||
(checkOperator && super.has(Rights.FLAGS.OPERATOR)) ||
|
||||
super.has(permission)
|
||||
);
|
||||
return (checkOperator && super.has(Rights.FLAGS.OPERATOR)) || super.has(permission);
|
||||
}
|
||||
|
||||
hasThrow(permission: RightResolvable) {
|
||||
if (this.has(permission)) return true;
|
||||
throw new HTTPError(
|
||||
`You are missing the following rights ${permission}`,
|
||||
403,
|
||||
);
|
||||
throw new HTTPError(`You are missing the following rights ${permission}`, 403);
|
||||
}
|
||||
}
|
||||
|
||||
const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce(
|
||||
(total, val) => total | val,
|
||||
BigInt(0),
|
||||
);
|
||||
const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce((total, val) => total | val, BigInt(0));
|
||||
|
||||
export async function getRights(
|
||||
user_id: string,
|
||||
|
||||
+11
-23
@@ -41,36 +41,24 @@ export const WebAuthn: {
|
||||
},
|
||||
};
|
||||
|
||||
export async function generateWebAuthnTicket(
|
||||
challenge: string,
|
||||
): Promise<string> {
|
||||
export async function generateWebAuthnTicket(challenge: string): Promise<string> {
|
||||
return new Promise((res, rej) => {
|
||||
loadOrGenerateKeypair().then(kp=>
|
||||
jwt.sign(
|
||||
{ challenge },
|
||||
kp.privateKey,
|
||||
jwtSignOptions,
|
||||
(err, token) => {
|
||||
if (err || !token) return rej(err || "no token");
|
||||
return res(token);
|
||||
},
|
||||
)
|
||||
loadOrGenerateKeypair().then((kp) =>
|
||||
jwt.sign({ challenge }, kp.privateKey, jwtSignOptions, (err, token) => {
|
||||
if (err || !token) return rej(err || "no token");
|
||||
return res(token);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export async function verifyWebAuthnToken(token: string) {
|
||||
return new Promise((res, rej) => {
|
||||
loadOrGenerateKeypair().then(kp=>
|
||||
jwt.verify(
|
||||
token,
|
||||
kp.publicKey,
|
||||
jwtVerifyOptions,
|
||||
async (err, decoded) => {
|
||||
if (err) return rej(err);
|
||||
return res(decoded);
|
||||
},
|
||||
)
|
||||
loadOrGenerateKeypair().then((kp) =>
|
||||
jwt.verify(token, kp.publicKey, jwtVerifyOptions, async (err, decoded) => {
|
||||
if (err) return rej(err);
|
||||
return res(decoded);
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
+13
-22
@@ -34,27 +34,21 @@ export async function uploadFile(
|
||||
filename: file.originalname,
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
`${Config.get().cdn.endpointPrivate || "http://localhost:3001"}${path}`,
|
||||
{
|
||||
headers: {
|
||||
signature: Config.get().security.requestSignature,
|
||||
...form.getHeaders(),
|
||||
},
|
||||
method: "POST",
|
||||
body: form.getBuffer(),
|
||||
const response = await fetch(`${Config.get().cdn.endpointPrivate || "http://localhost:3001"}${path}`, {
|
||||
headers: {
|
||||
signature: Config.get().security.requestSignature,
|
||||
...form.getHeaders(),
|
||||
},
|
||||
);
|
||||
method: "POST",
|
||||
body: form.getBuffer(),
|
||||
});
|
||||
const result = (await response.json()) as Attachment;
|
||||
|
||||
if (response.status !== 200) throw result;
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function handleFile(
|
||||
path: string,
|
||||
body?: string,
|
||||
): Promise<string | undefined> {
|
||||
export async function handleFile(path: string, body?: string): Promise<string | undefined> {
|
||||
if (!body || !body.startsWith("data:")) return undefined;
|
||||
try {
|
||||
const mimetype = body.split(":")[1].split(";")[0];
|
||||
@@ -73,15 +67,12 @@ export async function handleFile(
|
||||
}
|
||||
|
||||
export async function deleteFile(path: string) {
|
||||
const response = await fetch(
|
||||
`${Config.get().cdn.endpointPrivate || "http://localhost:3001"}${path}`,
|
||||
{
|
||||
headers: {
|
||||
signature: Config.get().security.requestSignature,
|
||||
},
|
||||
method: "DELETE",
|
||||
const response = await fetch(`${Config.get().cdn.endpointPrivate || "http://localhost:3001"}${path}`, {
|
||||
headers: {
|
||||
signature: Config.get().security.requestSignature,
|
||||
},
|
||||
);
|
||||
method: "DELETE",
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (response.status !== 200) throw result;
|
||||
|
||||
Reference in New Issue
Block a user