From f76984fa7d4ec0109bc02d88278a1fef6eae0ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linnea=20Gr=C3=A4f?= Date: Sat, 12 Apr 2025 12:46:12 +0200 Subject: [PATCH] cleanup music search + actually compile subdirectories with tsc :sob: --- .gitignore | 1 + src/command.ts | 2 +- src/commands/eval.ts | 8 ++--- src/commands/fediemoji.ts | 6 ++-- src/commands/mock.ts | 6 +--- src/commands/musicsearch.ts | 55 ++++++++++++++++++---------------- src/commands/nowplaying.ts | 2 +- src/commands/pat.ts | 4 +-- src/commands/ping.ts | 2 +- src/commands/songinfo.ts | 2 +- src/commands/src.ts | 2 +- src/commands/stealemoji.ts | 2 +- src/commands/superfakenitro.ts | 6 ++-- src/commands/uwuifier.ts | 6 +--- src/util.ts | 12 ++++++++ tsconfig.json | 2 +- 16 files changed, 63 insertions(+), 55 deletions(-) create mode 100644 src/util.ts diff --git a/.gitignore b/.gitignore index 7392e1d..1e0aeee 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* /.pnp +src/**/*.js .pnp.js .vscode/* \ No newline at end of file diff --git a/src/command.ts b/src/command.ts index ff9588d..8fc233b 100644 --- a/src/command.ts +++ b/src/command.ts @@ -1,5 +1,5 @@ import { ApplicationCommandType, type AutocompleteFocusedOption, AutocompleteInteraction, ChatInputCommandInteraction, ContextMenuCommandBuilder, ContextMenuCommandInteraction, Message, SharedSlashCommand, User } from "discord.js"; -import { type Config } from "./config"; +import { type Config } from "./config.ts"; export abstract class ICommand { } diff --git a/src/commands/eval.ts b/src/commands/eval.ts index f51439f..fc3cb99 100644 --- a/src/commands/eval.ts +++ b/src/commands/eval.ts @@ -2,14 +2,12 @@ import { ApplicationCommandType, ContextMenuCommandBuilder, ContextMenuCommandInteraction, escapeCodeBlock, - InteractionContextType, Message, - Snowflake, - User, UserResolvable + type UserResolvable } from "discord.js"; import { parse as acornParse } from 'acorn' import { ContextCommand } from "../command.ts"; -import {ModuleDeclaration, Statement} from "acorn"; +import {type ModuleDeclaration,type Statement} from "acorn"; import {generate} from "astring"; import {inspect} from "node:util"; @@ -130,4 +128,4 @@ export default class Mock extends ContextCommand { await interaction.editReply('```js\n' + escapeCodeBlock(inspect(result)) + "\n```") } } -} \ No newline at end of file +} diff --git a/src/commands/fediemoji.ts b/src/commands/fediemoji.ts index 3e4a0e1..94d65a6 100644 --- a/src/commands/fediemoji.ts +++ b/src/commands/fediemoji.ts @@ -1,11 +1,11 @@ import {Command} from "../command.ts"; import { - ApplicationIntegrationType, AutocompleteFocusedOption, AutocompleteInteraction, + ApplicationIntegrationType, type AutocompleteFocusedOption, AutocompleteInteraction, ChatInputCommandInteraction, - InteractionContextType, RESTGetAPIApplicationEmojisResult, Routes, + InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { config, Config } from "../config.ts"; +import { config, type Config } from "../config.ts"; export default class FediemojiCommand extends Command { async getSharkeyEmojis() { diff --git a/src/commands/mock.ts b/src/commands/mock.ts index c97c57b..70a2558 100644 --- a/src/commands/mock.ts +++ b/src/commands/mock.ts @@ -2,11 +2,7 @@ import { ApplicationCommandType, ContextMenuCommandBuilder, ContextMenuCommandInteraction, - InteractionContextType, - Message, - Snowflake, - User -} from "discord.js"; + Message} from "discord.js"; import { ContextCommand } from "../command.ts"; export default class Mock extends ContextCommand { diff --git a/src/commands/musicsearch.ts b/src/commands/musicsearch.ts index 3b0bc24..5378e67 100644 --- a/src/commands/musicsearch.ts +++ b/src/commands/musicsearch.ts @@ -1,4 +1,5 @@ import {Command} from "../command.ts"; +import {chunkArray} from '../util.ts'; import { ActionRowBuilder, ApplicationIntegrationType, ButtonBuilder, ButtonStyle, @@ -6,8 +7,21 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { Config } from "../config.ts"; +import { type Config } from "../config.ts"; import {getSongOnPreferredProvider, kyzaify} from "../helper.ts"; +import * as z from 'zod'; + +const itunesResponseShape = z.object({ + results: z.array(z.object({ + artistId: z.number(), + artistName: z.string(), + trackViewUrl: z.string(), + trackName: z.string(), + collectionName: z.string(), + collectionCensoredName: z.string().optional(), + censoredTrackName: z.string().optional(), + })) +}) export default class PingCommand extends Command { async run(interaction: ChatInputCommandInteraction, config: Config) { @@ -15,8 +29,11 @@ export default class PingCommand extends Command { const search = interaction.options.getString("search")! const paramsObj = {entity: "song", term: search}; const searchParams = new URLSearchParams(paramsObj); - const itunesinfo = (await (await fetch(`https://itunes.apple.com/search?${searchParams.toString()}`)).json()).results[0]; - const link = itunesinfo.trackViewUrl + const itunesResponse = await fetch(`https://itunes.apple.com/search?${searchParams.toString()}`); + const itunesJson = await itunesResponse.json(); + const itunesinfo = itunesResponseShape.parse(itunesJson); + const itunesSong = itunesinfo.results[0]; + const link = itunesSong.trackViewUrl const songlink = await fetch(`https://api.song.link/v1-alpha.1/links?url=${link}`).then(a => a.json()) const preferredApi = getSongOnPreferredProvider(songlink, link)! @@ -29,30 +46,18 @@ export default class PingCommand extends Command { .setFooter({ text: "amy jr", }); - const meow = Object.keys(songlink.linksByPlatform) - let message = "" - - const nya: ActionRowBuilder[] = []; - let currentRow = new ActionRowBuilder(); - - for (const meowi of meow) { - if (currentRow.components.length >= 5) { - nya.push(currentRow); - currentRow = new ActionRowBuilder(); - } - currentRow.addComponents( - new ButtonBuilder() - .setURL(songlink.linksByPlatform[meowi].url) - .setLabel(kyzaify(meowi)) - .setStyle(ButtonStyle.Link) - ); - } - if (currentRow.components.length > 0) { - nya.push(currentRow); - } + const platforms = Object.keys(songlink.linksByPlatform) + const buttons = platforms.map(platform => + new ButtonBuilder() + .setURL(songlink.linksByPlatform[platform].url) + .setLabel(kyzaify(platform)) + .setStyle(ButtonStyle.Link)); + const chunkedButtons = chunkArray(buttons, 5); + const rows = chunkedButtons.map(rowButtons => + new ActionRowBuilder().addComponents(...rowButtons)); await interaction.followUp({ - components: nya, + components: rows, embeds: [embed] }); } diff --git a/src/commands/nowplaying.ts b/src/commands/nowplaying.ts index f3b82d2..0b406b0 100644 --- a/src/commands/nowplaying.ts +++ b/src/commands/nowplaying.ts @@ -11,7 +11,7 @@ import { } from "discord.js"; import {getSongOnPreferredProvider, kyzaify} from "../helper.ts" -import {Config} from "../config.ts"; +import {type Config} from "../config.ts"; function keepV(url: string): string { const urlObj = new URL(url); diff --git a/src/commands/pat.ts b/src/commands/pat.ts index 5e4a709..57341e5 100644 --- a/src/commands/pat.ts +++ b/src/commands/pat.ts @@ -8,8 +8,8 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { Config } from "../config.ts"; -import sharp, { SharpInput } from "sharp"; +import { type Config } from "../config.ts"; +import sharp, { type SharpInput } from "sharp"; import * as path from 'path'; import { Canvas, loadImage } from "canvas"; import { readdir, readFile } from "fs/promises"; diff --git a/src/commands/ping.ts b/src/commands/ping.ts index a044620..c2f4e7d 100644 --- a/src/commands/ping.ts +++ b/src/commands/ping.ts @@ -5,7 +5,7 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { Config } from "../config.ts"; +import { type Config } from "../config.ts"; export default class PingCommand extends Command { async run(interaction: ChatInputCommandInteraction, config: Config) { diff --git a/src/commands/songinfo.ts b/src/commands/songinfo.ts index f524f54..e23e6ad 100644 --- a/src/commands/songinfo.ts +++ b/src/commands/songinfo.ts @@ -6,7 +6,7 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { Config } from "../config.ts"; +import { type Config } from "../config.ts"; import {getSongOnPreferredProvider, kyzaify} from "../helper.ts"; export default class MusicInfoCommand extends Command { diff --git a/src/commands/src.ts b/src/commands/src.ts index e8978b0..f675c0a 100644 --- a/src/commands/src.ts +++ b/src/commands/src.ts @@ -6,7 +6,7 @@ import { InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { Config } from "../config.ts"; +import { type Config } from "../config.ts"; export default class PingCommand extends Command { async run(interaction: ChatInputCommandInteraction, config: Config) { diff --git a/src/commands/stealemoji.ts b/src/commands/stealemoji.ts index e3778b9..3dd3ec5 100644 --- a/src/commands/stealemoji.ts +++ b/src/commands/stealemoji.ts @@ -5,7 +5,7 @@ import { InteractionContextType, Routes, SlashCommandBuilder } from "discord.js"; -import {Config} from "../config.ts"; +import {type Config} from "../config.ts"; export default class StealEmojiCommand extends Command { diff --git a/src/commands/superfakenitro.ts b/src/commands/superfakenitro.ts index 8aff4df..a7b8419 100644 --- a/src/commands/superfakenitro.ts +++ b/src/commands/superfakenitro.ts @@ -1,13 +1,13 @@ import { Command } from "../command.ts"; import { ApplicationIntegrationType, - AutocompleteFocusedOption, + type AutocompleteFocusedOption, AutocompleteInteraction, ChatInputCommandInteraction, - InteractionContextType, REST, RESTGetAPIApplicationEmojisResult, Routes, + InteractionContextType, SlashCommandBuilder } from "discord.js"; -import { config, Config } from "../config.ts"; +import type { Config } from "../config.ts"; export default class SuperFakeNitroCommand extends Command { async run(interaction: ChatInputCommandInteraction, config: Config) { diff --git a/src/commands/uwuifier.ts b/src/commands/uwuifier.ts index f5a06b7..e113948 100644 --- a/src/commands/uwuifier.ts +++ b/src/commands/uwuifier.ts @@ -2,11 +2,7 @@ import { ApplicationCommandType, ContextMenuCommandBuilder, ContextMenuCommandInteraction, - InteractionContextType, - Message, - Snowflake, - User -} from "discord.js"; + Message} from "discord.js"; import { ContextCommand } from "../command.ts"; export default class Uwuifier extends ContextCommand { diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..eeb886f --- /dev/null +++ b/src/util.ts @@ -0,0 +1,12 @@ +export function chunkArray( + array: T[], + chunkSize: number +): T[][] { + const b: T[][] = [] + array.forEach(element => + b && b[b.length - 1] && b[b.length - 1].length < chunkSize + ? b[b.length - 1].push(element) + : b.push([element]) + ) + return b +} diff --git a/tsconfig.json b/tsconfig.json index 1e21bcf..c771474 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,5 +17,5 @@ "module": "ESNext" } }, - "include": ["src/*"] + "include": ["src/**/*.ts"] }