diff --git a/package-lock.json b/package-lock.json index f9b7f1f2..a5fb79e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -259,8 +259,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "css": { "version": "2.2.1", @@ -550,8 +549,7 @@ "first-chunk-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", - "dev": true + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" }, "flagged-respawn": { "version": "0.3.2", @@ -982,8 +980,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "is-extglob": { "version": "1.0.0", @@ -1074,8 +1071,7 @@ "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, "is-valid-glob": { "version": "0.3.0", @@ -1900,13 +1896,11 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, "dependencies": { "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "readable-stream": { "version": "2.3.3", @@ -2119,8 +2113,7 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" } } } diff --git a/src/client/Client.ts b/src/client/Client.ts index a36c3ba1..6a02fc62 100644 --- a/src/client/Client.ts +++ b/src/client/Client.ts @@ -265,12 +265,18 @@ export class Client extends Discord.Client { await this._guildDataStorage.init(); await this._guildSettingStorage.init(); - await this._guildStorageLoader.loadStorages(this._guildDataStorage, this._guildSettingStorage); - await this.plugins._loadPlugins(); - if (!this.passive) this._dispatcher.setReady(); + if (!this.passive) + { + this._logger.info('Client', 'Initializing commands...'); + await this.commands._initCommands(); + this._logger.info('Client', 'Commands initialized.'); + this._dispatcher.setReady(); + this._logger.info('Client', 'Command dispatcher ready.'); + } + if (typeof this.readyText !== 'undefined') this._logger.log('Client', this.readyText); diff --git a/src/command/Command.ts b/src/command/Command.ts index 6ed85eec..053cc182 100644 --- a/src/command/Command.ts +++ b/src/command/Command.ts @@ -186,6 +186,20 @@ export class Command this._rateLimiter = new RateLimiter(info.ratelimit, false); } + /** + * Can be included in a command to initlialize any resources a command + * needs at runtime that require things that are not available within + * a command's constructor like the client instance or client/guild storages. + * + * Will be called after all commands are loaded (including those from + * any loaded plugins) and after all base framework storages (client and guild) + * are ready for use. + * + * >**Note:** Can be async if needed + * @returns {Promise} + */ + public async init(): Promise {} + /** * Action to be executed when the command is called. The following parameters * are what command actions will be passed by the {@link CommandDispatcher} whenever @@ -241,7 +255,8 @@ export class Command // Default guildOnly to true if permissions/roles are given if (!this.guildOnly && (this.callerPermissions.length || this.clientPermissions.length - || this.roles.length)) this.guildOnly = true; + || this.roles.length)) + this.guildOnly = true; if (!this.action) throw new TypeError(`Command "${this.name}".action: expected Function, got: ${typeof this.action}`); if (!(this.action instanceof Function)) throw new TypeError(`Command "${this.name}".action: expected Function, got: ${typeof this.action}`); diff --git a/src/command/CommandRegistry.ts b/src/command/CommandRegistry.ts index 0e56a24e..fc73ef9a 100644 --- a/src/command/CommandRegistry.ts +++ b/src/command/CommandRegistry.ts @@ -56,6 +56,16 @@ export class CommandRegistry + { + for (const command of this.values()) await command.init(); + } + /** * Register an external command and add it to the `.commands` * [collection]{@link external:Collection}, erroring on duplicate diff --git a/test/commands/test_command.ts b/test/commands/test_command.ts index af6aa744..6369fc0e 100644 --- a/test/commands/test_command.ts +++ b/test/commands/test_command.ts @@ -30,6 +30,13 @@ export default class extends Command }); } + public async init(): Promise + { + await this.logger.debug('Command:test', await this.client.storage.get('defaultGuildSettings.prefix')); + await this.logger.debug('Command:test', await this.client.storage.guilds.first().settings.get('prefix')); + await this.logger.debug('Command:test', 'Test command initialized.'); + } + // @using((message, args) => [message, args.map(a => a.toUpperCase())]) // @using(resolve(`test: Member, foo: String`)) // @using(expect(`test: Member, foo: ['foo', 'bar']`))