Move from interface to abstract class for resolver with some default methods

This commit is contained in:
Erik 2024-04-10 17:23:15 +03:00
parent 9735550272
commit fd620ec287
8 changed files with 62 additions and 31 deletions

View File

@ -1,7 +1,7 @@
/* eslint-disable max-classes-per-file */
import { CommandOption, IResolver } from '@navy.gif/commandparser';
import { CommandOption, AbstractResolver } from '@navy.gif/commandparser';
class Resolver implements IResolver
class Resolver implements AbstractResolver
{
resolveMember<Member, Guild> (_resolveable: string, _strict: boolean, _guild: Guild): Promise<Member | null>
{

View File

@ -6,6 +6,6 @@ export { CommandOption } from './src/classes/CommandOption.js';
export { SubcommandGroupOption } from './src/classes/SubcommandGroupOption.js';
export { SubcommandOption } from './src/classes/SubcommandOption.js';
export { IResolver } from './src/interfaces/Resolver.js';
export { AbstractResolver } from './src/interfaces/Resolver.js';
export { OptionType, CommandOptionDefinition } from './src/interfaces/CommandOption.js';
export { CommandDefinition, ICommand, CommandArgs } from './src/interfaces/Command.js';

View File

@ -40,5 +40,8 @@
"release:major": "yarn build && yarn version major && yarn npm publish",
"lint": "eslint --fix src/"
},
"packageManager": "yarn@4.1.1"
"packageManager": "yarn@4.1.1",
"dependencies": {
"@navy.gif/timestring": "^6.0.6"
}
}

View File

