zumito-framework 1.2.6 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -144,58 +144,19 @@ export declare class ZumitoFramework {
144
144
  */
145
145
  private initializeDiscordClient;
146
146
  /**
147
- * From a command-line string, returns an array of parameters.
148
- * @param commandLine
149
- * @returns {string[]}
150
- * @private
151
- * @static
152
- * @example
153
- * // returns ['a', 'b', 'c']
154
- * splitCommandLine('a b c');
155
- * @example
156
- * // returns ['a', 'b c']
157
- * splitCommandLine('a "b c"');
147
+ * @deprecated use CommandParser service instead
158
148
  */
159
149
  static splitCommandLine(commandLine: any): any;
160
150
  /**
161
- * Checks if a member has a permission in a channel.
162
- * @param member
163
- * @param channel
164
- * @param permission
165
- * @returns {Promise<boolean>}
166
- * @public
167
- * @example
168
- * // returns true if the member has the permission
169
- * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES);
170
- * @example
171
- * // returns true if the member has the permission
172
- * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES | Permissions.FLAGS.MANAGE_CHANNELS);
173
- * @example
174
- */
175
- memberHasPermission(member: GuildMember, channel: TextChannel, permission: bigint): Promise<boolean>;
176
- /**
177
- * Gets the guild settings from the database.
178
- * If the guild is not in the database, it is added.
179
- * @param guildId
180
- * @returns {Promise<any>}
181
- * @public
182
- * @async
183
- * @example
184
- * // returns the guild settings
185
- * getGuildSettings('123456789012345678');
186
- * @example
187
- * // returns the guild settings
188
- * getGuildSettings(guild.id);
189
- * @example
190
- * // returns the guild settings
191
- * getGuildSettings(message.guild.id);
192
- * @example
193
- * // returns the guild settings
194
- * getGuildSettings(interaction.guild.id);
195
- * @example
196
- * // returns the guild settings
197
- * getGuildSettings(interaction.guildId);
151
+ * @deprecated use MemberPermissionChecker service
152
+ */
153
+ memberHasPermission(member: GuildMember, channel: TextChannel, permission: bigint): Promise<any>;
154
+ /**
155
+ * @deprecated use GuildDataGetter service
198
156
  */
199
157
  getGuildSettings(guildId: string): Promise<unknown>;
158
+ /**
159
+ * @deprecated
160
+ */
200
161
  refreshSlashCommands(): Promise<void>;
201
162
  }
@@ -1,11 +1,8 @@
1
1
  import * as fs from 'fs';
2
2
  import * as url from 'url';
3
- import { Client, SlashCommandBuilder, } from 'discord.js';
3
+ import { Client, } from 'discord.js';
4
4
  import { ApiResponse } from './definitions/api/ApiResponse.js';
5
- import { CommandType } from './definitions/commands/CommandType.js';
6
5
  import { EventEmitter } from 'events';
7
- import { REST } from '@discordjs/rest';
8
- import { Routes } from 'discord-api-types/v9';
9
6
  import { StatusManager } from './services/StatusManager.js';
10
7
  import { TranslationManager } from './services/TranslationManager.js';
11
8
  import { betterLogging } from 'better-logging';
@@ -19,6 +16,11 @@ import { EventManager } from './services/EventManager.js';
19
16
  import { CommandManager } from './services/CommandManager.js';
20
17
  import { ModuleManager } from './services/ModuleManager.js';
21
18
  import { ServiceContainer } from './services/ServiceContainer.js';
19
+ import { GuildDataGetter } from './services/GuildDataGetter.js';
20
+ import { RecursiveObjectMerger } from './services/RecursiveObjectMerger.js';
21
+ import { MemberPermissionChecker } from './services/MemberPermissionChecker.js';
22
+ import { CommandParser } from './services/CommandParser.js';
23
+ import { SlashCommandRefresher } from './services/SlashCommandRefresher.js';
22
24
  // import better-logging
23
25
  betterLogging(console);
