diff --git a/src/bot.ts b/src/bot.ts index 823467025..a8a7c9cca 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -1,5 +1,5 @@ import { Client, GatewayIntentBits } from 'discord.js'; -import { DISCORD_TOKEN } from './core/process/args.js'; +import { DISCORD_TOKEN } from './core/node/args.js'; import { registerErrorHandlers } from './events/error.js'; import guildMemberAdd from './events/guildMemberAdd.js'; import interactionCreate from './events/interactionCreate/index.js'; diff --git a/src/commands/debug.ts b/src/commands/debug.ts index f32d66ff9..ff8d654c0 100644 --- a/src/commands/debug.ts +++ b/src/commands/debug.ts @@ -5,7 +5,7 @@ import { tankopedia } from '../core/blitz/tankopedia.js'; import { tankAverages } from '../core/blitzstars/tankAverages.js'; import cleanTable from '../core/interaction/cleanTable.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; -import getClientId from '../core/process/getClientId.js'; +import getClientId from '../core/node/getClientId.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; const executionStart = new Date().getTime(); @@ -19,7 +19,7 @@ export default { .setName('debug') .setDescription('Debug information about the bot'), - execute(interaction) { + handler(interaction) { const currentTime = new Date().getTime(); const uptime = currentTime - executionStart; diff --git a/src/commands/eligible.ts b/src/commands/eligible.ts index bd038a85a..0a65fa1e0 100644 --- a/src/commands/eligible.ts +++ b/src/commands/eligible.ts @@ -10,9 +10,9 @@ import { tankAverages } from '../core/blitzstars/tankAverages.js'; import cleanTable, { TableInput } from '../core/interaction/cleanTable.js'; import negativeEmbed from '../core/interaction/negativeEmbed.js'; import positiveEmbed from '../core/interaction/positiveEmbed.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; import resolvePlayer from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { AccountInfo } from '../types/accountInfo.js'; @@ -46,7 +46,7 @@ export default { ) .addStringOption(addUsernameOption), - async execute(interaction) { + async handler(interaction) { const clan = interaction.options.getString('clan') as SkilledClan; const { id, server } = await resolvePlayer(interaction); const accountInfo = await getWargamingResponse( diff --git a/src/commands/evolution.tsx b/src/commands/evolution.tsx index 318cf28d3..3d94f5883 100644 --- a/src/commands/evolution.tsx +++ b/src/commands/evolution.tsx @@ -2,8 +2,8 @@ import { SlashCommandBuilder } from 'discord.js'; import tanksAutocomplete from '../core/autocomplete/tanks.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import resolveTankId from '../core/blitz/resolveTankId.js'; +import resolvePeriodFromCommand from '../core/interaction/resolvePeriodFromCommand.js'; import addStatsSubCommandGroups from '../core/options/addStatsSubCommandGroups.js'; -import resolvePeriod from '../core/options/resolvePeriod.js'; import resolvePlayer from '../core/options/resolvePlayer.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import evolution from '../renderers/evolution.js'; @@ -20,12 +20,12 @@ export default { .setDescription('Evolution of statistics'), ), - async execute(interaction) { + async handler(interaction) { const commandGroup = interaction.options.getSubcommandGroup( true, ) as StatType; const player = await resolvePlayer(interaction); - const period = resolvePeriod(interaction); + const period = resolvePeriodFromCommand(interaction); const tankIdRaw = interaction.options.getString('tank')!; const tankId = commandGroup === 'tank' ? resolveTankId(tankIdRaw) : 0; diff --git a/src/commands/help.ts b/src/commands/help.ts index 08ba3ca10..0b178aa8d 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -17,7 +17,7 @@ export default { .setName('help') .setDescription('All the help you need about the bot'), - execute(interaction) { + handler(interaction) { return infoEmbed( `${client.user?.username} help`, `**About**\n${ diff --git a/src/commands/inactive.tsx b/src/commands/inactive.tsx index 4a45dc54a..36ce1fe63 100644 --- a/src/commands/inactive.tsx +++ b/src/commands/inactive.tsx @@ -8,8 +8,8 @@ import { BLITZ_SERVERS } from '../constants/servers.js'; import clanAutocomplete from '../core/autocomplete/clan.js'; import getBlitzClan from '../core/blitz/getBlitzClan.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addClanChoices from '../core/options/addClanChoices.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { AccountInfo } from '../types/accountInfo.js'; import { ClanInfo } from '../types/clanInfo.js'; @@ -34,7 +34,7 @@ export default { .setMinValue(0), ), - async execute(interaction) { + async handler(interaction) { const clanName = interaction.options.getString('clan')!; const { server, id } = await getBlitzClan(interaction, clanName); const threshold = diff --git a/src/commands/ownedtanks.tsx b/src/commands/ownedtanks.tsx index 14b0dfc52..ff41e146a 100644 --- a/src/commands/ownedtanks.tsx +++ b/src/commands/ownedtanks.tsx @@ -13,9 +13,9 @@ import { Tier, tankopedia, } from '../core/blitz/tankopedia.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; import resolvePlayer from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { AccountInfo } from '../types/accountInfo.js'; import { PlayerClanData } from '../types/playerClanData.js'; @@ -69,7 +69,7 @@ export default { ) .addStringOption(addUsernameOption), - async execute(interaction) { + async handler(interaction) { const tier = Number(interaction.options.getString('tier')); const account = await resolvePlayer(interaction); const { id, server } = account; diff --git a/src/commands/ping.ts b/src/commands/ping.ts index dd0b41471..6c99eda61 100644 --- a/src/commands/ping.ts +++ b/src/commands/ping.ts @@ -17,7 +17,7 @@ export default { option.setName('blitz').setDescription('Ping Blitz'), ), - async execute(interaction) { + async handler(interaction) { const subcommand = interaction.options.getSubcommand(); const executionStart = Date.now(); diff --git a/src/commands/playerachievements.ts b/src/commands/playerachievements.ts index 43b888103..258fd6f23 100644 --- a/src/commands/playerachievements.ts +++ b/src/commands/playerachievements.ts @@ -5,9 +5,9 @@ import usernameAutocomplete from '../core/autocomplete/username.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import cleanTable, { TableInputEntry } from '../core/interaction/cleanTable.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; import resolvePlayer from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { AccountAchievements } from '../types/accountAchievements.js'; import { AccountInfo } from '../types/accountInfo.js'; @@ -33,7 +33,7 @@ export default { ), ), - async execute(interaction) { + async handler(interaction) { const sortBy = (interaction.options.getString('sort') ?? 'name') as SortBy; const account = await resolvePlayer(interaction); const { id, server } = account; diff --git a/src/commands/playerinfo.ts b/src/commands/playerinfo.ts index f7dfde492..287e17d15 100644 --- a/src/commands/playerinfo.ts +++ b/src/commands/playerinfo.ts @@ -4,9 +4,9 @@ import usernameAutocomplete from '../core/autocomplete/username.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import cleanTable from '../core/interaction/cleanTable.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; import resolvePlayer from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { AccountInfo } from '../types/accountInfo.js'; @@ -20,7 +20,7 @@ export default { .setDescription('Basic information about a player') .addStringOption(addUsernameOption), - async execute(interaction) { + async handler(interaction) { const account = await resolvePlayer(interaction); const { id, server } = account; const accounts = await getWargamingResponse( diff --git a/src/commands/searchclans.ts b/src/commands/searchclans.ts index 5e005d6f1..bb5f2cf39 100644 --- a/src/commands/searchclans.ts +++ b/src/commands/searchclans.ts @@ -3,9 +3,9 @@ import markdownEscape from 'markdown-escape'; import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addClanChoices from '../core/options/addClanChoices.js'; import addServerChoices from '../core/options/addServerChoices.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { ClanList } from '../types/clanList.js'; @@ -27,7 +27,7 @@ export default { .setMaxValue(100), ), - async execute(interaction) { + async handler(interaction) { const server = interaction.options.getString('server') as BlitzServer; const clan = interaction.options.getString('clan')!; const limit = interaction.options.getInteger('limit') ?? 25; diff --git a/src/commands/searchplayers.ts b/src/commands/searchplayers.ts index d9b1ea2c7..4852d4b8d 100644 --- a/src/commands/searchplayers.ts +++ b/src/commands/searchplayers.ts @@ -4,9 +4,9 @@ import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import { usernamePattern } from '../core/blitz/listAccountsPanServer.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addServerChoices from '../core/options/addServerChoices.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { AccountList } from '../types/accountList.js'; @@ -30,7 +30,7 @@ export default { .setMaxValue(100), ), - async execute(interaction) { + async handler(interaction) { const server = interaction.options.getString('server') as BlitzServer; const name = interaction.options.getString('username')!; const limit = interaction.options.getInteger('limit') ?? 25; diff --git a/src/commands/searchtanks.ts b/src/commands/searchtanks.ts index bb4260b88..38c2c0d93 100644 --- a/src/commands/searchtanks.ts +++ b/src/commands/searchtanks.ts @@ -23,7 +23,7 @@ export default { .setMaxValue(100), ), - async execute(interaction) { + async handler(interaction) { const tank = interaction.options.getString('tank')!; const limit = interaction.options.getInteger('limit') ?? 25; const results = go(tank, TANK_NAMES, { limit }).map( diff --git a/src/commands/stats.tsx b/src/commands/stats.tsx index f036f0239..9c04f5370 100644 --- a/src/commands/stats.tsx +++ b/src/commands/stats.tsx @@ -6,9 +6,9 @@ import resolveTankId from '../core/blitz/resolveTankId.js'; import interactionToURL from '../core/interaction/interactionToURL.js'; import linkButton from '../core/interaction/linkButton.js'; import primaryButton from '../core/interaction/primaryButton.js'; +import resolvePeriodFromCommand from '../core/interaction/resolvePeriodFromCommand.js'; import { Period } from '../core/options/addPeriodSubCommands.js'; import addStatsSubCommandGroups from '../core/options/addStatsSubCommandGroups.js'; -import resolvePeriod from '../core/options/resolvePeriod.js'; import resolvePlayer from '../core/options/resolvePlayer.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import stats, { StatType } from '../renderers/stats.js'; @@ -24,13 +24,13 @@ export default { .setDescription('In-game statistics'), ), - async execute(interaction) { + async handler(interaction) { const commandGroup = interaction.options.getSubcommandGroup( true, ) as StatType; const subcommand = interaction.options.getSubcommand() as Period; const player = await resolvePlayer(interaction); - const period = resolvePeriod(interaction); + const period = resolvePeriodFromCommand(interaction); const tankIdRaw = interaction.options.getString('tank')!; const tankId = commandGroup === 'tank' ? resolveTankId(tankIdRaw) : 0; const start = interaction.options.getInteger('start'); @@ -57,7 +57,7 @@ export default { const url = new URL(`${CYCLIC_API}/${interaction.customId}`); const path = url.pathname.split('/').filter(Boolean); const commandGroup = path[1] as StatType; - const period = resolvePeriod(interaction); + const period = resolvePeriodFromCommand(interaction); const player = await resolvePlayer(interaction); return await stats( diff --git a/src/commands/today.tsx b/src/commands/today.tsx index 41988e021..2d6c1040a 100644 --- a/src/commands/today.tsx +++ b/src/commands/today.tsx @@ -15,7 +15,7 @@ export default { .setDescription('A general daily breakdown of your performance') .addStringOption(addUsernameOption), - async execute(interaction) { + async handler(interaction) { const player = await resolvePlayer(interaction); return await today(player); diff --git a/src/commands/verify.ts b/src/commands/verify.ts index 6d923e032..1ac4e466d 100644 --- a/src/commands/verify.ts +++ b/src/commands/verify.ts @@ -5,9 +5,9 @@ import usernameAutocomplete from '../core/autocomplete/username.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import negativeEmbed from '../core/interaction/negativeEmbed.js'; import positiveEmbed from '../core/interaction/positiveEmbed.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; import resolvePlayer from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate/index.js'; import { AccountInfo } from '../types/accountInfo.js'; import { PlayerClanData } from '../types/playerClanData.js'; @@ -22,7 +22,7 @@ export default { .setDescription("Set's the user's username to their in-game name") .addStringOption((option) => addUsernameOption(option).setRequired(true)), - async execute(interaction) { + async handler(interaction) { const blitzAccount = await resolvePlayer(interaction); const { id, server } = blitzAccount; const accountInfo = await getWargamingResponse( diff --git a/src/components/GenericAllStats.tsx b/src/components/GenericAllStats.tsx index 5374a0801..7fcc64f27 100644 --- a/src/components/GenericAllStats.tsx +++ b/src/components/GenericAllStats.tsx @@ -1,5 +1,5 @@ import getWN8Percentile from '../core/blitz/getWN8Percentile.js'; -import isNumber from '../core/process/isNumber.js'; +import isNumber from '../core/node/isNumber.js'; import { AllStats, SupplementaryStats } from '../types/accountInfo.js'; import GenericStats from './GenericStats/index.js'; diff --git a/src/components/TitleBar.tsx b/src/components/TitleBar.tsx index ead666fa2..0366b4fb1 100644 --- a/src/components/TitleBar.tsx +++ b/src/components/TitleBar.tsx @@ -1,4 +1,4 @@ -import isDev from '../core/process/isDev.js'; +import isDev from '../core/node/isDev.js'; import { theme } from '../stitches.config.js'; export interface TitleBarProps { diff --git a/src/core/blitz/getBlitzClan.ts b/src/core/blitz/getBlitzClan.ts index d511584fc..206aff2fc 100644 --- a/src/core/blitz/getBlitzClan.ts +++ b/src/core/blitz/getBlitzClan.ts @@ -1,7 +1,7 @@ import { CacheType, ChatInputCommandInteraction } from 'discord.js'; import { BlitzServer } from '../../constants/servers.js'; +import errorWithCause from '../node/errorWithCause.js'; import { serverAndIdPattern } from '../options/resolvePlayer.js'; -import errorWithCause from '../process/errorWithCause.js'; import listClansPanServer from './listClansPanServer.js'; export default async function getBlitzClan( diff --git a/src/core/blitz/getTankStats.ts b/src/core/blitz/getTankStats.ts index 66d1091d5..5579400bb 100644 --- a/src/core/blitz/getTankStats.ts +++ b/src/core/blitz/getTankStats.ts @@ -1,7 +1,7 @@ import { BLITZ_SERVERS, BlitzServer } from '../../constants/servers.js'; import { TanksStats } from '../../types/tanksStats.js'; -import { WARGAMING_APPLICATION_ID } from '../process/args.js'; -import errorWithCause from '../process/errorWithCause.js'; +import { WARGAMING_APPLICATION_ID } from '../node/args.js'; +import errorWithCause from '../node/errorWithCause.js'; import getWargamingResponse from './getWargamingResponse.js'; export default async function getTankStats(server: BlitzServer, id: number) { diff --git a/src/core/blitz/getWargamingResponse.ts b/src/core/blitz/getWargamingResponse.ts index 59d30f9d5..3d13701ab 100644 --- a/src/core/blitz/getWargamingResponse.ts +++ b/src/core/blitz/getWargamingResponse.ts @@ -1,5 +1,5 @@ import { WargamingResponse } from '../../types/wargamingResponse.js'; -import errorWithCause from '../process/errorWithCause.js'; +import errorWithCause from '../node/errorWithCause.js'; export default async function getWargamingResponse( url: string, diff --git a/src/core/blitz/listAccountsPanServer.ts b/src/core/blitz/listAccountsPanServer.ts index f09069ba7..e608ed77a 100644 --- a/src/core/blitz/listAccountsPanServer.ts +++ b/src/core/blitz/listAccountsPanServer.ts @@ -1,6 +1,6 @@ import { BlitzServer } from '../../constants/servers.js'; import { Account, AccountList } from '../../types/accountList.js'; -import { WARGAMING_APPLICATION_ID } from '../process/args.js'; +import { WARGAMING_APPLICATION_ID } from '../node/args.js'; import getWargamingResponse from './getWargamingResponse.js'; export type AccountListWithServer = (Account & { diff --git a/src/core/blitz/listClansPanServer.ts b/src/core/blitz/listClansPanServer.ts index 2d5fc148c..eb435d1b4 100644 --- a/src/core/blitz/listClansPanServer.ts +++ b/src/core/blitz/listClansPanServer.ts @@ -1,6 +1,6 @@ import { BlitzServer } from '../../constants/servers.js'; import { Clan, ClanList } from '../../types/clanList.js'; -import { WARGAMING_APPLICATION_ID } from '../process/args.js'; +import { WARGAMING_APPLICATION_ID } from '../node/args.js'; import getWargamingResponse from './getWargamingResponse.js'; export type ClanListWithServer = (Clan & { diff --git a/src/core/blitz/resolveTankId.ts b/src/core/blitz/resolveTankId.ts index 1364c35c1..6931996ed 100644 --- a/src/core/blitz/resolveTankId.ts +++ b/src/core/blitz/resolveTankId.ts @@ -1,5 +1,5 @@ import { go } from 'fuzzysort'; -import errorWithCause from '../process/errorWithCause.js'; +import errorWithCause from '../node/errorWithCause.js'; import { TANKS, tankopedia } from './tankopedia.js'; export default function resolveTankId(tank: string) { diff --git a/src/core/blitzstars/getPlayerHistories.ts b/src/core/blitzstars/getPlayerHistories.ts index d52cfd151..a99e1d10d 100644 --- a/src/core/blitzstars/getPlayerHistories.ts +++ b/src/core/blitzstars/getPlayerHistories.ts @@ -7,7 +7,7 @@ import { getHistoriesDefaultOptions, } from '../../types/histories.js'; import getWargamingResponse from '../blitz/getWargamingResponse.js'; -import { WARGAMING_APPLICATION_ID } from '../process/args.js'; +import { WARGAMING_APPLICATION_ID } from '../node/args.js'; import { emptyAllStats } from './getTankStatsOverTime.js'; export interface PlayerHistoryRaw { diff --git a/src/core/express/normalizeResponderReturnable.ts b/src/core/express/normalizeResponderReturnable.ts new file mode 100644 index 000000000..d0ffeadab --- /dev/null +++ b/src/core/express/normalizeResponderReturnable.ts @@ -0,0 +1,11 @@ +import { ResponderReturnable } from '../../server.js'; +import jsxToSvg from '../ui/jsxToSvg.js'; + +export default async function normalizeResponderReturnable( + returnable: ResponderReturnable, +) { + const awaitedReturnable = await returnable; + const svg = await jsxToSvg(awaitedReturnable); + + return svg; +} diff --git a/src/core/options/resolvePeriod.ts b/src/core/interaction/resolvePeriodFromCommand.ts similarity index 75% rename from src/core/options/resolvePeriod.ts rename to src/core/interaction/resolvePeriodFromCommand.ts index b8a2c5c4d..2eb25c58e 100644 --- a/src/core/options/resolvePeriod.ts +++ b/src/core/interaction/resolvePeriodFromCommand.ts @@ -3,11 +3,12 @@ import { CacheType, ChatInputCommandInteraction, } from 'discord.js'; +import { Request } from 'express'; import { CYCLIC_API } from '../../constants/cyclic.js'; import getPeriodNow from '../blitzstars/getPeriodNow.js'; import getPeriodStart from '../blitzstars/getPeriodStart.js'; import getTimeDaysAgo from '../blitzstars/getTimeDaysAgo.js'; -import { Period } from './addPeriodSubCommands.js'; +import { Period } from '../options/addPeriodSubCommands.js'; export const PERIOD_NAMES: Record = { today: "Today's statistics", @@ -34,10 +35,11 @@ export interface ResolvedPeriod { end: number; } -export default function resolvePeriod( - interaction: +export default function resolvePeriodFromCommand( + input: | ChatInputCommandInteraction - | ButtonInteraction, + | ButtonInteraction + | Request, ) { let statsName: string; let evolutionName: string; @@ -46,22 +48,26 @@ export default function resolvePeriod( let url: URL; let period: Period; - if (interaction instanceof ChatInputCommandInteraction) { - period = interaction.options.getSubcommand() as Period; + if (input instanceof ChatInputCommandInteraction) { + period = input.options.getSubcommand() as Period; } else { - url = new URL(`${CYCLIC_API}/${interaction.customId}`); + url = new URL( + `${CYCLIC_API}${ + input instanceof ButtonInteraction ? `/${input.customId}` : input.path + }`, + ); const path = url.pathname.split('/').filter(Boolean); period = path[path.length - 1] as Period; } if (period === 'custom') { const startRaw = - interaction instanceof ChatInputCommandInteraction - ? interaction.options.getInteger('start')! + input instanceof ChatInputCommandInteraction + ? input.options.getInteger('start')! : parseInt(url!.searchParams.get('start')!); const endRaw = - interaction instanceof ChatInputCommandInteraction - ? interaction.options.getInteger('end')! + input instanceof ChatInputCommandInteraction + ? input.options.getInteger('end')! : parseInt(url!.searchParams.get('end')!); const startMin = Math.min(startRaw, endRaw); const endMax = Math.max(startRaw, endRaw); diff --git a/src/core/process/args.ts b/src/core/node/args.ts similarity index 100% rename from src/core/process/args.ts rename to src/core/node/args.ts diff --git a/src/core/process/errorWithCause.ts b/src/core/node/errorWithCause.ts similarity index 100% rename from src/core/process/errorWithCause.ts rename to src/core/node/errorWithCause.ts diff --git a/src/core/process/getClientId.ts b/src/core/node/getClientId.ts similarity index 100% rename from src/core/process/getClientId.ts rename to src/core/node/getClientId.ts diff --git a/src/core/process/isDev.ts b/src/core/node/isDev.ts similarity index 100% rename from src/core/process/isDev.ts rename to src/core/node/isDev.ts diff --git a/src/core/process/isNumber.ts b/src/core/node/isNumber.ts similarity index 100% rename from src/core/process/isNumber.ts rename to src/core/node/isNumber.ts diff --git a/src/core/process/psa.ts b/src/core/node/psa.ts similarity index 100% rename from src/core/process/psa.ts rename to src/core/node/psa.ts diff --git a/src/core/options/addPeriodSubCommands.ts b/src/core/options/addPeriodSubCommands.ts index d8d28f2e9..450ea5c69 100644 --- a/src/core/options/addPeriodSubCommands.ts +++ b/src/core/options/addPeriodSubCommands.ts @@ -2,7 +2,7 @@ import { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder, } from 'discord.js'; -import { PERIOD_NAMES } from './resolvePeriod.js'; +import { PERIOD_NAMES } from '../interaction/resolvePeriodFromCommand.js'; export type Period = 'today' | '30' | '60' | '90' | 'career' | 'custom'; diff --git a/src/core/options/resolvePlayer.ts b/src/core/options/resolvePlayer.ts index 4e2d344d3..003a49e6c 100644 --- a/src/core/options/resolvePlayer.ts +++ b/src/core/options/resolvePlayer.ts @@ -8,7 +8,7 @@ import { BlitzServer } from '../../constants/servers.js'; import listAccountsPanServer, { usernamePatternWithoutPosition, } from '../blitz/listAccountsPanServer.js'; -import errorWithCause from '../process/errorWithCause.js'; +import errorWithCause from '../node/errorWithCause.js'; export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/; diff --git a/src/events/error.ts b/src/events/error.ts index ee73d6fdc..8dec386de 100644 --- a/src/events/error.ts +++ b/src/events/error.ts @@ -2,7 +2,7 @@ import { EmbedBuilder, TextChannel } from 'discord.js'; import discord from '../../discord.json' assert { type: 'json' }; import { client } from '../bot.js'; import { NEGATIVE_COLOR } from '../constants/colors.js'; -import isDev from '../core/process/isDev.js'; +import isDev from '../core/node/isDev.js'; const PROCESS_ERROR_EVENTS = ['uncaughtException']; const CLIENT_ERROR_EVENTS = ['error']; diff --git a/src/events/interactionCreate/handlers/chatInputCommand.ts b/src/events/interactionCreate/handlers/chatInputCommand.ts index 6907bf516..471c1d709 100644 --- a/src/events/interactionCreate/handlers/chatInputCommand.ts +++ b/src/events/interactionCreate/handlers/chatInputCommand.ts @@ -8,24 +8,24 @@ import { import negativeEmbed from '../../../core/interaction/negativeEmbed.js'; import normalizeInteractionReturnable from '../../../core/interaction/normalizeInteractionReturnable.js'; import warningEmbed from '../../../core/interaction/warningEmbed.js'; -import { psa } from '../../../core/process/psa.js'; +import { psa } from '../../../core/node/psa.js'; import { handleError } from '../../error.js'; import { commands } from '../index.js'; export default async function handleChatInputCommand( interaction: ChatInputCommandInteraction, ) { - const command = commands[interaction.commandName]; + const registry = commands[interaction.commandName]; console.log(interaction.toString()); await interaction.deferReply(); try { - const returnable = await command.execute(interaction); + const returnable = await registry.handler(interaction); - if (command.handlesInteraction) return; + if (registry.handlesInteraction) return; - const reply = await normalizeInteractionReturnable(returnable!); + const reply = await normalizeInteractionReturnable(returnable); if (psa.data) { if (!reply.embeds) reply.embeds = []; diff --git a/src/events/interactionCreate/index.ts b/src/events/interactionCreate/index.ts index 2b3d35c04..1594357df 100644 --- a/src/events/interactionCreate/index.ts +++ b/src/events/interactionCreate/index.ts @@ -28,9 +28,9 @@ import searchtanks from '../../commands/searchtanks.js'; import stats from '../../commands/stats.js'; import today from '../../commands/today.js'; import verify from '../../commands/verify.js'; -import { DISCORD_TOKEN } from '../../core/process/args.js'; -import getClientId from '../../core/process/getClientId.js'; -import isDev from '../../core/process/isDev.js'; +import { DISCORD_TOKEN } from '../../core/node/args.js'; +import getClientId from '../../core/node/getClientId.js'; +import isDev from '../../core/node/isDev.js'; import handleAutocomplete from './handlers/autocomplete.js'; import handleButton from './handlers/button.js'; import handleChatInputCommand from './handlers/chatInputCommand.js'; @@ -46,29 +46,26 @@ export type InteractionReturnable = | InteractionIterableReturnable | Promise; -export type CommandRegistry = { +export interface Registry { inDevelopment: boolean; inProduction: boolean; - inPublic: boolean; +} +export interface CommandRegistry + extends Registry { + inPublic: boolean; + handlesInteraction?: HandlesInteraction; command: | SlashCommandBuilder | SlashCommandSubcommandsOnlyBuilder | Omit; + + handler: ( + interaction: ChatInputCommandInteraction, + ) => HandlesInteraction extends true ? void : InteractionReturnable; autocomplete?: (interaction: AutocompleteInteraction) => void; button?: (interaction: ButtonInteraction) => InteractionReturnable; -} & ( - | { - handlesInteraction?: false; - execute: ( - interaction: ChatInputCommandInteraction, - ) => InteractionReturnable; - } - | { - handlesInteraction: true; - execute: (interaction: ChatInputCommandInteraction) => void; - } -); +} const rest = new REST().setToken(DISCORD_TOKEN); diff --git a/src/events/ready.ts b/src/events/ready.ts index 9fd2c068f..e84016295 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -1,5 +1,5 @@ import { Client } from 'discord.js'; -import isDev from '../core/process/isDev.js'; +import isDev from '../core/node/isDev.js'; export default function ready(client: Client) { console.log( diff --git a/src/renderers/evolution.tsx b/src/renderers/evolution.tsx index a4276b935..3a307585e 100644 --- a/src/renderers/evolution.tsx +++ b/src/renderers/evolution.tsx @@ -9,9 +9,9 @@ import resolveTankName from '../core/blitz/resolveTankName.js'; import { tankopedia } from '../core/blitz/tankopedia.js'; import getPlayerHistories from '../core/blitzstars/getPlayerHistories.js'; import getTankHistories from '../core/blitzstars/getTankHistories.js'; -import { ResolvedPeriod } from '../core/options/resolvePeriod.js'; +import { ResolvedPeriod } from '../core/interaction/resolvePeriodFromCommand.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import { ResolvedPlayer } from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { AccountInfo } from '../types/accountInfo.js'; import { Histories } from '../types/histories.js'; import { PlayerClanData } from '../types/playerClanData.js'; diff --git a/src/renderers/stats.tsx b/src/renderers/stats.tsx index cf7d3b9f9..1e5327f9c 100644 --- a/src/renderers/stats.tsx +++ b/src/renderers/stats.tsx @@ -12,9 +12,9 @@ import sumStats from '../core/blitz/sumStats.js'; import { Tier, tankopedia } from '../core/blitz/tankopedia.js'; import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js'; import { tankAverages } from '../core/blitzstars/tankAverages.js'; -import { ResolvedPeriod } from '../core/options/resolvePeriod.js'; +import { ResolvedPeriod } from '../core/interaction/resolvePeriodFromCommand.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import { ResolvedPlayer } from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { AccountInfo, AllStats, diff --git a/src/renderers/today.tsx b/src/renderers/today.tsx index 77650cb6b..385725b03 100644 --- a/src/renderers/today.tsx +++ b/src/renderers/today.tsx @@ -14,8 +14,8 @@ import getPeriodNow from '../core/blitzstars/getPeriodNow.js'; import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js'; import getTimeDaysAgo from '../core/blitzstars/getTimeDaysAgo.js'; import { tankAverages } from '../core/blitzstars/tankAverages.js'; +import { WARGAMING_APPLICATION_ID } from '../core/node/args.js'; import { ResolvedPlayer } from '../core/options/resolvePlayer.js'; -import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { AccountInfo, AllStats } from '../types/accountInfo.js'; import { PlayerClanData } from '../types/playerClanData.js'; diff --git a/src/responders/stats.tsx b/src/responders/stats.tsx new file mode 100644 index 000000000..ac5cba514 --- /dev/null +++ b/src/responders/stats.tsx @@ -0,0 +1,24 @@ +import { BlitzServer } from '../constants/servers.js'; +import resolvePeriodFromCommand from '../core/interaction/resolvePeriodFromCommand.js'; +import stats, { StatType } from '../renderers/stats.js'; +import { ResponderRegistry } from '../server.js'; + +export default { + route: '/stats/:type/:period', + inProduction: true, + inDevelopment: true, + + async handler(req) { + console.log('yeah'); + + return await stats( + req.params.type as StatType, + resolvePeriodFromCommand(req), + { + server: req.query.server as BlitzServer, + id: parseInt(req.query.id as string), + }, + parseInt(req.query.tank as string), + ); + }, +} satisfies ResponderRegistry; diff --git a/src/server.ts b/src/server.ts index 099ce5b56..0c2cf6462 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,18 +1,40 @@ -import express from 'express'; -import jsxToSvg from './core/ui/jsxToSvg.js'; -import today from './renderers/today.js'; +import express, { Request, Response } from 'express'; +import normalizeResponderReturnable from './core/express/normalizeResponderReturnable.js'; +import isDev from './core/node/isDev.js'; +import { Registry } from './events/interactionCreate/index.js'; +import stats from './responders/stats.js'; + +export type ResponderReturnable = JSX.Element | Promise; + +export interface ResponderRegistry + extends Registry { + route: string; + handlesInteraction?: HandlesInteraction; + + handler: ( + req: Request, + res: Response, + ) => HandlesInteraction extends true ? void : ResponderReturnable; +} const app = express(); -app.get('/', async (req, res) => { - const jsx = await today({ server: 'com', id: 1028700193 }); - const svg = await jsxToSvg(jsx); +([stats] as ResponderRegistry[]).forEach((registry) => { + if (!(isDev() ? registry.inDevelopment : registry.inProduction)) return; - res.writeHead(200, { - 'Content-Type': 'image/svg+xml', - 'Content-Length': svg.length, + app.get(registry.route, async (req, res) => { + const returnable = registry.handler(req, res); + + if (registry.handlesInteraction) return; + + const response = await normalizeResponderReturnable(returnable); + + res.writeHead(200, { + 'Content-Type': 'image/svg+xml', + 'Content-Length': response.length, + }); + res.end(response); }); - res.end(svg); }); app.listen(process.env.PORT ?? 3000); diff --git a/tsconfig.json b/tsconfig.json index 8ca930d1c..61fa9c597 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,5 +11,5 @@ "resolveJsonModule": true, "jsx": "react-jsx" }, - "include": ["src/**/*.ts", "src/renderers/stats.tsx", "src/events/interactionCreate/handlers/button.tsx"] + "include": ["src/**/*.ts", "src/renderers/stats.tsx", "src/events/interactionCreate/handlers/button.tsx", "src/responders/stats.tsx"] }