diff --git a/.gitignore b/.gitignore index 2b86767f..d4bb0e3d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ Thumbs.db # Bot Configuration -/config.js +/config.json # DB /giveaways.json diff --git a/config.sample.js b/config.sample.js deleted file mode 100644 index c2508e29..00000000 --- a/config.sample.js +++ /dev/null @@ -1,50 +0,0 @@ -export default { - /* The token of your Discord Bot */ - token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", - /* UserID of your Discord Bot */ - userId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", - /* The URL of the MongoDB database */ - mongoDB: "mongodb://127.0.0.1:27017/discordbot", - /* Set to true for production */ - /* If set to false, commands only will be registered on the support.id server */ - production: true, - /* Spotify */ - spotify: { - clientId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", - clientSecret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", - }, - /* YouTube Cookie */ - youtubeCookie: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", - /* Support server */ - support: { - id: "123456789098765432", // The ID of the support server - logs: "123456789098765432", // The channel's ID for logs on the support server (when bot joins or leaves a guild) - invite: "https://discord.gg/discord", // Invite link to the support server - }, - /* Dashboard configuration */ - /* dashboard: { - enabled: false, // Whether the dashboard is enabled or not - maintanceKey: "letmein", // Maintance key - port: 80, // Dashboard port - domain: "http://localhost", // The base URL of the dashboard without / at the end - secret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", // Your Bot's Client Secret - logs: "123456789098765432", // The channel ID for logs - }, */ - /* Embeds defaults */ - embed: { - color: "#00FF00", // Color - footer: { - text: - "My Discord Bot | v" + - import("./package.json", { - with: { type: "json" }, - }).version, // Footer text - }, - }, - /* Bot's owner informations */ - owner: { - id: "123456789098765432", // The ID of the bot's owner - }, - /* Add your own API keys here */ - apiKeys: {}, -}; diff --git a/config.sample.json b/config.sample.json new file mode 100644 index 00000000..66d68d51 --- /dev/null +++ b/config.sample.json @@ -0,0 +1,26 @@ +{ + "token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "userId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "mongoDB": "mongodb://127.0.0.1:27017/discordbot", + "production": true, + "spotify": { + "clientId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "clientSecret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" + }, + "youtubeCookie": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "support": { + "id": "123456789098765432", + "logs": "123456789098765432", + "invite": "https://discord.gg/discord" + }, + "embed": { + "color": "#00FF00", + "footer": { + "text": "My Discord Bot | v1.0.0" + } + }, + "owner": { + "id": "123456789098765432" + }, + "apiKeys": {} +} \ No newline at end of file diff --git a/src/base/Client.js b/src/base/Client.js index 45f45876..db50e763 100644 --- a/src/base/Client.js +++ b/src/base/Client.js @@ -10,7 +10,6 @@ import { promises as fs } from "fs"; import { setTimeout } from "timers/promises"; import mongoose from "mongoose"; -import config from "../../config.js"; import * as emojis from "../../emojis.json"; import langs from "../languages/language-meta.js"; import logger from "../helpers/logger.js"; diff --git a/src/constants/index.js b/src/constants/index.js index 5ee045d6..fdcb5a1b 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -1,3 +1,4 @@ import path from "node:path"; export const PROJECT_ROOT = path.join(import.meta.dirname, ".."); +export const CONFIG_PATH = path.join(PROJECT_ROOT, "..", "config.json"); diff --git a/src/services/config/index.js b/src/services/config/index.js new file mode 100644 index 00000000..d4a67192 --- /dev/null +++ b/src/services/config/index.js @@ -0,0 +1,63 @@ +import fs from "fs"; +import { CONFIG_PATH } from "../../constants/index.js"; +import logger from "../../helpers/logger.js"; + +class ConfigService { + constructor() { + this.config = this.#loadConfig(); + } + + /** + * + * @param {string} key - key of the config + * @returns {*} - value of the config + */ + get(key) { + const keys = key.split("."); + return keys.reduce((config, k) => (config && config[k] !== undefined ? config[k] : undefined), this.config); + } + + /** + * Set a config value. + * @param {string} key - key of the config to set + * @param {*} value - value to set + */ + set(key, value) { + const keys = key.split("."); + keys.reduce((config, k, i) => { + if (i === keys.length - 1) { + config[k] = value; + } else { + config[k] = config[k] || {}; + } + return config[k]; + }, this.config); + this.#saveConfig(); + } + + /** + * Load the config from the file. + * @returns {Config} - loaded config + */ + #loadConfig() { + if (fs.existsSync(CONFIG_PATH)) { + return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8")); + } else { + logger.error("Config file not found"); + process.exit(1); + } + } + + /** + * Save the config to the file. + */ + #saveConfig() { + try { + fs.writeFileSync(CONFIG_PATH, JSON.stringify(this.config, null, 4), "utf-8"); + } catch (e) { + logger.error("Failed to save config: ", e); + } + } +} + +export default ConfigService; diff --git a/src/structures/client.js b/src/structures/client.js index d614123d..50db67d6 100644 --- a/src/structures/client.js +++ b/src/structures/client.js @@ -1,9 +1,9 @@ import { Client } from "discord.js"; -import { config } from "../../config.js"; import MongooseAdapter from "../adapters/database/MongooseAdapter.js"; import { init as initCommands } from "../handlers/command-handler/index.js"; import { init as initEvents } from "../handlers/event-handler/index.js"; import logger from "../helpers/logger.js"; +import configService from "../services/config/index.js"; export class ExtendedClient extends Client { /** @@ -11,14 +11,16 @@ export class ExtendedClient extends Client { */ constructor(options) { super(options); - this.adapter = new MongooseAdapter(config.mongoDB); + + this.configService = new configService(); + this.adapter = new MongooseAdapter(this.configService.get("mongoDB")); } async init() { try { await this.adapter.connect(); - return this.login(config.token) + return this.login(this.configService.get("token")) .then(async () => await Promise.all([initCommands(), initEvents()])) .catch(console.error); } catch (error) {