cleanup music search + actually compile subdirectories with tsc 😭

This commit is contained in:
Linnea Gräf 2025-04-12 12:46:12 +02:00
parent bdec64a050
commit f76984fa7d
No known key found for this signature in database
GPG key ID: AA563E93EB628D91
16 changed files with 63 additions and 55 deletions

1
.gitignore vendored
View file

@ -8,6 +8,7 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
/.pnp
src/**/*.js
.pnp.js
.vscode/*

View file

@ -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 { }

View file

@ -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";

View file

@ -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() {

View file

@ -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<Message> {

View file

@ -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<ButtonBuilder>[] = [];
let currentRow = new ActionRowBuilder<ButtonBuilder>();
for (const meowi of meow) {
if (currentRow.components.length >= 5) {
nya.push(currentRow);
currentRow = new ActionRowBuilder<ButtonBuilder>();
}
currentRow.addComponents(
const platforms = Object.keys(songlink.linksByPlatform)
const buttons = platforms.map(platform =>
new ButtonBuilder()
.setURL(songlink.linksByPlatform[meowi].url)
.setLabel(kyzaify(meowi))
.setStyle(ButtonStyle.Link)
);
}
if (currentRow.components.length > 0) {
nya.push(currentRow);
}
.setURL(songlink.linksByPlatform[platform].url)
.setLabel(kyzaify(platform))
.setStyle(ButtonStyle.Link));
const chunkedButtons = chunkArray(buttons, 5);
const rows = chunkedButtons.map(rowButtons =>
new ActionRowBuilder<ButtonBuilder>().addComponents(...rowButtons));
await interaction.followUp({
components: nya,
components: rows,
embeds: [embed]
});
}

View file

@ -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);

View file

@ -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";

View file

@ -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) {

View file

@ -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 {

View file

@ -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) {

View file

@ -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 {

View file

@ -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) {

View file

@ -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<Message> {

12
src/util.ts Normal file
View file

@ -0,0 +1,12 @@
export function chunkArray<T>(
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
}

View file

@ -17,5 +17,5 @@
"module": "ESNext"
}
},
"include": ["src/*"]
"include": ["src/**/*.ts"]
}