Skip to content

Commit

Permalink
Merge pull request #217 from ghostdevv/doc-comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ghostdevv authored Nov 8, 2024
2 parents ff14a18 + 6697f39 commit f120f68
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/large-feet-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"jellycommands": patch
---

feat: add more jsdoc comments to exports
40 changes: 40 additions & 0 deletions packages/jellycommands/src/JellyCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,47 @@ import {
jellyCommandsOptionsSchema,
} from './options';

/**
* JellyCommands wraps the discord.js Client to provide a framework for building Discord Bots.
* If you’re familiar with discord.js you’ll see the similarities:
*
* ```js
* import { JellyCommands } from 'jellycommands';
* import { IntentsBitField } from 'discord.js';
*
* const client = new JellyCommands({
* clientOptions: {
* intents: [IntentsBitField.Flags.Guilds],
* },
* });
*
* client.login();
* ```
*
* @see https://jellycommands.dev/guide/overview/#the-client
*/
export class JellyCommands extends Client {
// todo these options include data that isn't relevant (like given components) so mayb shouldn't be here
/**
* The options you pass to JellyCommands when creating your client.
*/
public readonly joptions: JellyCommandsOptions;

/**
* todo https://github.com/ghostdevv/jellycommands/issues/209
*/
private readonly plugins: SortedPlugins;

/**
* Props are used to pass data around your client.
* @see https://jellycommands.dev/guide/props/
*/
public readonly props: Props;

/**
* A wrapper of console.log that adds a nice prefix.
* Designed for internal use, so won't expand upon current functionality.
*/
public readonly log: Logger;

constructor(options: JellyCommandsOptions) {
Expand Down Expand Up @@ -56,6 +92,10 @@ export class JellyCommands extends Client {
};
}

/**
* Internal fetch wrapper for making Discord API requests.
* Please don't use this, as it may have breaking changes or disappear.
*/
async $fetch<
R = any,
D extends Record<string, any> = any,
Expand Down
8 changes: 8 additions & 0 deletions packages/jellycommands/src/components/buttons/buttons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export type ButtonCallback = (context: {
interaction: ButtonInteraction;
}) => MaybePromise<any>;

/**
* Represents a button.
* @see https://jellycommands.dev/guide/buttons/files/
*/
export class Button extends Component<ButtonOptions> {
public readonly options: ButtonOptions;

Expand All @@ -28,6 +32,10 @@ export class Button extends Component<ButtonOptions> {
}
}

/**
* Creates a button.
* @see https://jellycommands.dev/guide/buttons/files/
*/
export const button = (options: ButtonOptions & { run: ButtonCallback }) => {
const { run, ...rest } = options;
return new Button(rest, run);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,19 @@ export abstract class BaseCommand<
OptionsType extends BaseOptions = BaseOptions,
InteractionType extends AnyCommandInteraction = AnyCommandInteraction,
> extends Component<OptionsType> {
/**
* The options you pass to when creating this command.
*/
public readonly options: OptionsType;

/**
* The callback function to call when your command is executed.
*/
public readonly run: CommandCallback<InteractionType>;

/**
* The command type for API purposes.
*/
public abstract readonly type: ApplicationCommandType;

constructor({
Expand Down Expand Up @@ -75,6 +85,9 @@ export abstract class BaseCommand<
}
}

/**
* This is for internal use and is subject to change.
*/
get applicationCommandData(): RESTPostAPIApplicationCommandsJSONBody {
return {
name: this.options.name,
Expand All @@ -86,6 +99,9 @@ export abstract class BaseCommand<
};
}

/**
* This is for internal use and is subject to change.
*/
get applicationCommandPermissions(): string | null {
if (this.options.guards?.permissions) {
const { bitfield } = new PermissionsBitField(
Expand All @@ -97,6 +113,9 @@ export abstract class BaseCommand<
return null;
}

/**
* This is for internal use and is subject to change.
*/
get hashId() {
return createHash('sha256')
.update(JSON.stringify(this.applicationCommandData))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export type AutocompleteHandler = (options: {
client: JellyCommands;
}) => MaybePromise<any>;

/**
* Represents a slash command.
* @see https://jellycommands.dev/guide/commands/files/#slash-commands
*/
export class Command extends BaseCommand<
CommandOptions,
ChatInputCommandInteraction
Expand All @@ -46,6 +50,9 @@ export class Command extends BaseCommand<
this.autocomplete = autocomplete;
}

/**
* This is for internal use and is subject to change.
*/
static transformOptionType(
option: JellyApplicationCommandOption,
): ApplicationCommandOptionData {
Expand All @@ -71,6 +78,9 @@ export class Command extends BaseCommand<
return { ...option, options, type } as ApplicationCommandOption;
}

/**
* This is for internal use and is subject to change.
*/
static transformOption(
option: JellyApplicationCommandOption,
): APIApplicationCommandOption {
Expand All @@ -96,8 +106,15 @@ export class Command extends BaseCommand<
}
}

/**
* Creates a slash command.
* @see https://jellycommands.dev/guide/commands/files/#slash-commands
*/
export const command = (
options: CommandOptions & {
/**
* The callback function to call when your command is executed.
*/
run: CommandCallback<ChatInputCommandInteraction>;
autocomplete?: AutocompleteHandler;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { messageCommandSchema, type MessageCommandOptions } from './options';
import { ApplicationCommandType } from 'discord-api-types/v10';
import { BaseCommand } from '../BaseCommand';

/**
* Represents a Message Context Menu command.
* @see https://jellycommands.dev/guide/commands/files/#message-commands
*/
export class MessageCommand extends BaseCommand<
MessageCommandOptions,
MessageContextMenuCommandInteraction
Expand All @@ -19,8 +23,15 @@ export class MessageCommand extends BaseCommand<
}
}

/**
* Creates a Message Context Menu command.
* @see https://jellycommands.dev/guide/commands/files/#message-commands
*/
export const messageCommand = (
options: MessageCommandOptions & {
/**
* The callback function to call when your command is executed.
*/
run: CommandCallback<MessageContextMenuCommandInteraction>;
},
) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { userCommandSchema, type UserCommandOptions } from './options';
import { ApplicationCommandType } from 'discord-api-types/v10';
import { BaseCommand } from '../BaseCommand';

/**
* Represents a User Context Menu command.
* @see https://jellycommands.dev/guide/commands/files/#user-commands
*/
export class UserCommand extends BaseCommand<
UserCommandOptions,
UserContextMenuCommandInteraction
Expand All @@ -19,8 +23,15 @@ export class UserCommand extends BaseCommand<
}
}

/**
* Creates a User Context Menu command.
* @see https://jellycommands.dev/guide/commands/files/#user-commands
*/
export const userCommand = (
options: UserCommandOptions & {
/**
* The callback function to call when your command is executed.
*/
run: CommandCallback<UserContextMenuCommandInteraction>;
},
) => {
Expand Down
3 changes: 3 additions & 0 deletions packages/jellycommands/src/components/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export interface BaseComponentOptions {

export const COMPONENT_SYMBOL = Symbol.for('jellycommands.component');

/**
* In JellyCommands component is a part of your Discord bot such as a `command`/`event`/etc.
*/
export abstract class Component<
O extends BaseComponentOptions = BaseComponentOptions,
> {
Expand Down
31 changes: 31 additions & 0 deletions packages/jellycommands/src/components/events/Event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@ import { EVENTS_COMPONENT_ID } from './plugin';
import type { ClientEvents } from 'discord.js';
import { parseSchema } from '../../utils/zod';

/**
* The Discord event name
* @see https://discord.js.org/docs/packages/discord.js/14.16.3/ClientEvents:Interface
*/
export type EventName = keyof ClientEvents | (string & {});

/**
* This callback will be run when your event is fired.
* It takes in a base JellyCommands context as it's first param,
* followed by all the arguments your event provides.
*
* @see https://jellycommands.dev/guide/events/files/
*/
export type EventCallback<E extends EventName> = (
ctx: { client: JellyCommands; props: Props },
...args: E extends keyof ClientEvents ? ClientEvents[E] : any[]
) => MaybePromise<any>;

export class Event<T extends EventName = EventName> extends Component {
/**
* The options you pass to when creating this event.
*/
public readonly options: Required<EventOptions<T>>;

constructor(
Expand All @@ -38,13 +52,30 @@ export class Event<T extends EventName = EventName> extends Component {
);
}

/**
* Type narrowing utility to check whether something is an event.
* @param item The thing to check
*/
static is(item: any): item is Event {
return isComponent(item) && item.id === EVENTS_COMPONENT_ID;
}
}

/**
* This creates an event component for your bot. Events can be used
* to respond to actions such as a new user joining a guild.
*
* @see https://jellycommands.dev/guide/events/files/
*/
export const event = <K extends EventName>(
options: EventOptions<K> & {
/**
* This callback will be run when your event is fired.
* It takes in a base JellyCommands context as it's first param,
* followed by all the arguments your event provides.
*
* @see https://jellycommands.dev/guide/events/files/
*/
run: EventCallback<K>;
},
) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/jellycommands/src/components/events/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import type { EventName } from './Event';
export interface EventOptions<Event extends EventName>
extends BaseComponentOptions {
/**
* The event name: https://discord.js.org/#/docs/main/stable/class/Client
* The Discord event name
* @see https://discord.js.org/docs/packages/discord.js/14.16.3/ClientEvents:Interface
*/
name: Event;

Expand Down
41 changes: 34 additions & 7 deletions packages/jellycommands/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ export interface JellyCommandsOptions {
components?: LoadableComponents;

/**
* Base discord.js client options
* You can use this to pass options to the base Discord.js client.
* This will need to be used to set `intents` at a minimum.
*
* @see https://discord.js.org/docs/packages/discord.js/14.16.3/ClientOptions:Interface
*/
clientOptions: ClientOptions;

Expand All @@ -76,22 +79,37 @@ export interface JellyCommandsOptions {
// plugins?: AnyPlugin[];

/**
* Inital props
* Props are used to pass data around your client.
* @see https://jellycommands.dev/guide/props/
*/
props?: Props;

/**
* Customisable responses
* This allows you to control the default messages sent by JellyCommands
* when your code is unable to handle them. Currently only handles
* an unknownCommand state.
*
* @see https://jellycommands.dev/guide/messages/
*/
messages?: {
/**
* This is sent when a unknown command is given
* This is sent when your bot recieves an unknown command. This only
* happens if your user sends a command just as you re-register them
* as we respond to commands based on id rather than name currently.
*
* @see https://jellycommands.dev/guide/messages/#unknown-command
*/
unknownCommand?: string | MessagePayload | InteractionReplyOptions;
};

/**
* Developer mode options
* Developer mode makes it easier to iterate on your commands
* by registering them locally to a guild rather than locally.
* Discord checks for fresh guild commands every time, while global
* commands are only checked periodically. You should enable this
* when developing, and disable this in production.
*
* @see https://jellycommands.dev/guide/commands/dev/
*/
dev?: {
/**
Expand All @@ -106,13 +124,22 @@ export interface JellyCommandsOptions {
};

/**
* Should jelly cache commands - highly recommended
* Controls whether commands should be cached. This allows for restarting
* your Discord Bot repeatedly without having to re-register commands each
* time. It computes a hash of all your commands, and stores it locally to
* the `.jellycommands` folder which you should add to your git ignore.
* When you run your bot it uses this to see if you made any changes to your
* commands. If you have it'll automatically re-register them!
*
* We recommend you leave this on, at least when developing.
*
* @default true
*/
cache?: boolean;

/**
* Whether jelly should emit debug messages
* Controls whether debug messages are logged to console.
* By default it's false, unless the `DEBUG` environment variable is set.
*/
debug?: boolean;

Expand Down

0 comments on commit f120f68

Please sign in to comment.