@sapphire/framework
Version:
Discord bot framework built for advanced and amazing bots.
174 lines (172 loc) • 8.47 kB
JavaScript
import { InternalRegistryAPIType, RegisterBehavior } from "../../types/Enums.mjs";
import { Events as Events$1 } from "../../types/Events.mjs";
import { ApplicationCommandRegistry } from "./ApplicationCommandRegistry.mjs";
import { getNeededRegistryParameters } from "./getNeededParameters.mjs";
import { bulkOverwriteDebug, bulkOverwriteWarn } from "./registriesLog.mjs";
import { emitBulkOverwriteError, emitPerRegistryError } from "./registriesErrors.mjs";
import { container } from "@sapphire/pieces";
import { retry } from "@sapphire/utilities";
import { ApplicationCommandType } from "discord.js";
//#region src/lib/utils/application-commands/ApplicationCommandRegistries.ts
let defaultBehaviorWhenNotIdentical = RegisterBehavior.Overwrite;
let defaultGuildIds = void 0;
let bulkOVerwriteRetries = 1;
const registries = /* @__PURE__ */ new Map();
const allGuildIdsToFetchCommandsFor = /* @__PURE__ */ new Set();
/**
* Acquires a registry for a command by its name.
* @param commandName The name of the command.
* @returns The application command registry for the command
*/
function acquire(commandName) {
const existing = registries.get(commandName);
if (existing) return existing;
const newRegistry = new ApplicationCommandRegistry(commandName);
registries.set(commandName, newRegistry);
return newRegistry;
}
/**
* Sets the default behavior when registered commands aren't identical to provided data.
* @param behavior The default behavior to have. Set this to `null` to reset it to the default
* of `RegisterBehavior.Overwrite`.
*/
function setDefaultBehaviorWhenNotIdentical(behavior) {
defaultBehaviorWhenNotIdentical = behavior ?? RegisterBehavior.Overwrite;
}
function getDefaultBehaviorWhenNotIdentical() {
return defaultBehaviorWhenNotIdentical;
}
/**
* Sets the default guild ids for registering commands. This is used when a command is registered _without_ providing
* `guildIds` in that command's own {@link Command.registerApplicationCommands} method.
* @param guildIds The default guildIds to set. Set this to `null` to reset it to the default
* of `undefined`.
*/
function setDefaultGuildIds(guildIds) {
defaultGuildIds = guildIds ?? void 0;
}
function getDefaultGuildIds() {
return defaultGuildIds;
}
/**
* Sets the amount of retries for when registering commands, only applies when {@link defaultBehaviorWhenNotIdentical}
* is set to {@link RegisterBehavior.BulkOverwrite}. This is used if registering the commands times out.
* The default value is `1`, which means no retries are performed.
* @param newAmountOfRetries The new amount of retries to set. Set this to `null` to reset it to the default
*/
function setBulkOverwriteRetries(newAmountOfRetries) {
newAmountOfRetries ??= 1;
if (newAmountOfRetries <= 0) throw new RangeError("The amount of retries must be greater than 0");
bulkOVerwriteRetries = newAmountOfRetries;
}
function getBulkOverwriteRetries() {
return bulkOVerwriteRetries;
}
async function handleRegistryAPICalls() {
container.client.emit(Events$1.ApplicationCommandRegistriesInitialising);
const commandStore = container.stores.get("commands");
for (const command of commandStore.values()) if (command.registerApplicationCommands) try {
await command.registerApplicationCommands(command.applicationCommandRegistry);
} catch (error) {
emitPerRegistryError(error, command);
}
if (getDefaultBehaviorWhenNotIdentical() === RegisterBehavior.BulkOverwrite) {
await handleBulkOverwrite(commandStore, container.client.application.commands);
return;
}
await handleAppendOrUpdate(commandStore, await getNeededRegistryParameters(allGuildIdsToFetchCommandsFor));
}
async function handleBulkOverwrite(commandStore, applicationCommands) {
const now = Date.now();
const foundGlobalCommands = [];
const foundGuildCommands = {};
for (const command of commandStore.values()) {
const registry = command.applicationCommandRegistry;
for (const call of registry["apiCalls"]) {
if (call.registerOptions.guildIds?.length) {
for (const guildId of call.registerOptions.guildIds) {
foundGuildCommands[guildId] ??= [];
foundGuildCommands[guildId].push({
piece: command,
data: call.builtData
});
}
continue;
}
foundGlobalCommands.push({
piece: command,
data: call.builtData
});
}
}
await retry(() => handleBulkOverwriteGlobalCommands(commandStore, applicationCommands, foundGlobalCommands), bulkOVerwriteRetries);
for (const [guildId, guildCommands] of Object.entries(foundGuildCommands)) await retry(() => handleBulkOverwriteGuildCommands(commandStore, applicationCommands, guildId, guildCommands), bulkOVerwriteRetries);
container.client.emit(Events$1.ApplicationCommandRegistriesRegistered, registries, Date.now() - now);
}
async function handleBulkOverwriteGlobalCommands(commandStore, applicationCommands, foundGlobalCommands) {
try {
bulkOverwriteDebug(`Overwriting global application commands, now at ${foundGlobalCommands.length} commands`);
const result = await applicationCommands.set(foundGlobalCommands.map((x) => x.data));
for (const [id, globalCommand] of result.entries()) {
const piece = foundGlobalCommands.find((x) => x.data.name === globalCommand.name)?.piece;
if (piece) {
const registry = piece.applicationCommandRegistry;
switch (globalCommand.type) {
case ApplicationCommandType.ChatInput:
registry["handleIdAddition"](InternalRegistryAPIType.ChatInput, id);
break;
case ApplicationCommandType.User:
case ApplicationCommandType.Message:
registry["handleIdAddition"](InternalRegistryAPIType.ContextMenu, id);
break;
}
commandStore.aliases.set(id, piece);
} else bulkOverwriteWarn(`Registered global command "${globalCommand.name}" (${id}) but failed to find the piece in the command store. This should not happen`);
}
container.client.emit(Events$1.ApplicationCommandRegistriesBulkOverwrite, result, null);
} catch (error) {
if (error instanceof Error && error.name === "AbortError") throw error;
emitBulkOverwriteError(error, null);
}
}
async function handleBulkOverwriteGuildCommands(commandStore, applicationCommands, guildId, guildCommands) {
try {
bulkOverwriteDebug(`Overwriting guild application commands for guild ${guildId}, now at ${guildCommands.length} commands`);
const result = await applicationCommands.set(guildCommands.map((x) => x.data), guildId);
for (const [id, guildCommand] of result.entries()) {
const piece = guildCommands.find((x) => x.data.name === guildCommand.name)?.piece;
if (piece) {
const registry = piece.applicationCommandRegistry;
switch (guildCommand.type) {
case ApplicationCommandType.ChatInput:
registry["handleIdAddition"](InternalRegistryAPIType.ChatInput, id, guildId);
break;
case ApplicationCommandType.User:
case ApplicationCommandType.Message:
registry["handleIdAddition"](InternalRegistryAPIType.ContextMenu, id, guildId);
break;
}
commandStore.aliases.set(id, piece);
} else bulkOverwriteWarn(`Registered guild command "${guildCommand.name}" (${id}) but failed to find the piece in the command store. This should not happen`);
}
container.client.emit(Events$1.ApplicationCommandRegistriesBulkOverwrite, result, guildId);
} catch (error) {
if (error instanceof Error && error.name === "AbortError") throw error;
emitBulkOverwriteError(error, guildId);
}
}
async function handleAppendOrUpdate(commandStore, { applicationCommands, globalCommands, guildCommands }) {
const now = Date.now();
for (const registry of registries.values()) {
await registry["runAPICalls"](applicationCommands, globalCommands, guildCommands);
const piece = registry.command;
if (piece) {
for (const nameOrId of piece.applicationCommandRegistry.chatInputCommands) commandStore.aliases.set(nameOrId, piece);
for (const nameOrId of piece.applicationCommandRegistry.contextMenuCommands) commandStore.aliases.set(nameOrId, piece);
}
}
container.client.emit(Events$1.ApplicationCommandRegistriesRegistered, registries, Date.now() - now);
}
//#endregion
export { acquire, allGuildIdsToFetchCommandsFor, defaultBehaviorWhenNotIdentical, defaultGuildIds, getBulkOverwriteRetries, getDefaultBehaviorWhenNotIdentical, getDefaultGuildIds, handleBulkOverwrite, handleRegistryAPICalls, registries, setBulkOverwriteRetries, setDefaultBehaviorWhenNotIdentical, setDefaultGuildIds };
//# sourceMappingURL=ApplicationCommandRegistries.mjs.map