zumito-framework 1.1.64 → 1.1.66
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 +20 -3
- package/dist/ZumitoFramework.js +32 -12
- package/dist/baseModule/events/discord/messageCreate.d.ts +1 -1
- package/dist/baseModule/events/discord/messageCreate.js +4 -2
- package/dist/index.d.ts +10 -7
- package/dist/index.js +8 -6
- package/dist/managers/StatusManager.d.ts +46 -0
- package/dist/managers/StatusManager.js +95 -0
- package/dist/types/FrameworkSettings.d.ts +2 -0
- package/dist/types/Module.js +2 -2
- package/dist/types/StatusManagerOptions.d.ts +14 -0
- package/dist/types/StatusManagerOptions.js +2 -0
- package/dist/utils/DatabaseConfigLoader.js +7 -1
- package/package.json +2 -2
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { GuildMember, TextChannel
|
|
1
|
+
import { Client, GuildMember, TextChannel } from 'discord.js';
|
|
2
2
|
import { Command } from './types/Command.js';
|
|
3
|
+
import { DatabaseModel } from './types/DatabaseModel.js';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
import { FrameworkEvent } from './types/FrameworkEvent.js';
|
|
3
6
|
import { FrameworkSettings } from './types/FrameworkSettings.js';
|
|
4
7
|
import { Module } from './types/Module.js';
|
|
5
|
-
import {
|
|
8
|
+
import { StatusManager } from './managers/StatusManager.js';
|
|
6
9
|
import { TranslationManager } from './TranslationManager.js';
|
|
7
|
-
import { DatabaseModel } from './types/DatabaseModel.js';
|
|
8
10
|
/**
|
|
9
11
|
* @class ZumitoFramework
|
|
10
12
|
* @description The main class of the framework.
|
|
@@ -82,6 +84,21 @@ export declare class ZumitoFramework {
|
|
|
82
84
|
* @see {@link https://expressjs.com/en/4x/api.html#app}
|
|
83
85
|
*/
|
|
84
86
|
app: any;
|
|
87
|
+
/**
|
|
88
|
+
* The Status Manager instance.
|
|
89
|
+
* @type {StatusManager}
|
|
90
|
+
* @private
|
|
91
|
+
* @see {@link StatusManager}
|
|
92
|
+
*/
|
|
93
|
+
statusManager: StatusManager;
|
|
94
|
+
/**
|
|
95
|
+
* Event emitter for the framework.
|
|
96
|
+
* All events related to the framework are emitted from here.
|
|
97
|
+
* @type {EventEmitter}
|
|
98
|
+
* @private
|
|
99
|
+
* @see {@link https://nodejs.org/api/events.html#events_class_eventemitter}
|
|
100
|
+
*/
|
|
101
|
+
eventEmitter: EventEmitter;
|
|
85
102
|
/**
|
|
86
103
|
* @constructor
|
|
87
104
|
* @param {FrameworkSettings} settings - The settings to use for the framework.
|
package/dist/ZumitoFramework.js
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { SlashCommandBuilder, Client, } from 'discord.js';
|
|
2
|
-
import { Module } from './types/Module.js';
|
|
3
|
-
import { ApiResponse } from './definitions/ApiResponse.js';
|
|
4
|
-
import { baseModule } from './baseModule/index.js';
|
|
5
|
-
import { TranslationManager } from './TranslationManager.js';
|
|
6
|
-
import express from 'express';
|
|
7
1
|
import * as fs from 'fs';
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
|
|
2
|
+
import * as url from 'url';
|
|
3
|
+
import { Client, SlashCommandBuilder, } from 'discord.js';
|
|
4
|
+
import { ApiResponse } from './definitions/ApiResponse.js';
|
|
5
|
+
import { CommandType } from './types/CommandType.js';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
import { Module } from './types/Module.js';
|
|
12
8
|
import { REST } from '@discordjs/rest';
|
|
13
9
|
import { Routes } from 'discord-api-types/v9';
|
|
10
|
+
import { StatusManager } from './managers/StatusManager.js';
|
|
11
|
+
import { TranslationManager } from './TranslationManager.js';
|
|
12
|
+
import { baseModule } from './baseModule/index.js';
|
|
13
|
+
import { betterLogging } from 'better-logging';
|
|
14
14
|
import canario from 'canario';
|
|
15
15
|
import cookieParser from 'cookie-parser';
|
|
16
16
|
import cors from 'cors';
|
|
17
|
+
import express from 'express';
|
|
17
18
|
import http from 'http';
|
|
18
|
-
import
|
|
19
|
-
import
|
|
19
|
+
import path from 'path';
|
|
20
|
+
// import better-logging
|
|
21
|
+
betterLogging(console);
|
|
20
22
|
/**
|
|
21
23
|
* @class ZumitoFramework
|
|
22
24
|
* @description The main class of the framework.
|
|
@@ -94,6 +96,21 @@ export class ZumitoFramework {
|
|
|
94
96
|
* @see {@link https://expressjs.com/en/4x/api.html#app}
|
|
95
97
|
*/
|
|
96
98
|
app;
|
|
99
|
+
/**
|
|
100
|
+
* The Status Manager instance.
|
|
101
|
+
* @type {StatusManager}
|
|
102
|
+
* @private
|
|
103
|
+
* @see {@link StatusManager}
|
|
104
|
+
*/
|
|
105
|
+
statusManager;
|
|
106
|
+
/**
|
|
107
|
+
* Event emitter for the framework.
|
|
108
|
+
* All events related to the framework are emitted from here.
|
|
109
|
+
* @type {EventEmitter}
|
|
110
|
+
* @private
|
|
111
|
+
* @see {@link https://nodejs.org/api/events.html#events_class_eventemitter}
|
|
112
|
+
*/
|
|
113
|
+
eventEmitter = new EventEmitter();
|
|
97
114
|
/**
|
|
98
115
|
* @constructor
|
|
99
116
|
* @param {FrameworkSettings} settings - The settings to use for the framework.
|
|
@@ -132,6 +149,9 @@ export class ZumitoFramework {
|
|
|
132
149
|
this.startApiServer();
|
|
133
150
|
await this.registerModules();
|
|
134
151
|
await this.refreshSlashCommands();
|
|
152
|
+
if (this.settings.statusOptions) {
|
|
153
|
+
this.statusManager = new StatusManager(this, this.settings.statusOptions);
|
|
154
|
+
}
|
|
135
155
|
}
|
|
136
156
|
async initializeDatabase() {
|
|
137
157
|
const folders = ['db', 'db/tingodb'];
|
|
@@ -7,7 +7,7 @@ export declare class MessageCreate extends FrameworkEvent {
|
|
|
7
7
|
autocorrect(str: string, words: string[]): any;
|
|
8
8
|
getErrorEmbed(error: any, parse: any): {
|
|
9
9
|
embeds: EmbedBuilder[];
|
|
10
|
-
components: ActionRowBuilder<import("
|
|
10
|
+
components: ActionRowBuilder<import("@discordjs/builders").AnyComponentBuilder>[];
|
|
11
11
|
allowedMentions: {
|
|
12
12
|
repliedUser: boolean;
|
|
13
13
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as url from 'url';
|
|
2
|
-
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, PermissionsBitField, } from 'discord.js';
|
|
2
|
+
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType, EmbedBuilder, PermissionsBitField, } from 'discord.js';
|
|
3
3
|
import ErrorStackParser from 'error-stack-parser';
|
|
4
4
|
import { FrameworkEvent } from '../../../types/FrameworkEvent.js';
|
|
5
5
|
import { ZumitoFramework } from '../../../ZumitoFramework.js';
|
|
@@ -141,7 +141,9 @@ export class MessageCreate extends FrameworkEvent {
|
|
|
141
141
|
message.reply(content);
|
|
142
142
|
}
|
|
143
143
|
catch (e) {
|
|
144
|
-
channel.
|
|
144
|
+
if (channel.type !== ChannelType.GuildStageVoice) {
|
|
145
|
+
channel.send(content);
|
|
146
|
+
}
|
|
145
147
|
}
|
|
146
148
|
}
|
|
147
149
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
+
import { PresenceDataRule, RuledPresenceData, StatusManagerOptions } from './types/StatusManagerOptions.js';
|
|
1
2
|
import { ApiResponse } from './definitions/ApiResponse.js';
|
|
2
|
-
import {
|
|
3
|
+
import { ButtonPressed } from './types/Commands/ButtonPressed.js';
|
|
4
|
+
import { ButtonPressedParams } from './types/Commands/ButtonPressedParams.js';
|
|
3
5
|
import { Command } from './types/Command.js';
|
|
4
6
|
import { CommandArgDefinition } from './types/CommandArgDefinition.js';
|
|
5
7
|
import { CommandArguments } from './types/CommandArguments.js';
|
|
6
8
|
import { CommandChoiceDefinition } from './types/CommandChoiceDefinition.js';
|
|
7
9
|
import { CommandParameters } from './types/CommandParameters.js';
|
|
8
|
-
import { ButtonPressed } from './types/Commands/ButtonPressed.js';
|
|
9
|
-
import { ButtonPressedParams } from './types/Commands/ButtonPressedParams.js';
|
|
10
10
|
import { CommandType } from './types/CommandType.js';
|
|
11
|
+
import { DatabaseConfigLoader } from './utils/DatabaseConfigLoader.js';
|
|
12
|
+
import { DatabaseModel } from './types/DatabaseModel.js';
|
|
13
|
+
import { EmojiFallback } from './utils/EmojiFallback.js';
|
|
11
14
|
import { FrameworkEvent } from './types/FrameworkEvent.js';
|
|
12
15
|
import { FrameworkSettings } from './types/FrameworkSettings.js';
|
|
13
16
|
import { Module } from './types/Module.js';
|
|
14
17
|
import { SelectMenuParameters } from './types/SelectMenuParameters.js';
|
|
15
|
-
import { Translation } from './types/Translation.js';
|
|
16
|
-
import { DatabaseConfigLoader } from './utils/DatabaseConfigLoader.js';
|
|
17
|
-
import { EmojiFallback } from './utils/EmojiFallback.js';
|
|
18
18
|
import { TextFormatter } from './utils/TextFormatter.js';
|
|
19
|
+
import { Translation } from './types/Translation.js';
|
|
20
|
+
import { TranslationManager } from './TranslationManager.js';
|
|
19
21
|
import { ZumitoFramework } from './ZumitoFramework.js';
|
|
20
|
-
|
|
22
|
+
import * as discord from 'discord.js';
|
|
23
|
+
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, };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { ApiResponse } from './definitions/ApiResponse.js';
|
|
2
|
-
import {
|
|
2
|
+
import { ButtonPressed } from './types/Commands/ButtonPressed.js';
|
|
3
3
|
import { Command } from './types/Command.js';
|
|
4
4
|
import { CommandArguments } from './types/CommandArguments.js';
|
|
5
|
-
import { ButtonPressed } from './types/Commands/ButtonPressed.js';
|
|
6
5
|
import { CommandType } from './types/CommandType.js';
|
|
7
|
-
import { FrameworkEvent } from './types/FrameworkEvent.js';
|
|
8
|
-
import { Module } from './types/Module.js';
|
|
9
|
-
import { Translation } from './types/Translation.js';
|
|
10
6
|
import { DatabaseConfigLoader } from './utils/DatabaseConfigLoader.js';
|
|
7
|
+
import { DatabaseModel } from './types/DatabaseModel.js';
|
|
11
8
|
import { EmojiFallback } from './utils/EmojiFallback.js';
|
|
9
|
+
import { FrameworkEvent } from './types/FrameworkEvent.js';
|
|
10
|
+
import { Module } from './types/Module.js';
|
|
12
11
|
import { TextFormatter } from './utils/TextFormatter.js';
|
|
12
|
+
import { Translation } from './types/Translation.js';
|
|
13
|
+
import { TranslationManager } from './TranslationManager.js';
|
|
13
14
|
import { ZumitoFramework } from './ZumitoFramework.js';
|
|
14
|
-
|
|
15
|
+
import * as discord from 'discord.js';
|
|
16
|
+
export { ZumitoFramework, Command, Module, CommandArguments, FrameworkEvent, Translation, TranslationManager, ApiResponse, CommandType, ButtonPressed, TextFormatter, EmojiFallback, DatabaseConfigLoader, DatabaseModel, discord, };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { PresenceData } from "discord.js";
|
|
2
|
+
import { StatusManagerOptions } from "../types/StatusManagerOptions";
|
|
3
|
+
import { ZumitoFramework } from "../ZumitoFramework";
|
|
4
|
+
export declare class StatusManager {
|
|
5
|
+
/**
|
|
6
|
+
* @param {ZumitoFramework} framework - The framework instance.
|
|
7
|
+
* @param {StatusManagerOptions} options - The options for the status manager.
|
|
8
|
+
*/
|
|
9
|
+
framework: ZumitoFramework;
|
|
10
|
+
options: StatusManagerOptions;
|
|
11
|
+
statusQueue: PresenceData[];
|
|
12
|
+
currentStatusIndex: number;
|
|
13
|
+
constructor(framework: ZumitoFramework, options: StatusManagerOptions);
|
|
14
|
+
/**
|
|
15
|
+
* Delegates the events.
|
|
16
|
+
* @returns {void}
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
private delegateEvents;
|
|
20
|
+
/**
|
|
21
|
+
* Sets the status of the bot.
|
|
22
|
+
* If no presence data is provided, the status will be set to next in the queue.
|
|
23
|
+
* @param {PresenceData} presenceData - The presence data to set.
|
|
24
|
+
* @returns {void}
|
|
25
|
+
* @example
|
|
26
|
+
*/
|
|
27
|
+
setStatus(presenceData?: PresenceData): void;
|
|
28
|
+
/**
|
|
29
|
+
* Gets list of all statuses matching rules if any.
|
|
30
|
+
* @returns {PresenceData[]}
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
getMatchingStatuses(): PresenceData[];
|
|
34
|
+
/**
|
|
35
|
+
* Gets the next status in the queue.
|
|
36
|
+
* @returns {PresenceData}
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
private getNextStatus;
|
|
40
|
+
/**
|
|
41
|
+
* Gets a random status.
|
|
42
|
+
* @returns {PresenceData}
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
getRandomStatus(): PresenceData;
|
|
46
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export class StatusManager {
|
|
2
|
+
/**
|
|
3
|
+
* @param {ZumitoFramework} framework - The framework instance.
|
|
4
|
+
* @param {StatusManagerOptions} options - The options for the status manager.
|
|
5
|
+
*/
|
|
6
|
+
framework;
|
|
7
|
+
options;
|
|
8
|
+
statusQueue = [];
|
|
9
|
+
currentStatusIndex = 0;
|
|
10
|
+
constructor(framework, options) {
|
|
11
|
+
this.framework = framework;
|
|
12
|
+
this.options = options;
|
|
13
|
+
this.delegateEvents();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Delegates the events.
|
|
17
|
+
* @returns {void}
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
delegateEvents() {
|
|
21
|
+
this.framework.client.on("ready", () => {
|
|
22
|
+
this.setStatus();
|
|
23
|
+
setInterval(() => {
|
|
24
|
+
this.setStatus();
|
|
25
|
+
}, this.options.updateInterval);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Sets the status of the bot.
|
|
30
|
+
* If no presence data is provided, the status will be set to next in the queue.
|
|
31
|
+
* @param {PresenceData} presenceData - The presence data to set.
|
|
32
|
+
* @returns {void}
|
|
33
|
+
* @example
|
|
34
|
+
*/
|
|
35
|
+
setStatus(presenceData) {
|
|
36
|
+
if (presenceData) {
|
|
37
|
+
this.framework.client.user.setPresence(presenceData);
|
|
38
|
+
this.framework.eventEmitter.emit("statusChanged", presenceData);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
let status = this.getNextStatus();
|
|
42
|
+
if (status) {
|
|
43
|
+
this.framework.client.user.setPresence(status);
|
|
44
|
+
this.framework.eventEmitter.emit("statusChanged", status);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Gets list of all statuses matching rules if any.
|
|
50
|
+
* @returns {PresenceData[]}
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
getMatchingStatuses() {
|
|
54
|
+
const now = new Date();
|
|
55
|
+
const matchingStatuses = [];
|
|
56
|
+
this.options.statuses.forEach((status) => matchingStatuses.push(status));
|
|
57
|
+
this.options.RuledStatuses.forEach((status) => {
|
|
58
|
+
let match = status.rules.some((rule) => {
|
|
59
|
+
if (rule.startTime && rule.startTime > now)
|
|
60
|
+
return false;
|
|
61
|
+
if (rule.endTime && rule.endTime < now)
|
|
62
|
+
return false;
|
|
63
|
+
return true;
|
|
64
|
+
});
|
|
65
|
+
if (match)
|
|
66
|
+
matchingStatuses.push(status);
|
|
67
|
+
});
|
|
68
|
+
return matchingStatuses;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Gets the next status in the queue.
|
|
72
|
+
* @returns {PresenceData}
|
|
73
|
+
* @private
|
|
74
|
+
*/
|
|
75
|
+
getNextStatus() {
|
|
76
|
+
let statuses = this.getMatchingStatuses();
|
|
77
|
+
if (statuses.length === 0)
|
|
78
|
+
return undefined;
|
|
79
|
+
if (this.options.order === "random") {
|
|
80
|
+
return this.getRandomStatus();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
this.currentStatusIndex = (this.currentStatusIndex + 1) % statuses.length;
|
|
84
|
+
return statuses[this.currentStatusIndex];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Gets a random status.
|
|
89
|
+
* @returns {PresenceData}
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
getRandomStatus() {
|
|
93
|
+
return this.getMatchingStatuses()[Math.floor(Math.random() * this.getMatchingStatuses().length)];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { StatusManagerOptions } from "./StatusManagerOptions";
|
|
1
2
|
export interface FrameworkSettings {
|
|
2
3
|
database: any;
|
|
3
4
|
logLevel?: number;
|
|
@@ -8,4 +9,5 @@ export interface FrameworkSettings {
|
|
|
8
9
|
clientId: string;
|
|
9
10
|
};
|
|
10
11
|
defaultPrefix?: string;
|
|
12
|
+
statusOptions?: StatusManagerOptions;
|
|
11
13
|
}
|
package/dist/types/Module.js
CHANGED
|
@@ -3,7 +3,7 @@ import chalk from 'chalk';
|
|
|
3
3
|
import boxen from 'boxen';
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
|
-
import { ButtonInteraction, CommandInteraction,
|
|
6
|
+
import { ButtonInteraction, CommandInteraction, StringSelectMenuInteraction, } from 'discord.js';
|
|
7
7
|
export class Module {
|
|
8
8
|
path;
|
|
9
9
|
framework;
|
|
@@ -135,7 +135,7 @@ export class Module {
|
|
|
135
135
|
args.forEach((arg) => {
|
|
136
136
|
finalArgs[arg.constructor.name.toLowerCase()] = arg;
|
|
137
137
|
});
|
|
138
|
-
const interaction = args.find((arg) => arg instanceof
|
|
138
|
+
const interaction = args.find((arg) => arg instanceof StringSelectMenuInteraction ||
|
|
139
139
|
arg instanceof CommandInteraction ||
|
|
140
140
|
arg instanceof ButtonInteraction);
|
|
141
141
|
if (interaction) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PresenceData } from "discord.js";
|
|
2
|
+
export interface PresenceDataRule {
|
|
3
|
+
startTime?: Date;
|
|
4
|
+
endTime?: Date;
|
|
5
|
+
}
|
|
6
|
+
export interface RuledPresenceData extends PresenceData {
|
|
7
|
+
rules: PresenceDataRule[];
|
|
8
|
+
}
|
|
9
|
+
export interface StatusManagerOptions {
|
|
10
|
+
statuses: PresenceData[];
|
|
11
|
+
RuledStatuses: RuledPresenceData[];
|
|
12
|
+
updateInterval: number;
|
|
13
|
+
order: "random" | "sequential";
|
|
14
|
+
}
|
|
@@ -26,7 +26,13 @@ export class DatabaseConfigLoader {
|
|
|
26
26
|
config.database = process.env.DATABASE_NAME;
|
|
27
27
|
}
|
|
28
28
|
else if (config.type == 'mongodb') {
|
|
29
|
-
config.
|
|
29
|
+
config.host = process.env.DATABASE_HOST || 'localhost';
|
|
30
|
+
config.port = process.env.DATABASE_PORT || 27017;
|
|
31
|
+
config.username = process.env.DATABASE_USERNAME || 'root';
|
|
32
|
+
config.password = process.env.DATABASE_PASSWORD;
|
|
33
|
+
if (process.env.DATABASE_NAME) {
|
|
34
|
+
config.database = process.env.DATABASE_NAME;
|
|
35
|
+
}
|
|
30
36
|
}
|
|
31
37
|
else if (config.type == 'tingodb') {
|
|
32
38
|
config.database = './db/tingodb';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zumito-framework",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.66",
|
|
4
4
|
"description": "Discord.js bot framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"chokidar": "^3.5.3",
|
|
30
30
|
"cookie-parser": "^1.4.6",
|
|
31
31
|
"cors": "^2.8.5",
|
|
32
|
-
"discord.js": "^14.
|
|
32
|
+
"discord.js": "^14.9.0",
|
|
33
33
|
"error-stack-parser": "^2.1.4",
|
|
34
34
|
"express": "^4.18.1",
|
|
35
35
|
"leven": "^4.0.0",
|