@ -3,7 +3,7 @@ import { EventEmitter } from 'events';
import CommandOption from './classes/CommandOption.js';
import { CommandOptionDefinition, OptionType } from './interfaces/CommandOption.js';
import IResolver from './interfaces/Resolver.js';
import AbstractResolver from './interfaces/Resolver.js';
import ExtendedMap from './util/Map.js';
import Util from './util/Util.js';
import { ICommand } from '../index.js';
@ -31,7 +31,7 @@ type ParserOptions = {
commands: Iterable<ICommand>,
prefix?: string,
debug?: boolean,
resolver?: IResolver,
resolver?: AbstractResolver,
/**
* Allow default value on a required Option
@ -64,7 +64,7 @@ class Parser extends EventEmitter
private commands: ExtendedMap<string, ICommand>;
private _debug = false;
prefix: string;
resolver?: IResolver;
resolver?: AbstractResolver;
allowDefaultOnRequired: boolean;
#globalFlags: CommandOption[];
#allowIncompleteReturn: string[];

View File

@ -1,6 +1,6 @@
/* eslint-disable no-undefined */
import ICommandOption, { Choice, CommandOptionDefinition, DependsOnMode, OptionType, ParseResult } from '../interfaces/CommandOption.js';
import IResolver from '../interfaces/Resolver.js';
import AbstractResolver from '../interfaces/Resolver.js';
const SUB = [ OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP ];
class CommandOption implements ICommandOption
@ -27,7 +27,7 @@ class CommandOption implements ICommandOption
value?: unknown;
aliased = false;
strict: boolean;
protected resolver?: IResolver | undefined;
protected resolver?: AbstractResolver | undefined;
constructor (def: CommandOptionDefinition|CommandOption|ICommandOption)
{
@ -86,7 +86,7 @@ class CommandOption implements ICommandOption
this.required = def.required || false;
}
clone (rawValue?: string[], resolver?: IResolver): CommandOption
clone (rawValue?: string[], resolver?: AbstractResolver): CommandOption
{
// Call own constructor, important to do it like this in order to preserve any potentially extended classes
// eslint-disable-next-line new-parens, no-extra-parens

View File

@ -29,7 +29,7 @@
// | 'POINTS'
import CommandOption from '../classes/CommandOption.js';
import IResolver from './Resolver.js';
import AbstractResolver from './Resolver.js';
enum OptionType {
SUB_COMMAND,
@ -130,11 +130,7 @@ interface ICommandOption {
rawValue?: string[]
aliased: boolean
// resolver?: IResolver<unknown, unknown, unknown, unknown>|undefined
// private _options?: CommandOptionDefinition
clone(rawValue?: string[], resolver?: IResolver): CommandOption
clone(rawValue?: string[], resolver?: AbstractResolver): CommandOption
parse(guild: unknown): Promise<ParseResult>

View File

@ -1,4 +1,7 @@
interface IResolver {
import timestring from '@navy.gif/timestring';
abstract class AbstractResolver
{
/**
* Should resolve to a user abstraction
@ -6,9 +9,9 @@ interface IResolver {
* @param {string} resolveable
* @param {boolean} [strict]
* @return {User} {User}
* @memberof IResolver
* @memberof AbstractResolver
*/
resolveUser<User>(resolveable: string, strict?: boolean): Promise<User | null>
abstract resolveUser<User>(resolveable: string, strict?: boolean): Promise<User | null>
/**
* Should resolve to a member abstraction
@ -17,9 +20,9 @@ interface IResolver {
* @param {boolean} [strict] Whether to strictly match the properties, e.g. a string must directly match a username & discriminator
* @param {Guild} guild The guild in which to look for the member
* @return {Member} {Member}
* @memberof IResolver
* @memberof AbstractResolver
*/
resolveMember<Member, Guild>(resolveable: string, strict: boolean, guild: Guild): Promise<Member | null>
abstract resolveMember<Member, Guild>(resolveable: string, strict: boolean, guild: Guild): Promise<Member | null>
/**
* Should resolve to a role abstraction
@ -28,9 +31,9 @@ interface IResolver {
* @param {boolean} [strict] Whether to strictly match the name, if strict is passed partial names should match
* @param {Guild} [guild] The guild in which to look for the channel
* @return {Channel} {Channel}
* @memberof IResolver
* @memberof AbstractResolver
*/
resolveChannel<Channel, Guild>(resolveable: string, strict: boolean, guild: Guild): Promise<Channel | null>
abstract resolveChannel<Channel, Guild>(resolveable: string, strict: boolean, guild: Guild): Promise<Channel | null>
/**
* Should resolve to a role abstraction
@ -39,9 +42,9 @@ interface IResolver {
* @param {boolean} [strict] Whether to strictly match the name, if strict is passed partial names should match
* @param {Guild} [guild] The guild in which to look for the role
* @return {Role} {Role}
* @memberof IResolver
* @memberof AbstractResolver
*/
resolveRole<Role, Guild>(resolveable: string, strict: boolean, guild: Guild): Promise<Role | null>
abstract resolveRole<Role, Guild>(resolveable: string, strict: boolean, guild: Guild): Promise<Role | null>
/**
* Should resolve to true when a truthy resolveable is passed, i.e. yes, true, on etc
@ -50,9 +53,20 @@ interface IResolver {
*
* @param {string} resolveable
* @return {boolean|null} {(boolean | null)}
* @memberof IResolver
* @memberof AbstractResolver
*/
resolveBoolean(resolveable: string): boolean | null
resolveBoolean (input: string | boolean): boolean | null
{
input = `${input}`.toLowerCase();
const truthy = [ 'on', 'true', 'yes', 'enable', 'y', 't' ];
const falsey = [ 'off', 'false', 'no', 'disable', 'n', 'f' ];
if (truthy.includes(input))
return true;
else if (falsey.includes(input))
return false;
return null;
}
/**
* Should resolve to a integer value from a string, e.g. 2w should resolve to 1209600 if seconds are user
@ -60,11 +74,21 @@ interface IResolver {
*
* @param {string} resolveable
* @return {number} {number}
* @memberof IResolver
* @memberof AbstractResolver
*/
resolveTime(resolveable: string): number | null
resolveTime (string: string): number | null
{
try
{
return timestring(string);
}
catch (err)
{
return null;
}
}
}
export { IResolver };
export default IResolver;
export { AbstractResolver };
export default AbstractResolver;

View File

@ -2061,6 +2061,7 @@ __metadata:
dependencies:
"@babel/core": "npm:^7.24.3"
"@babel/preset-env": "npm:^7.24.3"
"@navy.gif/timestring": "npm:^6.0.6"
"@types/node": "npm:^20.11.30"
"@typescript-eslint/eslint-plugin": "npm:^7.4.0"
"@typescript-eslint/parser": "npm:^7.4.0"
@ -2071,6 +2072,13 @@ __metadata:
languageName: unknown
linkType: soft
"@navy.gif/timestring@npm:^6.0.6":
version: 6.0.6
resolution: "@navy.gif/timestring@npm:6.0.6"
checksum: 10c0/da95f0db57b996b0de6d36ba4da113d09d4d6363c0c56d1cb2bdc5d4e85678a3ef9dbef8248f2af47eee8ff3fe49caf8228567448d608e6a64214e8f25bf375d
languageName: node
linkType: hard
"@nodelib/fs.scandir@npm:2.1.5":
version: 2.1.5
resolution: "@nodelib/fs.scandir@npm:2.1.5"