oceanic.js
Version:
A NodeJS library for interfacing with Discord.
730 lines • 62.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/** @module Util */
const Routes_1 = require("./Routes");
const Errors_1 = require("./Errors");
const Constants_1 = require("../Constants");
const Member_1 = tslib_1.__importDefault(require("../structures/Member"));
const Channel_1 = tslib_1.__importDefault(require("../structures/Channel"));
const Message_1 = tslib_1.__importDefault(require("../structures/Message"));
const Entitlement_1 = tslib_1.__importDefault(require("../structures/Entitlement"));
const TestEntitlement_1 = tslib_1.__importDefault(require("../structures/TestEntitlement"));
const node_util_1 = require("node:util");
/** A general set of utilities. These are intentionally poorly documented, as they serve almost no usefulness to outside developers. */
class Util {
_client;
constructor(client) {
this._client = client;
}
static rawEmbeds(embeds) {
const data = Util.prototype.embedsToParsed(Array.isArray(embeds) ? embeds : [embeds]);
return Array.isArray(embeds) ? data : data[0];
}
static rawMessageComponents(components) {
const data = Util.prototype.componentsToParsed(Array.isArray(components) ? components : [components]);
return Array.isArray(components) ? data : data[0];
}
static rawModalComponents(components) {
const data = Util.prototype.componentsToParsed(Array.isArray(components) ? components : [components]);
return Array.isArray(components) ? data : data[0];
}
/** @hidden intentionally not documented - this is an internal function */
_convertImage(image, name) {
try {
return this.convertImage(image);
}
catch (err) {
throw new TypeError(`Invalid ${name} provided. Ensure you are providing a valid, fully-qualified base64 url.`, { cause: err });
}
}
/** @hidden intended for internal use only */
_convertSound(sound, name) {
try {
return this.convertSound(sound);
}
catch (err) {
throw new TypeError(`Invalid ${name} provided. Ensure you are providing a valid, fully-qualified base64 url.`, { cause: err });
}
}
/** @internal */
_freeze(obj, detail) {
let message = "This is an error in the library and should be reported.";
if (detail) {
message += `Detail: ${detail}`;
}
if (typeof obj !== "object" || obj === null || node_util_1.types.isProxy(obj)) {
return obj;
}
return new Proxy(obj, {
set: (target, prop, value, receiver) => {
this._client.emit("error", new Errors_1.FrozenModificationError(message, prop));
return Reflect.set(target, prop, value, receiver);
}
});
}
/** @hidden intended for internal use only */
_getLimit(name, id) {
const opt = this._client.options.collectionLimits[name];
if (typeof opt === "number") {
return opt;
}
return (id === undefined ? undefined : opt[id]) ?? opt.default ?? Infinity;
}
/** @hidden intended for internal use only */
_isModuleInstalled(name) {
try {
// eslint-disable-next-line unicorn/prefer-module
require(name);
return true;
}
catch {
return false;
}
}
_setLimit(values, defaultValue = Infinity) {
if (values === undefined) {
return defaultValue;
}
if (typeof values === "object") {
return { default: defaultValue, ...values };
}
return values;
}
componentToParsed(component) {
switch (component.type) {
case Constants_1.ComponentTypes.ACTION_ROW: {
return {
components: component.components.map(c => this.componentToParsed(c)),
type: component.type
};
}
case Constants_1.ComponentTypes.BUTTON: {
if (component.style === Constants_1.ButtonStyles.LINK)
return component;
if (component.style === Constants_1.ButtonStyles.PREMIUM) {
return {
disabled: component.disabled,
skuID: component.sku_id,
style: component.style,
type: component.type
};
}
return {
customID: component.custom_id,
disabled: component.disabled,
emoji: component.emoji,
label: component.label,
style: component.style,
type: component.type
};
}
case Constants_1.ComponentTypes.TEXT_INPUT: {
return {
customID: component.custom_id,
label: component.label,
maxLength: component.max_length,
minLength: component.min_length,
placeholder: component.placeholder,
required: component.required,
style: component.style,
type: component.type,
value: component.value
};
}
case Constants_1.ComponentTypes.STRING_SELECT:
case Constants_1.ComponentTypes.USER_SELECT:
case Constants_1.ComponentTypes.ROLE_SELECT:
case Constants_1.ComponentTypes.MENTIONABLE_SELECT:
case Constants_1.ComponentTypes.CHANNEL_SELECT: {
const parsedComponent = {
customID: component.custom_id,
disabled: component.disabled,
maxValues: component.max_values,
minValues: component.min_values,
placeholder: component.placeholder,
type: component.type
};
if (component.type !== Constants_1.ComponentTypes.STRING_SELECT && component.default_values !== undefined) {
parsedComponent.defaultValues = component.default_values;
}
if (component.type === Constants_1.ComponentTypes.STRING_SELECT) {
return { ...parsedComponent, options: component.options };
}
else if (component.type === Constants_1.ComponentTypes.CHANNEL_SELECT) {
return { ...parsedComponent, channelTypes: component.channel_types };
}
else {
return parsedComponent;
}
}
case Constants_1.ComponentTypes.TEXT_DISPLAY:
case Constants_1.ComponentTypes.THUMBNAIL:
case Constants_1.ComponentTypes.MEDIA_GALLERY:
case Constants_1.ComponentTypes.FILE:
case Constants_1.ComponentTypes.SEPARATOR: {
return component;
}
case Constants_1.ComponentTypes.CONTAINER: {
return {
accentColor: component.accent_color,
components: component.components.map(c => this.componentToParsed(c)),
spoiler: component.spoiler,
type: component.type
};
}
case Constants_1.ComponentTypes.SECTION: {
return {
type: component.type,
accessory: component.accessory ? this.componentToParsed(component.accessory) : undefined,
components: component.components.map(c => this.componentToParsed(c))
};
}
case Constants_1.ComponentTypes.LABEL: {
return {
type: component.type,
label: component.label,
description: component.description,
component: this.componentToParsed(component.component)
};
}
case Constants_1.ComponentTypes.FILE_UPLOAD: {
return {
customID: component.custom_id,
maxValues: component.max_values,
minValues: component.min_values,
required: component.required,
type: component.type
};
}
default: {
return component;
}
}
}
componentToRaw(component) {
switch (component.type) {
case Constants_1.ComponentTypes.ACTION_ROW: {
return {
type: component.type,
components: component.components.map(c => this.componentToRaw(c))
};
}
case Constants_1.ComponentTypes.BUTTON: {
if (component.style === Constants_1.ButtonStyles.LINK)
return component;
if (component.style === Constants_1.ButtonStyles.PREMIUM) {
return {
disabled: component.disabled,
sku_id: component.skuID,
style: component.style,
type: component.type
};
}
return {
custom_id: component.customID,
disabled: component.disabled,
emoji: component.emoji,
label: component.label,
style: component.style,
type: component.type
};
}
case Constants_1.ComponentTypes.TEXT_INPUT: {
return {
custom_id: component.customID,
label: component.label,
max_length: component.maxLength,
min_length: component.minLength,
placeholder: component.placeholder,
required: component.required,
style: component.style,
type: component.type,
value: component.value
};
}
case Constants_1.ComponentTypes.STRING_SELECT:
case Constants_1.ComponentTypes.USER_SELECT:
case Constants_1.ComponentTypes.ROLE_SELECT:
case Constants_1.ComponentTypes.MENTIONABLE_SELECT:
case Constants_1.ComponentTypes.CHANNEL_SELECT: {
const rawComponent = {
custom_id: component.customID,
disabled: component.disabled,
max_values: component.maxValues,
min_values: component.minValues,
placeholder: component.placeholder,
required: component.required,
type: component.type
};
if (component.type !== Constants_1.ComponentTypes.STRING_SELECT && component.defaultValues !== undefined) {
rawComponent.default_values = component.defaultValues;
}
if (component.type === Constants_1.ComponentTypes.STRING_SELECT) {
return { ...rawComponent, options: component.options };
}
else if (component.type === Constants_1.ComponentTypes.CHANNEL_SELECT) {
return { ...rawComponent, channel_types: component.channelTypes };
}
else {
return rawComponent;
}
}
case Constants_1.ComponentTypes.TEXT_DISPLAY:
case Constants_1.ComponentTypes.THUMBNAIL:
case Constants_1.ComponentTypes.MEDIA_GALLERY:
case Constants_1.ComponentTypes.FILE:
case Constants_1.ComponentTypes.SEPARATOR: {
return component;
}
case Constants_1.ComponentTypes.CONTAINER: {
return {
accent_color: component.accentColor,
components: component.components.map(c => this.componentToRaw(c)),
spoiler: component.spoiler,
type: component.type
};
}
case Constants_1.ComponentTypes.SECTION: {
return {
type: component.type,
accessory: component.accessory ? this.componentToRaw(component.accessory) : undefined,
components: component.components.map(c => this.componentToRaw(c))
};
}
case Constants_1.ComponentTypes.LABEL: {
return {
type: component.type,
label: component.label,
description: component.description,
component: this.componentToRaw(component.component)
};
}
case Constants_1.ComponentTypes.FILE_UPLOAD:
return {
custom_id: component.customID,
max_values: component.maxValues,
min_values: component.minValues,
required: component.required,
type: component.type
};
default: {
return component;
}
}
}
componentsToParsed(components) {
return components.map(component => this.componentToParsed(component));
}
componentsToRaw(components) {
return components.map(component => this.componentToRaw(component));
}
convertApplicationEmoji(raw) {
return this.convertGuildEmoji(raw);
}
convertGuildEmoji(raw) {
return {
animated: raw.animated,
available: raw.available,
id: raw.id,
managed: raw.managed,
name: raw.name,
requireColons: raw.require_colons,
roles: raw.roles,
user: raw.user ? this._client.users.update(raw.user) : undefined
};
}
convertImage(img) {
if (Buffer.isBuffer(img)) {
const b64 = img.toString("base64");
let mime;
const magicMap = [
// 47 49 46 38
["image/gif", /^47494638/],
// 89 50 4E 47
["image/png", /^89504E47/],
// FF D8 FF
["image/jpeg", /^FFD8FF/],
// 52 49 46 46 ?? ?? ?? ?? 57 45 42 50
["image/webp", /^52494646\d{8}57454250/],
// 02 27 62 20 22 0 - lottie JSON (assuming all files will start with {"v":")
["application/json", /^02276220220/]
];
for (const format of magicMap) {
if (format[1].test(this.getMagic(img, 16))) {
mime = format[0];
break;
}
}
if (!mime) {
throw new TypeError(`Failed to determine image format. (magic: ${this.getMagic(img, 16)})`);
}
img = `data:${mime};base64,${b64}`;
}
return img;
}
convertSound(audio) {
if (Buffer.isBuffer(audio)) {
const b64 = audio.toString("base64");
let mime;
const magicMap = [
// 49 44 33
["audio/mpeg", /^494433/],
// FF FB
["audio/mpeg", /^FFFB/],
// 4F 67 67 53
["audio/ogg", /^4F676753/]
];
for (const format of magicMap) {
if (format[1].test(this.getMagic(audio, 16))) {
mime = format[0];
break;
}
}
if (!mime) {
throw new TypeError(`Failed to determine sound format. (magic: ${this.getMagic(audio, 16)})`);
}
audio = `data:${mime};base64,${b64}`;
}
return audio;
}
convertSticker(raw) {
return {
asset: raw.asset,
available: raw.available,
description: raw.description,
formatType: raw.format_type,
guildID: raw.guild_id,
id: raw.id,
name: raw.name,
packID: raw.pack_id,
sortValue: raw.sort_value,
tags: raw.tags,
type: raw.type,
user: raw.user ? this._client.users.update(raw.user) : undefined
};
}
async detectMissingPrivilegedIntents(intents) {
const application = this._client["_application"] || await this._client.rest.applications.getClient();
intents ??= this._client.shards.options.intents;
this._client["_application"] ??= application;
const missing = [];
const check = (intent, allowed) => {
if ((intents & intent) === intent && !allowed.some(flag => (application.flags & flag) === flag)) {
missing.push(Constants_1.Intents[intent]);
}
};
for (const [intent, allowed] of Constants_1.PrivilegedIntentMapping) {
check(intent, allowed);
}
return missing;
}
embedsToParsed(embeds) {
return embeds.map(embed => ({
author: embed.author === undefined ? undefined : {
name: embed.author.name,
iconURL: embed.author.icon_url,
proxyIconURL: embed.author.proxy_icon_url
},
color: embed.color,
description: embed.description,
fields: embed.fields?.map(field => ({
inline: field.inline,
name: field.name,
value: field.value
})),
flags: embed.flags,
footer: embed.footer === undefined ? undefined : {
flags: embed.footer.flags,
iconURL: embed.footer.icon_url,
proxyIconURL: embed.footer.proxy_icon_url,
text: embed.footer.text
},
timestamp: embed.timestamp,
title: embed.title,
image: embed.image === undefined ? undefined : {
flags: embed.image.flags,
height: embed.image.height,
proxyURL: embed.image.proxy_url,
url: embed.image.url,
width: embed.image.width
},
provider: embed.provider === undefined ? undefined : {
name: embed.provider.name,
url: embed.provider.url
},
thumbnail: embed.thumbnail === undefined ? undefined : {
url: embed.thumbnail.url,
height: embed.thumbnail.height,
proxyURL: embed.thumbnail.proxy_url,
width: embed.thumbnail.width
},
url: embed.url,
type: embed.type,
video: embed.video === undefined ? undefined : {
height: embed.video.height,
proxyURL: embed.video.proxy_url,
url: embed.video.url,
width: embed.video.width
}
}));
}
embedsToRaw(embeds) {
return embeds.map(embed => ({
author: embed.author === undefined ? undefined : {
name: embed.author.name,
icon_url: embed.author.iconURL,
url: embed.author.url
},
color: embed.color,
description: embed.description,
fields: embed.fields?.map(field => ({
inline: field.inline,
name: field.name,
value: field.value
})),
footer: embed.footer === undefined ? undefined : {
text: embed.footer.text,
icon_url: embed.footer.iconURL
},
timestamp: embed.timestamp,
title: embed.title,
image: embed.image === undefined ? undefined : { url: embed.image.url },
thumbnail: embed.thumbnail === undefined ? undefined : { url: embed.thumbnail.url },
url: embed.url
}));
}
formatAllowedMentions(allowed) {
const result = { parse: [] };
if (!allowed) {
return this.formatAllowedMentions(this._client.options.allowedMentions);
}
if (allowed.everyone === true) {
result.parse.push("everyone");
}
if (allowed.roles === true) {
result.parse.push("roles");
}
else if (Array.isArray(allowed.roles)) {
result.roles = allowed.roles;
}
if (allowed.users === true) {
result.parse.push("users");
}
else if (Array.isArray(allowed.users)) {
result.users = allowed.users;
}
if (allowed.repliedUser === true) {
result.replied_user = true;
}
return result;
}
formatImage(url, format, size) {
if (!format || !Constants_1.ImageFormats.includes(format.toLowerCase())) {
format = url.includes("/a_") ? "gif" : this._client.options.defaultImageFormat;
}
if (!size || !Constants_1.MEDIA_PROXY_SIZES.includes(size)) {
size = this._client.options.defaultImageSize;
}
return `${Routes_1.CDN_URL}${url}.${format}?size=${size}`;
}
getMagic(file, len = 4) {
return [...new Uint8Array(file.subarray(0, len))].map(b => b.toString(16).padStart(2, "0")).join("").toUpperCase();
}
modalSubmitComponentToParsed(component) {
switch (component.type) {
case Constants_1.ComponentTypes.TEXT_INPUT: {
return {
customID: component.custom_id,
type: component.type,
value: component.value
};
}
case Constants_1.ComponentTypes.STRING_SELECT:
case Constants_1.ComponentTypes.USER_SELECT:
case Constants_1.ComponentTypes.ROLE_SELECT:
case Constants_1.ComponentTypes.MENTIONABLE_SELECT:
case Constants_1.ComponentTypes.CHANNEL_SELECT:
case Constants_1.ComponentTypes.FILE_UPLOAD: {
return {
customID: component.custom_id,
type: component.type,
values: component.values
};
}
default: {
return component;
}
}
}
modalSubmitComponentsToParsed(components) {
return components.map(row => {
if (row.type === Constants_1.ComponentTypes.ACTION_ROW) {
return {
type: row.type,
components: row.components ? row.components.map(component => this.modalSubmitComponentToParsed(component)) : undefined
};
}
else {
return {
type: row.type,
component: row.component ? this.modalSubmitComponentToParsed(row.component) : undefined
};
}
});
}
optionToParsed(option) {
return {
autocomplete: option.autocomplete,
channelTypes: option.channel_types,
choices: option.choices,
description: option.description,
descriptionLocalizations: option.description_localizations,
descriptionLocalized: option.description_localized,
max_length: option.max_length,
max_value: option.max_value,
min_length: option.min_length,
min_value: option.min_value,
name: option.name,
nameLocalizations: option.name_localizations,
nameLocalized: option.name_localized,
options: option.options?.map(o => this.optionToParsed(o)),
required: option.required,
type: option.type
};
}
optionToRaw(option) {
const opt = option;
return {
autocomplete: opt.autocomplete,
channel_types: opt.channelTypes,
choices: opt.choices?.map(choice => ({
name: choice.name,
name_localizations: choice.nameLocalizations,
value: choice.value
})),
description: opt.description,
description_localizations: opt.descriptionLocalizations,
max_length: opt.maxLength,
max_value: opt.maxValue,
min_length: opt.minLength,
min_value: opt.minValue,
name: opt.name,
name_localizations: opt.nameLocalizations,
options: opt.options?.map(o => this.optionToRaw(o)),
required: opt.required,
type: opt.type
};
}
/** @internal */
replacePollAnswer(poll, answerID, count, users) {
let answerCount = poll.results.answerCounts.find(a => a.id === answerID);
if (!answerCount) {
answerCount = {
count,
id: answerID,
users: [],
meVoted: false
};
}
answerCount.count = count;
if (users) {
answerCount.users = users;
answerCount.meVoted = (this._client["_user"] && users.includes(this._client["_user"]?.id)) ?? false;
}
}
updateChannel(channelData) {
guild: if (channelData.guild_id) {
const guild = this._client.guilds.get(channelData.guild_id);
if (guild) {
if (Constants_1.ThreadChannelTypes.includes(channelData.type)) {
if (!channelData.parent_id) {
break guild;
}
return guild.threads.update(channelData);
}
else {
return guild.channels.update(channelData);
}
}
}
switch (channelData.type) {
case Constants_1.ChannelTypes.DM: return this._client.privateChannels.update(channelData);
case Constants_1.ChannelTypes.GROUP_DM: return this._client.groupChannels.update(channelData);
default: return Channel_1.default.from(channelData, this._client);
}
}
/** @internal */
updateEntitlement(data) {
if (this._client["_application"] === undefined) {
return "subscription_id" in data && data.subscription_id ?
new Entitlement_1.default(data, this._client) :
new TestEntitlement_1.default(data, this._client);
}
else {
return this._client.application.entitlements.update(data);
}
}
/** @internal */
updateMember(guildID, memberID, member) {
const guild = this._client.guilds.get(guildID);
if (guild && this._client["_user"] && this._client.user.id === memberID) {
if (guild["_clientMember"]) {
guild["_clientMember"]["update"](member);
}
else {
guild["_clientMember"] = guild.members.update({ ...member, id: memberID }, guildID);
}
return guild["_clientMember"];
}
return guild ? guild.members.update({ ...member, id: memberID }, guildID) : new Member_1.default({ ...member, id: memberID }, this._client, guildID);
}
/** @internal */
updateMessage(data) {
const channel = this._client.getChannel(data.channel_id);
if (channel && "messages" in channel) {
return channel.messages.update(data);
}
return new Message_1.default(data, this._client);
}
/** @internal */
updatePollAnswer(poll, answerID, count, user) {
let answerCount = poll.results.answerCounts.find(a => a.id === answerID);
if (!answerCount) {
if (count === -1) {
return;
}
answerCount = {
count,
id: answerID,
users: user ? [user] : [],
meVoted: user === this._client["_user"]?.id
};
poll.results.answerCounts.push(answerCount);
return;
}
answerCount.count += count;
if (user) {
if (count === 1 && !answerCount.users.includes(user)) {
answerCount.users.push(user);
answerCount.meVoted = user === this._client["_user"]?.id;
}
else if (count === -1 && answerCount.users.includes(user)) {
answerCount.users.splice(answerCount.users.indexOf(user), 1);
if (user === this._client["_user"]?.id) {
answerCount.meVoted = false;
}
}
}
}
/** @internal */
updateThread(threadData) {
const guild = this._client.guilds.get(threadData.guild_id);
if (guild) {
return guild.threads.update(threadData);
}
return Channel_1.default.from(threadData, this._client);
}
}
exports.default = Util;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi91dGlsL1V0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUJBQW1CO0FBQ25CLHFDQUFtQztBQUNuQyxxQ0FBbUQ7QUFFbkQsNENBWXNCO0FBb0J0QiwwRUFBMEM7QUFDMUMsNEVBQTRDO0FBK0I1Qyw0RUFBNEM7QUFDNUMsb0ZBQW9EO0FBQ3BELDRGQUE0RDtBQUU1RCx5Q0FBa0M7QUFFbEMsdUlBQXVJO0FBQ3ZJLE1BQXFCLElBQUk7SUFDYixPQUFPLENBQVM7SUFFeEIsWUFBWSxNQUFjO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0lBQzFCLENBQUM7SUFJRCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQWtDO1FBQy9DLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3RGLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUlELE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxVQUE0RDtRQUNwRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FB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