24
26
  /**
@@ -238,13 +240,16 @@ export class ZumitoFramework {
238
240
  else if (fs.existsSync(`${process.cwd()}/src/modules`)) {
239
241
  modulesFolder = `${process.cwd()}/src/modules`;
240
242
  }
241
- else
242
- return;
243
243
  const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
244
244
  await this.registerModule(path.join(__dirname, 'modules', 'core'), 'baseModule');
245
- const files = fs.readdirSync(modulesFolder);
246
- for (const file of files) {
247
- await this.registerModule(modulesFolder, file);
245
+ if (modulesFolder) {
246
+ const files = fs.readdirSync(modulesFolder);
247
+ for (const file of files) {
248
+ await this.registerModule(modulesFolder, file);
249
+ }
250
+ }
251
+ else if (this.settings.srcMode == 'monoBundle') {
252
+ await this.registerModule(process.cwd(), 'src');
248
253
  }
249
254
  // Define models
250
255
  const schemas = {};
@@ -253,7 +258,7 @@ export class ZumitoFramework {
253
258
  schemas[model.name] = model.getModel(this.database);
254
259
  }
255
260
  else {
256
- schemas[model.name] = MergeRecursive(schemas[model.name], model.getModel(this.database));
261
+ schemas[model.name] = RecursiveObjectMerger.merge(schemas[model.name], model.getModel(this.database));
257
262
  }
258
263
  });
259
264
  Object.keys(schemas).forEach((schemaName) => {
@@ -292,182 +297,30 @@ export class ZumitoFramework {
292
297
  });
293
298
  }
294
299
  /**
295
- * From a command-line string, returns an array of parameters.
296
- * @param commandLine
297
- * @returns {string[]}
298
- * @private
299
- * @static
300
- * @example
301
- * // returns ['a', 'b', 'c']
302
- * splitCommandLine('a b c');
303
- * @example
304
- * // returns ['a', 'b c']
305
- * splitCommandLine('a "b c"');
300
+ * @deprecated use CommandParser service instead
306
301
  */
307
302
  static splitCommandLine(commandLine) {
308
- //log( 'commandLine', commandLine ) ;
309
- // Find a unique marker for the space character.
310
- // Start with '<SP>' and repeatedly append '@' if necessary to make it unique.
311
- let spaceMarker = '<SP>';
312
- while (commandLine.indexOf(spaceMarker) > -1)
313
- spaceMarker += '@';
314
- // Protect double-quoted strings.
315
- // o Find strings of non-double-quotes, wrapped in double-quotes.
316
- // o The final double-quote is optional to allow for an unterminated string.
317
- // o Replace each double-quoted-string with what's inside the qouble-quotes,
318
- // after each space character has been replaced with the space-marker above.
319
- // o The outer double-quotes will not be present.
320
- const noSpacesInQuotes = commandLine.replace(/"([^"]*)"?/g, (fullMatch, capture) => {
321
- return capture.replace(/ /g, spaceMarker);
322
- });
323
- // Now that it is safe to do so, split the command-line at one-or-more spaces.
324
- const mangledParamArray = noSpacesInQuotes.split(/ +/);
325
- // Create a new array by restoring spaces from any space-markers.
326
- const paramArray = mangledParamArray.map((mangledParam) => {
327
- return mangledParam.replace(RegExp(spaceMarker, 'g'), ' ');
328
- });
329
- return paramArray;
303
+ return CommandParser.splitCommandLine(commandLine);
330
304
  }
331
305
  /**
332
- * Checks if a member has a permission in a channel.
333
- * @param member
334
- * @param channel
335
- * @param permission
336
- * @returns {Promise<boolean>}
337
- * @public
338
- * @example
339
- * // returns true if the member has the permission
340
- * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES);
341
- * @example
342
- * // returns true if the member has the permission
343
- * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES | Permissions.FLAGS.MANAGE_CHANNELS);
344
- * @example
306
+ * @deprecated use MemberPermissionChecker service
345
307
  */
