From 4585f60af79db37c04dff903df39f78a833c5fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linnea=20Gr=C3=A4f?= Date: Sat, 22 Feb 2025 16:06:44 +0100 Subject: [PATCH] Strongly typed config (and ts strict mode) --- src/command.ts | 10 +++++----- src/commands/nowplaying.ts | 7 ++++--- src/commands/ping.ts | 5 +++-- src/commands/src.ts | 5 +++-- src/config.ts | 11 +++++++++++ src/index.ts | 6 +++--- tsconfig.json | 3 ++- 7 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 src/config.ts diff --git a/src/command.ts b/src/command.ts index b13d862..399f575 100644 --- a/src/command.ts +++ b/src/command.ts @@ -1,7 +1,7 @@ import {ChatInputCommandInteraction, SharedSlashCommand} from "discord.js"; +import { Config } from "./config"; -export class Command { - constructor(){} - async run (interaction: ChatInputCommandInteraction, config): Promise{}; - slashCommand: SharedSlashCommand -} \ No newline at end of file +export abstract class Command { + abstract run(interaction: ChatInputCommandInteraction, config: Config): Promise; + abstract slashCommand: SharedSlashCommand +} diff --git a/src/commands/nowplaying.ts b/src/commands/nowplaying.ts index 2ed2e4e..7e1d2c8 100644 --- a/src/commands/nowplaying.ts +++ b/src/commands/nowplaying.ts @@ -11,8 +11,9 @@ import { } from "discord.js"; import { getSongOnPreferredProvider } from "../helper.ts" +import { Config } from "../config.ts"; -function keepV(url) { +function keepV(url: string): string { const urlObj = new URL(url); const vParam = urlObj.searchParams.get("v"); @@ -26,7 +27,7 @@ function keepV(url) { } export default class PingCommand extends Command { - async run(interaction: ChatInputCommandInteraction, config) { + async run(interaction: ChatInputCommandInteraction, config: Config) { await interaction.deferReply() @@ -76,4 +77,4 @@ export default class PingCommand extends Command { InteractionContextType.Guild, InteractionContextType.PrivateChannel ]); -} \ No newline at end of file +} diff --git a/src/commands/ping.ts b/src/commands/ping.ts index 179d9ab..a044620 100644 --- a/src/commands/ping.ts +++ b/src/commands/ping.ts @@ -5,9 +5,10 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; +import { Config } from "../config.ts"; export default class PingCommand extends Command { - async run(interaction: ChatInputCommandInteraction, config) { + async run(interaction: ChatInputCommandInteraction, config: Config) { await interaction.reply({ content: 'Pong!', }); @@ -23,4 +24,4 @@ export default class PingCommand extends Command { InteractionContextType.Guild, InteractionContextType.PrivateChannel ]); -} \ No newline at end of file +} diff --git a/src/commands/src.ts b/src/commands/src.ts index f39cf72..e8978b0 100644 --- a/src/commands/src.ts +++ b/src/commands/src.ts @@ -6,9 +6,10 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; +import { Config } from "../config.ts"; export default class PingCommand extends Command { - async run(interaction: ChatInputCommandInteraction, config) { + async run(interaction: ChatInputCommandInteraction, config: Config) { const repo = interaction.options.getString("repo") const meow = await fetch(config.gitapi + repo).then(res => res.json()); const embed = new EmbedBuilder() @@ -38,4 +39,4 @@ export default class PingCommand extends Command { InteractionContextType.Guild, InteractionContextType.PrivateChannel ]); -} \ No newline at end of file +} diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..1482ad9 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,11 @@ +import rawconfig from "../config.json" with {type: "json"}; +import {z} from 'zod'; +const configT = z.object({ + token: z.string(), + listenbrainzAccount: z.string(), + gitapi: z.string(), +}); +export type Config = z.infer; +export const config: Config = configT.parse(rawconfig); + + diff --git a/src/index.ts b/src/index.ts index d00b4c7..80e666c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import config from "../config.json" with {type: "json"}; import { Client, Events, @@ -10,6 +9,7 @@ import path from "node:path"; import fs from "node:fs"; import { Command } from "./command.ts"; import { fileURLToPath } from "url"; +import { config } from "./config.ts"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -36,7 +36,7 @@ client.once(Events.ClientReady, async () => { console.log("Ready"); const rest = new REST().setToken(config.token); const data = await rest.put( - Routes.applicationCommands(client.user.id), { body: commands.map(command => command.slashCommand.toJSON()) }, + Routes.applicationCommands(client.user!.id), { body: commands.map(command => command.slashCommand.toJSON()) }, ); // @ts-ignore console.log(`Successfully reloaded ${data.length} application (/) commands.`); @@ -62,4 +62,4 @@ client.on(Events.InteractionCreate, async (interaction) => { }) -await client.login(config.token); \ No newline at end of file +await client.login(config.token); diff --git a/tsconfig.json b/tsconfig.json index e1ead09..042b4a5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,8 @@ "esModuleInterop": true, "allowImportingTsExtensions": true, "noEmit": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "strict": true }, "ts-node": { "compilerOptions": {