Skip to content

Commit

Permalink
feat: more resolvers
Browse files Browse the repository at this point in the history
  • Loading branch information
samfundev committed Aug 6, 2022
1 parent a8503e2 commit cdd4955
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 19 deletions.
5 changes: 3 additions & 2 deletions src/lib/resolvers/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { container } from '@sapphire/pieces';
import { Result } from '@sapphire/result';
import type { Message, Snowflake } from 'discord.js';
import { Identifiers } from '../errors/Identifiers';
import { resolveId, IdResolvable } from '../utils/resolvers/resolveId';

export function resolveChannel(parameter: string, message: Message): Result<ChannelTypes, Identifiers.ArgumentChannelError> {
const channelId = (ChannelMentionRegex.exec(parameter)?.[1] ?? parameter) as Snowflake;
export function resolveChannel(parameter: IdResolvable, message: Message): Result<ChannelTypes, Identifiers.ArgumentChannelError> {
const channelId = resolveId(parameter, ChannelMentionRegex, 'channels') as Snowflake;
const channel = (message.guild ? message.guild.channels : container.client.channels).cache.get(channelId);
if (channel) return Result.ok(channel as ChannelTypes);
return Result.err(Identifiers.ArgumentChannelError);
Expand Down
12 changes: 7 additions & 5 deletions src/lib/resolvers/member.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { SnowflakeRegex, UserOrMemberMentionRegex } from '@sapphire/discord-utilities';
import { UserOrMemberMentionRegex } from '@sapphire/discord-utilities';
import { Result } from '@sapphire/result';
import type { Guild, GuildMember, Snowflake } from 'discord.js';
import { Identifiers } from '../errors/Identifiers';
import { resolveId, IdResolvable } from '../utils/resolvers/resolveId';

export async function resolveMember(parameter: string, guild: Guild): Promise<Result<GuildMember, Identifiers.ArgumentMemberError>> {
export async function resolveMember(parameter: IdResolvable, guild: Guild): Promise<Result<GuildMember, Identifiers.ArgumentMemberError>> {
const member = (await resolveById(parameter, guild)) ?? (await resolveByQuery(parameter, guild));
if (member) return Result.ok(member);
return Result.err(Identifiers.ArgumentMemberError);
}

async function resolveById(argument: string, guild: Guild): Promise<GuildMember | null> {
const memberId = UserOrMemberMentionRegex.exec(argument) ?? SnowflakeRegex.exec(argument);
async function resolveById(argument: IdResolvable, guild: Guild): Promise<GuildMember | null> {
const memberId = resolveId(argument, UserOrMemberMentionRegex, 'members');
return memberId ? guild.members.fetch(memberId[1] as Snowflake).catch(() => null) : null;
}

async function resolveByQuery(argument: string, guild: Guild): Promise<GuildMember | null> {
async function resolveByQuery(argument: IdResolvable, guild: Guild): Promise<GuildMember | null> {
if (typeof argument !== 'string') return null;
argument = argument.length > 5 && argument.at(-5) === '#' ? argument.slice(0, -5) : argument;

const members = await guild.members.fetch({ query: argument, limit: 1 }).catch(() => null);
Expand Down
5 changes: 3 additions & 2 deletions src/lib/resolvers/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import {
import { container } from '@sapphire/pieces';
import { Result } from '@sapphire/result';
import type { Awaitable } from '@sapphire/utilities';
import { BaseCommandInteraction, Message, Permissions, Snowflake, User } from 'discord.js';
import { Message, Permissions, Snowflake, User } from 'discord.js';
import { Identifiers } from '../errors/Identifiers';
import type { IdResolvable } from '../utils/resolvers/resolveId';

/**
* Options to resolve a message from a string, given a certain context.
Expand All @@ -35,7 +36,7 @@ export interface MessageResolverOptions {
}

export async function resolveMessage(
parameter: string | BaseCommandInteraction,
parameter: IdResolvable,
options: MessageResolverOptions
): Promise<Result<Message, Identifiers.ArgumentMessageError>> {
if (typeof parameter === 'string') {
Expand Down
12 changes: 7 additions & 5 deletions src/lib/resolvers/role.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { RoleMentionRegex, SnowflakeRegex } from '@sapphire/discord-utilities';
import { RoleMentionRegex } from '@sapphire/discord-utilities';
import { Result } from '@sapphire/result';
import type { Guild, Role, Snowflake } from 'discord.js';
import { Identifiers } from '../errors/Identifiers';
import { resolveId, IdResolvable } from '../utils/resolvers/resolveId';

export async function resolveRole(parameter: string, guild: Guild): Promise<Result<Role, Identifiers.ArgumentRoleError>> {
export async function resolveRole(parameter: IdResolvable, guild: Guild): Promise<Result<Role, Identifiers.ArgumentRoleError>> {
const role = (await resolveById(parameter, guild)) ?? resolveByQuery(parameter, guild);
if (role) return Result.ok(role);
return Result.err(Identifiers.ArgumentRoleError);
}

async function resolveById(argument: string, guild: Guild): Promise<Role | null> {
const roleId = RoleMentionRegex.exec(argument) ?? SnowflakeRegex.exec(argument);
async function resolveById(argument: IdResolvable, guild: Guild): Promise<Role | null> {
const roleId = resolveId(argument, RoleMentionRegex, 'roles');
return roleId ? guild.roles.fetch(roleId[1] as Snowflake) : null;
}

function resolveByQuery(argument: string, guild: Guild): Role | null {
function resolveByQuery(argument: IdResolvable, guild: Guild): Role | null {
if (typeof argument !== 'string') return null;
const lowerCaseArgument = argument.toLowerCase();
return guild.roles.cache.find((role) => role.name.toLowerCase() === lowerCaseArgument) ?? null;
}
11 changes: 6 additions & 5 deletions src/lib/resolvers/user.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { SnowflakeRegex, UserOrMemberMentionRegex } from '@sapphire/discord-utilities';
import { UserOrMemberMentionRegex } from '@sapphire/discord-utilities';
import { container } from '@sapphire/pieces';
import { Result } from '@sapphire/result';
import type { Snowflake, User } from 'discord.js';
import type { User } from 'discord.js';
import { Identifiers } from '../errors/Identifiers';
import { resolveId, IdResolvable } from '../utils/resolvers/resolveId';

export async function resolveUser(parameter: string): Promise<Result<User, Identifiers.ArgumentUserError>> {
const userId = UserOrMemberMentionRegex.exec(parameter) ?? SnowflakeRegex.exec(parameter);
const user = userId ? await container.client.users.fetch(userId[1] as Snowflake).catch(() => null) : null;
export async function resolveUser(parameter: IdResolvable): Promise<Result<User, Identifiers.ArgumentUserError>> {
const userId = resolveId(parameter, UserOrMemberMentionRegex, 'users');
const user = userId ? await container.client.users.fetch(userId).catch(() => null) : null;
if (user) return Result.ok(user);
return Result.err(Identifiers.ArgumentUserError);
}
13 changes: 13 additions & 0 deletions src/lib/utils/resolvers/resolveId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SnowflakeRegex } from '@sapphire/discord-utilities';
import type { CommandInteraction, CommandInteractionResolvedData, Snowflake } from 'discord.js';

export type IdResolvable = string | CommandInteraction;

export function resolveId(parameter: IdResolvable, mentionRegex: RegExp, key: keyof CommandInteractionResolvedData): Snowflake | null {
if (typeof parameter == 'string') return mentionRegex.exec(parameter)?.[1] ?? SnowflakeRegex.exec(parameter)?.[1] ?? null;
if (!parameter.inCachedGuild()) {
// TODO: figure out how to get uncached members
return key === 'members' ? null : parameter.options.resolved[key]!.first()!.id;
}
return parameter.options.resolved[key]!.first()!.id;
}

0 comments on commit cdd4955

Please sign in to comment.