346
308
  async memberHasPermission(member, channel, permission) {
347
- const memberPermission = await channel.permissionsFor(member);
348
- return memberPermission.has(permission);
309
+ const memberPermissionChecker = ServiceContainer.getService(MemberPermissionChecker);
310
+ return await memberPermissionChecker(member, channel, permission);
349
311
  }
350
312
  /**
351
- * Gets the guild settings from the database.
352
- * If the guild is not in the database, it is added.
353
- * @param guildId
354
- * @returns {Promise<any>}
355
- * @public
356
- * @async
357
- * @example
358
- * // returns the guild settings
359
- * getGuildSettings('123456789012345678');
360
- * @example
361
- * // returns the guild settings
362
- * getGuildSettings(guild.id);
363
- * @example
364
- * // returns the guild settings
365
- * getGuildSettings(message.guild.id);
366
- * @example
367
- * // returns the guild settings
368
- * getGuildSettings(interaction.guild.id);
369
- * @example
370
- * // returns the guild settings
371
- * getGuildSettings(interaction.guildId);
313
+ * @deprecated use GuildDataGetter service
372
314
  */
373
315
  async getGuildSettings(guildId) {
374
- const Guild = this.database.models.Guild;
375
- return await new Promise((resolve, reject) => {
376
- Guild.findOne({ where: { guild_id: guildId } }, (err, guild) => {
377
- if (err)
378
- reject(err);
379
- if (guild == null) {
380
- guild = new Guild({
381
- guild_id: guildId,
382
- });
383
- guild.save((err) => {
384
- if (err)
385
- reject(err);
386
- resolve(guild);
387
- });
388
- }
389
- else {
390
- resolve(guild);
391
- }
392
- });
393
- });
316
+ const guildDataGetter = ServiceContainer.getService(GuildDataGetter);
317
+ return await guildDataGetter.getGuildSettings(guildId);
394
318
  }
319
+ /**
320
+ * @deprecated
321
+ */
395
322
  async refreshSlashCommands() {
396
- const rest = new REST({ version: '10' }).setToken(this.settings.discordClientOptions.token);
397
- const commands = Array.from(this.commands.getAll().values())
398
- .filter((command) => command.type == CommandType.slash ||
399
- command.type == CommandType.separated ||
400
- command.type == CommandType.any)
401
- .map((command) => {
402
- const slashCommand = new SlashCommandBuilder()
403
- .setName(command.name)
404
- .setDescription(this.translations.get('command.' + command.name + '.description', 'en'));
405
- if (command.args) {
406
- command.args.forEach((arg) => {
407
- let method;
408
- switch (arg.type) {
409
- case 'string':
410
- method = 'addStringOption';
411
- break;
412
- case 'user':
413
- case 'member':
414
- method = 'addUserOption';
415
- break;
416
- case 'channel':
417
- method = 'addChannelOption';
418
- break;
419
- case 'role':
420
- method = 'addRoleOption';
421
- break;
422
- default:
423
- throw new Error('Invalid argument type ' + arg.type);
424
- }
425
- slashCommand[method]((option) => {
426
- option.setName(arg.name);
427
- option.setDescription(this.translations.get('command.' +
428
- command.name +
429
- '.args.' +
430
- arg.name +
431
- '.description', 'en'));
432
- option.setRequired(!arg.optional);
433
- if (arg.choices) {
434
- // if arg.choices is function, call it
435
- if (typeof arg.choices == 'function') {
436
- arg.choices =
437
- arg.choices();
438
- }
439
- arg.choices.forEach((choice) => {
440
- option.addChoices({
441
- name: choice.name,
442
- value: choice.value,
443
- });
444
- });
445
- }
446
- return option;
447
- });
448
- });
449
- }
450
- return slashCommand.toJSON();
451
- });
452
- const data = await rest.put(Routes.applicationCommands(this.settings.discordClientOptions.clientId), { body: commands });
453
- console.debug(`Successfully reloaded ${data.length} of ${commands.length} application (/) commands.`);
454
- }
455
- }
456
- function MergeRecursive(obj1, obj2) {
457
- for (const p in obj2) {
458
- try {
459
- // Property in destination object set; update its value.
460
- if (obj2[p].constructor == Object) {
461
- obj1[p] = MergeRecursive(obj1[p], obj2[p]);
462
- }
463
- else {
464
- obj1[p] = obj2[p];
465
- }
466
- }
467
- catch (e) {
468
- // Property in destination object not set; create it and set its value.
469
- obj1[p] = obj2[p];
470
- }
323
+ const slashCommandRefresher = ServiceContainer.getService(SlashCommandRefresher);
324
+ slashCommandRefresher.refreshSlashCommands();
471
325
  }
472
- return obj1;
473
326
  }
