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.
- package/dist/ZumitoFramework.d.ts +9 -48
- package/dist/ZumitoFramework.js +28 -175
- package/dist/definitions/FrameworkSettings.d.ts +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +9 -1
- package/dist/services/CommandParser.d.ts +16 -0
- package/dist/services/CommandParser.js +39 -0
- package/dist/services/GuildDataGetter.d.ts +29 -0
- package/dist/services/GuildDataGetter.js +51 -0
- package/dist/services/MemberPermissionChecker.d.ts +19 -0
- package/dist/services/MemberPermissionChecker.js +21 -0
- package/dist/services/RecursiveObjectMerger.d.ts +3 -0
- package/dist/services/RecursiveObjectMerger.js +20 -0
- package/dist/services/ServiceContainer.js +3 -2
- package/dist/services/SlashCommandRefresher.d.ts +6 -0
- package/dist/services/SlashCommandRefresher.js +73 -0
- package/package.json +1 -1
|
@@ -144,58 +144,19 @@ export declare class ZumitoFramework {
|
|
|
144
144
|
*/
|
|
145
145
|
private initializeDiscordClient;
|
|
146
146
|
/**
|
|
147
|
-
*
|
|
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
|
-
*
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
* @
|
|
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
|
}
|
package/dist/ZumitoFramework.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as url from 'url';
|
|
3
|
-
import { Client,
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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] =
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
348
|
-
return
|
|
309
|
+
const memberPermissionChecker = ServiceContainer.getService(MemberPermissionChecker);
|
|
310
|
+
return await memberPermissionChecker(member, channel, permission);
|
|
349
311
|
}
|
|
350
312
|
/**
|
|
351
|
-
*
|
|
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
|
|
375
|
-
return await
|
|
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
|
|
397
|
-
|
|
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
|
}
|
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
|
-
|
|
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
|
-
|
|
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,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
|
|
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 ${
|
|
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,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
|
+
}
|