From 2c749b33422d8b3e6ff07b0d6d4580143e2b42c4 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 01/12] =?UTF-8?q?=E3=81=AA=E3=82=93=E3=81=A8=E3=81=8B?= =?UTF-8?q?=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8736cda5..d890aee1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,4 +15,4 @@ "libsodium", "swcrc" ] -} +} \ No newline at end of file From 6c7212c62efc2a0e48f7e403dd194d1966758267 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 02/12] Add dependencies --- package.json | 1 + pnpm-lock.yaml | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/package.json b/package.json index 3347d851..4b4ea521 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "libsodium-wrappers": "^0.7.13", "lodash-es": "^4.17.21", "resolve": "^1.22.8", + "ytdl-core": "^4.11.5", "zod": "^3.22.4" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e89cdbf9..d624d15f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: resolve: specifier: ^1.22.8 version: 1.22.8 + ytdl-core: + specifier: ^4.11.5 + version: 4.11.5 zod: specifier: ^3.22.4 version: 3.22.4 @@ -2476,6 +2479,14 @@ packages: dependencies: yallist: 4.0.0 + /m3u8stream@0.8.6: + resolution: {integrity: sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==} + engines: {node: '>=12'} + dependencies: + miniget: 4.2.3 + sax: 1.3.0 + dev: false + /magic-bytes.js@1.5.0: resolution: {integrity: sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw==} dev: false @@ -2538,6 +2549,11 @@ packages: engines: {node: '>=10'} dev: true + /miniget@4.2.3: + resolution: {integrity: sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==} + engines: {node: '>=12'} + dev: false + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -2995,6 +3011,10 @@ packages: is-regex: 1.1.4 dev: true + /sax@1.3.0: + resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} + dev: false + /semver-regex@4.0.5: resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} engines: {node: '>=12'} @@ -3641,6 +3661,15 @@ packages: engines: {node: '>=12.20'} dev: true + /ytdl-core@4.11.5: + resolution: {integrity: sha512-27LwsW4n4nyNviRCO1hmr8Wr5J1wLLMawHCQvH8Fk0hiRqrxuIu028WzbJetiYH28K8XDbeinYW4/wcHQD1EXA==} + engines: {node: '>=12'} + dependencies: + m3u8stream: 0.8.6 + miniget: 4.2.3 + sax: 1.3.0 + dev: false + /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false From 1d0d2120c7134e46748e895e08d22d941706f1b6 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 03/12] =?UTF-8?q?console=E7=B3=BB=E6=AE=8B=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=81=9F=E3=82=89=E5=8F=96=E3=82=8A=E7=B7=A0=E3=81=BE?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc b/.eslintrc index 22c34c34..2be0a4a3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -31,6 +31,7 @@ "argsIgnorePattern": "^_" } ], + "no-console": "error", "import/no-duplicates": "error", "import/order": [ "error", From 24e16221320536a345247f3f77d24fe96407695e Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 04/12] =?UTF-8?q?=E3=83=89=E3=83=A1=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E3=81=AE=E8=A3=9C=E8=B6=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index bb4d2ef2..8e1ae0d8 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,8 @@ asdfを使っている場合はそのまま入ります。 - Python Pythonは、`@discordjs/opus`の入れるのに必要です。 + +# 登場するドメイン + +- Actor + - Userの子概念で、interactしたUserを指す。 From 2927132bd5d0486445c3347e08d6965e30183420 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 05/12] =?UTF-8?q?tsc=E3=81=AE=E8=B2=AC=E5=8B=99=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E5=89=A5=E3=81=8C=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tsconfig.json b/tsconfig.json index 3a49aafc..ac3c120d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,6 +28,8 @@ "src/utils/*" ] }, + "noUnusedLocals": false, + "noUnusedParameters": false }, "include": [ "src", From 184b200a4ab38b73bfce46f5188f1b2cd2cafad1 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 06/12] Update cSpell words --- .vscode/settings.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index d890aee1..fa6068c6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,7 @@ "cSpell.words": [ "jetdisc", "libsodium", - "swcrc" + "swcrc", + "ytdl" ] -} \ No newline at end of file +} From 2f1c028b5b9671fc4caf3ab46544b5ba572c650e Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 07/12] =?UTF-8?q?YouTube=E3=81=8B=E3=82=89=E3=81=AE?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=83=AA=E3=83=BC=E3=83=A0=E3=82=92=E3=81=A7?= =?UTF-8?q?=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .tool-versions | 1 + src/features/commands/index.ts | 1 + .../internal/VoiceChannel.class.ts | 5 +- .../commands/internal/YouTube/index.ts | 1 + .../YouTube/internal/YouTube.class.ts | 132 ++++++++++++++++++ .../YouTube/internal/YouTube.constants.ts | 27 ++++ src/features/core/index.ts | 4 +- .../internal/Client/internal/Client.class.ts | 1 + src/features/core/internal/Voice/index.ts | 5 +- .../Voice/internal/Voice.class.spec.ts | 17 ++- .../internal/Voice/internal/Voice.class.ts | 49 ++++++- .../internal/Voice/internal/Voice.types.ts | 7 + .../funcs/getActorConnection/index.ts | 1 - .../funcs/getActorConnectionState/index.ts | 1 + .../internal/getActorConnectionState.func.ts} | 27 ++-- .../internal/getJoinableStateStatus.func.ts | 19 +++ src/features/library/index.ts | 6 + src/features/others/assertNever.ts | 3 + .../getActorId/internal/getActorId.func.ts | 1 + .../getInteractionMemberId.func.spec.ts | 1 + .../others/log/internal/log.func.spec.ts | 1 + src/features/others/log/internal/log.func.ts | 1 + src/index.ts | 4 +- 23 files changed, 281 insertions(+), 34 deletions(-) create mode 100644 src/features/commands/internal/YouTube/index.ts create mode 100644 src/features/commands/internal/YouTube/internal/YouTube.class.ts create mode 100644 src/features/commands/internal/YouTube/internal/YouTube.constants.ts create mode 100644 src/features/core/internal/Voice/internal/Voice.types.ts delete mode 100644 src/features/core/internal/Voice/internal/funcs/getActorConnection/index.ts create mode 100644 src/features/core/internal/Voice/internal/funcs/getActorConnectionState/index.ts rename src/features/core/internal/Voice/internal/funcs/{getActorConnection/internal/getActorConnection.func.ts => getActorConnectionState/internal/getActorConnectionState.func.ts} (51%) create mode 100644 src/features/others/assertNever.ts diff --git a/.tool-versions b/.tool-versions index c81854a5..5d2f6c72 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,4 @@ nodejs 20.9.0 pnpm 8.10.5 python 3.11.6 +ffmpeg 6.1 diff --git a/src/features/commands/index.ts b/src/features/commands/index.ts index 1ad9f779..fdf0f6d6 100644 --- a/src/features/commands/index.ts +++ b/src/features/commands/index.ts @@ -1,3 +1,4 @@ export type { CommandBase } from './internal/CommandBase/index.js'; export { Ping } from './internal/Ping/index.js'; export { VoiceChannel } from './internal/VoiceChannel/index.js'; +export { YouTube } from './internal/YouTube/index.js'; diff --git a/src/features/commands/internal/VoiceChannel/internal/VoiceChannel.class.ts b/src/features/commands/internal/VoiceChannel/internal/VoiceChannel.class.ts index 9dcd6756..a7a9bf8d 100644 --- a/src/features/commands/internal/VoiceChannel/internal/VoiceChannel.class.ts +++ b/src/features/commands/internal/VoiceChannel/internal/VoiceChannel.class.ts @@ -1,6 +1,5 @@ -import { Voice } from '@/features/core/index.js'; +import { getVoiceInstance } from '@/features/core/index.js'; import { LogicException } from '@/features/others/Error/LogicException.js'; -import { singleton } from '@/features/others/singleton/index.js'; import { VoiceChannelCommandOptions } from './VoiceChannel.constants.js'; import type { InteractArgs } from '../../CommandBase/index.js'; @@ -13,8 +12,6 @@ export class VoiceChannel extends CommandBase { public override async interact({ interaction }: InteractArgs): Promise { const subcommand = interaction.options.getSubcommand(); - const createVoiceInstance = () => new Voice(); - const getVoiceInstance = singleton(createVoiceInstance); const voice = getVoiceInstance(); switch (subcommand) { diff --git a/src/features/commands/internal/YouTube/index.ts b/src/features/commands/internal/YouTube/index.ts new file mode 100644 index 00000000..d2d38eb0 --- /dev/null +++ b/src/features/commands/internal/YouTube/index.ts @@ -0,0 +1 @@ +export { YouTube } from './internal/YouTube.class.js'; diff --git a/src/features/commands/internal/YouTube/internal/YouTube.class.ts b/src/features/commands/internal/YouTube/internal/YouTube.class.ts new file mode 100644 index 00000000..aa94a1c3 --- /dev/null +++ b/src/features/commands/internal/YouTube/internal/YouTube.class.ts @@ -0,0 +1,132 @@ +import ytdl from 'ytdl-core'; + +import { + getActorConnectionState, + getVoiceInstance, +} from '@/features/core/index.js'; +import { + AudioPlayerStatus, + StreamType, + createAudioPlayer, + createAudioResource, + entersState, + isNil, +} from '@/features/library/index.js'; +import { LogicException } from '@/features/others/Error/LogicException.js'; + +import { + YOUTUBE_URL_VALIDATION_SCHEMA, + YouTubeCommandOptions, +} from './YouTube.constants.js'; +import type { InteractArgs } from '../../CommandBase/index.js'; +import { CommandBase } from '../../CommandBase/index.js'; + +/** + * TODO: キューイング + * TODO: 先頭に戻す操作 + * TODO: 次に送る操作 + * TODO: 一時停止と再開 + * TODO: 1曲をループし続けるモード + * TODO: プレイリストサポート + * TODO: プレイリストをループし続けるモード + */ +export class YouTube extends CommandBase { + public readonly name = 'youtube'; + public readonly description = 'Searches YouTube for a video'; + public override readonly options = Object.values(YouTubeCommandOptions); + + public override async interact({ interaction }: InteractArgs): Promise { + switch (interaction.options.getSubcommand()) { + case YouTubeCommandOptions.play.name: + await this.play({ interaction }); + break; + case YouTubeCommandOptions.stop.name: + await this.stop({ interaction }); + break; + default: + throw new Error('Unexpected subcommand'); + } + } + + private async play({ interaction }: InteractArgs) { + if (isNil(interaction.guild)) return; + + const url = (() => { + try { + const url = YOUTUBE_URL_VALIDATION_SCHEMA.parse( + interaction.options.getString('url') + ); + if (ytdl.validateURL(url)) return url; + else throw new Error('Invalid URL'); + } catch (error) { + return; + } + })(); + if (isNil(url)) { + interaction.reply('Invalid URL'); + return; + } + + const voice = getVoiceInstance(); + + const connection = await getActorConnectionState({ + interaction, + connections: voice.connection, + }); + + if (isNil(connection)) { + interaction.reply('Not connected to a voice channel'); + } else { + const player = createAudioPlayer(); + connection.player = player; + voice.connection = voice.connection.map(connection => { + if (connection.guildId === interaction.guildId) { + return { + ...connection, + player, + }; + } + return connection; + }); + + connection.connection.subscribe(player); + + const stream = ytdl(ytdl.getURLVideoID(url), { + filter: format => format.audioCodec === 'opus', //webm opus + quality: 'highestaudio', + highWaterMark: 32 * 1024 * 1024, // https://github.com/fent/node-ytdl-core/issues/902 + }); + + const resource = createAudioResource(stream, { + inputType: StreamType.WebmOpus, + inlineVolume: true, + }); + if (isNil(resource.volume)) throw new LogicException('Volume is null'); + resource.volume.setVolume(0.25); + + player.play(resource); + await entersState(player, AudioPlayerStatus.Playing, 10 * 1000); + interaction.reply(`Playing ${url}`); + } + } + + private async stop({ interaction }: InteractArgs) { + if (isNil(interaction.guild)) return; + + const voice = getVoiceInstance(); + + const connectionState = await getActorConnectionState({ + interaction, + connections: voice.connection, + }); + + if (isNil(connectionState)) { + interaction.reply('Not connected to a voice channel'); + } else if (isNil(connectionState.player)) { + interaction.reply('Not playing in a voice channel'); + } else { + connectionState.player.stop(); + interaction.reply('Stopped'); + } + } +} diff --git a/src/features/commands/internal/YouTube/internal/YouTube.constants.ts b/src/features/commands/internal/YouTube/internal/YouTube.constants.ts new file mode 100644 index 00000000..b19fb0d7 --- /dev/null +++ b/src/features/commands/internal/YouTube/internal/YouTube.constants.ts @@ -0,0 +1,27 @@ +import { z } from 'zod'; + +import type { ApplicationCommandOptionData } from '@/features/library/index.js'; +import { ApplicationCommandOptionType } from '@/features/library/index.js'; + +export const YouTubeCommandOptions = { + play: { + name: 'play', + description: 'Play the YouTube video immediately.', + type: ApplicationCommandOptionType.Subcommand, + options: [ + { + name: 'url', + description: 'The YouTube URL', + type: ApplicationCommandOptionType.String, + required: true, + }, + ], + }, + stop: { + name: 'stop', + description: 'stop the voice channel.', + type: ApplicationCommandOptionType.Subcommand, + }, +} as const satisfies Record; + +export const YOUTUBE_URL_VALIDATION_SCHEMA = z.string().url().min(1); diff --git a/src/features/core/index.ts b/src/features/core/index.ts index 17388e20..adf08c14 100644 --- a/src/features/core/index.ts +++ b/src/features/core/index.ts @@ -3,5 +3,7 @@ export { Voice, getJoinableStateStatus, JOINABLE_STATE_STATUS, - getActorConnection, + getActorConnectionState, + type ConnectionState, + getVoiceInstance, } from './internal/Voice/index.js'; diff --git a/src/features/core/internal/Client/internal/Client.class.ts b/src/features/core/internal/Client/internal/Client.class.ts index 52e09a51..54989421 100644 --- a/src/features/core/internal/Client/internal/Client.class.ts +++ b/src/features/core/internal/Client/internal/Client.class.ts @@ -21,6 +21,7 @@ export class Client extends DiscordJsClient { intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, + GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.MessageContent, ], }); diff --git a/src/features/core/internal/Voice/index.ts b/src/features/core/internal/Voice/index.ts index aeae3fa8..a8cd5dcf 100644 --- a/src/features/core/internal/Voice/index.ts +++ b/src/features/core/internal/Voice/index.ts @@ -1,6 +1,7 @@ -export { Voice } from './internal/Voice.class.js'; +export { Voice, getVoiceInstance } from './internal/Voice.class.js'; +export type { ConnectionState } from './internal/Voice.types.js'; export { getJoinableStateStatus, JOINABLE_STATE_STATUS, } from './internal/funcs/getJoinableStateStatus/index.js'; -export { getActorConnection } from './internal/funcs/getActorConnection/index.js'; +export { getActorConnectionState } from './internal/funcs/getActorConnectionState/index.js'; diff --git a/src/features/core/internal/Voice/internal/Voice.class.spec.ts b/src/features/core/internal/Voice/internal/Voice.class.spec.ts index d006d840..e8e06751 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.spec.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.spec.ts @@ -13,7 +13,8 @@ import { LogicException } from '@/features/others/Error/LogicException.js'; import { getActorId } from '@/features/others/discord/index.js'; import { Voice } from './Voice.class.js'; -import { getActorConnection } from './funcs/getActorConnection/index.js'; +import type { ConnectionState } from './Voice.types.js'; +import { getActorConnectionState } from './funcs/getActorConnectionState/index.js'; import { JOINABLE_STATE_STATUS, getJoinableStateStatus, @@ -50,9 +51,9 @@ vi.mock('./funcs/getJoinableStateStatus/index.js', async () => { }; }); -vi.mock('./funcs/getActorConnection/index.js', () => { +vi.mock('./funcs/getActorConnectionState/index.js', () => { return { - getActorConnection: vi.fn(), + getActorConnectionState: vi.fn(), }; }); @@ -251,10 +252,14 @@ describe('Voice', () => { } as unknown as Readonly; ( - getActorConnection as MockedFunction + getActorConnectionState as MockedFunction< + typeof getActorConnectionState + > ).mockResolvedValueOnce({ - destroy: vi.fn(), - } as unknown as VoiceConnection); + connection: { + destroy: vi.fn(), + }, + } as unknown as ConnectionState); const result = await voice.leave({ interaction }); diff --git a/src/features/core/internal/Voice/internal/Voice.class.ts b/src/features/core/internal/Voice/internal/Voice.class.ts index 2012e107..49710b4e 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.ts @@ -1,21 +1,28 @@ import type { VoiceConnection, ChatInputCommandInteraction, + AudioPlayer, } from '@/features/library/index.js'; import { isNil, joinVoiceChannel } from '@/features/library/index.js'; import { LogicException } from '@/features/others/Error/LogicException.js'; +import { assertNever } from '@/features/others/assertNever.js'; import { getActorId } from '@/features/others/discord/index.js'; +import { singleton } from '@/features/others/singleton/index.js'; -import { getActorConnection } from './funcs/getActorConnection/index.js'; +import { getActorConnectionState } from './funcs/getActorConnectionState/index.js'; import { JOINABLE_STATE_STATUS, getJoinableStateStatus, } from './funcs/getJoinableStateStatus/index.js'; +const createVoiceInstance = () => new Voice(); +export const getVoiceInstance = singleton(createVoiceInstance); + export class Voice { connection: Array<{ guildId: string; connection: VoiceConnection; + player: AudioPlayer | undefined; }> = []; public async join({ @@ -52,6 +59,38 @@ export class Voice { }); return false; + case JOINABLE_STATE_STATUS.ALREADY_JOINED: + const actor = await getActorId(interaction); + if ( + !( + this.connection.filter( + connection => connection.guildId === actor.guild.id + ).length > 0 + ) + ) { + if (isNil(channel)) + throw new LogicException( + 'Channel is null. Please check getJoinableStateStatus()' + ); + + // NOTE: クライアントでの接続情報がないので、再度接続という形を取る + const connectedChannel = joinVoiceChannel({ + channelId: channel.id, + guildId: channel.guild.id, + adapterCreator: channel.guild.voiceAdapterCreator, + }); + this.connection.push({ + guildId: actor.guild.id, + connection: connectedChannel, + player: undefined, + }); + } + interaction.reply({ + content: 'Already joined.', + ephemeral: false, + }); + return false; + case JOINABLE_STATE_STATUS.JOINABLE: if (isNil(channel)) throw new LogicException( @@ -66,10 +105,12 @@ export class Voice { this.connection.push({ guildId: channel.guild.id, connection, + player: undefined, }); return true; default: + assertNever(joinable); // HACK: ここでrejectするとSwitch外のカバレッジがuncoveredになる break; } @@ -82,14 +123,14 @@ export class Voice { }: { interaction: Readonly; }): Promise { - const actorConnection = await getActorConnection({ + const actorConnectionState = await getActorConnectionState({ interaction, connections: this.connection, }); - if (isNil(actorConnection)) return false; + if (isNil(actorConnectionState)) return false; else { - actorConnection.destroy(); + actorConnectionState.connection.destroy(); return true; } } diff --git a/src/features/core/internal/Voice/internal/Voice.types.ts b/src/features/core/internal/Voice/internal/Voice.types.ts new file mode 100644 index 00000000..cd1dee1c --- /dev/null +++ b/src/features/core/internal/Voice/internal/Voice.types.ts @@ -0,0 +1,7 @@ +import type { AudioPlayer, VoiceConnection } from '@/features/library/index.js'; + +export type ConnectionState = { + guildId: string; + connection: VoiceConnection; + player: AudioPlayer | undefined; +}; diff --git a/src/features/core/internal/Voice/internal/funcs/getActorConnection/index.ts b/src/features/core/internal/Voice/internal/funcs/getActorConnection/index.ts deleted file mode 100644 index 625bcd97..00000000 --- a/src/features/core/internal/Voice/internal/funcs/getActorConnection/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { getActorConnection } from './internal/getActorConnection.func.js'; diff --git a/src/features/core/internal/Voice/internal/funcs/getActorConnectionState/index.ts b/src/features/core/internal/Voice/internal/funcs/getActorConnectionState/index.ts new file mode 100644 index 00000000..004b5828 --- /dev/null +++ b/src/features/core/internal/Voice/internal/funcs/getActorConnectionState/index.ts @@ -0,0 +1 @@ +export { getActorConnectionState } from './internal/getActorConnectionState.func.js'; diff --git a/src/features/core/internal/Voice/internal/funcs/getActorConnection/internal/getActorConnection.func.ts b/src/features/core/internal/Voice/internal/funcs/getActorConnectionState/internal/getActorConnectionState.func.ts similarity index 51% rename from src/features/core/internal/Voice/internal/funcs/getActorConnection/internal/getActorConnection.func.ts rename to src/features/core/internal/Voice/internal/funcs/getActorConnectionState/internal/getActorConnectionState.func.ts index b5769e16..ce45dcc9 100644 --- a/src/features/core/internal/Voice/internal/funcs/getActorConnection/internal/getActorConnection.func.ts +++ b/src/features/core/internal/Voice/internal/funcs/getActorConnectionState/internal/getActorConnectionState.func.ts @@ -1,21 +1,15 @@ -import { - isNil, - type ChatInputCommandInteraction, - type VoiceConnection, - getVoiceConnection, -} from '@/features/library/index.js'; +import type { ConnectionState } from '@/features/core/index.js'; +import { isNil, getVoiceConnection } from '@/features/library/index.js'; +import type { ChatInputCommandInteraction } from '@/features/library/index.js'; import { getActorId } from '@/features/others/discord/index.js'; -export const getActorConnection = async ({ +export const getActorConnectionState = async ({ interaction, connections, }: { interaction: Readonly; - connections: Array<{ - guildId: string; - connection: VoiceConnection; - }>; -}): Promise => { + connections: Array; +}): Promise => { const guildId = interaction.guildId; if (isNil(guildId)) return null; @@ -28,8 +22,13 @@ export const getActorConnection = async ({ const connection = getVoiceConnection(actor.guild.id); if (isNil(connection)) return null; - else return connection; + else + return { + guildId: actor.guild.id, + connection, + player: undefined, + }; } else { - return connection.connection; + return connection; } }; diff --git a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts index 77454a38..84ffb332 100644 --- a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts @@ -2,17 +2,36 @@ import { isNil, type VoiceBasedChannel } from '@/features/library/index.js'; import { JOINABLE_STATE_STATUS } from './getJoinableStateStatus.constants.js'; +/** + * TODO: ALREADY_JOINEDのパターン作る + */ export const getJoinableStateStatus = ({ channel, }: { channel: VoiceBasedChannel | null; }): (typeof JOINABLE_STATE_STATUS)[keyof typeof JOINABLE_STATE_STATUS] => { + // getVoiceConnectionやgetVoiceConnectionsを利用せずに、自身がjoinしているかどうかを判定する + const client = channel?.client; + const guildId = channel?.guildId; + if (!client || !guildId) { + return JOINABLE_STATE_STATUS.NOT_FOUND; + } + + const voiceState = (() => { + const guild = client.guilds.cache.get(guildId); + if (!guild) return undefined; + const voiceState = guild.voiceStates.cache.get(client.user.id); + return voiceState; + })(); + if (isNil(channel)) { return JOINABLE_STATE_STATUS.NOT_FOUND; } else if (!channel.joinable) { return JOINABLE_STATE_STATUS.NOT_JOINABLE; } else if (!channel.viewable) { return JOINABLE_STATE_STATUS.NOT_VIEWABLE; + } else if (!isNil(voiceState)) { + return JOINABLE_STATE_STATUS.ALREADY_JOINED; } else { return JOINABLE_STATE_STATUS.JOINABLE; } diff --git a/src/features/library/index.ts b/src/features/library/index.ts index 65b9ea81..3fbe14cb 100644 --- a/src/features/library/index.ts +++ b/src/features/library/index.ts @@ -1,6 +1,12 @@ export { + StreamType, + entersState, + AudioPlayerStatus, + AudioPlayer, joinVoiceChannel, getVoiceConnection, + createAudioPlayer, + createAudioResource, VoiceConnection, } from '@discordjs/voice'; export { default as chalk } from 'chalk'; diff --git a/src/features/others/assertNever.ts b/src/features/others/assertNever.ts new file mode 100644 index 00000000..efc231b0 --- /dev/null +++ b/src/features/others/assertNever.ts @@ -0,0 +1,3 @@ +export const assertNever = (x: never): never => { + throw new Error(`${x} is unexpected value. Should have been never.`); +}; diff --git a/src/features/others/discord/internal/getActorId/internal/getActorId.func.ts b/src/features/others/discord/internal/getActorId/internal/getActorId.func.ts index 00748190..5c299ef4 100644 --- a/src/features/others/discord/internal/getActorId/internal/getActorId.func.ts +++ b/src/features/others/discord/internal/getActorId/internal/getActorId.func.ts @@ -5,6 +5,7 @@ import { } from '@/features/library/index.js'; import { getGuildFromInteraction } from '@/features/others/discord/index.js'; +// TODO: 命名変更 -> getActor export const getActorId = async ( interaction: Readonly ): Promise => { diff --git a/src/features/others/discord/internal/getActorId/internal/getInteractionMemberId.func.spec.ts b/src/features/others/discord/internal/getActorId/internal/getInteractionMemberId.func.spec.ts index ba103d99..8d9d67a6 100644 --- a/src/features/others/discord/internal/getActorId/internal/getInteractionMemberId.func.spec.ts +++ b/src/features/others/discord/internal/getActorId/internal/getInteractionMemberId.func.spec.ts @@ -31,6 +31,7 @@ const fakeInteraction = { member: { user: { id: '123' } }, } as ChatInputCommandInteraction; +// TODO: 命名変更に追従する describe('getActorId', () => { it('should fetch the member ID from the interaction', async () => { ( diff --git a/src/features/others/log/internal/log.func.spec.ts b/src/features/others/log/internal/log.func.spec.ts index f33c06c5..fd33d323 100644 --- a/src/features/others/log/internal/log.func.spec.ts +++ b/src/features/others/log/internal/log.func.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import type { SpyInstance } from 'vitest'; import { chalk } from '@/features/library/index.js'; diff --git a/src/features/others/log/internal/log.func.ts b/src/features/others/log/internal/log.func.ts index 4c2832ed..654d20fe 100644 --- a/src/features/others/log/internal/log.func.ts +++ b/src/features/others/log/internal/log.func.ts @@ -2,6 +2,7 @@ import { chalk } from '@/features/library/index.js'; export const log = ({ message, + // eslint-disable-next-line no-console stdoutMethod = console.log, }: { message: string; diff --git a/src/index.ts b/src/index.ts index 009aaae5..27058e96 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,10 @@ import 'dotenv/config'; -import { Ping, VoiceChannel } from './features/commands/index.js'; +import { Ping, VoiceChannel, YouTube } from './features/commands/index.js'; import { getConfig } from './features/config/index.js'; import { Client } from './features/core/index.js'; new Client({ config: getConfig(), - commands: [new Ping(), new VoiceChannel()], + commands: [new Ping(), new VoiceChannel(), new YouTube()], }); From cbc3f282ae0d0cb6ed623c43696628a40be44e50 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 08/12] Update dependencies --- package.json | 20 +- pnpm-lock.yaml | 724 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 538 insertions(+), 206 deletions(-) diff --git a/package.json b/package.json index 4b4ea521..25327622 100644 --- a/package.json +++ b/package.json @@ -19,20 +19,20 @@ "author": "", "license": "MIT", "devDependencies": { - "@swc/cli": "^0.1.62", - "@swc/core": "^1.3.96", + "@swc/cli": "^0.1.63", + "@swc/core": "^1.3.99", "@tsconfig/strictest": "^2.0.2", - "@types/lodash-es": "^4.17.11", - "@types/node": "^20.9.0", - "@typescript-eslint/eslint-plugin": "^6.10.0", - "@typescript-eslint/parser": "^6.10.0", + "@types/lodash-es": "^4.17.12", + "@types/node": "^20.9.4", + "@typescript-eslint/eslint-plugin": "^6.12.0", + "@typescript-eslint/parser": "^6.12.0", "@vitest/coverage-v8": "^0.34.6", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.0", - "prettier": "^3.0.3", - "tsx": "^4.1.1", - "typescript": "^5.2.2", + "prettier": "^3.1.0", + "tsx": "^4.2.0", + "typescript": "^5.3.2", "vitest": "^0.34.6" }, "dependencies": { @@ -42,7 +42,7 @@ "chalk": "^5.3.0", "discord.js": "^14.14.1", "dotenv": "^16.3.1", - "eslint": "^8.53.0", + "eslint": "^8.54.0", "libsodium-wrappers": "^0.7.13", "lodash-es": "^4.17.21", "resolve": "^1.22.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d624d15f..6d8d4336 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ dependencies: version: 0.16.1(@discordjs/opus@0.9.0) '@t3-oss/env-core': specifier: ^0.7.1 - version: 0.7.1(typescript@5.2.2)(zod@3.22.4) + version: 0.7.1(typescript@5.3.2)(zod@3.22.4) chalk: specifier: ^5.3.0 version: 5.3.0 @@ -24,8 +24,8 @@ dependencies: specifier: ^16.3.1 version: 16.3.1 eslint: - specifier: ^8.53.0 - version: 8.53.0 + specifier: ^8.54.0 + version: 8.54.0 libsodium-wrappers: specifier: ^0.7.13 version: 0.7.13 @@ -44,47 +44,47 @@ dependencies: devDependencies: '@swc/cli': - specifier: ^0.1.62 - version: 0.1.62(@swc/core@1.3.96) + specifier: ^0.1.63 + version: 0.1.63(@swc/core@1.3.99) '@swc/core': - specifier: ^1.3.96 - version: 1.3.96 + specifier: ^1.3.99 + version: 1.3.99 '@tsconfig/strictest': specifier: ^2.0.2 version: 2.0.2 '@types/lodash-es': - specifier: ^4.17.11 - version: 4.17.11 + specifier: ^4.17.12 + version: 4.17.12 '@types/node': - specifier: ^20.9.0 - version: 20.9.0 + specifier: ^20.9.4 + version: 20.9.4 '@typescript-eslint/eslint-plugin': - specifier: ^6.10.0 - version: 6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2) + specifier: ^6.12.0 + version: 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) '@typescript-eslint/parser': - specifier: ^6.10.0 - version: 6.10.0(eslint@8.53.0)(typescript@5.2.2) + specifier: ^6.12.0 + version: 6.12.0(eslint@8.54.0)(typescript@5.3.2) '@vitest/coverage-v8': specifier: ^0.34.6 version: 0.34.6(vitest@0.34.6) eslint-config-prettier: specifier: ^9.0.0 - version: 9.0.0(eslint@8.53.0) + version: 9.0.0(eslint@8.54.0) eslint-import-resolver-typescript: specifier: ^3.6.1 - version: 3.6.1(@typescript-eslint/parser@6.10.0)(eslint-plugin-import@2.29.0)(eslint@8.53.0) + version: 3.6.1(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) eslint-plugin-import: specifier: ^2.29.0 - version: 2.29.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) + version: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) prettier: - specifier: ^3.0.3 - version: 3.0.3 + specifier: ^3.1.0 + version: 3.1.0 tsx: - specifier: ^4.1.1 - version: 4.1.1 + specifier: ^4.2.0 + version: 4.2.0 typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.2 + version: 5.3.2 vitest: specifier: ^0.34.6 version: 0.34.6 @@ -167,8 +167,8 @@ packages: - supports-color dev: false - /@discordjs/rest@2.1.0: - resolution: {integrity: sha512-5gFWFkZX2JCFSRzs8ltx8bWmyVi0wPMk6pBa9KGIQSDPMmrP+uOrZ9j9HOwvmVWGe+LmZ5Bov0jMnQd6/jVReg==} + /@discordjs/rest@2.2.0: + resolution: {integrity: sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==} engines: {node: '>=16.11.0'} dependencies: '@discordjs/collection': 2.0.0 @@ -191,7 +191,7 @@ packages: resolution: {integrity: sha512-uiWiW0Ta6K473yf8zs13RfKuPqm/xU4m4dAidMkIdwqgy1CztbbZBtPLfDkVSKzpW7s6m072C+uQcs4LwF3FhA==} engines: {node: '>=16.11.0'} dependencies: - '@types/ws': 8.5.9 + '@types/ws': 8.5.10 discord-api-types: 0.37.61 prism-media: 1.3.5(@discordjs/opus@0.9.0) tslib: 2.6.2 @@ -210,7 +210,7 @@ packages: engines: {node: '>=16.11.0'} dependencies: '@discordjs/collection': 2.0.0 - '@discordjs/rest': 2.1.0 + '@discordjs/rest': 2.2.0 '@discordjs/util': 1.0.2 '@sapphire/async-queue': 1.5.0 '@types/ws': 8.5.9 @@ -232,6 +232,15 @@ packages: dev: true optional: true + /@esbuild/android-arm64@0.19.7: + resolution: {integrity: sha512-YEDcw5IT7hW3sFKZBkCAQaOCJQLONVcD4bOyTXMZz5fr66pTHnAet46XAtbXAkJRfIn2YVhdC6R9g4xa27jQ1w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm@0.18.20: resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -241,6 +250,15 @@ packages: dev: true optional: true + /@esbuild/android-arm@0.19.7: + resolution: {integrity: sha512-YGSPnndkcLo4PmVl2tKatEn+0mlVMr3yEpOOT0BeMria87PhvoJb5dg5f5Ft9fbCVgtAz4pWMzZVgSEGpDAlww==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.18.20: resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -250,6 +268,15 @@ packages: dev: true optional: true + /@esbuild/android-x64@0.19.7: + resolution: {integrity: sha512-jhINx8DEjz68cChFvM72YzrqfwJuFbfvSxZAk4bebpngGfNNRm+zRl4rtT9oAX6N9b6gBcFaJHFew5Blf6CvUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.18.20: resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -259,6 +286,15 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64@0.19.7: + resolution: {integrity: sha512-dr81gbmWN//3ZnBIm6YNCl4p3pjnabg1/ZVOgz2fJoUO1a3mq9WQ/1iuEluMs7mCL+Zwv7AY5e3g1hjXqQZ9Iw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.18.20: resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -268,6 +304,15 @@ packages: dev: true optional: true + /@esbuild/darwin-x64@0.19.7: + resolution: {integrity: sha512-Lc0q5HouGlzQEwLkgEKnWcSazqr9l9OdV2HhVasWJzLKeOt0PLhHaUHuzb8s/UIya38DJDoUm74GToZ6Wc7NGQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.18.20: resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -277,6 +322,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64@0.19.7: + resolution: {integrity: sha512-+y2YsUr0CxDFF7GWiegWjGtTUF6gac2zFasfFkRJPkMAuMy9O7+2EH550VlqVdpEEchWMynkdhC9ZjtnMiHImQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.18.20: resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -286,6 +340,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64@0.19.7: + resolution: {integrity: sha512-CdXOxIbIzPJmJhrpmJTLx+o35NoiKBIgOvmvT+jeSadYiWJn0vFKsl+0bSG/5lwjNHoIDEyMYc/GAPR9jxusTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.18.20: resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -295,6 +358,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm64@0.19.7: + resolution: {integrity: sha512-inHqdOVCkUhHNvuQPT1oCB7cWz9qQ/Cz46xmVe0b7UXcuIJU3166aqSunsqkgSGMtUCWOZw3+KMwI6otINuC9g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.18.20: resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -304,6 +376,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm@0.19.7: + resolution: {integrity: sha512-Y+SCmWxsJOdQtjcBxoacn/pGW9HDZpwsoof0ttL+2vGcHokFlfqV666JpfLCSP2xLxFpF1lj7T3Ox3sr95YXww==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.18.20: resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -313,6 +394,15 @@ packages: dev: true optional: true + /@esbuild/linux-ia32@0.19.7: + resolution: {integrity: sha512-2BbiL7nLS5ZO96bxTQkdO0euGZIUQEUXMTrqLxKUmk/Y5pmrWU84f+CMJpM8+EHaBPfFSPnomEaQiG/+Gmh61g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.18.20: resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -322,6 +412,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64@0.19.7: + resolution: {integrity: sha512-BVFQla72KXv3yyTFCQXF7MORvpTo4uTA8FVFgmwVrqbB/4DsBFWilUm1i2Oq6zN36DOZKSVUTb16jbjedhfSHw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.18.20: resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -331,6 +430,15 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el@0.19.7: + resolution: {integrity: sha512-DzAYckIaK+pS31Q/rGpvUKu7M+5/t+jI+cdleDgUwbU7KdG2eC3SUbZHlo6Q4P1CfVKZ1lUERRFP8+q0ob9i2w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.18.20: resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -340,6 +448,15 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64@0.19.7: + resolution: {integrity: sha512-JQ1p0SmUteNdUaaiRtyS59GkkfTW0Edo+e0O2sihnY4FoZLz5glpWUQEKMSzMhA430ctkylkS7+vn8ziuhUugQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.18.20: resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -349,6 +466,15 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64@0.19.7: + resolution: {integrity: sha512-xGwVJ7eGhkprY/nB7L7MXysHduqjpzUl40+XoYDGC4UPLbnG+gsyS1wQPJ9lFPcxYAaDXbdRXd1ACs9AE9lxuw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.18.20: resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -358,6 +484,15 @@ packages: dev: true optional: true + /@esbuild/linux-s390x@0.19.7: + resolution: {integrity: sha512-U8Rhki5PVU0L0nvk+E8FjkV8r4Lh4hVEb9duR6Zl21eIEYEwXz8RScj4LZWA2i3V70V4UHVgiqMpszXvG0Yqhg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.18.20: resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -367,6 +502,15 @@ packages: dev: true optional: true + /@esbuild/linux-x64@0.19.7: + resolution: {integrity: sha512-ZYZopyLhm4mcoZXjFt25itRlocKlcazDVkB4AhioiL9hOWhDldU9n38g62fhOI4Pth6vp+Mrd5rFKxD0/S+7aQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.18.20: resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -376,6 +520,15 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64@0.19.7: + resolution: {integrity: sha512-/yfjlsYmT1O3cum3J6cmGG16Fd5tqKMcg5D+sBYLaOQExheAJhqr8xOAEIuLo8JYkevmjM5zFD9rVs3VBcsjtQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.18.20: resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -385,6 +538,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64@0.19.7: + resolution: {integrity: sha512-MYDFyV0EW1cTP46IgUJ38OnEY5TaXxjoDmwiTXPjezahQgZd+j3T55Ht8/Q9YXBM0+T9HJygrSRGV5QNF/YVDQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.18.20: resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -394,6 +556,15 @@ packages: dev: true optional: true + /@esbuild/sunos-x64@0.19.7: + resolution: {integrity: sha512-JcPvgzf2NN/y6X3UUSqP6jSS06V0DZAV/8q0PjsZyGSXsIGcG110XsdmuWiHM+pno7/mJF6fjH5/vhUz/vA9fw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.18.20: resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -403,6 +574,15 @@ packages: dev: true optional: true + /@esbuild/win32-arm64@0.19.7: + resolution: {integrity: sha512-ZA0KSYti5w5toax5FpmfcAgu3ZNJxYSRm0AW/Dao5up0YV1hDVof1NvwLomjEN+3/GMtaWDI+CIyJOMTRSTdMw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.18.20: resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -412,6 +592,15 @@ packages: dev: true optional: true + /@esbuild/win32-ia32@0.19.7: + resolution: {integrity: sha512-CTOnijBKc5Jpk6/W9hQMMvJnsSYRYgveN6O75DTACCY18RA2nqka8dTZR+x/JqXCRiKk84+5+bRKXUSbbwsS0A==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.18.20: resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -421,13 +610,22 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.53.0): + /@esbuild/win32-x64@0.19.7: + resolution: {integrity: sha512-gRaP2sk6hc98N734luX4VpF318l3w+ofrtTu9j5L8EQXF+FzQKV6alCOHMVoJJHvVK/mGbwBXfOL1HETQu9IGQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.54.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.53.0 + eslint: 8.54.0 eslint-visitor-keys: 3.4.3 /@eslint-community/regexpp@4.10.0: @@ -442,7 +640,7 @@ packages: debug: 4.3.4 espree: 9.6.1 globals: 13.23.0 - ignore: 5.2.4 + ignore: 5.3.0 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -450,8 +648,8 @@ packages: transitivePeerDependencies: - supports-color - /@eslint/js@8.53.0: - resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} + /@eslint/js@8.54.0: + resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} /@fastify/busboy@2.1.0: @@ -550,6 +748,102 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + /@rollup/rollup-android-arm-eabi@4.5.1: + resolution: {integrity: sha512-YaN43wTyEBaMqLDYeze+gQ4ZrW5RbTEGtT5o1GVDkhpdNcsLTnLRcLccvwy3E9wiDKWg9RIhuoy3JQKDRBfaZA==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.5.1: + resolution: {integrity: sha512-n1bX+LCGlQVuPlCofO0zOKe1b2XkFozAVRoczT+yxWZPGnkEAKTTYVOGZz8N4sKuBnKMxDbfhUsB1uwYdup/sw==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.5.1: + resolution: {integrity: sha512-QqJBumdvfBqBBmyGHlKxje+iowZwrHna7pokj/Go3dV1PJekSKfmjKrjKQ/e6ESTGhkfPNLq3VXdYLAc+UtAQw==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.5.1: + resolution: {integrity: sha512-RrkDNkR/P5AEQSPkxQPmd2ri8WTjSl0RYmuFOiEABkEY/FSg0a4riihWQGKDJ4LnV9gigWZlTMx2DtFGzUrYQw==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.5.1: + resolution: {integrity: sha512-ZFPxvUZmE+fkB/8D9y/SWl/XaDzNSaxd1TJUSE27XAKlRpQ2VNce/86bGd9mEUgL3qrvjJ9XTGwoX0BrJkYK/A==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.5.1: + resolution: {integrity: sha512-FEuAjzVIld5WVhu+M2OewLmjmbXWd3q7Zcx+Rwy4QObQCqfblriDMMS7p7+pwgjZoo9BLkP3wa9uglQXzsB9ww==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.5.1: + resolution: {integrity: sha512-f5Gs8WQixqGRtI0Iq/cMqvFYmgFzMinuJO24KRfnv7Ohi/HQclwrBCYkzQu1XfLEEt3DZyvveq9HWo4bLJf1Lw==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.5.1: + resolution: {integrity: sha512-CWPkPGrFfN2vj3mw+S7A/4ZaU3rTV7AkXUr08W9lNP+UzOvKLVf34tWCqrKrfwQ0NTk5GFqUr2XGpeR2p6R4gw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.5.1: + resolution: {integrity: sha512-ZRETMFA0uVukUC9u31Ed1nx++29073goCxZtmZARwk5aF/ltuENaeTtRVsSQzFlzdd4J6L3qUm+EW8cbGt0CKQ==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.5.1: + resolution: {integrity: sha512-ihqfNJNb2XtoZMSCPeoo0cYMgU04ksyFIoOw5S0JUVbOhafLot+KD82vpKXOurE2+9o/awrqIxku9MRR9hozHQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.5.1: + resolution: {integrity: sha512-zK9MRpC8946lQ9ypFn4gLpdwr5a01aQ/odiIJeL9EbgZDMgbZjjT/XzTqJvDfTmnE1kHdbG20sAeNlpc91/wbg==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.5.1: + resolution: {integrity: sha512-5I3Nz4Sb9TYOtkRwlH0ow+BhMH2vnh38tZ4J4mggE48M/YyJyp/0sPSxhw1UeS1+oBgQ8q7maFtSeKpeRJu41Q==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@sapphire/async-queue@1.5.0: resolution: {integrity: sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} @@ -577,8 +871,8 @@ packages: engines: {node: '>=10'} dev: true - /@swc/cli@0.1.62(@swc/core@1.3.96): - resolution: {integrity: sha512-kOFLjKY3XH1DWLfXL1/B5MizeNorHR8wHKEi92S/Zi9Md/AK17KSqR8MgyRJ6C1fhKHvbBCl8wboyKAFXStkYw==} + /@swc/cli@0.1.63(@swc/core@1.3.99): + resolution: {integrity: sha512-EM9oxxHzmmsprYRbGqsS2M4M/Gr5Gkcl0ROYYIdlUyTkhOiX822EQiRCpPCwdutdnzH2GyaTN7wc6i0Y+CKd3A==} engines: {node: '>= 12.13'} hasBin: true peerDependencies: @@ -589,7 +883,7 @@ packages: optional: true dependencies: '@mole-inc/bin-wrapper': 8.0.1 - '@swc/core': 1.3.96 + '@swc/core': 1.3.99 commander: 7.2.0 fast-glob: 3.3.2 semver: 7.5.4 @@ -597,8 +891,8 @@ packages: source-map: 0.7.4 dev: true - /@swc/core-darwin-arm64@1.3.96: - resolution: {integrity: sha512-8hzgXYVd85hfPh6mJ9yrG26rhgzCmcLO0h1TIl8U31hwmTbfZLzRitFQ/kqMJNbIBCwmNH1RU2QcJnL3d7f69A==} + /@swc/core-darwin-arm64@1.3.99: + resolution: {integrity: sha512-Qj7Jct68q3ZKeuJrjPx7k8SxzWN6PqLh+VFxzA+KwLDpQDPzOlKRZwkIMzuFjLhITO4RHgSnXoDk/Syz0ZeN+Q==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] @@ -606,8 +900,8 @@ packages: dev: true optional: true - /@swc/core-darwin-x64@1.3.96: - resolution: {integrity: sha512-mFp9GFfuPg+43vlAdQZl0WZpZSE8sEzqL7sr/7Reul5McUHP0BaLsEzwjvD035ESfkY8GBZdLpMinblIbFNljQ==} + /@swc/core-darwin-x64@1.3.99: + resolution: {integrity: sha512-wR7m9QVJjgiBu1PSOHy7s66uJPa45Kf9bZExXUL+JAa9OQxt5y+XVzr+n+F045VXQOwdGWplgPnWjgbUUHEVyw==} engines: {node: '>=10'} cpu: [x64] os: [darwin] @@ -615,17 +909,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm-gnueabihf@1.3.96: - resolution: {integrity: sha512-8UEKkYJP4c8YzYIY/LlbSo8z5Obj4hqcv/fUTHiEePiGsOddgGf7AWjh56u7IoN/0uEmEro59nc1ChFXqXSGyg==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@swc/core-linux-arm64-gnu@1.3.96: - resolution: {integrity: sha512-c/IiJ0s1y3Ymm2BTpyC/xr6gOvoqAVETrivVXHq68xgNms95luSpbYQ28rqaZC8bQC8M5zdXpSc0T8DJu8RJGw==} + /@swc/core-linux-arm64-gnu@1.3.99: + resolution: {integrity: sha512-gcGv1l5t0DScEONmw5OhdVmEI/o49HCe9Ik38zzH0NtDkc+PDYaCcXU5rvfZP2qJFaAAr8cua8iJcOunOSLmnA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -633,8 +918,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm64-musl@1.3.96: - resolution: {integrity: sha512-i5/UTUwmJLri7zhtF6SAo/4QDQJDH2fhYJaBIUhrICmIkRO/ltURmpejqxsM/ye9Jqv5zG7VszMC0v/GYn/7BQ==} + /@swc/core-linux-arm64-musl@1.3.99: + resolution: {integrity: sha512-XL1/eUsTO8BiKsWq9i3iWh7H99iPO61+9HYiWVKhSavknfj4Plbn+XyajDpxsauln5o8t+BRGitymtnAWJM4UQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -642,8 +927,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-gnu@1.3.96: - resolution: {integrity: sha512-USdaZu8lTIkm4Yf9cogct/j5eqtdZqTgcTib4I+NloUW0E/hySou3eSyp3V2UAA1qyuC72ld1otXuyKBna0YKQ==} + /@swc/core-linux-x64-gnu@1.3.99: + resolution: {integrity: sha512-fGrXYE6DbTfGNIGQmBefYxSk3rp/1lgbD0nVg4rl4mfFRQPi7CgGhrrqSuqZ/ezXInUIgoCyvYGWFSwjLXt/Qg==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -651,8 +936,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-musl@1.3.96: - resolution: {integrity: sha512-QYErutd+G2SNaCinUVobfL7jWWjGTI0QEoQ6hqTp7PxCJS/dmKmj3C5ZkvxRYcq7XcZt7ovrYCTwPTHzt6lZBg==} + /@swc/core-linux-x64-musl@1.3.99: + resolution: {integrity: sha512-kvgZp/mqf3IJ806gUOL6gN6VU15+DfzM1Zv4Udn8GqgXiUAvbQehrtruid4Snn5pZTLj4PEpSCBbxgxK1jbssA==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -660,8 +945,8 @@ packages: dev: true optional: true - /@swc/core-win32-arm64-msvc@1.3.96: - resolution: {integrity: sha512-hjGvvAduA3Un2cZ9iNP4xvTXOO4jL3G9iakhFsgVhpkU73SGmK7+LN8ZVBEu4oq2SUcHO6caWvnZ881cxGuSpg==} + /@swc/core-win32-arm64-msvc@1.3.99: + resolution: {integrity: sha512-yt8RtZ4W/QgFF+JUemOUQAkVW58cCST7mbfKFZ1v16w3pl3NcWd9OrtppFIXpbjU1rrUX2zp2R7HZZzZ2Zk/aQ==} engines: {node: '>=10'} cpu: [arm64] os: [win32] @@ -669,8 +954,8 @@ packages: dev: true optional: true - /@swc/core-win32-ia32-msvc@1.3.96: - resolution: {integrity: sha512-Far2hVFiwr+7VPCM2GxSmbh3ikTpM3pDombE+d69hkedvYHYZxtTF+2LTKl/sXtpbUnsoq7yV/32c9R/xaaWfw==} + /@swc/core-win32-ia32-msvc@1.3.99: + resolution: {integrity: sha512-62p5fWnOJR/rlbmbUIpQEVRconICy5KDScWVuJg1v3GPLBrmacjphyHiJC1mp6dYvvoEWCk/77c/jcQwlXrDXw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] @@ -678,8 +963,8 @@ packages: dev: true optional: true - /@swc/core-win32-x64-msvc@1.3.96: - resolution: {integrity: sha512-4VbSAniIu0ikLf5mBX81FsljnfqjoVGleEkCQv4+zRlyZtO3FHoDPkeLVoy6WRlj7tyrRcfUJ4mDdPkbfTO14g==} + /@swc/core-win32-x64-msvc@1.3.99: + resolution: {integrity: sha512-PdppWhkoS45VGdMBxvClVgF1hVjqamtvYd82Gab1i4IV45OSym2KinoDCKE1b6j3LwBLOn2J9fvChGSgGfDCHQ==} engines: {node: '>=10'} cpu: [x64] os: [win32] @@ -687,8 +972,8 @@ packages: dev: true optional: true - /@swc/core@1.3.96: - resolution: {integrity: sha512-zwE3TLgoZwJfQygdv2SdCK9mRLYluwDOM53I+dT6Z5ZvrgVENmY3txvWDvduzkV+/8IuvrRbVezMpxcojadRdQ==} + /@swc/core@1.3.99: + resolution: {integrity: sha512-8O996RfuPC4ieb4zbYMfbyCU9k4gSOpyCNnr7qBQ+o7IEmh8JCV6B8wwu+fT/Om/6Lp34KJe1IpJ/24axKS6TQ==} engines: {node: '>=10'} requiresBuild: true peerDependencies: @@ -700,16 +985,15 @@ packages: '@swc/counter': 0.1.2 '@swc/types': 0.1.5 optionalDependencies: - '@swc/core-darwin-arm64': 1.3.96 - '@swc/core-darwin-x64': 1.3.96 - '@swc/core-linux-arm-gnueabihf': 1.3.96 - '@swc/core-linux-arm64-gnu': 1.3.96 - '@swc/core-linux-arm64-musl': 1.3.96 - '@swc/core-linux-x64-gnu': 1.3.96 - '@swc/core-linux-x64-musl': 1.3.96 - '@swc/core-win32-arm64-msvc': 1.3.96 - '@swc/core-win32-ia32-msvc': 1.3.96 - '@swc/core-win32-x64-msvc': 1.3.96 + '@swc/core-darwin-arm64': 1.3.99 + '@swc/core-darwin-x64': 1.3.99 + '@swc/core-linux-arm64-gnu': 1.3.99 + '@swc/core-linux-arm64-musl': 1.3.99 + '@swc/core-linux-x64-gnu': 1.3.99 + '@swc/core-linux-x64-musl': 1.3.99 + '@swc/core-win32-arm64-msvc': 1.3.99 + '@swc/core-win32-ia32-msvc': 1.3.99 + '@swc/core-win32-x64-msvc': 1.3.99 dev: true /@swc/counter@0.1.2: @@ -727,7 +1011,7 @@ packages: defer-to-connect: 2.0.1 dev: true - /@t3-oss/env-core@0.7.1(typescript@5.2.2)(zod@3.22.4): + /@t3-oss/env-core@0.7.1(typescript@5.3.2)(zod@3.22.4): resolution: {integrity: sha512-3+SQt39OlmSaRLqYVFv8uRm1BpFepM5TIiMytRqO9cjH+wB77o6BIJdeyM5h5U4qLBMEzOJWCY4MBaU/rLwbYw==} peerDependencies: typescript: '>=4.7.2' @@ -736,7 +1020,7 @@ packages: typescript: optional: true dependencies: - typescript: 5.2.2 + typescript: 5.3.2 zod: 3.22.4 dev: false @@ -753,18 +1037,18 @@ packages: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.9.0 + '@types/node': 20.9.4 '@types/responselike': 1.0.3 dev: true /@types/chai-subset@1.3.5: resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} dependencies: - '@types/chai': 4.3.10 + '@types/chai': 4.3.11 dev: true - /@types/chai@4.3.10: - resolution: {integrity: sha512-of+ICnbqjmFCiixUnqRulbylyXQrPqIGf/B3Jax1wIF3DvSheysQxAWvqHhZiW3IQrycvokcLcFQlveGp+vyNg==} + /@types/chai@4.3.11: + resolution: {integrity: sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ==} dev: true /@types/http-cache-semantics@4.0.4: @@ -786,42 +1070,48 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.9.0 + '@types/node': 20.9.4 dev: true - /@types/lodash-es@4.17.11: - resolution: {integrity: sha512-eCw8FYAWHt2DDl77s+AMLLzPn310LKohruumpucZI4oOFJkIgnlaJcy23OKMJxx4r9PeTF13Gv6w+jqjWQaYUg==} + /@types/lodash-es@4.17.12: + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} dependencies: - '@types/lodash': 4.14.201 + '@types/lodash': 4.14.202 dev: true - /@types/lodash@4.14.201: - resolution: {integrity: sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==} + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} dev: true - /@types/node@20.9.0: - resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==} + /@types/node@20.9.4: + resolution: {integrity: sha512-wmyg8HUhcn6ACjsn8oKYjkN/zUzQeNtMy44weTJSM6p4MMzEOuKbA3OjJ267uPCOW7Xex9dyrNTful8XTQYoDA==} dependencies: undici-types: 5.26.5 /@types/responselike@1.0.3: resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 20.9.0 + '@types/node': 20.9.4 dev: true - /@types/semver@7.5.5: - resolution: {integrity: sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==} + /@types/semver@7.5.6: + resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} dev: true + /@types/ws@8.5.10: + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + dependencies: + '@types/node': 20.9.4 + dev: false + /@types/ws@8.5.9: resolution: {integrity: sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==} dependencies: - '@types/node': 20.9.0 + '@types/node': 20.9.4 dev: false - /@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==} + /@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -832,25 +1122,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/type-utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/scope-manager': 6.12.0 + '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 - eslint: 8.53.0 + eslint: 8.54.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==} + /@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -859,27 +1149,27 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/scope-manager': 6.12.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 - eslint: 8.53.0 - typescript: 5.2.2 + eslint: 8.54.0 + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.10.0: - resolution: {integrity: sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==} + /@typescript-eslint/scope-manager@6.12.0: + resolution: {integrity: sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/visitor-keys': 6.12.0 dev: true - /@typescript-eslint/type-utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==} + /@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -888,23 +1178,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) debug: 4.3.4 - eslint: 8.53.0 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + eslint: 8.54.0 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.10.0: - resolution: {integrity: sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==} + /@typescript-eslint/types@6.12.0: + resolution: {integrity: sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.10.0(typescript@5.2.2): - resolution: {integrity: sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==} + /@typescript-eslint/typescript-estree@6.12.0(typescript@5.3.2): + resolution: {integrity: sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -912,42 +1202,42 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==} + /@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) '@types/json-schema': 7.0.15 - '@types/semver': 7.5.5 - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - eslint: 8.53.0 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 6.12.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + eslint: 8.54.0 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@6.10.0: - resolution: {integrity: sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==} + /@typescript-eslint/visitor-keys@6.12.0: + resolution: {integrity: sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.10.0 + '@typescript-eslint/types': 6.12.0 eslint-visitor-keys: 3.4.3 dev: true @@ -967,7 +1257,7 @@ packages: istanbul-reports: 3.1.6 magic-string: 0.30.5 picocolors: 1.0.0 - std-env: 3.4.3 + std-env: 3.5.0 test-exclude: 6.0.0 v8-to-istanbul: 9.1.3 vitest: 0.34.6 @@ -1435,7 +1725,7 @@ packages: '@discordjs/builders': 1.7.0 '@discordjs/collection': 1.5.3 '@discordjs/formatters': 0.3.3 - '@discordjs/rest': 2.1.0 + '@discordjs/rest': 2.2.0 '@discordjs/util': 1.0.2 '@discordjs/ws': 1.0.2 '@sapphire/snowflake': 3.5.1 @@ -1586,6 +1876,36 @@ packages: '@esbuild/win32-x64': 0.18.20 dev: true + /esbuild@0.19.7: + resolution: {integrity: sha512-6brbTZVqxhqgbpqBR5MzErImcpA0SQdoKOkcWK/U30HtQxnokIpG3TX2r0IJqbFUzqLjhU/zC1S5ndgakObVCQ==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.19.7 + '@esbuild/android-arm64': 0.19.7 + '@esbuild/android-x64': 0.19.7 + '@esbuild/darwin-arm64': 0.19.7 + '@esbuild/darwin-x64': 0.19.7 + '@esbuild/freebsd-arm64': 0.19.7 + '@esbuild/freebsd-x64': 0.19.7 + '@esbuild/linux-arm': 0.19.7 + '@esbuild/linux-arm64': 0.19.7 + '@esbuild/linux-ia32': 0.19.7 + '@esbuild/linux-loong64': 0.19.7 + '@esbuild/linux-mips64el': 0.19.7 + '@esbuild/linux-ppc64': 0.19.7 + '@esbuild/linux-riscv64': 0.19.7 + '@esbuild/linux-s390x': 0.19.7 + '@esbuild/linux-x64': 0.19.7 + '@esbuild/netbsd-x64': 0.19.7 + '@esbuild/openbsd-x64': 0.19.7 + '@esbuild/sunos-x64': 0.19.7 + '@esbuild/win32-arm64': 0.19.7 + '@esbuild/win32-ia32': 0.19.7 + '@esbuild/win32-x64': 0.19.7 + dev: true + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -1595,13 +1915,13 @@ packages: engines: {node: '>=12'} dev: true - /eslint-config-prettier@9.0.0(eslint@8.53.0): + /eslint-config-prettier@9.0.0(eslint@8.54.0): resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.53.0 + eslint: 8.54.0 dev: true /eslint-import-resolver-node@0.3.9: @@ -1614,7 +1934,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.10.0)(eslint-plugin-import@2.29.0)(eslint@8.53.0): + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0): resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -1623,9 +1943,9 @@ packages: dependencies: debug: 4.3.4 enhanced-resolve: 5.15.0 - eslint: 8.53.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) - eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) + eslint: 8.54.0 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -1637,7 +1957,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -1658,16 +1978,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) debug: 3.2.7 - eslint: 8.53.0 + eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.10.0)(eslint-plugin-import@2.29.0)(eslint@8.53.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.12.0)(eslint-plugin-import@2.29.0)(eslint@8.54.0) transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0): + /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0): resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} engines: {node: '>=4'} peerDependencies: @@ -1677,16 +1997,16 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.53.0 + eslint: 8.54.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.10.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.53.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.12.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.54.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -1713,15 +2033,15 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /eslint@8.53.0: - resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==} + /eslint@8.54.0: + resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) '@eslint-community/regexpp': 4.10.0 '@eslint/eslintrc': 2.1.3 - '@eslint/js': 8.53.0 + '@eslint/js': 8.54.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -1743,7 +2063,7 @@ packages: glob-parent: 6.0.2 globals: 13.23.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -2066,7 +2386,7 @@ packages: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.2.4 + ignore: 5.3.0 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -2177,8 +2497,8 @@ packages: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} /import-fresh@3.3.0: @@ -2595,7 +2915,7 @@ packages: acorn: 8.11.2 pathe: 1.1.1 pkg-types: 1.0.3 - ufo: 1.3.1 + ufo: 1.3.2 dev: true /ms@2.1.2: @@ -2855,8 +3175,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - /prettier@3.0.3: - resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} + /prettier@3.1.0: + resolution: {integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==} engines: {node: '>=14'} hasBin: true dev: true @@ -2977,11 +3297,23 @@ packages: dependencies: glob: 7.2.3 - /rollup@3.29.4: - resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + /rollup@4.5.1: + resolution: {integrity: sha512-0EQribZoPKpb5z1NW/QYm3XSR//Xr8BeEXU49Lc/mQmpmVVG5jPUVrpc2iptup/0WMrY9mzas0fxH+TjYvG2CA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.5.1 + '@rollup/rollup-android-arm64': 4.5.1 + '@rollup/rollup-darwin-arm64': 4.5.1 + '@rollup/rollup-darwin-x64': 4.5.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.5.1 + '@rollup/rollup-linux-arm64-gnu': 4.5.1 + '@rollup/rollup-linux-arm64-musl': 4.5.1 + '@rollup/rollup-linux-x64-gnu': 4.5.1 + '@rollup/rollup-linux-x64-musl': 4.5.1 + '@rollup/rollup-win32-arm64-msvc': 4.5.1 + '@rollup/rollup-win32-ia32-msvc': 4.5.1 + '@rollup/rollup-win32-x64-msvc': 4.5.1 fsevents: 2.3.3 dev: true @@ -3143,8 +3475,8 @@ packages: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true - /std-env@3.4.3: - resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==} + /std-env@3.5.0: + resolution: {integrity: sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA==} dev: true /string-width@4.2.3: @@ -3309,13 +3641,13 @@ packages: escape-string-regexp: 5.0.0 dev: true - /ts-api-utils@1.0.3(typescript@5.2.2): + /ts-api-utils@1.0.3(typescript@5.3.2): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.2.2 + typescript: 5.3.2 dev: true /ts-mixer@6.0.3: @@ -3335,8 +3667,8 @@ packages: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} dev: false - /tsx@4.1.1: - resolution: {integrity: sha512-zyPn5BFMB0TB5kMLbYPNx4x/oL/oSlaecdKCv6WeJ0TeSEfx8RTJWjuB5TZ2dSewktgfBsBO/HNA9mrMWqLXMA==} + /tsx@4.2.0: + resolution: {integrity: sha512-hvAXAz4KUYNyjXOjJJgyjT7YOGFUNLC8jnODI6Omc/wGKaZ7z0FvW5d2haqg1GLfX49H3nZOpLYRlHMYGI8Wbw==} engines: {node: '>=18.0.0'} hasBin: true dependencies: @@ -3400,13 +3732,13 @@ packages: is-typed-array: 1.1.12 dev: true - /typescript@5.2.2: - resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + /typescript@5.3.2: + resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} engines: {node: '>=14.17'} hasBin: true - /ufo@1.3.1: - resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==} + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} dev: true /unbox-primitive@1.0.2: @@ -3445,7 +3777,7 @@ packages: convert-source-map: 2.0.0 dev: true - /vite-node@0.34.6(@types/node@20.9.0): + /vite-node@0.34.6(@types/node@20.9.4): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -3455,7 +3787,7 @@ packages: mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.9.0) + vite: 5.0.2(@types/node@20.9.4) transitivePeerDependencies: - '@types/node' - less @@ -3467,12 +3799,12 @@ packages: - terser dev: true - /vite@4.5.0(@types/node@20.9.0): - resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} - engines: {node: ^14.18.0 || >=16.0.0} + /vite@5.0.2(@types/node@20.9.4): + resolution: {integrity: sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -3495,10 +3827,10 @@ packages: terser: optional: true dependencies: - '@types/node': 20.9.0 - esbuild: 0.18.20 + '@types/node': 20.9.4 + esbuild: 0.19.7 postcss: 8.4.31 - rollup: 3.29.4 + rollup: 4.5.1 optionalDependencies: fsevents: 2.3.3 dev: true @@ -3534,9 +3866,9 @@ packages: webdriverio: optional: true dependencies: - '@types/chai': 4.3.10 + '@types/chai': 4.3.11 '@types/chai-subset': 1.3.5 - '@types/node': 20.9.0 + '@types/node': 20.9.4 '@vitest/expect': 0.34.6 '@vitest/runner': 0.34.6 '@vitest/snapshot': 0.34.6 @@ -3551,12 +3883,12 @@ packages: magic-string: 0.30.5 pathe: 1.1.1 picocolors: 1.0.0 - std-env: 3.4.3 + std-env: 3.5.0 strip-literal: 1.3.0 tinybench: 2.5.1 tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.9.0) - vite-node: 0.34.6(@types/node@20.9.0) + vite: 5.0.2(@types/node@20.9.4) + vite-node: 0.34.6(@types/node@20.9.4) why-is-node-running: 2.2.2 transitivePeerDependencies: - less From 110f4b064e4dae173c92efd32b78fefa0cf9781c Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 09/12] =?UTF-8?q?nasm=E5=85=A5=E3=82=8C=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cc0e5a3..6b732915 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,10 @@ jobs: - name: Setup asdf uses: asdf-vm/actions/setup@v3.0.2 continue-on-error: true + - name: install ffmpeg dependencies + run: | + sudo apt-get update + sudo apt-get install -y nasm - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies @@ -27,6 +31,10 @@ jobs: - name: Setup asdf uses: asdf-vm/actions/setup@v3.0.2 continue-on-error: true + - name: install ffmpeg dependencies + run: | + sudo apt-get update + sudo apt-get install -y nasm - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies @@ -43,6 +51,10 @@ jobs: - name: Setup asdf uses: asdf-vm/actions/setup@v3.0.2 continue-on-error: true + - name: install ffmpeg dependencies + run: | + sudo apt-get update + sudo apt-get install -y nasm - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies @@ -61,6 +73,10 @@ jobs: - name: Setup asdf uses: asdf-vm/actions/setup@v3.0.2 continue-on-error: true + - name: install ffmpeg dependencies + run: | + sudo apt-get update + sudo apt-get install -y nasm - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies From 4a76543eeba79685bfe79654deaedca8daa59175 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 10/12] =?UTF-8?q?asdf=E3=81=AE=E3=82=A4=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=83=BC=E3=83=AB=E6=88=90=E6=9E=9C=E7=89=A9=E3=82=92?= =?UTF-8?q?=E3=82=AD=E3=83=A3=E3=83=83=E3=82=B7=E3=83=A5=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=81=BF=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b732915..682ad3d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,12 @@ jobs: run: | sudo apt-get update sudo apt-get install -y nasm + - name: Cache asdf + uses: actions/cache@v3 + with: + path: | + ~/.asdf + key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }} - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies @@ -35,6 +41,12 @@ jobs: run: | sudo apt-get update sudo apt-get install -y nasm + - name: Cache asdf + uses: actions/cache@v3 + with: + path: | + ~/.asdf + key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }} - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies @@ -55,6 +67,12 @@ jobs: run: | sudo apt-get update sudo apt-get install -y nasm + - name: Cache asdf + uses: actions/cache@v3 + with: + path: | + ~/.asdf + key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }} - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies @@ -77,6 +95,12 @@ jobs: run: | sudo apt-get update sudo apt-get install -y nasm + - name: Cache asdf + uses: actions/cache@v3 + with: + path: | + ~/.asdf + key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }} - name: asdf install uses: asdf-vm/actions/install@v3.0.2 - name: Install dependencies From b0125aae410da2dbd6e77abe2bf42fd1aad786f1 Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 11/12] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Voice/internal/Voice.class.spec.ts | 2 +- .../internal/Voice/internal/Voice.class.ts | 6 +-- .../internal/getJoinableStateStatus.func.ts | 41 +++++++------- .../internal/getJoinableStateStatus.spec.ts | 54 +++++++++++++++++-- 4 files changed, 72 insertions(+), 31 deletions(-) diff --git a/src/features/core/internal/Voice/internal/Voice.class.spec.ts b/src/features/core/internal/Voice/internal/Voice.class.spec.ts index e8e06751..42d89403 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.spec.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.spec.ts @@ -230,7 +230,7 @@ describe('Voice', () => { .mockReturnValueOnce('unknown' as any); await expect(voice.join({ interaction })).rejects.toThrowError( - 'Unknown joinable type.' + 'unknown is unexpected value. Should have been never.' ); }); }); diff --git a/src/features/core/internal/Voice/internal/Voice.class.ts b/src/features/core/internal/Voice/internal/Voice.class.ts index 49710b4e..b9f902ea 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.ts @@ -111,11 +111,9 @@ export class Voice { default: assertNever(joinable); - // HACK: ここでrejectするとSwitch外のカバレッジがuncoveredになる - break; } - - return Promise.reject(new LogicException('Unknown joinable type.')); + /* c8 ignore next */ + return; } public async leave({ diff --git a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts index 84ffb332..491add4a 100644 --- a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.func.ts @@ -10,29 +10,28 @@ export const getJoinableStateStatus = ({ }: { channel: VoiceBasedChannel | null; }): (typeof JOINABLE_STATE_STATUS)[keyof typeof JOINABLE_STATE_STATUS] => { - // getVoiceConnectionやgetVoiceConnectionsを利用せずに、自身がjoinしているかどうかを判定する - const client = channel?.client; - const guildId = channel?.guildId; - if (!client || !guildId) { - return JOINABLE_STATE_STATUS.NOT_FOUND; - } - - const voiceState = (() => { - const guild = client.guilds.cache.get(guildId); - if (!guild) return undefined; - const voiceState = guild.voiceStates.cache.get(client.user.id); - return voiceState; - })(); - if (isNil(channel)) { return JOINABLE_STATE_STATUS.NOT_FOUND; - } else if (!channel.joinable) { - return JOINABLE_STATE_STATUS.NOT_JOINABLE; - } else if (!channel.viewable) { - return JOINABLE_STATE_STATUS.NOT_VIEWABLE; - } else if (!isNil(voiceState)) { - return JOINABLE_STATE_STATUS.ALREADY_JOINED; } else { - return JOINABLE_STATE_STATUS.JOINABLE; + // getVoiceConnectionやgetVoiceConnectionsを利用せずに、自身がjoinしているかどうかを判定する + const client = channel.client; + const guildId = channel.guildId; + + const voiceState = (() => { + const guild = client.guilds.cache.get(guildId); + if (!guild) return undefined; + const voiceState = guild.voiceStates.cache.get(client.user.id); + return voiceState; + })(); + + if (!channel.joinable) { + return JOINABLE_STATE_STATUS.NOT_JOINABLE; + } else if (!channel.viewable) { + return JOINABLE_STATE_STATUS.NOT_VIEWABLE; + } else if (!!voiceState) { + return JOINABLE_STATE_STATUS.ALREADY_JOINED; + } else { + return JOINABLE_STATE_STATUS.JOINABLE; + } } }; diff --git a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts index e477231f..5b903fb5 100644 --- a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts @@ -1,17 +1,22 @@ import type { VoiceBasedChannel } from '@/features/library/index.js'; import { getJoinableStateStatus } from './getJoinableStateStatus.func.js'; +import { JOINABLE_STATE_STATUS } from './getJoinableStateStatus.constants.js'; describe('getJoinableStateStatus', () => { it('should return NOT_FOUND if the channel is null', () => { const result = getJoinableStateStatus({ channel: null }); - expect(result).toBe('NOT_FOUND'); + expect(result).toBe(JOINABLE_STATE_STATUS.NOT_FOUND); }); it('should return NOT_JOINABLE if the channel is not joinable', () => { const result = getJoinableStateStatus({ - channel: { joinable: false } as VoiceBasedChannel, + channel: { + joinable: false, + client: { guilds: { cache: new Map() } }, + guildId: 'guildId', + } as VoiceBasedChannel, }); expect(result).toBe('NOT_JOINABLE'); @@ -19,7 +24,12 @@ describe('getJoinableStateStatus', () => { it('should return NOT_VIEWABLE if the channel is not viewable', () => { const result = getJoinableStateStatus({ - channel: { joinable: true, viewable: false } as VoiceBasedChannel, + channel: { + joinable: true, + viewable: false, + client: { guilds: { cache: new Map() } }, + guildId: 'guildId', + } as VoiceBasedChannel, }); expect(result).toBe('NOT_VIEWABLE'); @@ -27,9 +37,43 @@ describe('getJoinableStateStatus', () => { it('should return JOINABLE if the channel is joinable and viewable', () => { const result = getJoinableStateStatus({ - channel: { joinable: true, viewable: true } as VoiceBasedChannel, + channel: { + joinable: true, + viewable: true, + client: { guilds: { cache: new Map() } }, + guildId: 'guildId', + } as VoiceBasedChannel, }); - expect(result).toBe('JOINABLE'); + expect(result).toBe(JOINABLE_STATE_STATUS.JOINABLE); + }); + + it('should return undefined if the voice state is not found', () => { + const result = getJoinableStateStatus({ + channel: { + joinable: true, + viewable: true, + client: { + user: { id: 'userId' }, + guilds: { + cache: new Map([ + [ + 'guildId', + { + voiceStates: { + cache: new Map([ + ['userId', { voiceStates: { cache: new Map() } }], + ]), + }, + }, + ], + ]), + }, + }, + guildId: 'guildId', + } as unknown as VoiceBasedChannel, + }); + + expect(result).toBe(JOINABLE_STATE_STATUS.ALREADY_JOINED); }); }); From 28b6c42611a6b417b3d0727f2dd2b62ac0b074de Mon Sep 17 00:00:00 2001 From: na2na-p Date: Wed, 22 Nov 2023 14:48:58 +0900 Subject: [PATCH 12/12] =?UTF-8?q?=E3=82=AB=E3=83=90=E3=83=AC=E3=83=83?= =?UTF-8?q?=E3=82=B8=E5=90=91=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/core/index.ts | 2 +- src/features/core/internal/Voice/index.ts | 9 ++- .../Voice/internal/Voice.class.spec.ts | 55 ++++++++++++++++++- .../internal/Voice/internal/Voice.class.ts | 15 ++--- .../internal/getJoinableStateStatus.spec.ts | 2 +- src/features/others/assertNever.ts | 3 - src/features/others/assertNever/index.ts | 1 + .../assertNever/internal/assertNever.func.ts | 4 ++ .../assertNever/internal/assertNever.spec.ts | 15 +++++ 9 files changed, 90 insertions(+), 16 deletions(-) delete mode 100644 src/features/others/assertNever.ts create mode 100644 src/features/others/assertNever/index.ts create mode 100644 src/features/others/assertNever/internal/assertNever.func.ts create mode 100644 src/features/others/assertNever/internal/assertNever.spec.ts diff --git a/src/features/core/index.ts b/src/features/core/index.ts index adf08c14..d69b76c4 100644 --- a/src/features/core/index.ts +++ b/src/features/core/index.ts @@ -1,9 +1,9 @@ export { Client } from './internal/Client/index.js'; export { - Voice, getJoinableStateStatus, JOINABLE_STATE_STATUS, getActorConnectionState, type ConnectionState, getVoiceInstance, } from './internal/Voice/index.js'; +export type { Voice } from './internal/Voice/index.js'; diff --git a/src/features/core/internal/Voice/index.ts b/src/features/core/internal/Voice/index.ts index a8cd5dcf..ad4d43c6 100644 --- a/src/features/core/internal/Voice/index.ts +++ b/src/features/core/internal/Voice/index.ts @@ -1,7 +1,14 @@ -export { Voice, getVoiceInstance } from './internal/Voice.class.js'; +import { singleton } from '@/features/others/singleton/index.js'; + +import { Voice } from './internal/Voice.class.js'; + +export type { Voice } from './internal/Voice.class.js'; export type { ConnectionState } from './internal/Voice.types.js'; export { getJoinableStateStatus, JOINABLE_STATE_STATUS, } from './internal/funcs/getJoinableStateStatus/index.js'; export { getActorConnectionState } from './internal/funcs/getActorConnectionState/index.js'; + +const createVoiceInstance = () => new Voice(); +export const getVoiceInstance = singleton(createVoiceInstance); diff --git a/src/features/core/internal/Voice/internal/Voice.class.spec.ts b/src/features/core/internal/Voice/internal/Voice.class.spec.ts index 42d89403..cfc41f99 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.spec.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.spec.ts @@ -171,6 +171,59 @@ describe('Voice', () => { ); }); + it('should throw an error if the channel is null', async () => { + const mockedInteraction = { + reply: vi.fn(), + } as unknown as Readonly; + + (getActorId as MockedFunction).mockResolvedValueOnce({ + voice: { channel: null }, + } as GuildMember); + ( + getJoinableStateStatus as MockedFunction + ).mockReturnValueOnce(JOINABLE_STATE_STATUS.ALREADY_JOINED); + + await expect( + voice.join({ interaction: mockedInteraction }) + ).rejects.toThrowError( + 'Channel is null. Please check getJoinableStateStatus()' + ); + }); + + // JOINABLE_STATE_STATUS.ALREADY_JOINED + it('should return false if the channel is already joined', async () => { + const mockedInteraction = { + reply: vi.fn(), + } as unknown as Readonly; + + (getActorId as MockedFunction).mockResolvedValueOnce({ + voice: { + channel: { + id: 'channelId', + guild: { + id: 'guildId', + }, + }, + }, + } as GuildMember); + ( + getJoinableStateStatus as MockedFunction + ).mockReturnValueOnce(JOINABLE_STATE_STATUS.ALREADY_JOINED); + + const result = await voice.join({ interaction: mockedInteraction }); + + expect(getJoinableStateStatus).toHaveBeenCalledWith({ + channel: { + id: 'channelId', + guild: { + id: 'guildId', + }, + }, + }); + + expect(result).toBe(false); + }); + it('should join the voice channel and return true', async () => { const mockedGuildMember = { voice: { @@ -230,7 +283,7 @@ describe('Voice', () => { .mockReturnValueOnce('unknown' as any); await expect(voice.join({ interaction })).rejects.toThrowError( - 'unknown is unexpected value. Should have been never.' + 'Unknown joinable type.' ); }); }); diff --git a/src/features/core/internal/Voice/internal/Voice.class.ts b/src/features/core/internal/Voice/internal/Voice.class.ts index b9f902ea..e818514d 100644 --- a/src/features/core/internal/Voice/internal/Voice.class.ts +++ b/src/features/core/internal/Voice/internal/Voice.class.ts @@ -5,9 +5,8 @@ import type { } from '@/features/library/index.js'; import { isNil, joinVoiceChannel } from '@/features/library/index.js'; import { LogicException } from '@/features/others/Error/LogicException.js'; -import { assertNever } from '@/features/others/assertNever.js'; +import { assertNever } from '@/features/others/assertNever/index.js'; import { getActorId } from '@/features/others/discord/index.js'; -import { singleton } from '@/features/others/singleton/index.js'; import { getActorConnectionState } from './funcs/getActorConnectionState/index.js'; import { @@ -15,9 +14,6 @@ import { getJoinableStateStatus, } from './funcs/getJoinableStateStatus/index.js'; -const createVoiceInstance = () => new Voice(); -export const getVoiceInstance = singleton(createVoiceInstance); - export class Voice { connection: Array<{ guildId: string; @@ -80,7 +76,7 @@ export class Voice { adapterCreator: channel.guild.voiceAdapterCreator, }); this.connection.push({ - guildId: actor.guild.id, + guildId: channel.guildId, connection: connectedChannel, player: undefined, }); @@ -110,10 +106,11 @@ export class Voice { return true; default: - assertNever(joinable); + assertNever(joinable, false); + break; + // HACK: カバレッジを100%にするための処置 } - /* c8 ignore next */ - return; + return Promise.reject(new LogicException('Unknown joinable type.')); } public async leave({ diff --git a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts index 5b903fb5..415c3975 100644 --- a/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts +++ b/src/features/core/internal/Voice/internal/funcs/getJoinableStateStatus/internal/getJoinableStateStatus.spec.ts @@ -1,7 +1,7 @@ import type { VoiceBasedChannel } from '@/features/library/index.js'; -import { getJoinableStateStatus } from './getJoinableStateStatus.func.js'; import { JOINABLE_STATE_STATUS } from './getJoinableStateStatus.constants.js'; +import { getJoinableStateStatus } from './getJoinableStateStatus.func.js'; describe('getJoinableStateStatus', () => { it('should return NOT_FOUND if the channel is null', () => { diff --git a/src/features/others/assertNever.ts b/src/features/others/assertNever.ts deleted file mode 100644 index efc231b0..00000000 --- a/src/features/others/assertNever.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const assertNever = (x: never): never => { - throw new Error(`${x} is unexpected value. Should have been never.`); -}; diff --git a/src/features/others/assertNever/index.ts b/src/features/others/assertNever/index.ts new file mode 100644 index 00000000..89d27f92 --- /dev/null +++ b/src/features/others/assertNever/index.ts @@ -0,0 +1 @@ +export { assertNever } from './internal/assertNever.func.js'; diff --git a/src/features/others/assertNever/internal/assertNever.func.ts b/src/features/others/assertNever/internal/assertNever.func.ts new file mode 100644 index 00000000..bfe7f856 --- /dev/null +++ b/src/features/others/assertNever/internal/assertNever.func.ts @@ -0,0 +1,4 @@ +export const assertNever = (x: never, shouldThrow: boolean = true): never => { + if (shouldThrow) throw new Error(`Unexpected object: ${x}`); + return x; +}; diff --git a/src/features/others/assertNever/internal/assertNever.spec.ts b/src/features/others/assertNever/internal/assertNever.spec.ts new file mode 100644 index 00000000..98fec024 --- /dev/null +++ b/src/features/others/assertNever/internal/assertNever.spec.ts @@ -0,0 +1,15 @@ +import { assertNever } from './assertNever.func.js'; + +describe('assertNever', () => { + it('should throw an error with the unexpected object', () => { + const unexpectedObject = {} as never; + expect(() => assertNever(unexpectedObject)).toThrowError( + 'Unexpected object: [object Object]' + ); + }); + + it('should not throw an error when shouldThrow is false', () => { + const unexpectedObject = {} as never; + expect(() => assertNever(unexpectedObject, false)).not.toThrow(); + }); +});