@@ -10,7 +10,9 @@ import { SpectrumLobby } from "../components/chat/lobby.component";
1010import { receivedTextMessage } from "../interfaces/spectrum/community/chat/receivedTextMessage.interface" ;
1111import { Service } from "typedi" ;
1212import { TSMap } from "typescript-map" ;
13-
13+ import { SpectrumCommandMakable } from "../components/api/decorators/spectrum-command.decorator" ;
14+ import * as requireGlob from "require-glob" ;
15+ import "reflect-metadata" ;
1416/** @class SpectrumCommand */
1517@Service ( )
1618export class SpectrumCommands {
@@ -21,7 +23,7 @@ export class SpectrumCommands {
2123 /** The prefix for the commands */
2224 protected prefix : string = "\\spbot" ;
2325 /** Map of commands */
24- protected _commandMap : TSMap < string , aSpectrumCommand > = new TSMap < string , aSpectrumCommand > ( ) ;
26+ protected _commandMap : Map < string , aSpectrumCommand > = new Map < string , aSpectrumCommand > ( ) ;
2527
2628 constructor ( ) {
2729 this . Broadcaster . addListener ( "message.new" , this . checkForCommand ) ;
@@ -57,16 +59,20 @@ export class SpectrumCommands {
5759 // }
5860 // }
5961
60- this . _commandMap . forEach ( ( value : aSpectrumCommand , key : string ) => {
61- let re = new RegExp ( "^" + key ) ;
62+ for ( let [ key , value ] of this . _commandMap . entries ( ) ) {
63+ let re = new RegExp ( `^ ${ this . escapeRegExp ( this . prefix ) } ${ key } ` ) ;
6264 let matches = messageAsLower . match ( re ) ;
6365 if ( matches ) {
6466 value . callback ( payload . message , lobby , matches ) ;
6567 return ; // there cant be 2 commands can there?
6668 }
67- } ) ;
69+ }
6870 } ;
6971
72+ /**
73+ * Set the prefix for every commands. Any text message not starting with this prefix will be ignored
74+ * (case insensitive)
75+ */
7076 public setPrefix ( prefix : string ) {
7177 this . prefix = prefix . toLowerCase ( ) ;
7278 }
@@ -79,15 +85,16 @@ export class SpectrumCommands {
7985 * @param shortCode the shortcode to listen for
8086 * @param callback the function to call when this command is used
8187 * @param manual an explanation of what this command does.
88+ * @deprecated use registerCommands instead
8289 * @return the aSpectrumCommand object that we are now listening for.
8390 */
8491 public registerCommand ( command : aSpectrumCommand ) : aSpectrumCommand ;
8592 public registerCommand ( name : string , shortCode , callback , manual ) : aSpectrumCommand ;
8693 public registerCommand (
8794 name : string | aSpectrumCommand ,
88- shortCode ?,
89- callback ?,
90- manual ?
95+ shortCode ?: string ,
96+ callback ?: Function ,
97+ manual ?: string
9198 ) : aSpectrumCommand {
9299 var co = null ;
93100 if ( typeof name === typeof "test" ) {
@@ -96,33 +103,67 @@ export class SpectrumCommands {
96103 co = name ;
97104 }
98105
99- var commandString = this . prefix . toLowerCase ( ) + " " + co . shortCode . toLowerCase ( ) ;
106+ var commandString = co . shortCode . toLowerCase ( ) ;
100107 this . _commandMap . set ( commandString , co ) ;
101108
102109 return co ;
103110 }
104111
105112 /**
106113 * Alias of registerCommand
114+ * @deprecated use registerCommands instead
107115 */
108116 public addCommand ( name , shortCode , callback , manual ) {
109117 return this . registerCommand ( name , shortCode , callback , manual ) ;
110118 }
111119
112120 /**
113121 * Unbinds a command and stop listening to it.
122+ * @todo
114123 */
115124 public unRegisterCommand ( command : aBotCommand ) ;
116125 public unRegisterCommand ( commandId : number ) ;
117126 public unRegisterCommand ( co ) {
118127 let shortcodeAsLower = co . shortCode . toLowerCase ( ) ;
119-
120- this . _commandMap . filter ( function ( command , key ) {
121- return key === shortcodeAsLower ;
122- } ) ;
123128 }
124129
130+ /**
131+ * Return the list of commands currently registered and active
132+ */
125133 public getCommandList ( ) : aSpectrumCommand [ ] {
126- return this . _commandMap . values ( ) ;
134+ return Array . from ( this . _commandMap . values ( ) ) ;
135+ }
136+
137+ /**
138+ * Register a batch of commands, either as an array or with a glob.
139+ * Commands __must be decorated__ with @SpectrumCommand() decorator
140+ */
141+ public async registerCommands ( opts : {
142+ /** array of actual commands or globs to import them */
143+ commands : SpectrumCommandMakable [ ] | string [ ] ;
144+ } ) {
145+ if ( opts . commands . length === 0 ) return ;
146+
147+ if ( typeof opts . commands [ 0 ] === "string" ) {
148+ // Import as glob, we have nothing to do.
149+ await requireGlob ( ( opts . commands as string [ ] ) . map ( path => `${ process . cwd ( ) } /${ path } ` ) ) ;
150+ } else {
151+ await Promise . all (
152+ ( opts . commands as SpectrumCommandMakable [ ] ) . map ( async Command => {
153+ // We just make sure it's decorated and that we have nothing to do.
154+ if ( ! Reflect . getMetadata ( "spectrum-command" , Command ) ) {
155+ console . error (
156+ `[ERROR] Could not register command ${
157+ Command . constructor . name
158+ } . Did you forget to decorate it with @SpectrumCommand() ?`
159+ ) ;
160+ }
161+ } )
162+ ) ;
163+ }
164+ }
165+
166+ protected escapeRegExp ( string : string ) {
167+ return string . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" ) ; // $& means the whole matched string
127168 }
128169}
0 commit comments