@@ -10,4 +10,5 @@ export interface FrameworkSettings {
10
10
  };
11
11
  defaultPrefix?: string;
12
12
  statusOptions?: StatusManagerOptions;
13
+ srcMode?: 'multiBundle' | 'monoBundle' | undefined;
13
14
  }
package/dist/index.d.ts CHANGED
@@ -22,4 +22,7 @@ import { ZumitoFramework } from './ZumitoFramework.js';
22
22
  import * as discord from 'discord.js';
23
23
  import { EventParameters } from './definitions/parameters/EventParameters.js';
24
24
  import { ServiceContainer } from './services/ServiceContainer.js';
25
- export { ZumitoFramework, FrameworkSettings, Command, Module, CommandParameters, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, SelectMenuParameters, CommandType, CommandArgDefinition, CommandChoiceDefinition, ButtonPressed, ButtonPressedParams, TextFormatter, EmojiFallback, DatabaseConfigLoader, DatabaseModel, PresenceDataRule, RuledPresenceData, StatusManagerOptions, discord, EventParameters, ServiceContainer };
25
+ import { GuildDataGetter } from './services/GuildDataGetter.js';
26
+ import { CommandParser } from './services/CommandParser.js';
27
+ import { SlashCommandRefresher } from './services/SlashCommandRefresher.js';
28
+ export { ZumitoFramework, FrameworkSettings, Command, Module, CommandParameters, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, SelectMenuParameters, CommandType, CommandArgDefinition, CommandChoiceDefinition, ButtonPressed, ButtonPressedParams, TextFormatter, EmojiFallback, DatabaseConfigLoader, DatabaseModel, PresenceDataRule, RuledPresenceData, StatusManagerOptions, discord, EventParameters, ServiceContainer, GuildDataGetter, SlashCommandRefresher, CommandParser, };
package/dist/index.js CHANGED
@@ -14,6 +14,14 @@ import { TranslationManager } from './services/TranslationManager.js';
14
14
  import { ZumitoFramework } from './ZumitoFramework.js';
15
15
  import * as discord from 'discord.js';
16
16
  import { ServiceContainer } from './services/ServiceContainer.js';
17
+ import { GuildDataGetter } from './services/GuildDataGetter.js';
18
+ import { MemberPermissionChecker } from './services/MemberPermissionChecker.js';
19
+ import { CommandParser } from './services/CommandParser.js';
20
+ import { SlashCommandRefresher } from './services/SlashCommandRefresher.js';
17
21
  ServiceContainer.addService(TextFormatter, []);
18
22
  ServiceContainer.addService(EmojiFallback, []);
19
- export { ZumitoFramework, Command, Module, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, CommandType, ButtonPressed, TextFormatter, EmojiFallback, DatabaseConfigLoader, DatabaseModel, discord, ServiceContainer };
23
+ ServiceContainer.addService(GuildDataGetter, [ZumitoFramework.name]);
24
+ ServiceContainer.addService(MemberPermissionChecker, []);
25
+ ServiceContainer.addService(CommandParser, []);
26
+ ServiceContainer.addService(SlashCommandRefresher, [ZumitoFramework.name]);
27
+ export { ZumitoFramework, Command, Module, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, CommandType, ButtonPressed, TextFormatter, EmojiFallback, DatabaseConfigLoader, DatabaseModel, discord, ServiceContainer, GuildDataGetter, SlashCommandRefresher, CommandParser, };
@@ -0,0 +1,16 @@
1
+ export declare class CommandParser {
2
+ /**
3
+ * From a command-line string, returns an array of parameters.
4
+ * @param commandLine
5
+ * @returns {string[]}
6
+ * @private
7
+ * @static
8
+ * @example
9
+ * // returns ['a', 'b', 'c']
10
+ * splitCommandLine('a b c');
11
+ * @example
12
+ * // returns ['a', 'b c']
13
+ * splitCommandLine('a "b c"');
14
+ */
15
+ static splitCommandLine(commandLine: any): any;
16
+ }
@@ -0,0 +1,39 @@
1
+ export class CommandParser {
2
+ /**
3
+ * From a command-line string, returns an array of parameters.
4
+ * @param commandLine
5
+ * @returns {string[]}
6
+ * @private
7
+ * @static
8
+ * @example
9
+ * // returns ['a', 'b', 'c']
10
+ * splitCommandLine('a b c');
11
+ * @example
12
+ * // returns ['a', 'b c']
13
+ * splitCommandLine('a "b c"');
14
+ */
15
+ static splitCommandLine(commandLine) {
16
+ //log( 'commandLine', commandLine ) ;
17
+ // Find a unique marker for the space character.
18
+ // Start with '<SP>' and repeatedly append '@' if necessary to make it unique.
19
+ let spaceMarker = '<SP>';
20
+ while (commandLine.indexOf(spaceMarker) > -1)
21
+ spaceMarker += '@';
22
+ // Protect double-quoted strings.
23
+ // o Find strings of non-double-quotes, wrapped in double-quotes.
24
+ // o The final double-quote is optional to allow for an unterminated string.
25
+ // o Replace each double-quoted-string with what's inside the qouble-quotes,
26
+ // after each space character has been replaced with the space-marker above.
27
+ // o The outer double-quotes will not be present.
28
+ const noSpacesInQuotes = commandLine.replace(/"([^"]*)"?/g, (fullMatch, capture) => {
29
+ return capture.replace(/ /g, spaceMarker);
30
+ });
31
+ // Now that it is safe to do so, split the command-line at one-or-more spaces.
32
+ const mangledParamArray = noSpacesInQuotes.split(/ +/);
33
+ // Create a new array by restoring spaces from any space-markers.
34
+ const paramArray = mangledParamArray.map((mangledParam) => {
35
+ return mangledParam.replace(RegExp(spaceMarker, 'g'), ' ');
36
+ });
37
+ return paramArray;
38
+ }
39
+ }
@@ -0,0 +1,29 @@
1
+ import { ZumitoFramework } from "../ZumitoFramework";
2
+ export declare class GuildDataGetter {
3
+ framework: ZumitoFramework;
4
+ constructor(framework: ZumitoFramework);
5
+ /**
6
+ * Gets the guild settings from the database.
7
+ * If the guild is not in the database, it is added.
8
+ * @param guildId
9
+ * @returns {Promise<any>}
10
+ * @public
11
+ * @async
12
+ * @example
13
+ * // returns the guild settings
14
+ * getGuildSettings('123456789012345678');
15
+ * @example
16
+ * // returns the guild settings
17
+ * getGuildSettings(guild.id);
18
+ * @example
19
+ * // returns the guild settings
20
+ * getGuildSettings(message.guild.id);
21
+ * @example
22
+ * // returns the guild settings
23
+ * getGuildSettings(interaction.guild.id);
24
+ * @example
25
+ * // returns the guild settings
26
+ * getGuildSettings(interaction.guildId);
27
+ */
28
+ getGuildSettings(guildId: string): Promise<unknown>;
29
+ }
@@ -0,0 +1,51 @@
1
+ export class GuildDataGetter {
2
+ framework;
3
+ constructor(framework) {
4
+ this.framework = framework;
5
+ }
6
+ /**
7
+ * Gets the guild settings from the database.
8
+ * If the guild is not in the database, it is added.
9
+ * @param guildId
10
+ * @returns {Promise<any>}
11
+ * @public
12
+ * @async
13
+ * @example
14
+ * // returns the guild settings
15
+ * getGuildSettings('123456789012345678');
16
+ * @example
17
+ * // returns the guild settings
18
+ * getGuildSettings(guild.id);
19
+ * @example
20
+ * // returns the guild settings
21
+ * getGuildSettings(message.guild.id);
22
+ * @example
23
+ * // returns the guild settings
24
+ * getGuildSettings(interaction.guild.id);
25
+ * @example
26
+ * // returns the guild settings
27
+ * getGuildSettings(interaction.guildId);
28
+ */
29
+ async getGuildSettings(guildId) {
30
+ const Guild = this.framework.database.models.Guild;
31
+ return await new Promise((resolve, reject) => {
32
+ Guild.findOne({ where: { guild_id: guildId } }, (err, guild) => {
33
+ if (err)
34
+ reject(err);
35
+ if (guild == null) {
36
+ guild = new Guild({
37
+ guild_id: guildId,
38
+ });
39
+ guild.save((err) => {
40
+ if (err)
41
+ reject(err);
42
+ resolve(guild);
43
+ });
44
+ }
45
+ else {
46
+ resolve(guild);
47
+ }
48
+ });
49
+ });
50
+ }
51
+ }
@@ -0,0 +1,19 @@
1
+ import { GuildMember, TextChannel } from "discord.js";
2
+ export declare class MemberPermissionChecker {
3
+ /**
4
+ * Checks if a member has a permission in a channel.
5
+ * @param member
6
+ * @param channel
7
+ * @param permission
8
+ * @returns {Promise<boolean>}
9
+ * @public
10
+ * @example
11
+ * // returns true if the member has the permission
12
+ * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES);
13
+ * @example
14
+ * // returns true if the member has the permission
15
+ * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES | Permissions.FLAGS.MANAGE_CHANNELS);
16
+ * @example
17
+ */
18
+ hasPermissionOnChannel(member: GuildMember, channel: TextChannel, permission: bigint): Promise<boolean>;
19
+ }
@@ -0,0 +1,21 @@
1
+ export class MemberPermissionChecker {
2
+ /**
3
+ * Checks if a member has a permission in a channel.
4
+ * @param member
5
+ * @param channel
6
+ * @param permission
7
+ * @returns {Promise<boolean>}
8
+ * @public
9
+ * @example
10
+ * // returns true if the member has the permission
11
+ * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES);
12
+ * @example
13
+ * // returns true if the member has the permission
14
+ * memberHasPermission(member, channel, Permissions.FLAGS.MANAGE_MESSAGES | Permissions.FLAGS.MANAGE_CHANNELS);
15
+ * @example
16
+ */
17
+ async hasPermissionOnChannel(member, channel, permission) {
18
+ const memberPermission = await channel.permissionsFor(member);
19
+ return memberPermission.has(permission);
20
+ }
21
+ }
@@ -0,0 +1,3 @@
1
+ export declare class RecursiveObjectMerger {
2
+ static merge(obj1: any, obj2: any): any;
3
+ }
@@ -0,0 +1,20 @@
1
+ export class RecursiveObjectMerger {
2
+ static merge(obj1, obj2) {
3
+ for (const p in obj2) {
4
+ try {
5
+ // Property in destination object set; update its value.
6
+ if (obj2[p].constructor == Object) {
7
+ obj1[p] = this.merge(obj1[p], obj2[p]);
8
+ }
9
+ else {
10
+ obj1[p] = obj2[p];
11
+ }
12
+ }
13
+ catch (e) {
14
+ // Property in destination object not set; create it and set its value.
15
+ obj1[p] = obj2[p];
16
+ }
17
+ }
18
+ return obj1;
19
+ }
20
+ }
@@ -9,9 +9,10 @@ class ServiceContainerManager {
9
9
  });
10
10
  }
11
11
  getService(serviceClass) {
12
- const service = this.services.get(serviceClass.name);
12
+ const classname = typeof serviceClass === 'string' ? serviceClass : serviceClass.name;
13
+ const service = this.services.get(classname);
13
14
  if (!service)
14
- throw new Error(`Service ${serviceClass.name} not found`);
15
+ throw new Error(`Service ${classname} not found`);
15
16
  if (service.singleton && service.instance)
16
17
  return service.instance;
17
18
  const dependencies = service.dependencies.map(dependency => this.getService(dependency));
@@ -0,0 +1,6 @@
1
+ import { ZumitoFramework } from "../ZumitoFramework";
2
+ export declare class SlashCommandRefresher {
3
+ framework: ZumitoFramework;
4
+ constructor(framework: ZumitoFramework);
5
+ refreshSlashCommands(): Promise<void>;
6
+ }
@@ -0,0 +1,73 @@
1
+ import { REST } from '@discordjs/rest';
2
+ import { Routes } from 'discord-api-types/v9';
3
+ import { CommandType } from "../definitions/commands/CommandType";
4
+ import { SlashCommandBuilder } from "discord.js";
5
+ export class SlashCommandRefresher {
6
+ framework;
7
+ constructor(framework) {
8
+ this.framework = framework;
9
+ }
10
+ /*
11
+ * Update slash commands on discord
12
+ */
13
+ async refreshSlashCommands() {
14
+ const rest = new REST({ version: '10' }).setToken(this.framework.settings.discordClientOptions.token);
15
+ const commands = Array.from(this.framework.commands.getAll().values())
16
+ .filter((command) => command.type == CommandType.slash ||
17
+ command.type == CommandType.separated ||
18
+ command.type == CommandType.any)
19
+ .map((command) => {
20
+ const slashCommand = new SlashCommandBuilder()
21
+ .setName(command.name)
22
+ .setDescription(this.framework.translations.get('command.' + command.name + '.description', 'en'));
23
+ if (command.args) {
24
+ command.args.forEach((arg) => {
25
+ let method;
26
+ switch (arg.type) {
27
+ case 'string':
28
+ method = 'addStringOption';
29
+ break;
30
+ case 'user':
31
+ case 'member':
32
+ method = 'addUserOption';
33
+ break;
34
+ case 'channel':
35
+ method = 'addChannelOption';
36
+ break;
37
+ case 'role':
38
+ method = 'addRoleOption';
39
+ break;
40
+ default:
41
+ throw new Error('Invalid argument type ' + arg.type);
42
+ }
43
+ slashCommand[method]((option) => {
44
+ option.setName(arg.name);
45
+ option.setDescription(this.framework.translations.get('command.' +
46
+ command.name +
47
+ '.args.' +
48
+ arg.name +
49
+ '.description', 'en'));
50
+ option.setRequired(!arg.optional);
51
+ if (arg.choices) {
52
+ // if arg.choices is function, call it
53
+ if (typeof arg.choices == 'function') {
54
+ arg.choices =
55
+ arg.choices();
56
+ }
57
+ arg.choices.forEach((choice) => {
58
+ option.addChoices({
59
+ name: choice.name,
60
+ value: choice.value,
61
+ });
62
+ });
63
+ }
64
+ return option;
65
+ });
66
+ });
67
+ }
68
+ return slashCommand.toJSON();
69
+ });
70
+ const data = await rest.put(Routes.applicationCommands(this.framework.settings.discordClientOptions.clientId), { body: commands });
71
+ console.debug(`Successfully reloaded ${data.length} of ${commands.length} application (/) commands.`);
72
+ }
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zumito-framework",
3
- "version": "1.2.6",
3
+ "version": "1.2.7",
4
4
  "description": "Discord.js bot framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",