Command: Add integration and context types
While discord api supports that, discord api types, which discord.js depends on does not.
This commit is contained in:
parent
0e5c8d22cc
commit
63cb52e7f4
2 changed files with 59 additions and 3 deletions
|
@ -4,13 +4,25 @@ import { REST, RESTGetAPIOAuth2CurrentApplicationResult, RESTPostAPIApplicationC
|
||||||
import { config } from "../src/index";
|
import { config } from "../src/index";
|
||||||
import requireDirectory from "require-directory";
|
import requireDirectory from "require-directory";
|
||||||
|
|
||||||
import Command from "../src/command";
|
import
|
||||||
|
Command
|
||||||
|
, {
|
||||||
|
ApplicationIntegrationType
|
||||||
|
, InteractionContextTypes
|
||||||
|
, InteractionTypeMap
|
||||||
|
} from "../src/command";
|
||||||
|
|
||||||
const post: RESTPostAPIApplicationCommandsJSONBody[] = [];
|
const post: RESTPostAPIApplicationCommandsJSONBody[] = [];
|
||||||
|
|
||||||
const guildId = process.argv.slice(2)[0];
|
const guildId = process.argv.slice(2)[0];
|
||||||
const importedCommands = requireDirectory(module, "../src/commands");
|
const importedCommands = requireDirectory(module, "../src/commands");
|
||||||
|
|
||||||
|
function isGuildCommand(command: Command<keyof InteractionTypeMap>): boolean {
|
||||||
|
// guild Commmand is when it's a guild install and context is guild (and these are defaults if not provided)
|
||||||
|
return (command.integration_types?.includes(ApplicationIntegrationType.Guild_Install) ?? true)
|
||||||
|
&& (command.contexts?.includes(InteractionContextTypes.Guild) ?? true);
|
||||||
|
}
|
||||||
|
|
||||||
for (const obj in importedCommands) {
|
for (const obj in importedCommands) {
|
||||||
try {
|
try {
|
||||||
const allExports = importedCommands[obj] as {default: unknown};
|
const allExports = importedCommands[obj] as {default: unknown};
|
||||||
|
@ -19,6 +31,10 @@ for (const obj in importedCommands) {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const constructedExport = new defaultExport() as unknown;
|
const constructedExport = new defaultExport() as unknown;
|
||||||
if (!(constructedExport instanceof Command)) throw new Error(`${obj}'s default does not extends Command`);
|
if (!(constructedExport instanceof Command)) throw new Error(`${obj}'s default does not extends Command`);
|
||||||
|
if (guildId && guildId !== "" && isGuildCommand(constructedExport as Command<keyof InteractionTypeMap>)) {
|
||||||
|
console.log(`Skipping ${obj} because it's not a guild command`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
post.push(constructedExport.toRESTPostApplicationCommands());
|
post.push(constructedExport.toRESTPostApplicationCommands());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
|
@ -2,12 +2,47 @@ import { AutocompleteInteraction, PermissionsBitField } from "discord.js";
|
||||||
import { RESTPostAPIApplicationCommandsJSONBody } from "discord.js";
|
import { RESTPostAPIApplicationCommandsJSONBody } from "discord.js";
|
||||||
import { APIApplicationCommandOption, ApplicationCommandType, ChatInputCommandInteraction, LocalizationMap, MessageInteraction, PermissionResolvable, UserSelectMenuInteraction } from "discord.js";
|
import { APIApplicationCommandOption, ApplicationCommandType, ChatInputCommandInteraction, LocalizationMap, MessageInteraction, PermissionResolvable, UserSelectMenuInteraction } from "discord.js";
|
||||||
|
|
||||||
type InteractionTypeMap = {
|
export type InteractionTypeMap = {
|
||||||
|
// [CommandType]: [Interaction, Description]
|
||||||
[ApplicationCommandType.ChatInput]: [ChatInputCommandInteraction, string];
|
[ApplicationCommandType.ChatInput]: [ChatInputCommandInteraction, string];
|
||||||
[ApplicationCommandType.Message]: [MessageInteraction, never];
|
[ApplicationCommandType.Message]: [MessageInteraction, never];
|
||||||
[ApplicationCommandType.User]: [UserSelectMenuInteraction, never];
|
[ApplicationCommandType.User]: [UserSelectMenuInteraction, never];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: At time of coding, Discord api types doesn't support user installations of bot/application yet
|
||||||
|
// replace this with the types from the discord api types when it's available
|
||||||
|
/**
|
||||||
|
* https://discord.com/developers/docs/resources/application#application-object-application-integration-types
|
||||||
|
*/
|
||||||
|
export enum ApplicationIntegrationType {
|
||||||
|
Guild_Install = 0,
|
||||||
|
User_Install = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-context-types
|
||||||
|
*/
|
||||||
|
export enum InteractionContextTypes {
|
||||||
|
Guild = 0,
|
||||||
|
BotDM = 1,
|
||||||
|
PrivateChannel = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-structure
|
||||||
|
*/
|
||||||
|
export type FutureRESTPostAPIApplicationCommandsJSONBody =
|
||||||
|
RESTPostAPIApplicationCommandsJSONBody
|
||||||
|
& {
|
||||||
|
/**
|
||||||
|
* @deprecated use contexts instead
|
||||||
|
*/
|
||||||
|
dm_permission?: boolean;
|
||||||
|
integration_types?: ApplicationIntegrationType[];
|
||||||
|
contexts?: InteractionContextTypes[];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
interface Command<Type extends keyof InteractionTypeMap = ApplicationCommandType> {
|
interface Command<Type extends keyof InteractionTypeMap = ApplicationCommandType> {
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly name_localizations?: LocalizationMap;
|
readonly name_localizations?: LocalizationMap;
|
||||||
|
@ -17,7 +52,10 @@ interface Command<Type extends keyof InteractionTypeMap = ApplicationCommandType
|
||||||
readonly default_member_permissions?: PermissionResolvable;
|
readonly default_member_permissions?: PermissionResolvable;
|
||||||
readonly type: Type;
|
readonly type: Type;
|
||||||
readonly nsfw?: boolean;
|
readonly nsfw?: boolean;
|
||||||
|
/** @deprecated use contexts instead */
|
||||||
readonly dm_permission?: boolean;
|
readonly dm_permission?: boolean;
|
||||||
|
readonly integration_types?: ApplicationIntegrationType[];
|
||||||
|
readonly contexts?: InteractionContextTypes[];
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Command<Type extends keyof InteractionTypeMap = ApplicationCommandType> {
|
abstract class Command<Type extends keyof InteractionTypeMap = ApplicationCommandType> {
|
||||||
|
@ -25,7 +63,7 @@ abstract class Command<Type extends keyof InteractionTypeMap = ApplicationComman
|
||||||
|
|
||||||
autocomplete?(interaction: Type extends ApplicationCommandType.ChatInput ? AutocompleteInteraction : never ): Promise<void>;
|
autocomplete?(interaction: Type extends ApplicationCommandType.ChatInput ? AutocompleteInteraction : never ): Promise<void>;
|
||||||
|
|
||||||
toRESTPostApplicationCommands(): RESTPostAPIApplicationCommandsJSONBody {
|
toRESTPostApplicationCommands(): FutureRESTPostAPIApplicationCommandsJSONBody {
|
||||||
return {
|
return {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
name_localizations: this.name_localizations,
|
name_localizations: this.name_localizations,
|
||||||
|
@ -36,6 +74,8 @@ abstract class Command<Type extends keyof InteractionTypeMap = ApplicationComman
|
||||||
type: this.type,
|
type: this.type,
|
||||||
nsfw: this.nsfw,
|
nsfw: this.nsfw,
|
||||||
dm_permission: this.dm_permission,
|
dm_permission: this.dm_permission,
|
||||||
|
integration_types: this.integration_types,
|
||||||
|
contexts: this.contexts,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue