feat(extensions): add sub prefix
This commit is contained in:
		
							parent
							
								
									1119379fb5
								
							
						
					
					
						commit
						0eadfd829e
					
				
					 6 changed files with 92 additions and 35 deletions
				
			
		|  | @ -9,6 +9,7 @@ export const ready: GatewayEventHandler = async ( | ||||||
| ) => { | ) => { | ||||||
|   await gateway.client.guilds.flush() |   await gateway.client.guilds.flush() | ||||||
| 
 | 
 | ||||||
|  |   await gateway.client.users.set(d.user.id, d.user) | ||||||
|   gateway.client.user = new User(gateway.client, d.user) |   gateway.client.user = new User(gateway.client, d.user) | ||||||
|   gateway.sessionID = d.session_id |   gateway.sessionID = d.session_id | ||||||
|   gateway.debug(`Received READY. Session: ${gateway.sessionID}`) |   gateway.debug(`Received READY. Session: ${gateway.sessionID}`) | ||||||
|  |  | ||||||
|  | @ -139,21 +139,6 @@ export class Client extends EventEmitter { | ||||||
|     this.emit('debug', `[${tag}] ${msg}`) |     this.emit('debug', `[${tag}] ${msg}`) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |  | ||||||
|    * EXPERIMENTAL Decorators support for listening to events. |  | ||||||
|    * @param event Event name to listen for |  | ||||||
|    */ |  | ||||||
|   event(event: string): CallableFunction { |  | ||||||
|     // eslint-disable-next-line @typescript-eslint/no-this-alias
 |  | ||||||
|     const parent = this |  | ||||||
|     return function ( |  | ||||||
|       target: { [name: string]: CallableFunction }, |  | ||||||
|       prop: string |  | ||||||
|     ) { |  | ||||||
|       parent.addListener(event, target[prop] as (...args: any[]) => any) |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // TODO(DjDeveloperr): Implement this
 |   // TODO(DjDeveloperr): Implement this
 | ||||||
|   // fetchApplication(): Promise<Application>
 |   // fetchApplication(): Promise<Application>
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -101,7 +101,7 @@ export class Command implements CommandOptions { | ||||||
| 
 | 
 | ||||||
|   toString(): string { |   toString(): string { | ||||||
|     return `Command: ${this.name}${ |     return `Command: ${this.name}${ | ||||||
|       this.extension !== undefined |       this.extension !== undefined && this.extension.name !== '' | ||||||
|         ? ` [${this.extension.name}]` |         ? ` [${this.extension.name}]` | ||||||
|         : this.category !== undefined |         : this.category !== undefined | ||||||
|         ? ` [${this.category}]` |         ? ` [${this.category}]` | ||||||
|  | @ -290,38 +290,86 @@ export class CommandsManager { | ||||||
|     return this.list.size |     return this.list.size | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** Find a Command by name/alias */ |   /** Filter out Commands by name/alias */ | ||||||
|   find(search: string): Command | undefined { |   filter(search: string, subPrefix?: string): Collection<string, Command> { | ||||||
|     if (this.client.caseSensitive === false) search = search.toLowerCase() |     if (this.client.caseSensitive === false) search = search.toLowerCase() | ||||||
|     return this.list.find((cmd: Command): boolean => { |     return this.list.filter((cmd: Command): boolean => { | ||||||
|  |       if (subPrefix !== undefined) { | ||||||
|  |         if ( | ||||||
|  |           this.client.caseSensitive === true | ||||||
|  |             ? subPrefix !== cmd.extension?.subPrefix | ||||||
|  |             : subPrefix.toLowerCase() !== | ||||||
|  |               cmd.extension?.subPrefix?.toLowerCase() | ||||||
|  |         ) { | ||||||
|  |           return false | ||||||
|  |         } | ||||||
|  |       } else if ( | ||||||
|  |         subPrefix === undefined && | ||||||
|  |         cmd.extension?.subPrefix !== undefined | ||||||
|  |       ) { | ||||||
|  |         return false | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       const name = |       const name = | ||||||
|         this.client.caseSensitive === true ? cmd.name : cmd.name.toLowerCase() |         this.client.caseSensitive === true ? cmd.name : cmd.name.toLowerCase() | ||||||
|       if (name === search) return true |       if (name === search) { | ||||||
|       else if (cmd.aliases !== undefined) { |         return true | ||||||
|  |       } else if (cmd.aliases !== undefined) { | ||||||
|         let aliases: string[] |         let aliases: string[] | ||||||
|         if (typeof cmd.aliases === 'string') aliases = [cmd.aliases] |         if (typeof cmd.aliases === 'string') aliases = [cmd.aliases] | ||||||
|         else aliases = cmd.aliases |         else aliases = cmd.aliases | ||||||
|         if (this.client.caseSensitive === false) |         if (this.client.caseSensitive === false) | ||||||
|           aliases = aliases.map((e) => e.toLowerCase()) |           aliases = aliases.map((e) => e.toLowerCase()) | ||||||
|  | 
 | ||||||
|         return aliases.includes(search) |         return aliases.includes(search) | ||||||
|       } else return false |       } else { | ||||||
|  |         return false | ||||||
|  |       } | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** Fetch a Command including disable checks */ |   /** Find a Command by name/alias */ | ||||||
|   fetch(name: string, bypassDisable?: boolean): Command | undefined { |   find(search: string, subPrefix?: string): Command | undefined { | ||||||
|     const cmd = this.find(name) |     const filtered = this.filter(search, subPrefix) | ||||||
|  |     return filtered.first() | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /** Fetch a Command including disable checks and subPrefix implementation */ | ||||||
|  |   fetch(parsed: ParsedCommand, bypassDisable?: boolean): Command | undefined { | ||||||
|  |     let cmd = this.find(parsed.name) | ||||||
|  |     if (cmd?.extension?.subPrefix !== undefined) cmd = undefined | ||||||
|  | 
 | ||||||
|  |     if (cmd === undefined && parsed.args.length > 0) { | ||||||
|  |       cmd = this.find(parsed.args[0], parsed.name) | ||||||
|  |       if (cmd === undefined || cmd.extension?.subPrefix === undefined) return | ||||||
|  |       if ( | ||||||
|  |         this.client.caseSensitive === true | ||||||
|  |           ? cmd.extension.subPrefix !== parsed.name | ||||||
|  |           : cmd.extension.subPrefix.toLowerCase() !== parsed.name.toLowerCase() | ||||||
|  |       ) | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |       parsed.args.shift() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (cmd === undefined) return |     if (cmd === undefined) return | ||||||
|     if (this.isDisabled(cmd) && bypassDisable !== true) return |     if (this.isDisabled(cmd) && bypassDisable !== true) return | ||||||
|     return cmd |     return cmd | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** Check whether a Command exists or not */ |   /** Check whether a Command exists or not */ | ||||||
|   exists(search: Command | string): boolean { |   exists(search: Command | string, subPrefix?: string): boolean { | ||||||
|     let exists = false |     let exists = false | ||||||
|     if (typeof search === 'string') return this.find(search) !== undefined | 
 | ||||||
|  |     if (typeof search === 'string') | ||||||
|  |       return this.find(search, subPrefix) !== undefined | ||||||
|     else { |     else { | ||||||
|       exists = this.find(search.name) !== undefined |       exists = | ||||||
|  |         this.find( | ||||||
|  |           search.name, | ||||||
|  |           subPrefix === undefined ? search.extension?.subPrefix : subPrefix | ||||||
|  |         ) !== undefined | ||||||
|  | 
 | ||||||
|       if (search.aliases !== undefined) { |       if (search.aliases !== undefined) { | ||||||
|         const aliases: string[] = |         const aliases: string[] = | ||||||
|           typeof search.aliases === 'string' ? [search.aliases] : search.aliases |           typeof search.aliases === 'string' ? [search.aliases] : search.aliases | ||||||
|  | @ -330,6 +378,7 @@ export class CommandsManager { | ||||||
|             .map((alias) => this.find(alias) !== undefined) |             .map((alias) => this.find(alias) !== undefined) | ||||||
|             .find((e) => e) ?? false |             .find((e) => e) ?? false | ||||||
|       } |       } | ||||||
|  | 
 | ||||||
|       return exists |       return exists | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | @ -338,11 +387,20 @@ export class CommandsManager { | ||||||
|   add(cmd: Command | typeof Command): boolean { |   add(cmd: Command | typeof Command): boolean { | ||||||
|     // eslint-disable-next-line new-cap
 |     // eslint-disable-next-line new-cap
 | ||||||
|     if (!(cmd instanceof Command)) cmd = new cmd() |     if (!(cmd instanceof Command)) cmd = new cmd() | ||||||
|     if (this.exists(cmd)) |     if (this.exists(cmd, cmd.extension?.subPrefix)) | ||||||
|       throw new Error( |       throw new Error( | ||||||
|         `Failed to add Command '${cmd.toString()}' with name/alias already exists.` |         `Failed to add Command '${cmd.toString()}' with name/alias already exists.` | ||||||
|       ) |       ) | ||||||
|     this.list.set(cmd.name, cmd) |     this.list.set( | ||||||
|  |       `${cmd.name}-${ | ||||||
|  |         this.list.filter((e) => | ||||||
|  |           this.client.caseSensitive === true | ||||||
|  |             ? e.name === cmd.name | ||||||
|  |             : e.name.toLowerCase() === cmd.name.toLowerCase() | ||||||
|  |         ).size | ||||||
|  |       }`,
 | ||||||
|  |       cmd | ||||||
|  |     ) | ||||||
|     return true |     return true | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -164,7 +164,7 @@ export class CommandClient extends Client implements CommandClientOptions { | ||||||
|     if (typeof prefix !== 'string') return |     if (typeof prefix !== 'string') return | ||||||
| 
 | 
 | ||||||
|     const parsed = parseCommand(this, msg, prefix) |     const parsed = parseCommand(this, msg, prefix) | ||||||
|     const command = this.commands.find(parsed.name) |     const command = this.commands.fetch(parsed) | ||||||
| 
 | 
 | ||||||
|     if (command === undefined) return |     if (command === undefined) return | ||||||
|     const category = |     const category = | ||||||
|  | @ -362,6 +362,8 @@ export function command(options?: CommandOptions) { | ||||||
| 
 | 
 | ||||||
|     if (options !== undefined) Object.assign(command, options) |     if (options !== undefined) Object.assign(command, options) | ||||||
| 
 | 
 | ||||||
|  |     if (target instanceof Extension) command.extension = target | ||||||
|  | 
 | ||||||
|     if (target._decoratedCommands === undefined) target._decoratedCommands = {} |     if (target._decoratedCommands === undefined) target._decoratedCommands = {} | ||||||
|     target._decoratedCommands[command.name] = command |     target._decoratedCommands[command.name] = command | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -67,6 +67,8 @@ export class Extension { | ||||||
|   description?: string |   description?: string | ||||||
|   /** Extensions's Commands Manager */ |   /** Extensions's Commands Manager */ | ||||||
|   commands: ExtensionCommands = new ExtensionCommands(this) |   commands: ExtensionCommands = new ExtensionCommands(this) | ||||||
|  |   /** Sub-Prefix to be used for ALL of Extenion's Commands. */ | ||||||
|  |   subPrefix?: string | ||||||
|   /** Events registered by this Extension */ |   /** Events registered by this Extension */ | ||||||
|   events: { [name: string]: (...args: any[]) => {} } = {} |   events: { [name: string]: (...args: any[]) => {} } = {} | ||||||
| 
 | 
 | ||||||
|  | @ -77,6 +79,7 @@ export class Extension { | ||||||
|     this.client = client |     this.client = client | ||||||
|     if (this._decoratedCommands !== undefined) { |     if (this._decoratedCommands !== undefined) { | ||||||
|       Object.entries(this._decoratedCommands).forEach((entry) => { |       Object.entries(this._decoratedCommands).forEach((entry) => { | ||||||
|  |         entry[1].extension = this | ||||||
|         this.commands.add(entry[1]) |         this.commands.add(entry[1]) | ||||||
|       }) |       }) | ||||||
|       this._decoratedCommands = undefined |       this._decoratedCommands = undefined | ||||||
|  |  | ||||||
|  | @ -4,7 +4,8 @@ import { | ||||||
|   Intents, |   Intents, | ||||||
|   command, |   command, | ||||||
|   CommandContext, |   CommandContext, | ||||||
|   Extension |   Extension, | ||||||
|  |   CommandBuilder | ||||||
| } from '../../mod.ts' | } from '../../mod.ts' | ||||||
| import { TOKEN } from './config.ts' | import { TOKEN } from './config.ts' | ||||||
| 
 | 
 | ||||||
|  | @ -21,15 +22,16 @@ class MyClient extends CommandClient { | ||||||
|     console.log(`Logged in as ${this.user?.tag}!`) |     console.log(`Logged in as ${this.user?.tag}!`) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   @command({ |   @command({ aliases: 'pong' }) | ||||||
|     aliases: 'pong' |  | ||||||
|   }) |  | ||||||
|   Ping(ctx: CommandContext): void { |   Ping(ctx: CommandContext): void { | ||||||
|     ctx.message.reply('Pong!') |     ctx.message.reply('Pong!') | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class VCExtension extends Extension { | class VCExtension extends Extension { | ||||||
|  |   name = 'VC' | ||||||
|  |   subPrefix = 'vc' | ||||||
|  | 
 | ||||||
|   @command() |   @command() | ||||||
|   async join(ctx: CommandContext): Promise<void> { |   async join(ctx: CommandContext): Promise<void> { | ||||||
|     const userVS = await ctx.guild?.voiceStates.get(ctx.author.id) |     const userVS = await ctx.guild?.voiceStates.get(ctx.author.id) | ||||||
|  | @ -59,4 +61,10 @@ const client = new MyClient() | ||||||
| 
 | 
 | ||||||
| client.extensions.load(VCExtension) | client.extensions.load(VCExtension) | ||||||
| 
 | 
 | ||||||
|  | client.commands.add( | ||||||
|  |   new CommandBuilder() | ||||||
|  |     .setName('join') | ||||||
|  |     .onExecute((ctx) => ctx.message.reply('haha')) | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| client.connect(TOKEN, Intents.All) | client.connect(TOKEN, Intents.All) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue