From dcf0853e205942f5ecd6df6fd4df32d22d8e44dd Mon Sep 17 00:00:00 2001 From: kimpure Date: Mon, 9 Feb 2026 18:31:56 +0000 Subject: [PATCH] init commit --- .dockerignore | 7 + .editorconfig | 1 + .gitignore | 9 + .node-version | 1 + Dockerfile | 9 + docker-compose.yml | 19 + package.json | 33 + packages/bot/admin.ts | 7 + packages/bot/command.ts | 41 + packages/bot/commands/getReadChannels.ts | 28 + packages/bot/commands/getStatus.ts | 22 + packages/bot/commands/joinVoiceChannel.ts | 48 + packages/bot/commands/leaveVoiceChannel.ts | 25 + packages/bot/commands/playVoice.ts | 36 + packages/bot/commands/readChannel.ts | 35 + packages/bot/commands/setNya.ts | 19 + packages/bot/commands/setVoice.ts | 30 + packages/bot/commands/unreadChannel.ts | 35 + packages/bot/db.ts | 134 + packages/bot/event.ts | 21 + packages/bot/events/readChannel.ts | 61 + packages/bot/events/useCommand.ts | 11 + packages/bot/index.ts | 66 + packages/bot/music.ts | 81 + packages/bot/tts.ts | 92 + packages/bot/util.ts | 25 + packages/cli/remove_command.ts | 11 + packages/db/generated/prisma/browser.ts | 29 + packages/db/generated/prisma/client.ts | 49 + .../db/generated/prisma/commonInputTypes.ts | 152 ++ packages/db/generated/prisma/enums.ts | 17 + .../db/generated/prisma/internal/class.ts | 200 ++ .../prisma/internal/prismaNamespace.ts | 844 ++++++ .../prisma/internal/prismaNamespaceBrowser.ts | 108 + packages/db/generated/prisma/models.ts | 13 + .../prisma/models/DiscordGuildProfile.ts | 1099 ++++++++ .../prisma/models/DiscordUserProfile.ts | 1156 +++++++++ packages/db/prisma.ts | 17 + packages/env.ts | 9 + packages/index.ts | 20 + packages/tts/index.ts | 95 + packages/tts/papago.ts | 101 + packages/tts/typecast.ts | 176 ++ packages/utils/callingNumberKorean.ts | 31 + packages/utils/fetch.ts | 15 + packages/utils/floatKorean.ts | 16 + packages/utils/integerKorean.ts | 109 + packages/utils/nyaize.ts | 137 + packages/utils/outputHandler.ts | 40 + packages/utils/requireDirectory.ts | 13 + pnpm-lock.yaml | 2305 +++++++++++++++++ prisma.config.ts | 14 + prisma/schema.prisma | 34 + tsconfig.json | 14 + 54 files changed, 7720 insertions(+) create mode 100644 .dockerignore create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .node-version create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 package.json create mode 100644 packages/bot/admin.ts create mode 100644 packages/bot/command.ts create mode 100644 packages/bot/commands/getReadChannels.ts create mode 100644 packages/bot/commands/getStatus.ts create mode 100644 packages/bot/commands/joinVoiceChannel.ts create mode 100644 packages/bot/commands/leaveVoiceChannel.ts create mode 100644 packages/bot/commands/playVoice.ts create mode 100644 packages/bot/commands/readChannel.ts create mode 100644 packages/bot/commands/setNya.ts create mode 100644 packages/bot/commands/setVoice.ts create mode 100644 packages/bot/commands/unreadChannel.ts create mode 100644 packages/bot/db.ts create mode 100644 packages/bot/event.ts create mode 100644 packages/bot/events/readChannel.ts create mode 100644 packages/bot/events/useCommand.ts create mode 100644 packages/bot/index.ts create mode 100644 packages/bot/music.ts create mode 100644 packages/bot/tts.ts create mode 100644 packages/bot/util.ts create mode 100644 packages/cli/remove_command.ts create mode 100644 packages/db/generated/prisma/browser.ts create mode 100644 packages/db/generated/prisma/client.ts create mode 100644 packages/db/generated/prisma/commonInputTypes.ts create mode 100644 packages/db/generated/prisma/enums.ts create mode 100644 packages/db/generated/prisma/internal/class.ts create mode 100644 packages/db/generated/prisma/internal/prismaNamespace.ts create mode 100644 packages/db/generated/prisma/internal/prismaNamespaceBrowser.ts create mode 100644 packages/db/generated/prisma/models.ts create mode 100644 packages/db/generated/prisma/models/DiscordGuildProfile.ts create mode 100644 packages/db/generated/prisma/models/DiscordUserProfile.ts create mode 100644 packages/db/prisma.ts create mode 100644 packages/env.ts create mode 100644 packages/index.ts create mode 100644 packages/tts/index.ts create mode 100644 packages/tts/papago.ts create mode 100644 packages/tts/typecast.ts create mode 100644 packages/utils/callingNumberKorean.ts create mode 100644 packages/utils/fetch.ts create mode 100644 packages/utils/floatKorean.ts create mode 100644 packages/utils/integerKorean.ts create mode 100644 packages/utils/nyaize.ts create mode 100644 packages/utils/outputHandler.ts create mode 100644 packages/utils/requireDirectory.ts create mode 100644 pnpm-lock.yaml create mode 100644 prisma.config.ts create mode 100644 prisma/schema.prisma create mode 100644 tsconfig.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7ac023d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +dist +node_modules +.env +.git +.trash + +packages/db/generated diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4c96fff --- /dev/null +++ b/.editorconfig @@ -0,0 +1 @@ +tab=4 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c07bafc --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +node_modules + +.trash + +dist +packages/generated + +.env +cache diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..e8416a1 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +v24.13.0 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5ef30b1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM node:24-slim + +COPY package*.json ./ +RUN npm install + +COPY . . +RUN npm run init + +CMD [ "node", "dist" ] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9170ef1 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,19 @@ +services: + discord-bot: + build: . + environment: + - DISCORD_TOKEN=MTQ2MDU5NTMyMzczODI2MzU3Mg.Gn2Mn-.dIRJ9MGKRs9mmUkDbDpZ4h_NSjiNVquKk9VPpo + - APPLICATION_ID=1460595323738263572 + - TYPECAST_TOKEN=__pltP9LVqfCqTGAk353JZsEKey49ivoWw799Lp9CM7Ru + - DATABASE_URL=postgresql://yaeju:251205Yaeji@localhost:5432/discord_bot?schema=public + db: + image: postgres:17 + restart: always + environment: + POSTGRES_USER: yaejy + POSTGRES_PASSWORD: 251205Yaeji + POSTGRES_DB: yaejudb + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..93ff9ff --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "scripts": { + "init": "prisma db push && npm run build", + "prismabuild": "prisma format && prisma generate", + "build": "npm run prismabuild && tsc", + "start": "npm run build && node dist" + }, + "dependencies": { + "@discordjs/opus": "^0.10.0", + "@discordjs/voice": "^0.19.0", + "@prisma/adapter-pg": "^7.2.0", + "@prisma/client": "^7.2.0", + "@snazzah/davey": "^0.1.9", + "discord.js": "^14.25.1", + "dotenv": "^17.2.3", + "fastify": "^5.7.1", + "ffprobe-static": "^3.1.0", + "libsodium-wrappers": "^0.8.0", + "node-fetch": "^3.3.2", + "opusscript": "^0.0.8", + "pg": "^8.17.1", + "play-dl": "^1.9.7", + "pnpm": "^10.28.0", + "prism-media": "^1.3.5", + "prisma": "^7.2.0", + "typescript": "^5.9.3" + }, + "devDependencies": { + "@types/ffprobe-static": "^2.0.3", + "@types/node": "25.0.9", + "@types/pg": "^8.16.0" + } +} diff --git a/packages/bot/admin.ts b/packages/bot/admin.ts new file mode 100644 index 0000000..51dab91 --- /dev/null +++ b/packages/bot/admin.ts @@ -0,0 +1,7 @@ +import { setUserCanTypecast } from "./db"; + +export const AdminUsers = [ "858173387775148073", "367946917197381644" ]; + +AdminUsers.forEach(userid => { + setUserCanTypecast(userid, true); +}); diff --git a/packages/bot/command.ts b/packages/bot/command.ts new file mode 100644 index 0000000..dbecee8 --- /dev/null +++ b/packages/bot/command.ts @@ -0,0 +1,41 @@ +import { ChatInputCommandInteraction, SlashCommandBuilder, SlashCommandOptionsOnlyBuilder, SlashCommandSubcommandBuilder } from "discord.js"; +import { join } from "node:path"; +import { requireDirectorySync } from "../utils/requireDirectory"; +import { AdminUsers } from "./admin"; + +export type DiscordCommandData = SlashCommandBuilder | SlashCommandOptionsOnlyBuilder | SlashCommandSubcommandBuilder +export type DiscordCommandExecute = (interaction: ChatInputCommandInteraction) => Promise + +export interface DiscordCommand { + data: DiscordCommandData + execute: DiscordCommandExecute +} + +export function defineCommand( + data: DiscordCommandData, + execute: DiscordCommandExecute, + isAdminCommand=false, +): DiscordCommand { + if (isAdminCommand) { + return { + data: data, + execute: async (interaction: ChatInputCommandInteraction): Promise => { + if (AdminUsers.includes(interaction.user.id)) { + execute(interaction); + } else { + interaction.reply("당신은 어드민이 아닙니다"); + } + } + } + } + return { + data: data, + execute: execute, + } +} + +export const commandDirectory = join(__dirname, "commands"); +export const commandMap = requireDirectorySync(commandDirectory); +export const commandExecuteNameHashMap: { + [key: string]: DiscordCommandExecute +} = Object.fromEntries(commandMap.map(command => [command.data.name, command.execute])); diff --git a/packages/bot/commands/getReadChannels.ts b/packages/bot/commands/getReadChannels.ts new file mode 100644 index 0000000..a7f8fba --- /dev/null +++ b/packages/bot/commands/getReadChannels.ts @@ -0,0 +1,28 @@ +import { ChatInputCommandInteraction, MessageFlags, SlashCommandBuilder } from "discord.js"; +import { defineCommand } from "../command"; +import { getGuildProfile } from "../db"; + +export default defineCommand( + new SlashCommandBuilder() + .setName("읽는채널") + .setDescription("예주가 읽어주는 채널들을 말해줘요"), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + const guildId = interaction.guildId; + + if (guildId == null) + return await interaction.editReply("알수없는 서버에요!"); + + try { + const guildProfile = await getGuildProfile(guildId); + const readChannel = guildProfile.readChannel; + + await interaction.editReply(readChannel.map(channel => `<#${channel}>`).join("\n") || "아무 채널도 읽지 않아요!"); + } catch { + await interaction.editReply("서버 프로필을 가져오는데 문제가 생겼어요"); + } + } +) \ No newline at end of file diff --git a/packages/bot/commands/getStatus.ts b/packages/bot/commands/getStatus.ts new file mode 100644 index 0000000..047d6b4 --- /dev/null +++ b/packages/bot/commands/getStatus.ts @@ -0,0 +1,22 @@ +import { AttachmentBuilder, ChatInputCommandInteraction, MessageFlags, SlashCommandBuilder } from "discord.js"; +import { defineCommand } from "../command"; +import { OutputHandler } from "../../utils/outputHandler"; + +export default defineCommand( + new SlashCommandBuilder() + .setName("상태") + .setDescription("예주의 상태를 확인해요"), + async (interaction: ChatInputCommandInteraction): Promise => { + if (interaction.guild == null) + return interaction.reply("올바르지 않은 서버에요"); + + const buffer = Buffer.from(await OutputHandler.getErrorLog(), 'utf-8'); + const attachment = new AttachmentBuilder(buffer, { name: 'result.txt' }); + + await interaction.reply({ + content: "제 상태에요", + files: [attachment] + }); + }, + true +) \ No newline at end of file diff --git a/packages/bot/commands/joinVoiceChannel.ts b/packages/bot/commands/joinVoiceChannel.ts new file mode 100644 index 0000000..089d467 --- /dev/null +++ b/packages/bot/commands/joinVoiceChannel.ts @@ -0,0 +1,48 @@ +import { Channel, ChannelType, ChatInputCommandInteraction, GuildMember, MessageFlags, SlashCommandBuilder } from "discord.js"; +import { defineCommand } from "../command"; +import { joinVoiceChannel } from "@discordjs/voice"; + +export default defineCommand( + new SlashCommandBuilder() + .setName("등장") + .setDescription("예주가 등장해요") + .addChannelOption(option => + option + .setName("channel") + .setDescription("예주가 등장할 채널이에요") + .addChannelTypes(ChannelType.GuildVoice) + ), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + const member = interaction.member as GuildMember | null; + if (member == null) + return; + + if (interaction.guild == null) + return interaction.reply({ + content: "올바르지 않은 서버에요", + ephemeral: true, + }); + + const channel = interaction.options.getChannel("channel") as Channel || member.voice.channel; + + if (channel == null) + return interaction.reply({ + content: "통화방에 들어가거나 채널을 지정해주세요!", + ephemeral: true, + }); + + joinVoiceChannel({ + channelId: channel.id, + guildId: interaction.guild.id, + adapterCreator: interaction.guild.voiceAdapterCreator, + selfDeaf: false, + selfMute: false, + }); + + await interaction.editReply("등장했어요!"); + } +) \ No newline at end of file diff --git a/packages/bot/commands/leaveVoiceChannel.ts b/packages/bot/commands/leaveVoiceChannel.ts new file mode 100644 index 0000000..9ca6a44 --- /dev/null +++ b/packages/bot/commands/leaveVoiceChannel.ts @@ -0,0 +1,25 @@ +import { ChatInputCommandInteraction, MessageFlags, SlashCommandBuilder } from "discord.js"; +import { defineCommand, DiscordCommand } from "../command"; +import { getVoiceConnection } from "@discordjs/voice"; + +export default defineCommand( + new SlashCommandBuilder() + .setName("퇴장") + .setDescription("예주가 퇴장해요"), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + if (interaction.guild == null) + return interaction.editReply("올바르지 않은 서버에요"); + + const connection = getVoiceConnection(interaction.guild.id); + if (!connection) + return interaction.editReply("예주는 통화방에 존제하지 않아요"); + + connection.disconnect(); + + await interaction.editReply("퇴장했어요!"); + } +) \ No newline at end of file diff --git a/packages/bot/commands/playVoice.ts b/packages/bot/commands/playVoice.ts new file mode 100644 index 0000000..42361bc --- /dev/null +++ b/packages/bot/commands/playVoice.ts @@ -0,0 +1,36 @@ +import { ChatInputCommandInteraction, MessageFlags, SlashCommandSubcommandBuilder } from "discord.js"; +import { defineCommand } from "../command"; +import { playVoice } from "../tts"; +import { getUserProfile } from "../db"; + +export default defineCommand( + new SlashCommandSubcommandBuilder() + .setName("말") + .setDescription("구구가가") + .addStringOption(option => + option + .setName("content") + .setDescription("예주가 말해준데요") + .setRequired(true) + ), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + if (interaction.guild == null) + return await interaction.editReply("올바르지 않은 서버에요"); + + try { + await playVoice( + interaction.guild, + await getUserProfile(interaction.user.id), + interaction.options.getString("content") as string + ); + + await interaction.editReply("말했어요!"); + } catch { + await interaction.editReply("오늘따라 말이 꼬이네요 ㅜ.ㅜ"); + } + } +) \ No newline at end of file diff --git a/packages/bot/commands/readChannel.ts b/packages/bot/commands/readChannel.ts new file mode 100644 index 0000000..1cf2e6d --- /dev/null +++ b/packages/bot/commands/readChannel.ts @@ -0,0 +1,35 @@ +import { Channel, ChatInputCommandInteraction, MessageFlags, SlashCommandSubcommandBuilder } from "discord.js"; +import { defineCommand, DiscordCommand } from "../command"; +import { insertGuildReadChannel } from "../db"; + +export default defineCommand( + new SlashCommandSubcommandBuilder() + .setName("읽어") + .setDescription("예주가 해당 채널을 읽어줘요") + .addChannelOption(option => + option + .setName("channel") + .setDescription("예주가 읽을 채널이에요") + .setRequired(true) + ), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + const channel = interaction.options.getChannel("channel") as Channel; + const guildId = interaction.guildId; + + if (guildId == null) + return await interaction.editReply("알수없는 서버에요!"); + + try { + await insertGuildReadChannel(guildId, channel.id); + } catch { + return await interaction.editReply("읽는대 너무 어려워요.."); + } + + await interaction.editReply("예주가 이제 이 채널을 읽어요!"); + }, + true +) \ No newline at end of file diff --git a/packages/bot/commands/setNya.ts b/packages/bot/commands/setNya.ts new file mode 100644 index 0000000..c7d8bc1 --- /dev/null +++ b/packages/bot/commands/setNya.ts @@ -0,0 +1,19 @@ +import { ChatInputCommandInteraction, GuildMember, MessageFlags, SlashCommandBuilder } from "discord.js"; +import { defineCommand } from "../command"; +import { getUserProfile, setUserNya } from "../db"; + +export default defineCommand( + new SlashCommandBuilder() + .setName("냥") + .setDescription("???"), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + const profile = await getUserProfile(interaction.user.id); + setUserNya(interaction.user.id, !profile.nya); + + await interaction.editReply(profile.nya ? "냐앙..." : "냐앙!!"); + } +) \ No newline at end of file diff --git a/packages/bot/commands/setVoice.ts b/packages/bot/commands/setVoice.ts new file mode 100644 index 0000000..bd56751 --- /dev/null +++ b/packages/bot/commands/setVoice.ts @@ -0,0 +1,30 @@ +import { ChatInputCommandInteraction, MessageFlags, SlashCommandSubcommandBuilder } from "discord.js"; +import { defineCommand } from "../command"; +import { Voice } from "../../db/generated/prisma/enums"; +import { setUserVoice } from "../db"; + +export default defineCommand( + new SlashCommandSubcommandBuilder() + .setName("목소리") + .setDescription("예주의 목소리를 설정해요") + .addStringOption(option => + option + .setName("voice") + .setDescription("사용할수 있는 목소리들이에요") + .setRequired(true) + .addChoices( + { name: "TypeCast", value: "TypeCast" }, + { name: "Papago", value: "Papago" } + ) + ), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + const voice = interaction.options.getString("voice") as Voice; + setUserVoice(interaction.user.id, voice); + + await interaction.editReply("예주의 목소리를 변경했어요!"); + } +) \ No newline at end of file diff --git a/packages/bot/commands/unreadChannel.ts b/packages/bot/commands/unreadChannel.ts new file mode 100644 index 0000000..b1ad45a --- /dev/null +++ b/packages/bot/commands/unreadChannel.ts @@ -0,0 +1,35 @@ +import { Channel, ChatInputCommandInteraction, MessageFlags, SlashCommandSubcommandBuilder } from "discord.js"; +import { defineCommand, DiscordCommand } from "../command"; +import { insertGuildReadChannel, removeGuildReadChannel } from "../db"; + +export default defineCommand( + new SlashCommandSubcommandBuilder() + .setName("읽지마") + .setDescription("예주가 해당 채널을 더이상 읽지 않아요") + .addChannelOption(option => + option + .setName("channel") + .setDescription("예주가 더이상 읽지 않을 채널이에요") + .setRequired(true) + ), + async (interaction: ChatInputCommandInteraction): Promise => { + await interaction.deferReply({ + flags: [MessageFlags.Ephemeral] + }); + + const channel = interaction.options.getChannel("channel") as Channel; + const guildId = interaction.guildId; + + if (guildId == null) + return await interaction.editReply("알수없는 서버에요!"); + + try { + await removeGuildReadChannel(guildId, channel.id); + } catch { + return await interaction.editReply("읽지 않는것을 실패했어요 ?ㄴ"); + } + + await interaction.editReply("예주가 이제 이 채널을 읽지않아요!"); + }, + true +) \ No newline at end of file diff --git a/packages/bot/db.ts b/packages/bot/db.ts new file mode 100644 index 0000000..23474ab --- /dev/null +++ b/packages/bot/db.ts @@ -0,0 +1,134 @@ +import { prisma } from "../db/prisma"; +import { DiscordUserProfile, DiscordGuildProfile, Voice } from "../db/generated/prisma/client"; + +export function getUserProfile(userId: string): Promise { + return prisma.discordUserProfile.upsert({ + where: { + userId: userId + }, + update: {}, + create: { + userId: userId, + }, + }); +} + +export async function setUserProfile(userId: string, profile: DiscordUserProfile): Promise { + await prisma.discordUserProfile.upsert({ + where: { + userId: userId + }, + update: { + voice: profile.voice, + nya: profile.nya + }, + create: { + userId: userId, + } + }); +} + +export async function setUserNya(userId: string, nya: boolean): Promise { + await prisma.discordUserProfile.upsert({ + where: { + userId: userId + }, + update: { + nya: nya + }, + create: { + userId: userId, + } + }); +} + +export async function setUserVoice(userId: string, voice: Voice): Promise { + await prisma.discordUserProfile.upsert({ + where: { + userId: userId + }, + update: { + voice: voice + }, + create: { + userId: userId, + voice: voice + } + }); +} + +export async function setUserCanTypecast(userId: string, canTypecast: boolean): Promise { + await prisma.discordUserProfile.upsert({ + where: { + userId: userId + }, + update: { + canTypecast: canTypecast + }, + create: { + userId: userId, + } + }); +} + +export function getGuildProfile(guildId: string): Promise { + return prisma.discordGuildProfile.upsert({ + where: { guildId: guildId }, + update: {}, + create: { + guildId: guildId, + }, + }); +} + +export async function hasGuildReadChannel(guildId: string, channelId: string): Promise { + return ( + await prisma.discordGuildProfile.findFirst({ + where: { + guildId: guildId, + readChannel: { has: channelId } + } + }) + ) != null; +} + +export async function removeGuildReadChannel(guildId: string, channelId: string): Promise { + const guildProfile = await prisma.discordGuildProfile.findUnique({ + where: { + guildId: guildId + }, + }); + + if (guildProfile) { + await prisma.discordGuildProfile.update({ + where: { + guildId: guildId + }, + data: { + readChannel: guildProfile.readChannel.filter(channel => channel != channelId), + }, + }); + } +} + +export async function insertGuildReadChannel(guildId: string, channelId: string): Promise { + await prisma.discordGuildProfile.upsert({ + where: { + guildId: guildId, + NOT: { + readChannel: { + has: channelId, + }, + } + }, + update: { + readChannel: { + push: channelId, + }, + }, + create: { + guildId: guildId, + readChannel: [channelId], + }, + }); +} diff --git a/packages/bot/event.ts b/packages/bot/event.ts new file mode 100644 index 0000000..31adae1 --- /dev/null +++ b/packages/bot/event.ts @@ -0,0 +1,21 @@ +import { ClientEvents } from "discord.js"; +import { join } from "node:path"; +import { requireDirectorySync } from "../utils/requireDirectory"; + +export interface DiscordEvent { + event: Event + callback: (...args: ClientEvents[Event]) => Promise +} + +export function defineEvent( + event: Event, + callback: (...args: ClientEvents[Event]) => Promise +): DiscordEvent { + return { + event: event, + callback: callback, + } +} + +export const eventDirectory = join(__dirname, "events"); +export const eventMap = requireDirectorySync>(eventDirectory); diff --git a/packages/bot/events/readChannel.ts b/packages/bot/events/readChannel.ts new file mode 100644 index 0000000..3cd9951 --- /dev/null +++ b/packages/bot/events/readChannel.ts @@ -0,0 +1,61 @@ +import { getOrCreateVoiceConnection } from "../util"; +import { getUserProfile, hasGuildReadChannel } from "../db"; +import { defineEvent } from "../event"; +import { playVoice } from "../tts"; + +export default defineEvent("messageCreate", async (message) => { + if (message.author.bot) + return; + + const guild = message.guild; + if (guild == null) + return; + + const hasChannel = await hasGuildReadChannel(guild.id, message.channelId); + if (!hasChannel) + return; + + const profile = await getUserProfile(message.author.id); + + let content = message.cleanContent; + let voice: string | null = null + if (content.startsWith("$t ")) { + voice = "TypeCast" + } else if (content.startsWith("$p ")) { + voice = "Papago" + } + + if (voice) { + content = content.replace(/^\$[^ ]+ +/, "") + } else { + voice = profile.voice; + } + + try { + if (!await getOrCreateVoiceConnection(guild)) + return; + + if (!guild.members.me?.voice.channel) + return; + + if (message.content === "") { + return await playVoice( + guild, + profile, + content = + message.attachments.size > 0 + ? `${message.attachments.size} 개의 첨부파일` + : "알수없는 메시지" + ); + } else { + await playVoice( + guild, + profile, + content = content + ); + } + + } catch(err) { + message.reply("말이 꼬이네요 ㅜ.ㅜ"); + } +}) \ No newline at end of file diff --git a/packages/bot/events/useCommand.ts b/packages/bot/events/useCommand.ts new file mode 100644 index 0000000..b8c942d --- /dev/null +++ b/packages/bot/events/useCommand.ts @@ -0,0 +1,11 @@ +import { commandExecuteNameHashMap, DiscordCommand, DiscordCommandExecute } from "../command"; +import { defineEvent } from "../event"; + +export default defineEvent("interactionCreate", async (interaction) => { + if (!interaction.isChatInputCommand()) + return; + + if (commandExecuteNameHashMap[interaction.commandName]) { + await commandExecuteNameHashMap[interaction.commandName](interaction); + } +}) \ No newline at end of file diff --git a/packages/bot/index.ts b/packages/bot/index.ts new file mode 100644 index 0000000..2213537 --- /dev/null +++ b/packages/bot/index.ts @@ -0,0 +1,66 @@ +import { Client, Events, GatewayIntentBits, REST, Routes } from "discord.js"; +import { commandMap, DiscordCommand } from "./command"; +import { eventMap } from "./event"; +import { OutputHandler } from "../utils/outputHandler"; +import { APPLICATION_ID, GUILD_ID } from "../env"; + +export class DiscordBot { + rest: REST; + client: Client; + + constructor(token: string) { + this.client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.GuildVoiceStates, + GatewayIntentBits.MessageContent, + ], + }); + this.rest = new REST({ version: "10" }).setToken(token); + } + + private async putCommands(commands: DiscordCommand[]): Promise { + if (!this.client.isReady()) + throw new Error("Client is not ready"); + + await this.rest.put( + Routes.applicationGuildCommands(this.client.application.id, GUILD_ID), + { + body: commands.map((command) => command.data.toJSON()), + } + ); + } + + public async registerCommands(): Promise { + try { + if (!this.client.isReady()) { + await this.client.once(Events.ClientReady, () => this.putCommands(commandMap)); + } else { + await this.putCommands(commandMap); + } + } catch(err) { + OutputHandler.errorLog("[Command Register Error]", err); + } + } + + public async deleteCommand(commandId: string): Promise { + if (!this.client.isReady()) + throw new Error("Client is not ready"); + + await this.rest.delete( + Routes.applicationCommand(this.client.application.id, commandId) + ); + } + + public registerEvents() { + try { + for (let index = 0; index < eventMap.length; index++) { + const event = eventMap[index]; + this.client.on(event.event, event.callback); + } + } catch(err) { + OutputHandler.errorLog("[Event Register Error]", err); + } + } +} diff --git a/packages/bot/music.ts b/packages/bot/music.ts new file mode 100644 index 0000000..9cf103a --- /dev/null +++ b/packages/bot/music.ts @@ -0,0 +1,81 @@ +import { AudioPlayerStatus, AudioResource, createAudioPlayer, createAudioResource, VoiceConnection } from "@discordjs/voice"; +import { stream as createStream } from "play-dl"; +import { Guild } from "discord.js"; +import { getOrCreateVoiceConnection } from "./util"; +import { OutputHandler } from "../utils/outputHandler"; +import play from "play-dl"; + +namespace InitPlayDl { + let initialized = false; + export async function init() { + if (initialized) + return; + + await play.getFreeClientID(); + initialized = true; + } +} + +class MusicQueue { + private connection: VoiceConnection; + private list: AudioResource[]; + constructor(connection: VoiceConnection) { + this.connection = connection; + this.list = []; + } + public static fromConnection(connection: VoiceConnection): MusicQueue { + return (connection as any).queue ??= new MusicQueue(connection); + } + private play() { + if (!this.list[0]) return; + const player = createAudioPlayer(); + this.connection.subscribe(player); + player.once(AudioPlayerStatus.Idle, this.next.bind(this)); + player.play(this.list[0]); + } + public enqueue(resource: AudioResource) { + this.list.push(resource); + if (this.list.length == 1) { + this.play(); + return; + } + } + public next() { + this.list.shift(); + this.play(); + } +} + +// TODO: 토큰 설정하고 플레이돼게 만들기 +export async function playMusic(guild: Guild, url: string) { + try { + const connection = await getOrCreateVoiceConnection(guild); + if (!connection) + throw new Error("Yaeju is not joined VoiceChat"); + + await InitPlayDl.init(); + + const validation = play.yt_validate(url); + + if (validation !== "video" && validation !== "playlist") + throw new Error("Invalid YouTube URL: " + validation); + + const stream = await play.stream(url); + MusicQueue.fromConnection(connection).enqueue( + createAudioResource(stream.stream, { + inputType: stream.type + }) + ); + } catch(err) { + OutputHandler.errorLog("[PlayMusic Error]", err); + throw err; + } +} + +export async function skipMusic(guild: Guild) { + const connection = await getOrCreateVoiceConnection(guild); + if (!connection) + throw new Error("Yaeju is not joined VoiceChat"); + + MusicQueue.fromConnection(connection).next(); +} diff --git a/packages/bot/tts.ts b/packages/bot/tts.ts new file mode 100644 index 0000000..8471c7d --- /dev/null +++ b/packages/bot/tts.ts @@ -0,0 +1,92 @@ +import { AudioPlayerStatus, AudioResource, createAudioPlayer, VoiceConnection } from "@discordjs/voice"; +import { Voice } from "../db/generated/prisma/enums"; +import TTSTypecastModel from "../tts/typecast"; +import TTSPapagoModel from "../tts/papago"; +import { Guild } from "discord.js"; +import { getOrCreateVoiceConnection } from "./util"; +import TTSModelBase from "../tts"; +import { DiscordUserProfile } from "../db/generated/prisma/client"; +import { nyaize } from "../utils/nyaize"; +import { OutputHandler } from "../utils/outputHandler"; + +export async function createVoiceBuffer(voice: Voice, text: string): Promise { + if (voice == "TypeCast") { + const content = TTSTypecastModel.instance.ttsify(text); + + if (!content.length) + throw new Error("Empty content"); + + return await TTSTypecastModel.instance.getMemcachedVoice( + TTSTypecastModel.instance.createRequestId(content) + ); + } else if (voice == "Papago") { + const content = TTSTypecastModel.instance.ttsify(text); + if (!content.length) + throw new Error("Empty content"); + + return await TTSPapagoModel.instance.getMemcachedVoice( + TTSPapagoModel.instance.createRequestId(content) + ); + } else { + throw new Error(`Unknown voice type: ${voice}`); + } +} + +class VoiceQueue { + private connection: VoiceConnection; + private list: AudioResource[]; + constructor(connection: VoiceConnection) { + this.connection = connection; + this.list = []; + } + public static fromConnection(connection: VoiceConnection): VoiceQueue { + return (connection as any).queue ??= new VoiceQueue(connection); + } + private play() { + if (!this.list[0]) return; + const player = createAudioPlayer(); + this.connection.subscribe(player); + player.once(AudioPlayerStatus.Idle, this.next.bind(this)); + player.play(this.list[0]); + } + public enqueue(resource: AudioResource) { + this.list.push(resource); + if (this.list.length == 1) { + this.play(); + return; + } + } + public next() { + this.list.shift(); + this.play(); + } +} + +export async function playVoice(guild: Guild, profile: DiscordUserProfile, text: string) { + if (profile.nya) + text = nyaize(text); + + try { + let connection = await getOrCreateVoiceConnection(guild); + if (!connection) + throw new Error("Yaeju is not joined VoiceChat"); + + let voiceBuffer: Buffer; + if (profile.voice == "TypeCast") { + if (profile.canTypecast) { + voiceBuffer = await createVoiceBuffer(profile.voice, text); + } else { + throw new Error(`the user ${profile.userId} is not admin`); + } + } else { + voiceBuffer = await createVoiceBuffer(profile.voice, text); + } + + VoiceQueue.fromConnection(connection).enqueue( + TTSModelBase.bufferToAudioResource(voiceBuffer) + ); + } catch(err) { + OutputHandler.errorLog("[PlayVoice Error]", err); + throw new Error(err as any); + } +} diff --git a/packages/bot/util.ts b/packages/bot/util.ts new file mode 100644 index 0000000..970e46d --- /dev/null +++ b/packages/bot/util.ts @@ -0,0 +1,25 @@ +import { getVoiceConnection as defaultGetVoiceConnection, EndBehaviorType, joinVoiceChannel, VoiceConnection } from "@discordjs/voice"; +import { Guild } from "discord.js"; + +export async function getOrCreateVoiceConnection(guild: Guild): Promise { + let connection = defaultGetVoiceConnection(guild.id); + + if (!connection) { + if (!guild.members.me?.voice.channel) + return; + + const channel = guild.members.me.voice.channel; + + connection = joinVoiceChannel({ + channelId: channel.id, + guildId: channel.guild.id, + adapterCreator: channel.guild.voiceAdapterCreator, + selfDeaf: false, + selfMute: false, + }); + + await new Promise((resolve) => setTimeout(resolve, 2000)); + } + + return connection; +} diff --git a/packages/cli/remove_command.ts b/packages/cli/remove_command.ts new file mode 100644 index 0000000..36b5f9b --- /dev/null +++ b/packages/cli/remove_command.ts @@ -0,0 +1,11 @@ +import { bot } from ".."; + +export default function remove() { + bot.deleteCommand("1463496119135899671"); + bot.deleteCommand("1463496119135899675"); + bot.deleteCommand("1463496119135899676"); + bot.deleteCommand("1463496119135899677"); + bot.deleteCommand("1463496119286759606"); + bot.deleteCommand("1464993345427476648"); + bot.deleteCommand("1464993345427476649"); +} \ No newline at end of file diff --git a/packages/db/generated/prisma/browser.ts b/packages/db/generated/prisma/browser.ts new file mode 100644 index 0000000..8448f78 --- /dev/null +++ b/packages/db/generated/prisma/browser.ts @@ -0,0 +1,29 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file should be your main import to use Prisma-related types and utilities in a browser. + * Use it to get access to models, enums, and input types. + * + * This file does not contain a `PrismaClient` class, nor several other helpers that are intended as server-side only. + * See `client.ts` for the standard, server-side entry point. + * + * 🟢 You can import this file directly. + */ + +import * as Prisma from './internal/prismaNamespaceBrowser' +export { Prisma } +export * as $Enums from './enums' +export * from './enums'; +/** + * Model DiscordUserProfile + * + */ +export type DiscordUserProfile = Prisma.DiscordUserProfileModel +/** + * Model DiscordGuildProfile + * + */ +export type DiscordGuildProfile = Prisma.DiscordGuildProfileModel diff --git a/packages/db/generated/prisma/client.ts b/packages/db/generated/prisma/client.ts new file mode 100644 index 0000000..a585700 --- /dev/null +++ b/packages/db/generated/prisma/client.ts @@ -0,0 +1,49 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file should be your main import to use Prisma. Through it you get access to all the models, enums, and input types. + * If you're looking for something you can import in the client-side of your application, please refer to the `browser.ts` file instead. + * + * 🟢 You can import this file directly. + */ + +import * as process from 'node:process' +import * as path from 'node:path' + +import * as runtime from "@prisma/client/runtime/client" +import * as $Enums from "./enums" +import * as $Class from "./internal/class" +import * as Prisma from "./internal/prismaNamespace" + +export * as $Enums from './enums' +export * from "./enums" +/** + * ## Prisma Client + * + * Type-safe database client for TypeScript + * @example + * ``` + * const prisma = new PrismaClient() + * // Fetch zero or more DiscordUserProfiles + * const discordUserProfiles = await prisma.discordUserProfile.findMany() + * ``` + * + * Read more in our [docs](https://pris.ly/d/client). + */ +export const PrismaClient = $Class.getPrismaClientClass() +export type PrismaClient = $Class.PrismaClient +export { Prisma } + +/** + * Model DiscordUserProfile + * + */ +export type DiscordUserProfile = Prisma.DiscordUserProfileModel +/** + * Model DiscordGuildProfile + * + */ +export type DiscordGuildProfile = Prisma.DiscordGuildProfileModel diff --git a/packages/db/generated/prisma/commonInputTypes.ts b/packages/db/generated/prisma/commonInputTypes.ts new file mode 100644 index 0000000..91b8604 --- /dev/null +++ b/packages/db/generated/prisma/commonInputTypes.ts @@ -0,0 +1,152 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file exports various common sort, input & filter types that are not directly linked to a particular model. + * + * 🟢 You can import this file directly. + */ + +import type * as runtime from "@prisma/client/runtime/client" +import * as $Enums from "./enums" +import type * as Prisma from "./internal/prismaNamespace" + + +export type StringFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + contains?: string | Prisma.StringFieldRefInput<$PrismaModel> + startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + mode?: Prisma.QueryMode + not?: Prisma.NestedStringFilter<$PrismaModel> | string +} + +export type EnumVoiceFilter<$PrismaModel = never> = { + equals?: $Enums.Voice | Prisma.EnumVoiceFieldRefInput<$PrismaModel> + in?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + notIn?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumVoiceFilter<$PrismaModel> | $Enums.Voice +} + +export type BoolFilter<$PrismaModel = never> = { + equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> + not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean +} + +export type StringWithAggregatesFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + contains?: string | Prisma.StringFieldRefInput<$PrismaModel> + startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + mode?: Prisma.QueryMode + not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedStringFilter<$PrismaModel> + _max?: Prisma.NestedStringFilter<$PrismaModel> +} + +export type EnumVoiceWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.Voice | Prisma.EnumVoiceFieldRefInput<$PrismaModel> + in?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + notIn?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumVoiceWithAggregatesFilter<$PrismaModel> | $Enums.Voice + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumVoiceFilter<$PrismaModel> + _max?: Prisma.NestedEnumVoiceFilter<$PrismaModel> +} + +export type BoolWithAggregatesFilter<$PrismaModel = never> = { + equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> + not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedBoolFilter<$PrismaModel> + _max?: Prisma.NestedBoolFilter<$PrismaModel> +} + +export type NestedStringFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + contains?: string | Prisma.StringFieldRefInput<$PrismaModel> + startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + not?: Prisma.NestedStringFilter<$PrismaModel> | string +} + +export type NestedEnumVoiceFilter<$PrismaModel = never> = { + equals?: $Enums.Voice | Prisma.EnumVoiceFieldRefInput<$PrismaModel> + in?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + notIn?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumVoiceFilter<$PrismaModel> | $Enums.Voice +} + +export type NestedBoolFilter<$PrismaModel = never> = { + equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> + not?: Prisma.NestedBoolFilter<$PrismaModel> | boolean +} + +export type NestedStringWithAggregatesFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + contains?: string | Prisma.StringFieldRefInput<$PrismaModel> + startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel> + not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedStringFilter<$PrismaModel> + _max?: Prisma.NestedStringFilter<$PrismaModel> +} + +export type NestedIntFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntFilter<$PrismaModel> | number +} + +export type NestedEnumVoiceWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.Voice | Prisma.EnumVoiceFieldRefInput<$PrismaModel> + in?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + notIn?: $Enums.Voice[] | Prisma.ListEnumVoiceFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumVoiceWithAggregatesFilter<$PrismaModel> | $Enums.Voice + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumVoiceFilter<$PrismaModel> + _max?: Prisma.NestedEnumVoiceFilter<$PrismaModel> +} + +export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = { + equals?: boolean | Prisma.BooleanFieldRefInput<$PrismaModel> + not?: Prisma.NestedBoolWithAggregatesFilter<$PrismaModel> | boolean + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedBoolFilter<$PrismaModel> + _max?: Prisma.NestedBoolFilter<$PrismaModel> +} + + diff --git a/packages/db/generated/prisma/enums.ts b/packages/db/generated/prisma/enums.ts new file mode 100644 index 0000000..73480e1 --- /dev/null +++ b/packages/db/generated/prisma/enums.ts @@ -0,0 +1,17 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* +* This file exports all enum related types from the schema. +* +* 🟢 You can import this file directly. +*/ + +export const Voice = { + TypeCast: 'TypeCast', + Papago: 'Papago' +} as const + +export type Voice = (typeof Voice)[keyof typeof Voice] diff --git a/packages/db/generated/prisma/internal/class.ts b/packages/db/generated/prisma/internal/class.ts new file mode 100644 index 0000000..05d333f --- /dev/null +++ b/packages/db/generated/prisma/internal/class.ts @@ -0,0 +1,200 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * WARNING: This is an internal file that is subject to change! + * + * 🛑 Under no circumstances should you import this file directly! 🛑 + * + * Please import the `PrismaClient` class from the `client.ts` file instead. + */ + +import * as runtime from "@prisma/client/runtime/client" +import type * as Prisma from "./prismaNamespace" + + +const config: runtime.GetPrismaClientConfig = { + "previewFeatures": [], + "clientVersion": "7.2.0", + "engineVersion": "0c8ef2ce45c83248ab3df073180d5eda9e8be7a3", + "activeProvider": "postgresql", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\n// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?\n// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init\n\ngenerator client {\n provider = \"prisma-client\"\n specifying = [\"prismaSchemaFolder\"]\n output = \"../packages/db/generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nenum Voice {\n TypeCast\n Papago\n}\n\nmodel DiscordUserProfile {\n id String @id @default(cuid())\n userId String @unique\n voice Voice @default(Papago)\n nya Boolean @default(false)\n canTypecast Boolean @default(false)\n}\n\nmodel DiscordGuildProfile {\n id String @id @default(cuid())\n guildId String @unique\n readChannel String[] @default([])\n}\n", + "runtimeDataModel": { + "models": {}, + "enums": {}, + "types": {} + } +} + +config.runtimeDataModel = JSON.parse("{\"models\":{\"DiscordUserProfile\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"voice\",\"kind\":\"enum\",\"type\":\"Voice\"},{\"name\":\"nya\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"canTypecast\",\"kind\":\"scalar\",\"type\":\"Boolean\"}],\"dbName\":null},\"DiscordGuildProfile\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"guildId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"readChannel\",\"kind\":\"scalar\",\"type\":\"String\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") + +async function decodeBase64AsWasm(wasmBase64: string): Promise { + const { Buffer } = await import('node:buffer') + const wasmArray = Buffer.from(wasmBase64, 'base64') + return new WebAssembly.Module(wasmArray) +} + +config.compilerWasm = { + getRuntime: async () => await import("@prisma/client/runtime/query_compiler_bg.postgresql.js"), + + getQueryCompilerWasmModule: async () => { + const { wasm } = await import("@prisma/client/runtime/query_compiler_bg.postgresql.wasm-base64.js") + return await decodeBase64AsWasm(wasm) + } +} + + + +export type LogOptions = + 'log' extends keyof ClientOptions ? ClientOptions['log'] extends Array ? Prisma.GetEvents : never : never + +export interface PrismaClientConstructor { + /** + * ## Prisma Client + * + * Type-safe database client for TypeScript + * @example + * ``` + * const prisma = new PrismaClient() + * // Fetch zero or more DiscordUserProfiles + * const discordUserProfiles = await prisma.discordUserProfile.findMany() + * ``` + * + * Read more in our [docs](https://pris.ly/d/client). + */ + + new < + Options extends Prisma.PrismaClientOptions = Prisma.PrismaClientOptions, + LogOpts extends LogOptions = LogOptions, + OmitOpts extends Prisma.PrismaClientOptions['omit'] = Options extends { omit: infer U } ? U : Prisma.PrismaClientOptions['omit'], + ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs + >(options: Prisma.Subset ): PrismaClient +} + +/** + * ## Prisma Client + * + * Type-safe database client for TypeScript + * @example + * ``` + * const prisma = new PrismaClient() + * // Fetch zero or more DiscordUserProfiles + * const discordUserProfiles = await prisma.discordUserProfile.findMany() + * ``` + * + * Read more in our [docs](https://pris.ly/d/client). + */ + +export interface PrismaClient< + in LogOpts extends Prisma.LogLevel = never, + in out OmitOpts extends Prisma.PrismaClientOptions['omit'] = undefined, + in out ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs +> { + [K: symbol]: { types: Prisma.TypeMap['other'] } + + $on(eventType: V, callback: (event: V extends 'query' ? Prisma.QueryEvent : Prisma.LogEvent) => void): PrismaClient; + + /** + * Connect with the database + */ + $connect(): runtime.Types.Utils.JsPromise; + + /** + * Disconnect from the database + */ + $disconnect(): runtime.Types.Utils.JsPromise; + +/** + * Executes a prepared raw query and returns the number of affected rows. + * @example + * ``` + * const result = await prisma.$executeRaw`UPDATE User SET cool = ${true} WHERE email = ${'user@email.com'};` + * ``` + * + * Read more in our [docs](https://pris.ly/d/raw-queries). + */ + $executeRaw(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise; + + /** + * Executes a raw query and returns the number of affected rows. + * Susceptible to SQL injections, see documentation. + * @example + * ``` + * const result = await prisma.$executeRawUnsafe('UPDATE User SET cool = $1 WHERE email = $2 ;', true, 'user@email.com') + * ``` + * + * Read more in our [docs](https://pris.ly/d/raw-queries). + */ + $executeRawUnsafe(query: string, ...values: any[]): Prisma.PrismaPromise; + + /** + * Performs a prepared raw query and returns the `SELECT` data. + * @example + * ``` + * const result = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${1} OR email = ${'user@email.com'};` + * ``` + * + * Read more in our [docs](https://pris.ly/d/raw-queries). + */ + $queryRaw(query: TemplateStringsArray | Prisma.Sql, ...values: any[]): Prisma.PrismaPromise; + + /** + * Performs a raw query and returns the `SELECT` data. + * Susceptible to SQL injections, see documentation. + * @example + * ``` + * const result = await prisma.$queryRawUnsafe('SELECT * FROM User WHERE id = $1 OR email = $2;', 1, 'user@email.com') + * ``` + * + * Read more in our [docs](https://pris.ly/d/raw-queries). + */ + $queryRawUnsafe(query: string, ...values: any[]): Prisma.PrismaPromise; + + + /** + * Allows the running of a sequence of read/write operations that are guaranteed to either succeed or fail as a whole. + * @example + * ``` + * const [george, bob, alice] = await prisma.$transaction([ + * prisma.user.create({ data: { name: 'George' } }), + * prisma.user.create({ data: { name: 'Bob' } }), + * prisma.user.create({ data: { name: 'Alice' } }), + * ]) + * ``` + * + * Read more in our [docs](https://www.prisma.io/docs/concepts/components/prisma-client/transactions). + */ + $transaction

[]>(arg: [...P], options?: { isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise> + + $transaction(fn: (prisma: Omit) => runtime.Types.Utils.JsPromise, options?: { maxWait?: number, timeout?: number, isolationLevel?: Prisma.TransactionIsolationLevel }): runtime.Types.Utils.JsPromise + + $extends: runtime.Types.Extensions.ExtendsHook<"extends", Prisma.TypeMapCb, ExtArgs, runtime.Types.Utils.Call, { + extArgs: ExtArgs + }>> + + /** + * `prisma.discordUserProfile`: Exposes CRUD operations for the **DiscordUserProfile** model. + * Example usage: + * ```ts + * // Fetch zero or more DiscordUserProfiles + * const discordUserProfiles = await prisma.discordUserProfile.findMany() + * ``` + */ + get discordUserProfile(): Prisma.DiscordUserProfileDelegate; + + /** + * `prisma.discordGuildProfile`: Exposes CRUD operations for the **DiscordGuildProfile** model. + * Example usage: + * ```ts + * // Fetch zero or more DiscordGuildProfiles + * const discordGuildProfiles = await prisma.discordGuildProfile.findMany() + * ``` + */ + get discordGuildProfile(): Prisma.DiscordGuildProfileDelegate; +} + +export function getPrismaClientClass(): PrismaClientConstructor { + return runtime.getPrismaClient(config) as unknown as PrismaClientConstructor +} diff --git a/packages/db/generated/prisma/internal/prismaNamespace.ts b/packages/db/generated/prisma/internal/prismaNamespace.ts new file mode 100644 index 0000000..930c1f4 --- /dev/null +++ b/packages/db/generated/prisma/internal/prismaNamespace.ts @@ -0,0 +1,844 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * WARNING: This is an internal file that is subject to change! + * + * 🛑 Under no circumstances should you import this file directly! 🛑 + * + * All exports from this file are wrapped under a `Prisma` namespace object in the client.ts file. + * While this enables partial backward compatibility, it is not part of the stable public API. + * + * If you are looking for your Models, Enums, and Input Types, please import them from the respective + * model files in the `model` directory! + */ + +import * as runtime from "@prisma/client/runtime/client" +import type * as Prisma from "../models" +import { type PrismaClient } from "./class" + +export type * from '../models' + +export type DMMF = typeof runtime.DMMF + +export type PrismaPromise = runtime.Types.Public.PrismaPromise + +/** + * Prisma Errors + */ + +export const PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError +export type PrismaClientKnownRequestError = runtime.PrismaClientKnownRequestError + +export const PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError +export type PrismaClientUnknownRequestError = runtime.PrismaClientUnknownRequestError + +export const PrismaClientRustPanicError = runtime.PrismaClientRustPanicError +export type PrismaClientRustPanicError = runtime.PrismaClientRustPanicError + +export const PrismaClientInitializationError = runtime.PrismaClientInitializationError +export type PrismaClientInitializationError = runtime.PrismaClientInitializationError + +export const PrismaClientValidationError = runtime.PrismaClientValidationError +export type PrismaClientValidationError = runtime.PrismaClientValidationError + +/** + * Re-export of sql-template-tag + */ +export const sql = runtime.sqltag +export const empty = runtime.empty +export const join = runtime.join +export const raw = runtime.raw +export const Sql = runtime.Sql +export type Sql = runtime.Sql + + + +/** + * Decimal.js + */ +export const Decimal = runtime.Decimal +export type Decimal = runtime.Decimal + +export type DecimalJsLike = runtime.DecimalJsLike + +/** +* Extensions +*/ +export type Extension = runtime.Types.Extensions.UserArgs +export const getExtensionContext = runtime.Extensions.getExtensionContext +export type Args = runtime.Types.Public.Args +export type Payload = runtime.Types.Public.Payload +export type Result = runtime.Types.Public.Result +export type Exact = runtime.Types.Public.Exact + +export type PrismaVersion = { + client: string + engine: string +} + +/** + * Prisma Client JS version: 7.2.0 + * Query Engine version: 0c8ef2ce45c83248ab3df073180d5eda9e8be7a3 + */ +export const prismaVersion: PrismaVersion = { + client: "7.2.0", + engine: "0c8ef2ce45c83248ab3df073180d5eda9e8be7a3" +} + +/** + * Utility Types + */ + +export type Bytes = runtime.Bytes +export type JsonObject = runtime.JsonObject +export type JsonArray = runtime.JsonArray +export type JsonValue = runtime.JsonValue +export type InputJsonObject = runtime.InputJsonObject +export type InputJsonArray = runtime.InputJsonArray +export type InputJsonValue = runtime.InputJsonValue + + +export const NullTypes = { + DbNull: runtime.NullTypes.DbNull as (new (secret: never) => typeof runtime.DbNull), + JsonNull: runtime.NullTypes.JsonNull as (new (secret: never) => typeof runtime.JsonNull), + AnyNull: runtime.NullTypes.AnyNull as (new (secret: never) => typeof runtime.AnyNull), +} +/** + * Helper for filtering JSON entries that have `null` on the database (empty on the db) + * + * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field + */ +export const DbNull = runtime.DbNull + +/** + * Helper for filtering JSON entries that have JSON `null` values (not empty on the db) + * + * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field + */ +export const JsonNull = runtime.JsonNull + +/** + * Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull` + * + * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field + */ +export const AnyNull = runtime.AnyNull + + +type SelectAndInclude = { + select: any + include: any +} + +type SelectAndOmit = { + select: any + omit: any +} + +/** + * From T, pick a set of properties whose keys are in the union K + */ +type Prisma__Pick = { + [P in K]: T[P]; +}; + +export type Enumerable = T | Array; + +/** + * Subset + * @desc From `T` pick properties that exist in `U`. Simple version of Intersection + */ +export type Subset = { + [key in keyof T]: key extends keyof U ? T[key] : never; +}; + +/** + * SelectSubset + * @desc From `T` pick properties that exist in `U`. Simple version of Intersection. + * Additionally, it validates, if both select and include are present. If the case, it errors. + */ +export type SelectSubset = { + [key in keyof T]: key extends keyof U ? T[key] : never +} & + (T extends SelectAndInclude + ? 'Please either choose `select` or `include`.' + : T extends SelectAndOmit + ? 'Please either choose `select` or `omit`.' + : {}) + +/** + * Subset + Intersection + * @desc From `T` pick properties that exist in `U` and intersect `K` + */ +export type SubsetIntersection = { + [key in keyof T]: key extends keyof U ? T[key] : never +} & + K + +type Without = { [P in Exclude]?: never }; + +/** + * XOR is needed to have a real mutually exclusive union type + * https://stackoverflow.com/questions/42123407/does-typescript-support-mutually-exclusive-types + */ +export type XOR = + T extends object ? + U extends object ? + (Without & U) | (Without & T) + : U : T + + +/** + * Is T a Record? + */ +type IsObject = T extends Array +? False +: T extends Date +? False +: T extends Uint8Array +? False +: T extends BigInt +? False +: T extends object +? True +: False + + +/** + * If it's T[], return T + */ +export type UnEnumerate = T extends Array ? U : T + +/** + * From ts-toolbelt + */ + +type __Either = Omit & + { + // Merge all but K + [P in K]: Prisma__Pick // With K possibilities + }[K] + +type EitherStrict = Strict<__Either> + +type EitherLoose = ComputeRaw<__Either> + +type _Either< + O extends object, + K extends Key, + strict extends Boolean +> = { + 1: EitherStrict + 0: EitherLoose +}[strict] + +export type Either< + O extends object, + K extends Key, + strict extends Boolean = 1 +> = O extends unknown ? _Either : never + +export type Union = any + +export type PatchUndefined = { + [K in keyof O]: O[K] extends undefined ? At : O[K] +} & {} + +/** Helper Types for "Merge" **/ +export type IntersectOf = ( + U extends unknown ? (k: U) => void : never +) extends (k: infer I) => void + ? I + : never + +export type Overwrite = { + [K in keyof O]: K extends keyof O1 ? O1[K] : O[K]; +} & {}; + +type _Merge = IntersectOf; +}>>; + +type Key = string | number | symbol; +type AtStrict = O[K & keyof O]; +type AtLoose = O extends unknown ? AtStrict : never; +export type At = { + 1: AtStrict; + 0: AtLoose; +}[strict]; + +export type ComputeRaw = A extends Function ? A : { + [K in keyof A]: A[K]; +} & {}; + +export type OptionalFlat = { + [K in keyof O]?: O[K]; +} & {}; + +type _Record = { + [P in K]: T; +}; + +// cause typescript not to expand types and preserve names +type NoExpand = T extends unknown ? T : never; + +// this type assumes the passed object is entirely optional +export type AtLeast = NoExpand< + O extends unknown + ? | (K extends keyof O ? { [P in K]: O[P] } & O : O) + | {[P in keyof O as P extends K ? P : never]-?: O[P]} & O + : never>; + +type _Strict = U extends unknown ? U & OptionalFlat<_Record, keyof U>, never>> : never; + +export type Strict = ComputeRaw<_Strict>; +/** End Helper Types for "Merge" **/ + +export type Merge = ComputeRaw<_Merge>>; + +export type Boolean = True | False + +export type True = 1 + +export type False = 0 + +export type Not = { + 0: 1 + 1: 0 +}[B] + +export type Extends = [A1] extends [never] + ? 0 // anything `never` is false + : A1 extends A2 + ? 1 + : 0 + +export type Has = Not< + Extends, U1> +> + +export type Or = { + 0: { + 0: 0 + 1: 1 + } + 1: { + 0: 1 + 1: 1 + } +}[B1][B2] + +export type Keys = U extends unknown ? keyof U : never + +export type GetScalarType = O extends object ? { + [P in keyof T]: P extends keyof O + ? O[P] + : never +} : never + +type FieldPaths< + T, + U = Omit +> = IsObject extends True ? U : T + +export type GetHavingFields = { + [K in keyof T]: Or< + Or, Extends<'AND', K>>, + Extends<'NOT', K> + > extends True + ? // infer is only needed to not hit TS limit + // based on the brilliant idea of Pierre-Antoine Mills + // https://github.com/microsoft/TypeScript/issues/30188#issuecomment-478938437 + T[K] extends infer TK + ? GetHavingFields extends object ? Merge> : never> + : never + : {} extends FieldPaths + ? never + : K +}[keyof T] + +/** + * Convert tuple to union + */ +type _TupleToUnion = T extends (infer E)[] ? E : never +type TupleToUnion = _TupleToUnion +export type MaybeTupleToUnion = T extends any[] ? TupleToUnion : T + +/** + * Like `Pick`, but additionally can also accept an array of keys + */ +export type PickEnumerable | keyof T> = Prisma__Pick> + +/** + * Exclude all keys with underscores + */ +export type ExcludeUnderscoreKeys = T extends `_${string}` ? never : T + + +export type FieldRef = runtime.FieldRef + +type FieldRefInputType = Model extends never ? never : FieldRef + + +export const ModelName = { + DiscordUserProfile: 'DiscordUserProfile', + DiscordGuildProfile: 'DiscordGuildProfile' +} as const + +export type ModelName = (typeof ModelName)[keyof typeof ModelName] + + + +export interface TypeMapCb extends runtime.Types.Utils.Fn<{extArgs: runtime.Types.Extensions.InternalArgs }, runtime.Types.Utils.Record> { + returns: TypeMap +} + +export type TypeMap = { + globalOmitOptions: { + omit: GlobalOmitOptions + } + meta: { + modelProps: "discordUserProfile" | "discordGuildProfile" + txIsolationLevel: TransactionIsolationLevel + } + model: { + DiscordUserProfile: { + payload: Prisma.$DiscordUserProfilePayload + fields: Prisma.DiscordUserProfileFieldRefs + operations: { + findUnique: { + args: Prisma.DiscordUserProfileFindUniqueArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findUniqueOrThrow: { + args: Prisma.DiscordUserProfileFindUniqueOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findFirst: { + args: Prisma.DiscordUserProfileFindFirstArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findFirstOrThrow: { + args: Prisma.DiscordUserProfileFindFirstOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findMany: { + args: Prisma.DiscordUserProfileFindManyArgs + result: runtime.Types.Utils.PayloadToResult[] + } + create: { + args: Prisma.DiscordUserProfileCreateArgs + result: runtime.Types.Utils.PayloadToResult + } + createMany: { + args: Prisma.DiscordUserProfileCreateManyArgs + result: BatchPayload + } + createManyAndReturn: { + args: Prisma.DiscordUserProfileCreateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + delete: { + args: Prisma.DiscordUserProfileDeleteArgs + result: runtime.Types.Utils.PayloadToResult + } + update: { + args: Prisma.DiscordUserProfileUpdateArgs + result: runtime.Types.Utils.PayloadToResult + } + deleteMany: { + args: Prisma.DiscordUserProfileDeleteManyArgs + result: BatchPayload + } + updateMany: { + args: Prisma.DiscordUserProfileUpdateManyArgs + result: BatchPayload + } + updateManyAndReturn: { + args: Prisma.DiscordUserProfileUpdateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + upsert: { + args: Prisma.DiscordUserProfileUpsertArgs + result: runtime.Types.Utils.PayloadToResult + } + aggregate: { + args: Prisma.DiscordUserProfileAggregateArgs + result: runtime.Types.Utils.Optional + } + groupBy: { + args: Prisma.DiscordUserProfileGroupByArgs + result: runtime.Types.Utils.Optional[] + } + count: { + args: Prisma.DiscordUserProfileCountArgs + result: runtime.Types.Utils.Optional | number + } + } + } + DiscordGuildProfile: { + payload: Prisma.$DiscordGuildProfilePayload + fields: Prisma.DiscordGuildProfileFieldRefs + operations: { + findUnique: { + args: Prisma.DiscordGuildProfileFindUniqueArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findUniqueOrThrow: { + args: Prisma.DiscordGuildProfileFindUniqueOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findFirst: { + args: Prisma.DiscordGuildProfileFindFirstArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findFirstOrThrow: { + args: Prisma.DiscordGuildProfileFindFirstOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findMany: { + args: Prisma.DiscordGuildProfileFindManyArgs + result: runtime.Types.Utils.PayloadToResult[] + } + create: { + args: Prisma.DiscordGuildProfileCreateArgs + result: runtime.Types.Utils.PayloadToResult + } + createMany: { + args: Prisma.DiscordGuildProfileCreateManyArgs + result: BatchPayload + } + createManyAndReturn: { + args: Prisma.DiscordGuildProfileCreateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + delete: { + args: Prisma.DiscordGuildProfileDeleteArgs + result: runtime.Types.Utils.PayloadToResult + } + update: { + args: Prisma.DiscordGuildProfileUpdateArgs + result: runtime.Types.Utils.PayloadToResult + } + deleteMany: { + args: Prisma.DiscordGuildProfileDeleteManyArgs + result: BatchPayload + } + updateMany: { + args: Prisma.DiscordGuildProfileUpdateManyArgs + result: BatchPayload + } + updateManyAndReturn: { + args: Prisma.DiscordGuildProfileUpdateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + upsert: { + args: Prisma.DiscordGuildProfileUpsertArgs + result: runtime.Types.Utils.PayloadToResult + } + aggregate: { + args: Prisma.DiscordGuildProfileAggregateArgs + result: runtime.Types.Utils.Optional + } + groupBy: { + args: Prisma.DiscordGuildProfileGroupByArgs + result: runtime.Types.Utils.Optional[] + } + count: { + args: Prisma.DiscordGuildProfileCountArgs + result: runtime.Types.Utils.Optional | number + } + } + } + } +} & { + other: { + payload: any + operations: { + $executeRaw: { + args: [query: TemplateStringsArray | Sql, ...values: any[]], + result: any + } + $executeRawUnsafe: { + args: [query: string, ...values: any[]], + result: any + } + $queryRaw: { + args: [query: TemplateStringsArray | Sql, ...values: any[]], + result: any + } + $queryRawUnsafe: { + args: [query: string, ...values: any[]], + result: any + } + } + } +} + +/** + * Enums + */ + +export const TransactionIsolationLevel = runtime.makeStrictEnum({ + ReadUncommitted: 'ReadUncommitted', + ReadCommitted: 'ReadCommitted', + RepeatableRead: 'RepeatableRead', + Serializable: 'Serializable' +} as const) + +export type TransactionIsolationLevel = (typeof TransactionIsolationLevel)[keyof typeof TransactionIsolationLevel] + + +export const DiscordUserProfileScalarFieldEnum = { + id: 'id', + userId: 'userId', + voice: 'voice', + nya: 'nya', + canTypecast: 'canTypecast' +} as const + +export type DiscordUserProfileScalarFieldEnum = (typeof DiscordUserProfileScalarFieldEnum)[keyof typeof DiscordUserProfileScalarFieldEnum] + + +export const DiscordGuildProfileScalarFieldEnum = { + id: 'id', + guildId: 'guildId', + readChannel: 'readChannel' +} as const + +export type DiscordGuildProfileScalarFieldEnum = (typeof DiscordGuildProfileScalarFieldEnum)[keyof typeof DiscordGuildProfileScalarFieldEnum] + + +export const SortOrder = { + asc: 'asc', + desc: 'desc' +} as const + +export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder] + + +export const QueryMode = { + default: 'default', + insensitive: 'insensitive' +} as const + +export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode] + + + +/** + * Field references + */ + + +/** + * Reference to a field of type 'String' + */ +export type StringFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'String'> + + + +/** + * Reference to a field of type 'String[]' + */ +export type ListStringFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'String[]'> + + + +/** + * Reference to a field of type 'Voice' + */ +export type EnumVoiceFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Voice'> + + + +/** + * Reference to a field of type 'Voice[]' + */ +export type ListEnumVoiceFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Voice[]'> + + + +/** + * Reference to a field of type 'Boolean' + */ +export type BooleanFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Boolean'> + + + +/** + * Reference to a field of type 'Int' + */ +export type IntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Int'> + + + +/** + * Reference to a field of type 'Int[]' + */ +export type ListIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Int[]'> + + +/** + * Batch Payload for updateMany & deleteMany & createMany + */ +export type BatchPayload = { + count: number +} + +export const defineExtension = runtime.Extensions.defineExtension as unknown as runtime.Types.Extensions.ExtendsHook<"define", TypeMapCb, runtime.Types.Extensions.DefaultArgs> +export type DefaultPrismaClient = PrismaClient +export type ErrorFormat = 'pretty' | 'colorless' | 'minimal' +export type PrismaClientOptions = ({ + /** + * Instance of a Driver Adapter, e.g., like one provided by `@prisma/adapter-pg`. + */ + adapter: runtime.SqlDriverAdapterFactory + accelerateUrl?: never +} | { + /** + * Prisma Accelerate URL allowing the client to connect through Accelerate instead of a direct database. + */ + accelerateUrl: string + adapter?: never +}) & { + /** + * @default "colorless" + */ + errorFormat?: ErrorFormat + /** + * @example + * ``` + * // Shorthand for `emit: 'stdout'` + * log: ['query', 'info', 'warn', 'error'] + * + * // Emit as events only + * log: [ + * { emit: 'event', level: 'query' }, + * { emit: 'event', level: 'info' }, + * { emit: 'event', level: 'warn' } + * { emit: 'event', level: 'error' } + * ] + * + * / Emit as events and log to stdout + * og: [ + * { emit: 'stdout', level: 'query' }, + * { emit: 'stdout', level: 'info' }, + * { emit: 'stdout', level: 'warn' } + * { emit: 'stdout', level: 'error' } + * + * ``` + * Read more in our [docs](https://pris.ly/d/logging). + */ + log?: (LogLevel | LogDefinition)[] + /** + * The default values for transactionOptions + * maxWait ?= 2000 + * timeout ?= 5000 + */ + transactionOptions?: { + maxWait?: number + timeout?: number + isolationLevel?: TransactionIsolationLevel + } + /** + * Global configuration for omitting model fields by default. + * + * @example + * ``` + * const prisma = new PrismaClient({ + * omit: { + * user: { + * password: true + * } + * } + * }) + * ``` + */ + omit?: GlobalOmitConfig + /** + * SQL commenter plugins that add metadata to SQL queries as comments. + * Comments follow the sqlcommenter format: https://google.github.io/sqlcommenter/ + * + * @example + * ``` + * const prisma = new PrismaClient({ + * adapter, + * comments: [ + * traceContext(), + * queryInsights(), + * ], + * }) + * ``` + */ + comments?: runtime.SqlCommenterPlugin[] +} +export type GlobalOmitConfig = { + discordUserProfile?: Prisma.DiscordUserProfileOmit + discordGuildProfile?: Prisma.DiscordGuildProfileOmit +} + +/* Types for Logging */ +export type LogLevel = 'info' | 'query' | 'warn' | 'error' +export type LogDefinition = { + level: LogLevel + emit: 'stdout' | 'event' +} + +export type CheckIsLogLevel = T extends LogLevel ? T : never; + +export type GetLogType = CheckIsLogLevel< + T extends LogDefinition ? T['level'] : T +>; + +export type GetEvents = T extends Array + ? GetLogType + : never; + +export type QueryEvent = { + timestamp: Date + query: string + params: string + duration: number + target: string +} + +export type LogEvent = { + timestamp: Date + message: string + target: string +} +/* End Types for Logging */ + + +export type PrismaAction = + | 'findUnique' + | 'findUniqueOrThrow' + | 'findMany' + | 'findFirst' + | 'findFirstOrThrow' + | 'create' + | 'createMany' + | 'createManyAndReturn' + | 'update' + | 'updateMany' + | 'updateManyAndReturn' + | 'upsert' + | 'delete' + | 'deleteMany' + | 'executeRaw' + | 'queryRaw' + | 'aggregate' + | 'count' + | 'runCommandRaw' + | 'findRaw' + | 'groupBy' + +/** + * `PrismaClient` proxy available in interactive transactions. + */ +export type TransactionClient = Omit + diff --git a/packages/db/generated/prisma/internal/prismaNamespaceBrowser.ts b/packages/db/generated/prisma/internal/prismaNamespaceBrowser.ts new file mode 100644 index 0000000..85b1a55 --- /dev/null +++ b/packages/db/generated/prisma/internal/prismaNamespaceBrowser.ts @@ -0,0 +1,108 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * WARNING: This is an internal file that is subject to change! + * + * 🛑 Under no circumstances should you import this file directly! 🛑 + * + * All exports from this file are wrapped under a `Prisma` namespace object in the browser.ts file. + * While this enables partial backward compatibility, it is not part of the stable public API. + * + * If you are looking for your Models, Enums, and Input Types, please import them from the respective + * model files in the `model` directory! + */ + +import * as runtime from "@prisma/client/runtime/index-browser" + +export type * from '../models' +export type * from './prismaNamespace' + +export const Decimal = runtime.Decimal + + +export const NullTypes = { + DbNull: runtime.NullTypes.DbNull as (new (secret: never) => typeof runtime.DbNull), + JsonNull: runtime.NullTypes.JsonNull as (new (secret: never) => typeof runtime.JsonNull), + AnyNull: runtime.NullTypes.AnyNull as (new (secret: never) => typeof runtime.AnyNull), +} +/** + * Helper for filtering JSON entries that have `null` on the database (empty on the db) + * + * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field + */ +export const DbNull = runtime.DbNull + +/** + * Helper for filtering JSON entries that have JSON `null` values (not empty on the db) + * + * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field + */ +export const JsonNull = runtime.JsonNull + +/** + * Helper for filtering JSON entries that are `Prisma.DbNull` or `Prisma.JsonNull` + * + * @see https://www.prisma.io/docs/concepts/components/prisma-client/working-with-fields/working-with-json-fields#filtering-on-a-json-field + */ +export const AnyNull = runtime.AnyNull + + +export const ModelName = { + DiscordUserProfile: 'DiscordUserProfile', + DiscordGuildProfile: 'DiscordGuildProfile' +} as const + +export type ModelName = (typeof ModelName)[keyof typeof ModelName] + +/* + * Enums + */ + +export const TransactionIsolationLevel = { + ReadUncommitted: 'ReadUncommitted', + ReadCommitted: 'ReadCommitted', + RepeatableRead: 'RepeatableRead', + Serializable: 'Serializable' +} as const + +export type TransactionIsolationLevel = (typeof TransactionIsolationLevel)[keyof typeof TransactionIsolationLevel] + + +export const DiscordUserProfileScalarFieldEnum = { + id: 'id', + userId: 'userId', + voice: 'voice', + nya: 'nya', + canTypecast: 'canTypecast' +} as const + +export type DiscordUserProfileScalarFieldEnum = (typeof DiscordUserProfileScalarFieldEnum)[keyof typeof DiscordUserProfileScalarFieldEnum] + + +export const DiscordGuildProfileScalarFieldEnum = { + id: 'id', + guildId: 'guildId', + readChannel: 'readChannel' +} as const + +export type DiscordGuildProfileScalarFieldEnum = (typeof DiscordGuildProfileScalarFieldEnum)[keyof typeof DiscordGuildProfileScalarFieldEnum] + + +export const SortOrder = { + asc: 'asc', + desc: 'desc' +} as const + +export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder] + + +export const QueryMode = { + default: 'default', + insensitive: 'insensitive' +} as const + +export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode] + diff --git a/packages/db/generated/prisma/models.ts b/packages/db/generated/prisma/models.ts new file mode 100644 index 0000000..f8793f9 --- /dev/null +++ b/packages/db/generated/prisma/models.ts @@ -0,0 +1,13 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This is a barrel export file for all models and their related types. + * + * 🟢 You can import this file directly. + */ +export type * from './models/DiscordUserProfile' +export type * from './models/DiscordGuildProfile' +export type * from './commonInputTypes' \ No newline at end of file diff --git a/packages/db/generated/prisma/models/DiscordGuildProfile.ts b/packages/db/generated/prisma/models/DiscordGuildProfile.ts new file mode 100644 index 0000000..37e6d65 --- /dev/null +++ b/packages/db/generated/prisma/models/DiscordGuildProfile.ts @@ -0,0 +1,1099 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file exports the `DiscordGuildProfile` model and its related types. + * + * 🟢 You can import this file directly. + */ +import type * as runtime from "@prisma/client/runtime/client" +import type * as $Enums from "../enums" +import type * as Prisma from "../internal/prismaNamespace" + +/** + * Model DiscordGuildProfile + * + */ +export type DiscordGuildProfileModel = runtime.Types.Result.DefaultSelection + +export type AggregateDiscordGuildProfile = { + _count: DiscordGuildProfileCountAggregateOutputType | null + _min: DiscordGuildProfileMinAggregateOutputType | null + _max: DiscordGuildProfileMaxAggregateOutputType | null +} + +export type DiscordGuildProfileMinAggregateOutputType = { + id: string | null + guildId: string | null +} + +export type DiscordGuildProfileMaxAggregateOutputType = { + id: string | null + guildId: string | null +} + +export type DiscordGuildProfileCountAggregateOutputType = { + id: number + guildId: number + readChannel: number + _all: number +} + + +export type DiscordGuildProfileMinAggregateInputType = { + id?: true + guildId?: true +} + +export type DiscordGuildProfileMaxAggregateInputType = { + id?: true + guildId?: true +} + +export type DiscordGuildProfileCountAggregateInputType = { + id?: true + guildId?: true + readChannel?: true + _all?: true +} + +export type DiscordGuildProfileAggregateArgs = { + /** + * Filter which DiscordGuildProfile to aggregate. + */ + where?: Prisma.DiscordGuildProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordGuildProfiles to fetch. + */ + orderBy?: Prisma.DiscordGuildProfileOrderByWithRelationInput | Prisma.DiscordGuildProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the start position + */ + cursor?: Prisma.DiscordGuildProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordGuildProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordGuildProfiles. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Count returned DiscordGuildProfiles + **/ + _count?: true | DiscordGuildProfileCountAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the minimum value + **/ + _min?: DiscordGuildProfileMinAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the maximum value + **/ + _max?: DiscordGuildProfileMaxAggregateInputType +} + +export type GetDiscordGuildProfileAggregateType = { + [P in keyof T & keyof AggregateDiscordGuildProfile]: P extends '_count' | 'count' + ? T[P] extends true + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType +} + + + + +export type DiscordGuildProfileGroupByArgs = { + where?: Prisma.DiscordGuildProfileWhereInput + orderBy?: Prisma.DiscordGuildProfileOrderByWithAggregationInput | Prisma.DiscordGuildProfileOrderByWithAggregationInput[] + by: Prisma.DiscordGuildProfileScalarFieldEnum[] | Prisma.DiscordGuildProfileScalarFieldEnum + having?: Prisma.DiscordGuildProfileScalarWhereWithAggregatesInput + take?: number + skip?: number + _count?: DiscordGuildProfileCountAggregateInputType | true + _min?: DiscordGuildProfileMinAggregateInputType + _max?: DiscordGuildProfileMaxAggregateInputType +} + +export type DiscordGuildProfileGroupByOutputType = { + id: string + guildId: string + readChannel: string[] + _count: DiscordGuildProfileCountAggregateOutputType | null + _min: DiscordGuildProfileMinAggregateOutputType | null + _max: DiscordGuildProfileMaxAggregateOutputType | null +} + +type GetDiscordGuildProfileGroupByPayload = Prisma.PrismaPromise< + Array< + Prisma.PickEnumerable & + { + [P in ((keyof T) & (keyof DiscordGuildProfileGroupByOutputType))]: P extends '_count' + ? T[P] extends boolean + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType + } + > + > + + + +export type DiscordGuildProfileWhereInput = { + AND?: Prisma.DiscordGuildProfileWhereInput | Prisma.DiscordGuildProfileWhereInput[] + OR?: Prisma.DiscordGuildProfileWhereInput[] + NOT?: Prisma.DiscordGuildProfileWhereInput | Prisma.DiscordGuildProfileWhereInput[] + id?: Prisma.StringFilter<"DiscordGuildProfile"> | string + guildId?: Prisma.StringFilter<"DiscordGuildProfile"> | string + readChannel?: Prisma.StringNullableListFilter<"DiscordGuildProfile"> +} + +export type DiscordGuildProfileOrderByWithRelationInput = { + id?: Prisma.SortOrder + guildId?: Prisma.SortOrder + readChannel?: Prisma.SortOrder +} + +export type DiscordGuildProfileWhereUniqueInput = Prisma.AtLeast<{ + id?: string + guildId?: string + AND?: Prisma.DiscordGuildProfileWhereInput | Prisma.DiscordGuildProfileWhereInput[] + OR?: Prisma.DiscordGuildProfileWhereInput[] + NOT?: Prisma.DiscordGuildProfileWhereInput | Prisma.DiscordGuildProfileWhereInput[] + readChannel?: Prisma.StringNullableListFilter<"DiscordGuildProfile"> +}, "id" | "guildId"> + +export type DiscordGuildProfileOrderByWithAggregationInput = { + id?: Prisma.SortOrder + guildId?: Prisma.SortOrder + readChannel?: Prisma.SortOrder + _count?: Prisma.DiscordGuildProfileCountOrderByAggregateInput + _max?: Prisma.DiscordGuildProfileMaxOrderByAggregateInput + _min?: Prisma.DiscordGuildProfileMinOrderByAggregateInput +} + +export type DiscordGuildProfileScalarWhereWithAggregatesInput = { + AND?: Prisma.DiscordGuildProfileScalarWhereWithAggregatesInput | Prisma.DiscordGuildProfileScalarWhereWithAggregatesInput[] + OR?: Prisma.DiscordGuildProfileScalarWhereWithAggregatesInput[] + NOT?: Prisma.DiscordGuildProfileScalarWhereWithAggregatesInput | Prisma.DiscordGuildProfileScalarWhereWithAggregatesInput[] + id?: Prisma.StringWithAggregatesFilter<"DiscordGuildProfile"> | string + guildId?: Prisma.StringWithAggregatesFilter<"DiscordGuildProfile"> | string + readChannel?: Prisma.StringNullableListFilter<"DiscordGuildProfile"> +} + +export type DiscordGuildProfileCreateInput = { + id?: string + guildId: string + readChannel?: Prisma.DiscordGuildProfileCreatereadChannelInput | string[] +} + +export type DiscordGuildProfileUncheckedCreateInput = { + id?: string + guildId: string + readChannel?: Prisma.DiscordGuildProfileCreatereadChannelInput | string[] +} + +export type DiscordGuildProfileUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + guildId?: Prisma.StringFieldUpdateOperationsInput | string + readChannel?: Prisma.DiscordGuildProfileUpdatereadChannelInput | string[] +} + +export type DiscordGuildProfileUncheckedUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + guildId?: Prisma.StringFieldUpdateOperationsInput | string + readChannel?: Prisma.DiscordGuildProfileUpdatereadChannelInput | string[] +} + +export type DiscordGuildProfileCreateManyInput = { + id?: string + guildId: string + readChannel?: Prisma.DiscordGuildProfileCreatereadChannelInput | string[] +} + +export type DiscordGuildProfileUpdateManyMutationInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + guildId?: Prisma.StringFieldUpdateOperationsInput | string + readChannel?: Prisma.DiscordGuildProfileUpdatereadChannelInput | string[] +} + +export type DiscordGuildProfileUncheckedUpdateManyInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + guildId?: Prisma.StringFieldUpdateOperationsInput | string + readChannel?: Prisma.DiscordGuildProfileUpdatereadChannelInput | string[] +} + +export type StringNullableListFilter<$PrismaModel = never> = { + equals?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + has?: string | Prisma.StringFieldRefInput<$PrismaModel> | null + hasEvery?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + hasSome?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> + isEmpty?: boolean +} + +export type DiscordGuildProfileCountOrderByAggregateInput = { + id?: Prisma.SortOrder + guildId?: Prisma.SortOrder + readChannel?: Prisma.SortOrder +} + +export type DiscordGuildProfileMaxOrderByAggregateInput = { + id?: Prisma.SortOrder + guildId?: Prisma.SortOrder +} + +export type DiscordGuildProfileMinOrderByAggregateInput = { + id?: Prisma.SortOrder + guildId?: Prisma.SortOrder +} + +export type DiscordGuildProfileCreatereadChannelInput = { + set: string[] +} + +export type DiscordGuildProfileUpdatereadChannelInput = { + set?: string[] + push?: string | string[] +} + + + +export type DiscordGuildProfileSelect = runtime.Types.Extensions.GetSelect<{ + id?: boolean + guildId?: boolean + readChannel?: boolean +}, ExtArgs["result"]["discordGuildProfile"]> + +export type DiscordGuildProfileSelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + guildId?: boolean + readChannel?: boolean +}, ExtArgs["result"]["discordGuildProfile"]> + +export type DiscordGuildProfileSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + guildId?: boolean + readChannel?: boolean +}, ExtArgs["result"]["discordGuildProfile"]> + +export type DiscordGuildProfileSelectScalar = { + id?: boolean + guildId?: boolean + readChannel?: boolean +} + +export type DiscordGuildProfileOmit = runtime.Types.Extensions.GetOmit<"id" | "guildId" | "readChannel", ExtArgs["result"]["discordGuildProfile"]> + +export type $DiscordGuildProfilePayload = { + name: "DiscordGuildProfile" + objects: {} + scalars: runtime.Types.Extensions.GetPayloadResult<{ + id: string + guildId: string + readChannel: string[] + }, ExtArgs["result"]["discordGuildProfile"]> + composites: {} +} + +export type DiscordGuildProfileGetPayload = runtime.Types.Result.GetResult + +export type DiscordGuildProfileCountArgs = + Omit & { + select?: DiscordGuildProfileCountAggregateInputType | true + } + +export interface DiscordGuildProfileDelegate { + [K: symbol]: { types: Prisma.TypeMap['model']['DiscordGuildProfile'], meta: { name: 'DiscordGuildProfile' } } + /** + * Find zero or one DiscordGuildProfile that matches the filter. + * @param {DiscordGuildProfileFindUniqueArgs} args - Arguments to find a DiscordGuildProfile + * @example + * // Get one DiscordGuildProfile + * const discordGuildProfile = await prisma.discordGuildProfile.findUnique({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUnique(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find one DiscordGuildProfile that matches the filter or throw an error with `error.code='P2025'` + * if no matches were found. + * @param {DiscordGuildProfileFindUniqueOrThrowArgs} args - Arguments to find a DiscordGuildProfile + * @example + * // Get one DiscordGuildProfile + * const discordGuildProfile = await prisma.discordGuildProfile.findUniqueOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUniqueOrThrow(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find the first DiscordGuildProfile that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordGuildProfileFindFirstArgs} args - Arguments to find a DiscordGuildProfile + * @example + * // Get one DiscordGuildProfile + * const discordGuildProfile = await prisma.discordGuildProfile.findFirst({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirst(args?: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find the first DiscordGuildProfile that matches the filter or + * throw `PrismaKnownClientError` with `P2025` code if no matches were found. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordGuildProfileFindFirstOrThrowArgs} args - Arguments to find a DiscordGuildProfile + * @example + * // Get one DiscordGuildProfile + * const discordGuildProfile = await prisma.discordGuildProfile.findFirstOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirstOrThrow(args?: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find zero or more DiscordGuildProfiles that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordGuildProfileFindManyArgs} args - Arguments to filter and select certain fields only. + * @example + * // Get all DiscordGuildProfiles + * const discordGuildProfiles = await prisma.discordGuildProfile.findMany() + * + * // Get first 10 DiscordGuildProfiles + * const discordGuildProfiles = await prisma.discordGuildProfile.findMany({ take: 10 }) + * + * // Only select the `id` + * const discordGuildProfileWithIdOnly = await prisma.discordGuildProfile.findMany({ select: { id: true } }) + * + */ + findMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions>> + + /** + * Create a DiscordGuildProfile. + * @param {DiscordGuildProfileCreateArgs} args - Arguments to create a DiscordGuildProfile. + * @example + * // Create one DiscordGuildProfile + * const DiscordGuildProfile = await prisma.discordGuildProfile.create({ + * data: { + * // ... data to create a DiscordGuildProfile + * } + * }) + * + */ + create(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Create many DiscordGuildProfiles. + * @param {DiscordGuildProfileCreateManyArgs} args - Arguments to create many DiscordGuildProfiles. + * @example + * // Create many DiscordGuildProfiles + * const discordGuildProfile = await prisma.discordGuildProfile.createMany({ + * data: [ + * // ... provide data here + * ] + * }) + * + */ + createMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Create many DiscordGuildProfiles and returns the data saved in the database. + * @param {DiscordGuildProfileCreateManyAndReturnArgs} args - Arguments to create many DiscordGuildProfiles. + * @example + * // Create many DiscordGuildProfiles + * const discordGuildProfile = await prisma.discordGuildProfile.createManyAndReturn({ + * data: [ + * // ... provide data here + * ] + * }) + * + * // Create many DiscordGuildProfiles and only return the `id` + * const discordGuildProfileWithIdOnly = await prisma.discordGuildProfile.createManyAndReturn({ + * select: { id: true }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + createManyAndReturn(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "createManyAndReturn", GlobalOmitOptions>> + + /** + * Delete a DiscordGuildProfile. + * @param {DiscordGuildProfileDeleteArgs} args - Arguments to delete one DiscordGuildProfile. + * @example + * // Delete one DiscordGuildProfile + * const DiscordGuildProfile = await prisma.discordGuildProfile.delete({ + * where: { + * // ... filter to delete one DiscordGuildProfile + * } + * }) + * + */ + delete(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Update one DiscordGuildProfile. + * @param {DiscordGuildProfileUpdateArgs} args - Arguments to update one DiscordGuildProfile. + * @example + * // Update one DiscordGuildProfile + * const discordGuildProfile = await prisma.discordGuildProfile.update({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + update(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Delete zero or more DiscordGuildProfiles. + * @param {DiscordGuildProfileDeleteManyArgs} args - Arguments to filter DiscordGuildProfiles to delete. + * @example + * // Delete a few DiscordGuildProfiles + * const { count } = await prisma.discordGuildProfile.deleteMany({ + * where: { + * // ... provide filter here + * } + * }) + * + */ + deleteMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more DiscordGuildProfiles. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordGuildProfileUpdateManyArgs} args - Arguments to update one or more rows. + * @example + * // Update many DiscordGuildProfiles + * const discordGuildProfile = await prisma.discordGuildProfile.updateMany({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + updateMany(args: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more DiscordGuildProfiles and returns the data updated in the database. + * @param {DiscordGuildProfileUpdateManyAndReturnArgs} args - Arguments to update many DiscordGuildProfiles. + * @example + * // Update many DiscordGuildProfiles + * const discordGuildProfile = await prisma.discordGuildProfile.updateManyAndReturn({ + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * + * // Update zero or more DiscordGuildProfiles and only return the `id` + * const discordGuildProfileWithIdOnly = await prisma.discordGuildProfile.updateManyAndReturn({ + * select: { id: true }, + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + updateManyAndReturn(args: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "updateManyAndReturn", GlobalOmitOptions>> + + /** + * Create or update one DiscordGuildProfile. + * @param {DiscordGuildProfileUpsertArgs} args - Arguments to update or create a DiscordGuildProfile. + * @example + * // Update or create a DiscordGuildProfile + * const discordGuildProfile = await prisma.discordGuildProfile.upsert({ + * create: { + * // ... data to create a DiscordGuildProfile + * }, + * update: { + * // ... in case it already exists, update + * }, + * where: { + * // ... the filter for the DiscordGuildProfile we want to update + * } + * }) + */ + upsert(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordGuildProfileClient, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + + /** + * Count the number of DiscordGuildProfiles. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordGuildProfileCountArgs} args - Arguments to filter DiscordGuildProfiles to count. + * @example + * // Count the number of DiscordGuildProfiles + * const count = await prisma.discordGuildProfile.count({ + * where: { + * // ... the filter for the DiscordGuildProfiles we want to count + * } + * }) + **/ + count( + args?: Prisma.Subset, + ): Prisma.PrismaPromise< + T extends runtime.Types.Utils.Record<'select', any> + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number + > + + /** + * Allows you to perform aggregations operations on a DiscordGuildProfile. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordGuildProfileAggregateArgs} args - Select which aggregations you would like to apply and on what fields. + * @example + * // Ordered by age ascending + * // Where email contains prisma.io + * // Limited to the 10 users + * const aggregations = await prisma.user.aggregate({ + * _avg: { + * age: true, + * }, + * where: { + * email: { + * contains: "prisma.io", + * }, + * }, + * orderBy: { + * age: "asc", + * }, + * take: 10, + * }) + **/ + aggregate(args: Prisma.Subset): Prisma.PrismaPromise> + + /** + * Group by DiscordGuildProfile. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordGuildProfileGroupByArgs} args - Group by arguments. + * @example + * // Group by city, order by createdAt, get count + * const result = await prisma.user.groupBy({ + * by: ['city', 'createdAt'], + * orderBy: { + * createdAt: true + * }, + * _count: { + * _all: true + * }, + * }) + * + **/ + groupBy< + T extends DiscordGuildProfileGroupByArgs, + HasSelectOrTake extends Prisma.Or< + Prisma.Extends<'skip', Prisma.Keys>, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: DiscordGuildProfileGroupByArgs['orderBy'] } + : { orderBy?: DiscordGuildProfileGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(args: Prisma.SubsetIntersection & InputErrors): {} extends InputErrors ? GetDiscordGuildProfileGroupByPayload : Prisma.PrismaPromise +/** + * Fields of the DiscordGuildProfile model + */ +readonly fields: DiscordGuildProfileFieldRefs; +} + +/** + * The delegate class that acts as a "Promise-like" for DiscordGuildProfile. + * Why is this prefixed with `Prisma__`? + * Because we want to prevent naming conflicts as mentioned in + * https://github.com/prisma/prisma-client-js/issues/707 + */ +export interface Prisma__DiscordGuildProfileClient extends Prisma.PrismaPromise { + readonly [Symbol.toStringTag]: "PrismaPromise" + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback for only the rejection of the Promise. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of the callback. + */ + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): runtime.Types.Utils.JsPromise +} + + + + +/** + * Fields of the DiscordGuildProfile model + */ +export interface DiscordGuildProfileFieldRefs { + readonly id: Prisma.FieldRef<"DiscordGuildProfile", 'String'> + readonly guildId: Prisma.FieldRef<"DiscordGuildProfile", 'String'> + readonly readChannel: Prisma.FieldRef<"DiscordGuildProfile", 'String[]'> +} + + +// Custom InputTypes +/** + * DiscordGuildProfile findUnique + */ +export type DiscordGuildProfileFindUniqueArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * Filter, which DiscordGuildProfile to fetch. + */ + where: Prisma.DiscordGuildProfileWhereUniqueInput +} + +/** + * DiscordGuildProfile findUniqueOrThrow + */ +export type DiscordGuildProfileFindUniqueOrThrowArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * Filter, which DiscordGuildProfile to fetch. + */ + where: Prisma.DiscordGuildProfileWhereUniqueInput +} + +/** + * DiscordGuildProfile findFirst + */ +export type DiscordGuildProfileFindFirstArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * Filter, which DiscordGuildProfile to fetch. + */ + where?: Prisma.DiscordGuildProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordGuildProfiles to fetch. + */ + orderBy?: Prisma.DiscordGuildProfileOrderByWithRelationInput | Prisma.DiscordGuildProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for DiscordGuildProfiles. + */ + cursor?: Prisma.DiscordGuildProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordGuildProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordGuildProfiles. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of DiscordGuildProfiles. + */ + distinct?: Prisma.DiscordGuildProfileScalarFieldEnum | Prisma.DiscordGuildProfileScalarFieldEnum[] +} + +/** + * DiscordGuildProfile findFirstOrThrow + */ +export type DiscordGuildProfileFindFirstOrThrowArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * Filter, which DiscordGuildProfile to fetch. + */ + where?: Prisma.DiscordGuildProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordGuildProfiles to fetch. + */ + orderBy?: Prisma.DiscordGuildProfileOrderByWithRelationInput | Prisma.DiscordGuildProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for DiscordGuildProfiles. + */ + cursor?: Prisma.DiscordGuildProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordGuildProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordGuildProfiles. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of DiscordGuildProfiles. + */ + distinct?: Prisma.DiscordGuildProfileScalarFieldEnum | Prisma.DiscordGuildProfileScalarFieldEnum[] +} + +/** + * DiscordGuildProfile findMany + */ +export type DiscordGuildProfileFindManyArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * Filter, which DiscordGuildProfiles to fetch. + */ + where?: Prisma.DiscordGuildProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordGuildProfiles to fetch. + */ + orderBy?: Prisma.DiscordGuildProfileOrderByWithRelationInput | Prisma.DiscordGuildProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for listing DiscordGuildProfiles. + */ + cursor?: Prisma.DiscordGuildProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordGuildProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordGuildProfiles. + */ + skip?: number + distinct?: Prisma.DiscordGuildProfileScalarFieldEnum | Prisma.DiscordGuildProfileScalarFieldEnum[] +} + +/** + * DiscordGuildProfile create + */ +export type DiscordGuildProfileCreateArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * The data needed to create a DiscordGuildProfile. + */ + data: Prisma.XOR +} + +/** + * DiscordGuildProfile createMany + */ +export type DiscordGuildProfileCreateManyArgs = { + /** + * The data used to create many DiscordGuildProfiles. + */ + data: Prisma.DiscordGuildProfileCreateManyInput | Prisma.DiscordGuildProfileCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * DiscordGuildProfile createManyAndReturn + */ +export type DiscordGuildProfileCreateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelectCreateManyAndReturn | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * The data used to create many DiscordGuildProfiles. + */ + data: Prisma.DiscordGuildProfileCreateManyInput | Prisma.DiscordGuildProfileCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * DiscordGuildProfile update + */ +export type DiscordGuildProfileUpdateArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * The data needed to update a DiscordGuildProfile. + */ + data: Prisma.XOR + /** + * Choose, which DiscordGuildProfile to update. + */ + where: Prisma.DiscordGuildProfileWhereUniqueInput +} + +/** + * DiscordGuildProfile updateMany + */ +export type DiscordGuildProfileUpdateManyArgs = { + /** + * The data used to update DiscordGuildProfiles. + */ + data: Prisma.XOR + /** + * Filter which DiscordGuildProfiles to update + */ + where?: Prisma.DiscordGuildProfileWhereInput + /** + * Limit how many DiscordGuildProfiles to update. + */ + limit?: number +} + +/** + * DiscordGuildProfile updateManyAndReturn + */ +export type DiscordGuildProfileUpdateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelectUpdateManyAndReturn | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * The data used to update DiscordGuildProfiles. + */ + data: Prisma.XOR + /** + * Filter which DiscordGuildProfiles to update + */ + where?: Prisma.DiscordGuildProfileWhereInput + /** + * Limit how many DiscordGuildProfiles to update. + */ + limit?: number +} + +/** + * DiscordGuildProfile upsert + */ +export type DiscordGuildProfileUpsertArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * The filter to search for the DiscordGuildProfile to update in case it exists. + */ + where: Prisma.DiscordGuildProfileWhereUniqueInput + /** + * In case the DiscordGuildProfile found by the `where` argument doesn't exist, create a new DiscordGuildProfile with this data. + */ + create: Prisma.XOR + /** + * In case the DiscordGuildProfile was found with the provided `where` argument, update it with this data. + */ + update: Prisma.XOR +} + +/** + * DiscordGuildProfile delete + */ +export type DiscordGuildProfileDeleteArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null + /** + * Filter which DiscordGuildProfile to delete. + */ + where: Prisma.DiscordGuildProfileWhereUniqueInput +} + +/** + * DiscordGuildProfile deleteMany + */ +export type DiscordGuildProfileDeleteManyArgs = { + /** + * Filter which DiscordGuildProfiles to delete + */ + where?: Prisma.DiscordGuildProfileWhereInput + /** + * Limit how many DiscordGuildProfiles to delete. + */ + limit?: number +} + +/** + * DiscordGuildProfile without action + */ +export type DiscordGuildProfileDefaultArgs = { + /** + * Select specific fields to fetch from the DiscordGuildProfile + */ + select?: Prisma.DiscordGuildProfileSelect | null + /** + * Omit specific fields from the DiscordGuildProfile + */ + omit?: Prisma.DiscordGuildProfileOmit | null +} diff --git a/packages/db/generated/prisma/models/DiscordUserProfile.ts b/packages/db/generated/prisma/models/DiscordUserProfile.ts new file mode 100644 index 0000000..178e0ba --- /dev/null +++ b/packages/db/generated/prisma/models/DiscordUserProfile.ts @@ -0,0 +1,1156 @@ + +/* !!! This is code generated by Prisma. Do not edit directly. !!! */ +/* eslint-disable */ +// biome-ignore-all lint: generated file +// @ts-nocheck +/* + * This file exports the `DiscordUserProfile` model and its related types. + * + * 🟢 You can import this file directly. + */ +import type * as runtime from "@prisma/client/runtime/client" +import type * as $Enums from "../enums" +import type * as Prisma from "../internal/prismaNamespace" + +/** + * Model DiscordUserProfile + * + */ +export type DiscordUserProfileModel = runtime.Types.Result.DefaultSelection + +export type AggregateDiscordUserProfile = { + _count: DiscordUserProfileCountAggregateOutputType | null + _min: DiscordUserProfileMinAggregateOutputType | null + _max: DiscordUserProfileMaxAggregateOutputType | null +} + +export type DiscordUserProfileMinAggregateOutputType = { + id: string | null + userId: string | null + voice: $Enums.Voice | null + nya: boolean | null + canTypecast: boolean | null +} + +export type DiscordUserProfileMaxAggregateOutputType = { + id: string | null + userId: string | null + voice: $Enums.Voice | null + nya: boolean | null + canTypecast: boolean | null +} + +export type DiscordUserProfileCountAggregateOutputType = { + id: number + userId: number + voice: number + nya: number + canTypecast: number + _all: number +} + + +export type DiscordUserProfileMinAggregateInputType = { + id?: true + userId?: true + voice?: true + nya?: true + canTypecast?: true +} + +export type DiscordUserProfileMaxAggregateInputType = { + id?: true + userId?: true + voice?: true + nya?: true + canTypecast?: true +} + +export type DiscordUserProfileCountAggregateInputType = { + id?: true + userId?: true + voice?: true + nya?: true + canTypecast?: true + _all?: true +} + +export type DiscordUserProfileAggregateArgs = { + /** + * Filter which DiscordUserProfile to aggregate. + */ + where?: Prisma.DiscordUserProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordUserProfiles to fetch. + */ + orderBy?: Prisma.DiscordUserProfileOrderByWithRelationInput | Prisma.DiscordUserProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the start position + */ + cursor?: Prisma.DiscordUserProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordUserProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordUserProfiles. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Count returned DiscordUserProfiles + **/ + _count?: true | DiscordUserProfileCountAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the minimum value + **/ + _min?: DiscordUserProfileMinAggregateInputType + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/aggregations Aggregation Docs} + * + * Select which fields to find the maximum value + **/ + _max?: DiscordUserProfileMaxAggregateInputType +} + +export type GetDiscordUserProfileAggregateType = { + [P in keyof T & keyof AggregateDiscordUserProfile]: P extends '_count' | 'count' + ? T[P] extends true + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType +} + + + + +export type DiscordUserProfileGroupByArgs = { + where?: Prisma.DiscordUserProfileWhereInput + orderBy?: Prisma.DiscordUserProfileOrderByWithAggregationInput | Prisma.DiscordUserProfileOrderByWithAggregationInput[] + by: Prisma.DiscordUserProfileScalarFieldEnum[] | Prisma.DiscordUserProfileScalarFieldEnum + having?: Prisma.DiscordUserProfileScalarWhereWithAggregatesInput + take?: number + skip?: number + _count?: DiscordUserProfileCountAggregateInputType | true + _min?: DiscordUserProfileMinAggregateInputType + _max?: DiscordUserProfileMaxAggregateInputType +} + +export type DiscordUserProfileGroupByOutputType = { + id: string + userId: string + voice: $Enums.Voice + nya: boolean + canTypecast: boolean + _count: DiscordUserProfileCountAggregateOutputType | null + _min: DiscordUserProfileMinAggregateOutputType | null + _max: DiscordUserProfileMaxAggregateOutputType | null +} + +type GetDiscordUserProfileGroupByPayload = Prisma.PrismaPromise< + Array< + Prisma.PickEnumerable & + { + [P in ((keyof T) & (keyof DiscordUserProfileGroupByOutputType))]: P extends '_count' + ? T[P] extends boolean + ? number + : Prisma.GetScalarType + : Prisma.GetScalarType + } + > + > + + + +export type DiscordUserProfileWhereInput = { + AND?: Prisma.DiscordUserProfileWhereInput | Prisma.DiscordUserProfileWhereInput[] + OR?: Prisma.DiscordUserProfileWhereInput[] + NOT?: Prisma.DiscordUserProfileWhereInput | Prisma.DiscordUserProfileWhereInput[] + id?: Prisma.StringFilter<"DiscordUserProfile"> | string + userId?: Prisma.StringFilter<"DiscordUserProfile"> | string + voice?: Prisma.EnumVoiceFilter<"DiscordUserProfile"> | $Enums.Voice + nya?: Prisma.BoolFilter<"DiscordUserProfile"> | boolean + canTypecast?: Prisma.BoolFilter<"DiscordUserProfile"> | boolean +} + +export type DiscordUserProfileOrderByWithRelationInput = { + id?: Prisma.SortOrder + userId?: Prisma.SortOrder + voice?: Prisma.SortOrder + nya?: Prisma.SortOrder + canTypecast?: Prisma.SortOrder +} + +export type DiscordUserProfileWhereUniqueInput = Prisma.AtLeast<{ + id?: string + userId?: string + AND?: Prisma.DiscordUserProfileWhereInput | Prisma.DiscordUserProfileWhereInput[] + OR?: Prisma.DiscordUserProfileWhereInput[] + NOT?: Prisma.DiscordUserProfileWhereInput | Prisma.DiscordUserProfileWhereInput[] + voice?: Prisma.EnumVoiceFilter<"DiscordUserProfile"> | $Enums.Voice + nya?: Prisma.BoolFilter<"DiscordUserProfile"> | boolean + canTypecast?: Prisma.BoolFilter<"DiscordUserProfile"> | boolean +}, "id" | "userId"> + +export type DiscordUserProfileOrderByWithAggregationInput = { + id?: Prisma.SortOrder + userId?: Prisma.SortOrder + voice?: Prisma.SortOrder + nya?: Prisma.SortOrder + canTypecast?: Prisma.SortOrder + _count?: Prisma.DiscordUserProfileCountOrderByAggregateInput + _max?: Prisma.DiscordUserProfileMaxOrderByAggregateInput + _min?: Prisma.DiscordUserProfileMinOrderByAggregateInput +} + +export type DiscordUserProfileScalarWhereWithAggregatesInput = { + AND?: Prisma.DiscordUserProfileScalarWhereWithAggregatesInput | Prisma.DiscordUserProfileScalarWhereWithAggregatesInput[] + OR?: Prisma.DiscordUserProfileScalarWhereWithAggregatesInput[] + NOT?: Prisma.DiscordUserProfileScalarWhereWithAggregatesInput | Prisma.DiscordUserProfileScalarWhereWithAggregatesInput[] + id?: Prisma.StringWithAggregatesFilter<"DiscordUserProfile"> | string + userId?: Prisma.StringWithAggregatesFilter<"DiscordUserProfile"> | string + voice?: Prisma.EnumVoiceWithAggregatesFilter<"DiscordUserProfile"> | $Enums.Voice + nya?: Prisma.BoolWithAggregatesFilter<"DiscordUserProfile"> | boolean + canTypecast?: Prisma.BoolWithAggregatesFilter<"DiscordUserProfile"> | boolean +} + +export type DiscordUserProfileCreateInput = { + id?: string + userId: string + voice?: $Enums.Voice + nya?: boolean + canTypecast?: boolean +} + +export type DiscordUserProfileUncheckedCreateInput = { + id?: string + userId: string + voice?: $Enums.Voice + nya?: boolean + canTypecast?: boolean +} + +export type DiscordUserProfileUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + userId?: Prisma.StringFieldUpdateOperationsInput | string + voice?: Prisma.EnumVoiceFieldUpdateOperationsInput | $Enums.Voice + nya?: Prisma.BoolFieldUpdateOperationsInput | boolean + canTypecast?: Prisma.BoolFieldUpdateOperationsInput | boolean +} + +export type DiscordUserProfileUncheckedUpdateInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + userId?: Prisma.StringFieldUpdateOperationsInput | string + voice?: Prisma.EnumVoiceFieldUpdateOperationsInput | $Enums.Voice + nya?: Prisma.BoolFieldUpdateOperationsInput | boolean + canTypecast?: Prisma.BoolFieldUpdateOperationsInput | boolean +} + +export type DiscordUserProfileCreateManyInput = { + id?: string + userId: string + voice?: $Enums.Voice + nya?: boolean + canTypecast?: boolean +} + +export type DiscordUserProfileUpdateManyMutationInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + userId?: Prisma.StringFieldUpdateOperationsInput | string + voice?: Prisma.EnumVoiceFieldUpdateOperationsInput | $Enums.Voice + nya?: Prisma.BoolFieldUpdateOperationsInput | boolean + canTypecast?: Prisma.BoolFieldUpdateOperationsInput | boolean +} + +export type DiscordUserProfileUncheckedUpdateManyInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + userId?: Prisma.StringFieldUpdateOperationsInput | string + voice?: Prisma.EnumVoiceFieldUpdateOperationsInput | $Enums.Voice + nya?: Prisma.BoolFieldUpdateOperationsInput | boolean + canTypecast?: Prisma.BoolFieldUpdateOperationsInput | boolean +} + +export type DiscordUserProfileCountOrderByAggregateInput = { + id?: Prisma.SortOrder + userId?: Prisma.SortOrder + voice?: Prisma.SortOrder + nya?: Prisma.SortOrder + canTypecast?: Prisma.SortOrder +} + +export type DiscordUserProfileMaxOrderByAggregateInput = { + id?: Prisma.SortOrder + userId?: Prisma.SortOrder + voice?: Prisma.SortOrder + nya?: Prisma.SortOrder + canTypecast?: Prisma.SortOrder +} + +export type DiscordUserProfileMinOrderByAggregateInput = { + id?: Prisma.SortOrder + userId?: Prisma.SortOrder + voice?: Prisma.SortOrder + nya?: Prisma.SortOrder + canTypecast?: Prisma.SortOrder +} + +export type StringFieldUpdateOperationsInput = { + set?: string +} + +export type EnumVoiceFieldUpdateOperationsInput = { + set?: $Enums.Voice +} + +export type BoolFieldUpdateOperationsInput = { + set?: boolean +} + + + +export type DiscordUserProfileSelect = runtime.Types.Extensions.GetSelect<{ + id?: boolean + userId?: boolean + voice?: boolean + nya?: boolean + canTypecast?: boolean +}, ExtArgs["result"]["discordUserProfile"]> + +export type DiscordUserProfileSelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + userId?: boolean + voice?: boolean + nya?: boolean + canTypecast?: boolean +}, ExtArgs["result"]["discordUserProfile"]> + +export type DiscordUserProfileSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ + id?: boolean + userId?: boolean + voice?: boolean + nya?: boolean + canTypecast?: boolean +}, ExtArgs["result"]["discordUserProfile"]> + +export type DiscordUserProfileSelectScalar = { + id?: boolean + userId?: boolean + voice?: boolean + nya?: boolean + canTypecast?: boolean +} + +export type DiscordUserProfileOmit = runtime.Types.Extensions.GetOmit<"id" | "userId" | "voice" | "nya" | "canTypecast", ExtArgs["result"]["discordUserProfile"]> + +export type $DiscordUserProfilePayload = { + name: "DiscordUserProfile" + objects: {} + scalars: runtime.Types.Extensions.GetPayloadResult<{ + id: string + userId: string + voice: $Enums.Voice + nya: boolean + canTypecast: boolean + }, ExtArgs["result"]["discordUserProfile"]> + composites: {} +} + +export type DiscordUserProfileGetPayload = runtime.Types.Result.GetResult + +export type DiscordUserProfileCountArgs = + Omit & { + select?: DiscordUserProfileCountAggregateInputType | true + } + +export interface DiscordUserProfileDelegate { + [K: symbol]: { types: Prisma.TypeMap['model']['DiscordUserProfile'], meta: { name: 'DiscordUserProfile' } } + /** + * Find zero or one DiscordUserProfile that matches the filter. + * @param {DiscordUserProfileFindUniqueArgs} args - Arguments to find a DiscordUserProfile + * @example + * // Get one DiscordUserProfile + * const discordUserProfile = await prisma.discordUserProfile.findUnique({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUnique(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "findUnique", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find one DiscordUserProfile that matches the filter or throw an error with `error.code='P2025'` + * if no matches were found. + * @param {DiscordUserProfileFindUniqueOrThrowArgs} args - Arguments to find a DiscordUserProfile + * @example + * // Get one DiscordUserProfile + * const discordUserProfile = await prisma.discordUserProfile.findUniqueOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findUniqueOrThrow(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "findUniqueOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find the first DiscordUserProfile that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordUserProfileFindFirstArgs} args - Arguments to find a DiscordUserProfile + * @example + * // Get one DiscordUserProfile + * const discordUserProfile = await prisma.discordUserProfile.findFirst({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirst(args?: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "findFirst", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> + + /** + * Find the first DiscordUserProfile that matches the filter or + * throw `PrismaKnownClientError` with `P2025` code if no matches were found. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordUserProfileFindFirstOrThrowArgs} args - Arguments to find a DiscordUserProfile + * @example + * // Get one DiscordUserProfile + * const discordUserProfile = await prisma.discordUserProfile.findFirstOrThrow({ + * where: { + * // ... provide filter here + * } + * }) + */ + findFirstOrThrow(args?: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "findFirstOrThrow", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Find zero or more DiscordUserProfiles that matches the filter. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordUserProfileFindManyArgs} args - Arguments to filter and select certain fields only. + * @example + * // Get all DiscordUserProfiles + * const discordUserProfiles = await prisma.discordUserProfile.findMany() + * + * // Get first 10 DiscordUserProfiles + * const discordUserProfiles = await prisma.discordUserProfile.findMany({ take: 10 }) + * + * // Only select the `id` + * const discordUserProfileWithIdOnly = await prisma.discordUserProfile.findMany({ select: { id: true } }) + * + */ + findMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions>> + + /** + * Create a DiscordUserProfile. + * @param {DiscordUserProfileCreateArgs} args - Arguments to create a DiscordUserProfile. + * @example + * // Create one DiscordUserProfile + * const DiscordUserProfile = await prisma.discordUserProfile.create({ + * data: { + * // ... data to create a DiscordUserProfile + * } + * }) + * + */ + create(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "create", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Create many DiscordUserProfiles. + * @param {DiscordUserProfileCreateManyArgs} args - Arguments to create many DiscordUserProfiles. + * @example + * // Create many DiscordUserProfiles + * const discordUserProfile = await prisma.discordUserProfile.createMany({ + * data: [ + * // ... provide data here + * ] + * }) + * + */ + createMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Create many DiscordUserProfiles and returns the data saved in the database. + * @param {DiscordUserProfileCreateManyAndReturnArgs} args - Arguments to create many DiscordUserProfiles. + * @example + * // Create many DiscordUserProfiles + * const discordUserProfile = await prisma.discordUserProfile.createManyAndReturn({ + * data: [ + * // ... provide data here + * ] + * }) + * + * // Create many DiscordUserProfiles and only return the `id` + * const discordUserProfileWithIdOnly = await prisma.discordUserProfile.createManyAndReturn({ + * select: { id: true }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + createManyAndReturn(args?: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "createManyAndReturn", GlobalOmitOptions>> + + /** + * Delete a DiscordUserProfile. + * @param {DiscordUserProfileDeleteArgs} args - Arguments to delete one DiscordUserProfile. + * @example + * // Delete one DiscordUserProfile + * const DiscordUserProfile = await prisma.discordUserProfile.delete({ + * where: { + * // ... filter to delete one DiscordUserProfile + * } + * }) + * + */ + delete(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "delete", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Update one DiscordUserProfile. + * @param {DiscordUserProfileUpdateArgs} args - Arguments to update one DiscordUserProfile. + * @example + * // Update one DiscordUserProfile + * const discordUserProfile = await prisma.discordUserProfile.update({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + update(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "update", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + /** + * Delete zero or more DiscordUserProfiles. + * @param {DiscordUserProfileDeleteManyArgs} args - Arguments to filter DiscordUserProfiles to delete. + * @example + * // Delete a few DiscordUserProfiles + * const { count } = await prisma.discordUserProfile.deleteMany({ + * where: { + * // ... provide filter here + * } + * }) + * + */ + deleteMany(args?: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more DiscordUserProfiles. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordUserProfileUpdateManyArgs} args - Arguments to update one or more rows. + * @example + * // Update many DiscordUserProfiles + * const discordUserProfile = await prisma.discordUserProfile.updateMany({ + * where: { + * // ... provide filter here + * }, + * data: { + * // ... provide data here + * } + * }) + * + */ + updateMany(args: Prisma.SelectSubset>): Prisma.PrismaPromise + + /** + * Update zero or more DiscordUserProfiles and returns the data updated in the database. + * @param {DiscordUserProfileUpdateManyAndReturnArgs} args - Arguments to update many DiscordUserProfiles. + * @example + * // Update many DiscordUserProfiles + * const discordUserProfile = await prisma.discordUserProfile.updateManyAndReturn({ + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * + * // Update zero or more DiscordUserProfiles and only return the `id` + * const discordUserProfileWithIdOnly = await prisma.discordUserProfile.updateManyAndReturn({ + * select: { id: true }, + * where: { + * // ... provide filter here + * }, + * data: [ + * // ... provide data here + * ] + * }) + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * + */ + updateManyAndReturn(args: Prisma.SelectSubset>): Prisma.PrismaPromise, T, "updateManyAndReturn", GlobalOmitOptions>> + + /** + * Create or update one DiscordUserProfile. + * @param {DiscordUserProfileUpsertArgs} args - Arguments to update or create a DiscordUserProfile. + * @example + * // Update or create a DiscordUserProfile + * const discordUserProfile = await prisma.discordUserProfile.upsert({ + * create: { + * // ... data to create a DiscordUserProfile + * }, + * update: { + * // ... in case it already exists, update + * }, + * where: { + * // ... the filter for the DiscordUserProfile we want to update + * } + * }) + */ + upsert(args: Prisma.SelectSubset>): Prisma.Prisma__DiscordUserProfileClient, T, "upsert", GlobalOmitOptions>, never, ExtArgs, GlobalOmitOptions> + + + /** + * Count the number of DiscordUserProfiles. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordUserProfileCountArgs} args - Arguments to filter DiscordUserProfiles to count. + * @example + * // Count the number of DiscordUserProfiles + * const count = await prisma.discordUserProfile.count({ + * where: { + * // ... the filter for the DiscordUserProfiles we want to count + * } + * }) + **/ + count( + args?: Prisma.Subset, + ): Prisma.PrismaPromise< + T extends runtime.Types.Utils.Record<'select', any> + ? T['select'] extends true + ? number + : Prisma.GetScalarType + : number + > + + /** + * Allows you to perform aggregations operations on a DiscordUserProfile. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordUserProfileAggregateArgs} args - Select which aggregations you would like to apply and on what fields. + * @example + * // Ordered by age ascending + * // Where email contains prisma.io + * // Limited to the 10 users + * const aggregations = await prisma.user.aggregate({ + * _avg: { + * age: true, + * }, + * where: { + * email: { + * contains: "prisma.io", + * }, + * }, + * orderBy: { + * age: "asc", + * }, + * take: 10, + * }) + **/ + aggregate(args: Prisma.Subset): Prisma.PrismaPromise> + + /** + * Group by DiscordUserProfile. + * Note, that providing `undefined` is treated as the value not being there. + * Read more here: https://pris.ly/d/null-undefined + * @param {DiscordUserProfileGroupByArgs} args - Group by arguments. + * @example + * // Group by city, order by createdAt, get count + * const result = await prisma.user.groupBy({ + * by: ['city', 'createdAt'], + * orderBy: { + * createdAt: true + * }, + * _count: { + * _all: true + * }, + * }) + * + **/ + groupBy< + T extends DiscordUserProfileGroupByArgs, + HasSelectOrTake extends Prisma.Or< + Prisma.Extends<'skip', Prisma.Keys>, + Prisma.Extends<'take', Prisma.Keys> + >, + OrderByArg extends Prisma.True extends HasSelectOrTake + ? { orderBy: DiscordUserProfileGroupByArgs['orderBy'] } + : { orderBy?: DiscordUserProfileGroupByArgs['orderBy'] }, + OrderFields extends Prisma.ExcludeUnderscoreKeys>>, + ByFields extends Prisma.MaybeTupleToUnion, + ByValid extends Prisma.Has, + HavingFields extends Prisma.GetHavingFields, + HavingValid extends Prisma.Has, + ByEmpty extends T['by'] extends never[] ? Prisma.True : Prisma.False, + InputErrors extends ByEmpty extends Prisma.True + ? `Error: "by" must not be empty.` + : HavingValid extends Prisma.False + ? { + [P in HavingFields]: P extends ByFields + ? never + : P extends string + ? `Error: Field "${P}" used in "having" needs to be provided in "by".` + : [ + Error, + 'Field ', + P, + ` in "having" needs to be provided in "by"`, + ] + }[HavingFields] + : 'take' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "take", you also need to provide "orderBy"' + : 'skip' extends Prisma.Keys + ? 'orderBy' extends Prisma.Keys + ? ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + : 'Error: If you provide "skip", you also need to provide "orderBy"' + : ByValid extends Prisma.True + ? {} + : { + [P in OrderFields]: P extends ByFields + ? never + : `Error: Field "${P}" in "orderBy" needs to be provided in "by"` + }[OrderFields] + >(args: Prisma.SubsetIntersection & InputErrors): {} extends InputErrors ? GetDiscordUserProfileGroupByPayload : Prisma.PrismaPromise +/** + * Fields of the DiscordUserProfile model + */ +readonly fields: DiscordUserProfileFieldRefs; +} + +/** + * The delegate class that acts as a "Promise-like" for DiscordUserProfile. + * Why is this prefixed with `Prisma__`? + * Because we want to prevent naming conflicts as mentioned in + * https://github.com/prisma/prisma-client-js/issues/707 + */ +export interface Prisma__DiscordUserProfileClient extends Prisma.PrismaPromise { + readonly [Symbol.toStringTag]: "PrismaPromise" + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: ((value: T) => TResult1 | PromiseLike) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback for only the rejection of the Promise. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of the callback. + */ + catch(onrejected?: ((reason: any) => TResult | PromiseLike) | undefined | null): runtime.Types.Utils.JsPromise + /** + * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The + * resolved value cannot be modified from the callback. + * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected). + * @returns A Promise for the completion of the callback. + */ + finally(onfinally?: (() => void) | undefined | null): runtime.Types.Utils.JsPromise +} + + + + +/** + * Fields of the DiscordUserProfile model + */ +export interface DiscordUserProfileFieldRefs { + readonly id: Prisma.FieldRef<"DiscordUserProfile", 'String'> + readonly userId: Prisma.FieldRef<"DiscordUserProfile", 'String'> + readonly voice: Prisma.FieldRef<"DiscordUserProfile", 'Voice'> + readonly nya: Prisma.FieldRef<"DiscordUserProfile", 'Boolean'> + readonly canTypecast: Prisma.FieldRef<"DiscordUserProfile", 'Boolean'> +} + + +// Custom InputTypes +/** + * DiscordUserProfile findUnique + */ +export type DiscordUserProfileFindUniqueArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * Filter, which DiscordUserProfile to fetch. + */ + where: Prisma.DiscordUserProfileWhereUniqueInput +} + +/** + * DiscordUserProfile findUniqueOrThrow + */ +export type DiscordUserProfileFindUniqueOrThrowArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * Filter, which DiscordUserProfile to fetch. + */ + where: Prisma.DiscordUserProfileWhereUniqueInput +} + +/** + * DiscordUserProfile findFirst + */ +export type DiscordUserProfileFindFirstArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * Filter, which DiscordUserProfile to fetch. + */ + where?: Prisma.DiscordUserProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordUserProfiles to fetch. + */ + orderBy?: Prisma.DiscordUserProfileOrderByWithRelationInput | Prisma.DiscordUserProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for DiscordUserProfiles. + */ + cursor?: Prisma.DiscordUserProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordUserProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordUserProfiles. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of DiscordUserProfiles. + */ + distinct?: Prisma.DiscordUserProfileScalarFieldEnum | Prisma.DiscordUserProfileScalarFieldEnum[] +} + +/** + * DiscordUserProfile findFirstOrThrow + */ +export type DiscordUserProfileFindFirstOrThrowArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * Filter, which DiscordUserProfile to fetch. + */ + where?: Prisma.DiscordUserProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordUserProfiles to fetch. + */ + orderBy?: Prisma.DiscordUserProfileOrderByWithRelationInput | Prisma.DiscordUserProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for searching for DiscordUserProfiles. + */ + cursor?: Prisma.DiscordUserProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordUserProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordUserProfiles. + */ + skip?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/distinct Distinct Docs} + * + * Filter by unique combinations of DiscordUserProfiles. + */ + distinct?: Prisma.DiscordUserProfileScalarFieldEnum | Prisma.DiscordUserProfileScalarFieldEnum[] +} + +/** + * DiscordUserProfile findMany + */ +export type DiscordUserProfileFindManyArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * Filter, which DiscordUserProfiles to fetch. + */ + where?: Prisma.DiscordUserProfileWhereInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/sorting Sorting Docs} + * + * Determine the order of DiscordUserProfiles to fetch. + */ + orderBy?: Prisma.DiscordUserProfileOrderByWithRelationInput | Prisma.DiscordUserProfileOrderByWithRelationInput[] + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination Cursor Docs} + * + * Sets the position for listing DiscordUserProfiles. + */ + cursor?: Prisma.DiscordUserProfileWhereUniqueInput + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Take `±n` DiscordUserProfiles from the position of the cursor. + */ + take?: number + /** + * {@link https://www.prisma.io/docs/concepts/components/prisma-client/pagination Pagination Docs} + * + * Skip the first `n` DiscordUserProfiles. + */ + skip?: number + distinct?: Prisma.DiscordUserProfileScalarFieldEnum | Prisma.DiscordUserProfileScalarFieldEnum[] +} + +/** + * DiscordUserProfile create + */ +export type DiscordUserProfileCreateArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * The data needed to create a DiscordUserProfile. + */ + data: Prisma.XOR +} + +/** + * DiscordUserProfile createMany + */ +export type DiscordUserProfileCreateManyArgs = { + /** + * The data used to create many DiscordUserProfiles. + */ + data: Prisma.DiscordUserProfileCreateManyInput | Prisma.DiscordUserProfileCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * DiscordUserProfile createManyAndReturn + */ +export type DiscordUserProfileCreateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelectCreateManyAndReturn | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * The data used to create many DiscordUserProfiles. + */ + data: Prisma.DiscordUserProfileCreateManyInput | Prisma.DiscordUserProfileCreateManyInput[] + skipDuplicates?: boolean +} + +/** + * DiscordUserProfile update + */ +export type DiscordUserProfileUpdateArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * The data needed to update a DiscordUserProfile. + */ + data: Prisma.XOR + /** + * Choose, which DiscordUserProfile to update. + */ + where: Prisma.DiscordUserProfileWhereUniqueInput +} + +/** + * DiscordUserProfile updateMany + */ +export type DiscordUserProfileUpdateManyArgs = { + /** + * The data used to update DiscordUserProfiles. + */ + data: Prisma.XOR + /** + * Filter which DiscordUserProfiles to update + */ + where?: Prisma.DiscordUserProfileWhereInput + /** + * Limit how many DiscordUserProfiles to update. + */ + limit?: number +} + +/** + * DiscordUserProfile updateManyAndReturn + */ +export type DiscordUserProfileUpdateManyAndReturnArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelectUpdateManyAndReturn | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * The data used to update DiscordUserProfiles. + */ + data: Prisma.XOR + /** + * Filter which DiscordUserProfiles to update + */ + where?: Prisma.DiscordUserProfileWhereInput + /** + * Limit how many DiscordUserProfiles to update. + */ + limit?: number +} + +/** + * DiscordUserProfile upsert + */ +export type DiscordUserProfileUpsertArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * The filter to search for the DiscordUserProfile to update in case it exists. + */ + where: Prisma.DiscordUserProfileWhereUniqueInput + /** + * In case the DiscordUserProfile found by the `where` argument doesn't exist, create a new DiscordUserProfile with this data. + */ + create: Prisma.XOR + /** + * In case the DiscordUserProfile was found with the provided `where` argument, update it with this data. + */ + update: Prisma.XOR +} + +/** + * DiscordUserProfile delete + */ +export type DiscordUserProfileDeleteArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null + /** + * Filter which DiscordUserProfile to delete. + */ + where: Prisma.DiscordUserProfileWhereUniqueInput +} + +/** + * DiscordUserProfile deleteMany + */ +export type DiscordUserProfileDeleteManyArgs = { + /** + * Filter which DiscordUserProfiles to delete + */ + where?: Prisma.DiscordUserProfileWhereInput + /** + * Limit how many DiscordUserProfiles to delete. + */ + limit?: number +} + +/** + * DiscordUserProfile without action + */ +export type DiscordUserProfileDefaultArgs = { + /** + * Select specific fields to fetch from the DiscordUserProfile + */ + select?: Prisma.DiscordUserProfileSelect | null + /** + * Omit specific fields from the DiscordUserProfile + */ + omit?: Prisma.DiscordUserProfileOmit | null +} diff --git a/packages/db/prisma.ts b/packages/db/prisma.ts new file mode 100644 index 0000000..cd77211 --- /dev/null +++ b/packages/db/prisma.ts @@ -0,0 +1,17 @@ +import { PrismaClient } from "./generated/prisma/client"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { Pool } from "pg"; +import { DATABASE_URL } from "../env" +import { OutputHandler } from "../utils/outputHandler"; + +const pool = new Pool({ connectionString: DATABASE_URL }); +const adapter = new PrismaPg(pool); + +pool.connect((err, client, release) => { + if (err) + return OutputHandler.errorLog("[PG Error]", err.message); + + release(); +}); + +export const prisma = new PrismaClient({ adapter }); diff --git a/packages/env.ts b/packages/env.ts new file mode 100644 index 0000000..6f90e4e --- /dev/null +++ b/packages/env.ts @@ -0,0 +1,9 @@ +import { config } from "dotenv" + +config({ quiet: true }); + +export const DISCORD_TOKEN = process.env.DISCORD_TOKEN as string; +export const APPLICATION_ID = process.env.APPLICATION_ID as string; +export const GUILD_ID = process.env.GUILD_ID as string; +export const TYPECAST_TOKENS = (process.env.TYPECAST_TOKEN as string).split(","); +export const DATABASE_URL = process.env.DATABASE_URL as string; diff --git a/packages/index.ts b/packages/index.ts new file mode 100644 index 0000000..d10276c --- /dev/null +++ b/packages/index.ts @@ -0,0 +1,20 @@ +import { Routes } from "discord.js"; +import { DiscordBot } from "./bot"; +import { APPLICATION_ID, DISCORD_TOKEN } from "./env"; +import remove from "./cli/remove_command"; + +export const bot = new DiscordBot(DISCORD_TOKEN); + +bot.client.once("ready", async (client) => { + await bot.registerCommands(); + await bot.registerEvents(); + + console.log( + "registerCommands: \n" + + ( + (await client.rest.get(Routes.applicationCommands(APPLICATION_ID))) as any[] + ).map(info => `name: ${info.name} id: ${info.id}`).join("\n") + ); +}); + +bot.client.login(DISCORD_TOKEN); \ No newline at end of file diff --git a/packages/tts/index.ts b/packages/tts/index.ts new file mode 100644 index 0000000..17ba50d --- /dev/null +++ b/packages/tts/index.ts @@ -0,0 +1,95 @@ +import { writeFile, mkdir, stat, readFile } from "fs/promises"; +import { dirname } from "path"; +import { AudioResource, createAudioResource, StreamType } from "@discordjs/voice"; +import { Readable } from "stream"; +import { createHash } from "node:crypto"; +import { join } from "node:path"; +import { existsSync } from "node:fs"; + +export abstract class TTSModelBase { + public ttsify(input: string): string { + return input + .replace(/:[^:]+:/g, (text: string): string => (TTSModelBase.EMOJI_MAP[text] ?? "이모지")) + .replace(/[:*"<>|]/g, "") + .replace(/[\t\n]/g, " ") + } + public abstract createRequestId(text: string): RequestId + public abstract getVoiceBuffer(id: RequestId): Promise + public abstract getVoicePath(id: RequestId): string + + /** + * id로 부터 음성을 생성하여 캐시 파일에 저장합니다 + * 생성된 음성을 반환합니다 + */ + public async createVoice(id: RequestId, audioPath?: string): Promise { + const voiceBuffer = await this.getVoiceBuffer(id); + audioPath ??= this.getVoicePath(id); + const buffer = Buffer.from(voiceBuffer); + + await mkdir(dirname(audioPath), { recursive: true }); + await writeFile(audioPath, buffer); + + return buffer; + } + /** + * id로 부터 파일에 캐싱된 음성을 얻거나 없는 경우 생성합니다 + */ + public async getVoice(id: RequestId, audioPath?: string): Promise { + audioPath ??= this.getVoicePath(id); + + if (existsSync(audioPath)) { + const buffer = await readFile(audioPath); + return buffer; + } + + return this.createVoice(id, audioPath); + } + /** + * id로 부터 메모리에 캐싱된 음성을 얻거나, 파일에 캐싱된 + * 음성을 얻거나, 없는 경우 생성합니다 + */ + protected abstract cachedVoice: Map> + public async getMemcachedVoice(id: RequestId): Promise { + const path = this.getVoicePath(id); + + const cached = this.cachedVoice.get(path); + if (cached) { + return cached; + } + + const waitter = this.getVoice(id); + this.cachedVoice.set(path, waitter); + setTimeout( + () => this.cachedVoice.delete(path), + TTSModelBase.MemCacheTTL + ); + return await waitter; + } +} +export namespace TTSModelBase { + export const EMOJI_MAP: { [key: string]: string } = { + ":heart:": "하트", + ":huck:": "헉헉!", + ":star:": "초롱초롱!" + } + export const AudioCachePath = join( + process.cwd(), + "cache", + "audio", + ); + export function bufferToAudioResource(buf: Buffer): AudioResource { + const stream = Readable.from(buf); + const resource = createAudioResource(stream, { + inlineVolume: true, + inputType: StreamType.Arbitrary, + }); + + resource.volume?.setVolume(0.3); + return resource; + } + export function hashAudioFile(audio: string, suffix: string = ""): string { + return createHash("md5").update(audio).digest("hex") + suffix + ".mp3"; + } + export const MemCacheTTL = 60 * 60 * 1000 +} +export default TTSModelBase; diff --git a/packages/tts/papago.ts b/packages/tts/papago.ts new file mode 100644 index 0000000..04e66e8 --- /dev/null +++ b/packages/tts/papago.ts @@ -0,0 +1,101 @@ +import { createHmac } from "crypto"; +import { join } from "path"; +import fetch from "../utils/fetch"; +import TTSModelBase from "."; + +export class TTSPapagoModel extends TTSModelBase { + protected cachedVoice: Map> + constructor() { + super() + this.cachedVoice = new Map(); + } + public getVoicePath(id: TTSPapagoModel.RequestId): string { + const audioFileName = TTSModelBase.hashAudioFile(id.text, `.${id.speaker}.${id.speed.replace(/\-/g, "_")}`); + const audioPath = join( + TTSPapagoModel.PapagoAudioCachePath, + audioFileName + ); + return audioPath; + } + async getVoiceBuffer(id: TTSPapagoModel.RequestId, voiceId?: string): Promise { + voiceId ??= await TTSPapagoModel.getVoiceId(id) + const response = await fetch(`https://papago.naver.com/apis/tts/${voiceId}`); + return await response.arrayBuffer(); + } + createRequestId(text: string, speaker?: string, speed?: string): TTSPapagoModel.RequestId { + return { + text, + speed: speed ?? "-1", + speaker: speaker ?? "kyuri", + }; + } +} +export namespace TTSPapagoModel { + export const instance = new TTSPapagoModel(); + export type RequestId = { + speaker: string; + speed: string; + text: string; + }; + export const GenerateTokenKey = "v1.9.3_3bdf0438a8"; + export function hmacMD5(key: string, plaintext: string) { + const hmac = createHmac("md5", key); + const data = hmac.update(plaintext); + + return data.digest("base64"); + } + export function generateToken(time: number) { + const e = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (e) => { + var t = (time + 16 * Math.random()) % 16 | 0; + return (time = Math.floor(time / 16)), ("x" === e ? t : (3 & t) | 8).toString(16); + }); + + const plain = `${e}\n${"https://papago.naver.com/apis/tts/makeID"}\n${time}`; + + return `PPG ${e}:${hmacMD5(GenerateTokenKey, plain)}`; + } + export async function getVoiceId(id: RequestId): Promise { + const input = { + alpha: "0", + pitch: "0", + speaker: id.speaker, + speed: id.speed, + text: id.text, + }; + + const time = new Date().getTime(); + const token = TTSPapagoModel.generateToken(time); + + const reqbody = new URLSearchParams(Object.entries(input)).toString(); + const response = await fetch("https://papago.naver.com/apis/tts/makeID", { + headers: { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0", + Accept: "application/json", + "Accept-Language": "en", + "Sec-GPC": "1", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "no-cors", + "Sec-Fetch-Site": "same-origin", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + Authorization: token, + Timestamp: time.toString(), + Pragma: "no-cache", + "Cache-Control": "no-cache", + }, + referrer: "https://papago.naver.com/", + body: reqbody, + method: "POST", + }); + + if (!response.ok) { + throw new Error(`TTS makeID request failed: ${response.status}: ${await response.text()}`); + } + + return ((await response.json()) as any).id; + } + export const PapagoAudioCachePath = join( + TTSModelBase.AudioCachePath, + "papago" + ); +} +export default TTSPapagoModel; diff --git a/packages/tts/typecast.ts b/packages/tts/typecast.ts new file mode 100644 index 0000000..fd36a70 --- /dev/null +++ b/packages/tts/typecast.ts @@ -0,0 +1,176 @@ +import { join } from "path"; +import { TYPECAST_TOKENS } from "../env"; +import fetch from "../utils/fetch"; +import TTSModelBase from "."; +import CallingNumberKorean from "../utils/callingNumberKorean"; +import IntegerKorean from "../utils/integerKorean"; +import FloatKorean from "../utils/floatKorean"; +import { readFileSync, writeFileSync } from "fs"; +import { cwd, env } from "process"; + +export class TTSTypecastModel extends TTSModelBase { + protected cachedVoice: Map> + private lastUseApiKeyPath: string + constructor() { + super() + this.cachedVoice = new Map(); + this.lastUseApiKeyPath = join(cwd(), "cache", "typecast", "lastUseApiToken"); + } + ttsify(input: string): string { + + return super.ttsify( + input + .replace(/\.+$/, "") + .replace(/\.\.+/g, "") + .replace(/\.[ \t]/g, " ") + .replace(/^[\?\!\'\"]+$/, (total)=>( + [...total].map(element => TTSTypecastModel.IsolatedSymbolMap[ + element as keyof typeof TTSTypecastModel.IsolatedSymbolMap + ]).join("") + )) + .replace(/\`\`\`.+?\`\`\`/g, "코드블럭") + .replace(/https\S+/g, "링크") + .replace(/ㄴㄴ/g, "노노") + .replace(/ㅇㅋ/g, "오키") + .replace(/ㅜㅜ/g, "눙물") + .replace(/빵/g, "빵 크크") + .replace(/[\?]+ *ㄴ/g, "물음표ㄴ") + .replace(/(\d+)[ \t\n]*([개살])/g, (_, num: string, postfix: string)=>{ + const intNum = parseInt(num) + if (CallingNumberKorean.canConvert(intNum)) { + return CallingNumberKorean.convert(intNum) + postfix; + } else { + return IntegerKorean.convertFromString(num) + postfix; + } + }) + .replace(/(v?)([\d\.]+)([ab]?)/g, (_, suffix: string, num: string, postfix: string) => { + const dotCount = [...num.matchAll(/\./g)].length; + const hasNoSuffix = suffix == ""; + + if (hasNoSuffix && dotCount == 0) { + return IntegerKorean.convertFromString(num) + postfix; + } else if (hasNoSuffix && dotCount == 1) { + const [intPart, floatPart] = num.split(/\./); + return ( + IntegerKorean.convertFromString(intPart) + + "쩜" + + FloatKorean.convert(floatPart) + + postfix + ) + } else if (suffix == "v") { + return ( + "버전" + + FloatKorean.convert(num) + + (TTSTypecastModel.VersionPostfix[ + postfix as keyof typeof TTSTypecastModel.VersionPostfix + ] ?? "") + ); + } else { + return FloatKorean.convert(num) + postfix; + } + }) + .replace(/[\%\^\&\*\#\@\.\-\+\_\=\/\\♡\$]/g, (t) => ( + TTSTypecastModel.SymbolMap[t as keyof typeof TTSTypecastModel.SymbolMap] + )) + .replace(/\?+/g, "?") + .replace(/\!+/g, "!") + ) + } + private async getTypecastResponse(apiKey: string, voiceId: TTSTypecastModel.RequestId) { + const payload = { + text: voiceId.text, + model: "ssfm-v21", + voice_id: voiceId.voiceId, + language: "kor", + prompt: { + emotion_preset: "happy", // Options: normal, happy, sad, angry, tonemid, toneup + emotion_intensity: 1 // Range: 0.0 to 2.0 + }, + output: { + volume: 45, // Range: 0 to 200 + audio_pitch: 1, // Range: -12 to +12 semitones + audio_tempo: 1, // Range: 0.5x to 2.0x + audio_format: "mp3" // Options: wav, mp3 + }, + seed: 22 // For reproducible results + }; + + return await fetch(TTSTypecastModel.TypecastApiUrl, { + method: "POST", + headers: { + "X-API-KEY": apiKey, + "Content-Type": "application/json" + }, + body: JSON.stringify(payload) + }); + } + async getVoiceBuffer(voiceId: TTSTypecastModel.RequestId): Promise { + let response: Response | undefined; + + for (let i = 0; i < TYPECAST_TOKENS.length; i++) { + response = await this.getTypecastResponse(readFileSync(this.lastUseApiKeyPath, "utf-8"), voiceId) as Response; + + if (response.ok) + return await response.arrayBuffer();; + + if (response.status === 402) { + writeFileSync(this.lastUseApiKeyPath, TYPECAST_TOKENS[i]); + } else { + throw new Error(`TTS makeID request failed: ${response.status}: ${await response.text()}`); + } + + } + + throw new Error("Typecast Api use all credit"); + } + public getVoicePath(id: TTSTypecastModel.RequestId): string { + const audioFileName = TTSModelBase.hashAudioFile(id.text); + const audioPath = join( + TTSTypecastModel.TypecastAudioCachePath, + id.voiceId, + audioFileName + ); + return audioPath; + } + public createRequestId(text: string, voiceId?: string): TTSTypecastModel.RequestId { + return { + text, + voiceId: voiceId ?? TTSTypecastModel.DefaultVoiceId, + }; + } +} +export namespace TTSTypecastModel { + export const IsolatedSymbolMap = { + "?": "물음표", + "!": "느낌표", + "'": "쿼트", + "\"": "더블쿼트", + } + export const SymbolMap = { + "%": "퍼센트", + "$": "달러싸인", + "^": "캐럿", + "&": "엠퍼센드", + "*": "스타", + "#": "해시", + "@": "엣", + ".": "쩜", + "-": "마이너스", + "+": "플러스", + "_": "언더바", + "=": "이퀄", + "/": "슬래쉬", + "\\": "역슬래쉬", + "♡": "하투 ", + }; + export const VersionPostfix = { + "a": "알파", + "b": "베타", + }; + export const instance = new TTSTypecastModel(); + export type RequestId = { text: string, voiceId: string }; + export const TypecastAudioCachePath = join(TTSModelBase.AudioCachePath, "typecast"); + export const TypecastApiUrl = "https://api.typecast.ai/v1/text-to-speech"; + export const DefaultVoiceId = "tc_6731b292d944a485bc406efb"; +} +export default TTSTypecastModel; diff --git a/packages/utils/callingNumberKorean.ts b/packages/utils/callingNumberKorean.ts new file mode 100644 index 0000000..7f0bf34 --- /dev/null +++ b/packages/utils/callingNumberKorean.ts @@ -0,0 +1,31 @@ +export default class CallingNumberKorean { + // 개, 살 이 붙는 경우 발음법 + static SecondDigit = [ + "열", "스물", "서른", "마흔", "쉰", + "예순", "일흔", "여든", "아흔", + ] + static FirstDigit = [ + "", "한", "두", "세", "네", "다섯", + "여섯", "일곱", "여덟", "아홉", "열", + ] + static FirstDigitSingle = [ + "영", "한", "두", "세", "네", "다섯", + "여섯", "일곱", "여덟", "아홉", "열", + ] + static canConvert(num: number): boolean { + return num < 100 && num >= 0 && !Number.isInteger(num) + } + static convert(num: number): string { + const firstDigit = num % 10; + const secondDigit = Math.floor(num / 10); + + if (secondDigit) { + return ( + this.SecondDigit[secondDigit] + + this.FirstDigit[firstDigit] + ); + } else { + return this.FirstDigitSingle[firstDigit]; + } + } +} diff --git a/packages/utils/fetch.ts b/packages/utils/fetch.ts new file mode 100644 index 0000000..b472426 --- /dev/null +++ b/packages/utils/fetch.ts @@ -0,0 +1,15 @@ +import { Response as NodeFetchResponse, RequestInit, RequestInfo } from "node-fetch"; +import defaultFetch from "node-fetch"; + +export default async function(url: URL | RequestInfo, request: RequestInit={}, time: number=5000): Promise { + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), time); + + request.signal ??= controller.signal; + + try { + return await defaultFetch(url, request);; + } finally { + clearTimeout(timeout); + } +} \ No newline at end of file diff --git a/packages/utils/floatKorean.ts b/packages/utils/floatKorean.ts new file mode 100644 index 0000000..971a3be --- /dev/null +++ b/packages/utils/floatKorean.ts @@ -0,0 +1,16 @@ +export default class FloatKorean { + static Digits = [ + "영", "일", "이", "삼", "사", "오", "육", "칠", "팔", "구" + ]; + static convert(num: string): string { + const buf = new Array(num.length); + for (let idx = 0; idx < num.length; idx++) { + if (num[idx] == ".") { + buf[idx] = "쩜"; + } else { + buf[idx] = this.Digits[+num[idx]]; + } + } + return buf.join(""); + } +} \ No newline at end of file diff --git a/packages/utils/integerKorean.ts b/packages/utils/integerKorean.ts new file mode 100644 index 0000000..7ac0347 --- /dev/null +++ b/packages/utils/integerKorean.ts @@ -0,0 +1,109 @@ +export default class IntegerKorean { + static DigitName = [ "영", "일", "이", "삼", "사", "오", "육", "칠", "팔", "구" ]; + static DigitModifier = ["", "십", "백", "천"]; + static Unit = [ "", "만", "억", "조", "경", "해", "자", "양", "구", "간", "정", "재", "극", "항하사", "아승기", "나유타", "불가사의", "무량대수" ]; + + private static stringifyKDigits( + first: number, second: number, third: number, forth: number + ): string { + const buf = []; + + if (forth) { + if (forth >= 2) buf.push(this.DigitName[forth]); + buf.push(this.DigitModifier[3]); + } + if (third) { + if (third >= 2) buf.push(this.DigitName[third]); + buf.push(this.DigitModifier[2]); + } + if (second) { + if (second >= 2) buf.push(this.DigitName[second]); + buf.push(this.DigitModifier[1]); + } + if (first || (!forth && !third && !second)) { + buf.push(this.DigitName[first]); + } + + return buf.join(""); + } + private static parseKDigitsFromNumber(num: number): string { + const first = num % 10; + const second = Math.floor(num / 10) % 10; + const third = Math.floor(num / 100) % 10; + const forth = Math.floor(num / 1000) % 10; + + return this.stringifyKDigits(first, second, third, forth); + } + private static parseKDigitsFromString(num: string, offset: number): string { + const first = +num[offset]; + const second = offset >= 1 ? +num[offset - 1] : 0; + const third = offset >= 2 ? +num[offset - 2] : 0; + const forth = offset >= 3 ? +num[offset - 3] : 0; + + return this.stringifyKDigits(first, second, third, forth); + } + + static convertFromString(num: string): string { + let isNegative = false; + if (num.startsWith("-")) { + num = num.slice(1, -1); + isNegative = true; + } + if (num == "0") { + return isNegative ? "마이너스영" : "영"; + } + + const unitStack = []; + let offset = num.length - 1; + while (offset >= 0) { + unitStack.push(this.parseKDigitsFromString(num, offset)); + offset -= 4; + } + + const buf = []; + if (isNegative) buf.push("마이너스"); + for (let i = unitStack.length - 1; i >= 0; i--) { + const currUnit = this.Unit[i]; + let currKDigits = unitStack[i]; + + if (currKDigits == "영") continue; + if (i == 1 && currKDigits == "일") + currKDigits = ""; + + buf.push(currKDigits + currUnit); + } + + return buf.join(""); + } + static convertFromNumber(num: number): string { + let isNegative = false; + if (num < 0) { + isNegative = true; + num *= -1; + } + if (num == 0) { + return "영"; + } + + const unitStack = []; + while (num) { + unitStack.push(this.parseKDigitsFromNumber(num)); + num = Math.floor(num / 10000); + } + + const buf = []; + if (isNegative) buf.push("마이너스"); + for (let i = unitStack.length - 1; i >= 0; i--) { + const currUnit = this.Unit[i]; + let currKDigits = unitStack[i]; + + if (currKDigits == "영") continue; + if (i == 1 && currKDigits == "일") + currKDigits = ""; + + buf.push(currKDigits + currUnit); + } + + return buf.join(""); + } +} diff --git a/packages/utils/nyaize.ts b/packages/utils/nyaize.ts new file mode 100644 index 0000000..1a200bb --- /dev/null +++ b/packages/utils/nyaize.ts @@ -0,0 +1,137 @@ +export const nyaWords = { + '나': "냐", + '낙': "냑", + '낚': "냒", + '낛': "냓", + '난': "냔", + '낝': "냕", + '낞': "냖", + '낟': "냗", + '날': "냘", + '낡': "냙", + '낢': "냚", + '낣': "냛", + '낤': "냜", + '낥': "냝", + '낦': "냞", + '낧': "냟", + '남': "냠", + '납': "냡", + '낪': "냢", + '낫': "냣", + '났': "냤", + '낭': "냥", + '낮': "냦", + '낯': "냧", + '낰': "냨", + '낱': "냩", + '낲': "냪", + '낳': "냫", +}; + +export const nyaWords2 = { + '내': "냥", + '넹': "냥", + '넴': "냥", + '넵': "냥", + '냐': "냥", + '님': "냥", + '니': "냥", + '다': "다냥", + '까': "까냥", + '네': "네냥", + '야': "야냥", + '꺼': "꺼냥", + '래': "래냥", + '해': "해냥", + '지': "지냥", + '라': "라냥", + '요': "요냥", + '가': "가냥", + '데': "데냥", + '돼': "돼냥", + '줘': "줘냥", + '마': "마냥", + '와': "와냥", + '어': "어냥", + '자': "자냥", + '죠': "죠냥", + '서': "서냥", + '게': "게냥", +}; + +function replacePunctuation(input: string): string { + return input.replace(/(^|\s)([?!,.;~^@()]+)/g, (match, p1, p2) => { + const firstChar = p2[0]; + let transformed; + + if (firstChar === '?') transformed = '냥?'; + else if (firstChar === '!') transformed = '냥!'; + else if (firstChar === ',') transformed = '냥,'; + else if (firstChar === '.') transformed = '냥.'; + else if (firstChar === ';') transformed = '냥;'; + else if (firstChar === '~') transformed = '냥~'; + else if (firstChar === '^') transformed = '냥^'; + else if (firstChar === '@') transformed = '냥@'; + else if (firstChar === '(') transformed = '냥('; + else if (firstChar === ')') transformed = '냥)'; + else transformed = p2; + + return p1 + transformed + p2.slice(1); + }); +} + +function addNyangAtMWord(sentence: string): string { + return sentence.split(' ').map((word) => { + const match = word.match(/^([가-힣]+)([?!,.;~^@()]*)$/); + + if (!match) return word; + + const baseWord = match[1]; + const punctuation = match[2]; + + const lastChar = baseWord[baseWord.length - 1]; + const charCode = lastChar.charCodeAt(0); + + if (charCode >= 0xAC00 && charCode <= 0xD7A3) { + const baseCode = charCode - 0xAC00; + const jongseong = baseCode % 28; + + if (jongseong === 16) { + return baseWord + "냥" + punctuation; + } + } + + return word; + }).join(' '); +} + +export function nyaize(text: string): string { + for (let key in nyaWords2) { + text = text.replaceAll(key + ".", nyaWords2[key as keyof typeof nyaWords2] + "."); // yeah I gotta optimize these + text = text.replaceAll(key + ",", nyaWords2[key as keyof typeof nyaWords2] + ","); + text = text.replaceAll(key + "?", nyaWords2[key as keyof typeof nyaWords2] + "?"); + text = text.replaceAll(key + "!", nyaWords2[key as keyof typeof nyaWords2] + "!"); + text = text.replaceAll(key + ";", nyaWords2[key as keyof typeof nyaWords2] + ";"); + text = text.replaceAll(key + "~", nyaWords2[key as keyof typeof nyaWords2] + "~"); + text = text.replaceAll(key + "^", nyaWords2[key as keyof typeof nyaWords2] + "^"); + text = text.replaceAll(key + "@", nyaWords2[key as keyof typeof nyaWords2] + "@"); + text = text.replaceAll(key + "(", nyaWords2[key as keyof typeof nyaWords2] + "("); + text = text.replaceAll(key + ")", nyaWords2[key as keyof typeof nyaWords2] + ")"); + text = text.replaceAll(key + " ", nyaWords2[key as keyof typeof nyaWords2] + " "); + + if (text.endsWith(key)) { + text = text.slice(0, -1) + nyaWords2[key as keyof typeof nyaWords2]; + } + } + + for (let key in nyaWords) { + text = text.replaceAll(key, nyaWords[key as keyof typeof nyaWords]); + } + + text = replacePunctuation(text); + + text = addNyangAtMWord(text); + + return text; +} \ No newline at end of file diff --git a/packages/utils/outputHandler.ts b/packages/utils/outputHandler.ts new file mode 100644 index 0000000..fcd20ac --- /dev/null +++ b/packages/utils/outputHandler.ts @@ -0,0 +1,40 @@ +import { dirname, join } from "path"; +import { mkdir, open, readFile } from "fs/promises" + +export namespace OutputHandler { + export const LogCachePath = join( + process.cwd(), + "cache", + "log", + ); + export const ErrorLogPath = join(LogCachePath, "error.log" ); + export function getErrorOutput(...args: any[]) { + const timestamp = new Date().toISOString(); + + const message = args + .map(arg => { + if (arg instanceof Error) { + return `${arg.name}: ${arg.message}\n${arg.stack}`; + } + if (typeof arg === 'object') { + return JSON.stringify(arg); + } + return String(arg); + }) + .join(' '); + + + return `[${timestamp}] ${message}`; + } + export async function errorLog(...args: any[]): Promise { + const output = getErrorOutput(...args); + await mkdir(dirname(ErrorLogPath), { recursive: true }); + + const fileHandle = await open(ErrorLogPath, "a"); + fileHandle.write(output + "\n"); + fileHandle.close(); + } + export async function getErrorLog(): Promise { + return (await readFile(ErrorLogPath)).toString(); + } +} diff --git a/packages/utils/requireDirectory.ts b/packages/utils/requireDirectory.ts new file mode 100644 index 0000000..8009d90 --- /dev/null +++ b/packages/utils/requireDirectory.ts @@ -0,0 +1,13 @@ +import { readdirSync } from "fs"; +import { readdir } from "fs/promises"; +import { join } from "path"; + +export async function requireDirectory(directory: string): Promise { + const requireFiles = (await readdir(directory)).filter(file => file.endsWith(".js")); + return requireFiles.map(file => require(join(directory, file)).default as T); +} + +export function requireDirectorySync(directory: string): T[] { + const requireFiles = readdirSync(directory).filter(file => file.endsWith(".js")); + return requireFiles.map(file => require(join(directory, file)).default as T).filter(x=>x); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..64a6045 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2305 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@discordjs/opus': + specifier: ^0.10.0 + version: 0.10.0 + '@discordjs/voice': + specifier: ^0.19.0 + version: 0.19.0(@discordjs/opus@0.10.0)(ffmpeg-static@5.3.0)(opusscript@0.0.8) + '@prisma/adapter-pg': + specifier: ^7.2.0 + version: 7.2.0 + '@prisma/client': + specifier: ^7.2.0 + version: 7.2.0(prisma@7.2.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3) + '@snazzah/davey': + specifier: ^0.1.9 + version: 0.1.9 + discord.js: + specifier: ^14.25.1 + version: 14.25.1 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + fastify: + specifier: ^5.7.1 + version: 5.7.1 + ffprobe-static: + specifier: ^3.1.0 + version: 3.1.0 + libsodium-wrappers: + specifier: ^0.8.0 + version: 0.8.0 + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 + opusscript: + specifier: ^0.0.8 + version: 0.0.8 + pg: + specifier: ^8.17.1 + version: 8.17.1 + play-dl: + specifier: ^1.9.7 + version: 1.9.7 + pnpm: + specifier: ^10.28.0 + version: 10.28.0 + prism-media: + specifier: ^1.3.5 + version: 1.3.5(@discordjs/opus@0.10.0)(ffmpeg-static@5.3.0)(opusscript@0.0.8) + prisma: + specifier: ^7.2.0 + version: 7.2.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + devDependencies: + '@types/ffprobe-static': + specifier: ^2.0.3 + version: 2.0.3 + '@types/node': + specifier: 25.0.9 + version: 25.0.9 + '@types/pg': + specifier: ^8.16.0 + version: 8.16.0 + +packages: + + '@chevrotain/cst-dts-gen@10.5.0': + resolution: {integrity: sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==} + + '@chevrotain/gast@10.5.0': + resolution: {integrity: sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==} + + '@chevrotain/types@10.5.0': + resolution: {integrity: sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==} + + '@chevrotain/utils@10.5.0': + resolution: {integrity: sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==} + + '@derhuerst/http-basic@8.2.4': + resolution: {integrity: sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==} + engines: {node: '>=6.0.0'} + + '@discordjs/builders@1.13.1': + resolution: {integrity: sha512-cOU0UDHc3lp/5nKByDxkmRiNZBpdp0kx55aarbiAfakfKJHlxv/yFW1zmIqCAmwH5CRlrH9iMFKJMpvW4DPB+w==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@1.5.3': + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@2.1.1': + resolution: {integrity: sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==} + engines: {node: '>=18'} + + '@discordjs/formatters@0.6.2': + resolution: {integrity: sha512-y4UPwWhH6vChKRkGdMB4odasUbHOUwy7KL+OVwF86PvT6QVOwElx+TiI1/6kcmcEe+g5YRXJFiXSXUdabqZOvQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/node-pre-gyp@0.4.5': + resolution: {integrity: sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==} + hasBin: true + + '@discordjs/opus@0.10.0': + resolution: {integrity: sha512-HHEnSNrSPmFEyndRdQBJN2YE6egyXS9JUnJWyP6jficK0Y+qKMEZXyYTgmzpjrxXP1exM/hKaNP7BRBUEWkU5w==} + engines: {node: '>=12.0.0'} + + '@discordjs/rest@2.6.0': + resolution: {integrity: sha512-RDYrhmpB7mTvmCKcpj+pc5k7POKszS4E2O9TYc+U+Y4iaCP+r910QdO43qmpOja8LRr1RJ0b3U+CqVsnPqzf4w==} + engines: {node: '>=18'} + + '@discordjs/util@1.2.0': + resolution: {integrity: sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg==} + engines: {node: '>=18'} + + '@discordjs/voice@0.19.0': + resolution: {integrity: sha512-UyX6rGEXzVyPzb1yvjHtPfTlnLvB5jX/stAMdiytHhfoydX+98hfympdOwsnTktzr+IRvphxTbdErgYDJkEsvw==} + engines: {node: '>=22.12.0'} + + '@discordjs/ws@1.2.3': + resolution: {integrity: sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw==} + engines: {node: '>=16.11.0'} + + '@electric-sql/pglite-socket@0.0.6': + resolution: {integrity: sha512-6RjmgzphIHIBA4NrMGJsjNWK4pu+bCWJlEWlwcxFTVY3WT86dFpKwbZaGWZV6C5Rd7sCk1Z0CI76QEfukLAUXw==} + hasBin: true + peerDependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite-tools@0.2.7': + resolution: {integrity: sha512-9dAccClqxx4cZB+Ar9B+FZ5WgxDc/Xvl9DPrTWv+dYTf0YNubLzi4wHHRGRGhrJv15XwnyKcGOZAP1VXSneSUg==} + peerDependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite@0.3.2': + resolution: {integrity: sha512-zfWWa+V2ViDCY/cmUfRqeWY1yLto+EpxjXnZzenB1TyxsTiXaTWeZFIZw6mac52BsuQm0RjCnisjBtdBaXOI6w==} + + '@emnapi/core@1.8.1': + resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==} + + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} + + '@emnapi/wasi-threads@1.1.0': + resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + + '@fastify/ajv-compiler@4.0.5': + resolution: {integrity: sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==} + + '@fastify/error@4.2.0': + resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==} + + '@fastify/fast-json-stringify-compiler@5.0.3': + resolution: {integrity: sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==} + + '@fastify/forwarded@3.0.1': + resolution: {integrity: sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==} + + '@fastify/merge-json-schemas@0.2.1': + resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} + + '@fastify/proxy-addr@5.1.0': + resolution: {integrity: sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==} + + '@hono/node-server@1.19.6': + resolution: {integrity: sha512-Shz/KjlIeAhfiuE93NDKVdZ7HdBVLQAfdbaXEaoAVO3ic9ibRSLGIQGkcBbFyuLr+7/1D5ZCINM8B+6IvXeMtw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@mrleebo/prisma-ast@0.12.1': + resolution: {integrity: sha512-JwqeCQ1U3fvccttHZq7Tk0m/TMC6WcFAQZdukypW3AzlJYKYTGNVd1ANU2GuhKnv4UQuOFj3oAl0LLG/gxFN1w==} + engines: {node: '>=16'} + + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + + '@pinojs/redact@0.4.0': + resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + + '@prisma/adapter-pg@7.2.0': + resolution: {integrity: sha512-euIdQ13cRB2wZ3jPsnDnFhINquo1PYFPCg6yVL8b2rp3EdinQHsX9EDdCtRr489D5uhphcRk463OdQAFlsCr0w==} + + '@prisma/client-runtime-utils@7.2.0': + resolution: {integrity: sha512-dn7oB53v0tqkB0wBdMuTNFNPdEbfICEUe82Tn9FoKAhJCUkDH+fmyEp0ClciGh+9Hp2Tuu2K52kth2MTLstvmA==} + + '@prisma/client@7.2.0': + resolution: {integrity: sha512-JdLF8lWZ+LjKGKpBqyAlenxd/kXjd1Abf/xK+6vUA7R7L2Suo6AFTHFRpPSdAKCan9wzdFApsUpSa/F6+t1AtA==} + engines: {node: ^20.19 || ^22.12 || >=24.0} + peerDependencies: + prisma: '*' + typescript: '>=5.4.0' + peerDependenciesMeta: + prisma: + optional: true + typescript: + optional: true + + '@prisma/config@7.2.0': + resolution: {integrity: sha512-qmvSnfQ6l/srBW1S7RZGfjTQhc44Yl3ldvU6y3pgmuLM+83SBDs6UQVgMtQuMRe9J3gGqB0RF8wER6RlXEr6jQ==} + + '@prisma/debug@6.8.2': + resolution: {integrity: sha512-4muBSSUwJJ9BYth5N8tqts8JtiLT8QI/RSAzEogwEfpbYGFo9mYsInsVo8dqXdPO2+Rm5OG5q0qWDDE3nyUbVg==} + + '@prisma/debug@7.2.0': + resolution: {integrity: sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==} + + '@prisma/dev@0.17.0': + resolution: {integrity: sha512-6sGebe5jxX+FEsQTpjHLzvOGPn6ypFQprcs3jcuIWv1Xp/5v6P/rjfdvAwTkP2iF6pDx2tCd8vGLNWcsWzImTA==} + + '@prisma/driver-adapter-utils@7.2.0': + resolution: {integrity: sha512-gzrUcbI9VmHS24Uf+0+7DNzdIw7keglJsD5m/MHxQOU68OhGVzlphQRobLiDMn8CHNA2XN8uugwKjudVtnfMVQ==} + + '@prisma/engines-version@7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3': + resolution: {integrity: sha512-KezsjCZDsbjNR7SzIiVlUsn9PnLePI7r5uxABlwL+xoerurZTfgQVbIjvjF2sVr3Uc0ZcsnREw3F84HvbggGdA==} + + '@prisma/engines@7.2.0': + resolution: {integrity: sha512-HUeOI/SvCDsHrR9QZn24cxxZcujOjcS3w1oW/XVhnSATAli5SRMOfp/WkG3TtT5rCxDA4xOnlJkW7xkho4nURA==} + + '@prisma/fetch-engine@7.2.0': + resolution: {integrity: sha512-Z5XZztJ8Ap+wovpjPD2lQKnB8nWFGNouCrglaNFjxIWAGWz0oeHXwUJRiclIoSSXN/ptcs9/behptSk8d0Yy6w==} + + '@prisma/get-platform@6.8.2': + resolution: {integrity: sha512-vXSxyUgX3vm1Q70QwzwkjeYfRryIvKno1SXbIqwSptKwqKzskINnDUcx85oX+ys6ooN2ATGSD0xN2UTfg6Zcow==} + + '@prisma/get-platform@7.2.0': + resolution: {integrity: sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA==} + + '@prisma/query-plan-executor@6.18.0': + resolution: {integrity: sha512-jZ8cfzFgL0jReE1R10gT8JLHtQxjWYLiQ//wHmVYZ2rVkFHoh0DT8IXsxcKcFlfKN7ak7k6j0XMNn2xVNyr5cA==} + + '@prisma/studio-core@0.9.0': + resolution: {integrity: sha512-xA2zoR/ADu/NCSQuriBKTh6Ps4XjU0bErkEcgMfnSGh346K1VI7iWKnoq1l2DoxUqiddPHIEWwtxJ6xCHG6W7g==} + peerDependencies: + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@sapphire/async-queue@1.5.5': + resolution: {integrity: sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/shapeshift@4.0.0': + resolution: {integrity: sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==} + engines: {node: '>=v16'} + + '@sapphire/snowflake@3.5.3': + resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@snazzah/davey-android-arm-eabi@0.1.9': + resolution: {integrity: sha512-Dq0WyeVGBw+uQbisV/6PeCQV2ndJozfhZqiNIfQxu6ehIdXB7iHILv+oY+AQN2n+qxiFmLh/MOX9RF+pIWdPbA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [android] + + '@snazzah/davey-android-arm64@0.1.9': + resolution: {integrity: sha512-OE16OZjv7F/JrD7Mzw5eL2gY2vXRPC8S7ZrmkcMyz/sHHJsGHlT+L7X5s56Bec1YDTVmzAsH4UBuvVBoXuIWEQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@snazzah/davey-darwin-arm64@0.1.9': + resolution: {integrity: sha512-z7oORvAPExikFkH6tvHhbUdZd77MYZp9VqbCpKEiI+sisWFVXgHde7F7iH3G4Bz6gUYJfgvKhWXiDRc+0SC4dg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@snazzah/davey-darwin-x64@0.1.9': + resolution: {integrity: sha512-f1LzGyRGlM414KpXml3OgWVSd7CgylcdYaFj/zDBb8bvWjxyvsI9iMeuPfe/cduloxRj8dELde/yCDZtFR6PdQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@snazzah/davey-freebsd-x64@0.1.9': + resolution: {integrity: sha512-k6p3JY2b8rD6j0V9Ql7kBUMR4eJdcpriNwiHltLzmtGuz/nK5RGQdkEP68gTLc+Uj3xs5Cy0jRKmv2xJQBR4sA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@snazzah/davey-linux-arm-gnueabihf@0.1.9': + resolution: {integrity: sha512-xDaAFUC/1+n/YayNwKsqKOBMuW0KI6F0SjgWU+krYTQTVmAKNjOM80IjemrVoqTpBOxBsT80zEtct2wj11CE3Q==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@snazzah/davey-linux-arm64-gnu@0.1.9': + resolution: {integrity: sha512-t1VxFBzWExPNpsNY/9oStdAAuHqFvwZvIO2YPYyVNstxfi2KmAbHMweHUW7xb2ppXuhVQZ4VGmmeXiXcXqhPBw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@snazzah/davey-linux-arm64-musl@0.1.9': + resolution: {integrity: sha512-Xvlr+nBPzuFV4PXHufddlt08JsEyu0p8mX2DpqdPxdpysYIH4I8V86yJiS4tk04a6pLBDd8IxTbBwvXJKqd/LQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@snazzah/davey-linux-x64-gnu@0.1.9': + resolution: {integrity: sha512-6Uunc/NxiEkg1reroAKZAGfOtjl1CGa7hfTTVClb2f+DiA8ZRQWBh+3lgkq/0IeL262B4F14X8QRv5Bsv128qw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@snazzah/davey-linux-x64-musl@0.1.9': + resolution: {integrity: sha512-fFQ/n3aWt1lXhxSdy+Ge3gi5bR3VETMVsWhH0gwBALUKrbo3ZzgSktm4lNrXE9i0ncMz/CDpZ5i0wt/N3XphEQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@snazzah/davey-wasm32-wasi@0.1.9': + resolution: {integrity: sha512-xWvzej8YCVlUvzlpmqJMIf0XmLlHqulKZ2e7WNe2TxQmsK+o0zTZqiQYs2MwaEbrNXBhYlHDkdpuwoXkJdscNQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@snazzah/davey-win32-arm64-msvc@0.1.9': + resolution: {integrity: sha512-sTqry/DfltX2OdW1CTLKa3dFYN5FloAEb2yhGsY1i5+Bms6OhwByXfALvyMHYVo61Th2+sD+9BJpQffHFKDA3w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@snazzah/davey-win32-ia32-msvc@0.1.9': + resolution: {integrity: sha512-twD3LwlkGnSwphsCtpGb5ztpBIWEvGdc0iujoVkdzZ6nJiq5p8iaLjJMO4hBm9h3s28fc+1Qd7AMVnagiOasnA==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@snazzah/davey-win32-x64-msvc@0.1.9': + resolution: {integrity: sha512-eMnXbv4GoTngWYY538i/qHz2BS+RgSXFsvKltPzKqnqzPzhQZIY7TemEJn3D5yWGfW4qHve9u23rz93FQqnQMA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@snazzah/davey@0.1.9': + resolution: {integrity: sha512-vNZk5y+IsxjwzTAXikvzz5pqMLb35YytC64nVF2MAFVhjpXu9ITOKUriZ0JG/llwzCAi56jb5x0cXDRIyE2A2A==} + engines: {node: '>= 10'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/ffprobe-static@2.0.3': + resolution: {integrity: sha512-86Q8dIzhjknxA6935ZcVLkVU3t6bP+F08mdriWZk2+3UqjxIbT3QEADjbO5Yq8826cVs/aZBREVZ7jUoSTgHiw==} + + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + + '@types/node@25.0.9': + resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} + + '@types/pg@8.16.0': + resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==} + + '@types/react@19.2.8': + resolution: {integrity: sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@vladfrangu/async_event_emitter@2.4.7': + resolution: {integrity: sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + abstract-logging@2.0.1: + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + avvio@9.1.0: + resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} + + aws-ssl-profiles@1.1.2: + resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} + engines: {node: '>= 6.0.0'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + c12@3.1.0: + resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + chevrotain@10.5.0: + resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deepmerge-ts@7.1.5: + resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + engines: {node: '>=16.0.0'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + discord-api-types@0.38.37: + resolution: {integrity: sha512-Cv47jzY1jkGkh5sv0bfHYqGgKOWO1peOrGMkDFM4UmaGMOTgOW8QSexhvixa9sVOiz8MnVOBryWYyw/CEVhj7w==} + + discord.js@14.25.1: + resolution: {integrity: sha512-2l0gsPOLPs5t6GFZfQZKnL1OJNYFcuC/ETWsW4VtKVD/tg4ICa9x+jb9bkPffkMdRpRpuUaO/fKkHCBeiCKh8g==} + engines: {node: '>=18'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + effect@3.18.4: + resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + + fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stringify@6.2.0: + resolution: {integrity: sha512-Eaf/KNIDwHkzfyeQFNfLXJnQ7cl1XQI3+zRqmPlvtkMigbXnAcasTrvJQmquBSxKfFGeRA6PFog8t+hFmpDoWw==} + + fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastify@5.7.1: + resolution: {integrity: sha512-ZW7S4fxlZhE+tYWVokFzjh+i56R+buYKNGhrVl6DtN8sxkyMEzpJnzvO8A/ZZrsg5w6X37u6I4EOQikYS5DXpA==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + ffmpeg-static@5.3.0: + resolution: {integrity: sha512-H+K6sW6TiIX6VGend0KQwthe+kaceeH/luE8dIZyOP35ik7ahYojDuqlTV1bOrtEwl01sy2HFNGQfi5IDJvotg==} + engines: {node: '>=16'} + + ffprobe-static@3.1.0: + resolution: {integrity: sha512-Dvpa9uhVMOYivhHKWLGDoa512J751qN1WZAIO+Xw4L/mrUSPxS4DApzSUDbCFE/LUq2+xYnznEahTd63AqBSpA==} + + find-my-way@9.4.0: + resolution: {integrity: sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==} + engines: {node: '>=20'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + + get-port-please@3.1.2: + resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + grammex@3.1.12: + resolution: {integrity: sha512-6ufJOsSA7LcQehIJNCO7HIBykfM7DXQual0Ny780/DEcJIpBlHRvcqEBWGPYd7hrXL2GJ3oJI1MIhaXjWmLQOQ==} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + hono@4.10.6: + resolution: {integrity: sha512-BIdolzGpDO9MQ4nu3AUuDwHZZ+KViNm+EZ75Ae55eMXMqLVhDFqEMXxtUe9Qh8hjL+pIna/frs2j6Y2yD5Ua/g==} + engines: {node: '>=16.9.0'} + + http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + json-schema-ref-resolver@3.0.0: + resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + libsodium-wrappers@0.8.0: + resolution: {integrity: sha512-PVyXAtP1nmpQrDKAVnA8pir0f7bj7vmMGs7mb+0OCSJ+BOfLNBb5hPy2GHfrx6cQ+Co9fMliR5R0WRbVuMllNA==} + + libsodium@0.8.0: + resolution: {integrity: sha512-GQ4Sg0/Z0Ui6ZvKeTd8bH7VAAqk1ZHZDAo/pcuSi0uPbIN6LYAAotR0GEYb8v+y4/tSsXZPr06D6hhqKd7tnoQ==} + + light-my-request@6.6.0: + resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + lru.min@1.1.3: + resolution: {integrity: sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q==} + engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} + + magic-bytes.js@1.12.1: + resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mysql2@3.15.3: + resolution: {integrity: sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==} + engines: {node: '>= 8.0'} + + named-placeholders@1.1.6: + resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} + engines: {node: '>=8.0.0'} + + node-addon-api@8.5.0: + resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} + engines: {node: ^18 || ^20 || >= 21} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + nypm@0.6.2: + resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + opusscript@0.0.8: + resolution: {integrity: sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==} + + parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + pg-cloudflare@1.3.0: + resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + + pg-connection-string@2.10.0: + resolution: {integrity: sha512-ur/eoPKzDx2IjPaYyXS6Y8NSblxM7X64deV2ObV57vhjsWiwLvUD6meukAzogiOsu60GO8m/3Cb6FdJsWNjwXg==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.11.0: + resolution: {integrity: sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.11.0: + resolution: {integrity: sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.17.1: + resolution: {integrity: sha512-EIR+jXdYNSMOrpRp7g6WgQr7SaZNZfS7IzZIO0oTNEeibq956JxeD15t3Jk3zZH0KH8DmOIx38qJfQenoE8bXQ==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + + pino-abstract-transport@3.0.0: + resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} + + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + + pino@10.2.0: + resolution: {integrity: sha512-NFnZqUliT+OHkRXVSf8vdOr13N1wv31hRryVjqbreVh/SDCNaI6mnRDDq89HVRCbem1SAl7yj04OANeqP0nT6A==} + hasBin: true + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + play-audio@0.5.2: + resolution: {integrity: sha512-ZAqHUKkQLix2Iga7pPbsf1LpUoBjcpwU93F1l3qBIfxYddQLhxS6GKmS0d3jV8kSVaUbr6NnOEcEMFvuX93SWQ==} + + play-dl@1.9.7: + resolution: {integrity: sha512-KpgerWxUCY4s9Mhze2qdqPhiqd8Ve6HufpH9mBH3FN+vux55qSh6WJKDabfie8IBHN7lnrAlYcT/UdGax58c2A==} + engines: {node: '>=16.0.0'} + + pnpm@10.28.0: + resolution: {integrity: sha512-Bd9x0UIfITmeBT/eVnzqNNRG+gLHZXFEG/wceVbpjjYwiJgtlARl/TRIDU2QoGaLwSNi+KqIAApk6D0LDke+SA==} + engines: {node: '>=18.12'} + hasBin: true + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-array@3.0.4: + resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==} + engines: {node: '>=12'} + + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + postgres@3.4.7: + resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} + engines: {node: '>=12'} + + prism-media@1.3.5: + resolution: {integrity: sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==} + peerDependencies: + '@discordjs/opus': '>=0.8.0 <1.0.0' + ffmpeg-static: ^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0 + node-opus: ^0.3.3 + opusscript: ^0.0.8 + peerDependenciesMeta: + '@discordjs/opus': + optional: true + ffmpeg-static: + optional: true + node-opus: + optional: true + opusscript: + optional: true + + prisma@7.2.0: + resolution: {integrity: sha512-jSdHWgWOgFF24+nRyyNRVBIgGDQEsMEF8KPHvhBBg3jWyR9fUAK0Nq9ThUmiGlNgq2FA7vSk/ZoCvefod+a8qg==} + engines: {node: ^20.19 || ^22.12 || >=24.0} + hasBin: true + peerDependencies: + better-sqlite3: '>=9.0.0' + typescript: '>=5.4.0' + peerDependenciesMeta: + better-sqlite3: + optional: true + typescript: + optional: true + + process-warning@4.0.1: + resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} + + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + react-dom@19.2.3: + resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==} + peerDependencies: + react: ^19.2.3 + + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} + engines: {node: '>=0.10.0'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + + regexp-to-ast@0.5.0: + resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} + + remeda@2.21.3: + resolution: {integrity: sha512-XXrZdLA10oEOQhLLzEJEiFFSKi21REGAkHdImIb4rt/XXy8ORGXh5HCcpUOsElfPNDb+X6TA/+wkh+p2KffYmg==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + ret@0.5.0: + resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} + engines: {node: '>=10'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex2@5.0.0: + resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + secure-json-parse@4.1.0: + resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + seq-queue@0.0.5: + resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + 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'} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sqlstring@2.3.3: + resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} + engines: {node: '>= 0.6'} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + thread-stream@4.0.0: + resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==} + engines: {node: '>=20'} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + toad-cache@3.7.0: + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} + engines: {node: '>=12'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@6.21.3: + resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} + engines: {node: '>=18.17'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + valibot@1.2.0: + resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + zeptomatch@2.0.2: + resolution: {integrity: sha512-H33jtSKf8Ijtb5BW6wua3G5DhnFjbFML36eFu+VdOoVY4HD9e7ggjqdM6639B+L87rjnR6Y+XeRzBXZdy52B/g==} + +snapshots: + + '@chevrotain/cst-dts-gen@10.5.0': + dependencies: + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/gast@10.5.0': + dependencies: + '@chevrotain/types': 10.5.0 + lodash: 4.17.21 + + '@chevrotain/types@10.5.0': {} + + '@chevrotain/utils@10.5.0': {} + + '@derhuerst/http-basic@8.2.4': + dependencies: + caseless: 0.12.0 + concat-stream: 2.0.0 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 + optional: true + + '@discordjs/builders@1.13.1': + dependencies: + '@discordjs/formatters': 0.6.2 + '@discordjs/util': 1.2.0 + '@sapphire/shapeshift': 4.0.0 + discord-api-types: 0.38.37 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.4 + tslib: 2.8.1 + + '@discordjs/collection@1.5.3': {} + + '@discordjs/collection@2.1.1': {} + + '@discordjs/formatters@0.6.2': + dependencies: + discord-api-types: 0.38.37 + + '@discordjs/node-pre-gyp@0.4.5': + dependencies: + detect-libc: 2.1.2 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.3 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@discordjs/opus@0.10.0': + dependencies: + '@discordjs/node-pre-gyp': 0.4.5 + node-addon-api: 8.5.0 + transitivePeerDependencies: + - encoding + - supports-color + + '@discordjs/rest@2.6.0': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/util': 1.2.0 + '@sapphire/async-queue': 1.5.5 + '@sapphire/snowflake': 3.5.3 + '@vladfrangu/async_event_emitter': 2.4.7 + discord-api-types: 0.38.37 + magic-bytes.js: 1.12.1 + tslib: 2.8.1 + undici: 6.21.3 + + '@discordjs/util@1.2.0': + dependencies: + discord-api-types: 0.38.37 + + '@discordjs/voice@0.19.0(@discordjs/opus@0.10.0)(ffmpeg-static@5.3.0)(opusscript@0.0.8)': + dependencies: + '@types/ws': 8.18.1 + discord-api-types: 0.38.37 + prism-media: 1.3.5(@discordjs/opus@0.10.0)(ffmpeg-static@5.3.0)(opusscript@0.0.8) + tslib: 2.8.1 + ws: 8.19.0 + transitivePeerDependencies: + - '@discordjs/opus' + - bufferutil + - ffmpeg-static + - node-opus + - opusscript + - utf-8-validate + + '@discordjs/ws@1.2.3': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/rest': 2.6.0 + '@discordjs/util': 1.2.0 + '@sapphire/async-queue': 1.5.5 + '@types/ws': 8.18.1 + '@vladfrangu/async_event_emitter': 2.4.7 + discord-api-types: 0.38.37 + tslib: 2.8.1 + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@electric-sql/pglite-socket@0.0.6(@electric-sql/pglite@0.3.2)': + dependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite-tools@0.2.7(@electric-sql/pglite@0.3.2)': + dependencies: + '@electric-sql/pglite': 0.3.2 + + '@electric-sql/pglite@0.3.2': {} + + '@emnapi/core@1.8.1': + dependencies: + '@emnapi/wasi-threads': 1.1.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@fastify/ajv-compiler@4.0.5': + dependencies: + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-uri: 3.1.0 + + '@fastify/error@4.2.0': {} + + '@fastify/fast-json-stringify-compiler@5.0.3': + dependencies: + fast-json-stringify: 6.2.0 + + '@fastify/forwarded@3.0.1': {} + + '@fastify/merge-json-schemas@0.2.1': + dependencies: + dequal: 2.0.3 + + '@fastify/proxy-addr@5.1.0': + dependencies: + '@fastify/forwarded': 3.0.1 + ipaddr.js: 2.3.0 + + '@hono/node-server@1.19.6(hono@4.10.6)': + dependencies: + hono: 4.10.6 + + '@mrleebo/prisma-ast@0.12.1': + dependencies: + chevrotain: 10.5.0 + lilconfig: 2.1.0 + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@pinojs/redact@0.4.0': {} + + '@prisma/adapter-pg@7.2.0': + dependencies: + '@prisma/driver-adapter-utils': 7.2.0 + pg: 8.17.1 + postgres-array: 3.0.4 + transitivePeerDependencies: + - pg-native + + '@prisma/client-runtime-utils@7.2.0': {} + + '@prisma/client@7.2.0(prisma@7.2.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3))(typescript@5.9.3)': + dependencies: + '@prisma/client-runtime-utils': 7.2.0 + optionalDependencies: + prisma: 7.2.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3) + typescript: 5.9.3 + + '@prisma/config@7.2.0': + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.18.4 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + + '@prisma/debug@6.8.2': {} + + '@prisma/debug@7.2.0': {} + + '@prisma/dev@0.17.0(typescript@5.9.3)': + dependencies: + '@electric-sql/pglite': 0.3.2 + '@electric-sql/pglite-socket': 0.0.6(@electric-sql/pglite@0.3.2) + '@electric-sql/pglite-tools': 0.2.7(@electric-sql/pglite@0.3.2) + '@hono/node-server': 1.19.6(hono@4.10.6) + '@mrleebo/prisma-ast': 0.12.1 + '@prisma/get-platform': 6.8.2 + '@prisma/query-plan-executor': 6.18.0 + foreground-child: 3.3.1 + get-port-please: 3.1.2 + hono: 4.10.6 + http-status-codes: 2.3.0 + pathe: 2.0.3 + proper-lockfile: 4.1.2 + remeda: 2.21.3 + std-env: 3.9.0 + valibot: 1.2.0(typescript@5.9.3) + zeptomatch: 2.0.2 + transitivePeerDependencies: + - typescript + + '@prisma/driver-adapter-utils@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + + '@prisma/engines-version@7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3': {} + + '@prisma/engines@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + '@prisma/engines-version': 7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3 + '@prisma/fetch-engine': 7.2.0 + '@prisma/get-platform': 7.2.0 + + '@prisma/fetch-engine@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + '@prisma/engines-version': 7.2.0-4.0c8ef2ce45c83248ab3df073180d5eda9e8be7a3 + '@prisma/get-platform': 7.2.0 + + '@prisma/get-platform@6.8.2': + dependencies: + '@prisma/debug': 6.8.2 + + '@prisma/get-platform@7.2.0': + dependencies: + '@prisma/debug': 7.2.0 + + '@prisma/query-plan-executor@6.18.0': {} + + '@prisma/studio-core@0.9.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@types/react': 19.2.8 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + + '@sapphire/async-queue@1.5.5': {} + + '@sapphire/shapeshift@4.0.0': + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.17.21 + + '@sapphire/snowflake@3.5.3': {} + + '@snazzah/davey-android-arm-eabi@0.1.9': + optional: true + + '@snazzah/davey-android-arm64@0.1.9': + optional: true + + '@snazzah/davey-darwin-arm64@0.1.9': + optional: true + + '@snazzah/davey-darwin-x64@0.1.9': + optional: true + + '@snazzah/davey-freebsd-x64@0.1.9': + optional: true + + '@snazzah/davey-linux-arm-gnueabihf@0.1.9': + optional: true + + '@snazzah/davey-linux-arm64-gnu@0.1.9': + optional: true + + '@snazzah/davey-linux-arm64-musl@0.1.9': + optional: true + + '@snazzah/davey-linux-x64-gnu@0.1.9': + optional: true + + '@snazzah/davey-linux-x64-musl@0.1.9': + optional: true + + '@snazzah/davey-wasm32-wasi@0.1.9': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@snazzah/davey-win32-arm64-msvc@0.1.9': + optional: true + + '@snazzah/davey-win32-ia32-msvc@0.1.9': + optional: true + + '@snazzah/davey-win32-x64-msvc@0.1.9': + optional: true + + '@snazzah/davey@0.1.9': + optionalDependencies: + '@snazzah/davey-android-arm-eabi': 0.1.9 + '@snazzah/davey-android-arm64': 0.1.9 + '@snazzah/davey-darwin-arm64': 0.1.9 + '@snazzah/davey-darwin-x64': 0.1.9 + '@snazzah/davey-freebsd-x64': 0.1.9 + '@snazzah/davey-linux-arm-gnueabihf': 0.1.9 + '@snazzah/davey-linux-arm64-gnu': 0.1.9 + '@snazzah/davey-linux-arm64-musl': 0.1.9 + '@snazzah/davey-linux-x64-gnu': 0.1.9 + '@snazzah/davey-linux-x64-musl': 0.1.9 + '@snazzah/davey-wasm32-wasi': 0.1.9 + '@snazzah/davey-win32-arm64-msvc': 0.1.9 + '@snazzah/davey-win32-ia32-msvc': 0.1.9 + '@snazzah/davey-win32-x64-msvc': 0.1.9 + + '@standard-schema/spec@1.1.0': {} + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/ffprobe-static@2.0.3': {} + + '@types/node@10.17.60': + optional: true + + '@types/node@25.0.9': + dependencies: + undici-types: 7.16.0 + + '@types/pg@8.16.0': + dependencies: + '@types/node': 25.0.9 + pg-protocol: 1.11.0 + pg-types: 2.2.0 + + '@types/react@19.2.8': + dependencies: + csstype: 3.2.3 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.0.9 + + '@vladfrangu/async_event_emitter@2.4.7': {} + + abbrev@1.1.1: {} + + abstract-logging@2.0.1: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + ajv-formats@3.0.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@5.0.1: {} + + aproba@2.1.0: {} + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + atomic-sleep@1.0.0: {} + + avvio@9.1.0: + dependencies: + '@fastify/error': 4.2.0 + fastq: 1.20.1 + + aws-ssl-profiles@1.1.2: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + buffer-from@1.1.2: + optional: true + + c12@3.1.0: + dependencies: + chokidar: 4.0.3 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 16.6.1 + exsolve: 1.0.8 + giget: 2.0.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + + caseless@0.12.0: + optional: true + + chevrotain@10.5.0: + dependencies: + '@chevrotain/cst-dts-gen': 10.5.0 + '@chevrotain/gast': 10.5.0 + '@chevrotain/types': 10.5.0 + '@chevrotain/utils': 10.5.0 + lodash: 4.17.21 + regexp-to-ast: 0.5.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@2.0.0: {} + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + color-support@1.1.3: {} + + concat-map@0.0.1: {} + + concat-stream@2.0.0: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + optional: true + + confbox@0.2.2: {} + + consola@3.4.2: {} + + console-control-strings@1.1.0: {} + + cookie@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.2.3: {} + + data-uri-to-buffer@4.0.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deepmerge-ts@7.1.5: {} + + defu@6.1.4: {} + + delegates@1.0.0: {} + + denque@2.1.0: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + + detect-libc@2.1.2: {} + + discord-api-types@0.38.37: {} + + discord.js@14.25.1: + dependencies: + '@discordjs/builders': 1.13.1 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.6.2 + '@discordjs/rest': 2.6.0 + '@discordjs/util': 1.2.0 + '@discordjs/ws': 1.2.3 + '@sapphire/snowflake': 3.5.3 + discord-api-types: 0.38.37 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + magic-bytes.js: 1.12.1 + tslib: 2.8.1 + undici: 6.21.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + dotenv@16.6.1: {} + + dotenv@17.2.3: {} + + effect@3.18.4: + dependencies: + '@standard-schema/spec': 1.1.0 + fast-check: 3.23.2 + + emoji-regex@8.0.0: {} + + empathic@2.0.0: {} + + env-paths@2.2.1: + optional: true + + exsolve@1.0.8: {} + + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + + fast-decode-uri-component@1.0.1: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stringify@6.2.0: + dependencies: + '@fastify/merge-json-schemas': 0.2.1 + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-uri: 3.1.0 + json-schema-ref-resolver: 3.0.0 + rfdc: 1.4.1 + + fast-querystring@1.1.2: + dependencies: + fast-decode-uri-component: 1.0.1 + + fast-uri@3.1.0: {} + + fastify@5.7.1: + dependencies: + '@fastify/ajv-compiler': 4.0.5 + '@fastify/error': 4.2.0 + '@fastify/fast-json-stringify-compiler': 5.0.3 + '@fastify/proxy-addr': 5.1.0 + abstract-logging: 2.0.1 + avvio: 9.1.0 + fast-json-stringify: 6.2.0 + find-my-way: 9.4.0 + light-my-request: 6.6.0 + pino: 10.2.0 + process-warning: 5.0.0 + rfdc: 1.4.1 + secure-json-parse: 4.1.0 + semver: 7.7.3 + toad-cache: 3.7.0 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + ffmpeg-static@5.3.0: + dependencies: + '@derhuerst/http-basic': 8.2.4 + env-paths: 2.2.1 + https-proxy-agent: 5.0.1 + progress: 2.0.3 + transitivePeerDependencies: + - supports-color + optional: true + + ffprobe-static@3.1.0: {} + + find-my-way@9.4.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 5.0.0 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + + gauge@3.0.2: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + + get-port-please@3.1.2: {} + + giget@2.0.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.7 + nypm: 0.6.2 + pathe: 2.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + graceful-fs@4.2.11: {} + + grammex@3.1.12: {} + + has-unicode@2.0.1: {} + + hono@4.10.6: {} + + http-response-object@3.0.2: + dependencies: + '@types/node': 10.17.60 + optional: true + + http-status-codes@2.3.0: {} + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ipaddr.js@2.3.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-property@1.0.2: {} + + isexe@2.0.0: {} + + jiti@2.6.1: {} + + json-schema-ref-resolver@3.0.0: + dependencies: + dequal: 2.0.3 + + json-schema-traverse@1.0.0: {} + + libsodium-wrappers@0.8.0: + dependencies: + libsodium: 0.8.0 + + libsodium@0.8.0: {} + + light-my-request@6.6.0: + dependencies: + cookie: 1.1.1 + process-warning: 4.0.1 + set-cookie-parser: 2.7.2 + + lilconfig@2.1.0: {} + + lodash.snakecase@4.1.1: {} + + lodash@4.17.21: {} + + long@5.3.2: {} + + lru.min@1.1.3: {} + + magic-bytes.js@1.12.1: {} + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + + ms@2.1.3: {} + + mysql2@3.15.3: + dependencies: + aws-ssl-profiles: 1.1.2 + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.7.2 + long: 5.3.2 + lru.min: 1.1.3 + named-placeholders: 1.1.6 + seq-queue: 0.0.5 + sqlstring: 2.3.3 + + named-placeholders@1.1.6: + dependencies: + lru.min: 1.1.3 + + node-addon-api@8.5.0: {} + + node-domexception@1.0.0: {} + + node-fetch-native@1.6.7: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + + nypm@0.6.2: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 2.3.0 + tinyexec: 1.0.2 + + object-assign@4.1.1: {} + + ohash@2.0.11: {} + + on-exit-leak-free@2.1.2: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + opusscript@0.0.8: {} + + parse-cache-control@1.0.1: + optional: true + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + pathe@2.0.3: {} + + perfect-debounce@1.0.0: {} + + pg-cloudflare@1.3.0: + optional: true + + pg-connection-string@2.10.0: {} + + pg-int8@1.0.1: {} + + pg-pool@3.11.0(pg@8.17.1): + dependencies: + pg: 8.17.1 + + pg-protocol@1.11.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.17.1: + dependencies: + pg-connection-string: 2.10.0 + pg-pool: 3.11.0(pg@8.17.1) + pg-protocol: 1.11.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.3.0 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + pino-abstract-transport@3.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@7.1.0: {} + + pino@10.2.0: + dependencies: + '@pinojs/redact': 0.4.0 + atomic-sleep: 1.0.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 3.0.0 + pino-std-serializers: 7.1.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.0 + thread-stream: 4.0.0 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.8 + pathe: 2.0.3 + + play-audio@0.5.2: {} + + play-dl@1.9.7: + dependencies: + play-audio: 0.5.2 + + pnpm@10.28.0: {} + + postgres-array@2.0.0: {} + + postgres-array@3.0.4: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + postgres@3.4.7: {} + + prism-media@1.3.5(@discordjs/opus@0.10.0)(ffmpeg-static@5.3.0)(opusscript@0.0.8): + optionalDependencies: + '@discordjs/opus': 0.10.0 + ffmpeg-static: 5.3.0 + opusscript: 0.0.8 + + prisma@7.2.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3): + dependencies: + '@prisma/config': 7.2.0 + '@prisma/dev': 0.17.0(typescript@5.9.3) + '@prisma/engines': 7.2.0 + '@prisma/studio-core': 0.9.0(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + mysql2: 3.15.3 + postgres: 3.4.7 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - magicast + - react + - react-dom + + process-warning@4.0.1: {} + + process-warning@5.0.0: {} + + progress@2.0.3: + optional: true + + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + pure-rand@6.1.0: {} + + quick-format-unescaped@4.0.4: {} + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + + react-dom@19.2.3(react@19.2.3): + dependencies: + react: 19.2.3 + scheduler: 0.27.0 + + react@19.2.3: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@4.1.2: {} + + real-require@0.2.0: {} + + regexp-to-ast@0.5.0: {} + + remeda@2.21.3: + dependencies: + type-fest: 4.41.0 + + require-from-string@2.0.2: {} + + ret@0.5.0: {} + + retry@0.12.0: {} + + reusify@1.1.0: {} + + rfdc@1.4.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + safe-buffer@5.2.1: {} + + safe-regex2@5.0.0: + dependencies: + ret: 0.5.0 + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + scheduler@0.27.0: {} + + secure-json-parse@4.1.0: {} + + semver@6.3.1: {} + + semver@7.7.3: {} + + seq-queue@0.0.5: {} + + set-blocking@2.0.0: {} + + set-cookie-parser@2.7.2: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + split2@4.2.0: {} + + sqlstring@2.3.3: {} + + std-env@3.9.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + thread-stream@4.0.0: + dependencies: + real-require: 0.2.0 + + tinyexec@1.0.2: {} + + toad-cache@3.7.0: {} + + tr46@0.0.3: {} + + ts-mixer@6.0.4: {} + + tslib@2.8.1: {} + + type-fest@4.41.0: {} + + typedarray@0.0.6: + optional: true + + typescript@5.9.3: {} + + undici-types@7.16.0: {} + + undici@6.21.3: {} + + util-deprecate@1.0.2: {} + + valibot@1.2.0(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + wrappy@1.0.2: {} + + ws@8.19.0: {} + + xtend@4.0.2: {} + + yallist@4.0.0: {} + + zeptomatch@2.0.2: + dependencies: + grammex: 3.1.12 diff --git a/prisma.config.ts b/prisma.config.ts new file mode 100644 index 0000000..9144291 --- /dev/null +++ b/prisma.config.ts @@ -0,0 +1,14 @@ +// This file was generated by Prisma, and assumes you have installed the following: +// npm install --save-dev prisma dotenv +import "dotenv/config"; +import { defineConfig } from "prisma/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + }, + datasource: { + url: process.env["DATABASE_URL"], + }, +}); diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..5a4624a --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,34 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? +// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init + +generator client { + provider = "prisma-client" + specifying = ["prismaSchemaFolder"] + output = "../packages/db/generated/prisma" +} + +datasource db { + provider = "postgresql" +} + +enum Voice { + TypeCast + Papago +} + +model DiscordUserProfile { + id String @id @default(cuid()) + userId String @unique + voice Voice @default(Papago) + nya Boolean @default(false) + canTypecast Boolean @default(false) +} + +model DiscordGuildProfile { + id String @id @default(cuid()) + guildId String @unique + readChannel String[] @default([]) +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..75e4641 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "lib": [ "ES2021", "DOM", "DOM.Iterable" ], + "moduleResolution": "node", + "outDir": "dist", + "strict": true, + "exactOptionalPropertyTypes": false, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true + }, + "include": ["./packages/**/*"] +} \ No newline at end of file