Socket
Socket
Sign inDemoInstall

@notenoughupdates/discord-akairo

Package Overview
Dependencies
Maintainers
1
Versions
140
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@notenoughupdates/discord-akairo - npm Package Compare versions

Comparing version 9.1.3-dev.1655521909.d87c26d to 9.1.3

.yarn/cache/@discordjs-builders-npm-0.16.0-5d4bdc03c0-bf7ab00924.zip

40

dist/package.json
{
"name": "@notenoughupdates/discord-akairo",
"version": "9.1.3-dev.1655521909.d87c26d",
"version": "9.1.3",
"description": "A highly customizable bot framework for Discord.js.",

@@ -40,19 +40,33 @@ "main": "./dist/src/index.js",

"devDependencies": {
"@favware/npm-deprecate": "^1.0.4",
"@types/node": "^17.0.43",
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
"@discordjs/voice": "^0.11.0",
"@favware/npm-deprecate": "^1.0.5",
"@types/node": "^18.6.3",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"copyfiles": "^2.4.1",
"discord-api-types": "0.34.0",
"discord.js": "npm:@notenoughupdates/discord.js@dev",
"eslint": "^8.17.0",
"discord-api-types": "^0.33.3",
"discord.js": "^13.9.2",
"eslint": "^8.20.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-deprecation": "^1.3.2",
"node-fetch": "^3.2.6",
"prettier": "^2.7.0",
"node-fetch": "^3.2.10",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"typedoc": "^0.22.17",
"typescript": "^4.7.3"
"typedoc": "^0.23.9",
"typescript": "^4.7.4"
},
"packageManager": "yarn@3.2.1"
"prettier": {
"useTabs": true,
"trailingComma": "none",
"arrowParens": "avoid",
"printWidth": 130,
"overrides": [
{
"files": "*.md",
"options": {
"useTabs": false
}
}
]
}
}

@@ -1,2 +0,30 @@

import { CommandUtil } from "./struct/commands/CommandUtil.js";
import { CommandUtil } from "./struct/commands/CommandUtil";
import * as Constants from "./util/Constants";
export * from "./struct/AkairoClient";
export * from "./struct/AkairoHandler";
export * from "./struct/AkairoModule";
export * from "./struct/ClientUtil";
export * from "./struct/commands/arguments/Argument";
export * from "./struct/commands/arguments/ArgumentRunner";
export * from "./struct/commands/arguments/TypeResolver";
export * from "./struct/commands/Command";
export * from "./struct/commands/CommandHandler";
export * from "./struct/commands/CommandUtil";
export * from "./struct/commands/ContentParser";
export * from "./struct/commands/Flag";
export * from "./struct/contextMenuCommands/ContextMenuCommand";
export * from "./struct/contextMenuCommands/ContextMenuCommandHandler";
export * from "./struct/inhibitors/Inhibitor";
export * from "./struct/inhibitors/InhibitorHandler";
export * from "./struct/listeners/Listener";
export * from "./struct/listeners/ListenerHandler";
export * from "./struct/tasks/Task";
export * from "./struct/tasks/TaskHandler";
export * from "./typings/events";
export * from "./util/AkairoError";
export * from "./util/AkairoMessage";
export * from "./util/Category";
export * from "./util/Util";
export { Constants };
export declare const version: string;
declare module "discord.js" {

@@ -7,3 +35,3 @@ interface Message<Cached extends boolean = boolean> extends Base {

* Utilities for command responding.
* Available on all messages after `'all'` inhibitors and built-in inhibitors (bot, client).
* Available on all messages after 'all' inhibitors and built-in inhibitors (bot, client).
* Not all properties of the util are available, depending on the input.

@@ -14,32 +42,2 @@ * */

}
export * from "./struct/AkairoClient.js";
export * from "./struct/AkairoHandler.js";
export * from "./struct/AkairoModule.js";
export * as ClientUtil from "./struct/ClientUtil.js";
export * from "./struct/commands/arguments/Argument.js";
export * from "./struct/commands/arguments/ArgumentRunner.js";
export * from "./struct/commands/arguments/TypeResolver.js";
export * from "./struct/commands/Command.js";
export * from "./struct/commands/CommandHandler.js";
export * from "./struct/commands/CommandUtil.js";
export * from "./struct/commands/ContentParser.js";
export * from "./struct/commands/Flag.js";
export * from "./struct/contextMenuCommands/ContextMenuCommand.js";
export * from "./struct/contextMenuCommands/ContextMenuCommandHandler.js";
export * from "./struct/inhibitors/Inhibitor.js";
export * from "./struct/inhibitors/InhibitorHandler.js";
export * from "./struct/listeners/Listener.js";
export * from "./struct/listeners/ListenerHandler.js";
export * from "./struct/tasks/Task.js";
export * from "./struct/tasks/TaskHandler.js";
export * from "./typings/events.js";
export * from "./util/AkairoError.js";
export * from "./util/AkairoMessage.js";
export * from "./util/Category.js";
export * as Constants from "./util/Constants.js";
export * as Util from "./util/Util.js";
/**
* The version of the library.
*/
export declare const version: string;
//# sourceMappingURL=index.d.ts.map

@@ -18,5 +18,2 @@ "use strict";

});
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importStar = (this && this.__importStar) || function (mod) {

@@ -29,2 +26,5 @@ if (mod && mod.__esModule) return mod;

};
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -34,35 +34,32 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

Object.defineProperty(exports, "__esModule", { value: true });
exports.version = exports.Util = exports.Constants = exports.ClientUtil = void 0;
/* eslint-disable @typescript-eslint/no-unused-vars */
exports.version = exports.Constants = void 0;
const package_json_1 = __importDefault(require("../package.json"));
__exportStar(require("./struct/AkairoClient.js"), exports);
__exportStar(require("./struct/AkairoHandler.js"), exports);
__exportStar(require("./struct/AkairoModule.js"), exports);
exports.ClientUtil = __importStar(require("./struct/ClientUtil.js"));
__exportStar(require("./struct/commands/arguments/Argument.js"), exports);
__exportStar(require("./struct/commands/arguments/ArgumentRunner.js"), exports);
__exportStar(require("./struct/commands/arguments/TypeResolver.js"), exports);
__exportStar(require("./struct/commands/Command.js"), exports);
__exportStar(require("./struct/commands/CommandHandler.js"), exports);
__exportStar(require("./struct/commands/CommandUtil.js"), exports);
__exportStar(require("./struct/commands/ContentParser.js"), exports);
__exportStar(require("./struct/commands/Flag.js"), exports);
__exportStar(require("./struct/contextMenuCommands/ContextMenuCommand.js"), exports);
__exportStar(require("./struct/contextMenuCommands/ContextMenuCommandHandler.js"), exports);
__exportStar(require("./struct/inhibitors/Inhibitor.js"), exports);
__exportStar(require("./struct/inhibitors/InhibitorHandler.js"), exports);
__exportStar(require("./struct/listeners/Listener.js"), exports);
__exportStar(require("./struct/listeners/ListenerHandler.js"), exports);
__exportStar(require("./struct/tasks/Task.js"), exports);
__exportStar(require("./struct/tasks/TaskHandler.js"), exports);
__exportStar(require("./typings/events.js"), exports);
__exportStar(require("./util/AkairoError.js"), exports);
__exportStar(require("./util/AkairoMessage.js"), exports);
__exportStar(require("./util/Category.js"), exports);
exports.Constants = __importStar(require("./util/Constants.js"));
exports.Util = __importStar(require("./util/Util.js"));
/**
* The version of the library.
*/
const Constants = __importStar(require("./util/Constants"));
exports.Constants = Constants;
__exportStar(require("./struct/AkairoClient"), exports);
__exportStar(require("./struct/AkairoHandler"), exports);
__exportStar(require("./struct/AkairoModule"), exports);
__exportStar(require("./struct/ClientUtil"), exports);
__exportStar(require("./struct/commands/arguments/Argument"), exports);
__exportStar(require("./struct/commands/arguments/ArgumentRunner"), exports);
__exportStar(require("./struct/commands/arguments/TypeResolver"), exports);
__exportStar(require("./struct/commands/Command"), exports);
__exportStar(require("./struct/commands/CommandHandler"), exports);
__exportStar(require("./struct/commands/CommandUtil"), exports);
__exportStar(require("./struct/commands/ContentParser"), exports);
__exportStar(require("./struct/commands/Flag"), exports);
__exportStar(require("./struct/contextMenuCommands/ContextMenuCommand"), exports);
__exportStar(require("./struct/contextMenuCommands/ContextMenuCommandHandler"), exports);
__exportStar(require("./struct/inhibitors/Inhibitor"), exports);
__exportStar(require("./struct/inhibitors/InhibitorHandler"), exports);
__exportStar(require("./struct/listeners/Listener"), exports);
__exportStar(require("./struct/listeners/ListenerHandler"), exports);
__exportStar(require("./struct/tasks/Task"), exports);
__exportStar(require("./struct/tasks/TaskHandler"), exports);
__exportStar(require("./typings/events"), exports);
__exportStar(require("./util/AkairoError"), exports);
__exportStar(require("./util/AkairoMessage"), exports);
__exportStar(require("./util/Category"), exports);
__exportStar(require("./util/Util"), exports);
exports.version = package_json_1.default.version;
//# sourceMappingURL=index.js.map
import { Awaitable, Client, ClientOptions, Snowflake, UserResolvable } from "discord.js";
import type { AkairoClientEvents } from "../typings/events.js";
import * as ClientUtil from "./ClientUtil.js";
import type { AkairoClientEvents } from "../typings/events";
import { ClientUtil } from "./ClientUtil.js";
/**

@@ -19,6 +19,6 @@ * The Akairo framework client. Creates the handlers and sets them up.

*/
util: typeof ClientUtil;
util: ClientUtil;
/**
* @param options - Options for the client.
* @param clientOptions - Options for Discord JS client. If not specified, the previous options parameter is used instead.
* @param clientOptions - Options for Discord JS client.If not specified, the previous options parameter is used instead.
*/

@@ -38,14 +38,14 @@ constructor(options: AkairoOptions & ClientOptions);

}
declare type Events = AkairoClientEvents;
declare type Event = AkairoClientEvents;
export interface AkairoClient<Ready extends boolean = boolean> extends Client<Ready> {
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
on<S extends string | symbol>(event: Exclude<S, keyof Events>, listener: (...args: any[]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<S extends string | symbol>(event: Exclude<S, keyof Events>, listener: (...args: any[]) => Awaitable<void>): this;
emit<K extends keyof Events>(event: K, ...args: Events[K]): boolean;
emit<S extends string | symbol>(event: Exclude<S, keyof Events>, ...args: unknown[]): boolean;
off<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
off<S extends string | symbol>(event: Exclude<S, keyof Events>, listener: (...args: any[]) => Awaitable<void>): this;
removeAllListeners<K extends keyof Events>(event?: K): this;
removeAllListeners<S extends string | symbol>(event?: Exclude<S, keyof Events>): this;
on<K extends keyof Event>(event: K, listener: (...args: Event[K]) => Awaitable<void>): this;
on<S extends string | symbol>(event: Exclude<S, keyof Event>, listener: (...args: any[]) => Awaitable<void>): this;
once<K extends keyof Event>(event: K, listener: (...args: Event[K]) => Awaitable<void>): this;
once<S extends string | symbol>(event: Exclude<S, keyof Event>, listener: (...args: any[]) => Awaitable<void>): this;
emit<K extends keyof Event>(event: K, ...args: Event[K]): boolean;
emit<S extends string | symbol>(event: Exclude<S, keyof Event>, ...args: unknown[]): boolean;
off<K extends keyof Event>(event: K, listener: (...args: Event[K]) => Awaitable<void>): this;
off<S extends string | symbol>(event: Exclude<S, keyof Event>, listener: (...args: any[]) => Awaitable<void>): this;
removeAllListeners<K extends keyof Event>(event?: K): this;
removeAllListeners<S extends string | symbol>(event?: Exclude<S, keyof Event>): this;
}

@@ -52,0 +52,0 @@ /**

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AkairoClient = void 0;
const discord_js_1 = require("discord.js");
const ClientUtil = __importStar(require("./ClientUtil.js"));
const ClientUtil_js_1 = require("./ClientUtil.js");
/**

@@ -34,7 +11,7 @@ * The Akairo framework client. Creates the handlers and sets them up.

constructor(options, clientOptions) {
const combinedOptions = { ...options, ...(clientOptions ?? {}) };
const combinedOptions = { ...options, ...clientOptions };
super(combinedOptions);
this.ownerID = combinedOptions.ownerID ?? [];
this.superUserID = combinedOptions.superUserID ?? [];
this.util = ClientUtil;
this.util = new ClientUtil_js_1.ClientUtil(this);
}

@@ -41,0 +18,0 @@ /**

@@ -0,11 +1,14 @@

/// <reference types="node" />
import { Collection } from "discord.js";
import EventEmitter from "node:events";
import EventEmitter from "events";
import { Category } from "../util/Category.js";
import type { AkairoClient } from "./AkairoClient.js";
import { AkairoModule } from "./AkairoModule.js";
export declare type Class<T> = abstract new (...args: any[]) => T;
export declare type Static<M> = {
(): M;
};
/**
* Base class for handling modules.
*/
export declare class AkairoHandler<Module extends AkairoModule<Handler, Module>, Handler extends AkairoHandler<Module, Handler>> extends EventEmitter {
export declare class AkairoHandler extends EventEmitter {
/**

@@ -18,7 +21,7 @@ * Whether or not to automate category names.

*/
categories: Collection<string, Category<string, Module>>;
categories: Collection<string, Category<string, AkairoModule>>;
/**
* Class to handle.
*/
classToHandle: Class<Module>;
classToHandle: typeof AkairoModule;
/**

@@ -43,3 +46,3 @@ * The Akairo client.

*/
modules: Collection<string, Module>;
modules: Collection<string, AkairoModule>;
/**

@@ -49,3 +52,3 @@ * @param client - The Akairo client.

*/
constructor(client: AkairoClient, options: AkairoHandlerOptions<Module, Handler>);
constructor(client: AkairoClient, options: AkairoHandlerOptions);
/**

@@ -55,3 +58,3 @@ * Deregisters a module.

*/
deregister(mod: Module): void;
deregister(mod: AkairoModule): void;
/**

@@ -61,3 +64,3 @@ * Finds a category by name.

*/
findCategory(name: string): Category<string, Module> | undefined;
findCategory(name: string): Category<string, AkairoModule> | undefined;
/**

@@ -68,3 +71,3 @@ * Loads a module, can be a module class or a filepath.

*/
load(thing: string | Module, isReload?: boolean): Promise<Module | undefined>;
load(thing: string | AkairoModule, isReload?: boolean): Promise<AkairoModule | undefined>;
/**

@@ -77,3 +80,3 @@ * Reads all modules from a directory and loads them.

*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<this>;
loadAll(directory?: string, filter?: LoadPredicate): Promise<AkairoHandler>;
/**

@@ -84,3 +87,3 @@ * Registers a module.

*/
register(mod: Module, filepath?: string): void;
register(mod: AkairoModule, filepath?: string): void;
/**

@@ -90,7 +93,7 @@ * Reloads a module.

*/
reload(id: string): Promise<Module | undefined>;
reload(id: string): Promise<AkairoModule | undefined>;
/**
* Reloads all modules.
*/
reloadAll(): Promise<this>;
reloadAll(): Promise<AkairoHandler>;
/**

@@ -100,7 +103,7 @@ * Removes a module.

*/
remove(id: string): Module;
remove(id: string): AkairoModule;
/**
* Removes all modules.
*/
removeAll(): this;
removeAll(): AkairoHandler;
/**

@@ -121,3 +124,3 @@ * Reads files recursively from a directory.

*/
export interface AkairoHandlerOptions<Module extends AkairoModule<Handler, Module>, Handler extends AkairoHandler<Module, Handler>> {
export interface AkairoHandlerOptions {
/**

@@ -132,3 +135,3 @@ * Whether or not to set each module's category to its parent directory name.

*/
classToHandle?: Class<Module>;
classToHandle?: typeof AkairoModule;
/**

@@ -135,0 +138,0 @@ * Directory to modules.

@@ -8,6 +8,6 @@ "use strict";

const discord_js_1 = require("discord.js");
const node_events_1 = __importDefault(require("node:events"));
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const node_url_1 = require("node:url");
const events_1 = __importDefault(require("events"));
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const url_1 = __importDefault(require("url"));
const AkairoError_js_1 = require("../util/AkairoError.js");

@@ -21,3 +21,3 @@ const Category_js_1 = require("../util/Category.js");

*/
class AkairoHandler extends node_events_1.default {
class AkairoHandler extends events_1.default {
/**

@@ -33,3 +33,3 @@ * @param client - The Akairo client.

throw new TypeError("options.classToHandle must be a class that extends AkairoModule.");
if (!(extensions instanceof Set) && !(0, Util_js_1.isArrayOf)(extensions, "string"))
if (!(extensions instanceof Set) && !Util_js_1.Util.isArrayOf(extensions, "string"))
throw new TypeError("options.extensions must be an array of strings or a Set.");

@@ -45,3 +45,3 @@ if (typeof automateCategories !== "boolean")

this.extensions = new Set(extensions);
this.automateCategories = automateCategories;
this.automateCategories = Boolean(automateCategories);
this.loadFilter = loadFilter;

@@ -77,3 +77,3 @@ this.modules = new discord_js_1.Collection();

const isClass = typeof thing === "function";
if (!isClass && !this.extensions.has((0, node_path_1.extname)(thing)))
if (!isClass && !this.extensions.has(path_1.default.extname(thing)))
return undefined;

@@ -88,3 +88,4 @@ let mod = isClass

return m.default ? findExport.call(this, m.default) : null;
}.call(this, await eval(`import(${JSON.stringify((0, node_url_1.pathToFileURL)(thing).toString())})`));
// eslint-disable-next-line @typescript-eslint/no-var-requires
}.call(this, await eval(`import(${JSON.stringify(url_1.default.pathToFileURL(thing).toString())})`));
if (mod && mod.prototype instanceof this.classToHandle) {

@@ -115,3 +116,3 @@ mod = new mod(this); // eslint-disable-line new-cap

for (let filepath of filepaths) {
filepath = (0, node_path_1.resolve)(filepath);
filepath = path_1.default.resolve(filepath);
if (filter(filepath))

@@ -134,3 +135,3 @@ promises.push(this.load(filepath));

if (mod.categoryID === "default" && this.automateCategories) {
const dirs = (0, node_path_1.dirname)(filepath).split(node_path_1.sep);
const dirs = path_1.default.dirname(filepath).split(path_1.default.sep);
mod.categoryID = dirs[dirs.length - 1];

@@ -201,6 +202,6 @@ }

(function read(dir) {
const files = (0, node_fs_1.readdirSync)(dir);
const files = fs_1.default.readdirSync(dir);
for (const file of files) {
const filepath = (0, node_path_1.join)(dir, file);
if ((0, node_fs_1.statSync)(filepath).isDirectory()) {
const filepath = path_1.default.join(dir, file);
if (fs_1.default.statSync(filepath).isDirectory()) {
read(filepath);

@@ -207,0 +208,0 @@ }

@@ -7,42 +7,42 @@ import type { Category } from "../util/Category.js";

*/
export declare abstract class AkairoModule<Handler extends AkairoHandler<Module, Handler>, Module extends AkairoModule<Handler, Module>> {
export declare abstract class AkairoModule {
/**
* The category this module belongs to.
* Category this belongs to.
*/
category: Category<string, this>;
category: Category<string, AkairoModule>;
/**
* The ID of the category this module belongs to.
* ID of the category this belongs to.
*/
categoryID: string;
/**
* The client thant instantiated this module.
* The Akairo client.
*/
client: AkairoClient;
/**
* The filepath of this module.
* The filepath.
*/
filepath: string;
/**
* The handler for this module.
* The handler.
*/
handler: Handler;
handler: AkairoHandler;
/**
* The ID of this module.
* ID of the module.
*/
id: string;
/**
* @param id The ID of module.
* @param options Additional options for this module.
* @param id - ID of module.
* @param options - Options.
*/
constructor(id: string, options?: AkairoModuleOptions);
/**
* Reloads this module.
* Reloads the module.
*/
reload(): Promise<Module>;
reload(): Promise<AkairoModule>;
/**
* Removes this module.
* Removes the module.
*/
remove(): Module;
remove(): AkairoModule;
/**
* Returns the ID of this module.
* Returns the ID.
*/

@@ -49,0 +49,0 @@ toString(): string;

@@ -9,4 +9,4 @@ "use strict";

/**
* @param id The ID of module.
* @param options Additional options for this module.
* @param id - ID of module.
* @param options - Options.
*/

@@ -25,3 +25,3 @@ constructor(id, options) {

/**
* Reloads this module.
* Reloads the module.
*/

@@ -32,3 +32,3 @@ reload() {

/**
* Removes this module.
* Removes the module.
*/

@@ -39,3 +39,3 @@ remove() {

/**
* Returns the ID of this module.
* Returns the ID.
*/

@@ -42,0 +42,0 @@ toString() {

/// <reference types="node" />
import { AttachmentBuilder, Collection, EmbedBuilder, type APIEmbed, type BufferResolvable, type EmbedData, type Emoji, type Guild, type GuildBasedChannel, type GuildMember, type PermissionsString, type Role, type Snowflake, type User } from "discord.js";
import type { Stream } from "node:stream";
import { APIEmbed } from "discord-api-types/v9";
import { BufferResolvable, Collection, Emoji, Guild, GuildChannel, GuildMember, MessageAttachment, MessageEmbed, PermissionString, Role, Snowflake, ThreadChannel, User } from "discord.js";
import type { Stream } from "stream";
import type { AkairoClient } from "./AkairoClient.js";
/**
* Makes a Attachment.
* @param file - The file.
* @param name - The filename.
* @param description - The description of the file.
* Client utilities to help with common tasks.
*/
export declare function attachment(file: BufferResolvable | Stream, name?: string, description?: string): AttachmentBuilder;
/**
* Checks if a string could be referring to a channel.
* @param text - Text to check.
* @param channel - Channel to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export declare function checkChannel<C extends GuildBasedChannel>(text: string, channel: C, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a emoji.
* @param text - Text to check.
* @param emoji - Emoji to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export declare function checkEmoji(text: string, emoji: Emoji, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a guild.
* @param text - Text to check.
* @param guild - Guild to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export declare function checkGuild(text: string, guild: Guild, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a member.
* @param text - Text to check.
* @param member - Member to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export declare function checkMember(text: string, member: GuildMember, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a role.
* @param text - Text to check.
* @param role - Role to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export declare function checkRole(text: string, role: Role, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function checkUser(text: string, user: User, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Makes a Collection.
* @param iterable - Entries to fill with.
*/
export declare function collection<K, V>(iterable?: ReadonlyArray<readonly [K, V]> | null): Collection<K, V>;
/**
* Compares two member objects presences and checks if they stopped or started a stream or not.
* Returns `0`, `1`, or `2` for no change, stopped, or started.
* @param oldMember - The old member.
* @param newMember - The new member.
*/
export declare function compareStreaming(oldMember: GuildMember, newMember: GuildMember): 0 | 1 | 2;
/**
* Makes a Embed.
* @param data - Embed data.
*/
export declare function embed(data?: EmbedData | APIEmbed): EmbedBuilder;
/**
* Combination of `<Client>.fetchUser()` and `<Guild>.fetchMember()`.
* @param guild - Guild to fetch in.
* @param id - ID of the user.
* @param cache - Whether or not to add to cache.
*/
export declare function fetchMember(guild: Guild, id: Snowflake, cache: boolean): Promise<GuildMember>;
/**
* Array of permission names.
*/
export declare function permissionNames(): PermissionsString[];
/**
* Resolves a channel from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveChannel<C extends GuildBasedChannel>(text: string, channels: Collection<Snowflake, C>, caseSensitive?: boolean, wholeWord?: boolean): C | null;
/**
* Resolves multiple channels from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveChannels<C extends GuildBasedChannel>(text: string, channels: Collection<Snowflake, C>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, C>;
/**
* Resolves a custom emoji from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveEmoji(text: string, emojis: Collection<Snowflake, Emoji>, caseSensitive?: boolean, wholeWord?: boolean): Emoji | null;
/**
* Resolves multiple custom emojis from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveEmojis(text: string, emojis: Collection<Snowflake, Emoji>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, Emoji>;
/**
* Resolves a guild from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveGuild(text: string, guilds: Collection<Snowflake, Guild>, caseSensitive?: boolean, wholeWord?: boolean): Guild | null;
/**
* Resolves multiple guilds from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveGuilds(text: string, guilds: Collection<Snowflake, Guild>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, Guild>;
/**
* Resolves a member from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveMember(text: string, members: Collection<Snowflake, GuildMember>, caseSensitive?: boolean, wholeWord?: boolean): GuildMember | null;
/**
* Resolves multiple members from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveMembers(text: string, members: Collection<Snowflake, GuildMember>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, GuildMember>;
/**
* Resolves a permission number and returns an array of permission names.
* @param number - The permissions number.
*/
export declare function resolvePermissionNumber(number: number): string[];
/**
* Resolves a role from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveRole(text: string, roles: Collection<Snowflake, Role>, caseSensitive?: boolean, wholeWord?: boolean): Role | null;
/**
* Resolves multiple roles from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveRoles(text: string, roles: Collection<Snowflake, Role>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, Role>;
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveUser(text: Snowflake | string, users: Collection<Snowflake, User>, caseSensitive?: boolean, wholeWord?: boolean): User | null;
/**
* Resolves multiple users from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export declare function resolveUsers(text: string, users: Collection<Snowflake, User>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, User>;
export declare class ClientUtil {
/**
* The Akairo client.
*/
readonly client: AkairoClient;
/**
* @param client - The client.
*/
constructor(client: AkairoClient);
/**
* Makes a MessageAttachment.
* @param file - The file.
* @param name - The filename.
*/
attachment(file: BufferResolvable | Stream, name?: string): MessageAttachment;
/**
* Checks if a string could be referring to a channel.
* @param text - Text to check.
* @param channel - Channel to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkChannel<C extends ThreadChannel | GuildChannel>(text: string, channel: C, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a emoji.
* @param text - Text to check.
* @param emoji - Emoji to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkEmoji(text: string, emoji: Emoji, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a guild.
* @param text - Text to check.
* @param guild - Guild to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkGuild(text: string, guild: Guild, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a member.
* @param text - Text to check.
* @param member - Member to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkMember(text: string, member: GuildMember, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Checks if a string could be referring to a role.
* @param text - Text to check.
* @param role - Role to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkRole(text: string, role: Role, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
checkUser(text: string, user: User, caseSensitive?: boolean, wholeWord?: boolean): boolean;
/**
* Makes a Collection.
* @param iterable - Entries to fill with.
*/
collection<K, V>(iterable?: ReadonlyArray<readonly [K, V]> | null): Collection<K, V>;
/**
* Compares two member objects presences and checks if they stopped or started a stream or not.
* Returns `0`, `1`, or `2` for no change, stopped, or started.
* @param oldMember - The old member.
* @param newMember - The new member.
*/
compareStreaming(oldMember: GuildMember, newMember: GuildMember): 0 | 1 | 2;
/**
* Makes a Embed.
* @param data - Embed data.
*/
embed(data?: MessageEmbed | APIEmbed): MessageEmbed;
/**
* Combination of `<Client>.fetchUser()` and `<Guild>.fetchMember()`.
* @param guild - Guild to fetch in.
* @param id - ID of the user.
* @param cache - Whether or not to add to cache.
*/
fetchMember(guild: Guild, id: Snowflake, cache: boolean): Promise<GuildMember>;
/**
* Array of permission names.
*/
permissionNames(): PermissionString[];
/**
* Resolves a channel from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveChannel<C extends ThreadChannel | GuildChannel>(text: string, channels: Collection<Snowflake, C>, caseSensitive?: boolean, wholeWord?: boolean): C | null;
/**
* Resolves multiple channels from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveChannels<C extends ThreadChannel | GuildChannel>(text: string, channels: Collection<Snowflake, C>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, C>;
/**
* Resolves a custom emoji from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveEmoji(text: string, emojis: Collection<Snowflake, Emoji>, caseSensitive?: boolean, wholeWord?: boolean): Emoji | null;
/**
* Resolves multiple custom emojis from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveEmojis(text: string, emojis: Collection<Snowflake, Emoji>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, Emoji>;
/**
* Resolves a guild from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveGuild(text: string, guilds: Collection<Snowflake, Guild>, caseSensitive?: boolean, wholeWord?: boolean): Guild | null;
/**
* Resolves multiple guilds from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveGuilds(text: string, guilds: Collection<Snowflake, Guild>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, Guild>;
/**
* Resolves a member from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveMember(text: string, members: Collection<Snowflake, GuildMember>, caseSensitive?: boolean, wholeWord?: boolean): GuildMember | null;
/**
* Resolves multiple members from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveMembers(text: string, members: Collection<Snowflake, GuildMember>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, GuildMember>;
/**
* Resolves a permission number and returns an array of permission names.
* @param number - The permissions number.
*/
resolvePermissionNumber(number: number): string[];
/**
* Resolves a role from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveRole(text: string, roles: Collection<Snowflake, Role>, caseSensitive?: boolean, wholeWord?: boolean): Role | null;
/**
* Resolves multiple roles from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveRoles(text: string, roles: Collection<Snowflake, Role>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, Role>;
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveUser(text: Snowflake | string, users: Collection<Snowflake, User>, caseSensitive?: boolean, wholeWord?: boolean): User | null;
/**
* Resolves multiple users from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveUsers(text: string, users: Collection<Snowflake, User>, caseSensitive?: boolean, wholeWord?: boolean): Collection<Snowflake, User>;
}
//# sourceMappingURL=ClientUtil.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveUsers = exports.resolveUser = exports.resolveRoles = exports.resolveRole = exports.resolvePermissionNumber = exports.resolveMembers = exports.resolveMember = exports.resolveGuilds = exports.resolveGuild = exports.resolveEmojis = exports.resolveEmoji = exports.resolveChannels = exports.resolveChannel = exports.permissionNames = exports.fetchMember = exports.embed = exports.compareStreaming = exports.collection = exports.checkUser = exports.checkRole = exports.checkMember = exports.checkGuild = exports.checkEmoji = exports.checkChannel = exports.attachment = void 0;
exports.ClientUtil = void 0;
const discord_js_1 = require("discord.js");
/**
* Makes a Attachment.
* @param file - The file.
* @param name - The filename.
* @param description - The description of the file.
* Client utilities to help with common tasks.
*/
function attachment(file, name, description) {
return new discord_js_1.AttachmentBuilder(file, { name, description });
}
exports.attachment = attachment;
/**
* Checks if a string could be referring to a channel.
* @param text - Text to check.
* @param channel - Channel to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
function checkChannel(text, channel, caseSensitive = false, wholeWord = false) {
if (channel.id === text)
return true;
const reg = /<#(\d{17,19})>/;
const match = text.match(reg);
if (match && channel.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? channel.name : channel.name.toLowerCase();
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^#/, ""));
class ClientUtil {
/**
* @param client - The client.
*/
constructor(client) {
this.client = client;
}
return name === text || name === text.replace(/^#/, "");
}
exports.checkChannel = checkChannel;
/**
* Checks if a string could be referring to a emoji.
* @param text - Text to check.
* @param emoji - Emoji to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
function checkEmoji(text, emoji, caseSensitive = false, wholeWord = false) {
if (emoji.id === text)
return true;
const reg = /<a?:[a-zA-Z0-9_]+:(\d{17,19})>/;
const match = text.match(reg);
if (match && emoji.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? emoji.name : emoji.name?.toLowerCase();
if (!wholeWord) {
return Boolean(name?.includes(text) || name?.includes(text.replace(/:/, "")));
/**
* Makes a MessageAttachment.
* @param file - The file.
* @param name - The filename.
*/
attachment(file, name) {
return new discord_js_1.MessageAttachment(file, name);
}
return name === text || name === text.replace(/:/, "");
}
exports.checkEmoji = checkEmoji;
/**
* Checks if a string could be referring to a guild.
* @param text - Text to check.
* @param guild - Guild to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
function checkGuild(text, guild, caseSensitive = false, wholeWord = false) {
if (guild.id === text)
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? guild.name : guild.name.toLowerCase();
if (!wholeWord)
return name.includes(text);
return name === text;
}
exports.checkGuild = checkGuild;
/**
* Checks if a string could be referring to a member.
* @param text - Text to check.
* @param member - Member to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
function checkMember(text, member, caseSensitive = false, wholeWord = false) {
if (member.id === text)
return true;
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
if (match && member.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? member.user.username : member.user.username.toLowerCase();
const displayName = caseSensitive ? member.displayName : member.displayName.toLowerCase();
const discrim = member.user.discriminator;
if (!wholeWord) {
return (displayName.includes(text) ||
username.includes(text) ||
((username.includes(text.split("#")[0]) || displayName.includes(text.split("#")[0])) &&
discrim.includes(text.split("#")[1])));
/**
* Checks if a string could be referring to a channel.
* @param text - Text to check.
* @param channel - Channel to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkChannel(text, channel, caseSensitive = false, wholeWord = false) {
if (channel.id === text)
return true;
const reg = /<#(\d{17,19})>/;
const match = text.match(reg);
if (match && channel.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? channel.name : channel.name.toLowerCase();
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^#/, ""));
}
return name === text || name === text.replace(/^#/, "");
}
return (displayName === text ||
username === text ||
((username === text.split("#")[0] || displayName === text.split("#")[0]) && discrim === text.split("#")[1]));
}
exports.checkMember = checkMember;
/**
* Checks if a string could be referring to a role.
* @param text - Text to check.
* @param role - Role to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
function checkRole(text, role, caseSensitive = false, wholeWord = false) {
if (role.id === text)
return true;
const reg = /<@&(\d{17,19})>/;
const match = text.match(reg);
if (match && role.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? role.name : role.name.toLowerCase();
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^@/, ""));
/**
* Checks if a string could be referring to a emoji.
* @param text - Text to check.
* @param emoji - Emoji to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkEmoji(text, emoji, caseSensitive = false, wholeWord = false) {
if (emoji.id === text)
return true;
const reg = /<a?:[a-zA-Z0-9_]+:(\d{17,19})>/;
const match = text.match(reg);
if (match && emoji.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? emoji.name : emoji.name?.toLowerCase();
if (!wholeWord) {
return Boolean(name?.includes(text) || name?.includes(text.replace(/:/, "")));
}
return name === text || name === text.replace(/:/, "");
}
return name === text || name === text.replace(/^@/, "");
}
exports.checkRole = checkRole;
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function checkUser(text, user, caseSensitive = false, wholeWord = false) {
if (user.id === text)
return true;
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
if (match && user.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? user.username : user.username.toLowerCase();
const discrim = user.discriminator;
if (!wholeWord) {
return username.includes(text) || (username.includes(text.split("#")[0]) && discrim.includes(text.split("#")[1]));
/**
* Checks if a string could be referring to a guild.
* @param text - Text to check.
* @param guild - Guild to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkGuild(text, guild, caseSensitive = false, wholeWord = false) {
if (guild.id === text)
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? guild.name : guild.name.toLowerCase();
if (!wholeWord)
return name.includes(text);
return name === text;
}
return username === text || (username === text.split("#")[0] && discrim === text.split("#")[1]);
}
exports.checkUser = checkUser;
/**
* Makes a Collection.
* @param iterable - Entries to fill with.
*/
function collection(iterable) {
return new discord_js_1.Collection(iterable);
}
exports.collection = collection;
/**
* Compares two member objects presences and checks if they stopped or started a stream or not.
* Returns `0`, `1`, or `2` for no change, stopped, or started.
* @param oldMember - The old member.
* @param newMember - The new member.
*/
function compareStreaming(oldMember, newMember) {
const s1 = oldMember.presence?.activities.find(c => c.type === discord_js_1.ActivityType.Streaming);
const s2 = newMember.presence?.activities.find(c => c.type === discord_js_1.ActivityType.Streaming);
if (s1 === s2)
/**
* Checks if a string could be referring to a member.
* @param text - Text to check.
* @param member - Member to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkMember(text, member, caseSensitive = false, wholeWord = false) {
if (member.id === text)
return true;
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
if (match && member.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? member.user.username : member.user.username.toLowerCase();
const displayName = caseSensitive ? member.displayName : member.displayName.toLowerCase();
const discrim = member.user.discriminator;
if (!wholeWord) {
return (displayName.includes(text) ||
username.includes(text) ||
((username.includes(text.split("#")[0]) || displayName.includes(text.split("#")[0])) &&
discrim.includes(text.split("#")[1])));
}
return (displayName === text ||
username === text ||
((username === text.split("#")[0] || displayName === text.split("#")[0]) && discrim === text.split("#")[1]));
}
/**
* Checks if a string could be referring to a role.
* @param text - Text to check.
* @param role - Role to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
checkRole(text, role, caseSensitive = false, wholeWord = false) {
if (role.id === text)
return true;
const reg = /<@&(\d{17,19})>/;
const match = text.match(reg);
if (match && role.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? role.name : role.name.toLowerCase();
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^@/, ""));
}
return name === text || name === text.replace(/^@/, "");
}
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
checkUser(text, user, caseSensitive = false, wholeWord = false) {
if (user.id === text)
return true;
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
if (match && user.id === match[1])
return true;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? user.username : user.username.toLowerCase();
const discrim = user.discriminator;
if (!wholeWord) {
return username.includes(text) || (username.includes(text.split("#")[0]) && discrim.includes(text.split("#")[1]));
}
return username === text || (username === text.split("#")[0] && discrim === text.split("#")[1]);
}
/**
* Makes a Collection.
* @param iterable - Entries to fill with.
*/
collection(iterable) {
return new discord_js_1.Collection(iterable);
}
/**
* Compares two member objects presences and checks if they stopped or started a stream or not.
* Returns `0`, `1`, or `2` for no change, stopped, or started.
* @param oldMember - The old member.
* @param newMember - The new member.
*/
compareStreaming(oldMember, newMember) {
const s1 = oldMember.presence?.activities.find(c => c.type === "STREAMING");
const s2 = newMember.presence?.activities.find(c => c.type === "STREAMING");
if (s1 === s2)
return 0;
if (s1)
return 1;
if (s2)
return 2;
return 0;
if (s1)
return 1;
if (s2)
return 2;
return 0;
}
exports.compareStreaming = compareStreaming;
/**
* Makes a Embed.
* @param data - Embed data.
*/
function embed(data) {
return new discord_js_1.EmbedBuilder(data);
}
exports.embed = embed;
/**
* Combination of `<Client>.fetchUser()` and `<Guild>.fetchMember()`.
* @param guild - Guild to fetch in.
* @param id - ID of the user.
* @param cache - Whether or not to add to cache.
*/
async function fetchMember(guild, id, cache) {
const user = await guild.client.users.fetch(id, { cache });
return guild.members.fetch({ user, cache });
}
exports.fetchMember = fetchMember;
/**
* Array of permission names.
*/
function permissionNames() {
return Object.keys(discord_js_1.PermissionFlagsBits);
}
exports.permissionNames = permissionNames;
/**
* Resolves a channel from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveChannel(text, channels, caseSensitive = false, wholeWord = false) {
return channels.get(text) ?? channels.find(channel => checkChannel(text, channel, caseSensitive, wholeWord)) ?? null;
}
exports.resolveChannel = resolveChannel;
/**
* Resolves multiple channels from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveChannels(text, channels, caseSensitive = false, wholeWord = false) {
return channels.filter(channel => checkChannel(text, channel, caseSensitive, wholeWord));
}
exports.resolveChannels = resolveChannels;
/**
* Resolves a custom emoji from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveEmoji(text, emojis, caseSensitive = false, wholeWord = false) {
return emojis.get(text) ?? emojis.find(emoji => checkEmoji(text, emoji, caseSensitive, wholeWord)) ?? null;
}
exports.resolveEmoji = resolveEmoji;
/**
* Resolves multiple custom emojis from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveEmojis(text, emojis, caseSensitive = false, wholeWord = false) {
return emojis.filter(emoji => checkEmoji(text, emoji, caseSensitive, wholeWord));
}
exports.resolveEmojis = resolveEmojis;
/**
* Resolves a guild from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveGuild(text, guilds, caseSensitive = false, wholeWord = false) {
return guilds.get(text) ?? guilds.find(guild => checkGuild(text, guild, caseSensitive, wholeWord)) ?? null;
}
exports.resolveGuild = resolveGuild;
/**
* Resolves multiple guilds from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveGuilds(text, guilds, caseSensitive = false, wholeWord = false) {
return guilds.filter(guild => checkGuild(text, guild, caseSensitive, wholeWord));
}
exports.resolveGuilds = resolveGuilds;
/**
* Resolves a member from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveMember(text, members, caseSensitive = false, wholeWord = false) {
return members.get(text) ?? members.find(member => checkMember(text, member, caseSensitive, wholeWord)) ?? null;
}
exports.resolveMember = resolveMember;
/**
* Resolves multiple members from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveMembers(text, members, caseSensitive = false, wholeWord = false) {
return members.filter(member => checkMember(text, member, caseSensitive, wholeWord));
}
exports.resolveMembers = resolveMembers;
/**
* Resolves a permission number and returns an array of permission names.
* @param number - The permissions number.
*/
function resolvePermissionNumber(number) {
const resolved = [];
for (const key of Object.keys(discord_js_1.PermissionFlagsBits)) {
if (BigInt(number) & discord_js_1.PermissionFlagsBits[key])
resolved.push(key);
}
return resolved;
/**
* Makes a Embed.
* @param data - Embed data.
*/
embed(data) {
return new discord_js_1.MessageEmbed(data);
}
/**
* Combination of `<Client>.fetchUser()` and `<Guild>.fetchMember()`.
* @param guild - Guild to fetch in.
* @param id - ID of the user.
* @param cache - Whether or not to add to cache.
*/
async fetchMember(guild, id, cache) {
const user = await this.client.users.fetch(id, { cache });
return guild.members.fetch({ user, cache });
}
/**
* Array of permission names.
*/
permissionNames() {
return Object.keys(discord_js_1.Permissions.FLAGS);
}
/**
* Resolves a channel from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveChannel(text, channels, caseSensitive = false, wholeWord = false) {
return channels.get(text) ?? channels.find(channel => this.checkChannel(text, channel, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple channels from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveChannels(text, channels, caseSensitive = false, wholeWord = false) {
return channels.filter(channel => this.checkChannel(text, channel, caseSensitive, wholeWord));
}
/**
* Resolves a custom emoji from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveEmoji(text, emojis, caseSensitive = false, wholeWord = false) {
return emojis.get(text) ?? emojis.find(emoji => this.checkEmoji(text, emoji, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple custom emojis from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveEmojis(text, emojis, caseSensitive = false, wholeWord = false) {
return emojis.filter(emoji => this.checkEmoji(text, emoji, caseSensitive, wholeWord));
}
/**
* Resolves a guild from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveGuild(text, guilds, caseSensitive = false, wholeWord = false) {
return guilds.get(text) ?? guilds.find(guild => this.checkGuild(text, guild, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple guilds from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveGuilds(text, guilds, caseSensitive = false, wholeWord = false) {
return guilds.filter(guild => this.checkGuild(text, guild, caseSensitive, wholeWord));
}
/**
* Resolves a member from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveMember(text, members, caseSensitive = false, wholeWord = false) {
return members.get(text) ?? members.find(member => this.checkMember(text, member, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple members from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveMembers(text, members, caseSensitive = false, wholeWord = false) {
return members.filter(member => this.checkMember(text, member, caseSensitive, wholeWord));
}
/**
* Resolves a permission number and returns an array of permission names.
* @param number - The permissions number.
*/
resolvePermissionNumber(number) {
const resolved = [];
for (const key of Object.keys(discord_js_1.Permissions.FLAGS)) {
if (BigInt(number) & discord_js_1.Permissions.FLAGS[key])
resolved.push(key);
}
return resolved;
}
/**
* Resolves a role from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveRole(text, roles, caseSensitive = false, wholeWord = false) {
return roles.get(text) ?? roles.find(role => this.checkRole(text, role, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple roles from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveRoles(text, roles, caseSensitive = false, wholeWord = false) {
return roles.filter(role => this.checkRole(text, role, caseSensitive, wholeWord));
}
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveUser(text, users, caseSensitive = false, wholeWord = false) {
return users.get(text) ?? users.find(user => this.checkUser(text, user, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple users from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
resolveUsers(text, users, caseSensitive = false, wholeWord = false) {
return users.filter(user => this.checkUser(text, user, caseSensitive, wholeWord));
}
}
exports.resolvePermissionNumber = resolvePermissionNumber;
/**
* Resolves a role from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveRole(text, roles, caseSensitive = false, wholeWord = false) {
return roles.get(text) ?? roles.find(role => checkRole(text, role, caseSensitive, wholeWord)) ?? null;
}
exports.resolveRole = resolveRole;
/**
* Resolves multiple roles from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveRoles(text, roles, caseSensitive = false, wholeWord = false) {
return roles.filter(role => checkRole(text, role, caseSensitive, wholeWord));
}
exports.resolveRoles = resolveRoles;
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveUser(text, users, caseSensitive = false, wholeWord = false) {
return users.get(text) ?? users.find(user => checkUser(text, user, caseSensitive, wholeWord)) ?? null;
}
exports.resolveUser = resolveUser;
/**
* Resolves multiple users from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
function resolveUsers(text, users, caseSensitive = false, wholeWord = false) {
return users.filter(user => checkUser(text, user, caseSensitive, wholeWord));
}
exports.resolveUsers = resolveUsers;
exports.ClientUtil = ClientUtil;
//# sourceMappingURL=ClientUtil.js.map
/// <reference types="node" />
import type { CategoryChannel, Collection, DirectoryChannel, Emoji, Guild, GuildBasedChannel, GuildChannel, GuildEmoji, GuildMember, Invite, Message, MessageOptions, MessagePayload, NewsChannel, Role, Snowflake, StageChannel, TextBasedChannel, TextChannel, ThreadChannel, User, VoiceBasedChannel, VoiceChannel } from "discord.js";
import type { URL } from "node:url";
import type { BaseGuildVoiceChannel, CategoryChannel, Collection, Emoji, Guild, GuildBasedChannel, GuildChannel, GuildEmoji, GuildMember, Invite, Message, MessageOptions, MessagePayload, NewsChannel, Role, StageChannel, StoreChannel, TextChannel, ThreadChannel, User, VoiceChannel } from "discord.js";
import type { URL } from "url";
import type { AkairoClient } from "../../AkairoClient.js";
import type { ContextMenuCommand } from "../../contextMenuCommands/ContextMenuCommand.js";
import type { Inhibitor } from "../../inhibitors/Inhibitor.js";
import type { Listener } from "../../listeners/Listener.js";
import type { Task } from "../../tasks/Task.js";
import { ContextMenuCommand } from "../../contextMenuCommands/ContextMenuCommand.js";
import { Inhibitor } from "../../inhibitors/Inhibitor.js";
import { Listener } from "../../listeners/Listener.js";
import { Task } from "../../tasks/Task.js";
import type { Command } from "../Command.js";

@@ -337,3 +337,3 @@ import type { CommandHandler } from "../CommandHandler.js";

* The command to be run may be the same command or some other command.
* @default true
* Defaults to true,
*/

@@ -346,4 +346,3 @@ breakout?: boolean;

/**
* Word to use for cancelling the command.
* @default "cancel"
* Word to use for cancelling the command. Defaults to 'cancel'.
*/

@@ -359,8 +358,7 @@ cancelWord?: string;

* The final evaluated argument will be an array of the inputs.
* @default false
* Defaults to false.
*/
infinite?: boolean;
/**
* Amount of inputs allowed for an infinite prompt before finishing.
* @default Infinity.
* Amount of inputs allowed for an infinite prompt before finishing. Defaults to Infinity.
*/

@@ -389,9 +387,7 @@ limit?: number;

/**
* Prompts only when argument is provided but was not of the right type.
* @default false
* Prompts only when argument is provided but was not of the right type. Defaults to false.
*/
optional?: boolean;
/**
* Amount of retries allowed.
* @default 1
* Amount of retries allowed. Defaults to 1.
*/

@@ -408,9 +404,7 @@ retries?: number;

/**
* Word to use for ending infinite prompts.
* @default "stop"
* Word to use for ending infinite prompts. Defaults to 'stop'.
*/
stopWord?: string;
/**
* Time to wait for input.
* @default 30000
* Time to wait for input. Defaults to 30000.
*/

@@ -474,5 +468,5 @@ time?: number;

* - `newsChannel` tries to resolve to a news channel.
* - `storeChannel` tries to resolve to a store channel.
* - `stageChannel` tries to resolve to a stage channel.
* - `threadChannel` tries to resolve a thread channel.
* - `directoryChannel` tries to resolve to a directory channel.
* - `role` tries to resolve to a role.

@@ -506,35 +500,29 @@ * - `emoji` tries to resolve to a custom emoji.

user: User | null;
users: Collection<Snowflake, User> | null;
users: Collection<string, User> | null;
member: GuildMember | null;
members: Collection<Snowflake, GuildMember> | null;
members: Collection<string, GuildMember> | null;
relevant: User | GuildMember | null;
relevants: Collection<Snowflake, User> | Collection<Snowflake, GuildMember> | null;
channel: GuildBasedChannel | null;
channels: Collection<Snowflake, GuildBasedChannel> | null;
relevants: Collection<string, User> | Collection<string, GuildMember> | null;
channel: GuildBasedChannel | BaseGuildVoiceChannel | null;
channels: Collection<string, GuildBasedChannel | BaseGuildVoiceChannel> | null;
textChannel: TextChannel | null;
textChannels: Collection<Snowflake, TextChannel> | null;
textChannels: Collection<string, TextChannel> | null;
voiceChannel: VoiceChannel | null;
voiceChannels: Collection<Snowflake, VoiceChannel> | null;
voiceChannels: Collection<string, VoiceChannel> | null;
categoryChannel: CategoryChannel | null;
categoryChannels: Collection<Snowflake, CategoryChannel> | null;
categoryChannels: Collection<string, CategoryChannel> | null;
newsChannel: NewsChannel | null;
newsChannels: Collection<Snowflake, NewsChannel> | null;
newsChannels: Collection<string, NewsChannel> | null;
storeChannel: StoreChannel | null;
storeChannels: Collection<string, StoreChannel> | null;
stageChannel: StageChannel | null;
stageChannels: Collection<Snowflake, StageChannel> | null;
stageChannels: Collection<string, StageChannel> | null;
threadChannel: ThreadChannel | null;
threadChannels: Collection<Snowflake, ThreadChannel> | null;
directoryChannel: DirectoryChannel | null;
directoryChannels: Collection<Snowflake, DirectoryChannel> | null;
forumChannel: unknown | null;
forumChannels: Collection<Snowflake, unknown> | null;
textBasedChannel: TextBasedChannel | null;
textBasedChannels: Collection<Snowflake, TextBasedChannel> | null;
voiceBasedChannel: VoiceBasedChannel | null;
voiceBasedChannels: Collection<Snowflake, VoiceBasedChannel> | null;
threadChannels: Collection<string, ThreadChannel> | null;
role: Role | null;
roles: Collection<Snowflake, Role> | null;
roles: Collection<string, Role> | null;
emoji: Emoji | null;
emojis: Collection<Snowflake, Emoji> | null;
emojis: Collection<string, Emoji> | null;
guild: Guild | null;
guilds: Collection<Snowflake, Guild> | null;
guilds: Collection<string, Guild> | null;
message: Message | null;

@@ -629,3 +617,3 @@ guildMessage: Message | null;

*/
export declare type OtherwiseContentModifier = (message: Message, text: string | MessagePayload | MessageOptions | OtherwiseContentSupplier, data: FailureData) => string | MessagePayload | MessageOptions | Promise<string | MessagePayload | MessageOptions>;
export declare type OtherwiseContentModifier = (message: Message, text: string, data: FailureData) => string | MessagePayload | MessageOptions | Promise<string | MessagePayload | MessageOptions>;
/**

@@ -643,3 +631,3 @@ * A function returning the content if argument parsing fails.

*/
export declare type PromptContentModifier = (message: Message, text: string | MessagePayload | MessageOptions | OtherwiseContentSupplier, data: ArgumentPromptData) => string | MessagePayload | MessageOptions | Promise<string | MessagePayload | MessageOptions>;
export declare type PromptContentModifier = (message: Message, text: string, data: ArgumentPromptData) => string | MessagePayload | MessageOptions | Promise<string | MessagePayload | MessageOptions>;
/**

@@ -646,0 +634,0 @@ * A function returning text for the prompt.

@@ -17,3 +17,3 @@ "use strict";

constructor(command, options = {}) {
// doing this instead of object deconstruction so it's valid to pass null values
// doing this instead of object deconstruction so its valid to pass null values
const match = options.match ?? Constants_js_1.ArgumentMatches.PHRASE, type = options.type ?? Constants_js_1.ArgumentTypes.STRING, flag = options.flag ?? null, multipleFlags = options.multipleFlags ?? false, index = options.index ?? null, unordered = options.unordered ?? false, limit = options.limit ?? Infinity, prompt = options.prompt ?? null, defaultValue = options.default ?? null, otherwise = options.otherwise ?? null, modifyOtherwise = options.modifyOtherwise ?? null;

@@ -30,3 +30,3 @@ if (!Object.values(Constants_js_1.ArgumentMatches).includes(match))

throw new TypeError("options.index must be a number or null.");
if (typeof unordered !== "boolean" && typeof unordered !== "number" && !(0, Util_js_1.isArrayOf)(unordered, "number"))
if (typeof unordered !== "boolean" && typeof unordered !== "number" && !Util_js_1.Util.isArrayOf(unordered, "number"))
throw new TypeError("options.unordered must be a boolean, number, or array of numbers.");

@@ -89,3 +89,3 @@ if (typeof limit !== "number")

const getText = async (promptType, prompter, retryCount, inputMessage, inputPhrase, inputParsed) => {
let text = await (0, Util_js_1.intoCallable)(prompter).call(this, message, {
let text = await Util_js_1.Util.intoCallable(prompter).call(this, message, {
retries: retryCount,

@@ -156,5 +156,3 @@ infinite: isInfinite,

}
if (!promptOptions.time)
return Flag_js_1.Flag.cancel();
return Flag_js_1.Flag.timeout(promptOptions.time);
return Flag_js_1.Flag.cancel();
}

@@ -226,3 +224,3 @@ if (promptOptions.breakout) {

const modifyOtherwise = this.modifyOtherwise ?? commandDefs.modifyOtherwise ?? handlerDefs.modifyOtherwise ?? null;
let text = await (0, Util_js_1.intoCallable)(otherwise).call(this, message, {
let text = await Util_js_1.Util.intoCallable(otherwise).call(this, message, {
phrase,

@@ -254,3 +252,3 @@ failure

}
return (0, Util_js_1.intoCallable)(this.default)(message, {
return Util_js_1.Util.intoCallable(this.default)(message, {
phrase,

@@ -268,3 +266,3 @@ failure: null

}
return this.default == null ? res : (0, Util_js_1.intoCallable)(this.default)(message, { phrase, failure: res });
return this.default == null ? res : Util_js_1.Util.intoCallable(this.default)(message, { phrase, failure: res });
}

@@ -289,3 +287,3 @@ return res;

let res = type(message, phrase);
if ((0, Util_js_1.isPromise)(res))
if (Util_js_1.Util.isPromise(res))
res = await res;

@@ -309,3 +307,3 @@ return res;

let res = resolver.type(type)?.call(this, message, phrase);
if ((0, Util_js_1.isPromise)(res))
if (Util_js_1.Util.isPromise(res))
res = await res;

@@ -312,0 +310,0 @@ return res;

import type { Message } from "discord.js";
import type { ArgumentGenerator, ArgumentGeneratorReturn, Command } from "../Command.js";
import { ArgumentGenerator, ArgumentGeneratorReturn, Command } from "../Command.js";
import type { ContentParserResult } from "../ContentParser.js";

@@ -4,0 +4,0 @@ import { Flag, FlagType } from "../Flag.js";

@@ -46,4 +46,2 @@ import { Collection } from "discord.js";

constructor(handler: CommandHandler);
private singleChannelBuiltInType;
private multipleChannelBuiltInType;
/**

@@ -50,0 +48,0 @@ * Adds built-in types.

@@ -5,3 +5,3 @@ "use strict";

const discord_js_1 = require("discord.js");
const node_url_1 = require("node:url");
const url_1 = require("url");
const Constants_js_1 = require("../../../util/Constants.js");

@@ -26,23 +26,2 @@ /**

}
singleChannelBuiltInType(type) {
return (message, phrase) => {
if (!phrase || !message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (channel?.type !== type)
return null;
return channel;
};
}
multipleChannelBuiltInType(type) {
return (message, phrase) => {
if (!phrase || !message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
const textChannels = channels.filter(c => c.type === type);
return textChannels.size ? textChannels : null;
};
}
/**

@@ -102,3 +81,3 @@ * Adds built-in types.

try {
return new node_url_1.URL(phrase);
return new url_1.URL(phrase);
}

@@ -158,3 +137,3 @@ catch (err) {

: this.client.util.resolveUser(phrase, new discord_js_1.Collection([
[message.channel.recipientId, message.channel.recipient],
[message.channel.recipient.id, message.channel.recipient],
[this.client.user.id, this.client.user]

@@ -172,3 +151,3 @@ ]));

: this.client.util.resolveUsers(phrase, new discord_js_1.Collection([
[message.channel.recipientId, message.channel.recipient],
[message.channel.recipient.id, message.channel.recipient],
[this.client.user.id, this.client.user]

@@ -195,69 +174,150 @@ ]));

},
[Constants_js_1.ArgumentTypes.TEXT_CHANNEL]: this.singleChannelBuiltInType(discord_js_1.ChannelType.GuildText),
[Constants_js_1.ArgumentTypes.TEXT_CHANNELS]: this.multipleChannelBuiltInType(discord_js_1.ChannelType.GuildText),
[Constants_js_1.ArgumentTypes.VOICE_CHANNEL]: this.singleChannelBuiltInType(discord_js_1.ChannelType.GuildVoice),
[Constants_js_1.ArgumentTypes.VOICE_CHANNELS]: this.multipleChannelBuiltInType(discord_js_1.ChannelType.GuildVoice),
[Constants_js_1.ArgumentTypes.CATEGORY_CHANNEL]: this.singleChannelBuiltInType(discord_js_1.ChannelType.GuildCategory),
[Constants_js_1.ArgumentTypes.CATEGORY_CHANNELS]: this.multipleChannelBuiltInType(discord_js_1.ChannelType.GuildCategory),
[Constants_js_1.ArgumentTypes.NEWS_CHANNEL]: this.singleChannelBuiltInType(discord_js_1.ChannelType.GuildNews),
[Constants_js_1.ArgumentTypes.NEWS_CHANNELS]: this.multipleChannelBuiltInType(discord_js_1.ChannelType.GuildCategory),
[Constants_js_1.ArgumentTypes.STAGE_CHANNEL]: this.singleChannelBuiltInType(discord_js_1.ChannelType.GuildStageVoice),
[Constants_js_1.ArgumentTypes.STAGE_CHANNELS]: this.multipleChannelBuiltInType(discord_js_1.ChannelType.GuildStageVoice),
[Constants_js_1.ArgumentTypes.THREAD_CHANNEL]: (message, phrase) => {
if (!phrase || !message.inGuild())
[Constants_js_1.ArgumentTypes.TEXT_CHANNEL]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel?.isThread())
if (!channel || channel.type !== "GUILD_TEXT")
return null;
return channel;
},
[Constants_js_1.ArgumentTypes.THREAD_CHANNELS]: (message, phrase) => {
if (!phrase || !message.inGuild())
[Constants_js_1.ArgumentTypes.TEXT_CHANNELS]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
const threadChannels = channels.filter(c => c.isThread());
return threadChannels.size ? threadChannels : null;
const textChannels = channels.filter(c => c.isText());
return textChannels.size ? textChannels : null;
},
// @ts-expect-error
[Constants_js_1.ArgumentTypes.DIRECTORY_CHANNEL]: this.singleChannelBuiltInType(discord_js_1.ChannelType.GuildDirectory),
// @ts-expect-error
[Constants_js_1.ArgumentTypes.DIRECTORY_CHANNELS]: this.multipleChannelBuiltInType(discord_js_1.ChannelType.GuildDirectory),
[Constants_js_1.ArgumentTypes.FORUM_CHANNEL]: this.singleChannelBuiltInType(discord_js_1.ChannelType.GuildForum),
[Constants_js_1.ArgumentTypes.FORUM_CHANNELS]: this.multipleChannelBuiltInType(discord_js_1.ChannelType.GuildForum),
[Constants_js_1.ArgumentTypes.TEXT_BASED_CHANNEL]: (message, phrase) => {
if (!phrase || !message.inGuild())
[Constants_js_1.ArgumentTypes.VOICE_CHANNEL]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel?.isTextBased())
if (!channel || channel.type !== "GUILD_VOICE")
return null;
return channel;
},
[Constants_js_1.ArgumentTypes.TEXT_BASED_CHANNELS]: (message, phrase) => {
if (!phrase || !message.inGuild())
[Constants_js_1.ArgumentTypes.VOICE_CHANNELS]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
const threadChannels = channels.filter(c => c.isTextBased());
return threadChannels.size ? threadChannels : null;
const voiceChannels = channels.filter(c => c.isVoice());
return voiceChannels.size ? voiceChannels : null;
},
[Constants_js_1.ArgumentTypes.VOICE_BASED_CHANNEL]: (message, phrase) => {
if (!phrase || !message.inGuild())
[Constants_js_1.ArgumentTypes.CATEGORY_CHANNEL]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel?.isVoiceBased())
if (!channel || channel.type !== "GUILD_CATEGORY")
return null;
return channel;
},
[Constants_js_1.ArgumentTypes.VOICE_BASED_CHANNELS]: (message, phrase) => {
if (!phrase || !message.inGuild())
[Constants_js_1.ArgumentTypes.CATEGORY_CHANNELS]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
const threadChannels = channels.filter(c => c.isVoiceBased());
return threadChannels.size ? threadChannels : null;
const categoryChannels = channels.filter(c => c.type === "GUILD_CATEGORY");
return categoryChannels.size ? categoryChannels : null;
},
[Constants_js_1.ArgumentTypes.NEWS_CHANNEL]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || channel.type !== "GUILD_NEWS")
return null;
return channel;
},
[Constants_js_1.ArgumentTypes.NEWS_CHANNELS]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
const newsChannels = channels.filter(c => c.type === "GUILD_NEWS");
return newsChannels.size ? newsChannels : null;
},
[Constants_js_1.ArgumentTypes.STORE_CHANNEL]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || channel.type !== "GUILD_STORE")
return null;
return channel;
},
[Constants_js_1.ArgumentTypes.STORE_CHANNELS]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
// eslint-disable-next-line deprecation/deprecation
const storeChannels = channels.filter(c => c.type === "GUILD_STORE");
return storeChannels.size ? storeChannels : null;
},
[Constants_js_1.ArgumentTypes.STAGE_CHANNEL]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || channel.type !== "GUILD_STAGE_VOICE")
return null;
return channel;
},
[Constants_js_1.ArgumentTypes.STAGE_CHANNELS]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
const storeChannels = channels.filter(c => c.type === "GUILD_STAGE_VOICE");
return storeChannels.size ? storeChannels : null;
},
[Constants_js_1.ArgumentTypes.THREAD_CHANNEL]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || !channel.isThread())
return null;
return channel;
},
[Constants_js_1.ArgumentTypes.THREAD_CHANNELS]: (message, phrase) => {
if (!phrase)
return null;
if (!message.inGuild())
return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size)
return null;
const storeChannels = channels.filter(c => c.isThread());
return storeChannels.size ? storeChannels : null;
},
[Constants_js_1.ArgumentTypes.ROLE]: (message, phrase) => {

@@ -320,3 +380,3 @@ if (!phrase)

for (const channel of message.guild.channels.cache.values()) {
if (!channel.isTextBased())
if (!channel.isText())
continue;

@@ -342,3 +402,3 @@ try {

for (const channel of message.guild.channels.cache.values()) {
if (!channel.isTextBased())
if (!channel.isText())
continue;

@@ -345,0 +405,0 @@ try {

@@ -1,13 +0,15 @@

import type { ApplicationCommandAutocompleteOption, ApplicationCommandChannelOptionData, ApplicationCommandChoicesData, ApplicationCommandNonOptionsData, ApplicationCommandNumericOptionData, ApplicationCommandSubCommandData, ApplicationCommandSubGroupData, AutocompleteInteraction, LocalizationMap, Message, PermissionResolvable, Snowflake } from "discord.js";
import { ApplicationCommandAutocompleteOption, ApplicationCommandChannelOptionData, ApplicationCommandChoicesData, ApplicationCommandNonOptionsData, ApplicationCommandNumericOptionData, ApplicationCommandPermissionData, ApplicationCommandSubCommandData, ApplicationCommandSubGroupData, AutocompleteInteraction, Guild, Message, PermissionResolvable, Snowflake } from "discord.js";
import type { AkairoMessage } from "../../util/AkairoMessage.js";
import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
import { Argument, type ArgumentOptions, type ArgumentTypeCasterReturn, type DefaultArgumentOptions } from "./arguments/Argument.js";
import { ArgumentRunner, type ArgumentRunnerState } from "./arguments/ArgumentRunner.js";
import type { CommandHandler, IgnoreCheckPredicate, PrefixSupplier, SlashResolveType } from "./CommandHandler.js";
import { ContentParser, type ContentParserResult } from "./ContentParser.js";
import type { Flag } from "./Flag.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import { Argument, ArgumentOptions, ArgumentTypeCasterReturn, DefaultArgumentOptions } from "./arguments/Argument.js";
import { ArgumentRunner, ArgumentRunnerState } from "./arguments/ArgumentRunner.js";
import { CommandHandler, IgnoreCheckPredicate, PrefixSupplier, SlashResolveType } from "./CommandHandler.js";
import { ContentParser, ContentParserResult } from "./ContentParser.js";
import { Flag } from "./Flag.js";
/**
* Represents a command.
*/
export declare abstract class Command extends AkairoModule<CommandHandler, Command> {
export declare abstract class Command extends AkairoModule {
/**

@@ -30,2 +32,6 @@ * Command names.

/**
* Category the command belongs to.
*/
category: Category<string, Command>;
/**
* Usable only in this channel type.

@@ -35,5 +41,9 @@ */

/**
* The Akairo client.
*/
client: AkairoClient;
/**
* Permissions required to run command by the client.
*/
clientPermissions?: PermissionResolvable | MissingPermissionSupplier;
clientPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;
/**

@@ -56,2 +66,14 @@ * Cooldown in milliseconds.

/**
* The filepath.
*/
filepath: string;
/**
* The handler.
*/
handler: CommandHandler;
/**
* The ID of the command.
*/
id: string;
/**
* ID of user(s) to ignore cooldown or a function to ignore.

@@ -65,9 +87,5 @@ */

/**
* The slash command localizations.
*/
localization: CommandLocalization;
/**
* The key supplier for the locker.
*/
lock?: KeySupplier;
lock?: KeySupplier | "channel" | "guild" | "user";
/**

@@ -106,11 +124,7 @@ * Stores the current locks.

/**
* The default bitfield used to determine whether this command be used in a guild
*/
slashDefaultMemberPermissions?: PermissionResolvable;
/**
* Whether the command is enabled in DMs
* The default permission to set when creating the slash command.
*
* **Cannot be enabled for commands that specify `slashGuilds`**
* **Note:** Requires the useSlashPermissions to be enabled in the command handler
*/
slashDmPermission?: boolean;
slashDefaultPermission: boolean;
/**

@@ -129,2 +143,6 @@ * Whether slash command responses for this command should be ephemeral or not.

/**
* The slash permissions to set in each guild for this command.
*/
slashPermissions?: ApplicationCommandPermissionData[] | SlashPermissionsSupplier;
/**
* Only allows this command to be executed as a slash command.

@@ -144,3 +162,3 @@ */

*/
userPermissions?: PermissionResolvable | MissingPermissionSupplier;
userPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;
/**

@@ -162,3 +180,2 @@ * Generator for arguments.

* @param state - Argument processing state.
* @abstract
*/

@@ -169,3 +186,2 @@ args(message: Message, parsed: ContentParserResult, state: ArgumentRunnerState): ArgumentGeneratorReturn;

* @param message - Message being handled.
* @abstract
*/

@@ -176,3 +192,2 @@ before(message: Message): any;

* @param message - Message being handled.
* @abstract
*/

@@ -184,6 +199,5 @@ condition(message: Message): boolean | Promise<boolean>;

* @param args - Evaluated arguments.
* @abstract
*/
exec?(message: Message, args: any): any;
exec?(message: Message | AkairoMessage, args: any): any;
exec(message: Message, args: any): any;
exec(message: Message | AkairoMessage, args: any): any;
/**

@@ -193,11 +207,9 @@ * Execute the slash command

* @param args - Slash command options
* @abstract
*/
execSlash?(message: AkairoMessage, ...args: any[]): any;
execSlash(message: AkairoMessage, ...args: any[]): any;
/**
* Respond to autocomplete interactions for this command.
* @param interaction The autocomplete interaction
* @abstract
*/
autocomplete?(interaction: AutocompleteInteraction): any;
autocomplete(interaction: AutocompleteInteraction): any;
/**

@@ -210,2 +222,12 @@ * Parses content using the command's arguments.

}
export interface Command extends AkairoModule {
/**
* Reloads the command.
*/
reload(): Promise<Command>;
/**
* Removes the command.
*/
remove(): Command;
}
/**

@@ -244,3 +266,3 @@ * Options to use for command execution behavior.

*/
clientPermissions?: PermissionResolvable | MissingPermissionSupplier;
clientPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;
/**

@@ -280,6 +302,2 @@ * Whether or not to run on messages that are not directly commands.

/**
* The slash command localizations.
*/
localization?: CommandLocalization;
/**
* The key type or key generator for the locker. If lock is a string, it's expected one of 'guild', 'channel', or 'user'

@@ -333,14 +351,8 @@ */

/**
* The default bitfield used to determine whether this command be used in a guild
* @default typeof this.userPermissions !== "function" ? this.userPermissions : undefined
*/
slashDefaultMemberPermissions?: PermissionResolvable;
/**
* Whether the command is enabled in DMs
* The default permission to set when creating the slash command.
*
* **Cannot be enabled for commands that specify `slashGuilds`**
*
* @default this.channel === 'dm'
* **Note:** Requires `useSlashPermissions` to be enabled in the command handler
* @default this.handler.useSlashPermissions ? !this.ownerOnly : true
*/
slashDmPermission?: boolean;
slashDefaultPermission?: boolean;
/**

@@ -361,2 +373,6 @@ * Whether slash command responses for this command should be ephemeral or not.

/**
* The slash permissions to set in each guild for this command.
*/
slashPermissions?: ApplicationCommandPermissionData[] | SlashPermissionsSupplier;
/**
* Only allow this command to be used as a slash command. Also makes `slash` `true`

@@ -379,3 +395,3 @@ */

*/
userPermissions?: PermissionResolvable | MissingPermissionSupplier;
userPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;
}

@@ -405,2 +421,7 @@ /**

/**
* A function used to create slash permissions depending on the guild.
* @param guild The guild to create slash permissions for.
*/
export declare type SlashPermissionsSupplier = (guild: Guild) => ApplicationCommandPermissionData[];
/**
* A function used to return a regular expression.

@@ -478,16 +499,2 @@ * @param message - Message to get regex for.

/**
* The localization for slash commands.
*
* @example
* const localization = {
* nameLocalizations: {
* ["en-US"]: "command name",
* },
* descriptionLocalizations: {
* ["en-US"]: "command description",
* },
* }
*/
export declare type CommandLocalization = Record<"nameLocalizations" | "descriptionLocalizations", LocalizationMap>;
/**
* @typedef {ApplicationCommandOptionType} VSCodePleaseStopRemovingMyImports

@@ -494,0 +501,0 @@ * @internal

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Command = void 0;
const AkairoError_js_1 = require("../../util/AkairoError.js");
const Util_js_1 = require("../../util/Util.js");

@@ -20,8 +21,6 @@ const AkairoModule_js_1 = require("../AkairoModule.js");

super(id, { category: options?.category });
const { aliases = [], args = this._args || this.args || [], argumentDefaults = {}, before = this.before || (() => undefined), channel = null, clientPermissions = this.clientPermissions, condition = this.condition || (() => false), cooldown = null, description = "", editable = true, flags = [], ignoreCooldown, ignorePermissions, localization = {}, lock, onlyNsfw = false, optionFlags = [], ownerOnly = false, prefix = this.prefix, quoted = true, ratelimit = 1, regex = this.regex, separator, slash = false, slashEphemeral = false, slashGuilds = [], slashOnly = false, slashOptions, superUserOnly = false, typing = false, userPermissions = this.userPermissions } = options ?? {};
// ts doesn't like it when I reference other properties when using destructuring syntax
const { slashDefaultMemberPermissions = userPermissions && typeof userPermissions !== "function" ? userPermissions : undefined, slashDmPermission = slashGuilds.length > 0 ? channel === null || channel === "dm" : undefined } = options ?? {};
if (!(0, Util_js_1.isArrayOf)(aliases, "string"))
const { aliases = [], args = this._args || this.args || [], argumentDefaults = {}, before = this.before || (() => undefined), channel = null, clientPermissions = this.clientPermissions, condition = this.condition || (() => false), cooldown = null, description = "", editable = true, flags = [], ignoreCooldown, ignorePermissions, lock, onlyNsfw = false, optionFlags = [], ownerOnly = false, prefix = this.prefix, quoted = true, ratelimit = 1, regex = this.regex, separator, slash = false, slashDefaultPermission, slashEphemeral = false, slashGuilds = [], slashOnly = false, slashOptions, slashPermissions, superUserOnly = false, typing = false, userPermissions = this.userPermissions } = options ?? {};
if (!Util_js_1.Util.isArrayOf(aliases, "string"))
throw new TypeError("options.aliases must be an array of strings.");
if (typeof args !== "function" && !(0, Util_js_1.isArrayOf)(args, "object"))
if (typeof args !== "function" && !Util_js_1.Util.isArrayOf(args, "object"))
throw new TypeError("options.args must be an array of argument objects or a function.");

@@ -40,3 +39,3 @@ if (typeof argumentDefaults !== "object")

throw new TypeError("options.editable must be a boolean.");
if (!(0, Util_js_1.isArrayOf)(flags, "string"))
if (!Util_js_1.Util.isArrayOf(flags, "string"))
throw new TypeError("options.flags must be an array of strings.");

@@ -47,4 +46,2 @@ if (ignoreCooldown !== undefined && !(0, Util_js_1.isStringArrayStringOrFunc)(ignoreCooldown))

throw new TypeError("options.ignorePermissions must be a string, function, or array of strings.");
if (typeof localization !== "object")
throw new TypeError("options.localization must be an object.");
if (lock !== undefined && typeof lock !== "function" && !["channel", "guild", "user"].includes(lock))

@@ -54,3 +51,3 @@ throw new TypeError("options.lock must be a function or a string with a value of 'channel', 'guild', or 'user'.");

throw new TypeError("options.onlyNsfw must be a boolean.");
if (!(0, Util_js_1.isArrayOf)(optionFlags, "string"))
if (!Util_js_1.Util.isArrayOf(optionFlags, "string"))
throw new TypeError("options.optionFlags must be an array of strings.");

@@ -71,14 +68,14 @@ if (typeof ownerOnly !== "boolean")

throw new TypeError("options.slash must be a boolean.");
if (slashDmPermission !== undefined && typeof slashDmPermission !== "boolean")
throw new TypeError("options.slashDmPermission must be a boolean.");
if (typeof slashDmPermission !== "boolean" && slashGuilds.length > 0)
throw new TypeError("You cannot set `options.slashDmPermission` with commands configured with `options.slashGuilds`.");
if (slashDefaultPermission && typeof slashDefaultPermission !== "boolean")
throw new TypeError("options.slashDefaultPermission must be a boolean.");
if (typeof slashEphemeral !== "boolean")
throw new TypeError("options.slashEphemeral must be a boolean.");
if (!(0, Util_js_1.isArrayOf)(slashGuilds, "string"))
if (!Util_js_1.Util.isArrayOf(slashGuilds, "string"))
throw new TypeError("options.slashGuilds must be an array of strings.");
if (typeof slashOnly !== "boolean")
throw new TypeError("options.slashOnly must be a boolean.");
if (slashOptions !== undefined && !(0, Util_js_1.isArrayOf)(slashOptions, "object"))
if (slashOptions !== undefined && !Util_js_1.Util.isArrayOf(slashOptions, "object"))
throw new TypeError("options.slashOptions must be an array of objects.");
if (slashPermissions !== undefined && typeof slashPermissions !== "function" && !Util_js_1.Util.isArrayOf(slashPermissions, "object"))
throw new TypeError("options.slashPermissions must be an array of objects or a function.");
if (typeof superUserOnly !== "boolean")

@@ -110,3 +107,3 @@ throw new TypeError("options.superUserOnly must be a boolean.");

this.editable = Boolean(editable);
this.localization = localization;
this.lock = lock;
this.onlyNsfw = Boolean(onlyNsfw);

@@ -120,10 +117,9 @@ this.ownerOnly = Boolean(ownerOnly);

this.userPermissions = typeof userPermissions === "function" ? userPermissions.bind(this) : userPermissions;
this.lock =
typeof lock === "string"
? {
guild: (message) => message.guild && message.guild.id,
channel: (message) => message.channel.id,
user: (message) => message.author.id
}[lock]
: lock;
if (typeof lock === "string") {
this.lock = {
guild: (message) => message.guild && message.guild.id,
channel: (message) => message.channel.id,
user: (message) => message.author.id
}[lock];
}
if (this.lock)

@@ -134,4 +130,3 @@ this.locker = new Set();

this.slash = slash;
this.slashDefaultMemberPermissions = slashDefaultMemberPermissions;
this.slashDmPermission = slashDmPermission;
this.slashDefaultPermission = slashDefaultPermission;
this.slashEphemeral = slashEphemeral;

@@ -141,2 +136,3 @@ this.slashGuilds = slashGuilds;

this.slashOptions = slashOptions;
this.slashPermissions = typeof slashPermissions === "function" ? slashPermissions.bind(this) : slashPermissions;
}

@@ -150,3 +146,2 @@ /**

* @param state - Argument processing state.
* @abstract
*/

@@ -158,3 +153,2 @@ // @ts-expect-error

* @param message - Message being handled.
* @abstract
*/

@@ -165,3 +159,2 @@ before(message) { }

* @param message - Message being handled.
* @abstract
*/

@@ -171,3 +164,19 @@ condition(message) {

}
exec(message, args) {
throw new AkairoError_js_1.AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
/**
* Execute the slash command
* @param message - Message for slash command
* @param args - Slash command options
*/
execSlash(message, ...args) {
throw new AkairoError_js_1.AkairoError("NOT_IMPLEMENTED", this.constructor.name, "execSlash");
}
/**
* Respond to autocomplete interactions for this command.
* @param interaction The autocomplete interaction
*/
autocomplete(interaction) { }
/**
* Parses content using the command's arguments.

@@ -183,5 +192,2 @@ * @param message - Message to use.

exports.Command = Command;
(0, Util_js_1.patchAbstract)(Command, "exec");
(0, Util_js_1.patchAbstract)(Command, "execSlash");
(0, Util_js_1.patchAbstract)(Command, "autocomplete");
/**

@@ -188,0 +194,0 @@ * @typedef {ApplicationCommandOptionType} VSCodePleaseStopRemovingMyImports

/// <reference types="node" />
import { Collection, DiscordAPIError, type ApplicationCommandData, type AutocompleteInteraction, type Awaitable, type ChatInputCommandInteraction, type Guild, type Message, type Snowflake, type TextBasedChannel, type User } from "discord.js";
import type { CommandHandlerEvents as CommandHandlerEventsType } from "../../typings/events.js";
import { ApplicationCommandData, AutocompleteInteraction, Awaitable, Collection, CommandInteraction, DiscordAPIError, Guild, Message, Snowflake, TextBasedChannel, User } from "discord.js";
import type { CommandHandlerEvents as CommandHandlerEventsType } from "../../typings/events";
import { AkairoMessage } from "../../util/AkairoMessage.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import type { Category } from "../../util/Category.js";
import { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import type { AkairoModule } from "../AkairoModule.js";
import { ContextMenuCommandHandler } from "../contextMenuCommands/ContextMenuCommandHandler.js";

@@ -18,3 +20,3 @@ import type { InhibitorHandler } from "../inhibitors/InhibitorHandler.js";

*/
export declare class CommandHandler extends AkairoHandler<Command, CommandHandler> {
export declare class CommandHandler extends AkairoHandler {
/**

@@ -53,2 +55,14 @@ * Collection of command aliases.

/**
* Categories, mapped by ID to Category.
*/
categories: Collection<string, Category<string, Command>>;
/**
* Class to handle
*/
classToHandle: typeof Command;
/**
* The Akairo client.
*/
client: AkairoClient;
/**
* Whether or not `message.util` is assigned.

@@ -82,2 +96,6 @@ */

/**
* Directory to commands.
*/
directory: string;
/**
* Whether or not to require the use of execSlash for slash commands.

@@ -107,2 +125,6 @@ */

/**
* Commands loaded, mapped by ID to Command.
*/
modules: Collection<string, Command>;
/**
* The prefix(es) for command parsing.

@@ -136,2 +158,8 @@ */

/**
* Use slash command permissions for owner only commands
*
* Warning: this is experimental
*/
useSlashPermissions: boolean;
/**
* @param client - The Akairo client.

@@ -150,2 +178,6 @@ * @param options - Options.

/**
* updates interaction permissions
*/
protected updateInteractionPermissions(owners: Snowflake | Snowflake[]): Promise<void>;
/**
* Registers a module.

@@ -170,3 +202,3 @@ * @param command - Module to use.

*/
handleSlash(interaction: ChatInputCommandInteraction): Promise<boolean | null>;
handleSlash(interaction: CommandInteraction): Promise<boolean | null>;
/**

@@ -268,3 +300,3 @@ * Handles autocomplete interactions.

*/
emitError(err: Error, message: Message | AkairoMessage, command?: Command): void;
emitError(err: Error, message: Message | AkairoMessage, command?: Command | AkairoModule): void;
/**

@@ -320,3 +352,32 @@ * Sweep command util instances from cache and returns amount sweeped.

declare type Events = CommandHandlerEventsType;
export interface CommandHandler extends AkairoHandler<Command, CommandHandler> {
export interface CommandHandler extends AkairoHandler {
/**
* Loads a command.
* @param thing - Module or path to module.
*/
load(thing: string | Command): Promise<Command>;
/**
* Reads all commands from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<CommandHandler>;
/**
* Removes a command.
* @param id - ID of the command.
*/
remove(id: string): Command;
/**
* Removes all commands.
*/
removeAll(): CommandHandler;
/**
* Reloads a command.
* @param id - ID of the command.
*/
reload(id: string): Promise<Command>;
/**
* Reloads all commands.
*/
reloadAll(): Promise<CommandHandler>;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;

@@ -332,3 +393,3 @@ once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;

}
export interface CommandHandlerOptions extends AkairoHandlerOptions<Command, CommandHandler> {
export interface CommandHandlerOptions extends AkairoHandlerOptions {
/**

@@ -435,2 +496,9 @@ * Regular expression to automatically make command aliases.

skipBuiltInPostInhibitors?: boolean;
/**
* Use slash command permissions for owner only commands
*
* Warning: this is experimental
* @default false
*/
useSlashPermissions?: boolean;
}

@@ -495,9 +563,5 @@ /**

export declare type PrefixSupplier = (message: Message) => string | string[] | Promise<string | string[]>;
declare const slashResolvable: readonly ["Attachment", "Boolean", "Channel", "Integer", "Member", "Mentionable", "Number", "Role", "String", "User"];
declare const slashResolvable: readonly ["Boolean", "Channel", "String", "Integer", "Number", "User", "Member", "Role", "Mentionable", "Attachment"];
export declare type SlashResolveType = typeof slashResolvable[number];
export {};
/**
* @typedef {CommandInteractionOptionResolver} VSCodePleaseStopRemovingMyImports
* @internal
*/
//# sourceMappingURL=CommandHandler.d.ts.map

@@ -19,8 +19,2 @@ "use strict";

class CommandHandler extends AkairoHandler_js_1.AkairoHandler {
// /**
// * Use slash command permissions for owner only commands
// *
// * Warning: this is experimental
// */
// public declare useSlashPermissions: boolean;
/**

@@ -32,5 +26,3 @@ * @param client - The Akairo client.

constructor(client, options) {
const { directory, classToHandle = Command_1.Command, extensions = [".js", ".ts"], automateCategories, loadFilter, blockClient = true, blockBots = true, fetchMembers = false, handleEdits = false, storeMessages = false, commandUtil = false, commandUtilLifetime = 3e5, commandUtilSweepInterval = 3e5, defaultCooldown = 0, ignoreCooldown = client.ownerID, ignorePermissions = [], argumentDefaults = {}, prefix = "!", allowMention = true, aliasReplacement, autoDefer = false, typing = false, autoRegisterSlashCommands = false, execSlash = false, skipBuiltInPostInhibitors = false
// useSlashPermissions = false
} = options ?? {};
const { directory, classToHandle = Command_1.Command, extensions = [".js", ".ts"], automateCategories, loadFilter, blockClient = true, blockBots = true, fetchMembers = false, handleEdits = false, storeMessages = false, commandUtil = false, commandUtilLifetime = 3e5, commandUtilSweepInterval = 3e5, defaultCooldown = 0, ignoreCooldown = client.ownerID, ignorePermissions = [], argumentDefaults = {}, prefix = "!", allowMention = true, aliasReplacement, autoDefer = false, typing = false, autoRegisterSlashCommands = false, execSlash = false, skipBuiltInPostInhibitors = false, useSlashPermissions = false } = options ?? {};
if (!(classToHandle.prototype instanceof Command_1.Command || classToHandle === Command_1.Command)) {

@@ -79,3 +71,4 @@ throw new AkairoError_js_1.AkairoError("INVALID_CLASS_TO_HANDLE", classToHandle.name, Command_1.Command.name);

throw new TypeError("options.skipBuiltInPostInhibitors must be a boolean.");
// if (typeof useSlashPermissions !== "boolean") throw new TypeError("options.useSlashPermissions must be a boolean.");
if (typeof useSlashPermissions !== "boolean")
throw new TypeError("options.useSlashPermissions must be a boolean.");
super(client, {

@@ -113,3 +106,3 @@ directory,

this.prompts = new discord_js_1.Collection();
this.argumentDefaults = (0, Util_js_1.deepAssign)({
this.argumentDefaults = Util_js_1.Util.deepAssign({
prompt: {

@@ -136,4 +129,4 @@ start: "",

this.execSlash = Boolean(execSlash);
// this.skipBuiltInPostInhibitors = Boolean(skipBuiltInPostInhibitors);
// this.useSlashPermissions = Boolean(useSlashPermissions);
this.skipBuiltInPostInhibitors = Boolean(skipBuiltInPostInhibitors);
this.useSlashPermissions = Boolean(useSlashPermissions);
this.setup();

@@ -147,6 +140,6 @@ }

if (this.autoRegisterSlashCommands)
this.registerInteractionCommands();
// .then(() => {
// if (this.useSlashPermissions) this.updateInteractionPermissions(this.client.ownerID /* this.client.superUserID */);
// });
this.registerInteractionCommands().then(() => {
if (this.useSlashPermissions)
this.updateInteractionPermissions(this.client.ownerID /* this.client.superUserID */);
});
this.client.on("messageCreate", async (m) => {

@@ -173,5 +166,5 @@ const message = m.partial ? await m.fetch().catch(() => null) : m;

this.client.on("interactionCreate", i => {
if (i.isChatInputCommand())
if (i.isCommand())
this.handleSlash(i);
if (i.type === discord_js_1.InteractionType.ApplicationCommandAutocomplete)
if (i.isAutocomplete())
this.handleAutocomplete(i);

@@ -215,7 +208,4 @@ });

guilds: data.slashGuilds ?? [],
defaultMemberPermissions: data.slashDefaultMemberPermissions,
dmPermission: data.slashDmPermission,
type: discord_js_1.ApplicationCommandType.ChatInput,
nameLocalizations: data.localization.nameLocalizations,
descriptionLocalizations: data.localization.descriptionLocalizations
defaultPermission: data.slashDefaultPermission,
type: 1 /* ApplicationCommandTypes.CHAT_INPUT */
});

@@ -235,6 +225,4 @@ }

guilds: data.guilds ?? [],
defaultMemberPermissions: data.defaultMemberPermissions,
dmPermission: data.dmPermission,
type: data.type,
nameLocalizations: data.nameLocalizations
defaultPermission: this.useSlashPermissions ? !(data.ownerOnly || /* data.superUserOnly || */ false) : true,
type: data.type
});

@@ -248,9 +236,10 @@ }

name: options.name,
description: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.description ?? "" : undefined,
options: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.options ?? [] : undefined,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
description: options.type === 1 /* ApplicationCommandTypes.CHAT_INPUT */ || options.type === "CHAT_INPUT"
? options.description ?? ""
: undefined,
options: options.type === 1 /* ApplicationCommandTypes.CHAT_INPUT */ || options.type === "CHAT_INPUT"
? options.options ?? []
: undefined,
defaultPermission: options.defaultPermission,
type: options.type
}))

@@ -265,11 +254,8 @@ .sort((a, b) => {

const currentGlobalCommands = (await this.client.application?.commands.fetch())
.map(options => ({
name: options.name,
description: options.description,
options: options.options,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
.map(value1 => ({
name: value1.name,
description: value1.description,
options: value1.options,
defaultPermission: value1.defaultPermission,
type: value1.type
}))

@@ -283,3 +269,3 @@ .sort((a, b) => {

});
if (!(0, Util_js_1.deepEquals)(currentGlobalCommands, slashCommandsApp)) {
if (!Util_js_1.Util.deepEquals(currentGlobalCommands, slashCommandsApp)) {
this.client.emit("akairoDebug", "[registerInteractionCommands] Updating global interaction commands.", slashCommandsApp);

@@ -303,9 +289,10 @@ await this.client.application?.commands.set(slashCommandsApp).catch(error => {

name: options.name,
description: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.description ?? "" : undefined,
options: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.options ?? [] : undefined,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
description: options.type === 1 /* ApplicationCommandTypes.CHAT_INPUT */ || options.type === "CHAT_INPUT"
? options.description ?? ""
: undefined,
options: options.type === 1 /* ApplicationCommandTypes.CHAT_INPUT */ || options.type === "CHAT_INPUT"
? options.options ?? []
: undefined,
defaultPermission: options.defaultPermission,
type: options.type
}

@@ -328,11 +315,8 @@ ]);

const currentGuildCommands = (await guild.commands.fetch())
.map(options => ({
name: options.name,
description: options.description,
options: options.options,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations: options.type === discord_js_1.ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
.map(value1 => ({
name: value1.name,
description: value1.description,
options: value1.options,
defaultPermission: value1.defaultPermission,
type: value1.type
}))

@@ -346,3 +330,3 @@ .sort((a, b) => {

});
if (!(0, Util_js_1.deepEquals)(currentGuildCommands, sortedCommands)) {
if (!Util_js_1.Util.deepEquals(currentGuildCommands, sortedCommands)) {
this.client.emit("akairoDebug", `[registerInteractionCommands] Updating guild commands for ${guild.name}.`, sortedCommands);

@@ -362,65 +346,56 @@ await guild.commands.set(sortedCommands).catch(error => {

}
// /**
// * updates interaction permissions
// */
// protected async updateInteractionPermissions(owners: Snowflake | Snowflake[] /* superUsers: Snowflake | Snowflake[] */) {
// const mapCom = (
// value: ApplicationCommand<{ guild: GuildResolvable }>,
// guild: Guild
// ): GuildApplicationCommandPermissionData => {
// const command = this.modules.find(mod => mod.aliases[0] === value.name);
// if (!command?.slashPermissions) {
// let allowedUsers: string[] = [];
// /* if (command.superUserOnly) allowedUsers.push(...Util.intoArray(superUsers)); */
// if (command?.ownerOnly) allowedUsers.push(...Util.intoArray(owners));
// allowedUsers = [...new Set(allowedUsers)]; // remove duplicates
// return {
// id: value.id,
// permissions: allowedUsers.map(u => ({
// id: u,
// type: ApplicationCommandPermissionType.User,
// permission: true
// }))
// };
// } else {
// return {
// id: value.id,
// permissions: typeof command.slashPermissions === "function" ? command.slashPermissions(guild) : command.slashPermissions
// };
// }
// };
// const globalCommands = (await this.client.application?.commands.fetch())?.filter(value =>
// Boolean(this.modules.find(mod => mod.aliases[0] === value.name))
// );
// const fullPermissions = globalCommands
// ?.filter(value => !value.defaultPermission)
// .filter(value => Boolean(this.modules.find(mod => mod.aliases[0] === value.name)));
// const promises = this.client.guilds.cache.map(
// /* async */ guild => {
// const perms = new Array(...((fullPermissions ?? new Collection()).map(value => mapCom(value, guild)) ?? []));
// // await guild.commands.fetch();
// if (guild.commands.cache.size)
// perms.push(...guild.commands.cache.filter(value => !value.defaultPermission).map(value => mapCom(value, guild)));
// if (guild.available)
// return guild.commands.permissions.set({
// fullPermissions: perms
// });
// // Return empty promise if guild is unavailable
// return Promise.resolve();
// }
// );
// try {
// await Promise.all(promises);
// } catch (e) {
// this.client.emit(
// "akairoDebug",
// "[updateInteractionPermissions] Error updating interaction permissions, here are the promises, globalCommands, and fullPermissions",
// promises,
// globalCommands,
// fullPermissions
// );
// throw e;
// }
// }
/**
* updates interaction permissions
*/
async updateInteractionPermissions(owners /* superUsers: Snowflake | Snowflake[] */) {
const mapCom = (value, guild) => {
const command = this.modules.find(mod => mod.aliases[0] === value.name);
if (!command?.slashPermissions) {
let allowedUsers = [];
/* if (command.superUserOnly) allowedUsers.push(...Util.intoArray(superUsers)); */
if (command?.ownerOnly)
allowedUsers.push(...Util_js_1.Util.intoArray(owners));
allowedUsers = [...new Set(allowedUsers)]; // remove duplicates
return {
id: value.id,
permissions: allowedUsers.map(u => ({
id: u,
type: "USER",
permission: true
}))
};
}
else {
return {
id: value.id,
permissions: typeof command.slashPermissions === "function" ? command.slashPermissions(guild) : command.slashPermissions
};
}
};
const globalCommands = (await this.client.application?.commands.fetch())?.filter(value => Boolean(this.modules.find(mod => mod.aliases[0] === value.name)));
const fullPermissions = globalCommands
?.filter(value => !value.defaultPermission)
.filter(value => Boolean(this.modules.find(mod => mod.aliases[0] === value.name)));
const promises = this.client.guilds.cache.map(
/* async */ guild => {
const perms = new Array(...((fullPermissions ?? new discord_js_1.Collection()).map(value => mapCom(value, guild)) ?? []));
// await guild.commands.fetch();
if (guild.commands.cache.size)
perms.push(...guild.commands.cache.filter(value => !value.defaultPermission).map(value => mapCom(value, guild)));
if (guild.available)
return guild.commands.permissions.set({
fullPermissions: perms
});
// Return empty promise if guild is unavailable
return Promise.resolve();
});
try {
await Promise.all(promises);
}
catch (e) {
this.client.emit("akairoDebug", "[updateInteractionPermissions] Error updating interaction permissions, here are the promises, globalCommands, and fullPermissions", promises, globalCommands, fullPermissions);
throw e;
}
}
/**
* Registers a module.

@@ -432,4 +407,4 @@ * @param command - Module to use.

super.register(command, filepath);
// if (command.slashDefaultPermission === undefined)
// command.slashDefaultPermission = this.useSlashPermissions ? !command.ownerOnly : true;
if (command.slashDefaultPermission === undefined)
command.slashDefaultPermission = this.useSlashPermissions ? !command.ownerOnly : true;
for (let alias of command.aliases) {

@@ -476,3 +451,3 @@ const conflict = this.aliases.get(alias.toLowerCase());

if (newEntry) {
this.prefixes = this.prefixes.sort((aVal, bVal, aKey, bKey) => (0, Util_js_1.prefixCompare)(aKey, bKey));
this.prefixes = this.prefixes.sort((aVal, bVal, aKey, bKey) => Util_js_1.Util.prefixCompare(aKey, bKey));
}

@@ -625,7 +600,6 @@ }

for (const option of interaction.options["_hoistedOptions"]) {
if (option.type === discord_js_1.ApplicationCommandOptionType.Subcommand ||
option.type === discord_js_1.ApplicationCommandOptionType.SubcommandGroup)
if (option.type === "SUB_COMMAND" || option.type === "SUB_COMMAND_GROUP")
continue;
const originalOption = commandModule.slashOptions?.find(o => o.name === option.name);
const func = `get${originalOption?.resolve ?? discord_js_1.ApplicationCommandOptionType[option.type]}`;
const func = `get${originalOption?.resolve ?? [option.type.charAt(0) + Util_js_1.Util.snakeToCamelCase(option.type.substring(1))]}`;
if (![

@@ -643,7 +617,7 @@ "getBoolean",

].includes(func))
throw new Error(`Unknown slash option type: ${option.type}`);
throw new Error(`${func} is not a valid get function.`);
convertedOptions[option.name] = interaction.options[func](option.name, false);
}
// Makes options that are not found to be null so that it matches the behavior normal commands.
out: {
(() => {
if (convertedOptions.subcommand || convertedOptions.subcommandGroup) {

@@ -653,20 +627,22 @@ const usedSubcommandOrGroup = commandModule.slashOptions?.find(o => o.name === convertedOptions.subcommand);

this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand");
break out;
return;
}
if (usedSubcommandOrGroup.type === discord_js_1.ApplicationCommandOptionType.Subcommand) {
if (usedSubcommandOrGroup.type === "SUB_COMMAND" ||
usedSubcommandOrGroup.type === 1 /* ApplicationCommandOptionTypes.SUB_COMMAND */) {
if (!usedSubcommandOrGroup.options) {
this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand options");
break out;
return;
}
handleOptions(usedSubcommandOrGroup.options);
}
else if (usedSubcommandOrGroup.type === discord_js_1.ApplicationCommandOptionType.SubcommandGroup) {
else if (usedSubcommandOrGroup.type === "SUB_COMMAND_GROUP" ||
usedSubcommandOrGroup.type === 2 /* ApplicationCommandOptionTypes.SUB_COMMAND_GROUP */) {
const usedSubCommand = usedSubcommandOrGroup.options?.find(subcommand => subcommand.name === convertedOptions.subcommand);
if (!usedSubCommand) {
this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand");
break out;
return;
}
else if (!usedSubCommand.options) {
this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand options");
break out;
return;
}

@@ -682,21 +658,26 @@ handleOptions(usedSubCommand.options);

}
// eslint-disable-next-line no-inner-declarations
function handleOptions(options) {
for (const option of options) {
switch (option.type) {
case discord_js_1.ApplicationCommandOptionType.Boolean:
case 5 /* ApplicationCommandOptionTypes.BOOLEAN */:
case "BOOLEAN":
convertedOptions[option.name] ??= false;
break;
case discord_js_1.ApplicationCommandOptionType.Channel:
case discord_js_1.ApplicationCommandOptionType.Integer:
case discord_js_1.ApplicationCommandOptionType.Mentionable:
case discord_js_1.ApplicationCommandOptionType.Number:
case discord_js_1.ApplicationCommandOptionType.Role:
case discord_js_1.ApplicationCommandOptionType.String:
case discord_js_1.ApplicationCommandOptionType.User:
case discord_js_1.ApplicationCommandOptionType.Attachment:
convertedOptions[option.name] ??= null;
break;
case 7 /* ApplicationCommandOptionTypes.CHANNEL */:
case "CHANNEL":
case 4 /* ApplicationCommandOptionTypes.INTEGER */:
case "INTEGER":
case 9 /* ApplicationCommandOptionTypes.MENTIONABLE */:
case "MENTIONABLE":
case 10 /* ApplicationCommandOptionTypes.NUMBER */:
case "NUMBER":
case 8 /* ApplicationCommandOptionTypes.ROLE */:
case "ROLE":
case 3 /* ApplicationCommandOptionTypes.STRING */:
case "STRING":
case 6 /* ApplicationCommandOptionTypes.USER */:
case "USER":
case 11 /* ApplicationCommandOptionTypes.ATTACHMENT */:
case "ATTACHMENT":
default:
// @ts-expect-error
convertedOptions[option.name] ??= null;

@@ -707,3 +688,3 @@ break;

}
}
})();
let key;

@@ -713,3 +694,3 @@ try {

key = commandModule.lock(message, convertedOptions);
if ((0, Util_js_1.isPromise)(key))
if (Util_js_1.Util.isPromise(key))
key = await key;

@@ -783,3 +764,3 @@ if (key) {

const before = command.before(message);
if ((0, Util_js_1.isPromise)(before))
if (Util_js_1.Util.isPromise(before))
await before;

@@ -791,6 +772,2 @@ const args = await command.parse(message, content);

}
else if (Flag_js_1.Flag.is(args, Flag_js_1.FlagType.Timeout)) {
this.emit(Constants_js_1.CommandHandlerEvents.COMMAND_TIMEOUT, message, command, args.time);
return true;
}
else if (Flag_js_1.Flag.is(args, Flag_js_1.FlagType.Retry)) {

@@ -807,3 +784,3 @@ this.emit(Constants_js_1.CommandHandlerEvents.COMMAND_BREAKOUT, message, command, args.message);

key = command.lock(message, args);
if ((0, Util_js_1.isPromise)(key))
if (Util_js_1.Util.isPromise(key))
key = await key;

@@ -877,3 +854,3 @@ if (key) {

const before = command.before(message);
if ((0, Util_js_1.isPromise)(before))
if (Util_js_1.Util.isPromise(before))
await before;

@@ -902,3 +879,3 @@ await this.runCommand(message, command, { match, matches });

let cond = command.condition(message);
if ((0, Util_js_1.isPromise)(cond))
if (Util_js_1.Util.isPromise(cond))
cond = await cond;

@@ -920,3 +897,3 @@ if (cond)

const before = command.before(message);
if ((0, Util_js_1.isPromise)(before))
if (Util_js_1.Util.isPromise(before))
await before;

@@ -1041,3 +1018,3 @@ await this.runCommand(message, command, {});

let missing = command.clientPermissions(message);
if ((0, Util_js_1.isPromise)(missing))
if (Util_js_1.Util.isPromise(missing))
missing = await missing;

@@ -1049,6 +1026,6 @@ if (missing != null) {

}
else if (message.inGuild()) {
if (!message.channel || message.channel.isDMBased())
else if (message.guild) {
if (message.channel?.type === "DM")
return false;
const missing = message.channel?.permissionsFor(message.guild.members.me)?.missing(command.clientPermissions);
const missing = message.channel?.permissionsFor(message.guild.me)?.missing(command.clientPermissions);
if (missing?.length) {

@@ -1070,3 +1047,3 @@ this.emit(event, message, command, "client", missing);

let missing = command.userPermissions(message);
if ((0, Util_js_1.isPromise)(missing))
if (Util_js_1.Util.isPromise(missing))
missing = await missing;

@@ -1078,4 +1055,4 @@ if (missing != null) {

}
else if (message.inGuild()) {
if (!message.channel || message.channel.isDMBased())
else if (message.guild) {
if (message.channel?.type === "DM")
return false;

@@ -1170,4 +1147,4 @@ const missing = message.channel?.permissionsFor(message.author)?.missing(command.userPermissions);

async parseCommand(message) {
const allowMention = await (0, Util_js_1.intoCallable)(this.prefix)(message);
let prefixes = (0, Util_js_1.intoArray)(allowMention);
const allowMention = await Util_js_1.Util.intoCallable(this.prefix)(message);
let prefixes = Util_js_1.Util.intoArray(allowMention);
if (allowMention) {

@@ -1177,3 +1154,3 @@ const mentions = [`<@${this.client.user?.id}>`, `<@!${this.client.user?.id}>`];

}
prefixes.sort(Util_js_1.prefixCompare);
prefixes.sort(Util_js_1.Util.prefixCompare);
return this.parseMultiplePrefixes(message, prefixes.map(p => [p, null]));

@@ -1190,7 +1167,7 @@ }

const promises = this.prefixes.map(async (cmds, provider) => {
const prefixes = (0, Util_js_1.intoArray)(await (0, Util_js_1.intoCallable)(provider)(message));
const prefixes = Util_js_1.Util.intoArray(await Util_js_1.Util.intoCallable(provider)(message));
return prefixes.map(p => [p, cmds]);
});
const pairs = (await Promise.all(promises)).flatMap(x => x, 1);
pairs.sort(([a], [b]) => (0, Util_js_1.prefixCompare)(a, b));
pairs.sort(([a], [b]) => Util_js_1.Util.prefixCompare(a, b));
return this.parseMultiplePrefixes(message, pairs);

@@ -1354,6 +1331,2 @@ }

class RegisterInteractionCommandError extends Error {
original;
type;
data;
guild;
constructor(original, type, data, guild = null) {

@@ -1369,17 +1342,13 @@ super("Failed to register interaction commands.");

const slashResolvable = [
"Attachment",
"Boolean",
"Channel",
"String",
"Integer",
"Number",
"User",
"Member",
"Role",
"Mentionable",
"Number",
"Role",
"String",
"User"
"Attachment"
];
/**
* @typedef {CommandInteractionOptionResolver} VSCodePleaseStopRemovingMyImports
* @internal
*/
//# sourceMappingURL=CommandHandler.js.map

@@ -1,5 +0,6 @@

import { Collection, MessagePayload, type InteractionReplyOptions, type Message, type MessageEditOptions, type MessageOptions, type ReplyMessageOptions, type Snowflake, type WebhookEditMessageOptions } from "discord.js";
import { APIMessage } from "discord-api-types/v9";
import { Collection, InteractionReplyOptions, Message, MessageEditOptions, MessageOptions, MessagePayload, ReplyMessageOptions, Snowflake, WebhookEditMessageOptions } from "discord.js";
import { AkairoMessage } from "../../util/AkairoMessage.js";
import type { ContextMenuCommandHandler } from "../contextMenuCommands/ContextMenuCommandHandler.js";
import { CommandHandler, type ParsedComponentData } from "./CommandHandler.js";
import { CommandHandler, ParsedComponentData } from "./CommandHandler.js";
/**

@@ -67,3 +68,3 @@ * Command utilities.

edit(options: string | MessageEditOptions | MessagePayload): Promise<Message>;
edit(options: string | WebhookEditMessageOptions | MessagePayload): Promise<Message>;
edit(options: string | WebhookEditMessageOptions | MessagePayload): Promise<Message | APIMessage>;
/**

@@ -75,3 +76,3 @@ * Send an inline reply or respond to a slash command.

reply(options: string | MessagePayload | ReplyMessageOptions): Promise<Message>;
reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage>;
/**

@@ -82,3 +83,3 @@ * Sends a response or edits an old response if available.

send(options: string | MessagePayload | MessageOptions): Promise<Message>;
send(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
send(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage>;
/**

@@ -89,3 +90,3 @@ * Sends a response, overwriting the last response.

sendNew(options: string | MessagePayload | MessageOptions): Promise<Message>;
sendNew(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
sendNew(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage>;
/**

@@ -92,0 +93,0 @@ * Changes if the message should be edited.

@@ -12,12 +12,2 @@ "use strict";

/**
* Saved deleted message ids.
*/
static deletedMessages = new Set();
/**
* Whether or not `this.message` has been deleted.
*/
get deleted() {
return this.isSlash ? false : CommandUtil.deletedMessages.has(this.message.id);
}
/**
* @param handler - The command handler.

@@ -36,2 +26,8 @@ * @param message - Message that triggered the command.

/**
* Whether or not `this.message` has been deleted.
*/
get deleted() {
return this.isSlash ? false : CommandUtil.deletedMessages.has(this.message.id);
}
/**
* Whether or not the provided message is a slash message

@@ -58,6 +54,6 @@ * @param message - The message to test

if (!this.isSlashMessage(this.message)) {
return await this.lastResponse.edit(options);
return this.lastResponse.edit(options);
}
else {
return await this.message.interaction.editReply(options);
return this.message.interaction.editReply(options);
}

@@ -73,3 +69,3 @@ }

}
return await this.send(newOptions);
return this.send(newOptions);
}

@@ -85,3 +81,3 @@ async send(options) {

!this.lastResponse.attachments.size) {
return await this.lastResponse.edit(newOptions);
return this.lastResponse.edit(newOptions);
}

@@ -145,6 +141,6 @@ const sent = await this.message.channel?.send(newOptions);

if (this.isSlashMessage(this.message)) {
return await this.message.interaction.deleteReply();
return this.message.interaction.deleteReply();
}
else {
return await this.lastResponse?.delete();
return this.lastResponse?.delete();
}

@@ -154,2 +150,6 @@ }

exports.CommandUtil = CommandUtil;
/**
* Saved deleted message ids.
*/
CommandUtil.deletedMessages = new Set();
//# sourceMappingURL=CommandUtil.js.map

@@ -206,9 +206,2 @@ "use strict";

class Parser {
/**
* Phrases are `{ type: 'Phrase', value, raw }`.
* Flags are `{ type: 'Flag', key, raw }`.
* Option flags are `{ type: 'OptionFlag', key, value, raw }`.
* The `all` property is partitioned into `phrases`, `flags`, and `optionFlags`.
*/
results;
constructor(tokens, options) {

@@ -370,5 +363,5 @@ const { separated } = options;

const { flagWords = [], optionFlagWords = [], quoted = true, separator } = options;
if (!(0, Util_js_1.isArrayOf)(flagWords, "string"))
if (!Util_js_1.Util.isArrayOf(flagWords, "string"))
throw new TypeError("options.flagWords must be an array of strings.");
if (!(0, Util_js_1.isArrayOf)(optionFlagWords, "string"))
if (!Util_js_1.Util.isArrayOf(optionFlagWords, "string"))
throw new TypeError("options.optionFlagWords must be an array of strings.");

@@ -375,0 +368,0 @@ if (typeof quoted !== "boolean")

@@ -11,8 +11,2 @@ import type { Message } from "discord.js";

/**
* Order waiting time .
*
* Only exists if {@link type} is {@link FlagType.Timeout}.
*/
time: T extends FlagType.Timeout ? number : never;
/**
* Message to handle.

@@ -55,3 +49,2 @@ *

private constructor();
private constructor();
/**

@@ -62,6 +55,2 @@ * Creates a flag that cancels the command.

/**
* Create a flag that cancels the command because of the timeout
*/
static timeout(time: number): Flag<FlagType.Timeout>;
/**
* Creates a flag that retries with another input.

@@ -88,7 +77,9 @@ * @param message - Message to handle.

*/
static is<Type extends FlagType>(value: unknown, type: Type): value is Flag<typeof type>;
static is(value: unknown, type: FlagType.Cancel): value is Flag<FlagType.Cancel>;
static is(value: unknown, type: FlagType.Continue): value is Flag<FlagType.Continue>;
static is(value: unknown, type: FlagType.Fail): value is Flag<FlagType.Fail>;
static is(value: unknown, type: FlagType.Retry): value is Flag<FlagType.Retry>;
}
export declare enum FlagType {
Cancel = "cancel",
Timeout = "timeout",
Retry = "retry",

@@ -95,0 +86,0 @@ Fail = "fail",

@@ -19,8 +19,2 @@ "use strict";

/**
* Create a flag that cancels the command because of the timeout
*/
static timeout(time) {
return new Flag(FlagType.Timeout, { time });
}
/**
* Creates a flag that retries with another input.

@@ -48,7 +42,2 @@ * @param message - Message to handle.

}
/**
* Checks if a value is a flag and of some type.
* @param value - Value to check.
* @param type - Type of flag.
*/
static is(value, type) {

@@ -62,3 +51,2 @@ return value instanceof Flag && value.type === type;

FlagType["Cancel"] = "cancel";
FlagType["Timeout"] = "timeout";
FlagType["Retry"] = "retry";

@@ -65,0 +53,0 @@ FlagType["Fail"] = "fail";

@@ -1,3 +0,5 @@

import { ApplicationCommandType, type ContextMenuCommandInteraction, type LocalizationMap, type PermissionResolvable, type Snowflake } from "discord.js";
import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
import { type ContextMenuInteraction, type Snowflake } from "discord.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import type { ContextMenuCommandHandler } from "./ContextMenuCommandHandler.js";

@@ -7,3 +9,3 @@ /**

*/
export declare abstract class ContextMenuCommand extends AkairoModule<ContextMenuCommandHandler, ContextMenuCommand> {
export declare abstract class ContextMenuCommand extends AkairoModule {
/**

@@ -28,18 +30,20 @@ * Assign context menu commands to Specific guilds. This option will make the commands not register globally, but only in the chosen servers.

*/
type: ApplicationCommandType.User | ApplicationCommandType.Message;
type: "USER" | "MESSAGE";
/**
* Name localization.
* The category of this context menu command.
*/
nameLocalizations?: LocalizationMap;
category: Category<string, ContextMenuCommand>;
/**
* The default bitfield used to determine whether this command be used in a guild
* The Akairo client.
*/
defaultMemberPermissions?: PermissionResolvable;
client: AkairoClient;
/**
* Whether the command is enabled in DMs
*
* **Cannot be enabled for command that specify `guilds`**
* The filepath.
*/
dmPermission?: boolean;
filepath: string;
/**
* The handler.
*/
handler: ContextMenuCommandHandler;
/**
* @param id - Listener ID.

@@ -53,4 +57,14 @@ * @param options - Options for the context menu command.

*/
abstract exec(interaction: ContextMenuCommandInteraction): any;
exec(interaction: ContextMenuInteraction): any;
}
export interface ContextMenuCommand extends AkairoModule {
/**
* Reloads the context menu command.
*/
reload(): Promise<ContextMenuCommand>;
/**
* Removes the context menu command.
*/
remove(): ContextMenuCommand;
}
/**

@@ -62,3 +76,2 @@ * Options to use for context menu command execution behavior.

* Assign context menu commands to Specific guilds. This option will make the commands not register globally, but only in the chosen servers.
* @default []
*/

@@ -81,18 +94,4 @@ guilds?: Snowflake[];

*/
type: ApplicationCommandType.User | ApplicationCommandType.Message;
/**
* Name localization.
*/
nameLocalizations?: LocalizationMap;
/**
* The default bitfield used to determine whether this command be used in a guild
*/
slashDefaultMemberPermissions?: PermissionResolvable;
/**
* Whether the command is enabled in DMs
*
* **Cannot be enabled for commands that specify `guilds`**
*/
slashDmPermission?: boolean;
type: "USER" | "MESSAGE";
}
//# sourceMappingURL=ContextMenuCommand.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextMenuCommand = void 0;
/* eslint-disable @typescript-eslint/no-unused-vars */
const discord_js_1 = require("discord.js");
const AkairoError_js_1 = require("../../util/AkairoError.js");
const Util_js_1 = require("../../util/Util.js");

@@ -17,6 +16,6 @@ const AkairoModule_js_1 = require("../AkairoModule.js");

constructor(id, options) {
const { category, guilds = [], name, ownerOnly, superUserOnly, type, nameLocalizations, slashDefaultMemberPermissions, slashDmPermission } = options;
const { category, guilds, name, ownerOnly, superUserOnly, type } = options;
if (category !== undefined && typeof category !== "string")
throw new TypeError("options.category must be a string.");
if (guilds !== undefined && !(0, Util_js_1.isArrayOf)(guilds, "string"))
if (guilds !== undefined && !Util_js_1.Util.isArrayOf(guilds, "string"))
throw new TypeError("options.guilds must be an array of strings.");

@@ -27,10 +26,4 @@ if (name !== undefined && typeof name !== "string")

throw new TypeError("options.ownerOnly must be a boolean");
if (type !== discord_js_1.ApplicationCommandType.User && type !== discord_js_1.ApplicationCommandType.Message)
throw new TypeError("options.type must be either ApplicationCommandType.User or ApplicationCommandType.Message.");
if (nameLocalizations !== undefined && typeof nameLocalizations !== "object")
throw new TypeError("options.nameLocalizations must be a object.");
if (slashDmPermission != null && typeof slashDmPermission !== "boolean")
throw new TypeError("options.slashDmPermission must be a boolean.");
if (slashDmPermission != null && guilds.length > 0)
throw new TypeError("You cannot set `options.slashDmPermission` with commands configured with `options.slashGuilds`.");
if (type !== "USER" && type !== "MESSAGE")
throw new TypeError("options.type must be either 'USER' or 'MESSAGE'.");
super(id, { category });

@@ -42,9 +35,12 @@ this.guilds = guilds;

this.type = type;
this.nameLocalizations = nameLocalizations;
this.defaultMemberPermissions = slashDefaultMemberPermissions;
this.dmPermission = slashDmPermission;
}
/**
* Executes the context menu command.
* @param interaction - The context menu command interaction.
*/
exec(interaction) {
throw new AkairoError_js_1.AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
exports.ContextMenuCommand = ContextMenuCommand;
(0, Util_js_1.patchAbstract)(ContextMenuCommand, "exec");
//# sourceMappingURL=ContextMenuCommand.js.map

@@ -1,5 +0,7 @@

import type { Awaitable, ContextMenuCommandInteraction } from "discord.js";
import type { ContextMenuCommandHandlerEvents } from "../../typings/events.js";
import type { Awaitable, Collection, ContextMenuInteraction } from "discord.js";
import type { ContextMenuCommandHandlerEvents } from "../../typings/events";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import type { AkairoModule } from "../AkairoModule.js";
import type { InhibitorHandler } from "../inhibitors/InhibitorHandler.js";

@@ -10,4 +12,20 @@ import { ContextMenuCommand } from "./ContextMenuCommand.js";

*/
export declare class ContextMenuCommandHandler extends AkairoHandler<ContextMenuCommand, ContextMenuCommandHandler> {
export declare class ContextMenuCommandHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
categories: Collection<string, Category<string, ContextMenuCommand>>;
/**
* Class to handle.
*/
classToHandle: typeof ContextMenuCommand;
/**
* The Akairo client.
*/
client: AkairoClient;
/**
* Directory to context menu commands.
*/
directory: string;
/**
* Inhibitor handler to use.

@@ -17,6 +35,10 @@ */

/**
* Context menu commands loaded, mapped by ID to context menu command.
*/
modules: Collection<string, ContextMenuCommand>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
constructor(client: AkairoClient, options: ContextMenuCommandHandlerOptions);
constructor(client: AkairoClient, options: AkairoHandlerOptions);
/**

@@ -30,3 +52,3 @@ * Set up the context menu command handler

*/
handle(interaction: ContextMenuCommandInteraction): Promise<boolean | null>;
handle(interaction: ContextMenuInteraction): Promise<boolean | null>;
/**

@@ -38,11 +60,55 @@ * Handles errors from the handling.

*/
emitError(err: Error, interaction: ContextMenuCommandInteraction, command: ContextMenuCommand): void;
emitError(err: Error, interaction: ContextMenuInteraction, command: ContextMenuCommand | AkairoModule): void;
}
declare type Events = ContextMenuCommandHandlerEvents;
export interface ContextMenuCommandHandler extends AkairoHandler<ContextMenuCommand, ContextMenuCommandHandler> {
export interface ContextMenuCommandHandler extends AkairoHandler {
/**
* Deregisters a module.
* @param contextMenuCommand - Module to use.
*/
deregister(contextMenuCommand: ContextMenuCommand): void;
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, ContextMenuCommand>;
/**
* Loads an context menu command.
* @param thing - Module or path to module.
*/
load(thing: string | ContextMenuCommand): Promise<ContextMenuCommand>;
/**
* Reads all context menu commands from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<ContextMenuCommandHandler>;
/**
* Registers a module.
* @param contextMenuCommand - Module to use.
* @param filepath - Filepath of module.
*/
register(contextMenuCommand: ContextMenuCommand, filepath?: string): void;
/**
* Reloads an context menu command.
* @param id - ID of the context menu command.
*/
reload(id: string): Promise<ContextMenuCommand>;
/**
* Reloads all context menu commands.
*/
reloadAll(): Promise<ContextMenuCommandHandler>;
/**
* Removes an context menu command.
* @param id - ID of the context menu command.
*/
remove(id: string): ContextMenuCommand;
/**
* Removes all context menu commands.
*/
removeAll(): ContextMenuCommandHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
}
export declare type ContextMenuCommandHandlerOptions = AkairoHandlerOptions<ContextMenuCommand, ContextMenuCommandHandler>;
export {};
//# sourceMappingURL=ContextMenuCommandHandler.d.ts.map

@@ -21,3 +21,9 @@ "use strict";

}
super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});
this.setup();

@@ -31,4 +37,5 @@ }

this.client.on("interactionCreate", i => {
if (i.isUserContextMenuCommand() || i.isMessageContextMenuCommand())
this.handle(i);
if (!i.isUserContextMenu())
return;
this.handle(i);
});

@@ -35,0 +42,0 @@ });

import type { Message } from "discord.js";
import type { AkairoMessage } from "../../util/AkairoMessage.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";

@@ -9,3 +11,3 @@ import type { Command } from "../commands/Command.js";

*/
export declare abstract class Inhibitor extends AkairoModule<InhibitorHandler, Inhibitor> {
export declare abstract class Inhibitor extends AkairoModule {
/**

@@ -16,2 +18,22 @@ * The priority of the inhibitor.

/**
* The category the inhibitor belongs to.
*/
category: Category<string, Inhibitor>;
/**
* The Akairo client.
*/
client: AkairoClient;
/**
* The filepath.
*/
filepath: string;
/**
* The inhibitor handler.
*/
handler: InhibitorHandler;
/**
* The ID of this inhibitor.
*/
id: string;
/**
* Reason emitted when command is inhibited.

@@ -36,7 +58,18 @@ */

*/
abstract exec(message: Message, command?: Command): boolean | Promise<boolean>;
abstract exec(message: Message | AkairoMessage, command?: Command): boolean | Promise<boolean>;
exec(message: Message, command?: Command): boolean | Promise<boolean>;
exec(message: Message | AkairoMessage, command?: Command): boolean | Promise<boolean>;
}
export interface Inhibitor extends AkairoModule {
/**
* Reloads the inhibitor.
*/
reload(): Promise<Inhibitor>;
/**
* Removes the inhibitor.
*/
remove(): Inhibitor;
}
/**
* Options to use for inhibitor execution behavior.
* Also includes properties from AkairoModuleOptions.
*/

@@ -43,0 +76,0 @@ export interface InhibitorOptions extends AkairoModuleOptions {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Inhibitor = void 0;
const Util_js_1 = require("../../util/Util.js");
const AkairoError_js_1 = require("../../util/AkairoError.js");
const AkairoModule_js_1 = require("../AkairoModule.js");

@@ -29,5 +29,7 @@ /**

}
exec(message, command) {
throw new AkairoError_js_1.AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
exports.Inhibitor = Inhibitor;
(0, Util_js_1.patchAbstract)(Inhibitor, "exec");
//# sourceMappingURL=Inhibitor.js.map

@@ -1,6 +0,7 @@

import type { Awaitable, Message } from "discord.js";
import type { InhibitorHandlerEvents } from "../../typings/events.js";
import type { Awaitable, Collection, Message } from "discord.js";
import type { InhibitorHandlerEvents } from "../../typings/events";
import type { AkairoMessage } from "../../util/AkairoMessage.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import type { Command } from "../commands/Command.js";

@@ -11,8 +12,28 @@ import { Inhibitor } from "./Inhibitor.js";

*/
export declare class InhibitorHandler extends AkairoHandler<Inhibitor, InhibitorHandler> {
export declare class InhibitorHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
categories: Collection<string, Category<string, Inhibitor>>;
/**
* Class to handle.
*/
classToHandle: typeof Inhibitor;
/**
* The Akairo client.
*/
client: AkairoClient;
/**
* Directory to inhibitors.
*/
directory: string;
/**
* Inhibitors loaded, mapped by ID to Inhibitor.
*/
modules: Collection<string, Inhibitor>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
constructor(client: AkairoClient, options: InhibitorHandlerOptions);
constructor(client: AkairoClient, options: AkairoHandlerOptions);
/**

@@ -28,8 +49,52 @@ * Tests inhibitors against the message.

declare type Events = InhibitorHandlerEvents;
export interface InhibitorHandler extends AkairoHandler<Inhibitor, InhibitorHandler> {
export interface InhibitorHandler extends AkairoHandler {
/**
* Deregisters an inhibitor.
* @param inhibitor - Inhibitor to use.
*/
deregister(inhibitor: Inhibitor): void;
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, Inhibitor>;
/**
* Loads an inhibitor.
* @param thing - Inhibitor or path to inhibitor.
*/
load(thing: string | Inhibitor): Promise<Inhibitor>;
/**
* Reads all inhibitors from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<InhibitorHandler>;
/**
* Registers an inhibitor.
* @param inhibitor - Inhibitor to use.
* @param filepath - Filepath of inhibitor.
*/
register(inhibitor: Inhibitor, filepath?: string): void;
/**
* Reloads an inhibitor.
* @param id - ID of the inhibitor.
*/
reload(id: string): Promise<Inhibitor>;
/**
* Reloads all inhibitors.
*/
reloadAll(): Promise<InhibitorHandler>;
/**
* Removes an inhibitor.
* @param id - ID of the inhibitor.
*/
remove(id: string): Inhibitor;
/**
* Removes all inhibitors.
*/
removeAll(): InhibitorHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
}
export declare type InhibitorHandlerOptions = AkairoHandlerOptions<Inhibitor, InhibitorHandler>;
export {};
//# sourceMappingURL=InhibitorHandler.d.ts.map

@@ -21,3 +21,9 @@ "use strict";

}
super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});
}

@@ -41,3 +47,3 @@ /**

let inhibited = inhibitor.exec(message, command);
if ((0, Util_js_1.isPromise)(inhibited))
if (Util_js_1.Util.isPromise(inhibited))
inhibited = await inhibited;

@@ -44,0 +50,0 @@ if (inhibited)

@@ -1,3 +0,6 @@

import EventEmitter from "node:events";
import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
/// <reference types="node" />
import EventEmitter from "events";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import type { ListenerHandler } from "./ListenerHandler.js";

@@ -7,4 +10,12 @@ /**

*/
export declare abstract class Listener extends AkairoModule<ListenerHandler, Listener> {
export declare abstract class Listener extends AkairoModule {
/**
* The category of this listener.
*/
category: Category<string, Listener>;
/**
* The Akairo client.
*/
client: AkairoClient;
/**
* The event emitter.

@@ -18,2 +29,10 @@ */

/**
* The filepath.
*/
filepath: string;
/**
* The handler.
*/
handler: ListenerHandler;
/**
* Type of listener.

@@ -31,4 +50,14 @@ */

*/
abstract exec(...args: any[]): any;
exec(...args: any[]): any;
}
export interface Listener extends AkairoModule {
/**
* Reloads the listener.
*/
reload(): Promise<Listener>;
/**
* Removes the listener.
*/
remove(): Listener;
}
/**

@@ -35,0 +64,0 @@ * Options to use for listener execution behavior.

@@ -8,4 +8,4 @@ "use strict";

/* eslint-disable func-names, @typescript-eslint/no-unused-vars */
const node_events_1 = __importDefault(require("node:events"));
const Util_js_1 = require("../../util/Util.js");
const events_1 = __importDefault(require("events"));
const AkairoError_js_1 = require("../../util/AkairoError.js");
const AkairoModule_js_1 = require("../AkairoModule.js");

@@ -22,3 +22,3 @@ /**

const { category, emitter, event, type = "on" } = options;
if (typeof emitter !== "string" && !(emitter instanceof node_events_1.default))
if (typeof emitter !== "string" && !(emitter instanceof events_1.default))
throw new TypeError("options.emitter must be a string or an EventEmitter.");

@@ -34,6 +34,12 @@ if (typeof event !== "string")

}
/**
* Executes the listener.
* @param args - Arguments.
*/
exec(...args) {
throw new AkairoError_js_1.AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
exports.Listener = Listener;
(0, Util_js_1.patchAbstract)(Listener, "exec");
const listenersTypes = ["on", "once", "prependListener", "prependOnceListener"];
//# sourceMappingURL=Listener.js.map

@@ -0,6 +1,8 @@

/// <reference types="node" />
import { Awaitable, Collection } from "discord.js";
import type EventEmitter from "node:events";
import type { ListenerHandlerEvents } from "../../typings/events.js";
import type EventEmitter from "events";
import type { ListenerHandlerEvents } from "../../typings/events";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import { Listener } from "./Listener.js";

@@ -10,4 +12,8 @@ /**

*/
export declare class ListenerHandler extends AkairoHandler<Listener, ListenerHandler> {
export declare class ListenerHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
categories: Collection<string, Category<string, Listener>>;
/**
* Class to handle.

@@ -17,2 +23,10 @@ */

/**
* The Akairo client
*/
client: AkairoClient;
/**
* Directory to listeners.
*/
directory: string;
/**
* EventEmitters for use, mapped by name to EventEmitter.

@@ -23,6 +37,10 @@ * By default, 'client' is set to the given client.

/**
* Listeners loaded, mapped by ID to Listener.
*/
modules: Collection<string, Listener>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
constructor(client: AkairoClient, options: ListenerHandlerOptions);
constructor(client: AkairoClient, options: AkairoHandlerOptions);
/**

@@ -56,8 +74,42 @@ * Adds a listener to the EventEmitter.

declare type Events = ListenerHandlerEvents;
export interface ListenerHandler extends AkairoHandler<Listener, ListenerHandler> {
export interface ListenerHandler extends AkairoHandler {
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, Listener>;
/**
* Loads a listener, can be a listener class or a filepath.
* @param thing - Listener class or path to listener.
* @param isReload - Whether this is a reload or not.
*/
load(thing: string | Listener, isReload?: boolean): Promise<Listener>;
/**
* Reads all listeners from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<ListenerHandler>;
/**
* Reloads a listener.
* @param id - ID of the listener.
*/
reload(id: string): Promise<Listener>;
/**
* Reloads all listeners.
*/
reloadAll(): Promise<ListenerHandler>;
/**
* Removes a listener.
* @param id - ID of the listener.
*/
remove(id: string): Listener;
/**
* Removes all listeners.
*/
removeAll(): ListenerHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
}
export declare type ListenerHandlerOptions = AkairoHandlerOptions<Listener, ListenerHandler>;
export {};
//# sourceMappingURL=ListenerHandler.d.ts.map

@@ -22,3 +22,9 @@ "use strict";

}
super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});
this.emitters = new discord_js_1.Collection();

@@ -35,4 +41,6 @@ this.emitters.set("client", this.client);

throw new AkairoError_js_1.AkairoError("MODULE_NOT_FOUND", this.classToHandle.name, id);
const emitter = (0, Util_js_1.isEventEmitter)(listener.emitter) ? listener.emitter : this.emitters.get(listener.emitter);
if (!(0, Util_js_1.isEventEmitter)(emitter))
const emitter = Util_js_1.Util.isEventEmitter(listener.emitter)
? listener.emitter
: this.emitters.get(listener.emitter);
if (!Util_js_1.Util.isEventEmitter(emitter))
throw new AkairoError_js_1.AkairoError("INVALID_TYPE", "emitter", "EventEmitter", true);

@@ -68,6 +76,6 @@ emitter[listener.type ?? "on"](listener.event, listener.exec);

throw new AkairoError_js_1.AkairoError("MODULE_NOT_FOUND", this.classToHandle.name, id);
const emitter = (0, Util_js_1.isEventEmitter)(listener.emitter)
const emitter = Util_js_1.Util.isEventEmitter(listener.emitter)
? listener.emitter
: this.emitters.get(listener.emitter);
if (!(0, Util_js_1.isEventEmitter)(emitter))
if (!Util_js_1.Util.isEventEmitter(emitter))
throw new AkairoError_js_1.AkairoError("INVALID_TYPE", "emitter", "EventEmitter", true);

@@ -83,3 +91,3 @@ emitter.removeListener(listener.event, listener.exec);

for (const [key, value] of Object.entries(emitters)) {
if (!(0, Util_js_1.isEventEmitter)(value))
if (!Util_js_1.Util.isEventEmitter(value))
throw new AkairoError_js_1.AkairoError("INVALID_TYPE", key, "EventEmitter", true);

@@ -86,0 +94,0 @@ this.emitters.set(key, value);

@@ -1,2 +0,4 @@

import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import type { TaskHandler } from "./TaskHandler.js";

@@ -6,4 +8,12 @@ /**

*/
export declare abstract class Task extends AkairoModule<TaskHandler, Task> {
export declare abstract class Task extends AkairoModule {
/**
* The category of this task.
*/
category: Category<string, Task>;
/**
* The Akairo client.
*/
client: AkairoClient;
/**
* The time in milliseconds between each time the task is run.

@@ -13,2 +23,10 @@ */

/**
* The filepath.
*/
filepath: string;
/**
* The handler.
*/
handler: TaskHandler;
/**
* Whether or not to run the task on start.

@@ -26,4 +44,18 @@ */

*/
abstract exec(...args: any[]): any;
exec(...args: any[]): any;
}
export interface Task extends AkairoModule {
/**
* Reloads the task.
*/
reload(): Promise<Task>;
/**
* Removes the task.
*/
remove(): Task;
/**
* Returns the ID.
*/
toString(): string;
}
/**

@@ -30,0 +62,0 @@ * Options to use for task execution behavior.

@@ -5,3 +5,3 @@ "use strict";

/* eslint-disable func-names, @typescript-eslint/no-unused-vars */
const Util_js_1 = require("../../util/Util.js");
const AkairoError_js_1 = require("../../util/AkairoError.js");
const AkairoModule_js_1 = require("../AkairoModule.js");

@@ -26,5 +26,11 @@ /**

}
/**
* Executes the task.
* @param args - Arguments.
*/
exec(...args) {
throw new AkairoError_js_1.AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
exports.Task = Task;
(0, Util_js_1.patchAbstract)(Task, "exec");
//# sourceMappingURL=Task.js.map

@@ -1,5 +0,6 @@

import type { Awaitable } from "discord.js";
import type { TaskHandlerEvents } from "../../typings/events.js";
import type { Awaitable, Collection } from "discord.js";
import type { TaskHandlerEvents } from "../../typings/events";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import { Task } from "./Task.js";

@@ -9,8 +10,28 @@ /**

*/
export declare class TaskHandler extends AkairoHandler<Task, TaskHandler> {
export declare class TaskHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
categories: Collection<string, Category<string, Task>>;
/**
* Class to handle.
*/
classToHandle: typeof Task;
/**
* The Akairo client
*/
client: AkairoClient;
/**
* Directory to tasks.
*/
directory: string;
/**
* Tasks loaded, mapped by ID to task.
*/
modules: Collection<string, Task>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
constructor(client: AkairoClient, options: AkairoHandlerOptions<Task, TaskHandler>);
constructor(client: AkairoClient, options: AkairoHandlerOptions);
/**

@@ -22,3 +43,48 @@ * Start all tasks.

declare type Events = TaskHandlerEvents;
export interface TaskHandler extends AkairoHandler<Task, TaskHandler> {
export interface TaskHandler extends AkairoHandler {
/**
* Deregisters a task.
* @param task - Task to use.
*/
deregister(task: Task): void;
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, Task>;
/**
* Loads a task.
* @param thing - Task or path to task.
*/
load(thing: string | Task, isReload?: boolean): Promise<Task>;
/**
* Reads all tasks from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<TaskHandler>;
/**
* Registers a task.
* @param task - Task to use.
* @param filepath - Filepath of task.
*/
register(task: Task, filepath?: string): void;
/**
* Reloads a task.
* @param id - ID of the task.
*/
reload(id: string): Promise<Task>;
/**
* Reloads all tasks.
*/
reloadAll(): Promise<TaskHandler>;
/**
* Removes a task.
* @param id - ID of the task.
*/
remove(id: string): Task;
/**
* Removes all tasks.
*/
removeAll(): TaskHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;

@@ -25,0 +91,0 @@ once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;

@@ -20,3 +20,9 @@ "use strict";

}
super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});
}

@@ -23,0 +29,0 @@ /**

@@ -1,17 +0,11 @@

import type { ChatInputCommandInteraction, ClientEvents, ContextMenuCommandInteraction, Message } from "discord.js";
import type { AkairoHandler } from "../struct/AkairoHandler.js";
import type { ClientEvents, CommandInteraction, ContextMenuInteraction, Message } from "discord.js";
import type { AkairoModule } from "../struct/AkairoModule.js";
import type { Command } from "../struct/commands/Command.js";
import type { CommandHandler } from "../struct/commands/CommandHandler.js";
import type { ContextMenuCommand } from "../struct/contextMenuCommands/ContextMenuCommand.js";
import type { ContextMenuCommandHandler } from "../struct/contextMenuCommands/ContextMenuCommandHandler.js";
import type { Inhibitor } from "../struct/inhibitors/Inhibitor.js";
import type { InhibitorHandler } from "../struct/inhibitors/InhibitorHandler.js";
import type { Listener } from "../struct/listeners/Listener.js";
import type { ListenerHandler } from "../struct/listeners/ListenerHandler.js";
import type { Task } from "../struct/tasks/Task.js";
import type { TaskHandler } from "../struct/tasks/TaskHandler.js";
import type { AkairoMessage } from "../util/AkairoMessage.js";
import type { BuiltInReasons } from "../util/Constants.js";
export interface AkairoHandlerEvents<Module extends AkairoModule<Handler, Module>, Handler extends AkairoHandler<Module, Handler>> {
export interface AkairoHandlerEvents {
/**

@@ -22,3 +16,3 @@ * Emitted when a module is loaded.

*/
load: [mod: Module, isReload: boolean];
load: [mod: AkairoModule, isReload: boolean];
/**

@@ -28,5 +22,5 @@ * Emitted when a module is removed.

*/
remove: [mod: Module];
remove: [mod: AkairoModule];
}
export interface CommandHandlerEvents extends AkairoHandlerEvents<Command, CommandHandler> {
export interface CommandHandlerEvents extends AkairoHandlerEvents {
/**

@@ -54,9 +48,2 @@ * Emitted when a command is blocked by a post-message inhibitor. The built-in inhibitors are `owner`, `superUser`, `guild`, and `dm`.

/**
* Emitted when a command is cancelled because of a timeout.
* @param message - Message sent.
* @param command - Command executed.
* @param time - Timeout in milliseconds.
*/
commandTimeout: [message: Message, command: Command, time: number];
/**
* Emitted when a command finishes execution.

@@ -109,2 +96,8 @@ * @param message - Message sent.

/**
* Emitted when a command is loaded.
* @param command - Module loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [command: Command, isReload: boolean];
/**
* Emitted when a message is blocked by a pre-message inhibitor. The built-in inhibitors are 'client' and 'bot'.

@@ -129,2 +122,7 @@ * @param message - Message sent.

/**
* Emitted when a command is removed.
* @param command - Command removed.
*/
remove: [command: Command];
/**
* Emitted when a slash command is blocked by a post-message inhibitor. The built-in inhibitors are `owner`, `superUser`, `guild`, and `dm`.

@@ -163,3 +161,3 @@ * @param message - The slash message.

*/
slashNotFound: [interaction: ChatInputCommandInteraction];
slashNotFound: [interaction: CommandInteraction];
/**

@@ -179,10 +177,54 @@ * Emitted when a slash command starts execution.

}
export interface InhibitorHandlerEvents extends AkairoHandlerEvents<Inhibitor, InhibitorHandler> {
export interface InhibitorHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when an inhibitor is removed.
* @param inhibitor - Inhibitor removed.
*/
remove: [inhibitor: Inhibitor];
/**
* Emitted when an inhibitor is loaded.
* @param inhibitor - Inhibitor loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [inhibitor: Inhibitor, isReload: boolean];
}
export interface ListenerHandlerEvents extends AkairoHandlerEvents<Listener, ListenerHandler> {
export interface ListenerHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when a listener is removed.
* @param listener - Listener removed.
*/
remove: [listener: Listener];
/**
* Emitted when a listener is loaded.
* @param listener - Listener loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [listener: Listener, isReload: boolean];
}
export interface TaskHandlerEvents extends AkairoHandlerEvents<Task, TaskHandler> {
export interface TaskHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when a task is removed.
* @param task - Task removed.
*/
remove: [task: Task];
/**
* Emitted when a task is loaded.
* @param task - Task loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [task: Task, isReload: boolean];
}
export interface ContextMenuCommandHandlerEvents extends AkairoHandlerEvents<ContextMenuCommand, ContextMenuCommandHandler> {
export interface ContextMenuCommandHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when a context menu command is removed.
* @param contextMenu - Context menu command removed.
*/
remove: [contextMenu: ContextMenuCommand];
/**
* Emitted when a context menu command is loaded.
* @param contextMenu - Context menu command loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [contextMenu: ContextMenuCommand, isReload: boolean];
/**
* Emitted when a context menu command errors.

@@ -193,3 +235,3 @@ * @param error - The error.

*/
error: [error: Error, interaction: ContextMenuCommandInteraction, command: ContextMenuCommand];
error: [error: Error, interaction: ContextMenuInteraction, command: ContextMenuCommand];
/**

@@ -201,3 +243,3 @@ * Emitted when a context menu command finishes execution.

*/
finished: [interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, returnValue: any];
finished: [interaction: ContextMenuInteraction, command: ContextMenuCommand, returnValue: any];
/**

@@ -207,3 +249,3 @@ * Emitted when a an incoming interaction command cannot be matched with a command.

*/
notFound: [interaction: ContextMenuCommandInteraction];
notFound: [interaction: ContextMenuInteraction];
/**

@@ -215,3 +257,3 @@ * Emitted when a command starts execution.

*/
started: [interaction: ContextMenuCommandInteraction, command: ContextMenuCommand];
started: [interaction: ContextMenuInteraction, command: ContextMenuCommand];
/**

@@ -224,3 +266,3 @@ * Emitted when a command is blocked.

blocked: [
interaction: ContextMenuCommandInteraction,
interaction: ContextMenuInteraction,
command: Command,

@@ -227,0 +269,0 @@ reason: typeof BuiltInReasons.OWNER | typeof BuiltInReasons.SUPER_USER

@@ -1,2 +0,2 @@

import type { SlashOption } from "../struct/commands/Command.js";
import { SlashOption } from "../struct/commands/Command";
declare const Messages: {

@@ -3,0 +3,0 @@ FILE_NOT_FOUND: (filename: string) => string;

@@ -1,2 +0,3 @@

import { Base, type CacheType, type ChatInputCommandInteraction, type InteractionReplyOptions, type Message, type MessagePayload } from "discord.js";
import type { APIInteractionGuildMember, APIMessage } from "discord-api-types/v9";
import { Base, CommandInteraction, Guild, GuildMember, GuildTextBasedChannel, InteractionReplyOptions, Message, MessagePayload, Snowflake, TextBasedChannel, User } from "discord.js";
import type { AkairoClient } from "../struct/AkairoClient.js";

@@ -7,15 +8,15 @@ import type { CommandUtil } from "../struct/commands/CommandUtil.js";

*/
export declare class AkairoMessage<Cached extends CacheType = CacheType> extends Base {
export declare class AkairoMessage extends Base {
/**
* The author of the interaction.
*/
author: ChatInputCommandInteraction<Cached>["user"];
author: User;
/**
* The application's id
*/
applicationId: ChatInputCommandInteraction<Cached>["applicationId"];
applicationId: Snowflake;
/**
* The id of the channel this interaction was sent in
*/
channelId: ChatInputCommandInteraction<Cached>["channelId"];
channelId: Snowflake | null;
/**

@@ -28,15 +29,15 @@ * The command name and arguments represented as a string.

*/
createdTimestamp: ChatInputCommandInteraction<Cached>["createdTimestamp"];
createdTimestamp: number;
/**
* The id of the guild this interaction was sent in
*/
guildId: ChatInputCommandInteraction<Cached>["guildId"];
guildId: Snowflake | null;
/**
* The ID of the interaction.
*/
id: ChatInputCommandInteraction<Cached>["id"];
id: Snowflake;
/**
* The command interaction.
*/
interaction: ChatInputCommandInteraction<Cached>;
interaction: CommandInteraction;
/**

@@ -46,7 +47,7 @@ * Represents the author of the interaction as a guild member.

*/
member: ChatInputCommandInteraction<Cached>["member"];
member: GuildMember | APIInteractionGuildMember | null;
/**
* Whether or not this message is a partial
*/
partial: false;
readonly partial: false;
/**

@@ -60,7 +61,7 @@ * Utilities for command responding.

*/
constructor(client: AkairoClient, interaction: ChatInputCommandInteraction<Cached>);
constructor(client: AkairoClient, interaction: CommandInteraction);
/**
* The channel that the interaction was sent in.
*/
get channel(): ChatInputCommandInteraction<Cached>["channel"];
get channel(): TextBasedChannel | null;
/**

@@ -74,7 +75,7 @@ * The message contents with all mentions replaced by the equivalent text.

*/
get guild(): ChatInputCommandInteraction<Cached>["guild"];
get guild(): Guild | null;
/**
* The time the message was sent at
*/
get createdAt(): ChatInputCommandInteraction<Cached>["createdAt"];
get createdAt(): Date;
/**

@@ -87,3 +88,3 @@ * The url to jump to this message

*/
inGuild(): this is AkairoMessage<"cached">;
inGuild(): this is AkairoMessageInGuild & this;
/**

@@ -97,4 +98,8 @@ * Deletes the reply to the command.

*/
reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage>;
}
export interface AkairoMessageInGuild {
guild: Guild;
channel: GuildTextBasedChannel;
}
//# sourceMappingURL=AkairoMessage.d.ts.map

@@ -37,3 +37,3 @@ "use strict";

get cleanContent() {
return this.content != null ? (0, discord_js_1.cleanContent)(this.content, this.channel) : null;
return this.content != null ? discord_js_1.Util.cleanContent(this.content, this.channel) : null;
}

@@ -64,3 +64,3 @@ /**

inGuild() {
return this.interaction.inCachedGuild();
return Boolean(this.guildId && this.member);
}

@@ -67,0 +67,0 @@ /**

@@ -6,3 +6,3 @@ import { Collection } from "discord.js";

*/
export declare class Category<K extends string, V extends AkairoModule<any, any>> extends Collection<K, V> {
export declare class Category<K extends string, V extends AkairoModule> extends Collection<K, V> {
/**

@@ -9,0 +9,0 @@ * ID of the category.

@@ -1,118 +0,111 @@

export declare enum ArgumentMatches {
PHRASE = "phrase",
FLAG = "flag",
OPTION = "option",
REST = "rest",
SEPARATE = "separate",
TEXT = "text",
CONTENT = "content",
REST_CONTENT = "restContent",
NONE = "none"
}
export declare enum ArgumentTypes {
STRING = "string",
LOWERCASE = "lowercase",
UPPERCASE = "uppercase",
CHAR_CODES = "charCodes",
NUMBER = "number",
INTEGER = "integer",
BIGINT = "bigint",
EMOJINT = "emojint",
URL = "url",
DATE = "date",
COLOR = "color",
USER = "user",
USERS = "users",
MEMBER = "member",
MEMBERS = "members",
RELEVANT = "relevant",
RELEVANTS = "relevants",
CHANNEL = "channel",
CHANNELS = "channels",
TEXT_CHANNEL = "textChannel",
TEXT_CHANNELS = "textChannels",
VOICE_CHANNEL = "voiceChannel",
VOICE_CHANNELS = "voiceChannels",
CATEGORY_CHANNEL = "categoryChannel",
CATEGORY_CHANNELS = "categoryChannels",
NEWS_CHANNEL = "newsChannel",
NEWS_CHANNELS = "newsChannels",
STAGE_CHANNEL = "stageChannel",
STAGE_CHANNELS = "stageChannels",
THREAD_CHANNEL = "threadChannel",
THREAD_CHANNELS = "threadChannels",
DIRECTORY_CHANNEL = "directoryChannel",
DIRECTORY_CHANNELS = "directoryChannels",
FORUM_CHANNEL = "forumChannel",
FORUM_CHANNELS = "forumChannels",
TEXT_BASED_CHANNEL = "textBasedChannel",
TEXT_BASED_CHANNELS = "textBasedChannels",
VOICE_BASED_CHANNEL = "voiceBasedChannel",
VOICE_BASED_CHANNELS = "voiceBasedChannels",
ROLE = "role",
ROLES = "roles",
EMOJI = "emoji",
EMOJIS = "emojis",
GUILD = "guild",
GUILDS = "guilds",
MESSAGE = "message",
GUILD_MESSAGE = "guildMessage",
RELEVANT_MESSAGE = "relevantMessage",
INVITE = "invite",
USER_MENTION = "userMention",
MEMBER_MENTION = "memberMention",
CHANNEL_MENTION = "channelMention",
ROLE_MENTION = "roleMention",
EMOJI_MENTION = "emojiMention",
COMMAND_ALIAS = "commandAlias",
COMMAND = "command",
INHIBITOR = "inhibitor",
LISTENER = "listener",
TASK = "task",
CONTEXT_MENU_COMMAND = "contextMenuCommand"
}
export declare enum AkairoHandlerEvents {
LOAD = "load",
REMOVE = "remove"
}
export declare enum CommandHandlerEvents {
COMMAND_BLOCKED = "commandBlocked",
COMMAND_BREAKOUT = "commandBreakout",
COMMAND_CANCELLED = "commandCancelled",
COMMAND_TIMEOUT = "commandTimeout",
COMMAND_FINISHED = "commandFinished",
COMMAND_INVALID = "commandInvalid",
COMMAND_LOCKED = "commandLocked",
COMMAND_STARTED = "commandStarted",
COOLDOWN = "cooldown",
ERROR = "error",
IN_PROMPT = "inPrompt",
MESSAGE_BLOCKED = "messageBlocked",
MESSAGE_INVALID = "messageInvalid",
MISSING_PERMISSIONS = "missingPermissions",
SLASH_BLOCKED = "slashBlocked",
SLASH_ERROR = "slashError",
SLASH_FINISHED = "slashFinished",
SLASH_MISSING_PERMISSIONS = "slashMissingPermissions",
SLASH_NOT_FOUND = "slashNotFound",
SLASH_STARTED = "slashStarted",
SLASH_ONLY = "slashOnly"
}
export declare enum ContextCommandHandlerEvents {
ERROR = "error",
FINISHED = "finished",
NOT_FOUND = "notFound",
STARTED = "started",
BLOCKED = "blocked"
}
export declare enum BuiltInReasons {
CLIENT = "client",
BOT = "bot",
OWNER = "owner",
SUPER_USER = "superUser",
GUILD = "guild",
DM = "dm",
AUTHOR_NOT_FOUND = "authorNotFound",
NOT_NSFW = "notNsfw"
}
export declare const ArgumentMatches: Readonly<{
readonly PHRASE: "phrase";
readonly FLAG: "flag";
readonly OPTION: "option";
readonly REST: "rest";
readonly SEPARATE: "separate";
readonly TEXT: "text";
readonly CONTENT: "content";
readonly REST_CONTENT: "restContent";
readonly NONE: "none";
}>;
export declare const ArgumentTypes: Readonly<{
readonly STRING: "string";
readonly LOWERCASE: "lowercase";
readonly UPPERCASE: "uppercase";
readonly CHAR_CODES: "charCodes";
readonly NUMBER: "number";
readonly INTEGER: "integer";
readonly BIGINT: "bigint";
readonly EMOJINT: "emojint";
readonly URL: "url";
readonly DATE: "date";
readonly COLOR: "color";
readonly USER: "user";
readonly USERS: "users";
readonly MEMBER: "member";
readonly MEMBERS: "members";
readonly RELEVANT: "relevant";
readonly RELEVANTS: "relevants";
readonly CHANNEL: "channel";
readonly CHANNELS: "channels";
readonly TEXT_CHANNEL: "textChannel";
readonly TEXT_CHANNELS: "textChannels";
readonly VOICE_CHANNEL: "voiceChannel";
readonly VOICE_CHANNELS: "voiceChannels";
readonly CATEGORY_CHANNEL: "categoryChannel";
readonly CATEGORY_CHANNELS: "categoryChannels";
readonly NEWS_CHANNEL: "newsChannel";
readonly NEWS_CHANNELS: "newsChannels";
readonly STORE_CHANNEL: "storeChannel";
readonly STORE_CHANNELS: "storeChannels";
readonly STAGE_CHANNEL: "stageChannel";
readonly STAGE_CHANNELS: "stageChannels";
readonly THREAD_CHANNEL: "threadChannel";
readonly THREAD_CHANNELS: "threadChannels";
readonly ROLE: "role";
readonly ROLES: "roles";
readonly EMOJI: "emoji";
readonly EMOJIS: "emojis";
readonly GUILD: "guild";
readonly GUILDS: "guilds";
readonly MESSAGE: "message";
readonly GUILD_MESSAGE: "guildMessage";
readonly RELEVANT_MESSAGE: "relevantMessage";
readonly INVITE: "invite";
readonly USER_MENTION: "userMention";
readonly MEMBER_MENTION: "memberMention";
readonly CHANNEL_MENTION: "channelMention";
readonly ROLE_MENTION: "roleMention";
readonly EMOJI_MENTION: "emojiMention";
readonly COMMAND_ALIAS: "commandAlias";
readonly COMMAND: "command";
readonly INHIBITOR: "inhibitor";
readonly LISTENER: "listener";
readonly TASK: "task";
readonly CONTEXT_MENU_COMMAND: "contextMenuCommand";
}>;
export declare const AkairoHandlerEvents: Readonly<{
readonly LOAD: "load";
readonly REMOVE: "remove";
}>;
export declare const CommandHandlerEvents: Readonly<{
readonly COMMAND_BLOCKED: "commandBlocked";
readonly COMMAND_BREAKOUT: "commandBreakout";
readonly COMMAND_CANCELLED: "commandCancelled";
readonly COMMAND_FINISHED: "commandFinished";
readonly COMMAND_INVALID: "commandInvalid";
readonly COMMAND_LOCKED: "commandLocked";
readonly COMMAND_STARTED: "commandStarted";
readonly COOLDOWN: "cooldown";
readonly ERROR: "error";
readonly IN_PROMPT: "inPrompt";
readonly MESSAGE_BLOCKED: "messageBlocked";
readonly MESSAGE_INVALID: "messageInvalid";
readonly MISSING_PERMISSIONS: "missingPermissions";
readonly SLASH_BLOCKED: "slashBlocked";
readonly SLASH_ERROR: "slashError";
readonly SLASH_FINISHED: "slashFinished";
readonly SLASH_MISSING_PERMISSIONS: "slashMissingPermissions";
readonly SLASH_NOT_FOUND: "slashNotFound";
readonly SLASH_STARTED: "slashStarted";
readonly SLASH_ONLY: "slashOnly";
}>;
export declare const ContextCommandHandlerEvents: Readonly<{
readonly ERROR: "error";
readonly FINISHED: "finished";
readonly NOT_FOUND: "notFound";
readonly STARTED: "started";
readonly BLOCKED: "blocked";
}>;
export declare const BuiltInReasons: Readonly<{
readonly CLIENT: "client";
readonly BOT: "bot";
readonly OWNER: "owner";
readonly SUPER_USER: "superUser";
readonly GUILD: "guild";
readonly DM: "dm";
readonly AUTHOR_NOT_FOUND: "authorNotFound";
readonly NOT_NSFW: "notNsfw";
}>;
//# sourceMappingURL=Constants.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BuiltInReasons = exports.ContextCommandHandlerEvents = exports.CommandHandlerEvents = exports.AkairoHandlerEvents = exports.ArgumentTypes = exports.ArgumentMatches = void 0;
var ArgumentMatches;
(function (ArgumentMatches) {
ArgumentMatches["PHRASE"] = "phrase";
ArgumentMatches["FLAG"] = "flag";
ArgumentMatches["OPTION"] = "option";
ArgumentMatches["REST"] = "rest";
ArgumentMatches["SEPARATE"] = "separate";
ArgumentMatches["TEXT"] = "text";
ArgumentMatches["CONTENT"] = "content";
ArgumentMatches["REST_CONTENT"] = "restContent";
ArgumentMatches["NONE"] = "none";
})(ArgumentMatches = exports.ArgumentMatches || (exports.ArgumentMatches = {}));
var ArgumentTypes;
(function (ArgumentTypes) {
ArgumentTypes["STRING"] = "string";
ArgumentTypes["LOWERCASE"] = "lowercase";
ArgumentTypes["UPPERCASE"] = "uppercase";
ArgumentTypes["CHAR_CODES"] = "charCodes";
ArgumentTypes["NUMBER"] = "number";
ArgumentTypes["INTEGER"] = "integer";
ArgumentTypes["BIGINT"] = "bigint";
ArgumentTypes["EMOJINT"] = "emojint";
ArgumentTypes["URL"] = "url";
ArgumentTypes["DATE"] = "date";
ArgumentTypes["COLOR"] = "color";
ArgumentTypes["USER"] = "user";
ArgumentTypes["USERS"] = "users";
ArgumentTypes["MEMBER"] = "member";
ArgumentTypes["MEMBERS"] = "members";
ArgumentTypes["RELEVANT"] = "relevant";
ArgumentTypes["RELEVANTS"] = "relevants";
ArgumentTypes["CHANNEL"] = "channel";
ArgumentTypes["CHANNELS"] = "channels";
ArgumentTypes["TEXT_CHANNEL"] = "textChannel";
ArgumentTypes["TEXT_CHANNELS"] = "textChannels";
ArgumentTypes["VOICE_CHANNEL"] = "voiceChannel";
ArgumentTypes["VOICE_CHANNELS"] = "voiceChannels";
ArgumentTypes["CATEGORY_CHANNEL"] = "categoryChannel";
ArgumentTypes["CATEGORY_CHANNELS"] = "categoryChannels";
ArgumentTypes["NEWS_CHANNEL"] = "newsChannel";
ArgumentTypes["NEWS_CHANNELS"] = "newsChannels";
ArgumentTypes["STAGE_CHANNEL"] = "stageChannel";
ArgumentTypes["STAGE_CHANNELS"] = "stageChannels";
ArgumentTypes["THREAD_CHANNEL"] = "threadChannel";
ArgumentTypes["THREAD_CHANNELS"] = "threadChannels";
ArgumentTypes["DIRECTORY_CHANNEL"] = "directoryChannel";
ArgumentTypes["DIRECTORY_CHANNELS"] = "directoryChannels";
ArgumentTypes["FORUM_CHANNEL"] = "forumChannel";
ArgumentTypes["FORUM_CHANNELS"] = "forumChannels";
ArgumentTypes["TEXT_BASED_CHANNEL"] = "textBasedChannel";
ArgumentTypes["TEXT_BASED_CHANNELS"] = "textBasedChannels";
ArgumentTypes["VOICE_BASED_CHANNEL"] = "voiceBasedChannel";
ArgumentTypes["VOICE_BASED_CHANNELS"] = "voiceBasedChannels";
ArgumentTypes["ROLE"] = "role";
ArgumentTypes["ROLES"] = "roles";
ArgumentTypes["EMOJI"] = "emoji";
ArgumentTypes["EMOJIS"] = "emojis";
ArgumentTypes["GUILD"] = "guild";
ArgumentTypes["GUILDS"] = "guilds";
ArgumentTypes["MESSAGE"] = "message";
ArgumentTypes["GUILD_MESSAGE"] = "guildMessage";
ArgumentTypes["RELEVANT_MESSAGE"] = "relevantMessage";
ArgumentTypes["INVITE"] = "invite";
ArgumentTypes["USER_MENTION"] = "userMention";
ArgumentTypes["MEMBER_MENTION"] = "memberMention";
ArgumentTypes["CHANNEL_MENTION"] = "channelMention";
ArgumentTypes["ROLE_MENTION"] = "roleMention";
ArgumentTypes["EMOJI_MENTION"] = "emojiMention";
ArgumentTypes["COMMAND_ALIAS"] = "commandAlias";
ArgumentTypes["COMMAND"] = "command";
ArgumentTypes["INHIBITOR"] = "inhibitor";
ArgumentTypes["LISTENER"] = "listener";
ArgumentTypes["TASK"] = "task";
ArgumentTypes["CONTEXT_MENU_COMMAND"] = "contextMenuCommand";
})(ArgumentTypes = exports.ArgumentTypes || (exports.ArgumentTypes = {}));
var AkairoHandlerEvents;
(function (AkairoHandlerEvents) {
AkairoHandlerEvents["LOAD"] = "load";
AkairoHandlerEvents["REMOVE"] = "remove";
})(AkairoHandlerEvents = exports.AkairoHandlerEvents || (exports.AkairoHandlerEvents = {}));
var CommandHandlerEvents;
(function (CommandHandlerEvents) {
CommandHandlerEvents["COMMAND_BLOCKED"] = "commandBlocked";
CommandHandlerEvents["COMMAND_BREAKOUT"] = "commandBreakout";
CommandHandlerEvents["COMMAND_CANCELLED"] = "commandCancelled";
CommandHandlerEvents["COMMAND_TIMEOUT"] = "commandTimeout";
CommandHandlerEvents["COMMAND_FINISHED"] = "commandFinished";
CommandHandlerEvents["COMMAND_INVALID"] = "commandInvalid";
CommandHandlerEvents["COMMAND_LOCKED"] = "commandLocked";
CommandHandlerEvents["COMMAND_STARTED"] = "commandStarted";
CommandHandlerEvents["COOLDOWN"] = "cooldown";
CommandHandlerEvents["ERROR"] = "error";
CommandHandlerEvents["IN_PROMPT"] = "inPrompt";
CommandHandlerEvents["MESSAGE_BLOCKED"] = "messageBlocked";
CommandHandlerEvents["MESSAGE_INVALID"] = "messageInvalid";
CommandHandlerEvents["MISSING_PERMISSIONS"] = "missingPermissions";
CommandHandlerEvents["SLASH_BLOCKED"] = "slashBlocked";
CommandHandlerEvents["SLASH_ERROR"] = "slashError";
CommandHandlerEvents["SLASH_FINISHED"] = "slashFinished";
CommandHandlerEvents["SLASH_MISSING_PERMISSIONS"] = "slashMissingPermissions";
CommandHandlerEvents["SLASH_NOT_FOUND"] = "slashNotFound";
CommandHandlerEvents["SLASH_STARTED"] = "slashStarted";
CommandHandlerEvents["SLASH_ONLY"] = "slashOnly";
})(CommandHandlerEvents = exports.CommandHandlerEvents || (exports.CommandHandlerEvents = {}));
var ContextCommandHandlerEvents;
(function (ContextCommandHandlerEvents) {
ContextCommandHandlerEvents["ERROR"] = "error";
ContextCommandHandlerEvents["FINISHED"] = "finished";
ContextCommandHandlerEvents["NOT_FOUND"] = "notFound";
ContextCommandHandlerEvents["STARTED"] = "started";
ContextCommandHandlerEvents["BLOCKED"] = "blocked";
})(ContextCommandHandlerEvents = exports.ContextCommandHandlerEvents || (exports.ContextCommandHandlerEvents = {}));
var BuiltInReasons;
(function (BuiltInReasons) {
BuiltInReasons["CLIENT"] = "client";
BuiltInReasons["BOT"] = "bot";
BuiltInReasons["OWNER"] = "owner";
BuiltInReasons["SUPER_USER"] = "superUser";
BuiltInReasons["GUILD"] = "guild";
BuiltInReasons["DM"] = "dm";
BuiltInReasons["AUTHOR_NOT_FOUND"] = "authorNotFound";
BuiltInReasons["NOT_NSFW"] = "notNsfw";
})(BuiltInReasons = exports.BuiltInReasons || (exports.BuiltInReasons = {}));
exports.ArgumentMatches = Object.freeze({
PHRASE: "phrase",
FLAG: "flag",
OPTION: "option",
REST: "rest",
SEPARATE: "separate",
TEXT: "text",
CONTENT: "content",
REST_CONTENT: "restContent",
NONE: "none"
});
exports.ArgumentTypes = Object.freeze({
STRING: "string",
LOWERCASE: "lowercase",
UPPERCASE: "uppercase",
CHAR_CODES: "charCodes",
NUMBER: "number",
INTEGER: "integer",
BIGINT: "bigint",
EMOJINT: "emojint",
URL: "url",
DATE: "date",
COLOR: "color",
USER: "user",
USERS: "users",
MEMBER: "member",
MEMBERS: "members",
RELEVANT: "relevant",
RELEVANTS: "relevants",
CHANNEL: "channel",
CHANNELS: "channels",
TEXT_CHANNEL: "textChannel",
TEXT_CHANNELS: "textChannels",
VOICE_CHANNEL: "voiceChannel",
VOICE_CHANNELS: "voiceChannels",
CATEGORY_CHANNEL: "categoryChannel",
CATEGORY_CHANNELS: "categoryChannels",
NEWS_CHANNEL: "newsChannel",
NEWS_CHANNELS: "newsChannels",
STORE_CHANNEL: "storeChannel",
STORE_CHANNELS: "storeChannels",
STAGE_CHANNEL: "stageChannel",
STAGE_CHANNELS: "stageChannels",
THREAD_CHANNEL: "threadChannel",
THREAD_CHANNELS: "threadChannels",
ROLE: "role",
ROLES: "roles",
EMOJI: "emoji",
EMOJIS: "emojis",
GUILD: "guild",
GUILDS: "guilds",
MESSAGE: "message",
GUILD_MESSAGE: "guildMessage",
RELEVANT_MESSAGE: "relevantMessage",
INVITE: "invite",
USER_MENTION: "userMention",
MEMBER_MENTION: "memberMention",
CHANNEL_MENTION: "channelMention",
ROLE_MENTION: "roleMention",
EMOJI_MENTION: "emojiMention",
COMMAND_ALIAS: "commandAlias",
COMMAND: "command",
INHIBITOR: "inhibitor",
LISTENER: "listener",
TASK: "task",
CONTEXT_MENU_COMMAND: "contextMenuCommand"
});
exports.AkairoHandlerEvents = Object.freeze({
LOAD: "load",
REMOVE: "remove"
});
exports.CommandHandlerEvents = Object.freeze({
COMMAND_BLOCKED: "commandBlocked",
COMMAND_BREAKOUT: "commandBreakout",
COMMAND_CANCELLED: "commandCancelled",
COMMAND_FINISHED: "commandFinished",
COMMAND_INVALID: "commandInvalid",
COMMAND_LOCKED: "commandLocked",
COMMAND_STARTED: "commandStarted",
COOLDOWN: "cooldown",
ERROR: "error",
IN_PROMPT: "inPrompt",
MESSAGE_BLOCKED: "messageBlocked",
MESSAGE_INVALID: "messageInvalid",
MISSING_PERMISSIONS: "missingPermissions",
SLASH_BLOCKED: "slashBlocked",
SLASH_ERROR: "slashError",
SLASH_FINISHED: "slashFinished",
SLASH_MISSING_PERMISSIONS: "slashMissingPermissions",
SLASH_NOT_FOUND: "slashNotFound",
SLASH_STARTED: "slashStarted",
SLASH_ONLY: "slashOnly"
});
exports.ContextCommandHandlerEvents = Object.freeze({
ERROR: "error",
FINISHED: "finished",
NOT_FOUND: "notFound",
STARTED: "started",
BLOCKED: "blocked"
});
exports.BuiltInReasons = Object.freeze({
CLIENT: "client",
BOT: "bot",
OWNER: "owner",
SUPER_USER: "superUser",
GUILD: "guild",
DM: "dm",
AUTHOR_NOT_FOUND: "authorNotFound",
NOT_NSFW: "notNsfw"
});
//# sourceMappingURL=Constants.js.map

@@ -1,50 +0,75 @@

import EventEmitter from "node:events";
import type { PrefixSupplier } from "../struct/commands/CommandHandler.js";
/// <reference types="node" />
import EventEmitter from "events";
import type { PrefixSupplier } from "../struct/commands/CommandHandler";
/**
* Deep assign properties to an object.
* @param target The object to assign values to.
* @param os The objects to assign from.
* Akairo Utilities.
*/
export declare function deepAssign<A, B>(target: A, ...os: B[]): A;
export declare class Util {
/**
* Deep assign properties to an object.
* @param target The object to assign values to.
* @param os The objects to assign from.
*/
static deepAssign<A, B>(target: A, ...os: B[]): A;
/**
* Converts the supplied value into an array if it is not already one.
* @param x - Value to convert.
*/
static intoArray<T>(x: T | T[]): T[];
/**
* Converts something to become callable.
* @param thing - What to turn into a callable.
* @returns - The callable.
*/
static intoCallable<T>(thing: T | ((...args: any[]) => T)): (...args: any[]) => T;
/**
* Checks if the supplied value is an event emitter.
* @param value - Value to check.
* @returns - Whether the value is an event emitter.
*/
static isEventEmitter(value: unknown): value is EventEmitter;
/**
* Checks if the supplied value is a promise.
* @param value - Value to check.
* @returns - Whether the value is a promise.
*/
static isPromise<T>(value: T | Promise<T>): value is Promise<T>;
/**
* Compares two prefixes.
* @param aKey - First prefix.
* @param bKey - Second prefix.
* @returns - Comparison result.
*/
static prefixCompare(aKey: string | PrefixSupplier, bKey: string | PrefixSupplier): number;
/**
* Compares each property of two objects to determine if they are equal.
* @param a - First value.
* @param b - Second value.
* @param ignoreUndefined - Whether to ignore undefined properties.
* @returns Whether the two values are equal.
*/
static deepEquals<T>(a: unknown, b: T, options?: DeepEqualsOptions): a is T;
/**
* Converts a string in snake_case to camelCase.
* @param str The string to convert.
*/
static snakeToCamelCase(str: string): string;
/**
* Converts a string in PascalCase to camelCase.
* @param str The string to convert.
*/
static pascalToCamelCase(str: string): string;
/**
* Checks if `array` is an array and its elements are typeof of `type`
* @param array The array to check.
* @param type The type to check the elements' type against.
* @returns Whether the array is an array and its elements are typeof of `type`.
*/
static isArrayOf<T>(array: T[], type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"): boolean;
}
/**
* Converts the supplied value into an array if it is not already one.
* @param x - Value to convert.
* Checks if a value is a string, an array of strings, or a function
* @internal
*/
export declare function intoArray<T>(x: T | T[]): T[];
/**
* Converts something to become callable.
* @param thing - What to turn into a callable.
* @returns - The callable.
*/
export declare function intoCallable<T>(thing: T | ((...args: any[]) => T)): (...args: any[]) => T;
/**
* Checks if the supplied value is an event emitter.
* @param value - Value to check.
* @returns - Whether the value is an event emitter.
*/
export declare function isEventEmitter(value: unknown): value is EventEmitter;
/**
* Checks if the supplied value is a promise.
* @param value - Value to check.
* @returns - Whether the value is a promise.
*/
export declare function isPromise<T>(value: T | Promise<T>): value is Promise<T>;
/**
* Compares two prefixes.
* @param aKey - First prefix.
* @param bKey - Second prefix.
* @returns - Comparison result.
*/
export declare function prefixCompare(aKey: string | PrefixSupplier, bKey: string | PrefixSupplier): number;
/**
* Compares each property of two objects to determine if they are equal.
* @param a - First value.
* @param b - Second value.
* @param options - Additional options.
* @returns Whether the two values are equal.
*/
export declare function deepEquals<T>(a: unknown, b: T, options?: DeepEqualsOptions): a is T;
/**
* Options for {@link deepEquals}.
*/
export declare function isStringArrayStringOrFunc(value: any): value is string | string[] | ((...args: any[]) => any);
export interface DeepEqualsOptions {

@@ -62,25 +87,2 @@ /**

}
/**
* Converts a string in snake_case to camelCase.
* @param str The string to convert.
*/
export declare function snakeToCamelCase(str: string): string;
/**
* Converts a string in PascalCase to camelCase.
* @param str The string to convert.
*/
export declare function pascalToCamelCase(str: string): string;
/**
* Checks if `array` is an array and its elements are typeof of `type`
* @param array The array to check.
* @param type The type to check the elements' type against.
* @returns Whether the array is an array and its elements are typeof of `type`.
*/
export declare function isArrayOf<T>(array: T[], type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"): boolean;
/**
* Defines an abstract method to a class to produce a runtime error.
* @param Class The class to patch.
* @param method The name of the method to patch.
*/
export declare function patchAbstract(Class: Function, method: string): void;
//# sourceMappingURL=Util.d.ts.map

@@ -6,166 +6,161 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.patchAbstract = exports.isStringArrayStringOrFunc = exports.isArrayOf = exports.pascalToCamelCase = exports.snakeToCamelCase = exports.deepEquals = exports.prefixCompare = exports.isPromise = exports.isEventEmitter = exports.intoCallable = exports.intoArray = exports.deepAssign = void 0;
const node_events_1 = __importDefault(require("node:events"));
const AkairoError_js_1 = require("./AkairoError.js");
exports.isStringArrayStringOrFunc = exports.Util = void 0;
const events_1 = __importDefault(require("events"));
/**
* Deep assign properties to an object.
* @param target The object to assign values to.
* @param os The objects to assign from.
* Akairo Utilities.
*/
function deepAssign(target, ...os) {
for (const o of os) {
for (const [key, value] of Object.entries(o)) {
const valueIsObject = value && typeof value === "object";
const targetKeyIsObject = Object.prototype.hasOwnProperty.call(target, key) &&
target[key] &&
typeof target[key] === "object";
if (valueIsObject && targetKeyIsObject) {
deepAssign(target[key], value);
class Util {
/**
* Deep assign properties to an object.
* @param target The object to assign values to.
* @param os The objects to assign from.
*/
static deepAssign(target, ...os) {
for (const o of os) {
for (const [key, value] of Object.entries(o)) {
const valueIsObject = value && typeof value === "object";
const targetKeyIsObject = Object.prototype.hasOwnProperty.call(target, key) &&
target[key] &&
typeof target[key] === "object";
if (valueIsObject && targetKeyIsObject) {
Util.deepAssign(target[key], value);
}
else {
target[key] = value;
}
}
else {
target[key] = value;
}
}
return target;
}
return target;
}
exports.deepAssign = deepAssign;
/**
* Converts the supplied value into an array if it is not already one.
* @param x - Value to convert.
*/
function intoArray(x) {
if (Array.isArray(x)) {
return x;
/**
* Converts the supplied value into an array if it is not already one.
* @param x - Value to convert.
*/
static intoArray(x) {
if (Array.isArray(x)) {
return x;
}
return [x];
}
return [x];
}
exports.intoArray = intoArray;
/**
* Converts something to become callable.
* @param thing - What to turn into a callable.
* @returns - The callable.
*/
function intoCallable(thing) {
if (typeof thing === "function") {
return thing;
/**
* Converts something to become callable.
* @param thing - What to turn into a callable.
* @returns - The callable.
*/
static intoCallable(thing) {
if (typeof thing === "function") {
return thing;
}
return () => thing;
}
return () => thing;
}
exports.intoCallable = intoCallable;
/**
* Checks if the supplied value is an event emitter.
* @param value - Value to check.
* @returns - Whether the value is an event emitter.
*/
function isEventEmitter(value) {
return value instanceof node_events_1.default;
}
exports.isEventEmitter = isEventEmitter;
/**
* Checks if the supplied value is a promise.
* @param value - Value to check.
* @returns - Whether the value is a promise.
*/
function isPromise(value) {
return value instanceof Promise;
}
exports.isPromise = isPromise;
/**
* Compares two prefixes.
* @param aKey - First prefix.
* @param bKey - Second prefix.
* @returns - Comparison result.
*/
function prefixCompare(aKey, bKey) {
if (aKey === "" && bKey === "")
return 0;
if (aKey === "")
return 1;
if (bKey === "")
return -1;
if (typeof aKey === "function" && typeof bKey === "function")
return 0;
if (typeof aKey === "function")
return 1;
if (typeof bKey === "function")
return -1;
return aKey.length === bKey.length ? aKey.localeCompare(bKey) : bKey.length - aKey.length;
}
exports.prefixCompare = prefixCompare;
// eslint-disable-next-line complexity
function deepEquals(a, b, options) {
const { ignoreUndefined = true, ignoreArrayOrder = true } = options ?? {};
if (a === b)
return true;
if (typeof a !== "object" || typeof b !== "object")
throw new TypeError("Not objects");
if ((Array.isArray(a) && !Array.isArray(b)) || (!Array.isArray(a) && Array.isArray(b)))
return false;
const newA = ignoreArrayOrder && Array.isArray(a) && a.length && typeof a[0] !== "object" ? [...a].sort() : a;
const newB = ignoreArrayOrder && Array.isArray(b) && b.length && typeof b[0] !== "object" ? [...b].sort() : b;
for (const key in newA) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined)
continue;
if (!(key in newB))
/**
* Checks if the supplied value is an event emitter.
* @param value - Value to check.
* @returns - Whether the value is an event emitter.
*/
static isEventEmitter(value) {
return value instanceof events_1.default;
}
/**
* Checks if the supplied value is a promise.
* @param value - Value to check.
* @returns - Whether the value is a promise.
*/
static isPromise(value) {
return value instanceof Promise;
}
/**
* Compares two prefixes.
* @param aKey - First prefix.
* @param bKey - Second prefix.
* @returns - Comparison result.
*/
static prefixCompare(aKey, bKey) {
if (aKey === "" && bKey === "")
return 0;
if (aKey === "")
return 1;
if (bKey === "")
return -1;
if (typeof aKey === "function" && typeof bKey === "function")
return 0;
if (typeof aKey === "function")
return 1;
if (typeof bKey === "function")
return -1;
return aKey.length === bKey.length ? aKey.localeCompare(bKey) : bKey.length - aKey.length;
}
// eslint-disable-next-line complexity
static deepEquals(a, b, options) {
const { ignoreUndefined = true, ignoreArrayOrder = true } = options ?? {};
if (a === b)
return true;
if (typeof a !== "object" || typeof b !== "object")
throw new TypeError("Not objects");
if ((Array.isArray(a) && !Array.isArray(b)) || (!Array.isArray(a) && Array.isArray(b)))
return false;
if (typeof newA[key] === "object" && typeof newB[key] === "object") {
if (!deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder }))
const newA = ignoreArrayOrder && Array.isArray(a) && a.length && typeof a[0] !== "object" ? [...a].sort() : a;
const newB = ignoreArrayOrder && Array.isArray(b) && b.length && typeof b[0] !== "object" ? [...b].sort() : b;
for (const key in newA) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined)
continue;
if (!(key in newB))
return false;
if (typeof newA[key] === "object" && typeof newB[key] === "object") {
if (!this.deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder }))
return false;
}
else if (newA[key] !== newB[key])
return false;
}
else if (newA[key] !== newB[key])
return false;
}
for (const key in newB) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined)
continue;
if (!(key in newA))
return false;
if (typeof newB[key] === "object" && typeof newA[key] === "object") {
if (!deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder }))
for (const key in newB) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined)
continue;
if (!(key in newA))
return false;
if (typeof newB[key] === "object" && typeof newA[key] === "object") {
if (!this.deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder }))
return false;
}
else if (newA[key] !== newB[key])
return false;
}
else if (newA[key] !== newB[key])
return true;
}
/**
* Converts a string in snake_case to camelCase.
* @param str The string to convert.
*/
static snakeToCamelCase(str) {
return str
.toLowerCase()
.split("_")
.map((word, index) => {
if (index !== 0)
return word.charAt(0).toUpperCase() + word.slice(1);
return word;
})
.join("");
}
/**
* Converts a string in PascalCase to camelCase.
* @param str The string to convert.
*/
static pascalToCamelCase(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
}
/**
* Checks if `array` is an array and its elements are typeof of `type`
* @param array The array to check.
* @param type The type to check the elements' type against.
* @returns Whether the array is an array and its elements are typeof of `type`.
*/
static isArrayOf(array, type) {
if (!Array.isArray(array))
return false;
return array.every(item => typeof item === type);
}
return true;
}
exports.deepEquals = deepEquals;
exports.Util = Util;
/**
* Converts a string in snake_case to camelCase.
* @param str The string to convert.
*/
function snakeToCamelCase(str) {
return str
.toLowerCase()
.split("_")
.map((word, index) => {
if (index !== 0)
return word.charAt(0).toUpperCase() + word.slice(1);
return word;
})
.join("");
}
exports.snakeToCamelCase = snakeToCamelCase;
/**
* Converts a string in PascalCase to camelCase.
* @param str The string to convert.
*/
function pascalToCamelCase(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
}
exports.pascalToCamelCase = pascalToCamelCase;
/**
* Checks if `array` is an array and its elements are typeof of `type`
* @param array The array to check.
* @param type The type to check the elements' type against.
* @returns Whether the array is an array and its elements are typeof of `type`.
*/
function isArrayOf(array, type) {
if (!Array.isArray(array))
return false;
return array.every(item => typeof item === type);
}
exports.isArrayOf = isArrayOf;
/**
* Checks if a value is a string, an array of strings, or a function

@@ -175,23 +170,5 @@ * @internal

function isStringArrayStringOrFunc(value) {
return typeof value === "string" || typeof value === "function" || isArrayOf(value, "string");
return typeof value === "string" || typeof value === "function" || Util.isArrayOf(value, "string");
}
exports.isStringArrayStringOrFunc = isStringArrayStringOrFunc;
/* eslint-disable @typescript-eslint/ban-types, func-names */
/**
* Defines an abstract method to a class to produce a runtime error.
* @param Class The class to patch.
* @param method The name of the method to patch.
*/
function patchAbstract(Class, method) {
Object.defineProperty(Class.prototype, method, {
configurable: true,
enumerable: false,
writable: true,
value: function () {
throw new AkairoError_js_1.AkairoError("NOT_IMPLEMENTED", this.constructor.name, method);
}
});
}
exports.patchAbstract = patchAbstract;
/* eslint-enable @typescript-eslint/ban-types, func-names */
//# sourceMappingURL=Util.js.map
{
"name": "@notenoughupdates/discord-akairo",
"version": "9.1.3-dev.1655521909.d87c26d",
"version": "9.1.3",
"description": "A highly customizable bot framework for Discord.js.",

@@ -40,19 +40,33 @@ "main": "./dist/src/index.js",

"devDependencies": {
"@favware/npm-deprecate": "^1.0.4",
"@types/node": "^17.0.43",
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
"@discordjs/voice": "^0.11.0",
"@favware/npm-deprecate": "^1.0.5",
"@types/node": "^18.6.3",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"copyfiles": "^2.4.1",
"discord-api-types": "0.34.0",
"discord.js": "npm:@notenoughupdates/discord.js@dev",
"eslint": "^8.17.0",
"discord-api-types": "^0.33.3",
"discord.js": "^13.9.2",
"eslint": "^8.20.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-deprecation": "^1.3.2",
"node-fetch": "^3.2.6",
"prettier": "^2.7.0",
"node-fetch": "^3.2.10",
"prettier": "^2.7.1",
"rimraf": "^3.0.2",
"typedoc": "^0.22.17",
"typescript": "^4.7.3"
"typedoc": "^0.23.9",
"typescript": "^4.7.4"
},
"packageManager": "yarn@3.2.1"
"prettier": {
"useTabs": true,
"trailingComma": "none",
"arrowParens": "avoid",
"printWidth": 130,
"overrides": [
{
"files": "*.md",
"options": {
"useTabs": false
}
}
]
}
}

@@ -20,3 +20,3 @@ <!-- markdownlint-disable MD041 MD033 MD001 MD026 -->

Please see [this file](/guide/general/updates.md) for a list of changes in this fork vs normal akairo.
Please see [this file](/docs/general/updates.md) for a list of changes in this fork vs normal akairo.
If you have any questions related to this fork please contact `IRONM00N#0001` in the akairo server or join my [bot's discord](https://discord.gg/7FpsYp2c47).

@@ -23,0 +23,0 @@

@@ -1,6 +0,34 @@

/* eslint-disable @typescript-eslint/no-unused-vars */
import packageJSON from "../package.json";
import { CommandUtil } from "./struct/commands/CommandUtil.js";
import { CommandUtil } from "./struct/commands/CommandUtil";
import * as Constants from "./util/Constants";
export * from "./struct/AkairoClient";
export * from "./struct/AkairoHandler";
export * from "./struct/AkairoModule";
export * from "./struct/ClientUtil";
export * from "./struct/commands/arguments/Argument";
export * from "./struct/commands/arguments/ArgumentRunner";
export * from "./struct/commands/arguments/TypeResolver";
export * from "./struct/commands/Command";
export * from "./struct/commands/CommandHandler";
export * from "./struct/commands/CommandUtil";
export * from "./struct/commands/ContentParser";
export * from "./struct/commands/Flag";
export * from "./struct/contextMenuCommands/ContextMenuCommand";
export * from "./struct/contextMenuCommands/ContextMenuCommandHandler";
export * from "./struct/inhibitors/Inhibitor";
export * from "./struct/inhibitors/InhibitorHandler";
export * from "./struct/listeners/Listener";
export * from "./struct/listeners/ListenerHandler";
export * from "./struct/tasks/Task";
export * from "./struct/tasks/TaskHandler";
export * from "./typings/events";
export * from "./util/AkairoError";
export * from "./util/AkairoMessage";
export * from "./util/Category";
export * from "./util/Util";
export { Constants };
export const { version } = packageJSON;
declare module "discord.js" {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export interface Message<Cached extends boolean = boolean> extends Base {

@@ -10,3 +38,3 @@ /**

* Utilities for command responding.
* Available on all messages after `'all'` inhibitors and built-in inhibitors (bot, client).
* Available on all messages after 'all' inhibitors and built-in inhibitors (bot, client).
* Not all properties of the util are available, depending on the input.

@@ -17,33 +45,1 @@ * */

}
export * from "./struct/AkairoClient.js";
export * from "./struct/AkairoHandler.js";
export * from "./struct/AkairoModule.js";
export * as ClientUtil from "./struct/ClientUtil.js";
export * from "./struct/commands/arguments/Argument.js";
export * from "./struct/commands/arguments/ArgumentRunner.js";
export * from "./struct/commands/arguments/TypeResolver.js";
export * from "./struct/commands/Command.js";
export * from "./struct/commands/CommandHandler.js";
export * from "./struct/commands/CommandUtil.js";
export * from "./struct/commands/ContentParser.js";
export * from "./struct/commands/Flag.js";
export * from "./struct/contextMenuCommands/ContextMenuCommand.js";
export * from "./struct/contextMenuCommands/ContextMenuCommandHandler.js";
export * from "./struct/inhibitors/Inhibitor.js";
export * from "./struct/inhibitors/InhibitorHandler.js";
export * from "./struct/listeners/Listener.js";
export * from "./struct/listeners/ListenerHandler.js";
export * from "./struct/tasks/Task.js";
export * from "./struct/tasks/TaskHandler.js";
export * from "./typings/events.js";
export * from "./util/AkairoError.js";
export * from "./util/AkairoMessage.js";
export * from "./util/Category.js";
export * as Constants from "./util/Constants.js";
export * as Util from "./util/Util.js";
/**
* The version of the library.
*/
export const version = packageJSON.version;
import { Awaitable, Client, ClientOptions, Snowflake, UserResolvable } from "discord.js";
import type { AkairoClientEvents } from "../typings/events.js";
import * as ClientUtil from "./ClientUtil.js";
import type { AkairoClientEvents } from "../typings/events";
import { ClientUtil } from "./ClientUtil.js";

@@ -22,7 +22,7 @@ /**

*/
public declare util: typeof ClientUtil;
public declare util: ClientUtil;
/**
* @param options - Options for the client.
* @param clientOptions - Options for Discord JS client. If not specified, the previous options parameter is used instead.
* @param clientOptions - Options for Discord JS client.If not specified, the previous options parameter is used instead.
*/

@@ -32,7 +32,7 @@ public constructor(options: AkairoOptions & ClientOptions);

public constructor(options: (AkairoOptions & ClientOptions) | AkairoOptions, clientOptions?: ClientOptions) {
const combinedOptions = <AkairoOptions & ClientOptions>{ ...options, ...(clientOptions ?? {}) };
super(combinedOptions);
const combinedOptions = { ...options, ...clientOptions };
super(combinedOptions as AkairoOptions & ClientOptions);
this.ownerID = combinedOptions.ownerID ?? [];
this.superUserID = combinedOptions.superUserID ?? [];
this.util = ClientUtil;
this.util = new ClientUtil(this);
}

@@ -63,19 +63,19 @@

type Events = AkairoClientEvents;
type Event = AkairoClientEvents;
export interface AkairoClient<Ready extends boolean = boolean> extends Client<Ready> {
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
on<S extends string | symbol>(event: Exclude<S, keyof Events>, listener: (...args: any[]) => Awaitable<void>): this;
on<K extends keyof Event>(event: K, listener: (...args: Event[K]) => Awaitable<void>): this;
on<S extends string | symbol>(event: Exclude<S, keyof Event>, listener: (...args: any[]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<S extends string | symbol>(event: Exclude<S, keyof Events>, listener: (...args: any[]) => Awaitable<void>): this;
once<K extends keyof Event>(event: K, listener: (...args: Event[K]) => Awaitable<void>): this;
once<S extends string | symbol>(event: Exclude<S, keyof Event>, listener: (...args: any[]) => Awaitable<void>): this;
emit<K extends keyof Events>(event: K, ...args: Events[K]): boolean;
emit<S extends string | symbol>(event: Exclude<S, keyof Events>, ...args: unknown[]): boolean;
emit<K extends keyof Event>(event: K, ...args: Event[K]): boolean;
emit<S extends string | symbol>(event: Exclude<S, keyof Event>, ...args: unknown[]): boolean;
off<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
off<S extends string | symbol>(event: Exclude<S, keyof Events>, listener: (...args: any[]) => Awaitable<void>): this;
off<K extends keyof Event>(event: K, listener: (...args: Event[K]) => Awaitable<void>): this;
off<S extends string | symbol>(event: Exclude<S, keyof Event>, listener: (...args: any[]) => Awaitable<void>): this;
removeAllListeners<K extends keyof Events>(event?: K): this;
removeAllListeners<S extends string | symbol>(event?: Exclude<S, keyof Events>): this;
removeAllListeners<K extends keyof Event>(event?: K): this;
removeAllListeners<S extends string | symbol>(event?: Exclude<S, keyof Event>): this;
}

@@ -82,0 +82,0 @@

import { Collection } from "discord.js";
import EventEmitter from "node:events";
import { readdirSync, statSync } from "node:fs";
import { dirname, extname, join, resolve, sep } from "node:path";
import { pathToFileURL } from "node:url";
import EventEmitter from "events";
import fs from "fs";
import path from "path";
import url from "url";
import { AkairoError } from "../util/AkairoError.js";
import { Category } from "../util/Category.js";
import { AkairoHandlerEvents } from "../util/Constants.js";
import { isArrayOf } from "../util/Util.js";
import { Util } from "../util/Util.js";
import type { AkairoClient } from "./AkairoClient.js";
import { AkairoModule } from "./AkairoModule.js";
export type Class<T> = abstract new (...args: any[]) => T;
export type Static<M> = { (): M };

@@ -18,6 +18,3 @@ /**

*/
export class AkairoHandler<
Module extends AkairoModule<Handler, Module>,
Handler extends AkairoHandler<Module, Handler>
> extends EventEmitter {
export class AkairoHandler extends EventEmitter {
/**

@@ -31,3 +28,3 @@ * Whether or not to automate category names.

*/
public declare categories: Collection<string, Category<string, Module>>;
public declare categories: Collection<string, Category<string, AkairoModule>>;

@@ -37,3 +34,3 @@ /**

*/
public declare classToHandle: Class<Module>;
public declare classToHandle: typeof AkairoModule;

@@ -63,3 +60,3 @@ /**

*/
public declare modules: Collection<string, Module>;
public declare modules: Collection<string, AkairoModule>;

@@ -70,3 +67,3 @@ /**

*/
public constructor(client: AkairoClient, options: AkairoHandlerOptions<Module, Handler>) {
public constructor(client: AkairoClient, options: AkairoHandlerOptions) {
const {

@@ -83,3 +80,3 @@ directory,

throw new TypeError("options.classToHandle must be a class that extends AkairoModule.");
if (!(extensions instanceof Set) && !isArrayOf(extensions, "string"))
if (!(extensions instanceof Set) && !Util.isArrayOf(extensions, "string"))
throw new TypeError("options.extensions must be an array of strings or a Set.");

@@ -93,5 +90,5 @@ if (typeof automateCategories !== "boolean") throw new TypeError("options.automateCategories must be a boolean.");

this.directory = directory;
this.classToHandle = <Class<Module>>classToHandle;
this.classToHandle = classToHandle;
this.extensions = new Set(extensions);
this.automateCategories = automateCategories;
this.automateCategories = Boolean(automateCategories);
this.loadFilter = loadFilter;

@@ -106,3 +103,3 @@ this.modules = new Collection();

*/
public deregister(mod: Module): void {
public deregister(mod: AkairoModule): void {
if (mod.filepath) delete require.cache[require.resolve(mod.filepath)];

@@ -117,3 +114,3 @@ this.modules.delete(mod.id);

*/
public findCategory(name: string): Category<string, Module> | undefined {
public findCategory(name: string): Category<string, AkairoModule> | undefined {
return this.categories.find(category => {

@@ -129,5 +126,5 @@ return category.id.toLowerCase() === name.toLowerCase();

*/
public async load(thing: string | Module, isReload = false): Promise<Module | undefined> {
public async load(thing: string | AkairoModule, isReload = false): Promise<AkairoModule | undefined> {
const isClass = typeof thing === "function";
if (!isClass && !this.extensions.has(extname(thing as string))) return undefined;
if (!isClass && !this.extensions.has(path.extname(thing as string))) return undefined;

@@ -140,3 +137,4 @@ let mod = isClass

return m.default ? findExport.call(this, m.default) : null;
}.call(this, await eval(`import(${JSON.stringify(pathToFileURL(thing as string).toString())})`));
// eslint-disable-next-line @typescript-eslint/no-var-requires
}.call(this, await eval(`import(${JSON.stringify(url.pathToFileURL(thing as string).toString())})`));

@@ -166,7 +164,7 @@ if (mod && mod.prototype instanceof this.classToHandle) {

filter: LoadPredicate = this.loadFilter || (() => true)
): Promise<this> {
): Promise<AkairoHandler> {
const filepaths = AkairoHandler.readdirRecursive(directory);
const promises = [];
for (let filepath of filepaths) {
filepath = resolve(filepath);
filepath = path.resolve(filepath);
if (filter(filepath)) promises.push(this.load(filepath));

@@ -184,10 +182,10 @@ }

*/
public register(mod: Module, filepath?: string): void {
public register(mod: AkairoModule, filepath?: string): void {
mod.filepath = filepath!;
mod.client = this.client;
mod.handler = <Handler>(<unknown>this);
mod.handler = this;
this.modules.set(mod.id, mod);
if (mod.categoryID === "default" && this.automateCategories) {
const dirs = dirname(filepath!).split(sep);
const dirs = path.dirname(filepath!).split(path.sep);
mod.categoryID = dirs[dirs.length - 1];

@@ -209,3 +207,3 @@ }

*/
public async reload(id: string): Promise<Module | undefined> {
public async reload(id: string): Promise<AkairoModule | undefined> {
const mod = this.modules.get(id.toString());

@@ -225,3 +223,3 @@ if (!mod) throw new AkairoError("MODULE_NOT_FOUND", this.classToHandle.name, id);

*/
public async reloadAll(): Promise<this> {
public async reloadAll(): Promise<AkairoHandler> {
const promises = [];

@@ -240,3 +238,3 @@ for (const m of Array.from(this.modules.values())) {

*/
public remove(id: string): Module {
public remove(id: string): AkairoModule {
const mod = this.modules.get(id.toString());

@@ -254,3 +252,3 @@ if (!mod) throw new AkairoError("MODULE_NOT_FOUND", this.classToHandle.name, id);

*/
public removeAll(): this {
public removeAll(): AkairoHandler {
for (const m of Array.from(this.modules.values())) {

@@ -271,8 +269,8 @@ if (m.filepath) this.remove(m.id);

(function read(dir) {
const files = readdirSync(dir);
const files = fs.readdirSync(dir);
for (const file of files) {
const filepath = join(dir, file);
const filepath = path.join(dir, file);
if (statSync(filepath).isDirectory()) {
if (fs.statSync(filepath).isDirectory()) {
read(filepath);

@@ -299,6 +297,3 @@ } else {

*/
export interface AkairoHandlerOptions<
Module extends AkairoModule<Handler, Module>,
Handler extends AkairoHandler<Module, Handler>
> {
export interface AkairoHandlerOptions {
/**

@@ -314,3 +309,3 @@ * Whether or not to set each module's category to its parent directory name.

*/
classToHandle?: Class<Module>;
classToHandle?: typeof AkairoModule;

@@ -317,0 +312,0 @@ /**

@@ -8,10 +8,10 @@ import type { Category } from "../util/Category.js";

*/
export abstract class AkairoModule<Handler extends AkairoHandler<Module, Handler>, Module extends AkairoModule<Handler, Module>> {
export abstract class AkairoModule {
/**
* The category this module belongs to.
* Category this belongs to.
*/
public declare category: Category<string, this>;
public declare category: Category<string, AkairoModule>;
/**
* The ID of the category this module belongs to.
* ID of the category this belongs to.
*/

@@ -21,3 +21,3 @@ public declare categoryID: string;

/**
* The client thant instantiated this module.
* The Akairo client.
*/

@@ -27,3 +27,3 @@ public declare client: AkairoClient;

/**
* The filepath of this module.
* The filepath.
*/

@@ -33,8 +33,8 @@ public declare filepath: string;

/**
* The handler for this module.
* The handler.
*/
public declare handler: Handler;
public declare handler: AkairoHandler;
/**
* The ID of this module.
* ID of the module.
*/

@@ -44,4 +44,4 @@ public declare id: string;

/**
* @param id The ID of module.
* @param options Additional options for this module.
* @param id - ID of module.
* @param options - Options.
*/

@@ -62,17 +62,17 @@ public constructor(id: string, options?: AkairoModuleOptions) {

/**
* Reloads this module.
* Reloads the module.
*/
public reload(): Promise<Module> {
return this.handler?.reload(this.id) as Promise<Module>;
public reload(): Promise<AkairoModule> {
return this.handler?.reload(this.id) as Promise<this>;
}
/**
* Removes this module.
* Removes the module.
*/
public remove(): Module {
return this.handler?.remove(this.id) as Module;
public remove(): AkairoModule {
return this.handler?.remove(this.id) as this;
}
/**
* Returns the ID of this module.
* Returns the ID.
*/

@@ -79,0 +79,0 @@ public toString(): string {

@@ -0,443 +1,454 @@

import { APIEmbed } from "discord-api-types/v9";
import {
ActivityType,
AttachmentBuilder,
BufferResolvable,
Collection,
EmbedBuilder,
PermissionFlagsBits,
type APIEmbed,
type BufferResolvable,
type EmbedData,
type Emoji,
type Guild,
type GuildBasedChannel,
type GuildMember,
type PermissionsString,
type Role,
type Snowflake,
type User
Emoji,
Guild,
GuildChannel,
GuildMember,
MessageAttachment,
MessageEmbed,
Permissions,
PermissionString,
Role,
Snowflake,
ThreadChannel,
User
} from "discord.js";
import type { Stream } from "node:stream";
import type { Stream } from "stream";
import type { AkairoClient } from "./AkairoClient.js";
/**
* Makes a Attachment.
* @param file - The file.
* @param name - The filename.
* @param description - The description of the file.
* Client utilities to help with common tasks.
*/
export function attachment(file: BufferResolvable | Stream, name?: string, description?: string): AttachmentBuilder {
return new AttachmentBuilder(file, { name, description });
}
export class ClientUtil {
/**
* The Akairo client.
*/
public declare readonly client: AkairoClient;
/**
* Checks if a string could be referring to a channel.
* @param text - Text to check.
* @param channel - Channel to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export function checkChannel<C extends GuildBasedChannel>(
text: string,
channel: C,
caseSensitive = false,
wholeWord = false
): boolean {
if (channel.id === text) return true;
/**
* @param client - The client.
*/
public constructor(client: AkairoClient) {
this.client = client;
}
const reg = /<#(\d{17,19})>/;
const match = text.match(reg);
/**
* Makes a MessageAttachment.
* @param file - The file.
* @param name - The filename.
*/
public attachment(file: BufferResolvable | Stream, name?: string): MessageAttachment {
return new MessageAttachment(file, name);
}
if (match && channel.id === match[1]) return true;
/**
* Checks if a string could be referring to a channel.
* @param text - Text to check.
* @param channel - Channel to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
public checkChannel<C extends ThreadChannel | GuildChannel>(
text: string,
channel: C,
caseSensitive = false,
wholeWord = false
): boolean {
if (channel.id === text) return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? channel.name : channel.name.toLowerCase();
const reg = /<#(\d{17,19})>/;
const match = text.match(reg);
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^#/, ""));
if (match && channel.id === match[1]) return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? channel.name : channel.name.toLowerCase();
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^#/, ""));
}
return name === text || name === text.replace(/^#/, "");
}
return name === text || name === text.replace(/^#/, "");
}
/**
* Checks if a string could be referring to a emoji.
* @param text - Text to check.
* @param emoji - Emoji to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
public checkEmoji(text: string, emoji: Emoji, caseSensitive = false, wholeWord = false): boolean {
if (emoji.id === text) return true;
/**
* Checks if a string could be referring to a emoji.
* @param text - Text to check.
* @param emoji - Emoji to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export function checkEmoji(text: string, emoji: Emoji, caseSensitive = false, wholeWord = false): boolean {
if (emoji.id === text) return true;
const reg = /<a?:[a-zA-Z0-9_]+:(\d{17,19})>/;
const match = text.match(reg);
const reg = /<a?:[a-zA-Z0-9_]+:(\d{17,19})>/;
const match = text.match(reg);
if (match && emoji.id === match[1]) return true;
if (match && emoji.id === match[1]) return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? emoji.name : emoji.name?.toLowerCase();
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? emoji.name : emoji.name?.toLowerCase();
if (!wholeWord) {
return Boolean(name?.includes(text) || name?.includes(text.replace(/:/, "")));
}
if (!wholeWord) {
return Boolean(name?.includes(text) || name?.includes(text.replace(/:/, "")));
return name === text || name === text.replace(/:/, "");
}
return name === text || name === text.replace(/:/, "");
}
/**
* Checks if a string could be referring to a guild.
* @param text - Text to check.
* @param guild - Guild to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
public checkGuild(text: string, guild: Guild, caseSensitive = false, wholeWord = false): boolean {
if (guild.id === text) return true;
/**
* Checks if a string could be referring to a guild.
* @param text - Text to check.
* @param guild - Guild to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export function checkGuild(text: string, guild: Guild, caseSensitive = false, wholeWord = false): boolean {
if (guild.id === text) return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? guild.name : guild.name.toLowerCase();
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? guild.name : guild.name.toLowerCase();
if (!wholeWord) return name.includes(text);
return name === text;
}
if (!wholeWord) return name.includes(text);
return name === text;
}
/**
* Checks if a string could be referring to a member.
* @param text - Text to check.
* @param member - Member to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
public checkMember(text: string, member: GuildMember, caseSensitive = false, wholeWord = false): boolean {
if (member.id === text) return true;
/**
* Checks if a string could be referring to a member.
* @param text - Text to check.
* @param member - Member to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export function checkMember(text: string, member: GuildMember, caseSensitive = false, wholeWord = false): boolean {
if (member.id === text) return true;
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
if (match && member.id === match[1]) return true;
if (match && member.id === match[1]) return true;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? member.user.username : member.user.username.toLowerCase();
const displayName = caseSensitive ? member.displayName : member.displayName.toLowerCase();
const discrim = member.user.discriminator;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? member.user.username : member.user.username.toLowerCase();
const displayName = caseSensitive ? member.displayName : member.displayName.toLowerCase();
const discrim = member.user.discriminator;
if (!wholeWord) {
return (
displayName.includes(text) ||
username.includes(text) ||
((username.includes(text.split("#")[0]) || displayName.includes(text.split("#")[0])) &&
discrim.includes(text.split("#")[1]))
);
}
if (!wholeWord) {
return (
displayName.includes(text) ||
username.includes(text) ||
((username.includes(text.split("#")[0]) || displayName.includes(text.split("#")[0])) &&
discrim.includes(text.split("#")[1]))
displayName === text ||
username === text ||
((username === text.split("#")[0] || displayName === text.split("#")[0]) && discrim === text.split("#")[1])
);
}
return (
displayName === text ||
username === text ||
((username === text.split("#")[0] || displayName === text.split("#")[0]) && discrim === text.split("#")[1])
);
}
/**
* Checks if a string could be referring to a role.
* @param text - Text to check.
* @param role - Role to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
public checkRole(text: string, role: Role, caseSensitive = false, wholeWord = false): boolean {
if (role.id === text) return true;
/**
* Checks if a string could be referring to a role.
* @param text - Text to check.
* @param role - Role to check.
* @param caseSensitive - Makes checking by name case sensitive.
* @param wholeWord - Makes checking by name match full word only.
*/
export function checkRole(text: string, role: Role, caseSensitive = false, wholeWord = false): boolean {
if (role.id === text) return true;
const reg = /<@&(\d{17,19})>/;
const match = text.match(reg);
const reg = /<@&(\d{17,19})>/;
const match = text.match(reg);
if (match && role.id === match[1]) return true;
if (match && role.id === match[1]) return true;
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? role.name : role.name.toLowerCase();
text = caseSensitive ? text : text.toLowerCase();
const name = caseSensitive ? role.name : role.name.toLowerCase();
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^@/, ""));
}
if (!wholeWord) {
return name.includes(text) || name.includes(text.replace(/^@/, ""));
return name === text || name === text.replace(/^@/, "");
}
return name === text || name === text.replace(/^@/, "");
}
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public checkUser(text: string, user: User, caseSensitive = false, wholeWord = false): boolean {
if (user.id === text) return true;
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function checkUser(text: string, user: User, caseSensitive = false, wholeWord = false): boolean {
if (user.id === text) return true;
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
const reg = /<@!?(\d{17,19})>/;
const match = text.match(reg);
if (match && user.id === match[1]) return true;
if (match && user.id === match[1]) return true;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? user.username : user.username.toLowerCase();
const discrim = user.discriminator;
text = caseSensitive ? text : text.toLowerCase();
const username = caseSensitive ? user.username : user.username.toLowerCase();
const discrim = user.discriminator;
if (!wholeWord) {
return username.includes(text) || (username.includes(text.split("#")[0]) && discrim.includes(text.split("#")[1]));
}
if (!wholeWord) {
return username.includes(text) || (username.includes(text.split("#")[0]) && discrim.includes(text.split("#")[1]));
return username === text || (username === text.split("#")[0] && discrim === text.split("#")[1]);
}
return username === text || (username === text.split("#")[0] && discrim === text.split("#")[1]);
}
/**
* Makes a Collection.
* @param iterable - Entries to fill with.
*/
public collection<K, V>(iterable?: ReadonlyArray<readonly [K, V]> | null): Collection<K, V> {
return new Collection(iterable);
}
/**
* Makes a Collection.
* @param iterable - Entries to fill with.
*/
export function collection<K, V>(iterable?: ReadonlyArray<readonly [K, V]> | null): Collection<K, V> {
return new Collection(iterable);
}
/**
* Compares two member objects presences and checks if they stopped or started a stream or not.
* Returns `0`, `1`, or `2` for no change, stopped, or started.
* @param oldMember - The old member.
* @param newMember - The new member.
*/
public compareStreaming(oldMember: GuildMember, newMember: GuildMember): 0 | 1 | 2 {
const s1 = oldMember.presence?.activities.find(c => c.type === "STREAMING");
const s2 = newMember.presence?.activities.find(c => c.type === "STREAMING");
if (s1 === s2) return 0;
if (s1) return 1;
if (s2) return 2;
return 0;
}
/**
* Compares two member objects presences and checks if they stopped or started a stream or not.
* Returns `0`, `1`, or `2` for no change, stopped, or started.
* @param oldMember - The old member.
* @param newMember - The new member.
*/
export function compareStreaming(oldMember: GuildMember, newMember: GuildMember): 0 | 1 | 2 {
const s1 = oldMember.presence?.activities.find(c => c.type === ActivityType.Streaming);
const s2 = newMember.presence?.activities.find(c => c.type === ActivityType.Streaming);
if (s1 === s2) return 0;
if (s1) return 1;
if (s2) return 2;
return 0;
}
/**
* Makes a Embed.
* @param data - Embed data.
*/
public embed(data?: MessageEmbed | APIEmbed): MessageEmbed {
return new MessageEmbed(data);
}
/**
* Makes a Embed.
* @param data - Embed data.
*/
export function embed(data?: EmbedData | APIEmbed): EmbedBuilder {
return new EmbedBuilder(data);
}
/**
* Combination of `<Client>.fetchUser()` and `<Guild>.fetchMember()`.
* @param guild - Guild to fetch in.
* @param id - ID of the user.
* @param cache - Whether or not to add to cache.
*/
public async fetchMember(guild: Guild, id: Snowflake, cache: boolean): Promise<GuildMember> {
const user = await this.client.users.fetch(id, { cache });
return guild.members.fetch({ user, cache });
}
/**
* Combination of `<Client>.fetchUser()` and `<Guild>.fetchMember()`.
* @param guild - Guild to fetch in.
* @param id - ID of the user.
* @param cache - Whether or not to add to cache.
*/
export async function fetchMember(guild: Guild, id: Snowflake, cache: boolean): Promise<GuildMember> {
const user = await guild.client.users.fetch(id, { cache });
return guild.members.fetch({ user, cache });
}
/**
* Array of permission names.
*/
public permissionNames(): PermissionString[] {
return Object.keys(Permissions.FLAGS) as PermissionString[];
}
/**
* Array of permission names.
*/
export function permissionNames(): PermissionsString[] {
return Object.keys(PermissionFlagsBits) as PermissionsString[];
}
/**
* Resolves a channel from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveChannel<C extends ThreadChannel | GuildChannel>(
text: string,
channels: Collection<Snowflake, C>,
caseSensitive = false,
wholeWord = false
): C | null {
return channels.get(text) ?? channels.find(channel => this.checkChannel(text, channel, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves a channel from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveChannel<C extends GuildBasedChannel>(
text: string,
channels: Collection<Snowflake, C>,
caseSensitive = false,
wholeWord = false
): C | null {
return channels.get(text) ?? channels.find(channel => checkChannel(text, channel, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple channels from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveChannels<C extends ThreadChannel | GuildChannel>(
text: string,
channels: Collection<Snowflake, C>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, C> {
return channels.filter(channel => this.checkChannel(text, channel, caseSensitive, wholeWord));
}
/**
* Resolves multiple channels from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param channels - Collection of channels to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveChannels<C extends GuildBasedChannel>(
text: string,
channels: Collection<Snowflake, C>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, C> {
return channels.filter(channel => checkChannel(text, channel, caseSensitive, wholeWord));
}
/**
* Resolves a custom emoji from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveEmoji(
text: string,
emojis: Collection<Snowflake, Emoji>,
caseSensitive = false,
wholeWord = false
): Emoji | null {
return emojis.get(text) ?? emojis.find(emoji => this.checkEmoji(text, emoji, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves a custom emoji from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveEmoji(
text: string,
emojis: Collection<Snowflake, Emoji>,
caseSensitive = false,
wholeWord = false
): Emoji | null {
return emojis.get(text) ?? emojis.find(emoji => checkEmoji(text, emoji, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple custom emojis from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveEmojis(
text: string,
emojis: Collection<Snowflake, Emoji>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, Emoji> {
return emojis.filter(emoji => this.checkEmoji(text, emoji, caseSensitive, wholeWord));
}
/**
* Resolves multiple custom emojis from a string, such as a name or a mention.
* @param text - Text to resolve.
* @param emojis - Collection of emojis to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveEmojis(
text: string,
emojis: Collection<Snowflake, Emoji>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, Emoji> {
return emojis.filter(emoji => checkEmoji(text, emoji, caseSensitive, wholeWord));
}
/**
* Resolves a guild from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveGuild(
text: string,
guilds: Collection<Snowflake, Guild>,
caseSensitive = false,
wholeWord = false
): Guild | null {
return guilds.get(text) ?? guilds.find(guild => this.checkGuild(text, guild, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves a guild from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveGuild(
text: string,
guilds: Collection<Snowflake, Guild>,
caseSensitive = false,
wholeWord = false
): Guild | null {
return guilds.get(text) ?? guilds.find(guild => checkGuild(text, guild, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple guilds from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveGuilds(
text: string,
guilds: Collection<Snowflake, Guild>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, Guild> {
return guilds.filter(guild => this.checkGuild(text, guild, caseSensitive, wholeWord));
}
/**
* Resolves multiple guilds from a string, such as an ID or a name.
* @param text - Text to resolve.
* @param guilds - Collection of guilds to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveGuilds(
text: string,
guilds: Collection<Snowflake, Guild>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, Guild> {
return guilds.filter(guild => checkGuild(text, guild, caseSensitive, wholeWord));
}
/**
* Resolves a member from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveMember(
text: string,
members: Collection<Snowflake, GuildMember>,
caseSensitive = false,
wholeWord = false
): GuildMember | null {
return members.get(text) ?? members.find(member => this.checkMember(text, member, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves a member from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveMember(
text: string,
members: Collection<Snowflake, GuildMember>,
caseSensitive = false,
wholeWord = false
): GuildMember | null {
return members.get(text) ?? members.find(member => checkMember(text, member, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple members from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveMembers(
text: string,
members: Collection<Snowflake, GuildMember>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, GuildMember> {
return members.filter(member => this.checkMember(text, member, caseSensitive, wholeWord));
}
/**
* Resolves multiple members from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param members - Collection of members to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveMembers(
text: string,
members: Collection<Snowflake, GuildMember>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, GuildMember> {
return members.filter(member => checkMember(text, member, caseSensitive, wholeWord));
}
/**
* Resolves a permission number and returns an array of permission names.
* @param number - The permissions number.
*/
public resolvePermissionNumber(number: number): string[] {
const resolved = [];
/**
* Resolves a permission number and returns an array of permission names.
* @param number - The permissions number.
*/
export function resolvePermissionNumber(number: number): string[] {
const resolved = [];
for (const key of Object.keys(Permissions.FLAGS)) {
if (BigInt(number) & Permissions.FLAGS[key as PermissionString]) resolved.push(key);
}
for (const key of Object.keys(PermissionFlagsBits)) {
if (BigInt(number) & PermissionFlagsBits[key as PermissionsString]) resolved.push(key);
return resolved;
}
return resolved;
}
/**
* Resolves a role from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveRole(text: string, roles: Collection<Snowflake, Role>, caseSensitive = false, wholeWord = false): Role | null {
return roles.get(text) ?? roles.find(role => this.checkRole(text, role, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves a role from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveRole(
text: string,
roles: Collection<Snowflake, Role>,
caseSensitive = false,
wholeWord = false
): Role | null {
return roles.get(text) ?? roles.find(role => checkRole(text, role, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves multiple roles from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveRoles(
text: string,
roles: Collection<Snowflake, Role>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, Role> {
return roles.filter(role => this.checkRole(text, role, caseSensitive, wholeWord));
}
/**
* Resolves multiple roles from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param roles - Collection of roles to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveRoles(
text: string,
roles: Collection<Snowflake, Role>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, Role> {
return roles.filter(role => checkRole(text, role, caseSensitive, wholeWord));
}
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveUser(
text: Snowflake | string,
users: Collection<Snowflake, User>,
caseSensitive = false,
wholeWord = false
): User | null {
return users.get(text) ?? users.find(user => this.checkUser(text, user, caseSensitive, wholeWord)) ?? null;
}
/**
* Resolves a user from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveUser(
text: Snowflake | string,
users: Collection<Snowflake, User>,
caseSensitive = false,
wholeWord = false
): User | null {
return users.get(text) ?? users.find(user => checkUser(text, user, caseSensitive, wholeWord)) ?? null;
/**
* Resolves multiple users from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
public resolveUsers(
text: string,
users: Collection<Snowflake, User>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, User> {
return users.filter(user => this.checkUser(text, user, caseSensitive, wholeWord));
}
}
/**
* Resolves multiple users from a string, such as an ID, a name, or a mention.
* @param text - Text to resolve.
* @param users - Collection of users to find in.
* @param caseSensitive - Makes finding by name case sensitive.
* @param wholeWord - Makes finding by name match full word only.
*/
export function resolveUsers(
text: string,
users: Collection<Snowflake, User>,
caseSensitive = false,
wholeWord = false
): Collection<Snowflake, User> {
return users.filter(user => checkUser(text, user, caseSensitive, wholeWord));
}
import type {
BaseGuildVoiceChannel,
CategoryChannel,
Collection,
DirectoryChannel,
Emoji,

@@ -17,19 +17,17 @@ Guild,

Role,
Snowflake,
StageChannel,
TextBasedChannel,
StoreChannel,
TextChannel,
ThreadChannel,
User,
VoiceBasedChannel,
VoiceChannel
} from "discord.js";
import type { URL } from "node:url";
import type { URL } from "url";
import { ArgumentMatches, ArgumentTypes } from "../../../util/Constants.js";
import { intoCallable, isArrayOf, isPromise, isStringArrayStringOrFunc } from "../../../util/Util.js";
import { isStringArrayStringOrFunc, Util } from "../../../util/Util.js";
import type { AkairoClient } from "../../AkairoClient.js";
import type { ContextMenuCommand } from "../../contextMenuCommands/ContextMenuCommand.js";
import type { Inhibitor } from "../../inhibitors/Inhibitor.js";
import type { Listener } from "../../listeners/Listener.js";
import type { Task } from "../../tasks/Task.js";
import { ContextMenuCommand } from "../../contextMenuCommands/ContextMenuCommand.js";
import { Inhibitor } from "../../inhibitors/Inhibitor.js";
import { Listener } from "../../listeners/Listener.js";
import { Task } from "../../tasks/Task.js";
import type { Command } from "../Command.js";

@@ -145,3 +143,3 @@ import type { CommandHandler } from "../CommandHandler.js";

public constructor(command: Command, options: ArgumentOptions = {}) {
// doing this instead of object deconstruction so it's valid to pass null values
// doing this instead of object deconstruction so its valid to pass null values
const match = options.match ?? ArgumentMatches.PHRASE,

@@ -159,3 +157,3 @@ type = options.type ?? ArgumentTypes.STRING,

if (!Object.values(ArgumentMatches).includes(match as ArgumentMatches))
if (!Object.values(ArgumentMatches).includes(match))
throw new TypeError(

@@ -170,3 +168,3 @@ `options.match must one of ${Object.values(ArgumentMatches)

if (index !== null && typeof index !== "number") throw new TypeError("options.index must be a number or null.");
if (typeof unordered !== "boolean" && typeof unordered !== "number" && !isArrayOf(unordered, "number"))
if (typeof unordered !== "boolean" && typeof unordered !== "number" && !Util.isArrayOf(unordered, "number"))
throw new TypeError("options.unordered must be a boolean, number, or array of numbers.");

@@ -242,3 +240,3 @@ if (typeof limit !== "number") throw new TypeError("options.limit must be a number.");

) => {
let text = await intoCallable(prompter).call(this, message, {
let text = await Util.intoCallable(prompter).call(this, message, {
retries: retryCount,

@@ -321,4 +319,4 @@ infinite: isInfinite,

}
if (!promptOptions.time) return Flag.cancel();
return Flag.timeout(promptOptions.time);
return Flag.cancel();
}

@@ -402,3 +400,3 @@

let text = await intoCallable(otherwise).call(this, message, {
let text = await Util.intoCallable(otherwise).call(this, message, {
phrase,

@@ -434,3 +432,3 @@ failure

return intoCallable(this.default)(message, {
return Util.intoCallable(this.default)(message, {
phrase,

@@ -451,3 +449,3 @@ failure: null

return this.default == null ? res : intoCallable(this.default)(message, { phrase, failure: res });
return this.default == null ? res : Util.intoCallable(this.default)(message, { phrase, failure: res });
}

@@ -485,3 +483,3 @@

let res = type(message, phrase);
if (isPromise(res)) res = await res;
if (Util.isPromise(res)) res = await res;
return res;

@@ -509,3 +507,3 @@ }

let res = resolver.type(type)?.call(this, message, phrase);
if (isPromise(res)) res = await res;
if (Util.isPromise(res)) res = await res;
return res;

@@ -853,3 +851,3 @@ }

* The command to be run may be the same command or some other command.
* @default true
* Defaults to true,
*/

@@ -864,4 +862,3 @@ breakout?: boolean;

/**
* Word to use for cancelling the command.
* @default "cancel"
* Word to use for cancelling the command. Defaults to 'cancel'.
*/

@@ -879,3 +876,3 @@ cancelWord?: string;

* The final evaluated argument will be an array of the inputs.
* @default false
* Defaults to false.
*/

@@ -885,4 +882,3 @@ infinite?: boolean;

/**
* Amount of inputs allowed for an infinite prompt before finishing.
* @default Infinity.
* Amount of inputs allowed for an infinite prompt before finishing. Defaults to Infinity.
*/

@@ -917,4 +913,3 @@ limit?: number;

/**
* Prompts only when argument is provided but was not of the right type.
* @default false
* Prompts only when argument is provided but was not of the right type. Defaults to false.
*/

@@ -924,4 +919,3 @@ optional?: boolean;

/**
* Amount of retries allowed.
* @default 1
* Amount of retries allowed. Defaults to 1.
*/

@@ -941,4 +935,3 @@ retries?: number;

/**
* Word to use for ending infinite prompts.
* @default "stop"
* Word to use for ending infinite prompts. Defaults to 'stop'.
*/

@@ -948,4 +941,3 @@ stopWord?: string;

/**
* Time to wait for input.
* @default 30000
* Time to wait for input. Defaults to 30000.
*/

@@ -1012,5 +1004,5 @@ time?: number;

* - `newsChannel` tries to resolve to a news channel.
* - `storeChannel` tries to resolve to a store channel.
* - `stageChannel` tries to resolve to a stage channel.
* - `threadChannel` tries to resolve a thread channel.
* - `directoryChannel` tries to resolve to a directory channel.
* - `role` tries to resolve to a role.

@@ -1044,35 +1036,31 @@ * - `emoji` tries to resolve to a custom emoji.

user: User | null;
users: Collection<Snowflake, User> | null;
users: Collection<string, User> | null;
member: GuildMember | null;
members: Collection<Snowflake, GuildMember> | null;
members: Collection<string, GuildMember> | null;
relevant: User | GuildMember | null;
relevants: Collection<Snowflake, User> | Collection<Snowflake, GuildMember> | null;
channel: GuildBasedChannel | null;
channels: Collection<Snowflake, GuildBasedChannel> | null;
relevants: Collection<string, User> | Collection<string, GuildMember> | null;
channel: GuildBasedChannel | BaseGuildVoiceChannel | null;
channels: Collection<string, GuildBasedChannel | BaseGuildVoiceChannel> | null;
textChannel: TextChannel | null;
textChannels: Collection<Snowflake, TextChannel> | null;
textChannels: Collection<string, TextChannel> | null;
voiceChannel: VoiceChannel | null;
voiceChannels: Collection<Snowflake, VoiceChannel> | null;
voiceChannels: Collection<string, VoiceChannel> | null;
categoryChannel: CategoryChannel | null;
categoryChannels: Collection<Snowflake, CategoryChannel> | null;
categoryChannels: Collection<string, CategoryChannel> | null;
newsChannel: NewsChannel | null;
newsChannels: Collection<Snowflake, NewsChannel> | null;
newsChannels: Collection<string, NewsChannel> | null;
// eslint-disable-next-line deprecation/deprecation
storeChannel: StoreChannel | null;
// eslint-disable-next-line deprecation/deprecation
storeChannels: Collection<string, StoreChannel> | null;
stageChannel: StageChannel | null;
stageChannels: Collection<Snowflake, StageChannel> | null;
stageChannels: Collection<string, StageChannel> | null;
threadChannel: ThreadChannel | null;
threadChannels: Collection<Snowflake, ThreadChannel> | null;
directoryChannel: DirectoryChannel | null;
directoryChannels: Collection<Snowflake, DirectoryChannel> | null;
forumChannel: unknown | null;
forumChannels: Collection<Snowflake, unknown> | null;
textBasedChannel: TextBasedChannel | null;
textBasedChannels: Collection<Snowflake, TextBasedChannel> | null;
voiceBasedChannel: VoiceBasedChannel | null;
voiceBasedChannels: Collection<Snowflake, VoiceBasedChannel> | null;
threadChannels: Collection<string, ThreadChannel> | null;
role: Role | null;
roles: Collection<Snowflake, Role> | null;
roles: Collection<string, Role> | null;
emoji: Emoji | null;
emojis: Collection<Snowflake, Emoji> | null;
emojis: Collection<string, Emoji> | null;
guild: Guild | null;
guilds: Collection<Snowflake, Guild> | null;
guilds: Collection<string, Guild> | null;
message: Message | null;

@@ -1180,3 +1168,3 @@ guildMessage: Message | null;

message: Message,
text: string | MessagePayload | MessageOptions | OtherwiseContentSupplier,
text: string,
data: FailureData

@@ -1203,3 +1191,3 @@ ) => string | MessagePayload | MessageOptions | Promise<string | MessagePayload | MessageOptions>;

message: Message,
text: string | MessagePayload | MessageOptions | OtherwiseContentSupplier,
text: string,
data: ArgumentPromptData

@@ -1206,0 +1194,0 @@ ) => string | MessagePayload | MessageOptions | Promise<string | MessagePayload | MessageOptions>;

import type { Message } from "discord.js";
import { AkairoError } from "../../../util/AkairoError.js";
import { ArgumentMatches } from "../../../util/Constants.js";
import type { ArgumentGenerator, ArgumentGeneratorReturn, Command } from "../Command.js";
import { ArgumentGenerator, ArgumentGeneratorReturn, Command } from "../Command.js";
import type { ContentParserResult } from "../ContentParser.js";
import { Flag, FlagType } from "../Flag.js";
import { Argument, type ArgumentOptions, type ArgumentTypeCasterReturn } from "./Argument.js";
import { Argument, ArgumentOptions, ArgumentTypeCasterReturn } from "./Argument.js";

@@ -49,3 +49,8 @@ /**

generator: ArgumentGenerator
): Promise<Flag | { [args: string]: unknown }> {
): Promise<
| Flag
| {
[args: string]: unknown;
}
> {
const state = {

@@ -52,0 +57,0 @@ usedIndices: new Set<number>(),

import {
ChannelType,
CategoryChannel,
Collection,
type CategoryChannel,
type DirectoryChannel,
type DMChannel,
type GuildBasedChannel,
type GuildMember,
type Message,
type NewsChannel,
type Snowflake,
type StageChannel,
type TextBasedChannel,
type TextChannel,
type ThreadChannel,
type VoiceBasedChannel,
type VoiceChannel
DMChannel,
GuildMember,
Message,
NewsChannel,
StageChannel,
StoreChannel,
TextChannel,
ThreadChannel,
VoiceChannel
} from "discord.js";
import { URL } from "node:url";
import { URL } from "url";
import { ArgumentTypes } from "../../../util/Constants.js";

@@ -83,23 +78,2 @@ import type { AkairoClient } from "../../AkairoClient.js";

private singleChannelBuiltInType<R extends GuildBasedChannel>(type: ChannelType) {
return (message: Message, phrase: string): R | null => {
if (!phrase || !message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (channel?.type !== type) return null;
return <R>channel;
};
}
private multipleChannelBuiltInType<R extends GuildBasedChannel>(type: ChannelType) {
return (message: Message, phrase: string): Collection<Snowflake, R> | null => {
if (!phrase || !message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
const textChannels = <Collection<Snowflake, R>>channels.filter(c => c.type === type);
return textChannels.size ? textChannels : null;
};
}
/**

@@ -218,3 +192,3 @@ * Adds built-in types.

new Collection([
[(message.channel as DMChannel).recipientId, (message.channel as DMChannel).recipient!],
[(message.channel as DMChannel).recipient.id!, (message.channel as DMChannel).recipient!],
[this.client.user!.id, this.client.user!]

@@ -235,3 +209,3 @@ ])

new Collection([
[(message.channel as DMChannel).recipientId, (message.channel as DMChannel).recipient!],
[(message.channel as DMChannel).recipient.id, (message.channel as DMChannel).recipient],
[this.client.user!.id, this.client.user!]

@@ -258,26 +232,63 @@ ])

[ArgumentTypes.TEXT_CHANNEL]: this.singleChannelBuiltInType<TextChannel>(ChannelType.GuildText),
[ArgumentTypes.TEXT_CHANNEL]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || channel.type !== "GUILD_TEXT") return null;
[ArgumentTypes.TEXT_CHANNELS]: this.multipleChannelBuiltInType<TextChannel>(ChannelType.GuildText),
return channel;
},
[ArgumentTypes.VOICE_CHANNEL]: this.singleChannelBuiltInType<VoiceChannel>(ChannelType.GuildVoice),
[ArgumentTypes.TEXT_CHANNELS]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
[ArgumentTypes.VOICE_CHANNELS]: this.multipleChannelBuiltInType<VoiceChannel>(ChannelType.GuildVoice),
const textChannels = <Collection<string, TextChannel>>channels.filter(c => c.isText());
return textChannels.size ? textChannels : null;
},
[ArgumentTypes.CATEGORY_CHANNEL]: this.singleChannelBuiltInType<CategoryChannel>(ChannelType.GuildCategory),
[ArgumentTypes.VOICE_CHANNEL]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || channel.type !== "GUILD_VOICE") return null;
return channel;
},
[ArgumentTypes.CATEGORY_CHANNELS]: this.multipleChannelBuiltInType<CategoryChannel>(ChannelType.GuildCategory),
[ArgumentTypes.VOICE_CHANNELS]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
[ArgumentTypes.NEWS_CHANNEL]: this.singleChannelBuiltInType<NewsChannel>(ChannelType.GuildNews),
const voiceChannels = <Collection<string, VoiceChannel>>channels.filter(c => c.isVoice());
return voiceChannels.size ? voiceChannels : null;
},
[ArgumentTypes.NEWS_CHANNELS]: this.multipleChannelBuiltInType<NewsChannel>(ChannelType.GuildCategory),
[ArgumentTypes.CATEGORY_CHANNEL]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || channel.type !== "GUILD_CATEGORY") return null;
[ArgumentTypes.STAGE_CHANNEL]: this.singleChannelBuiltInType<StageChannel>(ChannelType.GuildStageVoice),
return channel;
},
[ArgumentTypes.STAGE_CHANNELS]: this.multipleChannelBuiltInType<StageChannel>(ChannelType.GuildStageVoice),
[ArgumentTypes.CATEGORY_CHANNELS]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
[ArgumentTypes.THREAD_CHANNEL]: (message, phrase) => {
if (!phrase || !message.inGuild()) return null;
const categoryChannels = <Collection<string, CategoryChannel>>channels.filter(c => c.type === "GUILD_CATEGORY");
return categoryChannels.size ? categoryChannels : null;
},
[ArgumentTypes.NEWS_CHANNEL]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel?.isThread()) return null;
if (!channel || channel.type !== "GUILD_NEWS") return null;

@@ -287,25 +298,37 @@ return channel;

[ArgumentTypes.THREAD_CHANNELS]: (message, phrase) => {
if (!phrase || !message.inGuild()) return null;
[ArgumentTypes.NEWS_CHANNELS]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
const threadChannels = <Collection<Snowflake, ThreadChannel>>channels.filter(c => c.isThread());
return threadChannels.size ? threadChannels : null;
const newsChannels = <Collection<string, NewsChannel>>channels.filter(c => c.type === "GUILD_NEWS");
return newsChannels.size ? newsChannels : null;
},
// @ts-expect-error
[ArgumentTypes.DIRECTORY_CHANNEL]: this.singleChannelBuiltInType<DirectoryChannel>(ChannelType.GuildDirectory),
[ArgumentTypes.STORE_CHANNEL]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel || channel.type !== "GUILD_STORE") return null;
// @ts-expect-error
[ArgumentTypes.DIRECTORY_CHANNELS]: this.multipleChannelBuiltInType<DirectoryChannel>(ChannelType.GuildDirectory),
return channel;
},
[ArgumentTypes.FORUM_CHANNEL]: this.singleChannelBuiltInType<any>(ChannelType.GuildForum),
[ArgumentTypes.STORE_CHANNELS]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
[ArgumentTypes.FORUM_CHANNELS]: this.multipleChannelBuiltInType<any>(ChannelType.GuildForum),
// eslint-disable-next-line deprecation/deprecation
const storeChannels = <Collection<string, StoreChannel>>channels.filter(c => c.type === "GUILD_STORE");
return storeChannels.size ? storeChannels : null;
},
[ArgumentTypes.TEXT_BASED_CHANNEL]: (message, phrase) => {
if (!phrase || !message.inGuild()) return null;
[ArgumentTypes.STAGE_CHANNEL]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel?.isTextBased()) return null;
if (!channel || channel.type !== "GUILD_STAGE_VOICE") return null;

@@ -315,15 +338,17 @@ return channel;

[ArgumentTypes.TEXT_BASED_CHANNELS]: (message, phrase) => {
if (!phrase || !message.inGuild()) return null;
[ArgumentTypes.STAGE_CHANNELS]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
const threadChannels = <Collection<Snowflake, TextBasedChannel>>channels.filter(c => c.isTextBased());
return threadChannels.size ? threadChannels : null;
const storeChannels = <Collection<string, StageChannel>>channels.filter(c => c.type === "GUILD_STAGE_VOICE");
return storeChannels.size ? storeChannels : null;
},
[ArgumentTypes.VOICE_BASED_CHANNEL]: (message, phrase) => {
if (!phrase || !message.inGuild()) return null;
[ArgumentTypes.THREAD_CHANNEL]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channel = this.client.util.resolveChannel(phrase, message.guild.channels.cache);
if (!channel?.isVoiceBased()) return null;
if (!channel || !channel.isThread()) return null;

@@ -333,9 +358,10 @@ return channel;

[ArgumentTypes.VOICE_BASED_CHANNELS]: (message, phrase) => {
if (!phrase || !message.inGuild()) return null;
[ArgumentTypes.THREAD_CHANNELS]: (message, phrase) => {
if (!phrase) return null;
if (!message.inGuild()) return null;
const channels = this.client.util.resolveChannels(phrase, message.guild.channels.cache);
if (!channels.size) return null;
const threadChannels = <Collection<Snowflake, VoiceBasedChannel>>channels.filter(c => c.isVoiceBased());
return threadChannels.size ? threadChannels : null;
const storeChannels = <Collection<string, ThreadChannel>>channels.filter(c => c.isThread());
return storeChannels.size ? storeChannels : null;
},

@@ -393,3 +419,3 @@

for (const channel of message.guild.channels.cache.values()) {
if (!channel.isTextBased()) continue;
if (!channel.isText()) continue;
try {

@@ -414,3 +440,3 @@ return await channel.messages.fetch(phrase);

for (const channel of message.guild.channels.cache.values()) {
if (!channel.isTextBased()) continue;
if (!channel.isText()) continue;
try {

@@ -417,0 +443,0 @@ return await channel.messages.fetch(phrase);

@@ -1,3 +0,3 @@

/* eslint-disable @typescript-eslint/no-unused-vars */
import type {
/* eslint-disable func-names, @typescript-eslint/no-unused-vars */
import {
ApplicationCommandAutocompleteOption,

@@ -9,6 +9,7 @@ ApplicationCommandChannelOptionData,

ApplicationCommandOptionType,
ApplicationCommandPermissionData,
ApplicationCommandSubCommandData,
ApplicationCommandSubGroupData,
AutocompleteInteraction,
LocalizationMap,
Guild,
Message,

@@ -18,15 +19,13 @@ PermissionResolvable,

} from "discord.js";
import { AkairoError } from "../../util/AkairoError.js";
import type { AkairoMessage } from "../../util/AkairoMessage.js";
import { isArrayOf, isStringArrayStringOrFunc, patchAbstract } from "../../util/Util.js";
import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
import {
Argument,
type ArgumentOptions,
type ArgumentTypeCasterReturn,
type DefaultArgumentOptions
} from "./arguments/Argument.js";
import { ArgumentRunner, type ArgumentRunnerState } from "./arguments/ArgumentRunner.js";
import type { CommandHandler, IgnoreCheckPredicate, PrefixSupplier, SlashResolveType } from "./CommandHandler.js";
import { ContentParser, type ContentParserResult } from "./ContentParser.js";
import type { Flag } from "./Flag.js";
import type { Category } from "../../util/Category.js";
import { isStringArrayStringOrFunc, Util } from "../../util/Util.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import { Argument, ArgumentOptions, ArgumentTypeCasterReturn, DefaultArgumentOptions } from "./arguments/Argument.js";
import { ArgumentRunner, ArgumentRunnerState } from "./arguments/ArgumentRunner.js";
import { CommandHandler, IgnoreCheckPredicate, PrefixSupplier, SlashResolveType } from "./CommandHandler.js";
import { ContentParser, ContentParserResult } from "./ContentParser.js";
import { Flag } from "./Flag.js";

@@ -36,3 +35,3 @@ /**

*/
export abstract class Command extends AkairoModule<CommandHandler, Command> {
export abstract class Command extends AkairoModule {
/**

@@ -59,2 +58,7 @@ * Command names.

/**
* Category the command belongs to.
*/
public declare category: Category<string, Command>;
/**
* Usable only in this channel type.

@@ -65,5 +69,10 @@ */

/**
* The Akairo client.
*/
public declare client: AkairoClient;
/**
* Permissions required to run command by the client.
*/
public declare clientPermissions?: PermissionResolvable | MissingPermissionSupplier;
public declare clientPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;

@@ -91,2 +100,17 @@ /**

/**
* The filepath.
*/
public declare filepath: string;
/**
* The handler.
*/
public declare handler: CommandHandler;
/**
* The ID of the command.
*/
public declare id: string;
/**
* ID of user(s) to ignore cooldown or a function to ignore.

@@ -102,10 +126,5 @@ */

/**
* The slash command localizations.
*/
public declare localization: CommandLocalization;
/**
* The key supplier for the locker.
*/
public declare lock?: KeySupplier;
public declare lock?: KeySupplier | "channel" | "guild" | "user";

@@ -153,12 +172,7 @@ /**

/**
* The default bitfield used to determine whether this command be used in a guild
*/
public declare slashDefaultMemberPermissions?: PermissionResolvable;
/**
* Whether the command is enabled in DMs
* The default permission to set when creating the slash command.
*
* **Cannot be enabled for commands that specify `slashGuilds`**
* **Note:** Requires the useSlashPermissions to be enabled in the command handler
*/
public declare slashDmPermission?: boolean;
public declare slashDefaultPermission: boolean;

@@ -181,2 +195,7 @@ /**

/**
* The slash permissions to set in each guild for this command.
*/
public declare slashPermissions?: ApplicationCommandPermissionData[] | SlashPermissionsSupplier;
/**
* Only allows this command to be executed as a slash command.

@@ -199,3 +218,3 @@ */

*/
public declare userPermissions?: PermissionResolvable | MissingPermissionSupplier;
public declare userPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;

@@ -229,3 +248,2 @@ /**

ignorePermissions,
localization = {},
lock,

@@ -241,2 +259,3 @@ onlyNsfw = false,

slash = false,
slashDefaultPermission,
slashEphemeral = false,

@@ -246,2 +265,3 @@ slashGuilds = [],

slashOptions,
slashPermissions,
superUserOnly = false,

@@ -252,10 +272,4 @@ typing = false,

// ts doesn't like it when I reference other properties when using destructuring syntax
const {
slashDefaultMemberPermissions = userPermissions && typeof userPermissions !== "function" ? userPermissions : undefined,
slashDmPermission = slashGuilds.length > 0 ? channel === null || channel === "dm" : undefined
} = options ?? {};
if (!isArrayOf(aliases, "string")) throw new TypeError("options.aliases must be an array of strings.");
if (typeof args !== "function" && !isArrayOf(args, "object"))
if (!Util.isArrayOf(aliases, "string")) throw new TypeError("options.aliases must be an array of strings.");
if (typeof args !== "function" && !Util.isArrayOf(args, "object"))
throw new TypeError("options.args must be an array of argument objects or a function.");

@@ -269,3 +283,3 @@ if (typeof argumentDefaults !== "object") throw new TypeError("options.argumentDefaults must be an object.");

if (typeof editable !== "boolean") throw new TypeError("options.editable must be a boolean.");
if (!isArrayOf(flags, "string")) throw new TypeError("options.flags must be an array of strings.");
if (!Util.isArrayOf(flags, "string")) throw new TypeError("options.flags must be an array of strings.");
if (ignoreCooldown !== undefined && !isStringArrayStringOrFunc(ignoreCooldown))

@@ -275,7 +289,6 @@ throw new TypeError("options.ignoreCooldown must be a string, function, or array of strings.");

throw new TypeError("options.ignorePermissions must be a string, function, or array of strings.");
if (typeof localization !== "object") throw new TypeError("options.localization must be an object.");
if (lock !== undefined && typeof lock !== "function" && !(["channel", "guild", "user"] as const).includes(lock))
throw new TypeError("options.lock must be a function or a string with a value of 'channel', 'guild', or 'user'.");
if (typeof onlyNsfw !== "boolean") throw new TypeError("options.onlyNsfw must be a boolean.");
if (!isArrayOf(optionFlags, "string")) throw new TypeError("options.optionFlags must be an array of strings.");
if (!Util.isArrayOf(optionFlags, "string")) throw new TypeError("options.optionFlags must be an array of strings.");
if (typeof ownerOnly !== "boolean") throw new TypeError("options.ownerOnly must be a boolean.");

@@ -290,11 +303,11 @@ if (prefix !== undefined && !isStringArrayStringOrFunc(prefix))

if (typeof slash !== "boolean") throw new TypeError("options.slash must be a boolean.");
if (slashDmPermission !== undefined && typeof slashDmPermission !== "boolean")
throw new TypeError("options.slashDmPermission must be a boolean.");
if (typeof slashDmPermission !== "boolean" && slashGuilds.length > 0)
throw new TypeError("You cannot set `options.slashDmPermission` with commands configured with `options.slashGuilds`.");
if (slashDefaultPermission && typeof slashDefaultPermission !== "boolean")
throw new TypeError("options.slashDefaultPermission must be a boolean.");
if (typeof slashEphemeral !== "boolean") throw new TypeError("options.slashEphemeral must be a boolean.");
if (!isArrayOf(slashGuilds, "string")) throw new TypeError("options.slashGuilds must be an array of strings.");
if (!Util.isArrayOf(slashGuilds, "string")) throw new TypeError("options.slashGuilds must be an array of strings.");
if (typeof slashOnly !== "boolean") throw new TypeError("options.slashOnly must be a boolean.");
if (slashOptions !== undefined && !isArrayOf(slashOptions, "object"))
if (slashOptions !== undefined && !Util.isArrayOf(slashOptions, "object"))
throw new TypeError("options.slashOptions must be an array of objects.");
if (slashPermissions !== undefined && typeof slashPermissions !== "function" && !Util.isArrayOf(slashPermissions, "object"))
throw new TypeError("options.slashPermissions must be an array of objects or a function.");
if (typeof superUserOnly !== "boolean") throw new TypeError("options.superUserOnly must be a boolean.");

@@ -325,3 +338,3 @@ if (typeof typing !== "boolean") throw new TypeError("options.typing must be a boolean.");

this.editable = Boolean(editable);
this.localization = <CommandLocalization>localization;
this.lock = lock;
this.onlyNsfw = Boolean(onlyNsfw);

@@ -335,10 +348,9 @@ this.ownerOnly = Boolean(ownerOnly);

this.userPermissions = typeof userPermissions === "function" ? userPermissions.bind(this) : userPermissions;
this.lock =
typeof lock === "string"
? {
guild: (message: Message | AkairoMessage): string => message.guild! && message.guild.id!,
channel: (message: Message | AkairoMessage): string => message.channel!.id,
user: (message: Message | AkairoMessage): string => message.author.id
}[lock]
: lock;
if (typeof lock === "string") {
this.lock = {
guild: (message: Message | AkairoMessage): string => message.guild! && message.guild.id!,
channel: (message: Message | AkairoMessage): string => message.channel!.id,
user: (message: Message | AkairoMessage): string => message.author.id
}[lock];
}
if (this.lock) this.locker = new Set();

@@ -348,4 +360,3 @@ this.ignoreCooldown = typeof ignoreCooldown === "function" ? ignoreCooldown.bind(this) : ignoreCooldown;

this.slash = slash;
this.slashDefaultMemberPermissions = slashDefaultMemberPermissions;
this.slashDmPermission = slashDmPermission;
this.slashDefaultPermission = slashDefaultPermission!;
this.slashEphemeral = slashEphemeral;

@@ -355,2 +366,3 @@ this.slashGuilds = slashGuilds;

this.slashOptions = slashOptions;
this.slashPermissions = typeof slashPermissions === "function" ? slashPermissions.bind(this) : slashPermissions;
}

@@ -365,3 +377,2 @@

* @param state - Argument processing state.
* @abstract
*/

@@ -374,3 +385,2 @@ // @ts-expect-error

* @param message - Message being handled.
* @abstract
*/

@@ -382,3 +392,2 @@ public before(message: Message): any {}

* @param message - Message being handled.
* @abstract
*/

@@ -393,6 +402,8 @@ public condition(message: Message): boolean | Promise<boolean> {

* @param args - Evaluated arguments.
* @abstract
*/
public exec?(message: Message, args: any): any;
public exec?(message: Message | AkairoMessage, args: any): any;
public exec(message: Message, args: any): any;
public exec(message: Message | AkairoMessage, args: any): any;
public exec(message: Message | AkairoMessage, args: any): any {
throw new AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}

@@ -403,5 +414,6 @@ /**

* @param args - Slash command options
* @abstract
*/
public execSlash?(message: AkairoMessage, ...args: any[]): any;
public execSlash(message: AkairoMessage, ...args: any[]): any {
throw new AkairoError("NOT_IMPLEMENTED", this.constructor.name, "execSlash");
}

@@ -411,5 +423,4 @@ /**

* @param interaction The autocomplete interaction
* @abstract
*/
public autocomplete?(interaction: AutocompleteInteraction): any;
public autocomplete(interaction: AutocompleteInteraction): any {}

@@ -427,6 +438,14 @@ /**

patchAbstract(Command, "exec");
patchAbstract(Command, "execSlash");
patchAbstract(Command, "autocomplete");
export interface Command extends AkairoModule {
/**
* Reloads the command.
*/
reload(): Promise<Command>;
/**
* Removes the command.
*/
remove(): Command;
}
/**

@@ -470,3 +489,3 @@ * Options to use for command execution behavior.

*/
clientPermissions?: PermissionResolvable | MissingPermissionSupplier;
clientPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;

@@ -514,7 +533,2 @@ /**

/**
* The slash command localizations.
*/
localization?: CommandLocalization;
/**
* The key type or key generator for the locker. If lock is a string, it's expected one of 'guild', 'channel', or 'user'

@@ -578,15 +592,8 @@ */

/**
* The default bitfield used to determine whether this command be used in a guild
* @default typeof this.userPermissions !== "function" ? this.userPermissions : undefined
*/
slashDefaultMemberPermissions?: PermissionResolvable;
/**
* Whether the command is enabled in DMs
* The default permission to set when creating the slash command.
*
* **Cannot be enabled for commands that specify `slashGuilds`**
*
* @default this.channel === 'dm'
* **Note:** Requires `useSlashPermissions` to be enabled in the command handler
* @default this.handler.useSlashPermissions ? !this.ownerOnly : true
*/
slashDmPermission?: boolean;
slashDefaultPermission?: boolean;

@@ -611,2 +618,7 @@ /**

/**
* The slash permissions to set in each guild for this command.
*/
slashPermissions?: ApplicationCommandPermissionData[] | SlashPermissionsSupplier;
/**
* Only allow this command to be used as a slash command. Also makes `slash` `true`

@@ -632,3 +644,3 @@ */

*/
userPermissions?: PermissionResolvable | MissingPermissionSupplier;
userPermissions?: PermissionResolvable | PermissionResolvable[] | MissingPermissionSupplier;
}

@@ -663,2 +675,8 @@

/**
* A function used to create slash permissions depending on the guild.
* @param guild The guild to create slash permissions for.
*/
export type SlashPermissionsSupplier = (guild: Guild) => ApplicationCommandPermissionData[];
/**
* A function used to return a regular expression.

@@ -765,19 +783,4 @@ * @param message - Message to get regex for.

/**
* The localization for slash commands.
*
* @example
* const localization = {
* nameLocalizations: {
* ["en-US"]: "command name",
* },
* descriptionLocalizations: {
* ["en-US"]: "command description",
* },
* }
*/
export type CommandLocalization = Record<"nameLocalizations" | "descriptionLocalizations", LocalizationMap>;
/**
* @typedef {ApplicationCommandOptionType} VSCodePleaseStopRemovingMyImports
* @internal
*/
import {
ApplicationCommandOptionType,
ApplicationCommandType,
ApplicationCommand,
ApplicationCommandData,
ApplicationCommandOptionData,
AutocompleteInteraction,
Awaitable,
Collection,
CommandInteraction,
CommandInteractionOption,
CommandInteractionOptionResolver,
DiscordAPIError,
InteractionType,
type ApplicationCommandData,
type ApplicationCommandOptionData,
type AutocompleteInteraction,
type Awaitable,
type ChatInputCommandInteraction,
type CommandInteractionOption,
type CommandInteractionOptionResolver,
type Guild,
type Message,
type Snowflake,
type TextBasedChannel,
type User
Guild,
GuildApplicationCommandPermissionData,
GuildResolvable,
Message,
Snowflake,
TextBasedChannel,
User
} from "discord.js";
import type { CommandHandlerEvents as CommandHandlerEventsType } from "../../typings/events.js";
import { ApplicationCommandOptionTypes, ApplicationCommandTypes } from "discord.js/typings/enums";
import type { CommandHandlerEvents as CommandHandlerEventsType } from "../../typings/events";
import { AkairoError } from "../../util/AkairoError.js";
import { AkairoMessage } from "../../util/AkairoMessage.js";
import type { Category } from "../../util/Category.js";
import { BuiltInReasons, CommandHandlerEvents } from "../../util/Constants.js";
import {
deepAssign,
deepEquals,
intoArray,
intoCallable,
isPromise,
isStringArrayStringOrFunc,
prefixCompare
} from "../../util/Util.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import { isStringArrayStringOrFunc, Util } from "../../util/Util.js";
import { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import type { AkairoModule } from "../AkairoModule.js";
import { ContextMenuCommandHandler } from "../contextMenuCommands/ContextMenuCommandHandler.js";

@@ -42,9 +37,9 @@ import type { InhibitorHandler } from "../inhibitors/InhibitorHandler.js";

import {
AkairoApplicationCommandChannelOptionData,
AkairoApplicationCommandChoicesData,
AkairoApplicationCommandNonOptionsData,
AkairoApplicationCommandSubCommandData,
AkairoApplicationCommandSubGroupData,
Command,
type AkairoApplicationCommandChannelOptionData,
type AkairoApplicationCommandChoicesData,
type AkairoApplicationCommandNonOptionsData,
type AkairoApplicationCommandSubCommandData,
type AkairoApplicationCommandSubGroupData,
type KeySupplier
KeySupplier
} from "./Command";

@@ -57,3 +52,3 @@ import { CommandUtil } from "./CommandUtil.js";

*/
export class CommandHandler extends AkairoHandler<Command, CommandHandler> {
export class CommandHandler extends AkairoHandler {
/**

@@ -100,2 +95,17 @@ * Collection of command aliases.

/**
* Categories, mapped by ID to Category.
*/
public declare categories: Collection<string, Category<string, Command>>;
/**
* Class to handle
*/
public declare classToHandle: typeof Command;
/**
* The Akairo client.
*/
public declare client: AkairoClient;
/**
* Whether or not `message.util` is assigned.

@@ -133,2 +143,7 @@ */

/**
* Directory to commands.
*/
public declare directory: string;
/**
* Whether or not to require the use of execSlash for slash commands.

@@ -164,2 +179,7 @@ */

/**
* Commands loaded, mapped by ID to Command.
*/
public declare modules: Collection<string, Command>;
/**
* The prefix(es) for command parsing.

@@ -199,8 +219,8 @@ */

// /**
// * Use slash command permissions for owner only commands
// *
// * Warning: this is experimental
// */
// public declare useSlashPermissions: boolean;
/**
* Use slash command permissions for owner only commands
*
* Warning: this is experimental
*/
public declare useSlashPermissions: boolean;

@@ -238,4 +258,4 @@ /**

execSlash = false,
skipBuiltInPostInhibitors = false
// useSlashPermissions = false
skipBuiltInPostInhibitors = false,
useSlashPermissions = false
} = options ?? {};

@@ -273,3 +293,3 @@

throw new TypeError("options.skipBuiltInPostInhibitors must be a boolean.");
// if (typeof useSlashPermissions !== "boolean") throw new TypeError("options.useSlashPermissions must be a boolean.");
if (typeof useSlashPermissions !== "boolean") throw new TypeError("options.useSlashPermissions must be a boolean.");

@@ -307,3 +327,3 @@ super(client, {

this.prompts = new Collection();
this.argumentDefaults = deepAssign(
this.argumentDefaults = Util.deepAssign(
{

@@ -333,4 +353,4 @@ prompt: {

this.execSlash = Boolean(execSlash);
// this.skipBuiltInPostInhibitors = Boolean(skipBuiltInPostInhibitors);
// this.useSlashPermissions = Boolean(useSlashPermissions);
this.skipBuiltInPostInhibitors = Boolean(skipBuiltInPostInhibitors);
this.useSlashPermissions = Boolean(useSlashPermissions);
this.setup();

@@ -344,6 +364,6 @@ }

this.client.once("ready", () => {
if (this.autoRegisterSlashCommands) this.registerInteractionCommands();
// .then(() => {
// if (this.useSlashPermissions) this.updateInteractionPermissions(this.client.ownerID /* this.client.superUserID */);
// });
if (this.autoRegisterSlashCommands)
this.registerInteractionCommands().then(() => {
if (this.useSlashPermissions) this.updateInteractionPermissions(this.client.ownerID /* this.client.superUserID */);
});

@@ -369,4 +389,4 @@ this.client.on("messageCreate", async m => {

this.client.on("interactionCreate", i => {
if (i.isChatInputCommand()) this.handleSlash(i);
if (i.type === InteractionType.ApplicationCommandAutocomplete) this.handleAutocomplete(i);
if (i.isCommand()) this.handleSlash(i);
if (i.isAutocomplete()) this.handleAutocomplete(i);
});

@@ -409,7 +429,4 @@ });

guilds: data.slashGuilds ?? [],
defaultMemberPermissions: data.slashDefaultMemberPermissions,
dmPermission: data.slashDmPermission,
type: ApplicationCommandType.ChatInput,
nameLocalizations: data.localization.nameLocalizations,
descriptionLocalizations: data.localization.descriptionLocalizations
defaultPermission: data.slashDefaultPermission,
type: ApplicationCommandTypes.CHAT_INPUT
});

@@ -430,6 +447,4 @@ }

guilds: data.guilds ?? [],
defaultMemberPermissions: data.defaultMemberPermissions,
dmPermission: data.dmPermission,
type: data.type,
nameLocalizations: data.nameLocalizations
defaultPermission: this.useSlashPermissions ? !(data.ownerOnly || /* data.superUserOnly || */ false) : true,
type: data.type
});

@@ -444,9 +459,12 @@ }

name: options.name,
description: options.type === ApplicationCommandType.ChatInput ? options.description ?? "" : undefined,
options: options.type === ApplicationCommandType.ChatInput ? options.options ?? [] : undefined,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations: options.type === ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
description:
options.type === ApplicationCommandTypes.CHAT_INPUT || options.type === "CHAT_INPUT"
? options.description ?? ""
: undefined,
options:
options.type === ApplicationCommandTypes.CHAT_INPUT || options.type === "CHAT_INPUT"
? options.options ?? []
: undefined,
defaultPermission: options.defaultPermission,
type: options.type
}))

@@ -459,11 +477,8 @@ .sort((a, b) => {

const currentGlobalCommands = (await this.client.application?.commands.fetch())!
.map(options => ({
name: options.name,
description: options.description,
options: options.options,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations: options.type === ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
.map(value1 => ({
name: value1.name,
description: value1.description,
options: value1.options,
defaultPermission: value1.defaultPermission,
type: value1.type
}))

@@ -476,3 +491,3 @@ .sort((a, b) => {

if (!deepEquals(currentGlobalCommands, slashCommandsApp)) {
if (!Util.deepEquals(currentGlobalCommands, slashCommandsApp)) {
this.client.emit("akairoDebug", "[registerInteractionCommands] Updating global interaction commands.", slashCommandsApp);

@@ -494,10 +509,12 @@ await this.client.application?.commands.set(slashCommandsApp).catch(error => {

name: options.name,
description: options.type === ApplicationCommandType.ChatInput ? options.description ?? "" : undefined,
options: options.type === ApplicationCommandType.ChatInput ? options.options ?? [] : undefined,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations:
options.type === ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
description:
options.type === ApplicationCommandTypes.CHAT_INPUT || options.type === "CHAT_INPUT"
? options.description ?? ""
: undefined,
options:
options.type === ApplicationCommandTypes.CHAT_INPUT || options.type === "CHAT_INPUT"
? options.options ?? []
: undefined,
defaultPermission: options.defaultPermission,
type: options.type
} as ApplicationCommandData

@@ -520,12 +537,8 @@ ]);

const currentGuildCommands = (await guild.commands.fetch())
.map(options => ({
name: options.name,
description: options.description,
options: options.options,
defaultMemberPermissions: options.defaultMemberPermissions,
dmPermission: options.dmPermission,
type: options.type,
nameLocalizations: options.nameLocalizations,
descriptionLocalizations:
options.type === ApplicationCommandType.ChatInput ? options.descriptionLocalizations : undefined
.map(value1 => ({
name: value1.name,
description: value1.description,
options: value1.options,
defaultPermission: value1.defaultPermission,
type: value1.type
}))

@@ -538,3 +551,3 @@ .sort((a, b) => {

if (!deepEquals(currentGuildCommands, sortedCommands)) {
if (!Util.deepEquals(currentGuildCommands, sortedCommands)) {
this.client.emit(

@@ -557,68 +570,68 @@ "akairoDebug",

// /**
// * updates interaction permissions
// */
// protected async updateInteractionPermissions(owners: Snowflake | Snowflake[] /* superUsers: Snowflake | Snowflake[] */) {
// const mapCom = (
// value: ApplicationCommand<{ guild: GuildResolvable }>,
// guild: Guild
// ): GuildApplicationCommandPermissionData => {
// const command = this.modules.find(mod => mod.aliases[0] === value.name);
/**
* updates interaction permissions
*/
protected async updateInteractionPermissions(owners: Snowflake | Snowflake[] /* superUsers: Snowflake | Snowflake[] */) {
const mapCom = (
value: ApplicationCommand<{ guild: GuildResolvable }>,
guild: Guild
): GuildApplicationCommandPermissionData => {
const command = this.modules.find(mod => mod.aliases[0] === value.name);
// if (!command?.slashPermissions) {
// let allowedUsers: string[] = [];
// /* if (command.superUserOnly) allowedUsers.push(...Util.intoArray(superUsers)); */
// if (command?.ownerOnly) allowedUsers.push(...Util.intoArray(owners));
// allowedUsers = [...new Set(allowedUsers)]; // remove duplicates
if (!command?.slashPermissions) {
let allowedUsers: string[] = [];
/* if (command.superUserOnly) allowedUsers.push(...Util.intoArray(superUsers)); */
if (command?.ownerOnly) allowedUsers.push(...Util.intoArray(owners));
allowedUsers = [...new Set(allowedUsers)]; // remove duplicates
// return {
// id: value.id,
// permissions: allowedUsers.map(u => ({
// id: u,
// type: ApplicationCommandPermissionType.User,
// permission: true
// }))
// };
// } else {
// return {
// id: value.id,
// permissions: typeof command.slashPermissions === "function" ? command.slashPermissions(guild) : command.slashPermissions
// };
// }
// };
return {
id: value.id,
permissions: allowedUsers.map(u => ({
id: u,
type: "USER",
permission: true
}))
};
} else {
return {
id: value.id,
permissions: typeof command.slashPermissions === "function" ? command.slashPermissions(guild) : command.slashPermissions
};
}
};
// const globalCommands = (await this.client.application?.commands.fetch())?.filter(value =>
// Boolean(this.modules.find(mod => mod.aliases[0] === value.name))
// );
// const fullPermissions = globalCommands
// ?.filter(value => !value.defaultPermission)
// .filter(value => Boolean(this.modules.find(mod => mod.aliases[0] === value.name)));
const globalCommands = (await this.client.application?.commands.fetch())?.filter(value =>
Boolean(this.modules.find(mod => mod.aliases[0] === value.name))
);
const fullPermissions = globalCommands
?.filter(value => !value.defaultPermission)
.filter(value => Boolean(this.modules.find(mod => mod.aliases[0] === value.name)));
// const promises = this.client.guilds.cache.map(
// /* async */ guild => {
// const perms = new Array(...((fullPermissions ?? new Collection()).map(value => mapCom(value, guild)) ?? []));
// // await guild.commands.fetch();
// if (guild.commands.cache.size)
// perms.push(...guild.commands.cache.filter(value => !value.defaultPermission).map(value => mapCom(value, guild)));
// if (guild.available)
// return guild.commands.permissions.set({
// fullPermissions: perms
// });
// // Return empty promise if guild is unavailable
// return Promise.resolve();
// }
// );
// try {
// await Promise.all(promises);
// } catch (e) {
// this.client.emit(
// "akairoDebug",
// "[updateInteractionPermissions] Error updating interaction permissions, here are the promises, globalCommands, and fullPermissions",
// promises,
// globalCommands,
// fullPermissions
// );
// throw e;
// }
// }
const promises = this.client.guilds.cache.map(
/* async */ guild => {
const perms = new Array(...((fullPermissions ?? new Collection()).map(value => mapCom(value, guild)) ?? []));
// await guild.commands.fetch();
if (guild.commands.cache.size)
perms.push(...guild.commands.cache.filter(value => !value.defaultPermission).map(value => mapCom(value, guild)));
if (guild.available)
return guild.commands.permissions.set({
fullPermissions: perms
});
// Return empty promise if guild is unavailable
return Promise.resolve();
}
);
try {
await Promise.all(promises);
} catch (e) {
this.client.emit(
"akairoDebug",
"[updateInteractionPermissions] Error updating interaction permissions, here are the promises, globalCommands, and fullPermissions",
promises,
globalCommands,
fullPermissions
);
throw e;
}
}

@@ -633,4 +646,4 @@ /**

// if (command.slashDefaultPermission === undefined)
// command.slashDefaultPermission = this.useSlashPermissions ? !command.ownerOnly : true;
if (command.slashDefaultPermission === undefined)
command.slashDefaultPermission = this.useSlashPermissions ? !command.ownerOnly : true;

@@ -678,3 +691,3 @@ for (let alias of command.aliases) {

if (newEntry) {
this.prefixes = this.prefixes.sort((aVal, bVal, aKey, bKey) => prefixCompare(aKey, bKey));
this.prefixes = this.prefixes.sort((aVal, bVal, aKey, bKey) => Util.prefixCompare(aKey, bKey));
}

@@ -790,3 +803,3 @@ }

// eslint-disable-next-line complexity
public async handleSlash(interaction: ChatInputCommandInteraction): Promise<boolean | null> {
public async handleSlash(interaction: CommandInteraction): Promise<boolean | null> {
const commandModule = this.findCommand(interaction.commandName);

@@ -845,10 +858,8 @@

for (const option of (interaction.options as CommandInteractionOptionResolver)["_hoistedOptions"]) {
if (
option.type === ApplicationCommandOptionType.Subcommand ||
option.type === ApplicationCommandOptionType.SubcommandGroup
)
continue;
if (option.type === "SUB_COMMAND" || option.type === "SUB_COMMAND_GROUP") continue;
const originalOption = commandModule.slashOptions?.find(o => o.name === option.name);
const func = `get${originalOption?.resolve ?? (ApplicationCommandOptionType[option.type] as SlashResolveType)}` as const;
const func = `get${
originalOption?.resolve ?? [option.type.charAt(0) + Util.snakeToCamelCase(option.type.substring(1))]
}` as GetFunction;
if (

@@ -870,3 +881,3 @@ !(

)
throw new Error(`Unknown slash option type: ${option.type}`);
throw new Error(`${func} is not a valid get function.`);
convertedOptions[option.name] = interaction.options[func](option.name, false);

@@ -876,3 +887,3 @@ }

// Makes options that are not found to be null so that it matches the behavior normal commands.
out: {
(() => {
type SubCommand = AkairoApplicationCommandSubCommandData;

@@ -889,11 +900,17 @@ type SubCommandGroup = AkairoApplicationCommandSubGroupData;

this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand");
break out;
return;
}
if (usedSubcommandOrGroup.type === ApplicationCommandOptionType.Subcommand) {
if (
usedSubcommandOrGroup.type === "SUB_COMMAND" ||
usedSubcommandOrGroup.type === ApplicationCommandOptionTypes.SUB_COMMAND
) {
if (!(<SubCommand>usedSubcommandOrGroup).options) {
this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand options");
break out;
return;
}
handleOptions((<SubCommand>usedSubcommandOrGroup).options!);
} else if (usedSubcommandOrGroup.type === ApplicationCommandOptionType.SubcommandGroup) {
} else if (
usedSubcommandOrGroup.type === "SUB_COMMAND_GROUP" ||
usedSubcommandOrGroup.type === ApplicationCommandOptionTypes.SUB_COMMAND_GROUP
) {
const usedSubCommand = (<SubCommandGroup>usedSubcommandOrGroup).options?.find(

@@ -904,6 +921,6 @@ subcommand => subcommand.name === convertedOptions.subcommand

this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand");
break out;
return;
} else if (!usedSubCommand.options) {
this.client.emit("akairoDebug", "[handleSlash] Unable to find subcommand options");
break out;
return;
}

@@ -919,21 +936,26 @@

// eslint-disable-next-line no-inner-declarations
function handleOptions(options: NonSubSlashOptions[]) {
for (const option of options) {
switch (option.type) {
case ApplicationCommandOptionType.Boolean:
case ApplicationCommandOptionTypes.BOOLEAN:
case "BOOLEAN":
convertedOptions[option.name] ??= false;
break;
case ApplicationCommandOptionType.Channel:
case ApplicationCommandOptionType.Integer:
case ApplicationCommandOptionType.Mentionable:
case ApplicationCommandOptionType.Number:
case ApplicationCommandOptionType.Role:
case ApplicationCommandOptionType.String:
case ApplicationCommandOptionType.User:
case ApplicationCommandOptionType.Attachment:
convertedOptions[option.name] ??= null;
break;
case ApplicationCommandOptionTypes.CHANNEL:
case "CHANNEL":
case ApplicationCommandOptionTypes.INTEGER:
case "INTEGER":
case ApplicationCommandOptionTypes.MENTIONABLE:
case "MENTIONABLE":
case ApplicationCommandOptionTypes.NUMBER:
case "NUMBER":
case ApplicationCommandOptionTypes.ROLE:
case "ROLE":
case ApplicationCommandOptionTypes.STRING:
case "STRING":
case ApplicationCommandOptionTypes.USER:
case "USER":
case ApplicationCommandOptionTypes.ATTACHMENT:
case "ATTACHMENT":
default:
// @ts-expect-error
convertedOptions[option.name] ??= null;

@@ -944,3 +966,3 @@ break;

}
}
})();

@@ -950,3 +972,3 @@ let key;

if (commandModule.lock) key = (commandModule.lock as KeySupplier)(message, convertedOptions);
if (isPromise(key)) key = await key;
if (Util.isPromise(key)) key = await key;
if (key) {

@@ -974,4 +996,4 @@ if (commandModule.locker?.has(key)) {

Object.getOwnPropertyNames(Object.getPrototypeOf(commandModule)).includes("execSlash") || this.execSlash
? await commandModule.execSlash!(message, convertedOptions)
: await commandModule.exec!(message, convertedOptions);
? await commandModule.execSlash(message, convertedOptions)
: await commandModule.exec(message, convertedOptions);
this.emit(CommandHandlerEvents.SLASH_FINISHED, message, commandModule, convertedOptions, ret);

@@ -1002,3 +1024,3 @@ return true;

this.client.emit("akairoDebug", `[handleAutocomplete] Autocomplete started for ${interaction.commandName}`);
commandModule.autocomplete!(interaction);
commandModule.autocomplete(interaction);
}

@@ -1026,3 +1048,3 @@

const before = command.before(message);
if (isPromise(before)) await before;
if (Util.isPromise(before)) await before;

@@ -1033,5 +1055,2 @@ const args = await command.parse(message, content);

return true;
} else if (Flag.is(args, FlagType.Timeout)) {
this.emit(CommandHandlerEvents.COMMAND_TIMEOUT, message, command, args.time);
return true;
} else if (Flag.is(args, FlagType.Retry)) {

@@ -1047,3 +1066,3 @@ this.emit(CommandHandlerEvents.COMMAND_BREAKOUT, message, command, args.message);

if (command.lock) key = (command.lock as KeySupplier)(message, args);
if (isPromise(key)) key = await key;
if (Util.isPromise(key)) key = await key;
if (key) {

@@ -1098,6 +1117,6 @@ if (command.locker?.has(key)) {

const matches: RegExpExecArray[] = [];
const matches = [];
if (entry.regex.global) {
let matched: RegExpExecArray | null;
let matched;

@@ -1124,3 +1143,3 @@ while ((matched = entry.regex.exec(message.content)) != null) {

const before = command.before(message);
if (isPromise(before)) await before;
if (Util.isPromise(before)) await before;

@@ -1152,3 +1171,3 @@ await this.runCommand(message, command, { match, matches });

let cond = command.condition(message);
if (isPromise(cond)) cond = await cond;
if (Util.isPromise(cond)) cond = await cond;
if (cond) trueCommands.push(command);

@@ -1172,3 +1191,3 @@ })()

const before = command.before(message);
if (isPromise(before)) await before;
if (Util.isPromise(before)) await before;
await this.runCommand(message, command, {});

@@ -1310,3 +1329,3 @@ } catch (err) {

let missing = command.clientPermissions(message);
if (isPromise(missing)) missing = await missing;
if (Util.isPromise(missing)) missing = await missing;

@@ -1317,5 +1336,5 @@ if (missing != null) {

}
} else if (message.inGuild()) {
if (!message.channel || message.channel.isDMBased()) return false;
const missing = message.channel?.permissionsFor(message.guild.members.me!)?.missing(command.clientPermissions);
} else if (message.guild) {
if (message.channel?.type === "DM") return false;
const missing = message.channel?.permissionsFor(message.guild.me!)?.missing(command.clientPermissions);
if (missing?.length) {

@@ -1339,3 +1358,3 @@ this.emit(event, message, command, "client", missing);

let missing = command.userPermissions(message);
if (isPromise(missing)) missing = await missing;
if (Util.isPromise(missing)) missing = await missing;

@@ -1346,4 +1365,4 @@ if (missing != null) {

}
} else if (message.inGuild()) {
if (!message.channel || message.channel.isDMBased()) return false;
} else if (message.guild) {
if (message.channel?.type === "DM") return false;
const missing = message.channel?.permissionsFor(message.author)?.missing(command.userPermissions);

@@ -1435,3 +1454,3 @@ if (missing?.length) {

this.emit(CommandHandlerEvents.COMMAND_STARTED, message, command, args);
const ret = await command.exec!(message, args);
const ret = await command.exec(message, args);
this.emit(CommandHandlerEvents.COMMAND_FINISHED, message, command, args, ret);

@@ -1448,4 +1467,4 @@ } finally {

public async parseCommand(message: Message | AkairoMessage): Promise<ParsedComponentData> {
const allowMention = await intoCallable(this.prefix)(message);
let prefixes = intoArray(allowMention);
const allowMention = await Util.intoCallable(this.prefix)(message);
let prefixes = Util.intoArray(allowMention);
if (allowMention) {

@@ -1456,3 +1475,3 @@ const mentions = [`<@${this.client.user?.id}>`, `<@!${this.client.user?.id}>`];

prefixes.sort(prefixCompare);
prefixes.sort(Util.prefixCompare);
return this.parseMultiplePrefixes(

@@ -1474,3 +1493,3 @@ message,

const promises = this.prefixes.map(async (cmds, provider) => {
const prefixes = intoArray(await intoCallable(provider)(message));
const prefixes = Util.intoArray(await Util.intoCallable(provider)(message));
return prefixes.map(p => [p, cmds]);

@@ -1480,3 +1499,3 @@ });

const pairs = (await Promise.all(promises)).flatMap(x => x, 1);
pairs.sort(([a]: any, [b]: any) => prefixCompare(a, b));
pairs.sort(([a]: any, [b]: any) => Util.prefixCompare(a, b));
return this.parseMultiplePrefixes(message, pairs as [string, Set<string>][]);

@@ -1550,3 +1569,3 @@ }

*/
public emitError(err: Error, message: Message | AkairoMessage, command?: Command): void {
public emitError(err: Error, message: Message | AkairoMessage, command?: Command | AkairoModule): void {
if (this.listenerCount(CommandHandlerEvents.ERROR)) {

@@ -1665,3 +1684,38 @@ this.emit(CommandHandlerEvents.ERROR, err, message, command);

export interface CommandHandler extends AkairoHandler<Command, CommandHandler> {
export interface CommandHandler extends AkairoHandler {
/**
* Loads a command.
* @param thing - Module or path to module.
*/
load(thing: string | Command): Promise<Command>;
/**
* Reads all commands from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<CommandHandler>;
/**
* Removes a command.
* @param id - ID of the command.
*/
remove(id: string): Command;
/**
* Removes all commands.
*/
removeAll(): CommandHandler;
/**
* Reloads a command.
* @param id - ID of the command.
*/
reload(id: string): Promise<Command>;
/**
* Reloads all commands.
*/
reloadAll(): Promise<CommandHandler>;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;

@@ -1691,3 +1745,3 @@ once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;

export interface CommandHandlerOptions extends AkairoHandlerOptions<Command, CommandHandler> {
export interface CommandHandlerOptions extends AkairoHandlerOptions {
/**

@@ -1814,9 +1868,9 @@ * Regular expression to automatically make command aliases.

// /**
// * Use slash command permissions for owner only commands
// *
// * Warning: this is experimental
// * @default false
// */
// useSlashPermissions?: boolean;
/**
* Use slash command permissions for owner only commands
*
* Warning: this is experimental
* @default false
*/
useSlashPermissions?: boolean;
}

@@ -1894,15 +1948,20 @@

const slashResolvable = [
"Attachment",
"Boolean",
"Channel",
"String",
"Integer",
"Number",
"User",
"Member",
"Role",
"Mentionable",
"Number",
"Role",
"String",
"User"
"Attachment"
] as const;
export type SlashResolveType = typeof slashResolvable[number];
/**
* Calls the corresponding get function on the {@link CommandInteractionOptionResolver}
*/
type GetFunction = `get${SlashResolveType}`;
type ConvertedOptionsType = {

@@ -1922,6 +1981,1 @@ [key: string]:

};
/**
* @typedef {CommandInteractionOptionResolver} VSCodePleaseStopRemovingMyImports
* @internal
*/

@@ -0,15 +1,17 @@

/* eslint-disable require-await */
import { APIMessage } from "discord-api-types/v9";
import {
Collection,
InteractionReplyOptions,
Message,
MessageEditOptions,
MessageOptions,
MessagePayload,
type InteractionReplyOptions,
type Message,
type MessageEditOptions,
type MessageOptions,
type ReplyMessageOptions,
type Snowflake,
type WebhookEditMessageOptions
ReplyMessageOptions,
Snowflake,
WebhookEditMessageOptions
} from "discord.js";
import { AkairoMessage } from "../../util/AkairoMessage.js";
import type { ContextMenuCommandHandler } from "../contextMenuCommands/ContextMenuCommandHandler.js";
import { CommandHandler, type ParsedComponentData } from "./CommandHandler.js";
import { CommandHandler, ParsedComponentData } from "./CommandHandler.js";

@@ -115,8 +117,10 @@ /**

public async edit(options: string | MessageEditOptions | MessagePayload): Promise<Message>;
public async edit(options: string | WebhookEditMessageOptions | MessagePayload): Promise<Message>;
public async edit(options: string | WebhookEditMessageOptions | WebhookEditMessageOptions | MessagePayload): Promise<Message> {
public async edit(options: string | WebhookEditMessageOptions | MessagePayload): Promise<Message | APIMessage>;
public async edit(
options: string | WebhookEditMessageOptions | WebhookEditMessageOptions | MessagePayload
): Promise<Message | APIMessage> {
if (!this.isSlashMessage(this.message)) {
return await this.lastResponse!.edit(options);
return this.lastResponse!.edit(options);
} else {
return await this.message.interaction.editReply(options);
return this.message.interaction.editReply(options);
}

@@ -131,4 +135,6 @@ }

public async reply(options: string | MessagePayload | ReplyMessageOptions): Promise<Message>;
public async reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
public async reply(options: string | MessagePayload | ReplyMessageOptions | InteractionReplyOptions): Promise<Message> {
public async reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage>;
public async reply(
options: string | MessagePayload | ReplyMessageOptions | InteractionReplyOptions
): Promise<Message | APIMessage> {
const newOptions = (typeof options === "string" ? { content: options } : options) as ReplyMessageOptions;

@@ -142,3 +148,3 @@

}
return await this.send(newOptions);
return this.send(newOptions);
}

@@ -151,4 +157,4 @@

public async send(options: string | MessagePayload | MessageOptions): Promise<Message>;
public async send(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
public async send(options: string | MessagePayload | MessageOptions | InteractionReplyOptions): Promise<Message> {
public async send(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage>;
public async send(options: string | MessagePayload | MessageOptions | InteractionReplyOptions): Promise<Message | APIMessage> {
const hasFiles = typeof options === "string" || !options.files?.length ? false : options.files?.length > 0;

@@ -164,3 +170,3 @@ const newOptions = typeof options === "string" ? { content: options } : options;

) {
return await this.lastResponse!.edit(newOptions as MessageEditOptions);
return this.lastResponse!.edit(newOptions as MessageEditOptions);
}

@@ -193,4 +199,6 @@ const sent = await this.message.channel?.send(newOptions as MessageOptions);

public async sendNew(options: string | MessagePayload | MessageOptions): Promise<Message>;
public async sendNew(options: string | MessagePayload | InteractionReplyOptions): Promise<Message>;
public async sendNew(options: string | MessagePayload | MessageOptions | InteractionReplyOptions): Promise<Message> {
public async sendNew(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage>;
public async sendNew(
options: string | MessagePayload | MessageOptions | InteractionReplyOptions
): Promise<Message | APIMessage> {
if (!this.isSlashMessage(this.message)) {

@@ -237,7 +245,7 @@ const sent = await this.message.channel?.send(options as string | MessagePayload | MessageOptions);

if (this.isSlashMessage(this.message)) {
return await this.message.interaction.deleteReply();
return this.message.interaction.deleteReply();
} else {
return await this.lastResponse?.delete();
return this.lastResponse?.delete();
}
}
}
import { ArgumentMatches } from "../../util/Constants.js";
import { isArrayOf } from "../../util/Util.js";
import { Util } from "../../util/Util.js";
import type { ArgumentOptions } from "./arguments/Argument.js";

@@ -493,4 +493,4 @@

if (!isArrayOf(flagWords, "string")) throw new TypeError("options.flagWords must be an array of strings.");
if (!isArrayOf(optionFlagWords, "string")) throw new TypeError("options.optionFlagWords must be an array of strings.");
if (!Util.isArrayOf(flagWords, "string")) throw new TypeError("options.flagWords must be an array of strings.");
if (!Util.isArrayOf(optionFlagWords, "string")) throw new TypeError("options.optionFlagWords must be an array of strings.");
if (typeof quoted !== "boolean") throw new TypeError("options.quoted must be a boolean.");

@@ -497,0 +497,0 @@ if (separator !== undefined && typeof separator !== "string") throw new TypeError("options.separator must be a string.");

@@ -13,9 +13,2 @@ import type { Message } from "discord.js";

/**
* Order waiting time .
*
* Only exists if {@link type} is {@link FlagType.Timeout}.
*/
public declare time: T extends FlagType.Timeout ? number : never;
/**
* Message to handle.

@@ -60,10 +53,6 @@ *

private constructor(type: T & FlagType.Cancel);
private constructor(type: T & FlagType.Timeout, data?: FlagTimeoutData);
private constructor(type: T & FlagType.Retry, data?: FlagRetryData);
private constructor(type: T & FlagType.Fail, data?: FlagFailData);
private constructor(type: T & FlagType.Continue, data?: FlagContinueData);
private constructor(
type: T,
data: Record<string, never> | FlagTimeoutData | FlagRetryData | FlagFailData | FlagContinueData = {}
) {
private constructor(type: T, data: Record<string, never> | FlagRetryData | FlagFailData | FlagContinueData = {}) {
this.type = type;

@@ -81,9 +70,2 @@ Object.assign(this, data);

/**
* Create a flag that cancels the command because of the timeout
*/
public static timeout(time: number): Flag<FlagType.Timeout> {
return new Flag(FlagType.Timeout, { time });
}
/**
* Creates a flag that retries with another input.

@@ -119,3 +101,7 @@ * @param message - Message to handle.

*/
public static is<Type extends FlagType>(value: unknown, type: Type): value is Flag<typeof type> {
public static is(value: unknown, type: FlagType.Cancel): value is Flag<FlagType.Cancel>;
public static is(value: unknown, type: FlagType.Continue): value is Flag<FlagType.Continue>;
public static is(value: unknown, type: FlagType.Fail): value is Flag<FlagType.Fail>;
public static is(value: unknown, type: FlagType.Retry): value is Flag<FlagType.Retry>;
public static is(value: unknown, type: FlagType): value is Flag<typeof type> {
return value instanceof Flag && value.type === type;

@@ -127,3 +113,2 @@ }

Cancel = "cancel",
Timeout = "timeout",
Retry = "retry",

@@ -134,6 +119,2 @@ Fail = "fail",

interface FlagTimeoutData {
time: number;
}
interface FlagRetryData {

@@ -140,0 +121,0 @@ message: Message;

@@ -1,11 +0,8 @@

/* eslint-disable @typescript-eslint/no-unused-vars */
import {
ApplicationCommandType,
type ContextMenuCommandInteraction,
type LocalizationMap,
type PermissionResolvable,
type Snowflake
} from "discord.js";
import { isArrayOf, patchAbstract } from "../../util/Util.js";
import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
/* eslint-disable func-names, @typescript-eslint/no-unused-vars */
import { type ContextMenuInteraction, type Snowflake } from "discord.js";
import { AkairoError } from "../../util/AkairoError.js";
import type { Category } from "../../util/Category.js";
import { Util } from "../../util/Util.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import type { ContextMenuCommandHandler } from "./ContextMenuCommandHandler.js";

@@ -16,3 +13,3 @@

*/
export abstract class ContextMenuCommand extends AkairoModule<ContextMenuCommandHandler, ContextMenuCommand> {
export abstract class ContextMenuCommand extends AkairoModule {
/**

@@ -41,22 +38,25 @@ * Assign context menu commands to Specific guilds. This option will make the commands not register globally, but only in the chosen servers.

*/
public declare type: ApplicationCommandType.User | ApplicationCommandType.Message;
public declare type: "USER" | "MESSAGE";
/**
* Name localization.
* The category of this context menu command.
*/
public declare nameLocalizations?: LocalizationMap;
public declare category: Category<string, ContextMenuCommand>;
/**
* The default bitfield used to determine whether this command be used in a guild
* The Akairo client.
*/
public declare defaultMemberPermissions?: PermissionResolvable;
public declare client: AkairoClient;
/**
* Whether the command is enabled in DMs
*
* **Cannot be enabled for command that specify `guilds`**
* The filepath.
*/
public declare dmPermission?: boolean;
public declare filepath: string;
/**
* The handler.
*/
public declare handler: ContextMenuCommandHandler;
/**
* @param id - Listener ID.

@@ -66,26 +66,10 @@ * @param options - Options for the context menu command.

public constructor(id: string, options: ContextMenuCommandOptions) {
const {
category,
guilds = [],
name,
ownerOnly,
superUserOnly,
type,
nameLocalizations,
slashDefaultMemberPermissions,
slashDmPermission
} = options;
const { category, guilds, name, ownerOnly, superUserOnly, type } = options;
if (category !== undefined && typeof category !== "string") throw new TypeError("options.category must be a string.");
if (guilds !== undefined && !isArrayOf(guilds, "string")) throw new TypeError("options.guilds must be an array of strings.");
if (guilds !== undefined && !Util.isArrayOf(guilds, "string"))
throw new TypeError("options.guilds must be an array of strings.");
if (name !== undefined && typeof name !== "string") throw new TypeError("options.name must be a string.");
if (ownerOnly !== undefined && typeof ownerOnly !== "boolean") throw new TypeError("options.ownerOnly must be a boolean");
if (type !== ApplicationCommandType.User && type !== ApplicationCommandType.Message)
throw new TypeError("options.type must be either ApplicationCommandType.User or ApplicationCommandType.Message.");
if (nameLocalizations !== undefined && typeof nameLocalizations !== "object")
throw new TypeError("options.nameLocalizations must be a object.");
if (slashDmPermission != null && typeof slashDmPermission !== "boolean")
throw new TypeError("options.slashDmPermission must be a boolean.");
if (slashDmPermission != null && guilds.length > 0)
throw new TypeError("You cannot set `options.slashDmPermission` with commands configured with `options.slashGuilds`.");
if (type !== "USER" && type !== "MESSAGE") throw new TypeError("options.type must be either 'USER' or 'MESSAGE'.");

@@ -99,5 +83,2 @@ super(id, { category });

this.type = type;
this.nameLocalizations = nameLocalizations;
this.defaultMemberPermissions = slashDefaultMemberPermissions;
this.dmPermission = slashDmPermission;
}

@@ -109,7 +90,19 @@

*/
public abstract exec(interaction: ContextMenuCommandInteraction): any;
public exec(interaction: ContextMenuInteraction): any {
throw new AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
patchAbstract(ContextMenuCommand, "exec");
export interface ContextMenuCommand extends AkairoModule {
/**
* Reloads the context menu command.
*/
reload(): Promise<ContextMenuCommand>;
/**
* Removes the context menu command.
*/
remove(): ContextMenuCommand;
}
/**

@@ -121,3 +114,2 @@ * Options to use for context menu command execution behavior.

* Assign context menu commands to Specific guilds. This option will make the commands not register globally, but only in the chosen servers.
* @default []
*/

@@ -144,20 +136,3 @@ guilds?: Snowflake[];

*/
type: ApplicationCommandType.User | ApplicationCommandType.Message;
/**
* Name localization.
*/
nameLocalizations?: LocalizationMap;
/**
* The default bitfield used to determine whether this command be used in a guild
*/
slashDefaultMemberPermissions?: PermissionResolvable;
/**
* Whether the command is enabled in DMs
*
* **Cannot be enabled for commands that specify `guilds`**
*/
slashDmPermission?: boolean;
type: "USER" | "MESSAGE";
}

@@ -1,7 +0,9 @@

import type { Awaitable, ContextMenuCommandInteraction } from "discord.js";
import type { ContextMenuCommandHandlerEvents } from "../../typings/events.js";
import type { Awaitable, Collection, ContextMenuInteraction } from "discord.js";
import type { ContextMenuCommandHandlerEvents } from "../../typings/events";
import { AkairoError } from "../../util/AkairoError.js";
import type { Category } from "../../util/Category.js";
import { BuiltInReasons, ContextCommandHandlerEvents } from "../../util/Constants.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import type { AkairoModule } from "../AkairoModule.js";
import type { InhibitorHandler } from "../inhibitors/InhibitorHandler.js";

@@ -13,4 +15,24 @@ import { ContextMenuCommand } from "./ContextMenuCommand.js";

*/
export class ContextMenuCommandHandler extends AkairoHandler<ContextMenuCommand, ContextMenuCommandHandler> {
export class ContextMenuCommandHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
public declare categories: Collection<string, Category<string, ContextMenuCommand>>;
/**
* Class to handle.
*/
public declare classToHandle: typeof ContextMenuCommand;
/**
* The Akairo client.
*/
public declare client: AkairoClient;
/**
* Directory to context menu commands.
*/
public declare directory: string;
/**
* Inhibitor handler to use.

@@ -21,6 +43,11 @@ */

/**
* Context menu commands loaded, mapped by ID to context menu command.
*/
public declare modules: Collection<string, ContextMenuCommand>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
public constructor(client: AkairoClient, options: ContextMenuCommandHandlerOptions) {
public constructor(client: AkairoClient, options: AkairoHandlerOptions) {
const {

@@ -38,3 +65,9 @@ directory,

super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});

@@ -50,3 +83,5 @@ this.setup();

this.client.on("interactionCreate", i => {
if (i.isUserContextMenuCommand() || i.isMessageContextMenuCommand()) this.handle(i);
if (!i.isUserContextMenu()) return;
this.handle(i);
});

@@ -60,3 +95,3 @@ });

*/
public async handle(interaction: ContextMenuCommandInteraction): Promise<boolean | null> {
public async handle(interaction: ContextMenuInteraction): Promise<boolean | null> {
const command = this.modules.find(module => module.name === interaction.commandName);

@@ -93,3 +128,3 @@

*/
public emitError(err: Error, interaction: ContextMenuCommandInteraction, command: ContextMenuCommand): void {
public emitError(err: Error, interaction: ContextMenuInteraction, command: ContextMenuCommand | AkairoModule): void {
if (this.listenerCount(ContextCommandHandlerEvents.ERROR)) {

@@ -106,7 +141,59 @@ this.emit(ContextCommandHandlerEvents.ERROR, err, interaction, command);

export interface ContextMenuCommandHandler extends AkairoHandler<ContextMenuCommand, ContextMenuCommandHandler> {
export interface ContextMenuCommandHandler extends AkairoHandler {
/**
* Deregisters a module.
* @param contextMenuCommand - Module to use.
*/
deregister(contextMenuCommand: ContextMenuCommand): void;
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, ContextMenuCommand>;
/**
* Loads an context menu command.
* @param thing - Module or path to module.
*/
load(thing: string | ContextMenuCommand): Promise<ContextMenuCommand>;
/**
* Reads all context menu commands from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<ContextMenuCommandHandler>;
/**
* Registers a module.
* @param contextMenuCommand - Module to use.
* @param filepath - Filepath of module.
*/
register(contextMenuCommand: ContextMenuCommand, filepath?: string): void;
/**
* Reloads an context menu command.
* @param id - ID of the context menu command.
*/
reload(id: string): Promise<ContextMenuCommand>;
/**
* Reloads all context menu commands.
*/
reloadAll(): Promise<ContextMenuCommandHandler>;
/**
* Removes an context menu command.
* @param id - ID of the context menu command.
*/
remove(id: string): ContextMenuCommand;
/**
* Removes all context menu commands.
*/
removeAll(): ContextMenuCommandHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
}
export type ContextMenuCommandHandlerOptions = AkairoHandlerOptions<ContextMenuCommand, ContextMenuCommandHandler>;
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { Message } from "discord.js";
import { AkairoError } from "../../util/AkairoError.js";
import type { AkairoMessage } from "../../util/AkairoMessage.js";
import { patchAbstract } from "../../util/Util.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";

@@ -12,3 +14,3 @@ import type { Command } from "../commands/Command.js";

*/
export abstract class Inhibitor extends AkairoModule<InhibitorHandler, Inhibitor> {
export abstract class Inhibitor extends AkairoModule {
/**

@@ -20,2 +22,27 @@ * The priority of the inhibitor.

/**
* The category the inhibitor belongs to.
*/
public declare category: Category<string, Inhibitor>;
/**
* The Akairo client.
*/
public declare client: AkairoClient;
/**
* The filepath.
*/
public declare filepath: string;
/**
* The inhibitor handler.
*/
public declare handler: InhibitorHandler;
/**
* The ID of this inhibitor.
*/
public declare id: string;
/**
* Reason emitted when command is inhibited.

@@ -57,10 +84,24 @@ */

*/
public abstract exec(message: Message, command?: Command): boolean | Promise<boolean>;
public abstract exec(message: Message | AkairoMessage, command?: Command): boolean | Promise<boolean>;
public exec(message: Message, command?: Command): boolean | Promise<boolean>;
public exec(message: Message | AkairoMessage, command?: Command): boolean | Promise<boolean>;
public exec(message: Message | AkairoMessage, command?: Command): boolean | Promise<boolean> {
throw new AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
patchAbstract(Inhibitor, "exec");
export interface Inhibitor extends AkairoModule {
/**
* Reloads the inhibitor.
*/
reload(): Promise<Inhibitor>;
/**
* Removes the inhibitor.
*/
remove(): Inhibitor;
}
/**
* Options to use for inhibitor execution behavior.
* Also includes properties from AkairoModuleOptions.
*/

@@ -67,0 +108,0 @@ export interface InhibitorOptions extends AkairoModuleOptions {

@@ -1,8 +0,9 @@

import type { Awaitable, Message } from "discord.js";
import type { InhibitorHandlerEvents } from "../../typings/events.js";
import type { Awaitable, Collection, Message } from "discord.js";
import type { InhibitorHandlerEvents } from "../../typings/events";
import { AkairoError } from "../../util/AkairoError.js";
import type { AkairoMessage } from "../../util/AkairoMessage.js";
import { isPromise } from "../../util/Util.js";
import type { Category } from "../../util/Category.js";
import { Util } from "../../util/Util.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import type { Command } from "../commands/Command.js";

@@ -14,8 +15,33 @@ import { Inhibitor } from "./Inhibitor.js";

*/
export class InhibitorHandler extends AkairoHandler<Inhibitor, InhibitorHandler> {
export class InhibitorHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
public declare categories: Collection<string, Category<string, Inhibitor>>;
/**
* Class to handle.
*/
public declare classToHandle: typeof Inhibitor;
/**
* The Akairo client.
*/
public declare client: AkairoClient;
/**
* Directory to inhibitors.
*/
public declare directory: string;
/**
* Inhibitors loaded, mapped by ID to Inhibitor.
*/
public declare modules: Collection<string, Inhibitor>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
public constructor(client: AkairoClient, options: InhibitorHandlerOptions) {
public constructor(client: AkairoClient, options: AkairoHandlerOptions) {
const { directory, classToHandle = Inhibitor, extensions = [".js", ".ts"], automateCategories, loadFilter } = options ?? {};

@@ -27,3 +53,9 @@

super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});
}

@@ -54,3 +86,3 @@

let inhibited = inhibitor.exec(message, command);
if (isPromise(inhibited)) inhibited = await inhibited;
if (Util.isPromise(inhibited)) inhibited = await inhibited;
if (inhibited) return inhibitor;

@@ -72,7 +104,59 @@ return null;

export interface InhibitorHandler extends AkairoHandler<Inhibitor, InhibitorHandler> {
export interface InhibitorHandler extends AkairoHandler {
/**
* Deregisters an inhibitor.
* @param inhibitor - Inhibitor to use.
*/
deregister(inhibitor: Inhibitor): void;
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, Inhibitor>;
/**
* Loads an inhibitor.
* @param thing - Inhibitor or path to inhibitor.
*/
load(thing: string | Inhibitor): Promise<Inhibitor>;
/**
* Reads all inhibitors from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<InhibitorHandler>;
/**
* Registers an inhibitor.
* @param inhibitor - Inhibitor to use.
* @param filepath - Filepath of inhibitor.
*/
register(inhibitor: Inhibitor, filepath?: string): void;
/**
* Reloads an inhibitor.
* @param id - ID of the inhibitor.
*/
reload(id: string): Promise<Inhibitor>;
/**
* Reloads all inhibitors.
*/
reloadAll(): Promise<InhibitorHandler>;
/**
* Removes an inhibitor.
* @param id - ID of the inhibitor.
*/
remove(id: string): Inhibitor;
/**
* Removes all inhibitors.
*/
removeAll(): InhibitorHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
}
export type InhibitorHandlerOptions = AkairoHandlerOptions<Inhibitor, InhibitorHandler>;
/* eslint-disable func-names, @typescript-eslint/no-unused-vars */
import EventEmitter from "node:events";
import { patchAbstract } from "../../util/Util.js";
import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
import EventEmitter from "events";
import { AkairoError } from "../../util/AkairoError.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import type { ListenerHandler } from "./ListenerHandler.js";

@@ -10,4 +12,14 @@

*/
export abstract class Listener extends AkairoModule<ListenerHandler, Listener> {
export abstract class Listener extends AkairoModule {
/**
* The category of this listener.
*/
public declare category: Category<string, Listener>;
/**
* The Akairo client.
*/
public declare client: AkairoClient;
/**
* The event emitter.

@@ -23,2 +35,12 @@ */

/**
* The filepath.
*/
public declare filepath: string;
/**
* The handler.
*/
public declare handler: ListenerHandler;
/**
* Type of listener.

@@ -51,7 +73,19 @@ */

*/
public abstract exec(...args: any[]): any;
public exec(...args: any[]): any {
throw new AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
patchAbstract(Listener, "exec");
export interface Listener extends AkairoModule {
/**
* Reloads the listener.
*/
reload(): Promise<Listener>;
/**
* Removes the listener.
*/
remove(): Listener;
}
/**

@@ -58,0 +92,0 @@ * Options to use for listener execution behavior.

import { Awaitable, Collection } from "discord.js";
import type EventEmitter from "node:events";
import type { ListenerHandlerEvents } from "../../typings/events.js";
import type EventEmitter from "events";
import type { ListenerHandlerEvents } from "../../typings/events";
import { AkairoError } from "../../util/AkairoError.js";
import { isEventEmitter } from "../../util/Util.js";
import type { Category } from "../../util/Category.js";
import { Util } from "../../util/Util.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import { Listener } from "./Listener.js";

@@ -13,4 +14,9 @@

*/
export class ListenerHandler extends AkairoHandler<Listener, ListenerHandler> {
export class ListenerHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
public declare categories: Collection<string, Category<string, Listener>>;
/**
* Class to handle.

@@ -21,2 +27,12 @@ */

/**
* The Akairo client
*/
public declare client: AkairoClient;
/**
* Directory to listeners.
*/
public declare directory: string;
/**
* EventEmitters for use, mapped by name to EventEmitter.

@@ -28,6 +44,11 @@ * By default, 'client' is set to the given client.

/**
* Listeners loaded, mapped by ID to Listener.
*/
public declare modules: Collection<string, Listener>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
public constructor(client: AkairoClient, options: ListenerHandlerOptions) {
public constructor(client: AkairoClient, options: AkairoHandlerOptions) {
const { directory, classToHandle = Listener, extensions = [".js", ".ts"], automateCategories, loadFilter } = options ?? {};

@@ -39,3 +60,9 @@

super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});

@@ -54,4 +81,6 @@ this.emitters = new Collection();

const emitter = isEventEmitter(listener.emitter) ? listener.emitter : this.emitters.get(listener.emitter as string)!;
if (!isEventEmitter(emitter)) throw new AkairoError("INVALID_TYPE", "emitter", "EventEmitter", true);
const emitter: EventEmitter = Util.isEventEmitter(listener.emitter)
? (listener.emitter as EventEmitter)
: this.emitters.get(listener.emitter as string)!;
if (!Util.isEventEmitter(emitter)) throw new AkairoError("INVALID_TYPE", "emitter", "EventEmitter", true);

@@ -90,6 +119,6 @@ emitter[listener.type ?? "on"](listener.event, listener.exec);

const emitter: EventEmitter = isEventEmitter(listener.emitter)
const emitter: EventEmitter = Util.isEventEmitter(listener.emitter)
? (listener.emitter as EventEmitter)
: this.emitters.get(listener.emitter as string)!;
if (!isEventEmitter(emitter)) throw new AkairoError("INVALID_TYPE", "emitter", "EventEmitter", true);
if (!Util.isEventEmitter(emitter)) throw new AkairoError("INVALID_TYPE", "emitter", "EventEmitter", true);

@@ -106,3 +135,3 @@ emitter.removeListener(listener.event, listener.exec);

for (const [key, value] of Object.entries(emitters)) {
if (!isEventEmitter(value)) throw new AkairoError("INVALID_TYPE", key, "EventEmitter", true);
if (!Util.isEventEmitter(value)) throw new AkairoError("INVALID_TYPE", key, "EventEmitter", true);
this.emitters.set(key, value);

@@ -117,7 +146,47 @@ }

export interface ListenerHandler extends AkairoHandler<Listener, ListenerHandler> {
export interface ListenerHandler extends AkairoHandler {
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, Listener>;
/**
* Loads a listener, can be a listener class or a filepath.
* @param thing - Listener class or path to listener.
* @param isReload - Whether this is a reload or not.
*/
load(thing: string | Listener, isReload?: boolean): Promise<Listener>;
/**
* Reads all listeners from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<ListenerHandler>;
/**
* Reloads a listener.
* @param id - ID of the listener.
*/
reload(id: string): Promise<Listener>;
/**
* Reloads all listeners.
*/
reloadAll(): Promise<ListenerHandler>;
/**
* Removes a listener.
* @param id - ID of the listener.
*/
remove(id: string): Listener;
/**
* Removes all listeners.
*/
removeAll(): ListenerHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
}
export type ListenerHandlerOptions = AkairoHandlerOptions<Listener, ListenerHandler>;
/* eslint-disable func-names, @typescript-eslint/no-unused-vars */
import { patchAbstract } from "../../util/Util.js";
import { AkairoModule, type AkairoModuleOptions } from "../AkairoModule.js";
import { AkairoError } from "../../util/AkairoError.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoModule, AkairoModuleOptions } from "../AkairoModule.js";
import type { TaskHandler } from "./TaskHandler.js";

@@ -9,4 +11,14 @@

*/
export abstract class Task extends AkairoModule<TaskHandler, Task> {
export abstract class Task extends AkairoModule {
/**
* The category of this task.
*/
public declare category: Category<string, Task>;
/**
* The Akairo client.
*/
public declare client: AkairoClient;
/**
* The time in milliseconds between each time the task is run.

@@ -17,2 +29,12 @@ */

/**
* The filepath.
*/
public declare filepath: string;
/**
* The handler.
*/
public declare handler: TaskHandler;
/**
* Whether or not to run the task on start.

@@ -41,7 +63,24 @@ */

*/
public abstract exec(...args: any[]): any;
public exec(...args: any[]): any {
throw new AkairoError("NOT_IMPLEMENTED", this.constructor.name, "exec");
}
}
patchAbstract(Task, "exec");
export interface Task extends AkairoModule {
/**
* Reloads the task.
*/
reload(): Promise<Task>;
/**
* Removes the task.
*/
remove(): Task;
/**
* Returns the ID.
*/
toString(): string;
}
/**

@@ -48,0 +87,0 @@ * Options to use for task execution behavior.

@@ -1,6 +0,7 @@

import type { Awaitable } from "discord.js";
import type { TaskHandlerEvents } from "../../typings/events.js";
import type { Awaitable, Collection } from "discord.js";
import type { TaskHandlerEvents } from "../../typings/events";
import { AkairoError } from "../../util/AkairoError.js";
import type { Category } from "../../util/Category.js";
import type { AkairoClient } from "../AkairoClient.js";
import { AkairoHandler, type AkairoHandlerOptions } from "../AkairoHandler.js";
import { AkairoHandler, AkairoHandlerOptions, LoadPredicate } from "../AkairoHandler.js";
import { Task } from "./Task.js";

@@ -11,8 +12,33 @@

*/
export class TaskHandler extends AkairoHandler<Task, TaskHandler> {
export class TaskHandler extends AkairoHandler {
/**
* Categories, mapped by ID to Category.
*/
public declare categories: Collection<string, Category<string, Task>>;
/**
* Class to handle.
*/
public declare classToHandle: typeof Task;
/**
* The Akairo client
*/
public declare client: AkairoClient;
/**
* Directory to tasks.
*/
public declare directory: string;
/**
* Tasks loaded, mapped by ID to task.
*/
public declare modules: Collection<string, Task>;
/**
* @param client - The Akairo client.
* @param options - Options.
*/
public constructor(client: AkairoClient, options: AkairoHandlerOptions<Task, TaskHandler>) {
public constructor(client: AkairoClient, options: AkairoHandlerOptions) {
const { directory, classToHandle = Task, extensions = [".js", ".ts"], automateCategories, loadFilter } = options ?? {};

@@ -24,3 +50,9 @@

super(client, { directory, classToHandle, extensions, automateCategories, loadFilter });
super(client, {
directory,
classToHandle,
extensions,
automateCategories,
loadFilter
});
}

@@ -48,5 +80,59 @@

export interface TaskHandler extends AkairoHandler<Task, TaskHandler> {
export interface TaskHandler extends AkairoHandler {
/**
* Deregisters a task.
* @param task - Task to use.
*/
deregister(task: Task): void;
/**
* Finds a category by name.
* @param name - Name to find with.
*/
findCategory(name: string): Category<string, Task>;
/**
* Loads a task.
* @param thing - Task or path to task.
*/
load(thing: string | Task, isReload?: boolean): Promise<Task>;
/**
* Reads all tasks from the directory and loads them.
* @param directory - Directory to load from. Defaults to the directory passed in the constructor.
* @param filter - Filter for files, where true means it should be loaded.
*/
loadAll(directory?: string, filter?: LoadPredicate): Promise<TaskHandler>;
/**
* Registers a task.
* @param task - Task to use.
* @param filepath - Filepath of task.
*/
register(task: Task, filepath?: string): void;
/**
* Reloads a task.
* @param id - ID of the task.
*/
reload(id: string): Promise<Task>;
/**
* Reloads all tasks.
*/
reloadAll(): Promise<TaskHandler>;
/**
* Removes a task.
* @param id - ID of the task.
*/
remove(id: string): Task;
/**
* Removes all tasks.
*/
removeAll(): TaskHandler;
on<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
once<K extends keyof Events>(event: K, listener: (...args: Events[K]) => Awaitable<void>): this;
}

@@ -1,22 +0,12 @@

/* eslint-disable @typescript-eslint/no-empty-interface */
import type { ChatInputCommandInteraction, ClientEvents, ContextMenuCommandInteraction, Message } from "discord.js";
import type { AkairoHandler } from "../struct/AkairoHandler.js";
import type { ClientEvents, CommandInteraction, ContextMenuInteraction, Message } from "discord.js";
import type { AkairoModule } from "../struct/AkairoModule.js";
import type { Command } from "../struct/commands/Command.js";
import type { CommandHandler } from "../struct/commands/CommandHandler.js";
import type { ContextMenuCommand } from "../struct/contextMenuCommands/ContextMenuCommand.js";
import type { ContextMenuCommandHandler } from "../struct/contextMenuCommands/ContextMenuCommandHandler.js";
import type { Inhibitor } from "../struct/inhibitors/Inhibitor.js";
import type { InhibitorHandler } from "../struct/inhibitors/InhibitorHandler.js";
import type { Listener } from "../struct/listeners/Listener.js";
import type { ListenerHandler } from "../struct/listeners/ListenerHandler.js";
import type { Task } from "../struct/tasks/Task.js";
import type { TaskHandler } from "../struct/tasks/TaskHandler.js";
import type { AkairoMessage } from "../util/AkairoMessage.js";
import type { BuiltInReasons } from "../util/Constants.js";
export interface AkairoHandlerEvents<
Module extends AkairoModule<Handler, Module>,
Handler extends AkairoHandler<Module, Handler>
> {
export interface AkairoHandlerEvents {
/**

@@ -27,3 +17,3 @@ * Emitted when a module is loaded.

*/
load: [mod: Module, isReload: boolean];
load: [mod: AkairoModule, isReload: boolean];

@@ -34,6 +24,6 @@ /**

*/
remove: [mod: Module];
remove: [mod: AkairoModule];
}
export interface CommandHandlerEvents extends AkairoHandlerEvents<Command, CommandHandler> {
export interface CommandHandlerEvents extends AkairoHandlerEvents {
/**

@@ -64,10 +54,2 @@ * Emitted when a command is blocked by a post-message inhibitor. The built-in inhibitors are `owner`, `superUser`, `guild`, and `dm`.

/**
* Emitted when a command is cancelled because of a timeout.
* @param message - Message sent.
* @param command - Command executed.
* @param time - Timeout in milliseconds.
*/
commandTimeout: [message: Message, command: Command, time: number];
/**
* Emitted when a command finishes execution.

@@ -127,2 +109,9 @@ * @param message - Message sent.

/**
* Emitted when a command is loaded.
* @param command - Module loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [command: Command, isReload: boolean];
/**
* Emitted when a message is blocked by a pre-message inhibitor. The built-in inhibitors are 'client' and 'bot'.

@@ -150,2 +139,8 @@ * @param message - Message sent.

/**
* Emitted when a command is removed.
* @param command - Command removed.
*/
remove: [command: Command];
/**
* Emitted when a slash command is blocked by a post-message inhibitor. The built-in inhibitors are `owner`, `superUser`, `guild`, and `dm`.

@@ -188,3 +183,3 @@ * @param message - The slash message.

*/
slashNotFound: [interaction: ChatInputCommandInteraction];
slashNotFound: [interaction: CommandInteraction];

@@ -207,10 +202,62 @@ /**

export interface InhibitorHandlerEvents extends AkairoHandlerEvents<Inhibitor, InhibitorHandler> {}
export interface InhibitorHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when an inhibitor is removed.
* @param inhibitor - Inhibitor removed.
*/
remove: [inhibitor: Inhibitor];
export interface ListenerHandlerEvents extends AkairoHandlerEvents<Listener, ListenerHandler> {}
/**
* Emitted when an inhibitor is loaded.
* @param inhibitor - Inhibitor loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [inhibitor: Inhibitor, isReload: boolean];
}
export interface TaskHandlerEvents extends AkairoHandlerEvents<Task, TaskHandler> {}
export interface ListenerHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when a listener is removed.
* @param listener - Listener removed.
*/
remove: [listener: Listener];
export interface ContextMenuCommandHandlerEvents extends AkairoHandlerEvents<ContextMenuCommand, ContextMenuCommandHandler> {
/**
* Emitted when a listener is loaded.
* @param listener - Listener loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [listener: Listener, isReload: boolean];
}
export interface TaskHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when a task is removed.
* @param task - Task removed.
*/
remove: [task: Task];
/**
* Emitted when a task is loaded.
* @param task - Task loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [task: Task, isReload: boolean];
}
export interface ContextMenuCommandHandlerEvents extends AkairoHandlerEvents {
/**
* Emitted when a context menu command is removed.
* @param contextMenu - Context menu command removed.
*/
remove: [contextMenu: ContextMenuCommand];
/**
* Emitted when a context menu command is loaded.
* @param contextMenu - Context menu command loaded.
* @param isReload - Whether or not this was a reload.
*/
load: [contextMenu: ContextMenuCommand, isReload: boolean];
/**
* Emitted when a context menu command errors.

@@ -221,3 +268,3 @@ * @param error - The error.

*/
error: [error: Error, interaction: ContextMenuCommandInteraction, command: ContextMenuCommand];
error: [error: Error, interaction: ContextMenuInteraction, command: ContextMenuCommand];

@@ -230,3 +277,3 @@ /**

*/
finished: [interaction: ContextMenuCommandInteraction, command: ContextMenuCommand, returnValue: any];
finished: [interaction: ContextMenuInteraction, command: ContextMenuCommand, returnValue: any];

@@ -237,3 +284,3 @@ /**

*/
notFound: [interaction: ContextMenuCommandInteraction];
notFound: [interaction: ContextMenuInteraction];

@@ -246,3 +293,3 @@ /**

*/
started: [interaction: ContextMenuCommandInteraction, command: ContextMenuCommand];
started: [interaction: ContextMenuInteraction, command: ContextMenuCommand];

@@ -256,3 +303,3 @@ /**

blocked: [
interaction: ContextMenuCommandInteraction,
interaction: ContextMenuInteraction,
command: Command,

@@ -259,0 +306,0 @@ reason: typeof BuiltInReasons.OWNER | typeof BuiltInReasons.SUPER_USER

@@ -1,2 +0,2 @@

import type { SlashOption } from "../struct/commands/Command.js";
import { SlashOption } from "../struct/commands/Command";

@@ -3,0 +3,0 @@ const Messages = {

@@ -0,9 +1,15 @@

import type { APIInteractionGuildMember, APIMessage } from "discord-api-types/v9";
import {
Base,
cleanContent,
type CacheType,
type ChatInputCommandInteraction,
type InteractionReplyOptions,
type Message,
type MessagePayload
CommandInteraction,
Guild,
GuildMember,
GuildTextBasedChannel,
InteractionReplyOptions,
Message,
MessagePayload,
Snowflake,
TextBasedChannel,
User,
Util
} from "discord.js";

@@ -16,7 +22,7 @@ import type { AkairoClient } from "../struct/AkairoClient.js";

*/
export class AkairoMessage<Cached extends CacheType = CacheType> extends Base {
export class AkairoMessage extends Base {
/**
* The author of the interaction.
*/
public declare author: ChatInputCommandInteraction<Cached>["user"];
public declare author: User;

@@ -26,3 +32,3 @@ /**

*/
public declare applicationId: ChatInputCommandInteraction<Cached>["applicationId"];
public declare applicationId: Snowflake;

@@ -32,3 +38,3 @@ /**

*/
public declare channelId: ChatInputCommandInteraction<Cached>["channelId"];
public declare channelId: Snowflake | null;

@@ -43,3 +49,3 @@ /**

*/
public declare createdTimestamp: ChatInputCommandInteraction<Cached>["createdTimestamp"];
public declare createdTimestamp: number;

@@ -49,3 +55,3 @@ /**

*/
public declare guildId: ChatInputCommandInteraction<Cached>["guildId"];
public declare guildId: Snowflake | null;

@@ -55,3 +61,3 @@ /**

*/
public declare id: ChatInputCommandInteraction<Cached>["id"];
public declare id: Snowflake;

@@ -61,3 +67,3 @@ /**

*/
public declare interaction: ChatInputCommandInteraction<Cached>;
public declare interaction: CommandInteraction;

@@ -68,3 +74,3 @@ /**

*/
public declare member: ChatInputCommandInteraction<Cached>["member"];
public declare member: GuildMember | APIInteractionGuildMember | null;

@@ -74,3 +80,3 @@ /**

*/
public declare partial: false;
public declare readonly partial: false;

@@ -86,3 +92,3 @@ /**

*/
public constructor(client: AkairoClient, interaction: ChatInputCommandInteraction<Cached>) {
public constructor(client: AkairoClient, interaction: CommandInteraction) {
super(client);

@@ -105,3 +111,3 @@

*/
public get channel(): ChatInputCommandInteraction<Cached>["channel"] {
public get channel(): TextBasedChannel | null {
return this.interaction.channel;

@@ -115,3 +121,3 @@ }

public get cleanContent(): string | null {
return this.content != null ? cleanContent(this.content, this.channel!) : null;
return this.content != null ? Util.cleanContent(this.content, this.channel!) : null;
}

@@ -122,3 +128,3 @@

*/
public get guild(): ChatInputCommandInteraction<Cached>["guild"] {
public get guild(): Guild | null {
return this.interaction.guild;

@@ -130,3 +136,3 @@ }

*/
public get createdAt(): ChatInputCommandInteraction<Cached>["createdAt"] {
public get createdAt(): Date {
return this.interaction.createdAt;

@@ -147,4 +153,4 @@ }

*/
public inGuild(): this is AkairoMessage<"cached"> {
return this.interaction.inCachedGuild();
public inGuild(): this is AkairoMessageInGuild & this {
return Boolean(this.guildId && this.member);
}

@@ -163,5 +169,10 @@

*/
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message> {
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<Message | APIMessage> {
return this.util.reply(options);
}
}
export interface AkairoMessageInGuild {
guild: Guild;
channel: GuildTextBasedChannel;
}

@@ -7,3 +7,3 @@ import { Collection } from "discord.js";

*/
export class Category<K extends string, V extends AkairoModule<any, any>> extends Collection<K, V> {
export class Category<K extends string, V extends AkairoModule> extends Collection<K, V> {
/**

@@ -19,3 +19,3 @@ * ID of the category.

public constructor(id: string, iterable?: Iterable<readonly [K, V]>) {
super(iterable);
super(iterable!);
this.id = id;

@@ -22,0 +22,0 @@ }

@@ -1,122 +0,115 @@

export enum ArgumentMatches {
PHRASE = "phrase",
FLAG = "flag",
OPTION = "option",
REST = "rest",
SEPARATE = "separate",
TEXT = "text",
CONTENT = "content",
REST_CONTENT = "restContent",
NONE = "none"
}
export const ArgumentMatches = Object.freeze({
PHRASE: "phrase",
FLAG: "flag",
OPTION: "option",
REST: "rest",
SEPARATE: "separate",
TEXT: "text",
CONTENT: "content",
REST_CONTENT: "restContent",
NONE: "none"
} as const);
export enum ArgumentTypes {
STRING = "string",
LOWERCASE = "lowercase",
UPPERCASE = "uppercase",
CHAR_CODES = "charCodes",
NUMBER = "number",
INTEGER = "integer",
BIGINT = "bigint",
EMOJINT = "emojint",
URL = "url",
DATE = "date",
COLOR = "color",
USER = "user",
USERS = "users",
MEMBER = "member",
MEMBERS = "members",
RELEVANT = "relevant",
RELEVANTS = "relevants",
CHANNEL = "channel",
CHANNELS = "channels",
TEXT_CHANNEL = "textChannel",
TEXT_CHANNELS = "textChannels",
VOICE_CHANNEL = "voiceChannel",
VOICE_CHANNELS = "voiceChannels",
CATEGORY_CHANNEL = "categoryChannel",
CATEGORY_CHANNELS = "categoryChannels",
NEWS_CHANNEL = "newsChannel",
NEWS_CHANNELS = "newsChannels",
STAGE_CHANNEL = "stageChannel",
STAGE_CHANNELS = "stageChannels",
THREAD_CHANNEL = "threadChannel",
THREAD_CHANNELS = "threadChannels",
DIRECTORY_CHANNEL = "directoryChannel",
DIRECTORY_CHANNELS = "directoryChannels",
FORUM_CHANNEL = "forumChannel",
FORUM_CHANNELS = "forumChannels",
TEXT_BASED_CHANNEL = "textBasedChannel",
TEXT_BASED_CHANNELS = "textBasedChannels",
VOICE_BASED_CHANNEL = "voiceBasedChannel",
VOICE_BASED_CHANNELS = "voiceBasedChannels",
ROLE = "role",
ROLES = "roles",
EMOJI = "emoji",
EMOJIS = "emojis",
GUILD = "guild",
GUILDS = "guilds",
MESSAGE = "message",
GUILD_MESSAGE = "guildMessage",
RELEVANT_MESSAGE = "relevantMessage",
INVITE = "invite",
USER_MENTION = "userMention",
MEMBER_MENTION = "memberMention",
CHANNEL_MENTION = "channelMention",
ROLE_MENTION = "roleMention",
EMOJI_MENTION = "emojiMention",
COMMAND_ALIAS = "commandAlias",
COMMAND = "command",
INHIBITOR = "inhibitor",
LISTENER = "listener",
TASK = "task",
CONTEXT_MENU_COMMAND = "contextMenuCommand"
}
export const ArgumentTypes = Object.freeze({
STRING: "string",
LOWERCASE: "lowercase",
UPPERCASE: "uppercase",
CHAR_CODES: "charCodes",
NUMBER: "number",
INTEGER: "integer",
BIGINT: "bigint",
EMOJINT: "emojint",
URL: "url",
DATE: "date",
COLOR: "color",
USER: "user",
USERS: "users",
MEMBER: "member",
MEMBERS: "members",
RELEVANT: "relevant",
RELEVANTS: "relevants",
CHANNEL: "channel",
CHANNELS: "channels",
TEXT_CHANNEL: "textChannel",
TEXT_CHANNELS: "textChannels",
VOICE_CHANNEL: "voiceChannel",
VOICE_CHANNELS: "voiceChannels",
CATEGORY_CHANNEL: "categoryChannel",
CATEGORY_CHANNELS: "categoryChannels",
NEWS_CHANNEL: "newsChannel",
NEWS_CHANNELS: "newsChannels",
STORE_CHANNEL: "storeChannel",
STORE_CHANNELS: "storeChannels",
STAGE_CHANNEL: "stageChannel",
STAGE_CHANNELS: "stageChannels",
THREAD_CHANNEL: "threadChannel",
THREAD_CHANNELS: "threadChannels",
ROLE: "role",
ROLES: "roles",
EMOJI: "emoji",
EMOJIS: "emojis",
GUILD: "guild",
GUILDS: "guilds",
MESSAGE: "message",
GUILD_MESSAGE: "guildMessage",
RELEVANT_MESSAGE: "relevantMessage",
INVITE: "invite",
USER_MENTION: "userMention",
MEMBER_MENTION: "memberMention",
CHANNEL_MENTION: "channelMention",
ROLE_MENTION: "roleMention",
EMOJI_MENTION: "emojiMention",
COMMAND_ALIAS: "commandAlias",
COMMAND: "command",
INHIBITOR: "inhibitor",
LISTENER: "listener",
TASK: "task",
CONTEXT_MENU_COMMAND: "contextMenuCommand"
} as const);
export enum AkairoHandlerEvents {
LOAD = "load",
REMOVE = "remove"
}
export const AkairoHandlerEvents = Object.freeze({
LOAD: "load",
REMOVE: "remove"
} as const);
export enum CommandHandlerEvents {
COMMAND_BLOCKED = "commandBlocked",
COMMAND_BREAKOUT = "commandBreakout",
COMMAND_CANCELLED = "commandCancelled",
COMMAND_TIMEOUT = "commandTimeout",
COMMAND_FINISHED = "commandFinished",
COMMAND_INVALID = "commandInvalid",
COMMAND_LOCKED = "commandLocked",
COMMAND_STARTED = "commandStarted",
COOLDOWN = "cooldown",
ERROR = "error",
IN_PROMPT = "inPrompt",
MESSAGE_BLOCKED = "messageBlocked",
MESSAGE_INVALID = "messageInvalid",
MISSING_PERMISSIONS = "missingPermissions",
SLASH_BLOCKED = "slashBlocked",
SLASH_ERROR = "slashError",
SLASH_FINISHED = "slashFinished",
SLASH_MISSING_PERMISSIONS = "slashMissingPermissions",
SLASH_NOT_FOUND = "slashNotFound",
SLASH_STARTED = "slashStarted",
SLASH_ONLY = "slashOnly"
}
export const CommandHandlerEvents = Object.freeze({
COMMAND_BLOCKED: "commandBlocked",
COMMAND_BREAKOUT: "commandBreakout",
COMMAND_CANCELLED: "commandCancelled",
COMMAND_FINISHED: "commandFinished",
COMMAND_INVALID: "commandInvalid",
COMMAND_LOCKED: "commandLocked",
COMMAND_STARTED: "commandStarted",
COOLDOWN: "cooldown",
ERROR: "error",
IN_PROMPT: "inPrompt",
MESSAGE_BLOCKED: "messageBlocked",
MESSAGE_INVALID: "messageInvalid",
MISSING_PERMISSIONS: "missingPermissions",
SLASH_BLOCKED: "slashBlocked",
SLASH_ERROR: "slashError",
SLASH_FINISHED: "slashFinished",
SLASH_MISSING_PERMISSIONS: "slashMissingPermissions",
SLASH_NOT_FOUND: "slashNotFound",
SLASH_STARTED: "slashStarted",
SLASH_ONLY: "slashOnly"
} as const);
export enum ContextCommandHandlerEvents {
ERROR = "error",
FINISHED = "finished",
NOT_FOUND = "notFound",
STARTED = "started",
BLOCKED = "blocked"
}
export const ContextCommandHandlerEvents = Object.freeze({
ERROR: "error",
FINISHED: "finished",
NOT_FOUND: "notFound",
STARTED: "started",
BLOCKED: "blocked"
} as const);
export enum BuiltInReasons {
CLIENT = "client",
BOT = "bot",
OWNER = "owner",
SUPER_USER = "superUser",
GUILD = "guild",
DM = "dm",
AUTHOR_NOT_FOUND = "authorNotFound",
NOT_NSFW = "notNsfw"
}
export const BuiltInReasons = Object.freeze({
CLIENT: "client",
BOT: "bot",
OWNER: "owner",
SUPER_USER: "superUser",
GUILD: "guild",
DM: "dm",
AUTHOR_NOT_FOUND: "authorNotFound",
NOT_NSFW: "notNsfw"
} as const);

@@ -1,125 +0,171 @@

import EventEmitter from "node:events";
import type { PrefixSupplier } from "../struct/commands/CommandHandler.js";
import { AkairoError } from "./AkairoError.js";
import EventEmitter from "events";
import type { PrefixSupplier } from "../struct/commands/CommandHandler";
/**
* Deep assign properties to an object.
* @param target The object to assign values to.
* @param os The objects to assign from.
* Akairo Utilities.
*/
export function deepAssign<A, B>(target: A, ...os: B[]): A {
for (const o of os) {
for (const [key, value] of Object.entries(o)) {
const valueIsObject = value && typeof value === "object";
const targetKeyIsObject =
Object.prototype.hasOwnProperty.call(target, key) &&
target[key as keyof typeof target] &&
typeof target[key as keyof typeof target] === "object";
if (valueIsObject && targetKeyIsObject) {
deepAssign(target[key as keyof typeof target], value);
} else {
target[key as keyof typeof target] = value;
export class Util {
/**
* Deep assign properties to an object.
* @param target The object to assign values to.
* @param os The objects to assign from.
*/
public static deepAssign<A, B>(target: A, ...os: B[]): A {
for (const o of os) {
for (const [key, value] of Object.entries(o)) {
const valueIsObject = value && typeof value === "object";
const targetKeyIsObject =
Object.prototype.hasOwnProperty.call(target, key) &&
target[key as keyof typeof target] &&
typeof target[key as keyof typeof target] === "object";
if (valueIsObject && targetKeyIsObject) {
Util.deepAssign(target[key as keyof typeof target], value);
} else {
target[key as keyof typeof target] = value;
}
}
}
return target;
}
return target;
}
/**
* Converts the supplied value into an array if it is not already one.
* @param x - Value to convert.
*/
public static intoArray<T>(x: T | T[]): T[] {
if (Array.isArray(x)) {
return x;
}
/**
* Converts the supplied value into an array if it is not already one.
* @param x - Value to convert.
*/
export function intoArray<T>(x: T | T[]): T[] {
if (Array.isArray(x)) {
return x;
return [x];
}
return [x];
}
/**
* Converts something to become callable.
* @param thing - What to turn into a callable.
* @returns - The callable.
*/
public static intoCallable<T>(thing: T | ((...args: any[]) => T)): (...args: any[]) => T {
if (typeof thing === "function") {
return thing as () => T;
}
/**
* Converts something to become callable.
* @param thing - What to turn into a callable.
* @returns - The callable.
*/
export function intoCallable<T>(thing: T | ((...args: any[]) => T)): (...args: any[]) => T {
if (typeof thing === "function") {
return thing as () => T;
return () => thing;
}
return () => thing;
}
/**
* Checks if the supplied value is an event emitter.
* @param value - Value to check.
* @returns - Whether the value is an event emitter.
*/
public static isEventEmitter(value: unknown): value is EventEmitter {
return value instanceof EventEmitter;
}
/**
* Checks if the supplied value is an event emitter.
* @param value - Value to check.
* @returns - Whether the value is an event emitter.
*/
export function isEventEmitter(value: unknown): value is EventEmitter {
return value instanceof EventEmitter;
}
/**
* Checks if the supplied value is a promise.
* @param value - Value to check.
* @returns - Whether the value is a promise.
*/
public static isPromise<T>(value: T | Promise<T>): value is Promise<T> {
return value instanceof Promise;
}
/**
* Checks if the supplied value is a promise.
* @param value - Value to check.
* @returns - Whether the value is a promise.
*/
export function isPromise<T>(value: T | Promise<T>): value is Promise<T> {
return value instanceof Promise;
}
/**
* Compares two prefixes.
* @param aKey - First prefix.
* @param bKey - Second prefix.
* @returns - Comparison result.
*/
public static prefixCompare(aKey: string | PrefixSupplier, bKey: string | PrefixSupplier): number {
if (aKey === "" && bKey === "") return 0;
if (aKey === "") return 1;
if (bKey === "") return -1;
if (typeof aKey === "function" && typeof bKey === "function") return 0;
if (typeof aKey === "function") return 1;
if (typeof bKey === "function") return -1;
return aKey.length === bKey.length ? aKey.localeCompare(bKey) : bKey.length - aKey.length;
}
/**
* Compares two prefixes.
* @param aKey - First prefix.
* @param bKey - Second prefix.
* @returns - Comparison result.
*/
export function prefixCompare(aKey: string | PrefixSupplier, bKey: string | PrefixSupplier): number {
if (aKey === "" && bKey === "") return 0;
if (aKey === "") return 1;
if (bKey === "") return -1;
if (typeof aKey === "function" && typeof bKey === "function") return 0;
if (typeof aKey === "function") return 1;
if (typeof bKey === "function") return -1;
return aKey.length === bKey.length ? aKey.localeCompare(bKey) : bKey.length - aKey.length;
}
/**
* Compares each property of two objects to determine if they are equal.
* @param a - First value.
* @param b - Second value.
* @param ignoreUndefined - Whether to ignore undefined properties.
* @returns Whether the two values are equal.
*/
public static deepEquals<T>(a: unknown, b: T, options?: DeepEqualsOptions): a is T;
// eslint-disable-next-line complexity
public static deepEquals(a: any, b: any, options?: DeepEqualsOptions): boolean {
const { ignoreUndefined = true, ignoreArrayOrder = true } = options ?? {};
/**
* Compares each property of two objects to determine if they are equal.
* @param a - First value.
* @param b - Second value.
* @param options - Additional options.
* @returns Whether the two values are equal.
*/
export function deepEquals<T>(a: unknown, b: T, options?: DeepEqualsOptions): a is T;
// eslint-disable-next-line complexity
export function deepEquals(a: any, b: any, options?: DeepEqualsOptions): boolean {
const { ignoreUndefined = true, ignoreArrayOrder = true } = options ?? {};
if (a === b) return true;
if (typeof a !== "object" || typeof b !== "object") throw new TypeError("Not objects");
if ((Array.isArray(a) && !Array.isArray(b)) || (!Array.isArray(a) && Array.isArray(b))) return false;
const newA = ignoreArrayOrder && Array.isArray(a) && a.length && typeof a[0] !== "object" ? [...a].sort() : a;
const newB = ignoreArrayOrder && Array.isArray(b) && b.length && typeof b[0] !== "object" ? [...b].sort() : b;
for (const key in newA) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined) continue;
if (!(key in newB)) return false;
if (typeof newA[key] === "object" && typeof newB[key] === "object") {
if (!this.deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder })) return false;
} else if (newA[key] !== newB[key]) return false;
}
for (const key in newB) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined) continue;
if (!(key in newA)) return false;
if (typeof newB[key] === "object" && typeof newA[key] === "object") {
if (!this.deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder })) return false;
} else if (newA[key] !== newB[key]) return false;
}
return true;
}
if (a === b) return true;
if (typeof a !== "object" || typeof b !== "object") throw new TypeError("Not objects");
if ((Array.isArray(a) && !Array.isArray(b)) || (!Array.isArray(a) && Array.isArray(b))) return false;
const newA = ignoreArrayOrder && Array.isArray(a) && a.length && typeof a[0] !== "object" ? [...a].sort() : a;
const newB = ignoreArrayOrder && Array.isArray(b) && b.length && typeof b[0] !== "object" ? [...b].sort() : b;
for (const key in newA) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined) continue;
if (!(key in newB)) return false;
if (typeof newA[key] === "object" && typeof newB[key] === "object") {
if (!deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder })) return false;
} else if (newA[key] !== newB[key]) return false;
/**
* Converts a string in snake_case to camelCase.
* @param str The string to convert.
*/
public static snakeToCamelCase(str: string): string {
return str
.toLowerCase()
.split("_")
.map((word, index) => {
if (index !== 0) return word.charAt(0).toUpperCase() + word.slice(1);
return word;
})
.join("");
}
for (const key in newB) {
if (ignoreUndefined && newA[key] === undefined && newB[key] === undefined) continue;
if (!(key in newA)) return false;
if (typeof newB[key] === "object" && typeof newA[key] === "object") {
if (!deepEquals(newA[key], newB[key], { ignoreUndefined, ignoreArrayOrder })) return false;
} else if (newA[key] !== newB[key]) return false;
/**
* Converts a string in PascalCase to camelCase.
* @param str The string to convert.
*/
public static pascalToCamelCase(str: string): string {
return str.charAt(0).toLowerCase() + str.slice(1);
}
return true;
/**
* Checks if `array` is an array and its elements are typeof of `type`
* @param array The array to check.
* @param type The type to check the elements' type against.
* @returns Whether the array is an array and its elements are typeof of `type`.
*/
public static isArrayOf<T>(
array: T[],
type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
): boolean {
if (!Array.isArray(array)) return false;
return array.every(item => typeof item === type);
}
}
/**
* Options for {@link deepEquals}.
* Checks if a value is a string, an array of strings, or a function
* @internal
*/
export function isStringArrayStringOrFunc(value: any): value is string | string[] | ((...args: any[]) => any) {
return typeof value === "string" || typeof value === "function" || Util.isArrayOf(value, "string");
}
export interface DeepEqualsOptions {

@@ -138,64 +184,1 @@ /**

}
/**
* Converts a string in snake_case to camelCase.
* @param str The string to convert.
*/
export function snakeToCamelCase(str: string): string {
return str
.toLowerCase()
.split("_")
.map((word, index) => {
if (index !== 0) return word.charAt(0).toUpperCase() + word.slice(1);
return word;
})
.join("");
}
/**
* Converts a string in PascalCase to camelCase.
* @param str The string to convert.
*/
export function pascalToCamelCase(str: string): string {
return str.charAt(0).toLowerCase() + str.slice(1);
}
/**
* Checks if `array` is an array and its elements are typeof of `type`
* @param array The array to check.
* @param type The type to check the elements' type against.
* @returns Whether the array is an array and its elements are typeof of `type`.
*/
export function isArrayOf<T>(
array: T[],
type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
): boolean {
if (!Array.isArray(array)) return false;
return array.every(item => typeof item === type);
}
/**
* Checks if a value is a string, an array of strings, or a function
* @internal
*/
export function isStringArrayStringOrFunc(value: any): value is string | string[] | ((...args: any[]) => any) {
return typeof value === "string" || typeof value === "function" || isArrayOf(value, "string");
}
/* eslint-disable @typescript-eslint/ban-types, func-names */
/**
* Defines an abstract method to a class to produce a runtime error.
* @param Class The class to patch.
* @param method The name of the method to patch.
*/
export function patchAbstract(Class: Function, method: string): void {
Object.defineProperty(Class.prototype, method, {
configurable: true,
enumerable: false,
writable: true,
value: function () {
throw new AkairoError("NOT_IMPLEMENTED", this.constructor.name, method);
}
});
}
/* eslint-enable @typescript-eslint/ban-types, func-names */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"target": "ES2021",
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"useUnknownInCatchVariables": false,
"alwaysStrict": true,
"strict": true,
"noImplicitOverride": true
},
"include": ["src/**/*.ts", "test/**/*.ts", "test/**/*.js"],
"exclude": ["node_modules", "dist"]
}
{
"compilerOptions": {
/* Type Checking */
"module": "CommonJS",
"target": "ES2021",
"outDir": "dist",
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noErrorTruncation": true,
"useUnknownInCatchVariables": false,
"alwaysStrict": true,
"strict": true,
"noImplicitOverride": true,
"strict": true,
"useUnknownInCatchVariables": false,
/* Modules */
"module": "CommonJS",
"resolveJsonModule": true,
/* Emit */
"declarationMap": true,
"declaration": true,
"declarationMap": true,
"outDir": "dist",
"sourceMap": true,
"stripInternal": true,
/* Language and Environment */
"target": "ES2022",
/* Interop Constraints */
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
/* Output Formatting */
"noErrorTruncation": true
"noEmitHelpers": false,
"importHelpers": false
},

@@ -30,0 +20,0 @@ "include": ["src/**/*.ts"],

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc