diff --git a/base/newClient.js b/base/newClient.js index 28a2cb30..b1b4e2f1 100644 --- a/base/newClient.js +++ b/base/newClient.js @@ -1,12 +1,9 @@ -import { Client, Collection, REST, Routes } from "discord.js"; +import { Client } from "discord.js"; import { config } from "../config.js"; -import { glob } from "glob"; -import { dirname } from "node:path"; +import { init as initCommands } from "../handlers/command-handler/index.js"; +import { init as initEvents } from "../handlers/event-handler/index.js"; export class ExtendedClient extends Client { - commands = new Collection(); - __dirname = dirname(new URL(import.meta.url).pathname); - rest = new REST().setToken(config.token); /** * @param {import("discord.js").ClientOptions} options */ @@ -14,58 +11,7 @@ export class ExtendedClient extends Client { super(options); } - init() { - this.registerModules(); - this.login(config.token); - } - - async importFile(filePath) { - return (await import(`file://${filePath}`))?.default; - } - - async registerModules() { - await Promise.all([this.registerCommands(this.__dirname), this.registerEvents(this.__dirname)]); - } - - async registerCommands(baseDir) { - const commandFiles = await glob(`${baseDir}/../newCommands/*/*.js`); - const slashCommands = []; - - for (const filePath of commandFiles) { - try { - const command = await this.importFile(filePath); - if (!command.data.name) return; - - this.commands.set(command.data.name, command); - slashCommands.push(command.data.toJSON()); - } catch (error) { - console.error(`Error loading command ${filePath}:`, error); - } - } - - if (!slashCommands.length) return; - - try { - const route = config.production ? Routes.applicationCommands(config.userId) : Routes.applicationGuildCommands(config.userId, config.support.id); - const data = await this.rest.put(route, { body: slashCommands }); - - console.log(`Successfully registered ${data.length} application commands.`); - } catch (error) { - console.log(error); - } - } - - async registerEvents(baseDir) { - const eventFiles = await glob(`${baseDir}/../newEvents/**/*.js`); - - for (const file of eventFiles) { - const event = await this.importFile(file); - - if (event.data.once) { - this.once(event.data.name, event.run); - } else { - this.on(event.data.name, event.run); - } - } + async init() { + this.login(config.token).then(async () => await Promise.all([initCommands(), initEvents()]).catch(console.error)); } } diff --git a/base/newCommand.js b/base/newCommand.js deleted file mode 100644 index 82dcad43..00000000 --- a/base/newCommand.js +++ /dev/null @@ -1,18 +0,0 @@ -export default class Command { - constructor(options) { - /** - * @type {import("discord.js").ApplicationCommandData} - */ - this.data = options.data; - /** - * @type {Boolean} - */ - this.ownerOnly = !!options.ownerOnly || false; - /** - * @param {import("discord.js").CommandInteraction} [interaction] - * @param {import('./newClient.js').ExtendedClient} [client] - * @param {import("discord.js").CommandInteractionOptionResolver} [args] - */ - this.execute = function () {}; - } -} diff --git a/base/newEvent.js b/base/newEvent.js deleted file mode 100644 index 4675a7fc..00000000 --- a/base/newEvent.js +++ /dev/null @@ -1,10 +0,0 @@ -export default class BaseEvent { - /** - * @param {{ name: import("discord.js").ClientEvents, once: boolean}} options - * @param {Function} run - */ - constructor(data, run) { - this.data = data; - this.run = run; - } -} diff --git a/handlers/command-handler/functions/registerCommands.js b/handlers/command-handler/functions/registerCommands.js new file mode 100644 index 00000000..2f4e5740 --- /dev/null +++ b/handlers/command-handler/functions/registerCommands.js @@ -0,0 +1,19 @@ +export default async function registerCommands(props) { + const globalCommands = props.commands.filter(cmd => !cmd.options?.devOnly); + await registerGlobalCommands(props.client, globalCommands); +} + +const registerGlobalCommands = async (client, commands) => { + const appCommandsManager = client.application.commands; + await appCommandsManager.fetch(); + + const newCommands = commands.filter(cmd => !appCommandsManager.cache.some(existingCmd => existingCmd.name === cmd.data.name)); + + await Promise.all( + newCommands.map(data => + appCommandsManager.create(data).catch(() => { + throw new Error(`Failed to register command: ${data.name}`); + }), + ), + ); +}; diff --git a/handlers/command-handler/index.js b/handlers/command-handler/index.js new file mode 100644 index 00000000..50538603 --- /dev/null +++ b/handlers/command-handler/index.js @@ -0,0 +1,35 @@ +import { client } from "../../index.js"; +import { getFilePaths } from "../../utils/get-path.js"; +import { toFileURL } from "../../utils/resolve-file.js"; +import registerCommands from "./functions/registerCommands.js"; + +export const commands = []; + +export const init = async () => { + await buildCommands(); + + await registerCommands({ + client, + commands, + }); +}; + +const buildCommands = async () => { + const commandFilePaths = (await getFilePaths("./newCommands", true)).filter(path => path.endsWith(".js")); + + for (const cmdFilePath of commandFilePaths) { + const { data, run } = await import(toFileURL(cmdFilePath)); + + if (!data || !data.name) { + console.warn(`Command ${cmdFilePath} does not have a data object or name`); + continue; + } + + if (typeof run !== "function") { + console.warn(`Command ${cmdFilePath} does not have a run function or it is not a function`); + continue; + } + + commands.push({ data, run }); + } +}; diff --git a/handlers/event-handler/index.js b/handlers/event-handler/index.js new file mode 100644 index 00000000..cd52e970 --- /dev/null +++ b/handlers/event-handler/index.js @@ -0,0 +1,41 @@ +import { client } from "../../index.js"; +import { getFilePaths } from "../../utils/get-path.js"; +import { toFileURL } from "../../utils/resolve-file.js"; + +export const events = []; + +export const init = async () => { + await buildEvents(); + + registerEvents(); +}; + +const buildEvents = async () => { + const eventFilePaths = (await getFilePaths("./newEvents", true)).filter(path => path.endsWith(".js")); + + for (const eventFilePath of eventFilePaths) { + const { data, run } = await import(toFileURL(eventFilePath)); + + if (!data || !data.name) { + console.warn(`Event ${eventFilePath} does not have a data object or name`); + continue; + } + + if (typeof run !== "function") { + console.warn(`Event ${eventFilePath} does not have a run function or it is not a function`); + continue; + } + + events.push({ data, run }); + } +}; + +const registerEvents = () => { + for (const { data, run } of events) { + if (data.once) { + client.once(data.name, run); + } else { + client.on(data.name, run); + } + } +}; diff --git a/newCommands/Fun/8ball.js b/newCommands/Fun/8ball.js index 226246bf..7600c06c 100644 --- a/newCommands/Fun/8ball.js +++ b/newCommands/Fun/8ball.js @@ -1,10 +1,8 @@ -import { SlashCommandBuilder } from "discord.js"; -import Command from "../../base/newCommand.js"; +export const data = { + name: "8ball", + description: "8ball", +}; -export default new Command({ - data: new SlashCommandBuilder().setName("8ball").setDescription("8ball"), - execute(interaction) { - console.log("8ball"); - interaction.reply("8ball"); - }, -}); +export const run = () => { + console.log("8ball"); +}; diff --git a/newEvents/ready.js b/newEvents/ready.js index 433cbcb3..dfa2a88b 100644 --- a/newEvents/ready.js +++ b/newEvents/ready.js @@ -1,11 +1,8 @@ -import Event from "../base/newEvent.js"; +export const data = { + name: "ready", + once: true, +}; -export default new Event( - { - name: "ready", - once: true, - }, - client => { - console.log(client.user.tag + " is online!"); - }, -); +export async function run(client) { + console.log(client.user.tag + " is online!"); +} diff --git a/package.json b/package.json index 4fcc3794..f69dbec3 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "discord-player-youtubei": "1.3.5", "discord.js": "^14.16.3", "gamedig": "^5.1.4", - "glob": "^11.0.0", "i18next": "^24.0.0", "i18next-fs-backend": "^2.6.0", "md5": "^2.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c08938c..c6b4d075 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,9 +47,6 @@ importers: gamedig: specifier: ^5.1.4 version: 5.1.4 - glob: - specifier: ^11.0.0 - version: 11.0.0 i18next: specifier: ^24.0.0 version: 24.0.0(typescript@5.7.2) @@ -230,10 +227,6 @@ packages: resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -448,10 +441,6 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} - ansi-styles@2.2.1: resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} engines: {node: '>=0.10.0'} @@ -464,10 +453,6 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -682,15 +667,9 @@ packages: domutils@3.1.0: resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -814,10 +793,6 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} - engines: {node: '>=14'} - form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} @@ -862,11 +837,6 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@11.0.0: - resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} - engines: {node: 20 || >=22} - hasBin: true - glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -1006,10 +976,6 @@ packages: isomorphic-unfetch@4.0.2: resolution: {integrity: sha512-1Yd+CF/7al18/N2BDbsLBcp6RO3tucSW+jcLq24dqdX5MNbCNTw1z4BsGsp4zNmjr/Izm2cs/cEqZPp4kvWSCA==} - jackspeak@4.0.2: - resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} - engines: {node: 20 || >=22} - jintr@3.0.2: resolution: {integrity: sha512-5g2EBudeJFOopjAX4exAv5OCCW1DgUISfoioCsm1h9Q9HJ41LmnZ6J52PCsqBlQihsmp0VDuxreAVzM7yk5nFA==} @@ -1073,10 +1039,6 @@ packages: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lru-cache@11.0.2: - resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} - engines: {node: 20 || >=22} - luxon@3.5.0: resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} engines: {node: '>=12'} @@ -1110,10 +1072,6 @@ packages: resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} - engines: {node: 20 || >=22} - minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -1132,10 +1090,6 @@ packages: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -1258,9 +1212,6 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - package-json-from-dist@1.0.1: - resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1283,10 +1234,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} - engines: {node: 20 || >=22} - path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -1452,10 +1399,6 @@ packages: signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -1492,10 +1435,6 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} @@ -1513,10 +1452,6 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -1646,14 +1581,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -1893,15 +1820,6 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 @@ -2085,8 +2003,6 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.1.0: {} - ansi-styles@2.2.1: {} ansi-styles@4.3.0: @@ -2095,8 +2011,6 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} - any-promise@1.3.0: {} aproba@2.0.0: {} @@ -2344,12 +2258,8 @@ snapshots: domelementtype: 2.3.0 domhandler: 5.0.3 - eastasianwidth@0.2.0: {} - emoji-regex@8.0.0: {} - emoji-regex@9.2.2: {} - entities@4.5.0: {} escape-string-regexp@1.0.5: {} @@ -2537,11 +2447,6 @@ snapshots: flatted@3.3.1: {} - foreground-child@3.3.0: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - form-data-encoder@2.1.4: {} formdata-polyfill@4.0.10: @@ -2600,15 +2505,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@11.0.0: - dependencies: - foreground-child: 3.3.0 - jackspeak: 4.0.2 - minimatch: 10.0.1 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.0 - glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -2747,10 +2643,6 @@ snapshots: node-fetch: 3.3.2 unfetch: 5.0.0 - jackspeak@4.0.2: - dependencies: - '@isaacs/cliui': 8.0.2 - jintr@3.0.2: dependencies: acorn: 8.12.1 @@ -2806,8 +2698,6 @@ snapshots: lowercase-keys@3.0.0: {} - lru-cache@11.0.2: {} - luxon@3.5.0: {} magic-bytes.js@1.10.0: {} @@ -2835,10 +2725,6 @@ snapshots: mimic-response@4.0.0: {} - minimatch@10.0.1: - dependencies: - brace-expansion: 2.0.1 - minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -2855,8 +2741,6 @@ snapshots: minipass@5.0.0: {} - minipass@7.1.2: {} - minizlib@2.1.2: dependencies: minipass: 3.3.6 @@ -2971,8 +2855,6 @@ snapshots: dependencies: p-limit: 3.1.0 - package-json-from-dist@1.0.1: {} - parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -2992,11 +2874,6 @@ snapshots: path-key@3.1.1: {} - path-scurry@2.0.0: - dependencies: - lru-cache: 11.0.2 - minipass: 7.1.2 - path-type@4.0.0: {} peek-readable@4.1.0: {} @@ -3135,8 +3012,6 @@ snapshots: signal-exit@3.0.7: {} - signal-exit@4.1.0: {} - slash@3.0.0: {} smart-buffer@4.2.0: @@ -3177,12 +3052,6 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - string_decoder@0.10.31: {} string_decoder@1.1.1: @@ -3201,10 +3070,6 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - strip-json-comments@3.1.1: {} strtok3@6.3.0: @@ -3321,18 +3186,6 @@ snapshots: word-wrap@1.2.5: {} - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - wrappy@1.0.2: {} ws@8.18.0: {} diff --git a/utils/get-path.js b/utils/get-path.js new file mode 100644 index 00000000..800ce749 --- /dev/null +++ b/utils/get-path.js @@ -0,0 +1,24 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +export const getFilePaths = async (directory, nesting) => { + let filePaths = []; + + if (!directory) return; + + const files = await fs.readdir(directory, { withFileTypes: true }); + + for (const file of files) { + const filePath = path.join(directory, file.name); + + if (file.isFile()) { + filePaths.push(filePath); + } + + if (nesting && file.isDirectory()) { + filePaths = [...filePaths, ...(await getFilePaths(filePath, true))]; + } + } + + return filePaths; +}; diff --git a/utils/resolve-file.js b/utils/resolve-file.js new file mode 100644 index 00000000..58264449 --- /dev/null +++ b/utils/resolve-file.js @@ -0,0 +1,11 @@ +import path from "node:path"; + +/** + * Convert a local file path to a file URL. + * @param {string} filePath - local file's path. + * @returns {string} file URL + */ +export const toFileURL = filePath => { + const resolvedPath = path.resolve(filePath); + return "file://" + resolvedPath.replace(/\\\\|\\/g, "/"); +};