Skip to content

Commit

Permalink
docs: add jsdoc for project
Browse files Browse the repository at this point in the history
  • Loading branch information
SocketSomeone committed Mar 11, 2024
1 parent 4af3843 commit 457ca51
Show file tree
Hide file tree
Showing 51 changed files with 459 additions and 5 deletions.
18 changes: 18 additions & 0 deletions src/commands/command.discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,39 @@ export interface BaseCommandMeta extends BaseApplicationCommandData {
guilds?: Snowflake[];
}

/**
* Represents a command discovery.
* @abstract
* @url https://necord.org/interactions/slash-commands
*/
export abstract class CommandDiscovery<
T extends BaseCommandMeta = BaseCommandMeta
> extends NecordBaseDiscovery<T> {
/**
* Returns the command name.
*/
public getName() {
return this.meta.name;
}

/**
* Sets the command guilds for register.
* @param guilds
*/
public setGuilds(guilds: Snowflake[]) {
this.meta.guilds = guilds;
}

/**
* Checks if the command has a guild.
*/
public hasGuild(guild: Snowflake) {
return this.meta.guilds?.includes(guild);
}

/**
* Returns the guilds.
*/
public getGuilds(): Snowflake[] {
return this.meta.guilds;
}
Expand Down
12 changes: 12 additions & 0 deletions src/commands/commands.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { CommandDiscovery } from './command.discovery';
import { ContextMenusService } from './context-menus';
import { SlashCommandsService } from './slash-commands';

/**
* Represents a service that manages commands.
* @url https://necord.org/interactions/slash-commands
*/
@Injectable()
export class CommandsService {
private readonly logger = new Logger(CommandsService.name);
Expand All @@ -14,6 +18,10 @@ export class CommandsService {
private readonly slashCommandsService: SlashCommandsService
) {}

/**
* Registers all commands.
*
*/
public async registerAllCommands() {
const guilds = new Set(this.getCommandsByGuilds().keys());

Expand All @@ -24,6 +32,10 @@ export class CommandsService {
this.logger.log(`Successfully reloaded application commands.`);
}

/**
* Registers commands in a guild.
* @param guildId
*/
public async registerInGuild(guildId: string) {
const commands = this.getGuildCommands(guildId);

Expand Down
21 changes: 21 additions & 0 deletions src/commands/context-menus/context-menu.discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,44 @@ import {
} from 'discord.js';
import { CommandDiscovery } from '../command.discovery';

/**
* The context menu metadata.
*/
export type ContextMenuMeta = (MessageApplicationCommandData | UserApplicationCommandData) & {
guilds?: Snowflake[];
};

/**
* The context menu discovery.
* @see CommandDiscovery
* @see ContextMenuMeta
*/
export class ContextMenuDiscovery extends CommandDiscovery<ContextMenuMeta> {
/**
* Gets the discovery type.
*/
public getType() {
return this.meta.type;
}

/**
* Type guard for the context menu discovery.
*/
public isContextMenu(): this is ContextMenuDiscovery {
return true;
}

/**
* Executes the context menu discovery.
* @param interaction The interaction to execute.
*/
public execute(interaction: ContextMenuCommandInteraction): any {
return super.execute([interaction]);
}

/**
* Converts the context menu discovery to JSON.
*/
public override toJSON() {
return this.meta;
}
Expand Down
8 changes: 8 additions & 0 deletions src/commands/context-menus/context-menus.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ import { Collection } from 'discord.js';
import { Injectable, Logger } from '@nestjs/common';
import { ContextMenuDiscovery, ContextMenuMeta } from './context-menu.discovery';

/**
* Service that manages context menus.
* @see ContextMenuDiscovery
* @see ContextMenuMeta
* @see ContextMenu
* @see MessageCommand
* @see UserCommand
*/
@Injectable()
export class ContextMenusService {
private readonly logger = new Logger(ContextMenusService.name);
Expand Down
10 changes: 10 additions & 0 deletions src/commands/context-menus/decorators/context-menu.decorator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { ContextMenuDiscovery, ContextMenuMeta } from '../context-menu.discovery';
import { Reflector } from '@nestjs/core';

/**
* Decorator that marks a method as a context menu.
* @param options The context menu options.
* @returns The decorated method.
* @see ContextMenuDiscovery
* @see ContextMenuMeta
* @see MessageCommand
* @see UserCommand
* @url https://necord.org/interactions/context-menus
*/
export const ContextMenu = Reflector.createDecorator<ContextMenuMeta, ContextMenuDiscovery>({
transform: options => new ContextMenuDiscovery(options)
});
16 changes: 16 additions & 0 deletions src/commands/context-menus/decorators/message-command.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,21 @@ import { ContextMenuMeta } from '../context-menu.discovery';
import { ApplicationCommandType } from 'discord.js';
import { ContextMenu } from './context-menu.decorator';

/**
* Decorator that marks a method as a message context menu.
* @param options The context menu options.
* @returns The decorated method.
* @see ContextMenu
* @see ContextMenuMeta
* @see TargetMessage
* @url https://necord.org/interactions/context-menus#message-commands
* @example
* ```ts
* @MessageCommand({ name: 'quote', type: 'MESSAGE' })
* public async quote(@TargetMessage() message: Message) {
* message.reply('Quoting...');
* }
* ```
*/
export const MessageCommand = (options: Omit<ContextMenuMeta, 'type'>) =>
ContextMenu({ type: ApplicationCommandType.Message, ...options });
42 changes: 42 additions & 0 deletions src/commands/context-menus/decorators/target.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ export const Target = createParamDecorator((_, context) => {
: interaction.options.getUser('user');
});

/**
* Decorator that injects the target message of a message context menu command.
* @see TargetUser
* @see TargetMember
* @see MessageCommand
* @returns The target message.
* @example
* ```ts
* @MessageCommand({ name: 'quote', type: 'MESSAGE' })
* public async quote(@TargetMessage() message: Message) {
* message.reply('Quoting...');
* }
* ```
*/
export const TargetMessage = createParamDecorator((_, context) => {
const necordContext = NecordExecutionContext.create(context);
const [interaction] = necordContext.getContext<'interactionCreate'>();
Expand All @@ -24,6 +38,20 @@ export const TargetMessage = createParamDecorator((_, context) => {
return interaction.targetMessage;
});

/**
* Decorator that injects the target user of a user context menu command.
* @see TargetMessage
* @see TargetMember
* @see UserCommand
* @returns The target user.
* @example
* ```ts
* @UserCommand({ name: 'kick', type: 'USER' })
* public async avatar(@TargetUser() user: User) {
* user.avatarURL();
* }
* ```
*/
export const TargetUser = createParamDecorator((_, context) => {
const necordContext = NecordExecutionContext.create(context);
const [interaction] = necordContext.getContext<'interactionCreate'>();
Expand All @@ -33,6 +61,20 @@ export const TargetUser = createParamDecorator((_, context) => {
return interaction.targetUser;
});

/**
* Decorator that injects the target member of a user context menu command.
* @see TargetMessage
* @see TargetUser
* @see UserCommand
* @returns The target member.
* @example
* ```ts
* @UserCommand({ name: 'ban', type: 'USER' })
* public async ban(@TargetMember() member: GuildMember) {
* member.ban();
* }
* ```
*/
export const TargetMember = createParamDecorator((_, context) => {
const necordContext = NecordExecutionContext.create(context);
const [interaction] = necordContext.getContext<'interactionCreate'>();
Expand Down
17 changes: 17 additions & 0 deletions src/commands/context-menus/decorators/user-command.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,22 @@ import { ApplicationCommandType } from 'discord.js';
import { ContextMenuMeta } from '../context-menu.discovery';
import { ContextMenu } from './context-menu.decorator';

/**
* Decorator that marks a method as a user context menu.
* @param options The context menu options.
* @returns The decorated method.
* @see ContextMenu
* @see ContextMenuMeta
* @see TargetUser
* @see TargetMessage
* @url https://necord.org/interactions/context-menus#user-commands
* @example
* ```ts
* @UserCommand({ name: 'ping' })
* public async ping(@TargetUser() user: User) {
* user.send('Pong!');
* }
* ```
*/
export const UserCommand = (options: Omit<ContextMenuMeta, 'type'>) =>
ContextMenu({ type: ApplicationCommandType.User, ...options });
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { Observable, of } from 'rxjs';
import { AutocompleteContext, NecordExecutionContext } from '../../../context';
import { AutocompleteInteraction } from 'discord.js';

/**
* The autocomplete interceptor.
* @see AutocompleteContext
* @see AutocompleteInteraction
* @url https://necord.org/interactions/slash-commands#autocomplete
*/
@Injectable()
export abstract class AutocompleteInterceptor implements NestInterceptor {
public abstract transformOptions(interaction: AutocompleteInteraction): void | Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import { SlashCommandDiscovery, SlashCommandMeta } from '../slash-command.discov
import { ApplicationCommandType } from 'discord.js';
import { Reflector } from '@nestjs/core';

/**
* Decorator that marks a method as a slash command.
* @param options The slash command options.
* @returns The decorated method.
* @see SlashCommandDiscovery
* @see SlashCommandMeta
* @url https://necord.org/interactions/slash-commands
*
*/
export const SlashCommand = Reflector.createDecorator<
Omit<SlashCommandMeta, 'type' | 'options'>,
SlashCommandDiscovery
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import { SlashCommand } from './slash-command.decorator';
import { noop } from 'rxjs';
import { Reflector } from '@nestjs/core';

/**
* Decorator that marks a method as a subcommand.
* @param options The subcommand options.
* @returns The decorated method.
* @see SlashCommandDiscovery
* @url https://necord.org/interactions/slash-commands#groups
*/
export const SubcommandGroup = Reflector.createDecorator<
Omit<SlashCommandMeta, 'type' | 'options' | 'guilds' | 'defaultMemberPermissions'>,
SlashCommandDiscovery
Expand All @@ -16,6 +23,14 @@ export const SubcommandGroup = Reflector.createDecorator<
})
});

/**
* Factory that creates a decorator that marks a class as a slash command group.
* @param rootOptions
* @returns The decorator.
* @see SlashCommand
* @see SubcommandGroup
* @url https://necord.org/interactions/slash-commands#groups
*/
export const createCommandGroupDecorator = (rootOptions: Omit<SlashCommandMeta, 'type'>) => {
const rootCommand = SlashCommand(rootOptions);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { SlashCommandDiscovery, SlashCommandMeta } from '../slash-command.discovery';
import { ApplicationCommandOptionType } from 'discord.js';
import { Reflector } from '@nestjs/core';
import { SlashCommand } from './slash-command.decorator';

/**
* Decorator that marks a method as a subcommand.
* @param options The subcommand options.
* @returns The decorated method.
* @see SlashCommandDiscovery
* @url https://necord.org/interactions/slash-commands#groups
*/
export const Subcommand = Reflector.createDecorator<
Omit<SlashCommandMeta, 'type' | 'options' | 'guilds' | 'defaultMemberPermissions'>,
SlashCommandDiscovery
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ApplicationCommandOptionType, APIApplicationCommandAttachmentOption } from 'discord.js';
import { createOptionDecorator } from './option.util';

/**
* Param decorator that marks a method as an attachment option.
* @param options The attachment options.
* @returns The decorated method.
* @url https://necord.org/interactions/slash-commands#options
*/
export const AttachmentOption = createOptionDecorator<APIApplicationCommandAttachmentOption>(
ApplicationCommandOptionType.Attachment,
'getAttachment'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ApplicationCommandOptionType, APIApplicationCommandBooleanOption } from 'discord.js';
import { createOptionDecorator } from './option.util';

/**
* Param decorator that marks a method as a boolean option.
* @param options The boolean options.
* @returns The decorated method.
* @url https://necord.org/interactions/slash-commands#options
*/
export const BooleanOption = createOptionDecorator<APIApplicationCommandBooleanOption>(
ApplicationCommandOptionType.Boolean,
'getBoolean'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ApplicationCommandOptionType, APIApplicationCommandChannelOption } from 'discord.js';
import { createOptionDecorator } from './option.util';

/**
* Param decorator that marks a method as a channel option.
* @param options The channel options.
* @returns The decorated method.
* @url https://necord.org/interactions/slash-commands#options
*/
export const ChannelOption = createOptionDecorator<APIApplicationCommandChannelOption>(
ApplicationCommandOptionType.Channel,
'getChannel'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ApplicationCommandOptionType, APIApplicationCommandIntegerOption } from 'discord.js';
import { createOptionDecorator } from './option.util';

/**
* Param decorator that marks a method as an integer option.
* @param options The integer options.
* @returns The decorated method.
* @url https://necord.org/interactions/slash-commands#options
*/
export const IntegerOption = createOptionDecorator<APIApplicationCommandIntegerOption>(
ApplicationCommandOptionType.Integer,
'getInteger'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { ApplicationCommandOptionType, APIApplicationCommandUserOption } from 'discord.js';
import { createOptionDecorator } from './option.util';

/**
* Param decorator that marks a method as a member option.
* @param options The member options.
* @returns The decorated method.
* @url https://necord.org/interactions/slash-commands#options
*/
export const MemberOption = createOptionDecorator<APIApplicationCommandUserOption>(
ApplicationCommandOptionType.User,
'getMember'
Expand Down
Loading

0 comments on commit 457ca51

Please sign in to comment.