From bf0eec82b51d4559c90d6e66ea0dd711afc50241 Mon Sep 17 00:00:00 2001 From: youKnowOwO Date: Sat, 3 Oct 2020 14:10:26 +0800 Subject: [PATCH 1/6] feat: Script to create command --- package.json | 1 + src/util/CreateCommand.ts | 73 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/util/CreateCommand.ts diff --git a/package.json b/package.json index c3577ee..b863926 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint:fix": "eslint --ignore-path .gitignore \"**/*.+(ts|js)\" --fix", "start": "node dist", "start:dev": "node dist/yumeko.js dev", + "createCmd": "node dist/util/CreateCommand.js", "test": "yarn lint && yarn build" }, "repository": "https://github.com/youKnowOwO/yumeko-ts.git", diff --git a/src/util/CreateCommand.ts b/src/util/CreateCommand.ts new file mode 100644 index 0000000..76fb26a --- /dev/null +++ b/src/util/CreateCommand.ts @@ -0,0 +1,73 @@ +import { createInterface, ReadLineOptions } from "readline"; +import { promises } from "fs"; +import { join } from "path"; +import { firstUpperCase } from "./Util"; +import chalk from "chalk"; + +const categories = Object.keys(require("../../assets/json/help.json")); + +const rl = createInterface({ + input: process.stdin, + output: process.stdout +} as ReadLineOptions); + +function awaitQuestion(query: string): Promise { + return new Promise(resolve => rl.question(query, resolve)); +} + +function end(reason?: string): void { + rl.write("\n"); + if (reason) rl.write(chalk`{bgRed {black \ CANCELED }} ${reason}`); + else rl.write(chalk`{bgGreen {black \ SUCCES }} Command created ✓`); + rl.write("\n"); + process.exit(0); +} + +export async function exec(): Promise { + rl.write(chalk`{bgBlue {black \ INFO }} Please describe your command !`); + rl.write("\n"); + let aliases: string[] = []; + const id = await awaitQuestion(chalk` {blue •} What identifier for this command ? `); + if (!id.length) return end("Command identifier is required"); + aliases.push(id); + await awaitQuestion(chalk` {blue •} Please insert aliases you want splited by comma (,) ! `).then(x => aliases.push(...x.split(","))); + aliases = aliases.filter(x => x.length); + const descriptionContent = await awaitQuestion(chalk` {blue •} What description of the command ? (if came from localization please insert the id between <>) `) + .then(x => { + if (x.startsWith("<") && x.endsWith(">")) + return `(msg): string => msg.ctx.lang("${x.replace(/<|>/g, "")}")`; + return `"${x}"`; + }); + if (!descriptionContent.length) return end("Command Description is required"); + const usageDescription = await awaitQuestion(chalk` {blue •} How you usage this command ? `); + if (!usageDescription.length) return end("Command usage is required"); + const exampleDescription = await awaitQuestion(chalk` {blue •} Please write at least 1 example ! `); + if (!exampleDescription.length) return end("Command example is required"); + const category = await awaitQuestion(chalk` {blue •} Which category that ship this command ? (${categories.join(", ")}) `); + if (!category.length) return end("Command category is required"); + const filename = await awaitQuestion(chalk` {blue •} What the filename do you want ? (${firstUpperCase(id)}) `).then(x => x.length ? x : firstUpperCase(id)); + const dirname = await awaitQuestion(chalk` {blue •} What the dirname do you want ? (${firstUpperCase(category)}) `).then(x => x.length ? x : firstUpperCase(category)); + const toWrite = `import Command from "@yumeko/classes/Command"; +import type { Message } from "discord.js"; +import { DeclareCommand, constantly } from "@yumeko/decorators"; + +@DeclareCommand("${id}", { + aliases: [${aliases.map(x => `"${x}"`).join(", ")}], + description: { + content: ${descriptionContent}, + usage: "${usageDescription}", + examples: ["${exampleDescription}"] + }, + category: "${category}" +}) +export default class extends Command { + @constantly + public async exec(msg: Message): Promise { + return msg; + } +}`; + await promises.writeFile(join("./src/commands", dirname, `${filename}.ts`), toWrite, { encoding: "utf-8" }); + return end(); +} + +exec(); \ No newline at end of file From 2a8332da65e2274f1b078d6e05f7673abdea7788 Mon Sep 17 00:00:00 2001 From: youKnowOwO Date: Sat, 3 Oct 2020 14:29:37 +0800 Subject: [PATCH 2/6] refactor: createCmd to create:cmd suggested by @KurokuTetsuya --- package.json | 2 +- src/util/CreateCommand.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b863926..867d048 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint:fix": "eslint --ignore-path .gitignore \"**/*.+(ts|js)\" --fix", "start": "node dist", "start:dev": "node dist/yumeko.js dev", - "createCmd": "node dist/util/CreateCommand.js", + "create:cmd": "node dist/util/CreateCommand.js", "test": "yarn lint && yarn build" }, "repository": "https://github.com/youKnowOwO/yumeko-ts.git", diff --git a/src/util/CreateCommand.ts b/src/util/CreateCommand.ts index 76fb26a..7d952be 100644 --- a/src/util/CreateCommand.ts +++ b/src/util/CreateCommand.ts @@ -16,7 +16,6 @@ function awaitQuestion(query: string): Promise { } function end(reason?: string): void { - rl.write("\n"); if (reason) rl.write(chalk`{bgRed {black \ CANCELED }} ${reason}`); else rl.write(chalk`{bgGreen {black \ SUCCES }} Command created ✓`); rl.write("\n"); @@ -34,6 +33,7 @@ export async function exec(): Promise { aliases = aliases.filter(x => x.length); const descriptionContent = await awaitQuestion(chalk` {blue •} What description of the command ? (if came from localization please insert the id between <>) `) .then(x => { + if (!x.length) return ""; if (x.startsWith("<") && x.endsWith(">")) return `(msg): string => msg.ctx.lang("${x.replace(/<|>/g, "")}")`; return `"${x}"`; From 0cc18f86b9f1db70475072a6cf5ffda8d5745f54 Mon Sep 17 00:00:00 2001 From: youKnowOwO Date: Sat, 3 Oct 2020 16:28:13 +0800 Subject: [PATCH 3/6] refactor: Changing some folder name to sync with CreateCommand --- src/commands/{Util => Utility}/Brainly.ts | 0 src/commands/{Util => Utility}/Code.ts | 0 src/commands/{Util => Utility}/Docs.ts | 0 src/commands/{Util => Utility}/EslintRule.ts | 0 src/commands/{Util => Utility}/Google.ts | 0 src/commands/{Util => Utility}/Instagram.ts | 0 src/commands/{Util => Utility}/Jisho.ts | 0 src/commands/{Util => Utility}/Lint.ts | 0 src/commands/{Util => Utility}/MDN.ts | 0 src/commands/{Util => Utility}/Npm.ts | 0 src/commands/{Util => Utility}/Stackoverflow/Show.ts | 0 src/commands/{Util => Utility}/Stackoverflow/Stackoverflow.ts | 0 src/commands/{Util => Utility}/Weather.ts | 0 src/commands/{Util => Utility}/Webshot.ts | 0 src/util/CodeLinter.ts | 2 +- src/util/Myriad.ts | 2 +- 16 files changed, 2 insertions(+), 2 deletions(-) rename src/commands/{Util => Utility}/Brainly.ts (100%) rename src/commands/{Util => Utility}/Code.ts (100%) rename src/commands/{Util => Utility}/Docs.ts (100%) rename src/commands/{Util => Utility}/EslintRule.ts (100%) rename src/commands/{Util => Utility}/Google.ts (100%) rename src/commands/{Util => Utility}/Instagram.ts (100%) rename src/commands/{Util => Utility}/Jisho.ts (100%) rename src/commands/{Util => Utility}/Lint.ts (100%) rename src/commands/{Util => Utility}/MDN.ts (100%) rename src/commands/{Util => Utility}/Npm.ts (100%) rename src/commands/{Util => Utility}/Stackoverflow/Show.ts (100%) rename src/commands/{Util => Utility}/Stackoverflow/Stackoverflow.ts (100%) rename src/commands/{Util => Utility}/Weather.ts (100%) rename src/commands/{Util => Utility}/Webshot.ts (100%) diff --git a/src/commands/Util/Brainly.ts b/src/commands/Utility/Brainly.ts similarity index 100% rename from src/commands/Util/Brainly.ts rename to src/commands/Utility/Brainly.ts diff --git a/src/commands/Util/Code.ts b/src/commands/Utility/Code.ts similarity index 100% rename from src/commands/Util/Code.ts rename to src/commands/Utility/Code.ts diff --git a/src/commands/Util/Docs.ts b/src/commands/Utility/Docs.ts similarity index 100% rename from src/commands/Util/Docs.ts rename to src/commands/Utility/Docs.ts diff --git a/src/commands/Util/EslintRule.ts b/src/commands/Utility/EslintRule.ts similarity index 100% rename from src/commands/Util/EslintRule.ts rename to src/commands/Utility/EslintRule.ts diff --git a/src/commands/Util/Google.ts b/src/commands/Utility/Google.ts similarity index 100% rename from src/commands/Util/Google.ts rename to src/commands/Utility/Google.ts diff --git a/src/commands/Util/Instagram.ts b/src/commands/Utility/Instagram.ts similarity index 100% rename from src/commands/Util/Instagram.ts rename to src/commands/Utility/Instagram.ts diff --git a/src/commands/Util/Jisho.ts b/src/commands/Utility/Jisho.ts similarity index 100% rename from src/commands/Util/Jisho.ts rename to src/commands/Utility/Jisho.ts diff --git a/src/commands/Util/Lint.ts b/src/commands/Utility/Lint.ts similarity index 100% rename from src/commands/Util/Lint.ts rename to src/commands/Utility/Lint.ts diff --git a/src/commands/Util/MDN.ts b/src/commands/Utility/MDN.ts similarity index 100% rename from src/commands/Util/MDN.ts rename to src/commands/Utility/MDN.ts diff --git a/src/commands/Util/Npm.ts b/src/commands/Utility/Npm.ts similarity index 100% rename from src/commands/Util/Npm.ts rename to src/commands/Utility/Npm.ts diff --git a/src/commands/Util/Stackoverflow/Show.ts b/src/commands/Utility/Stackoverflow/Show.ts similarity index 100% rename from src/commands/Util/Stackoverflow/Show.ts rename to src/commands/Utility/Stackoverflow/Show.ts diff --git a/src/commands/Util/Stackoverflow/Stackoverflow.ts b/src/commands/Utility/Stackoverflow/Stackoverflow.ts similarity index 100% rename from src/commands/Util/Stackoverflow/Stackoverflow.ts rename to src/commands/Utility/Stackoverflow/Stackoverflow.ts diff --git a/src/commands/Util/Weather.ts b/src/commands/Utility/Weather.ts similarity index 100% rename from src/commands/Util/Weather.ts rename to src/commands/Utility/Weather.ts diff --git a/src/commands/Util/Webshot.ts b/src/commands/Utility/Webshot.ts similarity index 100% rename from src/commands/Util/Webshot.ts rename to src/commands/Utility/Webshot.ts diff --git a/src/util/CodeLinter.ts b/src/util/CodeLinter.ts index eba246e..e7668c5 100644 --- a/src/util/CodeLinter.ts +++ b/src/util/CodeLinter.ts @@ -1,5 +1,5 @@ import type YumekoClient from "@yumeko/classes/Client"; -import LintCommand from "@yumeko/commands/Util/Lint"; +import LintCommand from "@yumeko/commands/Utility/Lint"; import type { Message } from "discord.js"; import { TypeCodeReturn } from "@yumeko/interfaces"; import { Linter, Rule } from "eslint"; diff --git a/src/util/Myriad.ts b/src/util/Myriad.ts index 64abc5b..afb2986 100644 --- a/src/util/Myriad.ts +++ b/src/util/Myriad.ts @@ -3,7 +3,7 @@ import request from "node-superfetch"; import { Message, MessageReaction, User } from "discord.js"; import { TypeCodeReturn } from "@yumeko/interfaces"; import { join } from "path"; -import type CodeCommand from "@yumeko/commands/Util/Code"; +import type CodeCommand from "@yumeko/commands/Utility/Code"; export async function exec(client: YumekoClient, code: string, language: string): Promise<[boolean, string]> { const endpoint = join(client.config.myriad, "eval"); From 5412d6506ca9726c57b04840790b6f05b54d6a11 Mon Sep 17 00:00:00 2001 From: youKnowOwO Date: Sat, 3 Oct 2020 17:43:20 +0800 Subject: [PATCH 4/6] refactor: Renew CreateCommand interface --- src/util/CreateCommand.ts | 48 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/util/CreateCommand.ts b/src/util/CreateCommand.ts index 7d952be..1f68ae5 100644 --- a/src/util/CreateCommand.ts +++ b/src/util/CreateCommand.ts @@ -1,5 +1,5 @@ import { createInterface, ReadLineOptions } from "readline"; -import { promises } from "fs"; +import { existsSync, promises } from "fs"; import { join } from "path"; import { firstUpperCase } from "./Util"; import chalk from "chalk"; @@ -15,38 +15,36 @@ function awaitQuestion(query: string): Promise { return new Promise(resolve => rl.question(query, resolve)); } -function end(reason?: string): void { - if (reason) rl.write(chalk`{bgRed {black \ CANCELED }} ${reason}`); - else rl.write(chalk`{bgGreen {black \ SUCCES }} Command created ✓`); +function end(prop?: string): void { + if (prop) rl.write(chalk`{bgRed {black \ ERROR }} Command {blue ${prop}} is required`); rl.write("\n"); process.exit(0); } export async function exec(): Promise { - rl.write(chalk`{bgBlue {black \ INFO }} Please describe your command !`); - rl.write("\n"); + rl.write(chalk`\n{bgBlue {black \ INFO }} Please describe your {blue command} !\n\n`); let aliases: string[] = []; - const id = await awaitQuestion(chalk` {blue •} What identifier for this command ? `); - if (!id.length) return end("Command identifier is required"); + const id = await awaitQuestion(chalk` {blue •} What {blue identifier} for this command ? `); + if (!id.length) return end("identifier"); aliases.push(id); - await awaitQuestion(chalk` {blue •} Please insert aliases you want splited by comma (,) ! `).then(x => aliases.push(...x.split(","))); + await awaitQuestion(chalk` {blue •} Please insert {blue aliases} you want splited by comma (,) ! `).then(x => aliases.push(...x.split(","))); aliases = aliases.filter(x => x.length); - const descriptionContent = await awaitQuestion(chalk` {blue •} What description of the command ? (if came from localization please insert the id between <>) `) + const descriptionContent = await awaitQuestion(chalk` {blue •} What {blue description} of the command ? {gray (if came from localization please insert the id between <>)} `) .then(x => { if (!x.length) return ""; if (x.startsWith("<") && x.endsWith(">")) return `(msg): string => msg.ctx.lang("${x.replace(/<|>/g, "")}")`; return `"${x}"`; }); - if (!descriptionContent.length) return end("Command Description is required"); - const usageDescription = await awaitQuestion(chalk` {blue •} How you usage this command ? `); - if (!usageDescription.length) return end("Command usage is required"); - const exampleDescription = await awaitQuestion(chalk` {blue •} Please write at least 1 example ! `); - if (!exampleDescription.length) return end("Command example is required"); - const category = await awaitQuestion(chalk` {blue •} Which category that ship this command ? (${categories.join(", ")}) `); - if (!category.length) return end("Command category is required"); - const filename = await awaitQuestion(chalk` {blue •} What the filename do you want ? (${firstUpperCase(id)}) `).then(x => x.length ? x : firstUpperCase(id)); - const dirname = await awaitQuestion(chalk` {blue •} What the dirname do you want ? (${firstUpperCase(category)}) `).then(x => x.length ? x : firstUpperCase(category)); + if (!descriptionContent.length) return end("description"); + const usageDescription = await awaitQuestion(chalk` {blue •} How you {blue usage} this command ? `); + if (!usageDescription.length) return end("usage"); + const exampleDescription = await awaitQuestion(chalk` {blue •} Please write at least 1 {blue example} ! `); + if (!exampleDescription.length) return end("example"); + const category = await awaitQuestion(chalk` {blue •} Which {blue category} that ship this command ? {gray (${categories.join(", ")})} `); + if (!category.length) return end("categroy"); + const filename = await awaitQuestion(chalk` {blue •} What the {blue filename} do you want ? {gray (${firstUpperCase(id)})} `).then(x => x.length ? x : firstUpperCase(id)); + const dirname = await awaitQuestion(chalk` {blue •} What the {blue dirname} do you want ? {gray (${firstUpperCase(category)})} `).then(x => x.length ? x : firstUpperCase(category)); const toWrite = `import Command from "@yumeko/classes/Command"; import type { Message } from "discord.js"; import { DeclareCommand, constantly } from "@yumeko/decorators"; @@ -66,7 +64,17 @@ export default class extends Command { return msg; } }`; - await promises.writeFile(join("./src/commands", dirname, `${filename}.ts`), toWrite, { encoding: "utf-8" }); + const path = join("./src/commands", dirname); + rl.write(chalk`\n{bgBlue {black \ INFO }} Checking directory...\n`); + if (!existsSync(path)) { + rl.write(chalk`{bgBlue {black \ INFO }} Directory isn't exist try to create...\n`); + await promises.mkdir(path, { recursive: true }); + rl.write(chalk`{bgGreen {black \ DONE }} Directory Created !\n`); + } + rl.write(chalk`{bgBlue {black \ INFO }} Writting command...\n`); + const file = join(path, `${filename}.ts`); + await promises.writeFile(file, toWrite, { encoding: "utf-8" }); + rl.write(chalk`{bgGreen {black \ DONE }} Succes write command to {green ${file}}\n`); return end(); } From 6ebfb8f18bc9a9952fccab16b55f1ecf7590495e Mon Sep 17 00:00:00 2001 From: youKnowOwO Date: Sun, 4 Oct 2020 09:04:13 +0800 Subject: [PATCH 5/6] refactor: show error when promise fail --- src/util/CreateCommand.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/util/CreateCommand.ts b/src/util/CreateCommand.ts index 1f68ae5..cb99530 100644 --- a/src/util/CreateCommand.ts +++ b/src/util/CreateCommand.ts @@ -15,8 +15,9 @@ function awaitQuestion(query: string): Promise { return new Promise(resolve => rl.question(query, resolve)); } -function end(prop?: string): void { - if (prop) rl.write(chalk`{bgRed {black \ ERROR }} Command {blue ${prop}} is required`); +function end(prop?: string, error = false): void { + if (error) rl.write(chalk`{bgRed {black \ ERROR }} {red ${prop}}`); + else if (prop) rl.write(chalk`{bgRed {black \ ERROR }} Command {blue ${prop}} is required`); rl.write("\n"); process.exit(0); } @@ -78,4 +79,4 @@ export default class extends Command { return end(); } -exec(); \ No newline at end of file +exec().catch((e: Error) => end(String(e), true)); \ No newline at end of file From 4d2ee508cd0af148e9d92949e36931f3d1500f63 Mon Sep 17 00:00:00 2001 From: youKnowOwO Date: Thu, 8 Oct 2020 22:26:58 +0800 Subject: [PATCH 6/6] feat: Renew Log & Add Sync Config --- config.json.example | 2 +- package.json | 1 + src/classes/Client.ts | 3 ++- src/events/Debug.ts | 6 ++++-- src/events/Ready.ts | 4 ---- src/interfaces/Config.ts | 16 ++++++++++++++++ src/interfaces/Event.ts | 17 ++++++++++++----- src/interfaces/index.ts | 3 ++- src/libs/CommandCollector.ts | 8 +++----- src/libs/EventLoader.ts | 1 + src/util/ConfigTypeSync.ts | 32 ++++++++++++++++++++++++++++++++ src/yumeko.ts | 2 +- 12 files changed, 75 insertions(+), 20 deletions(-) create mode 100644 src/interfaces/Config.ts create mode 100644 src/util/ConfigTypeSync.ts diff --git a/config.json.example b/config.json.example index ecb04f0..2a3b961 100644 --- a/config.json.example +++ b/config.json.example @@ -11,5 +11,5 @@ "password": "" }, "myriad": "", - "debug": false + "dev": false } \ No newline at end of file diff --git a/package.json b/package.json index 867d048..012fef7 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "start": "node dist", "start:dev": "node dist/yumeko.js dev", "create:cmd": "node dist/util/CreateCommand.js", + "config:sync": "node dist/util/ConfigTypeSync.js", "test": "yarn lint && yarn build" }, "repository": "https://github.com/youKnowOwO/yumeko-ts.git", diff --git a/src/classes/Client.ts b/src/classes/Client.ts index 8b11d2e..f42a42e 100644 --- a/src/classes/Client.ts +++ b/src/classes/Client.ts @@ -7,6 +7,7 @@ import Logger from "@yumeko/libs/Logger"; import eventLoader from "@yumeko/libs/EventLoader"; import nowPlayMoe from "@yumeko/libs/NowplayMoeWS"; import { langCollector } from "@yumeko/libs/Localization"; +import { Config } from "@yumeko/interfaces"; import { Client } from "discord.js"; import { Node as Lavalink } from "lavalink"; @@ -14,7 +15,7 @@ import "../extension"; import { hide } from "@yumeko/decorators"; // i don't want compiler compile these one -const config = require("../../config.json"); +const config: Config = require("../../config.json"); export default class YumekoClient extends Client { @hide diff --git a/src/events/Debug.ts b/src/events/Debug.ts index 33a47fa..a07babf 100644 --- a/src/events/Debug.ts +++ b/src/events/Debug.ts @@ -3,10 +3,12 @@ import { Event } from "@yumeko/interfaces"; export default class DebugEvent implements Event { public readonly listener = "debug"; + public readonly devOnly = true; public constructor(public readonly client: YumekoClient) {} public exec(msg: string): void { - if (this.client.config.debug) { + if (this.client.config.dev) { this.client.log.info(msg); } } -} \ No newline at end of file +} + diff --git a/src/events/Ready.ts b/src/events/Ready.ts index 755485d..5c5e369 100644 --- a/src/events/Ready.ts +++ b/src/events/Ready.ts @@ -1,6 +1,5 @@ import type YumekoClient from "@yumeko/classes/Client"; import { Event } from "@yumeko/interfaces"; -import { stripIndents } from "common-tags"; import { constantly } from "@yumeko/decorators"; const presences = require("../../assets/json/presence.json"); @@ -12,9 +11,6 @@ export default class ReadyEvent implements Event { @constantly public exec (): void { assignDB(this.client); - this.client.log.info(stripIndents` - ${this.client.log.color(this.client.user!.tag, "FFFFFF")} is Ready to play. ${this.client.shard ? this.client.shard.ids.map(x => this.client.log.color(`#${x + 1}`, "00FFFF")).join(", ") : ""} - `); this.client.lavalink.userID = this.client.user!.id; presence.call(null, this.client); setInterval(presence.bind(null, this.client), 60000); diff --git a/src/interfaces/Config.ts b/src/interfaces/Config.ts new file mode 100644 index 0000000..d6924c2 --- /dev/null +++ b/src/interfaces/Config.ts @@ -0,0 +1,16 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +export interface Config { + owners: string[]; + prefix: string; + color: string; + lavalink: { + hosts: { + rest: string; + ws: string; + }; + password: string; + }; + myriad: string; + dev: boolean; +} \ No newline at end of file diff --git a/src/interfaces/Event.ts b/src/interfaces/Event.ts index 5ffcd49..f7f718e 100644 --- a/src/interfaces/Event.ts +++ b/src/interfaces/Event.ts @@ -1,10 +1,17 @@ +import type Command from "@yumeko/classes/Command"; import type { ClientEvents } from "discord.js"; -export interface YumekoClientEvents extends ClientEvents { - raw: [any]; -} +type EventKeys = keyof ClientEvents; export interface Event { - readonly listener: keyof YumekoClientEvents; - exec(...args: YumekoClientEvents[Event["listener"]]): any; + readonly listener: EventKeys; + readonly devOnly?: boolean; + exec(...args: ClientEvents[EventKeys]): any; +} + +declare module "discord.js" { + interface ClientEvents { + raw: [any]; + commandStored: [Command?]; + } } \ No newline at end of file diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index 17f8272..ac8b39e 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -1,4 +1,5 @@ export * from "@yumeko/interfaces/Command"; export * from "@yumeko/interfaces/Other"; export * from "@yumeko/interfaces/Event"; -export * from "@yumeko/interfaces/HTTPResponse"; \ No newline at end of file +export * from "@yumeko/interfaces/HTTPResponse"; +export * from "@yumeko/interfaces/Config"; \ No newline at end of file diff --git a/src/libs/CommandCollector.ts b/src/libs/CommandCollector.ts index 84d54eb..0ff834e 100644 --- a/src/libs/CommandCollector.ts +++ b/src/libs/CommandCollector.ts @@ -18,25 +18,23 @@ export default class CommandCollector { public constructor(public client: YumekoClient) {} - public loadAll(log = true): void { + public loadAll(): void { const path = join(__dirname, "../commands"); const files = readdirRecursive(path); - const { print, color, equal, date } = this.client.log; - if (log) print(equal(color("▶️ Collecting Command", "00C2FF"))); for (const file of files) { const load = require(file).default; if (!load || !(load.prototype instanceof Command)) continue; const command = this.getCommand(file); this.registry(command); - if (log) print(`+ ${color(command.identifier, "FE9DFF")} (${color(file, "A20092")})`); } - if (log) print(equal(color(date(), "505050"))); + this.client.emit("commandStored"); } public registry(command: string | Command): void { if (typeof command === "string") command = this.getCommand(command); this.addToCategory(command); this.commands.set(command.identifier, command); + this.client.emit("commandStored", command); } public getCommand(path: string): Command { diff --git a/src/libs/EventLoader.ts b/src/libs/EventLoader.ts index 379e58e..b1cd9bf 100644 --- a/src/libs/EventLoader.ts +++ b/src/libs/EventLoader.ts @@ -8,6 +8,7 @@ export default function EventLoader (client: YumekoClient): void { const files = readdirRecursive(path); for (const file of files) { const event: Event = new (require(file).default)(client); + if (event.devOnly && !client.config.dev) continue; client.addListener(event.listener, event.exec.bind(event) as any); } } \ No newline at end of file diff --git a/src/util/ConfigTypeSync.ts b/src/util/ConfigTypeSync.ts new file mode 100644 index 0000000..13a1a1e --- /dev/null +++ b/src/util/ConfigTypeSync.ts @@ -0,0 +1,32 @@ +/* eslint-disable @typescript-eslint/ban-types */ +import chalk from "chalk"; +import { promises } from "fs"; + +const config: object = require("../../config.json"); + +function parse(data: any, indent = 1): string { + const type = typeof data; + if (data instanceof Array) return parseArray(data, indent); + if (type === "object") return parseObject(data, indent); + return type; +} + +function parseObject(data: Record | null, indent: number): string { + if (data === null) return "null"; + const space = " ".repeat(indent * 4); + const types = []; + for (const x of Object.keys(data)) types.push(`${space}${x}: ${parse(data[x], indent + 1)};`); + return types.length ? `{\n${types.join("\n")}\n${space.slice(4)}}` : "{}"; +} + +function parseArray(data: T[], indent: number): string { + const parsed = parse(data[0], indent); + return `${parsed}[]`; +} + +void async function exec(): Promise { + const toWrite = `// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.\n\nexport interface Config ${parse(config)}`; + await promises.writeFile("./src/interfaces/Config.ts", toWrite); + process.stdout.write(chalk`{bgGreen {black \ DONE }} Config sucessfully sync`); + process.stdout.write("\n"); +}(); \ No newline at end of file diff --git a/src/yumeko.ts b/src/yumeko.ts index 59c82cf..b1426be 100644 --- a/src/yumeko.ts +++ b/src/yumeko.ts @@ -2,7 +2,7 @@ import YumekoClient from "./classes/Client"; if (process.argv[2] === "dev") { require("./util/EnvLoader"); - require("../config.json").debug = true; + require("../config.json").dev = true; } const client = new YumekoClient();