aboutsummaryrefslogtreecommitdiff
path: root/src/lib/extensions
diff options
context:
space:
mode:
authorIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-12-26 17:16:32 -0500
committerIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-12-26 17:16:32 -0500
commitfc390ffc300334c396d9d06b0feaf8fbc6ed2814 (patch)
treea6282a74cf99033291ac7bc9de123ae273d528d2 /src/lib/extensions
parent062435590980b87f5b054418ed88604e26358ae9 (diff)
downloadtanzanite-fc390ffc300334c396d9d06b0feaf8fbc6ed2814.tar.gz
tanzanite-fc390ffc300334c396d9d06b0feaf8fbc6ed2814.tar.bz2
tanzanite-fc390ffc300334c396d9d06b0feaf8fbc6ed2814.zip
documentation, bug fixes etc
Diffstat (limited to 'src/lib/extensions')
-rw-r--r--src/lib/extensions/discord-akairo/BushClient.ts195
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts102
-rw-r--r--src/lib/extensions/discord-akairo/BushCommand.ts188
-rw-r--r--src/lib/extensions/discord-akairo/BushInhibitor.ts7
-rw-r--r--src/lib/extensions/discord-akairo/BushSlashMessage.ts2
-rw-r--r--src/lib/extensions/discord.js/BushActivity.ts3
-rw-r--r--src/lib/extensions/discord.js/BushApplicationCommand.ts3
-rw-r--r--src/lib/extensions/discord.js/BushApplicationCommandManager.d.ts101
-rw-r--r--src/lib/extensions/discord.js/BushApplicationCommandPermissionsManager.d.ts123
-rw-r--r--src/lib/extensions/discord.js/BushBaseGuildEmojiManager.d.ts8
-rw-r--r--src/lib/extensions/discord.js/BushBaseGuildTextChannel.ts3
-rw-r--r--src/lib/extensions/discord.js/BushBaseGuildVoiceChannel.d.ts13
-rw-r--r--src/lib/extensions/discord.js/BushButtonInteraction.ts7
-rw-r--r--src/lib/extensions/discord.js/BushCategoryChannel.ts7
-rw-r--r--src/lib/extensions/discord.js/BushChannel.d.ts14
-rw-r--r--src/lib/extensions/discord.js/BushChannelManager.d.ts20
-rw-r--r--src/lib/extensions/discord.js/BushClientEvents.d.ts29
-rw-r--r--src/lib/extensions/discord.js/BushClientUser.d.ts78
-rw-r--r--src/lib/extensions/discord.js/BushCommandInteraction.ts31
-rw-r--r--src/lib/extensions/discord.js/BushDMChannel.ts3
-rw-r--r--src/lib/extensions/discord.js/BushEmoji.ts3
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts109
-rw-r--r--src/lib/extensions/discord.js/BushGuildApplicationCommandManager.d.ts89
-rw-r--r--src/lib/extensions/discord.js/BushGuildBan.d.ts3
-rw-r--r--src/lib/extensions/discord.js/BushGuildChannel.ts9
-rw-r--r--src/lib/extensions/discord.js/BushGuildEmoji.ts3
-rw-r--r--src/lib/extensions/discord.js/BushGuildEmojiRoleManager.d.ts36
-rw-r--r--src/lib/extensions/discord.js/BushGuildManager.d.ts16
-rw-r--r--src/lib/extensions/discord.js/BushGuildMember.ts289
-rw-r--r--src/lib/extensions/discord.js/BushGuildMemberManager.d.ts131
-rw-r--r--src/lib/extensions/discord.js/BushMessage.ts10
-rw-r--r--src/lib/extensions/discord.js/BushMessageManager.d.ts84
-rw-r--r--src/lib/extensions/discord.js/BushMessageReaction.ts3
-rw-r--r--src/lib/extensions/discord.js/BushNewsChannel.ts3
-rw-r--r--src/lib/extensions/discord.js/BushPresence.ts3
-rw-r--r--src/lib/extensions/discord.js/BushReactionEmoji.ts5
-rw-r--r--src/lib/extensions/discord.js/BushRole.ts3
-rw-r--r--src/lib/extensions/discord.js/BushSelectMenuInteraction.ts7
-rw-r--r--src/lib/extensions/discord.js/BushStageChannel.ts5
-rw-r--r--src/lib/extensions/discord.js/BushStageInstance.ts3
-rw-r--r--src/lib/extensions/discord.js/BushStoreChannel.ts4
-rw-r--r--src/lib/extensions/discord.js/BushTextChannel.ts3
-rw-r--r--src/lib/extensions/discord.js/BushThreadChannel.ts3
-rw-r--r--src/lib/extensions/discord.js/BushThreadManager.d.ts57
-rw-r--r--src/lib/extensions/discord.js/BushThreadMember.ts3
-rw-r--r--src/lib/extensions/discord.js/BushThreadMemberManager.d.ts31
-rw-r--r--src/lib/extensions/discord.js/BushUser.ts9
-rw-r--r--src/lib/extensions/discord.js/BushUserManager.d.ts59
-rw-r--r--src/lib/extensions/discord.js/BushVoiceChannel.ts3
-rw-r--r--src/lib/extensions/discord.js/BushVoiceState.ts9
-rw-r--r--src/lib/extensions/global.d.ts7
51 files changed, 1636 insertions, 303 deletions
diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts
index a9e172a..d7c8b60 100644
--- a/src/lib/extensions/discord-akairo/BushClient.ts
+++ b/src/lib/extensions/discord-akairo/BushClient.ts
@@ -1,26 +1,25 @@
import type {
BushApplicationCommand,
BushBaseGuildEmojiManager,
- BushChannel,
BushChannelManager,
BushClientEvents,
BushClientUser,
BushGuildManager,
BushReactionEmoji,
+ BushStageChannel,
BushUserManager,
Config
} from '#lib';
-import { patch, type PatchedElements } from '@notenoughupdates/events-intercept';
+import { patch, PatchedElements } from '@notenoughupdates/events-intercept';
import * as Sentry from '@sentry/node';
import { AkairoClient, ContextMenuCommandHandler, version as akairoVersion } from 'discord-akairo';
import {
+ Awaitable,
Intents,
Options,
Structures,
version as discordJsVersion,
- type Awaitable,
type Collection,
- type DMChannel,
type InteractionReplyOptions,
type Message,
type MessageEditOptions,
@@ -31,6 +30,7 @@ import {
type Snowflake,
type WebhookEditMessageOptions
} from 'discord.js';
+import EventEmitter from 'events';
import path from 'path';
import readline from 'readline';
import type { Sequelize as SequelizeType } from 'sequelize';
@@ -100,9 +100,28 @@ export type BushEmojiIdentifierResolvable = string | BushEmojiResolvable;
export type BushThreadChannelResolvable = BushThreadChannel | Snowflake;
export type BushApplicationCommandResolvable = BushApplicationCommand | Snowflake;
export type BushGuildTextChannelResolvable = BushTextChannel | BushNewsChannel | Snowflake;
-export type BushChannelResolvable = BushChannel | Snowflake;
-export type BushTextBasedChannels = PartialDMChannel | BushDMChannel | BushTextChannel | BushNewsChannel | BushThreadChannel;
-export type BushGuildTextBasedChannel = Exclude<BushTextBasedChannels, PartialDMChannel | BushDMChannel | DMChannel>;
+export type BushChannelResolvable = BushAnyChannel | Snowflake;
+export type BushGuildChannelResolvable = Snowflake | BushGuildBasedChannel;
+export type BushAnyChannel =
+ | BushCategoryChannel
+ | BushDMChannel
+ | PartialDMChannel
+ | BushNewsChannel
+ | BushStageChannel
+ // eslint-disable-next-line deprecation/deprecation
+ | BushStoreChannel
+ | BushTextChannel
+ | BushThreadChannel
+ | BushVoiceChannel;
+export type BushTextBasedChannel = PartialDMChannel | BushThreadChannel | BushDMChannel | BushNewsChannel | BushTextChannel;
+export type BushTextBasedChannelTypes = BushTextBasedChannel['type'];
+export type BushVoiceBasedChannel = Extract<BushAnyChannel, { bitrate: number }>;
+export type BushGuildBasedChannel = Extract<BushAnyChannel, { guild: BushGuild }>;
+export type BushNonThreadGuildBasedChannel = Exclude<BushGuildBasedChannel, BushThreadChannel>;
+export type BushGuildTextBasedChannel = Extract<BushGuildBasedChannel, BushTextBasedChannel>;
+export type BushTextChannelResolvable = Snowflake | BushTextChannel;
+export type BushGuildVoiceChannelResolvable = BushVoiceBasedChannel | Snowflake;
+
export interface BushFetchedThreads {
threads: Collection<Snowflake, BushThreadChannel>;
hasMore?: boolean;
@@ -118,29 +137,86 @@ type If<T extends boolean, A, B = null> = T extends true ? A : T extends false ?
const __dirname = path.dirname(fileURLToPath(import.meta.url));
+/**
+ * The main hub for interacting with the Discord API.
+ */
export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Ready> {
public declare channels: BushChannelManager;
public declare readonly emojis: BushBaseGuildEmojiManager;
public declare guilds: BushGuildManager;
public declare user: If<Ready, BushClientUser>;
public declare users: BushUserManager;
+ public declare util: BushClientUtil;
+ public declare ownerID: Snowflake[];
+ /**
+ * Whether or not the client is ready.
+ */
public customReady = false;
- public stats: { cpu: number | undefined; commandsUsed: bigint } = { cpu: undefined, commandsUsed: 0n };
+
+ /**
+ * Stats for the client.
+ */
+ public stats: BushStats = { cpu: undefined, commandsUsed: 0n };
+
+ /**
+ * The configuration for the client.
+ */
public config: Config;
+
+ /**
+ * The handler for the bot's listeners.
+ */
public listenerHandler: BushListenerHandler;
+
+ /**
+ * The handler for the bot's command inhibitors.
+ */
public inhibitorHandler: BushInhibitorHandler;
+
+ /**
+ * The handler for the bot's commands.
+ */
public commandHandler: BushCommandHandler;
+
+ /**
+ * The handler for the bot's tasks.
+ */
public taskHandler: BushTaskHandler;
+
+ /**
+ * The handler for the bot's context menu commands.
+ */
public contextMenuCommandHandler: ContextMenuCommandHandler;
- public declare util: BushClientUtil;
- public declare ownerID: Snowflake[];
+
+ /**
+ * The database connection for the bot.
+ */
public db: SequelizeType;
+
+ /**
+ * A custom logging system for the bot.
+ */
public logger = BushLogger;
+
+ /**
+ * Constants for the bot.
+ */
public constants = BushConstants;
+
+ /**
+ * Cached global and guild database data.
+ */
public cache = new BushCache();
+
+ /**
+ * Sentry error reporting for the bot.
+ */
public sentry!: typeof Sentry;
+ /**
+ * @param config The configuration for the bot.
+ */
public constructor(config: Config) {
super({
ownerID: config.owners,
@@ -163,25 +239,18 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
this.token = config.token as If<Ready, string, string | null>;
this.config = config;
- // Create listener handler
this.listenerHandler = new BushListenerHandler(this, {
directory: path.join(__dirname, '..', '..', '..', 'listeners'),
automateCategories: true
});
-
- // Create inhibitor handler
this.inhibitorHandler = new BushInhibitorHandler(this, {
directory: path.join(__dirname, '..', '..', '..', 'inhibitors'),
automateCategories: true
});
-
- // Create task handler
this.taskHandler = new BushTaskHandler(this, {
directory: path.join(__dirname, '..', '..', '..', 'tasks'),
automateCategories: true
});
-
- // Create command handler
this.commandHandler = new BushCommandHandler(this, {
directory: path.join(__dirname, '..', '..', '..', 'commands'),
prefix: async ({ guild }: Message) => {
@@ -215,12 +284,10 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
useSlashPermissions: true,
aliasReplacement: /-/g
});
-
this.contextMenuCommandHandler = new ContextMenuCommandHandler(this, {
directory: path.join(__dirname, '..', '..', '..', 'context-menu-commands'),
automateCategories: true
});
-
this.util = new BushClientUtil(this);
this.db = new Sequelize({
database: this.config.isDevelopment ? 'bushbot-dev' : this.config.isBeta ? 'bushbot-beta' : 'bushbot',
@@ -234,15 +301,24 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
});
}
- get console(): typeof BushLogger {
+ /**
+ * A custom logging system for the bot.
+ */
+ public get console(): typeof BushLogger {
return this.logger;
}
- get consts(): typeof BushConstants {
+ /**
+ * Constants for the bot.
+ */
+ public get consts(): typeof BushConstants {
return this.constants;
}
- public static init(): void {
+ /**
+ * Extends discord.js structures before the client is instantiated.
+ */
+ public static extendStructures(): void {
Structures.extend('GuildEmoji', () => BushGuildEmoji);
Structures.extend('DMChannel', () => BushDMChannel);
Structures.extend('TextChannel', () => BushTextChannel);
@@ -265,18 +341,28 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
Structures.extend('SelectMenuInteraction', () => BushSelectMenuInteraction);
}
- // Initialize everything
- async #init() {
- this.commandHandler.useListenerHandler(this.listenerHandler);
+ /**
+ * Initializes the bot.
+ */
+ async init() {
+ if (!process.version.startsWith('v17.')) {
+ void (await this.console.error('version', `Please use node <<v17.x.x>>, not <<${process.version}>>.`, false));
+ process.exit(2);
+ }
+
this.commandHandler.useInhibitorHandler(this.inhibitorHandler);
+ this.commandHandler.useListenerHandler(this.listenerHandler);
+ this.commandHandler.useTaskHandler(this.taskHandler);
+ this.commandHandler.useContextMenuCommandHandler(this.contextMenuCommandHandler);
this.commandHandler.ignorePermissions = this.config.owners;
this.commandHandler.ignoreCooldown = [...new Set([...this.config.owners, ...this.cache.global.superUsers])];
this.listenerHandler.setEmitters({
client: this,
commandHandler: this.commandHandler,
- listenerHandler: this.listenerHandler,
inhibitorHandler: this.inhibitorHandler,
+ listenerHandler: this.listenerHandler,
taskHandler: this.taskHandler,
+ contextMenuCommandHandler: this.contextMenuCommandHandler,
process,
stdin: rl,
gateway: this.ws
@@ -301,28 +387,31 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
void this.logger.success('startup', `Successfully connected to <<Sentry>>.`, false);
// loads all the handlers
- const loaders = {
+ const handlers = {
commands: this.commandHandler,
- contextMenuCommand: this.contextMenuCommandHandler,
+ contextMenuCommands: this.contextMenuCommandHandler,
listeners: this.listenerHandler,
inhibitors: this.inhibitorHandler,
tasks: this.taskHandler
};
- for (const loader in loaders) {
- try {
- await loaders[loader as keyof typeof loaders].loadAll();
- void this.logger.success('startup', `Successfully loaded <<${loader}>>.`, false);
- } catch (e) {
- void this.logger.error('startup', `Unable to load loader <<${loader}>> with error:\n${e?.stack || e}`, false);
- }
- }
- await this.dbPreInit();
- await UpdateCacheTask.init(this);
- void this.console.success('startup', `Successfully created <<cache>>.`, false);
- this.stats.commandsUsed = await UpdateStatsTask.init();
+ const handlerPromises = Object.entries(handlers).map(([handlerName, handler]) =>
+ handler
+ .loadAll()
+ .then(() => {
+ void this.logger.success('startup', `Successfully loaded <<${handlerName}>>.`, false);
+ })
+ .catch((e) => {
+ void this.logger.error('startup', `Unable to load loader <<${handlerName}>> with error:\n${e?.stack || e}`, false);
+ if (process.argv.includes('dry')) process.exit(1);
+ })
+ );
+ await Promise.allSettled(handlerPromises);
}
- public async dbPreInit() {
+ /**
+ * Connects to the database, initializes models, and creates tables if they do not exist.
+ */
+ private async dbPreInit() {
try {
await this.db.authenticate();
Global.initModel(this.db);
@@ -348,10 +437,6 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
* Starts the bot
*/
public async start() {
- if (!process.version.startsWith('v17.')) {
- void (await this.console.error('version', `Please use node <<v17.x.x>>, not <<${process.version}>>.`, false));
- process.exit(2);
- }
this.intercept('ready', async (arg, done) => {
await this.guilds.fetch();
const promises = this.guilds.cache.map((guild) => {
@@ -368,7 +453,10 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
global.util = this.util;
try {
- await this.#init();
+ await this.dbPreInit();
+ await UpdateCacheTask.init(this);
+ void this.console.success('startup', `Successfully created <<cache>>.`, false);
+ this.stats.commandsUsed = await UpdateStatsTask.init();
await this.login(this.token!);
} catch (e) {
await this.console.error('start', util.inspect(e, { colors: true, depth: 1 }), false);
@@ -389,13 +477,14 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
public override isOwner(user: BushUserResolvable): boolean {
return this.config.owners.includes(this.users.resolveId(user!)!);
}
+
public override isSuperUser(user: BushUserResolvable): boolean {
const userID = this.users.resolveId(user)!;
return !!client.cache?.global?.superUsers?.includes(userID) || this.config.owners.includes(userID);
}
}
-export interface BushClient extends PatchedElements {
+export interface BushClient extends EventEmitter, PatchedElements {
on<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this;
on<S extends string | symbol>(event: Exclude<S, keyof BushClientEvents>, listener: (...args: any[]) => Awaitable<void>): this;
@@ -411,3 +500,15 @@ export interface BushClient extends PatchedElements {
removeAllListeners<K extends keyof BushClientEvents>(event?: K): this;
removeAllListeners<S extends string | symbol>(event?: Exclude<S, keyof BushClientEvents>): this;
}
+
+export interface BushStats {
+ /**
+ * The average cpu usage of the bot from the past 60 seconds.
+ */
+ cpu: number | undefined;
+
+ /**
+ * The total number of times any command has been used.
+ */
+ commandsUsed: bigint;
+}
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index ab1f3ed..5ae2ac0 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -2,6 +2,7 @@ import {
Arg,
BushConstants,
Global,
+ GlobalCache,
type BushClient,
type BushInspectOptions,
type BushMessage,
@@ -438,6 +439,12 @@ export class BushClientUtil extends ClientUtil {
return array.join(', ');
}
+ public getGlobal(): GlobalCache;
+ public getGlobal<K extends keyof GlobalCache>(key: K): GlobalCache[K];
+ public getGlobal(key?: keyof GlobalCache) {
+ return key ? client.cache.global[key] : client.cache.global;
+ }
+
/**
* Add or remove an element from an array stored in the Globals database.
* @param action Either `add` or `remove` an element.
@@ -610,11 +617,11 @@ export class BushClientUtil extends ClientUtil {
/**
* Wait an amount in seconds.
- * @param s The number of seconds to wait
+ * @param seconds The number of seconds to wait
* @returns A promise that resolves after the specified amount of seconds
*/
- public async sleep(s: number) {
- return new Promise((resolve) => setTimeout(resolve, s * 1000));
+ public async sleep(seconds: number) {
+ return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
/**
@@ -629,8 +636,13 @@ export class BushClientUtil extends ClientUtil {
});
}
+ /**
+ * Fetches a user from discord.
+ * @param user The user to fetch
+ * @returns Undefined if the user is not found, otherwise the user.
+ */
public async resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<BushUser | undefined> {
- if (!user) return undefined;
+ if (user == null) return undefined;
const id =
user instanceof User || user instanceof GuildMember || user instanceof ThreadMember
? user.id
@@ -643,6 +655,11 @@ export class BushClientUtil extends ClientUtil {
else return await client.users.fetch(id).catch(() => undefined);
}
+ /**
+ * Get the pronouns of a discord user from pronoundb.org
+ * @param user The user to retrieve the promises of.
+ * @returns The human readable pronouns of the user, or undefined if they do not have any.
+ */
public async getPronounsOf(user: User | Snowflake): Promise<Pronoun | undefined> {
const _user = await this.resolveNonCachedUser(user);
if (!_user) throw new Error(`Cannot find user ${user}`);
@@ -657,6 +674,11 @@ export class BushClientUtil extends ClientUtil {
return client.constants.pronounMapping[apiRes.pronouns!]!;
}
+ /**
+ * List the methods of an object.
+ * @param obj The object to get the methods of.
+ * @returns A string with each method on a new line.
+ */
public getMethods(obj: Record<string, any>): string {
// modified from https://stackoverflow.com/questions/31054910/get-functions-methods-of-a-class
// answer by Bruno Grieder
@@ -700,13 +722,17 @@ export class BushClientUtil extends ClientUtil {
return props.join('\n');
}
+ /**
+ * Uploads an image to imgur.
+ * @param image The image to upload.
+ * @returns The url of the imgur.
+ */
public async uploadImageToImgur(image: string) {
const clientId = this.client.config.credentials.imgurClientId;
const resp = (await got
.post('https://api.imgur.com/3/upload', {
headers: {
- // Authorization: `Bearer ${token}`,
Authorization: `Client-ID ${clientId}`,
Accept: 'application/json'
},
@@ -721,18 +747,38 @@ export class BushClientUtil extends ClientUtil {
return resp.data.link;
}
+ /**
+ * Checks if a user has a certain guild permission (doesn't check channel permissions).
+ * @param message The message to check the user from.
+ * @param permissions The permissions to check for.
+ * @returns The missing permissions or null if none are missing.
+ */
public userGuildPermCheck(message: BushMessage | BushSlashMessage, permissions: PermissionResolvable) {
const missing = message.member?.permissions.missing(permissions) ?? [];
return missing.length ? missing : null;
}
+ /**
+ * Check if the client has certain permissions in the guild (doesn't check channel permissions).
+ * @param message The message to check the client user from.
+ * @param permissions The permissions to check for.
+ * @returns The missing permissions or null if none are missing.
+ */
public clientGuildPermCheck(message: BushMessage | BushSlashMessage, permissions: PermissionResolvable) {
const missing = message.guild?.me?.permissions.missing(permissions) ?? [];
return missing.length ? missing : null;
}
+ /**
+ * Check if the client has permission to send messages in the channel as well as check if they have other permissions
+ * in the guild (or the channel if `checkChannel` is `true`).
+ * @param message The message to check the client user from.
+ * @param permissions The permissions to check for.
+ * @param checkChannel Whether to check the channel permissions instead of the guild permissions.
+ * @returns The missing permissions or null if none are missing.
+ */
public clientSendAndPermCheck(
message: BushMessage | BushSlashMessage,
permissions: PermissionResolvable = [],
@@ -752,6 +798,11 @@ export class BushClientUtil extends ClientUtil {
return missing.length ? missing : null;
}
+ /**
+ * Gets the prefix based off of the message.
+ * @param message The message to get the prefix from.
+ * @returns The prefix.
+ */
public prefix(message: BushMessage | BushSlashMessage): string {
return message.util.isSlash
? '/'
@@ -760,14 +811,55 @@ export class BushClientUtil extends ClientUtil {
: message.util.parsed?.prefix ?? client.config.prefix;
}
+ /**
+ * Recursively apply provided options operations on object
+ * and all of the object properties that are either object or function.
+ *
+ * By default freezes object.
+ *
+ * @param obj - The object to which will be applied `freeze`, `seal` or `preventExtensions`
+ * @param options default `{ action: 'freeze' }`
+ * @param options.action
+ * ```
+ * | action | Add | Modify | Delete | Reconfigure |
+ * | ----------------- | --- | ------ | ------ | ----------- |
+ * | preventExtensions | - | + | + | + |
+ * | seal | - | + | - | - |
+ * | freeze | - | - | - | - |
+ * ```
+ *
+ * @returns Initial object with applied options action
+ */
public get deepFreeze() {
return deepLock;
}
+ /**
+ * Recursively apply provided options operations on object
+ * and all of the object properties that are either object or function.
+ *
+ * By default freezes object.
+ *
+ * @param obj - The object to which will be applied `freeze`, `seal` or `preventExtensions`
+ * @param options default `{ action: 'freeze' }`
+ * @param options.action
+ * ```
+ * | action | Add | Modify | Delete | Reconfigure |
+ * | ----------------- | --- | ------ | ------ | ----------- |
+ * | preventExtensions | - | + | + | + |
+ * | seal | - | + | - | - |
+ * | freeze | - | - | - | - |
+ * ```
+ *
+ * @returns Initial object with applied options action
+ */
public static get deepFreeze() {
return deepLock;
}
+ /**
+ * A wrapper for the Argument class that adds custom typings.
+ */
public get arg() {
return Arg;
}
diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts
index ae3dcb2..6b54e20 100644
--- a/src/lib/extensions/discord-akairo/BushCommand.ts
+++ b/