From fd620ec287ff144dfdbc1746ce25f31bcb61025c Mon Sep 17 00:00:00 2001 From: "Navy.gif" Date: Wed, 10 Apr 2024 17:23:15 +0300 Subject: [PATCH] Move from interface to abstract class for resolver with some default methods --- examples/ExtendedCommandOption.ts | 4 +-- index.ts | 2 +- package.json | 5 ++- src/Parser.ts | 6 ++-- src/classes/CommandOption.ts | 6 ++-- src/interfaces/CommandOption.ts | 8 ++--- src/interfaces/Resolver.ts | 54 ++++++++++++++++++++++--------- yarn.lock | 8 +++++ 8 files changed, 62 insertions(+), 31 deletions(-) diff --git a/examples/ExtendedCommandOption.ts b/examples/ExtendedCommandOption.ts index 83dfd8f..6696302 100644 --- a/examples/ExtendedCommandOption.ts +++ b/examples/ExtendedCommandOption.ts @@ -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 (_resolveable: string, _strict: boolean, _guild: Guild): Promise { diff --git a/index.ts b/index.ts index f1a3a4b..7dc7087 100644 --- a/index.ts +++ b/index.ts @@ -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'; \ No newline at end of file diff --git a/package.json b/package.json index 2ab2752..7d6033b 100644 --- a/package.json +++ b/package.json @@ -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" + } } diff --git a/src/Parser.ts b/src/Parser.ts index 754fdb8..96e7aeb 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -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, 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; private _debug = false; prefix: string; - resolver?: IResolver; + resolver?: AbstractResolver; allowDefaultOnRequired: boolean; #globalFlags: CommandOption[]; #allowIncompleteReturn: string[]; diff --git a/src/classes/CommandOption.ts b/src/classes/CommandOption.ts index a3e7252..a7ad3d6 100644 --- a/src/classes/CommandOption.ts +++ b/src/classes/CommandOption.ts @@ -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 diff --git a/src/interfaces/CommandOption.ts b/src/interfaces/CommandOption.ts index d0e9500..83b9578 100644 --- a/src/interfaces/CommandOption.ts +++ b/src/interfaces/CommandOption.ts @@ -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|undefined - - // private _options?: CommandOptionDefinition - - clone(rawValue?: string[], resolver?: IResolver): CommandOption + clone(rawValue?: string[], resolver?: AbstractResolver): CommandOption parse(guild: unknown): Promise diff --git a/src/interfaces/Resolver.ts b/src/interfaces/Resolver.ts index 517ec7b..6d19a73 100644 --- a/src/interfaces/Resolver.ts +++ b/src/interfaces/Resolver.ts @@ -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(resolveable: string, strict?: boolean): Promise + abstract resolveUser(resolveable: string, strict?: boolean): Promise /** * 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(resolveable: string, strict: boolean, guild: Guild): Promise + abstract resolveMember(resolveable: string, strict: boolean, guild: Guild): Promise /** * 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(resolveable: string, strict: boolean, guild: Guild): Promise + abstract resolveChannel(resolveable: string, strict: boolean, guild: Guild): Promise /** * 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(resolveable: string, strict: boolean, guild: Guild): Promise + abstract resolveRole(resolveable: string, strict: boolean, guild: Guild): Promise /** * 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; \ No newline at end of file +export { AbstractResolver }; +export default AbstractResolver; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 67efc42..33e816e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"