From c0ec15b7ded7fa303d47434f86cb30d15e6b8da0 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Fri, 21 Mar 2025 21:47:08 +0200 Subject: [PATCH] Unify db type files --- app/components/Avatar.tsx | 4 +- app/components/BuildCard.tsx | 11 +- app/components/Combobox.tsx | 2 +- app/components/MapPoolSelector.tsx | 10 +- app/db/seed/index.ts | 7 +- app/db/tables.ts | 73 ++- app/db/types.ts | 602 ------------------ app/features/art/art-types.ts | 24 +- app/features/art/queries/addNewArt.server.ts | 21 +- app/features/art/queries/allArtTags.server.ts | 4 +- .../art/queries/findArtById.server.ts | 14 +- .../art/queries/showcaseArts.server.ts | 4 +- app/features/auth/core/user.server.ts | 4 +- .../auth/queries/createLogInLink.server.ts | 4 +- app/features/badges/badges-utils.ts | 4 +- .../badges/routes/badges.$id.edit.tsx | 6 +- .../builds/queries/buildsBy.server.ts | 27 +- .../calendar/CalendarRepository.server.ts | 9 +- .../calendar/actions/calendar.new.server.ts | 7 +- app/features/calendar/calendar-constants.ts | 2 +- app/features/calendar/components/Tags.tsx | 2 +- app/features/calendar/routes/calendar.new.tsx | 5 +- app/features/calendar/routes/calendar.tsx | 5 +- app/features/chat/components/Chat.tsx | 7 +- .../img-upload/queries/addNewImage.ts | 4 +- .../img-upload/queries/oneUnvalidatedImage.ts | 4 +- .../queries/XPLeaderboard.server.ts | 18 +- .../seasonPopularUsersWeapon.server.ts | 9 +- .../queries/userSPLeaderboard.server.ts | 14 +- .../core/map-list-generator/utils.ts | 4 +- .../map-list-generator/core/map-pool.ts | 6 +- .../map-list-generator/routes/maps.tsx | 4 +- .../findCurrentSkillByUserId.server.ts | 4 +- ...findCurrentTeamSkillByIdentifier.server.ts | 4 +- .../mmr/queries/orderedMMRBySeason.server.ts | 4 +- app/features/mmr/tiered.server.ts | 4 +- .../routes/plus.suggestions.new.tsx | 2 +- .../routes/plus.suggestions.tsx | 6 +- app/features/plus-voting/core/types.ts | 4 +- .../plus-voting/core/usePlusVoting.ts | 4 +- .../routes/plus.voting.results.tsx | 2 +- .../sendouq-match/QMatchRepository.server.ts | 3 +- app/features/sendouq/components/GroupCard.tsx | 4 +- app/features/sendouq/core/groups.server.ts | 3 +- app/features/sendouq/core/groups.ts | 4 +- app/features/sendouq/core/skills.server.ts | 23 +- .../sendouq/core/summarizer.server.ts | 6 +- app/features/sendouq/q-types.ts | 27 +- app/features/sendouq/q-utils.ts | 6 +- .../sendouq/queries/addMapResults.server.ts | 4 +- .../sendouq/queries/addMember.server.ts | 4 +- .../queries/addPlayerResults.server.ts | 4 +- .../sendouq/queries/addSkills.server.ts | 6 +- .../sendouq/queries/createMatch.server.ts | 5 +- .../findCurrentGroupByUserId.server.ts | 6 +- .../queries/findGroupByInviteCode.server.ts | 10 +- .../sendouq/queries/findMatchById.server.ts | 21 +- .../findRecentMatchPlayersByUserId.server.ts | 7 +- .../sendouq/queries/groupSuccessorOwner.ts | 4 +- .../sendouq/queries/morphGroups.server.ts | 11 +- .../sendouq/queries/reportScore.server.ts | 4 +- .../reportedWeaponsByMatchId.server.ts | 6 +- .../queries/seasonMatchesByUserId.server.ts | 29 +- .../queries/seasonStagesByUserId.server.ts | 4 +- .../seasonsMatesEnemiesByUserId.server.ts | 6 +- .../queries/setGroupAsActive.server.ts | 4 +- .../sendouq/queries/updateNote.server.ts | 8 +- app/features/sendouq/routes/q.match.$id.tsx | 4 +- app/features/sendouq/routes/q.tsx | 4 +- app/features/team/loaders/t.server.ts | 2 +- .../queries/findPlacements.server.ts | 12 +- app/features/top-search/routes/xsearch.tsx | 4 +- .../core/brackets-manager/crud-db.server.ts | 132 ++-- .../core/summarizer.server.ts | 19 +- .../queries/addSummary.server.ts | 4 +- .../queries/bestOfsByTournamentId.server.ts | 6 +- .../queries/findMapPoolByTeamId.server.ts | 6 +- .../queries/findMatchById.server.ts | 30 +- .../queries/findResultsByMatchId.server.ts | 11 +- ...dTieBreakerMapPoolByTournamentId.server.ts | 4 +- .../insertTournamentMatchGameResult.server.ts | 3 +- .../playersThatPlayedByTeamId.server.ts | 4 +- .../tournament-bracket-utils.ts | 5 +- .../queries/deleteSub.server.ts | 4 +- .../queries/findSubsByTournamentId.server.ts | 12 +- .../queries/upsertSub.server.ts | 4 +- .../tournament/components/TeamWithRoster.tsx | 8 +- app/features/tournament/core/sets.server.ts | 3 +- .../queries/changeTeamOwner.server.ts | 8 +- .../queries/findByIdentifier.server.ts | 18 +- .../findMapPoolsByTournamentId.server.ts | 4 +- .../queries/findOwnTournamentTeam.server.ts | 6 +- .../queries/hasTournamentFinalized.server.ts | 6 +- .../queries/hasTournamentStarted.server.ts | 6 +- .../queries/setHistoryByTeamId.server.ts | 11 +- .../queries/upsertCounterpickMaps.server.ts | 4 +- app/features/tournament/tournament-utils.ts | 5 +- .../user-page/UserRepository.server.ts | 6 +- .../routes/u.$identifier.builds.new.tsx | 2 +- .../user-page/routes/u.$identifier.edit.tsx | 8 +- app/features/vods/queries/createVod.server.ts | 4 +- app/features/vods/queries/findVods.server.ts | 4 +- app/features/vods/routes/vods.new.tsx | 10 +- app/features/vods/vods-constants.ts | 7 +- app/features/vods/vods-types.ts | 20 +- app/features/vods/vods-utils.ts | 8 +- .../test/double-elimination.test.ts | 18 +- .../test/single-elimination.test.ts | 30 +- .../brackets-manager/test/update.test.ts | 34 +- app/permissions.ts | 29 +- app/utils/strings.ts | 2 +- app/utils/urls.ts | 28 +- app/utils/users.ts | 4 +- scripts/placements/index.ts | 4 +- scripts/season-initial-powers.ts | 6 +- 115 files changed, 602 insertions(+), 1145 deletions(-) delete mode 100644 app/db/types.ts diff --git a/app/components/Avatar.tsx b/app/components/Avatar.tsx index 47812a308..46c63c9c4 100644 --- a/app/components/Avatar.tsx +++ b/app/components/Avatar.tsx @@ -1,6 +1,6 @@ import clsx from "clsx"; import * as React from "react"; -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { BLANK_IMAGE_URL, discordAvatarUrl } from "~/utils/urls"; const dimensions = { @@ -21,7 +21,7 @@ function _Avatar({ alt = "", ...rest }: { - user?: Pick; + user?: Pick; url?: string; className?: string; alt?: string; diff --git a/app/components/BuildCard.tsx b/app/components/BuildCard.tsx index 3e7aa1bc9..2499345b0 100644 --- a/app/components/BuildCard.tsx +++ b/app/components/BuildCard.tsx @@ -1,12 +1,7 @@ import clsx from "clsx"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; -import type { - Build, - BuildWeapon, - GearType, - UserWithPlusTier, -} from "~/db/types"; +import type { GearType, Tables, UserWithPlusTier } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import type { BuildWeaponWithTop500Info } from "~/features/builds/queries/buildsBy.server"; import { useIsMounted } from "~/hooks/useIsMounted"; @@ -41,7 +36,7 @@ import { TrashIcon } from "./icons/Trash"; interface BuildProps { build: Pick< - Build, + Tables["Build"], | "id" | "title" | "description" @@ -55,7 +50,7 @@ interface BuildProps { unsortedAbilities: BuildAbilitiesTuple; modes: ModeShort[] | null; weapons: Array<{ - weaponSplId: BuildWeapon["weaponSplId"]; + weaponSplId: Tables["BuildWeapon"]["weaponSplId"]; minRank: number | null; maxPower: number | null; }>; diff --git a/app/components/Combobox.tsx b/app/components/Combobox.tsx index 479e9a2b7..1371e5ed4 100644 --- a/app/components/Combobox.tsx +++ b/app/components/Combobox.tsx @@ -3,7 +3,7 @@ import clsx from "clsx"; import Fuse, { type IFuseOptions } from "fuse.js"; import * as React from "react"; import { useTranslation } from "react-i18next"; -import type { GearType } from "~/db/types"; +import type { GearType } from "~/db/tables"; import type { SerializedMapPoolEvent } from "~/features/calendar/routes/map-pool-events"; import { useAllEventsWithMapPools } from "~/hooks/swr"; import type { MainWeaponId } from "~/modules/in-game-lists"; diff --git a/app/components/MapPoolSelector.tsx b/app/components/MapPoolSelector.tsx index d5bdea437..f9f2b75b5 100644 --- a/app/components/MapPoolSelector.tsx +++ b/app/components/MapPoolSelector.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; import { Button } from "~/components/Button"; import { Image } from "~/components/Image"; -import type { CalendarEvent } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { SerializedMapPoolEvent } from "~/features/calendar/routes/map-pool-events"; import { MapPool } from "~/features/map-list-generator/core/map-pool"; import { BANNED_MAPS } from "~/features/sendouq-settings/banned-maps"; @@ -26,11 +26,11 @@ export type MapPoolSelectorProps = { handleRemoval?: () => void; handleMapPoolChange: ( mapPool: MapPool, - event?: Pick, + event?: Pick, ) => void; className?: string; recentEvents?: SerializedMapPoolEvent[]; - initialEvent?: Pick; + initialEvent?: Pick; title?: string; modesToInclude?: ModeShort[]; info?: React.ReactNode; @@ -376,7 +376,7 @@ function detectTemplate(mapPool: MapPool): MapPoolTemplateValue { type MapPoolTemplateSelectProps = { value: MapPoolTemplateValue; handleChange: (newValue: MapPoolTemplateValue) => void; - recentEvents?: Pick[]; + recentEvents?: Pick[]; }; function MapPoolTemplateSelect({ @@ -428,7 +428,7 @@ function MapPoolTemplateSelect({ type TemplateEventSelectionProps = { handleEventChange: ( mapPool: MapPool, - event?: Pick, + event?: Pick, ) => void; initialEvent?: SerializedMapPoolEvent; }; diff --git a/app/db/seed/index.ts b/app/db/seed/index.ts index e1b9ab43e..6b579fc57 100644 --- a/app/db/seed/index.ts +++ b/app/db/seed/index.ts @@ -71,7 +71,6 @@ import { dateToDatabaseTimestamp } from "~/utils/dates"; import invariant from "~/utils/invariant"; import { mySlugify } from "~/utils/urls"; import type { Tables, UserMapModePreferences } from "../tables"; -import type { Art, UserSubmittedImage } from "../types"; import { ADMIN_TEST_AVATAR, AMOUNT_OF_CALENDAR_EVENTS, @@ -1950,12 +1949,12 @@ function arts() { validatedAt: dateToDatabaseTimestamp(new Date()), url: getUrl(), submitterUserId: userId, - }) as UserSubmittedImage + }) as Tables["UserSubmittedImage"] ).id, authorId: userId, isShowcase: i === 0 ? 1 : 0, description: Math.random() > 0.5 ? faker.lorem.paragraph() : null, - }) as Art; + }) as Tables["Art"]; if (i === 1) { for ( @@ -2204,7 +2203,7 @@ async function playedMatches() { skills: newSkills, differences, groupMatchId: match.id, - oldMatchMemento: { users: {}, groups: {} }, + oldMatchMemento: { users: {}, groups: {}, pools: [] }, }); setGroupAsInactive(groupAlpha); setGroupAsInactive(groupBravo); diff --git a/app/db/tables.ts b/app/db/tables.ts index 36f70e0af..78fc8f5a7 100644 --- a/app/db/tables.ts +++ b/app/db/tables.ts @@ -6,6 +6,10 @@ import type { SqlBool, Updateable, } from "kysely"; +import type { + persistedTags, + tags, +} from "~/features/calendar/calendar-constants"; import type { TieredSkill } from "~/features/mmr/tiered.server"; import type { Notification as NotificationValue } from "~/features/notifications/notifications-types"; import type { TEAM_MEMBER_ROLES } from "~/features/team/team-constants"; @@ -17,7 +21,6 @@ import type { ModeShort, StageId, } from "~/modules/in-game-lists"; -import type { GroupSkillDifference, UserSkillDifference } from "./types"; export type Generated = T extends ColumnType ? ColumnType @@ -103,10 +106,12 @@ export interface Build { updatedAt: Generated; } +export type GearType = "HEAD" | "CLOTHES" | "SHOES"; + export interface BuildAbility { ability: Ability; buildId: number; - gearType: string; + gearType: GearType; slotIndex: number; } @@ -121,6 +126,9 @@ export type CalendarEventAvatarMetadata = { textColor: string; }; +export type PersistedCalendarEventTag = keyof typeof persistedTags; +export type CalendarEventTag = keyof typeof tags; + export interface CalendarEvent { authorId: number; bracketUrl: string; @@ -189,6 +197,27 @@ export interface GroupLike { isRechallenge: number | null; } +type CalculatingSkill = { + calculated: false; + matchesCount: number; + matchesCountNeeded: number; + /** Freshly calculated skill */ + newSp?: number; +}; +export type UserSkillDifference = + | { + calculated: true; + spDiff: number; + } + | CalculatingSkill; +export type GroupSkillDifference = + | { + calculated: true; + oldSp: number; + newSp: number; + } + | CalculatingSkill; + export type ParsedMemento = { users: Record< number, @@ -359,7 +388,7 @@ export interface PlusVotingResult { export interface ReportedWeapon { groupMatchMapId: number | null; userId: number; - weaponSplId: number; + weaponSplId: MainWeaponId; } export interface Skill { @@ -492,6 +521,23 @@ export interface TournamentGroup { stageId: number; } +export const TournamentMatchStatus = { + /** The two matches leading to this one are not completed yet. */ + Locked: 0, + + /** One participant is ready and waiting for the other one. */ + Waiting: 1, + + /** Both participants are ready to start. */ + Ready: 2, + + /** The match is running. */ + Running: 3, + + /** The match is completed. */ + Completed: 4, +}; + export interface TournamentMatch { // TODO: remove bestOf: Generated<3 | 5 | 7>; @@ -503,7 +549,7 @@ export interface TournamentMatch { opponentTwo: ColumnType; roundId: number; stageId: number; - status: number; + status: (typeof TournamentMatchStatus)[keyof typeof TournamentMatchStatus]; // used only for swiss because it's the only stage type where matches are not created in advance createdAt: Generated; } @@ -807,6 +853,11 @@ export interface User { preferences: ColumnType; } +/** Represents User joined with PlusTier table */ +export type UserWithPlusTier = Tables["User"] & { + plusTier: PlusTier["tier"] | null; +}; + export interface UserResultHighlight { teamId: number; userId: number; @@ -815,7 +866,7 @@ export interface UserResultHighlight { export interface UserSubmittedImage { id: GeneratedAlways; submitterUserId: number | null; - url: string | null; + url: string; validatedAt: number | null; } @@ -837,12 +888,12 @@ export interface UserFriendCode { export interface Video { eventId: number | null; id: GeneratedAlways; - submitterUserId: number | null; - title: string | null; - type: string | null; + submitterUserId: number; + title: string; + type: "SCRIM" | "TOURNAMENT" | "MATCHMAKING" | "CAST" | "SENDOUQ"; validatedAt: number | null; - youtubeDate: number | null; - youtubeId: string | null; + youtubeDate: number; + youtubeId: string; } export interface VideoMatch { @@ -872,7 +923,7 @@ export interface XRankPlacement { playerId: number; power: number; rank: number; - region: string; + region: "WEST" | "JPN"; title: string; weaponSplId: MainWeaponId; year: number; diff --git a/app/db/types.ts b/app/db/types.ts deleted file mode 100644 index fb3ee63f6..000000000 --- a/app/db/types.ts +++ /dev/null @@ -1,602 +0,0 @@ -import type { - persistedTags, - tags, -} from "~/features/calendar/calendar-constants"; -import type { TieredSkill } from "~/features/mmr/tiered.server"; -import type { TEAM_MEMBER_ROLES } from "~/features/team/team-constants"; -import type { - Ability, - MainWeaponId, - ModeShort, - RankedModeShort, - StageId, -} from "~/modules/in-game-lists"; - -export interface User { - id: number; - discordId: string; - /** Discord display name aka global name (non-unique) */ - discordName: string; - username: string; - discordAvatar: string | null; - /** Discord username (unique) */ - discordUniqueName: string | null; - showDiscordUniqueName: number; - twitch: string | null; - youtubeId: string | null; - bio: string | null; - css: string | null; - country: string | null; - customUrl: string | null; - stickSens: number | null; - motionSens: number | null; - inGameName: string | null; - patronTier: number | null; - patronSince: number | null; - /** Used to overwrite normal patron giving process and force give the patron status till this date */ - patronTill: number | null; - isVideoAdder: number; - isArtist: number; - favoriteBadgeId: number | null; - commissionsOpen: number; - commissionText: string | null; - banned: number; - vc: "YES" | "NO" | "LISTEN_ONLY"; - languages: string | null; -} - -/** User table after joined with PlusTier table */ -export interface UserWithPlusTier extends User { - plusTier: PlusTier["tier"] | null; -} - -export interface UserWeapon { - userId: number; - weaponSplId: MainWeaponId; - createdAt: number; - order: number; - isFavorite: number; -} - -export interface LogInLink { - code: string; - expiresAt: number; - userId: number; -} - -export interface PlusSuggestion { - id: number; - text: string; - authorId: number; - suggestedId: number; - month: number; - year: number; - tier: number; - createdAt: number; -} - -export interface PlusVote { - month: number; - year: number; - tier: number; - authorId: number; - votedId: number; - score: number; - validAfter: number; -} - -export interface PlusVotingResult { - votedId: number; - tier: number; - score: number; - month: number; - year: number; - wasSuggested: number; - passedVoting: number; -} - -export interface PlusTier { - userId: number; - tier: number; -} - -export interface Badge { - id: number; - code: string; - displayName: string; - hue?: number; -} - -/** View that is union of TournamentBadgeOwner and Patreon badges */ -export interface BadgeOwner { - badgeId: number; - userId: number; -} - -export interface TournamentBadgeOwner { - badgeId: number; - userId: number; -} - -export interface BadgeManager { - badgeId: number; - userId: number; -} - -export interface CalendarEvent { - id: number; - name: string; - authorId: number; - tags: string | null; - description: string | null; - discordInviteCode: string | null; - // generated column - discordUrl: string | null; - bracketUrl: string; - participantCount: number | null; - tournamentId: number | null; -} - -export type PersistedCalendarEventTag = keyof typeof persistedTags; -export type CalendarEventTag = keyof typeof tags; - -export interface CalendarEventDate { - id: number; - eventId: number; - startTime: number; -} - -export interface CalendarEventResultTeam { - id: number; - eventId: number; - name: string; - placement: number; -} - -export interface CalendarEventResultPlayer { - teamId: number; - userId: number | null; - name: string | null; -} - -export interface UserResultHighlight { - teamId: number; - userId: number; -} - -export interface CalendarEventBadge { - eventId: number; - badgeId: number; -} - -export interface Build { - id: number; - ownerId: number; - title: string; - /** Private builds are only visible on the user builds page to the owner only */ - private: number | null; - description: string | null; - modes: string | null; - headGearSplId: number; - clothesGearSplId: number; - shoesGearSplId: number; - updatedAt: number; -} - -export interface BuildWeapon { - buildId: number; - weaponSplId: MainWeaponId; -} - -export type GearType = "HEAD" | "CLOTHES" | "SHOES"; - -export interface BuildAbility { - buildId: number; - gearType: "HEAD" | "CLOTHES" | "SHOES"; - ability: Ability; - slotIndex: 0 | 1 | 2 | 3; - abilityPoints: number; // 3 or 10 -} - -export interface MapPoolMap { - calendarEventId: number | null; // Part of tournament's map pool - tournamentTeamId: number | null; // Part of team's map pool - tieBreakerCalendarEventId: number | null; // Part of the tournament's tiebreaker pool - stageId: StageId; - mode: ModeShort; -} - -// AUTO = style where teams pick their map pool ahead of time and the map lists are automatically made for each round -// could also have the traditional style where TO picks the maps later -type TournamentMapPickingStyle = - | "AUTO_ALL" - | "AUTO_SZ" - | "AUTO_TC" - | "AUTO_RM" - | "AUTO_CB"; - -// TODO: later also e.g. RR_TO_DE where we also need an additional field -// describing how many teams advance -export type TournamentFormat = "SE" | "DE"; - -export interface Tournament { - id: number; - mapPickingStyle: TournamentMapPickingStyle; - format: TournamentFormat; -} - -export interface TournamentTeam { - id: number; - name: string; - createdAt: number; - seed: number | null; - tournamentId: number; - inviteCode: string; - prefersNotToHost: number; -} - -export interface TournamentTeamCheckIn { - tournamentTeamId: number; - checkedInAt: number; -} - -export interface TournamentTeamMember { - tournamentTeamId: number; - userId: number; - isOwner: number; - createdAt: number; -} - -/** A stage is an intermediate phase in a tournament. - * Supported stage types are round-robin, single elimination and double elimination. */ -export interface TournamentStage { - id: number; - tournamentId: number; - name: string; - type: "round_robin" | "single_elimination" | "double_elimination"; - settings: string; // json - number: number; - createdAt: number | null; -} - -/** A group is a logical structure used to group multiple rounds together. - -- In round-robin stages, a group is a pool. -- In elimination stages, a group is a bracket. - - A single elimination stage can have one or two groups: - - The unique bracket. - - If enabled, the Consolation Final. - - A double elimination stage can have two or three groups: - - Upper and lower brackets. - - If enabled, the Grand Final. */ -export interface TournamentGroup { - id: number; - stageId: number; - /** In double elimination 1 = Winners, 2 = Losers, 3 = Grand Finals+Bracket Reset */ - number: number; -} - -/** - * A round is a logical structure used to group multiple matches together. - - - In round-robin stages, a round can be viewed as a day or just as a list of matches that can be played at the same time. - - In elimination stages, a round is a round of a bracket, e.g. 8th finals, semi-finals, etc. - */ -export interface TournamentRound { - id: number; - stageId: number; - groupId: number; - number: number; -} - -export enum Status { - /** The two matches leading to this one are not completed yet. */ - Locked = 0, - - /** One participant is ready and waiting for the other one. */ - Waiting = 1, - - /** Both participants are ready to start. */ - Ready = 2, - - /** The match is running. */ - Running = 3, - - /** The match is completed. */ - Completed = 4, -} - -/** A match between two participants (more participants are not allowed). - * Participants can be teams or individuals. */ -export interface TournamentMatch { - id: number; - bestOf: 3 | 5 | 7; - roundId: number; - stageId: number; - groupId: number; - number: number; - opponentOne: string; // json - opponentTwo: string; // json - status: Status; - chatCode: string | null; -} - -export interface TournamentMatchGameResult { - id: number; - matchId: number; - number: number; - stageId: StageId; - mode: ModeShort; - /** serialized TournamentMaplistSource */ - source: string; - winnerTeamId: number; - reporterId: number; - createdAt: number; -} - -export interface TournamentMatchGameResultParticipant { - matchGameResultId: number; - userId: number; -} - -export interface TournamentSub { - userId: number; - tournamentId: number; - canVc: number; - bestWeapons: string; - okWeapons: string | null; - message: string | null; - visibility: "+1" | "+2" | "+3" | "ALL"; - createdAt: number; -} - -export interface Skill { - id: number; - mu: number; - sigma: number; - ordinal: number; - userId: number | null; - /** e.g. 12-24-44-1024 for "team skills" */ - identifier: string | null; - matchesCount: number; - /** Tournament that caused the skill to change */ - tournamentId: number | null; - /** Group match that caused the skill to change */ - groupMatchId: number | null; - season: number; -} - -export interface SkillTeamUser { - userId: number; - skillId: number; -} - -export interface MapResult { - mode: ModeShort; - stageId: StageId; - userId: number; - wins: number; - losses: number; - season: number; -} - -export interface PlayerResult { - ownerUserId: number; - otherUserId: number; - mapWins: number; - mapLosses: number; - setWins: number; - setLosses: number; - type: "MATE" | "ENEMY"; - season: number; -} - -export interface TournamentResult { - tournamentId: number; - userId: number; - placement: number; - participantCount: number; - tournamentTeamId: number; - isHighlight: number; -} - -export interface TrustRelationship { - trustGiverUserId: number; - trustReceiverUserId: number; -} - -export interface UserSubmittedImage { - id: number; - validatedAt: number | null; - url: string; - submitterUserId: number; -} - -export interface Team { - id: number; - name: string; - customUrl: string; - inviteCode: string; - css: string | null; - bio: string | null; - avatarImgId: number | null; - bannerImgId: number | null; - createdAt: number; - deletedAt: number | null; -} - -export type MemberRole = (typeof TEAM_MEMBER_ROLES)[number]; - -export interface TeamMember { - teamId: number; - userId: number; - role: MemberRole | null; - isOwner: number; - createdAt: number; - leftAt: number | null; -} - -export interface Video { - id: number; - title: string; - type: "SCRIM" | "TOURNAMENT" | "MATCHMAKING" | "CAST" | "SENDOUQ"; - youtubeDate: number; - eventId: number | null; - youtubeId: string; - submitterUserId: number; - validatedAt: number | null; -} - -export interface VideoMatch { - id: number; - videoId: number; - startsAt: number; - stageId: StageId; - mode: ModeShort; -} - -export interface VideoMatchPlayer { - videoMatchId: number; - playerUserId: number | null; - playerName: string | null; - weaponSplId: MainWeaponId; - player: number; -} - -export interface XRankPlacement { - id: number; - weaponSplId: MainWeaponId; - name: string; - nameDiscriminator: string; - power: number; - rank: number; - title: string; - badges: string; // badge id's separated by comma - bannerSplId: number; - playerId: number; - month: number; - year: number; - mode: RankedModeShort; - region: "WEST" | "JPN"; -} - -export interface SplatoonPlayer { - id: number; - userId: number; - splId: string; -} - -export interface Art { - id: number; - imgId: number; - authorId: number; - isShowcase: number; - description: string | null; - createdAt: number; -} - -export interface ArtTag { - id: number; - name: string; - authorId: number; - createdAt: number; -} - -export interface TaggedArt { - artId: number; - tagId: number; -} - -export interface ArtUserMetadata { - artId: number; - userId: number; -} - -export interface Group { - id: number; - teamId: number | null; - createdAt: number; - latestActionAt: number; - inviteCode: string; - chatCode: string | null; - status: "PREPARING" | "ACTIVE" | "INACTIVE"; -} - -export interface GroupMember { - groupId: number; - userId: number; - role: "OWNER" | "MANAGER" | "REGULAR"; - note: string | null; - createdAt: number; -} - -export interface GroupLike { - likerGroupId: number; - targetGroupId: number; - createdAt: number; -} - -type CalculatingSkill = { - calculated: false; - matchesCount: number; - matchesCountNeeded: number; - /** Freshly calculated skill */ - newSp?: number; -}; -export type UserSkillDifference = - | { - calculated: true; - spDiff: number; - } - | CalculatingSkill; -export type GroupSkillDifference = - | { - calculated: true; - oldSp: number; - newSp: number; - } - | CalculatingSkill; -export type ParsedMemento = { - users: Record< - User["id"], - { - plusTier?: PlusTier["tier"]; - skill?: TieredSkill; - skillDifference?: UserSkillDifference; - } - >; - groups: Record< - Group["id"], - { - tier?: TieredSkill["tier"]; - skillDifference?: GroupSkillDifference; - } - >; -}; -export interface GroupMatch { - id: number; - alphaGroupId: number; - bravoGroupId: number; - createdAt: number; - reportedAt: number | null; - reportedByUserId: number | null; - chatCode: string | null; - memento: string | null; -} - -export interface GroupMatchMap { - id: number; - matchId: number; - index: number; - mode: ModeShort; - stageId: StageId; - /** serialized TournamentMaplistSource */ - source: string; - winnerGroupId: number | null; -} - -export interface ReportedWeapon { - groupMatchMapId: number | null; - weaponSplId: MainWeaponId; - userId: User["id"]; -} diff --git a/app/features/art/art-types.ts b/app/features/art/art-types.ts index 351acc20b..def8e528a 100644 --- a/app/features/art/art-types.ts +++ b/app/features/art/art-types.ts @@ -1,21 +1,21 @@ -import type { Art, User, UserSubmittedImage } from "~/db/types"; +import type { Tables } from "~/db/tables"; export interface ListedArt { - id: Art["id"]; - createdAt: Art["createdAt"]; - url: UserSubmittedImage["url"]; - description?: Art["description"]; + id: Tables["Art"]["id"]; + createdAt: Tables["Art"]["createdAt"]; + url: Tables["UserSubmittedImage"]["url"]; + description?: Tables["Art"]["description"]; tags?: string[]; linkedUsers?: Array<{ - discordId: User["discordId"]; - username: User["username"]; - customUrl: User["customUrl"]; + discordId: Tables["User"]["discordId"]; + username: Tables["User"]["username"]; + customUrl: Tables["User"]["customUrl"]; }>; author?: { - discordId: User["discordId"]; - username: User["username"]; - discordAvatar: User["discordAvatar"]; - commissionsOpen?: User["commissionsOpen"]; + discordId: Tables["User"]["discordId"]; + username: Tables["User"]["username"]; + discordAvatar: Tables["User"]["discordAvatar"]; + commissionsOpen?: Tables["User"]["commissionsOpen"]; }; } diff --git a/app/features/art/queries/addNewArt.server.ts b/app/features/art/queries/addNewArt.server.ts index da943b0b2..686a47b14 100644 --- a/app/features/art/queries/addNewArt.server.ts +++ b/app/features/art/queries/addNewArt.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Art, ArtTag, UserSubmittedImage } from "~/db/types"; +import type { Tables } from "~/db/tables"; import invariant from "~/utils/invariant"; const addImgStm = sql.prepare(/* sql */ ` @@ -92,9 +92,9 @@ const removeUserMetadataStm = sql.prepare(/* sql */ ` "artId" = @artId `); -type TagsToAdd = Array>>; -type AddNewArtArgs = Pick & - Pick & { +type TagsToAdd = Array>>; +type AddNewArtArgs = Pick & + Pick & { linkedUsers: number[]; tags: TagsToAdd; }; @@ -104,12 +104,12 @@ export const addNewArt = sql.transaction((args: AddNewArtArgs) => { authorId: args.authorId, url: args.url, validatedAt: args.validatedAt, - }) as UserSubmittedImage; + }) as Tables["UserSubmittedImage"]; const art = addArtStm.get({ authorId: args.authorId, description: args.description, imgId: img.id, - }) as Art; + }) as Tables["Art"]; for (const userId of args.linkedUsers) { addArtUserMetadataStm.run({ artId: art.id, userId }); @@ -123,7 +123,7 @@ export const addNewArt = sql.transaction((args: AddNewArtArgs) => { const newTag = addArtTagStm.get({ name: tag.name, authorId: args.authorId, - }) as ArtTag; + }) as Tables["ArtTag"]; tagId = newTag.id; } @@ -133,7 +133,10 @@ export const addNewArt = sql.transaction((args: AddNewArtArgs) => { return art.id; }); -type EditArtArgs = Pick & { +type EditArtArgs = Pick< + Tables["Art"], + "authorId" | "description" | "isShowcase" +> & { linkedUsers: number[]; artId: number; tags: TagsToAdd; @@ -166,7 +169,7 @@ export const editArt = sql.transaction((args: EditArtArgs) => { const newTag = addArtTagStm.get({ name: tag.name, authorId: args.authorId, - }) as ArtTag; + }) as Tables["ArtTag"]; tagId = newTag.id; } diff --git a/app/features/art/queries/allArtTags.server.ts b/app/features/art/queries/allArtTags.server.ts index 0c50bba8b..be6b3f03f 100644 --- a/app/features/art/queries/allArtTags.server.ts +++ b/app/features/art/queries/allArtTags.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { ArtTag } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -9,6 +9,6 @@ const stm = sql.prepare(/* sql */ ` "ArtTag" `); -export function allArtTags(): Array> { +export function allArtTags(): Array> { return stm.all() as any; } diff --git a/app/features/art/queries/findArtById.server.ts b/app/features/art/queries/findArtById.server.ts index 1a01c38b2..03a930e79 100644 --- a/app/features/art/queries/findArtById.server.ts +++ b/app/features/art/queries/findArtById.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Art, ArtTag, User, UserSubmittedImage } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { parseDBArray } from "~/utils/sql"; const findArtStm = sql.prepare(/* sql */ ` @@ -26,12 +26,12 @@ const findTagsStm = sql.prepare(/* sql */ ` `); interface FindArtById { - isShowcase: Art["isShowcase"]; - description: Art["description"]; - url: UserSubmittedImage["url"]; - authorId: Art["authorId"]; - linkedUsers: User["id"][]; - tags: Array>; + isShowcase: Tables["Art"]["isShowcase"]; + description: Tables["Art"]["description"]; + url: Tables["UserSubmittedImage"]["url"]; + authorId: Tables["Art"]["authorId"]; + linkedUsers: Tables["User"]["id"][]; + tags: Array>; } export function findArtById(artId: number): FindArtById | null { diff --git a/app/features/art/queries/showcaseArts.server.ts b/app/features/art/queries/showcaseArts.server.ts index f85996d2f..0648111c6 100644 --- a/app/features/art/queries/showcaseArts.server.ts +++ b/app/features/art/queries/showcaseArts.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { ArtTag } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { ListedArt } from "../art-types"; const showcaseArtsStm = sql.prepare(/* sql */ ` @@ -55,7 +55,7 @@ const showcaseArtsByTagStm = sql.prepare(/* sql */ ` `); -export function showcaseArtsByTag(tagId: ArtTag["id"]): ListedArt[] { +export function showcaseArtsByTag(tagId: Tables["ArtTag"]["id"]): ListedArt[] { const encounteredUserIds = new Set(); return showcaseArtsByTagStm diff --git a/app/features/auth/core/user.server.ts b/app/features/auth/core/user.server.ts index 5b291cb59..52dd7bd6b 100644 --- a/app/features/auth/core/user.server.ts +++ b/app/features/auth/core/user.server.ts @@ -1,5 +1,5 @@ import { redirect } from "@remix-run/node"; -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { userIsBanned } from "~/features/ban/core/banned.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { SUSPENDED_PAGE } from "~/utils/urls"; @@ -9,7 +9,7 @@ import { authSessionStorage } from "./session.server"; export async function getUserId( request: Request, redirectIfBanned = true, -): Promise | undefined> { +): Promise | undefined> { const session = await authSessionStorage.getSession( request.headers.get("Cookie"), ); diff --git a/app/features/auth/queries/createLogInLink.server.ts b/app/features/auth/queries/createLogInLink.server.ts index f19c53440..01a8d47ce 100644 --- a/app/features/auth/queries/createLogInLink.server.ts +++ b/app/features/auth/queries/createLogInLink.server.ts @@ -1,6 +1,6 @@ import { nanoid } from "nanoid"; import { sql } from "~/db/sql"; -import type { LogInLink } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { dateToDatabaseTimestamp } from "~/utils/dates"; const stm = sql.prepare(/* sql */ ` @@ -26,5 +26,5 @@ export function createLogInLink(userId: number) { new Date(Date.now() + LOG_IN_LINK_VALID_FOR), ), code: nanoid(LOG_IN_LINK_LENGTH), - }) as LogInLink; + }) as Tables["LogInLink"]; } diff --git a/app/features/badges/badges-utils.ts b/app/features/badges/badges-utils.ts index ed130e486..ba5c27f15 100644 --- a/app/features/badges/badges-utils.ts +++ b/app/features/badges/badges-utils.ts @@ -1,10 +1,10 @@ import type { TFunction } from "i18next"; import { SPLATOON_3_XP_BADGE_VALUES } from "~/constants"; -import type { Badge as BadgeDBType } from "~/db/types"; +import type { Tables } from "~/db/tables"; export function badgeExplanationText( t: TFunction<"badges", undefined>, - badge: Pick & { count?: number }, + badge: Pick & { count?: number }, ) { if (badge.code === "patreon") return t("patreon"); if (badge.code === "patreon_plus") { diff --git a/app/features/badges/routes/badges.$id.edit.tsx b/app/features/badges/routes/badges.$id.edit.tsx index 4ab710c8a..8c00892fa 100644 --- a/app/features/badges/routes/badges.$id.edit.tsx +++ b/app/features/badges/routes/badges.$id.edit.tsx @@ -8,7 +8,7 @@ import { Dialog } from "~/components/Dialog"; import { Label } from "~/components/Label"; import { UserSearch } from "~/components/UserSearch"; import { TrashIcon } from "~/components/icons/Trash"; -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import { requireUserId } from "~/features/auth/core/user.server"; import { notify } from "~/features/notifications/core/notify.server"; @@ -321,7 +321,7 @@ function getOwnerDifferences( oldOwners: BadgeRepository.FindOwnersByBadgeIdItem[], ) { const result: Array<{ - id: User["id"]; + id: Tables["User"]["id"]; type: "added" | "removed"; difference: number; username: string; @@ -353,7 +353,7 @@ function getOwnerDifferences( } function countArrayToDuplicatedIdsArray( - owners: Array<{ id: User["id"]; count: number }>, + owners: Array<{ id: Tables["User"]["id"]; count: number }>, ) { return owners.flatMap((o) => new Array(o.count).fill(null).map(() => o.id)); } diff --git a/app/features/builds/queries/buildsBy.server.ts b/app/features/builds/queries/buildsBy.server.ts index 1173b4dbc..155189bc3 100644 --- a/app/features/builds/queries/buildsBy.server.ts +++ b/app/features/builds/queries/buildsBy.server.ts @@ -1,10 +1,5 @@ import { sql } from "~/db/sql"; -import type { - Build, - BuildAbility, - BuildWeapon, - UserWithPlusTier, -} from "~/db/types"; +import type { Tables, UserWithPlusTier } from "~/db/tables"; import { type ModeShort, weaponIdToAltId } from "~/modules/in-game-lists"; import type { BuildAbilitiesTuple, @@ -120,7 +115,7 @@ export function buildsByWeaponId({ weaponId, limit, }: { - weaponId: BuildWeapon["weaponSplId"]; + weaponId: Tables["BuildWeapon"]["weaponSplId"]; limit: number; }) { const [altWeaponId, altWeaponIdTwo] = (() => { @@ -144,17 +139,17 @@ export function buildsByWeaponId({ } type BuildsByUserRow = Pick< - Build, + Tables["Build"], | "id" | "title" | "description" - | "modes" | "headGearSplId" | "clothesGearSplId" | "shoesGearSplId" | "updatedAt" | "private" > & { + modes: string; weapons: string; abilities: string; }; @@ -170,14 +165,14 @@ function augmentBuild({ modes: rawModes, abilities: rawAbilities, ...row -}: T & { modes: Build["modes"]; weapons: string; abilities: string }) { +}: T & { modes: string; weapons: string; abilities: string }) { const modes = rawModes ? (JSON.parse(rawModes) as ModeShort[]) : null; const weapons = ( JSON.parse(rawWeapons) as Array ).sort((a, b) => a.weaponSplId - b.weaponSplId); const abilities = dbAbilitiesToArrayOfArrays( JSON.parse(rawAbilities) as Array< - Pick + Pick >, ); @@ -190,9 +185,15 @@ function augmentBuild({ }; } -const gearOrder: Array = ["HEAD", "CLOTHES", "SHOES"]; +const gearOrder: Array = [ + "HEAD", + "CLOTHES", + "SHOES", +]; function dbAbilitiesToArrayOfArrays( - abilities: Array>, + abilities: Array< + Pick + >, ): BuildAbilitiesTuple { const sorted = abilities .slice() diff --git a/app/features/calendar/CalendarRepository.server.ts b/app/features/calendar/CalendarRepository.server.ts index 431505bf8..31c49d185 100644 --- a/app/features/calendar/CalendarRepository.server.ts +++ b/app/features/calendar/CalendarRepository.server.ts @@ -2,8 +2,13 @@ import type { Expression, ExpressionBuilder, Transaction } from "kysely"; import { sql } from "kysely"; import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite"; import { db } from "~/db/sql"; -import type { DB, Tables, TournamentSettings } from "~/db/tables"; -import type { CalendarEventTag, PersistedCalendarEventTag } from "~/db/types"; +import type { + CalendarEventTag, + DB, + PersistedCalendarEventTag, + Tables, + TournamentSettings, +} from "~/db/tables"; import { MapPool } from "~/features/map-list-generator/core/map-pool"; import * as Progression from "~/features/tournament-bracket/core/Progression"; import { databaseTimestampNow, dateToDatabaseTimestamp } from "~/utils/dates"; diff --git a/app/features/calendar/actions/calendar.new.server.ts b/app/features/calendar/actions/calendar.new.server.ts index 355f51c39..340972c54 100644 --- a/app/features/calendar/actions/calendar.new.server.ts +++ b/app/features/calendar/actions/calendar.new.server.ts @@ -1,8 +1,11 @@ import type { ActionFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { z } from "zod"; -import { TOURNAMENT_STAGE_TYPES } from "~/db/tables"; -import type { CalendarEventTag, PersistedCalendarEventTag } from "~/db/types"; +import { + type CalendarEventTag, + type PersistedCalendarEventTag, + TOURNAMENT_STAGE_TYPES, +} from "~/db/tables"; import { requireUser } from "~/features/auth/core/user.server"; import * as CalendarRepository from "~/features/calendar/CalendarRepository.server"; import * as ShowcaseTournaments from "~/features/front-page/core/ShowcaseTournaments.server"; diff --git a/app/features/calendar/calendar-constants.ts b/app/features/calendar/calendar-constants.ts index c38beff54..5dde8c591 100644 --- a/app/features/calendar/calendar-constants.ts +++ b/app/features/calendar/calendar-constants.ts @@ -1,4 +1,4 @@ -import type { CalendarEventTag, PersistedCalendarEventTag } from "~/db/types"; +import type { CalendarEventTag, PersistedCalendarEventTag } from "~/db/tables"; export const persistedTags = { SPECIAL: { diff --git a/app/features/calendar/components/Tags.tsx b/app/features/calendar/components/Tags.tsx index 194c54715..a8f06d092 100644 --- a/app/features/calendar/components/Tags.tsx +++ b/app/features/calendar/components/Tags.tsx @@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next"; import { Badge } from "~/components/Badge"; import { Button } from "~/components/Button"; import { CrossIcon } from "~/components/icons/Cross"; -import type { CalendarEventTag } from "~/db/types"; +import type { CalendarEventTag } from "~/db/tables"; import type * as CalendarRepository from "../CalendarRepository.server"; import { tags as allTags } from "../calendar-constants"; diff --git a/app/features/calendar/routes/calendar.new.tsx b/app/features/calendar/routes/calendar.new.tsx index 59449507d..1808d817e 100644 --- a/app/features/calendar/routes/calendar.new.tsx +++ b/app/features/calendar/routes/calendar.new.tsx @@ -19,8 +19,7 @@ import { RequiredHiddenInput } from "~/components/RequiredHiddenInput"; import { SubmitButton } from "~/components/SubmitButton"; import { CrossIcon } from "~/components/icons/Cross"; import { TrashIcon } from "~/components/icons/Trash"; -import type { Tables } from "~/db/tables"; -import type { Badge as BadgeType, CalendarEventTag } from "~/db/types"; +import type { CalendarEventTag, Tables } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import { MapPool } from "~/features/map-list-generator/core/map-pool"; import * as Progression from "~/features/tournament-bracket/core/Progression"; @@ -641,7 +640,7 @@ function BadgesAdder() { if (managedBadges.length === 0) return input; - const handleBadgeDelete = (badgeId: BadgeType["id"]) => { + const handleBadgeDelete = (badgeId: Tables["Badge"]["id"]) => { setBadges(badges.filter((badge) => badge.id !== badgeId)); }; diff --git a/app/features/calendar/routes/calendar.tsx b/app/features/calendar/routes/calendar.tsx index 6a3b9e407..5d6efac89 100644 --- a/app/features/calendar/routes/calendar.tsx +++ b/app/features/calendar/routes/calendar.tsx @@ -43,10 +43,6 @@ import { } from "~/utils/urls"; import { actualNumber, safeSplit } from "~/utils/zod"; import { Label } from "../../../components/Label"; -import type { - CalendarEventTag, - PersistedCalendarEventTag, -} from "../../../db/types"; import { metaTags } from "../../../utils/remix"; import * as CalendarRepository from "../CalendarRepository.server"; import { calendarEventTagSchema } from "../actions/calendar.new.server"; @@ -55,6 +51,7 @@ import { closeByWeeks } from "../calendar-utils"; import { Tags } from "../components/Tags"; import "~/styles/calendar.css"; import { SendouSwitch } from "~/components/elements/Switch"; +import type { CalendarEventTag, PersistedCalendarEventTag } from "~/db/tables"; export const meta: MetaFunction = (args) => { const data = args.data as SerializeFrom | null; diff --git a/app/features/chat/components/Chat.tsx b/app/features/chat/components/Chat.tsx index 40f6a7861..2e9549c37 100644 --- a/app/features/chat/components/Chat.tsx +++ b/app/features/chat/components/Chat.tsx @@ -4,7 +4,7 @@ import { nanoid } from "nanoid"; import * as React from "react"; import { useTranslation } from "react-i18next"; import ReconnectingWebSocket from "reconnecting-websocket"; -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import invariant from "~/utils/invariant"; import { logger } from "~/utils/logger"; @@ -17,7 +17,10 @@ import { useChatAutoScroll } from "../chat-hooks"; import type { ChatMessage } from "../chat-types"; import { messageTypeToSound, soundEnabled, soundVolume } from "../chat-utils"; -type ChatUser = Pick & { +type ChatUser = Pick< + Tables["User"], + "username" | "discordId" | "discordAvatar" +> & { chatNameColor: string | null; title?: string; }; diff --git a/app/features/img-upload/queries/addNewImage.ts b/app/features/img-upload/queries/addNewImage.ts index 20cd83310..627fe5106 100644 --- a/app/features/img-upload/queries/addNewImage.ts +++ b/app/features/img-upload/queries/addNewImage.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { UserSubmittedImage } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { ImageUploadType } from "../upload-types"; const addImgStm = sql.prepare(/* sql */ ` @@ -48,7 +48,7 @@ export const addNewImage = sql.transaction( submitterUserId, url, validatedAt, - }) as UserSubmittedImage; + }) as Tables["UserSubmittedImage"]; if (type === "team-pfp") { updateTeamAvatarStm.run({ avatarImgId: img.id, teamId: teamId ?? null }); diff --git a/app/features/img-upload/queries/oneUnvalidatedImage.ts b/app/features/img-upload/queries/oneUnvalidatedImage.ts index 9316520f1..69ae5bb04 100644 --- a/app/features/img-upload/queries/oneUnvalidatedImage.ts +++ b/app/features/img-upload/queries/oneUnvalidatedImage.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { UserSubmittedImage } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -20,7 +20,7 @@ const stm = sql.prepare(/* sql */ ` `); type UnvalidatedImage = Pick< - UserSubmittedImage, + Tables["UserSubmittedImage"], "id" | "url" | "submitterUserId" >; diff --git a/app/features/leaderboards/queries/XPLeaderboard.server.ts b/app/features/leaderboards/queries/XPLeaderboard.server.ts index 3d432d89c..c252c63d1 100644 --- a/app/features/leaderboards/queries/XPLeaderboard.server.ts +++ b/app/features/leaderboards/queries/XPLeaderboard.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { User, XRankPlacement } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { MainWeaponId } from "~/modules/in-game-lists"; import { DEFAULT_LEADERBOARD_MAX_SIZE } from "../leaderboards-constants"; @@ -41,13 +41,13 @@ const weaponStm = getStm(/* sql */ ` export interface XPLeaderboardItem { entryId: number; power: number; - id: User["id"]; - name: XRankPlacement["name"]; - playerId: XRankPlacement["playerId"]; - username: User["username"] | null; - discordAvatar: User["discordAvatar"] | null; - discordId: User["discordId"] | null; - customUrl: User["customUrl"] | null; + id: Tables["User"]["id"]; + name: Tables["XRankPlacement"]["name"]; + playerId: Tables["XRankPlacement"]["playerId"]; + username: Tables["User"]["username"] | null; + discordAvatar: Tables["User"]["discordAvatar"] | null; + discordId: Tables["User"]["discordId"] | null; + customUrl: Tables["User"]["customUrl"] | null; placementRank: number; weaponSplId: MainWeaponId; } @@ -57,7 +57,7 @@ export function allXPLeaderboard(): XPLeaderboardItem[] { } export function modeXPLeaderboard( - mode: XRankPlacement["mode"], + mode: Tables["XRankPlacement"]["mode"], ): XPLeaderboardItem[] { return modeStm.all({ mode }) as any[]; } diff --git a/app/features/leaderboards/queries/seasonPopularUsersWeapon.server.ts b/app/features/leaderboards/queries/seasonPopularUsersWeapon.server.ts index 1032b43fe..d66afd638 100644 --- a/app/features/leaderboards/queries/seasonPopularUsersWeapon.server.ts +++ b/app/features/leaderboards/queries/seasonPopularUsersWeapon.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { seasonObject } from "~/features/mmr/season"; import type { MainWeaponId } from "~/modules/in-game-lists"; import { dateToDatabaseTimestamp } from "~/utils/dates"; @@ -26,7 +26,10 @@ const stm = sql.prepare(/* sql */ ` group by "q1"."userId" `); -export type SeasonPopularUsersWeapon = Record; +export type SeasonPopularUsersWeapon = Record< + Tables["User"]["id"], + MainWeaponId +>; export function seasonPopularUsersWeapon( season: number, @@ -39,7 +42,7 @@ export function seasonPopularUsersWeapon( ends: dateToDatabaseTimestamp(ends), }) as Array<{ count: number; - userId: User["id"]; + userId: Tables["User"]["id"]; weaponSplId: MainWeaponId; }>; diff --git a/app/features/leaderboards/queries/userSPLeaderboard.server.ts b/app/features/leaderboards/queries/userSPLeaderboard.server.ts index d2792cd1a..35e21eb44 100644 --- a/app/features/leaderboards/queries/userSPLeaderboard.server.ts +++ b/app/features/leaderboards/queries/userSPLeaderboard.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { PlusTier, User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { ordinalToSp } from "~/features/mmr/mmr-utils"; import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "../leaderboards-constants"; @@ -36,14 +36,14 @@ const stm = sql.prepare(/* sql */ ` export interface UserSPLeaderboardItem { entryId: number; power: number; - id: User["id"]; - username: User["username"]; - discordAvatar: User["discordAvatar"]; - discordId: User["discordId"]; - customUrl: User["customUrl"]; + id: Tables["User"]["id"]; + username: Tables["User"]["username"]; + discordAvatar: Tables["User"]["discordAvatar"]; + discordId: Tables["User"]["discordId"]; + customUrl: Tables["User"]["customUrl"]; plusSkippedForSeasonNth: number | null; /** Plus tier player is on track to join */ - pendingPlusTier?: PlusTier["tier"]; + pendingPlusTier?: Tables["PlusTier"]["tier"]; placementRank: number; } diff --git a/app/features/map-list-generator/core/map-list-generator/utils.ts b/app/features/map-list-generator/core/map-list-generator/utils.ts index c7f0aee7a..2e44ac4a8 100644 --- a/app/features/map-list-generator/core/map-list-generator/utils.ts +++ b/app/features/map-list-generator/core/map-list-generator/utils.ts @@ -1,4 +1,4 @@ -import type { MapPoolMap } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { ModeShort } from "../../../../modules/in-game-lists"; import type { MapPool } from "../map-pool"; import type { MapPoolObject } from "../map-pool-serializer/types"; @@ -16,7 +16,7 @@ export function mapPoolToNonEmptyModes(mapPool: MapPool) { } export function mapPoolListToMapPoolObject( - mapPoolList: Array>, + mapPoolList: Array>, ) { const result: MapPoolObject = { TW: [], diff --git a/app/features/map-list-generator/core/map-pool.ts b/app/features/map-list-generator/core/map-pool.ts index 7324767dd..5de9dac77 100644 --- a/app/features/map-list-generator/core/map-pool.ts +++ b/app/features/map-list-generator/core/map-pool.ts @@ -1,4 +1,4 @@ -import type { MapPoolMap } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { type ModeShort, type StageId, @@ -14,7 +14,9 @@ import type { ReadonlyMapPoolObject, } from "./map-pool-serializer/types"; -export type DbMapPoolList = Array>; +export type DbMapPoolList = Array< + Pick +>; export class MapPool { private source: string | ReadonlyMapPoolObject; diff --git a/app/features/map-list-generator/routes/maps.tsx b/app/features/map-list-generator/routes/maps.tsx index 4c2263ef2..853b6fc3a 100644 --- a/app/features/map-list-generator/routes/maps.tsx +++ b/app/features/map-list-generator/routes/maps.tsx @@ -9,7 +9,6 @@ import { Label } from "~/components/Label"; import { Main } from "~/components/Main"; import { MapPoolSelector, MapPoolStages } from "~/components/MapPoolSelector"; import { EditIcon } from "~/components/icons/Edit"; -import type { CalendarEvent } from "~/db/types"; import { getUserId } from "~/features/auth/core/user.server"; import * as CalendarRepository from "~/features/calendar/CalendarRepository.server"; import { type ModeWithStage, stageIds } from "~/modules/in-game-lists"; @@ -27,6 +26,7 @@ import { mapPoolToNonEmptyModes } from "../core/map-list-generator/utils"; import { MapPool } from "../core/map-pool"; import "~/styles/maps.css"; import { SendouSwitch } from "~/components/elements/Switch"; +import type { Tables } from "~/db/tables"; import { metaTags } from "~/utils/remix"; const AMOUNT_OF_MAPS_IN_MAP_LIST = stageIds.length * 2; @@ -155,7 +155,7 @@ function useSearchParamPersistedMapPool() { const handleMapPoolChange = ( newMapPool: MapPool, - event?: Pick, + event?: Pick, ) => { setMapPool(newMapPool); setSearchParams( diff --git a/app/features/mmr/queries/findCurrentSkillByUserId.server.ts b/app/features/mmr/queries/findCurrentSkillByUserId.server.ts index 996f7111a..223fd1ef6 100644 --- a/app/features/mmr/queries/findCurrentSkillByUserId.server.ts +++ b/app/features/mmr/queries/findCurrentSkillByUserId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Skill } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -26,7 +26,7 @@ export function findCurrentSkillByUserId({ season: number; }) { return stm.get({ userId, season }) as Pick< - Skill, + Tables["Skill"], "mu" | "sigma" | "matchesCount" > | null; } diff --git a/app/features/mmr/queries/findCurrentTeamSkillByIdentifier.server.ts b/app/features/mmr/queries/findCurrentTeamSkillByIdentifier.server.ts index 67860b598..6a7ada235 100644 --- a/app/features/mmr/queries/findCurrentTeamSkillByIdentifier.server.ts +++ b/app/features/mmr/queries/findCurrentTeamSkillByIdentifier.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Skill } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -26,7 +26,7 @@ export function findCurrentTeamSkillByIdentifier({ season: number; }) { return stm.get({ identifier, season }) as Pick< - Skill, + Tables["Skill"], "mu" | "sigma" | "matchesCount" > | null; } diff --git a/app/features/mmr/queries/orderedMMRBySeason.server.ts b/app/features/mmr/queries/orderedMMRBySeason.server.ts index 94dfa42ba..4f008b119 100644 --- a/app/features/mmr/queries/orderedMMRBySeason.server.ts +++ b/app/features/mmr/queries/orderedMMRBySeason.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Skill } from "~/db/types"; +import type { Tables } from "~/db/tables"; const userStm = sql.prepare(/* sql */ ` select @@ -51,6 +51,6 @@ export function orderedMMRBySeason({ const stm = type === "team" ? teamStm : userStm; return stm.all({ season }) as Array< - Pick + Pick >; } diff --git a/app/features/mmr/tiered.server.ts b/app/features/mmr/tiered.server.ts index 5fbcbc190..1c26ddb59 100644 --- a/app/features/mmr/tiered.server.ts +++ b/app/features/mmr/tiered.server.ts @@ -1,4 +1,4 @@ -import type { Skill } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { cache, syncCached } from "~/utils/cache.server"; import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "../leaderboards/leaderboards-constants"; import { USER_SKILLS_CACHE_KEY } from "../sendouq/q-constants"; @@ -71,7 +71,7 @@ export type SkillTierInterval = ReturnType< >["intervals"][number]; function skillTierIntervals( - orderedPoints: Array>, + orderedPoints: Array>, type: "user" | "team", ) { const LEADERBOARD_MIN_ENTRIES_FOR_LEVIATHAN = diff --git a/app/features/plus-suggestions/routes/plus.suggestions.new.tsx b/app/features/plus-suggestions/routes/plus.suggestions.new.tsx index f933b70e3..126300fe8 100644 --- a/app/features/plus-suggestions/routes/plus.suggestions.new.tsx +++ b/app/features/plus-suggestions/routes/plus.suggestions.new.tsx @@ -14,7 +14,7 @@ import { PLUS_TIERS, PlUS_SUGGESTION_FIRST_COMMENT_MAX_LENGTH, } from "~/constants"; -import type { UserWithPlusTier } from "~/db/types"; +import type { UserWithPlusTier } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import { requireUser } from "~/features/auth/core/user.server"; import { notify } from "~/features/notifications/core/notify.server"; diff --git a/app/features/plus-suggestions/routes/plus.suggestions.tsx b/app/features/plus-suggestions/routes/plus.suggestions.tsx index b63cb5c8c..d84c7aad1 100644 --- a/app/features/plus-suggestions/routes/plus.suggestions.tsx +++ b/app/features/plus-suggestions/routes/plus.suggestions.tsx @@ -15,7 +15,7 @@ import { FormWithConfirm } from "~/components/FormWithConfirm"; import { RelativeTime } from "~/components/RelativeTime"; import { TrashIcon } from "~/components/icons/Trash"; import { PLUS_TIERS } from "~/constants"; -import type { PlusSuggestion, User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import { requireUser } from "~/features/auth/core/user.server"; import * as PlusSuggestionRepository from "~/features/plus-suggestions/PlusSuggestionRepository.server"; @@ -366,7 +366,7 @@ export function PlusSuggestionComments({ }: { suggestion: PlusSuggestionRepository.FindAllByMonthItem; deleteButtonArgs?: { - user?: Pick; + user?: Pick; suggestions: PlusSuggestionRepository.FindAllByMonthItem[]; tier: string; suggested: PlusSuggestionRepository.FindAllByMonthItem["suggested"]; @@ -425,7 +425,7 @@ function CommentDeleteButton({ suggestedUsername, isFirstSuggestion = false, }: { - suggestionId: PlusSuggestion["id"]; + suggestionId: Tables["PlusSuggestion"]["id"]; tier: string; suggestedUsername: string; isFirstSuggestion?: boolean; diff --git a/app/features/plus-voting/core/types.ts b/app/features/plus-voting/core/types.ts index b98b640b0..a5c56842f 100644 --- a/app/features/plus-voting/core/types.ts +++ b/app/features/plus-voting/core/types.ts @@ -1,8 +1,8 @@ -import type { PlusVote } from "~/db/types"; +import type { Tables } from "~/db/tables"; export interface MonthYear { month: number; year: number; } -export type PlusVoteFromFE = Pick; +export type PlusVoteFromFE = Pick; diff --git a/app/features/plus-voting/core/usePlusVoting.ts b/app/features/plus-voting/core/usePlusVoting.ts index f1cd534e2..04273688a 100644 --- a/app/features/plus-voting/core/usePlusVoting.ts +++ b/app/features/plus-voting/core/usePlusVoting.ts @@ -1,6 +1,6 @@ import * as React from "react"; import { PLUS_DOWNVOTE, PLUS_UPVOTE } from "~/constants"; -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type * as PlusVotingRepository from "~/features/plus-voting/PlusVotingRepository.server"; import invariant from "~/utils/invariant"; import type { PlusVoteFromFE } from "./types"; @@ -13,7 +13,7 @@ interface VotingLocalStorageData { year: number; votes: PlusVoteFromFE[]; /** User id -> order for sorting */ - usersForVotingOrder: Record; + usersForVotingOrder: Record; } export function usePlusVoting( diff --git a/app/features/plus-voting/routes/plus.voting.results.tsx b/app/features/plus-voting/routes/plus.voting.results.tsx index 892152616..04fb66947 100644 --- a/app/features/plus-voting/routes/plus.voting.results.tsx +++ b/app/features/plus-voting/routes/plus.voting.results.tsx @@ -5,7 +5,6 @@ import type { } from "@remix-run/node"; import { Link, useLoaderData } from "@remix-run/react"; import clsx from "clsx"; -import type { UserWithPlusTier } from "~/db/types"; import { getUser } from "~/features/auth/core/user.server"; import * as PlusVotingRepository from "~/features/plus-voting/PlusVotingRepository.server"; import { lastCompletedVoting } from "~/features/plus-voting/core"; @@ -15,6 +14,7 @@ import { PLUS_SERVER_DISCORD_URL, userPage } from "~/utils/urls"; import { isAtLeastFiveDollarTierPatreon } from "~/utils/users"; import "~/styles/plus-history.css"; +import type { UserWithPlusTier } from "~/db/tables"; import { metaTags } from "~/utils/remix"; export const meta: MetaFunction = (args) => { diff --git a/app/features/sendouq-match/QMatchRepository.server.ts b/app/features/sendouq-match/QMatchRepository.server.ts index 8723de4e5..fafdaffa3 100644 --- a/app/features/sendouq-match/QMatchRepository.server.ts +++ b/app/features/sendouq-match/QMatchRepository.server.ts @@ -1,7 +1,6 @@ import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite"; import { db } from "~/db/sql"; -import type { ParsedMemento, Tables } from "~/db/tables"; -import type { UserSkillDifference } from "~/db/types"; +import type { ParsedMemento, Tables, UserSkillDifference } from "~/db/tables"; import type { MainWeaponId } from "~/modules/in-game-lists"; import { COMMON_USER_FIELDS, userChatNameColor } from "~/utils/kysely.server"; diff --git a/app/features/sendouq/components/GroupCard.tsx b/app/features/sendouq/components/GroupCard.tsx index aede42d2a..c690989e9 100644 --- a/app/features/sendouq/components/GroupCard.tsx +++ b/app/features/sendouq/components/GroupCard.tsx @@ -18,7 +18,7 @@ import { SpeakerXIcon } from "~/components/icons/SpeakerX"; import { StarIcon } from "~/components/icons/Star"; import { StarFilledIcon } from "~/components/icons/StarFilled"; import { TrashIcon } from "~/components/icons/Trash"; -import type { GroupMember as GroupMemberType, ParsedMemento } from "~/db/types"; +import type { ParsedMemento, Tables } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "~/features/leaderboards/leaderboards-constants"; import { ordinalToRoundedSp } from "~/features/mmr/mmr-utils"; @@ -55,7 +55,7 @@ export function GroupCard({ }: { group: Omit; action?: "LIKE" | "UNLIKE" | "GROUP_UP" | "MATCH_UP" | "MATCH_UP_RECHALLENGE"; - ownRole?: GroupMemberType["role"] | "PREVIEWER"; + ownRole?: Tables["GroupMember"]["role"] | "PREVIEWER"; ownGroup?: boolean; isExpired?: boolean; displayOnly?: boolean; diff --git a/app/features/sendouq/core/groups.server.ts b/app/features/sendouq/core/groups.server.ts index afd4a390b..826294ecc 100644 --- a/app/features/sendouq/core/groups.server.ts +++ b/app/features/sendouq/core/groups.server.ts @@ -1,5 +1,4 @@ import type { Tables } from "~/db/tables"; -import type { Group } from "~/db/types"; import { TIERS } from "~/features/mmr/mmr-constants"; import { defaultOrdinal } from "~/features/mmr/mmr-utils"; import type { @@ -467,7 +466,7 @@ function resolveGroupSkill({ } export function groupExpiryStatus( - group?: Pick, + group?: Pick, ): null | GroupExpiryStatus { if (!group) return null; diff --git a/app/features/sendouq/core/groups.ts b/app/features/sendouq/core/groups.ts index 4ae8ea5d0..d1b1d42df 100644 --- a/app/features/sendouq/core/groups.ts +++ b/app/features/sendouq/core/groups.ts @@ -1,4 +1,4 @@ -import type { GroupMember } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { LookingGroup } from "../q-types"; // logic is that team who is bigger decides the settings @@ -31,6 +31,6 @@ export function groupAfterMorph({ return ourGroup; } -export function hasGroupManagerPerms(role: GroupMember["role"]) { +export function hasGroupManagerPerms(role: Tables["GroupMember"]["role"]) { return role === "OWNER" || role === "MANAGER"; } diff --git a/app/features/sendouq/core/skills.server.ts b/app/features/sendouq/core/skills.server.ts index 4b0c32f18..8a2c0c0ce 100644 --- a/app/features/sendouq/core/skills.server.ts +++ b/app/features/sendouq/core/skills.server.ts @@ -1,13 +1,10 @@ import type { Rating } from "node_modules/openskill/dist/types"; import { ordinal } from "openskill"; import type { - Group, - GroupMatch, GroupSkillDifference, - Skill, - User, + Tables, UserSkillDifference, -} from "~/db/types"; +} from "~/db/tables"; import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "~/features/leaderboards/leaderboards-constants"; import { ordinalToSp, @@ -25,13 +22,13 @@ import { roundToNDecimalPlaces } from "~/utils/number"; export type MementoSkillDifferences = { users: Record< - User["id"], + Tables["User"]["id"], { skillDifference?: UserSkillDifference; } >; groups: Record< - Group["id"], + Tables["Group"]["id"], { skillDifference?: GroupSkillDifference; } @@ -45,15 +42,15 @@ export function calculateMatchSkills({ winnerGroupId, loserGroupId, }: { - groupMatchId: GroupMatch["id"]; - winner: User["id"][]; - loser: User["id"][]; - winnerGroupId: Group["id"]; - loserGroupId: Group["id"]; + groupMatchId: Tables["GroupMatch"]["id"]; + winner: Tables["User"]["id"][]; + loser: Tables["User"]["id"][]; + winnerGroupId: Tables["Group"]["id"]; + loserGroupId: Tables["Group"]["id"]; }) { const newSkills: Array< Pick< - Skill, + Tables["Skill"], "groupMatchId" | "identifier" | "mu" | "season" | "sigma" | "userId" > > = []; diff --git a/app/features/sendouq/core/summarizer.server.ts b/app/features/sendouq/core/summarizer.server.ts index bda7dc26b..b798f3d89 100644 --- a/app/features/sendouq/core/summarizer.server.ts +++ b/app/features/sendouq/core/summarizer.server.ts @@ -1,4 +1,4 @@ -import type { MapResult, PlayerResult } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { currentOrPreviousSeason } from "~/features/mmr/season"; import invariant from "~/utils/invariant"; import { winnersArrayToWinner } from "../q-utils"; @@ -16,7 +16,7 @@ export function summarizeMaps({ const season = currentOrPreviousSeason(new Date())?.nth; invariant(typeof season === "number", "No ranked season for skills"); - const result: Array = []; + const result: Array = []; const playedMaps = match.mapList.slice(0, winners.length); @@ -66,7 +66,7 @@ export function summarizePlayerResults({ const season = currentOrPreviousSeason(new Date())?.nth; invariant(typeof season === "number", "No ranked season for skills"); - const result: Array = []; + const result: Array = []; const addMapResult = ({ outcome, diff --git a/app/features/sendouq/q-types.ts b/app/features/sendouq/q-types.ts index 4b5b216a1..37ab93f06 100644 --- a/app/features/sendouq/q-types.ts +++ b/app/features/sendouq/q-types.ts @@ -1,18 +1,11 @@ -import type { Tables } from "~/db/tables"; -import type { - Group, - GroupMember, - ParsedMemento, - PlusTier, - User, -} from "~/db/types"; +import type { ParsedMemento, Tables } from "~/db/tables"; import type { MainWeaponId, ModeShort } from "~/modules/in-game-lists"; import type { TieredSkill } from "../mmr/tiered.server"; import type { GroupForMatch } from "../sendouq-match/QMatchRepository.server"; export type LookingGroup = { id: number; - createdAt: Group["createdAt"]; + createdAt: Tables["Group"]["createdAt"]; tier?: TieredSkill["tier"]; tierRange?: { range?: [TieredSkill["tier"], TieredSkill["tier"]]; @@ -23,7 +16,7 @@ export type LookingGroup = { isLiked?: boolean; isRechallenge?: boolean; team?: GroupForMatch["team"]; - chatCode?: Group["chatCode"]; + chatCode?: Tables["Group"]["chatCode"]; mapModePreferences?: Array>; futureMatchModes?: Array; rechallengeMatchModes?: Array; @@ -34,14 +27,14 @@ export type LookingGroup = { username: string; discordAvatar: string | null; noScreen?: number; - customUrl?: User["customUrl"]; - plusTier?: PlusTier["tier"]; - role: GroupMember["role"]; - note?: GroupMember["note"]; + customUrl?: Tables["User"]["customUrl"]; + plusTier?: Tables["PlusTier"]["tier"]; + role: Tables["GroupMember"]["role"]; + note?: Tables["GroupMember"]["note"]; weapons?: MainWeaponId[]; skill?: TieredSkill | "CALCULATING"; - vc?: User["vc"]; - inGameName?: User["inGameName"]; + vc?: Tables["User"]["vc"]; + inGameName?: Tables["User"]["inGameName"]; languages: string[]; chatNameColor: string | null; skillDifference?: ParsedMemento["users"][number]["skillDifference"]; @@ -54,7 +47,7 @@ export type LookingGroup = { }; export type LookingGroupWithInviteCode = LookingGroup & { - inviteCode: Group["inviteCode"]; + inviteCode: Tables["Group"]["inviteCode"]; members: NonNullable; }; diff --git a/app/features/sendouq/q-utils.ts b/app/features/sendouq/q-utils.ts index b5e8f7c1a..e902fe80c 100644 --- a/app/features/sendouq/q-utils.ts +++ b/app/features/sendouq/q-utils.ts @@ -1,4 +1,4 @@ -import type { Group } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { stageIds } from "~/modules/in-game-lists"; import { rankedModesShort } from "~/modules/in-game-lists/modes"; import { databaseTimestampToDate } from "~/utils/dates"; @@ -13,7 +13,7 @@ import type { MapPool } from "../map-list-generator/core/map-pool"; import { SENDOUQ } from "./q-constants"; function groupRedirectLocation( - group?: Pick & { matchId?: number }, + group?: Pick & { matchId?: number }, ) { if (group?.status === "PREPARING") return SENDOUQ_PREPARING_PAGE; if (group?.matchId) return sendouQMatchPage(group.matchId); @@ -26,7 +26,7 @@ export function groupRedirectLocationByCurrentLocation({ group, currentLocation, }: { - group?: Pick & { matchId?: number }; + group?: Pick & { matchId?: number }; currentLocation: "default" | "preparing" | "looking" | "match"; }) { const newLocation = groupRedirectLocation(group); diff --git a/app/features/sendouq/queries/addMapResults.server.ts b/app/features/sendouq/queries/addMapResults.server.ts index bd41e78b9..91fee9148 100644 --- a/app/features/sendouq/queries/addMapResults.server.ts +++ b/app/features/sendouq/queries/addMapResults.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { MapResult } from "~/db/types"; +import type { Tables } from "~/db/tables"; const addMapResultDeltaStm = sql.prepare(/* sql */ ` insert into "MapResult" ( @@ -25,7 +25,7 @@ const addMapResultDeltaStm = sql.prepare(/* sql */ ` export function addMapResults( results: Array< - Pick + Pick >, ) { for (const result of results) { diff --git a/app/features/sendouq/queries/addMember.server.ts b/app/features/sendouq/queries/addMember.server.ts index 4a6be6cf3..6615feb81 100644 --- a/app/features/sendouq/queries/addMember.server.ts +++ b/app/features/sendouq/queries/addMember.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { GroupMember } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` insert into "GroupMember" ( @@ -20,7 +20,7 @@ export function addMember({ }: { groupId: number; userId: number; - role?: GroupMember["role"]; + role?: Tables["GroupMember"]["role"]; }) { stm.run({ groupId, userId, role }); } diff --git a/app/features/sendouq/queries/addPlayerResults.server.ts b/app/features/sendouq/queries/addPlayerResults.server.ts index dbde4fdbf..b845b6581 100644 --- a/app/features/sendouq/queries/addPlayerResults.server.ts +++ b/app/features/sendouq/queries/addPlayerResults.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { PlayerResult } from "~/db/types"; +import type { Tables } from "~/db/tables"; const addPlayerResultDeltaStm = sql.prepare(/* sql */ ` insert into "PlayerResult" ( @@ -29,7 +29,7 @@ const addPlayerResultDeltaStm = sql.prepare(/* sql */ ` "setLosses" = "setLosses" + @setLosses `); -export function addPlayerResults(results: Array) { +export function addPlayerResults(results: Array) { for (const result of results) { addPlayerResultDeltaStm.run({ ownerUserId: result.ownerUserId, diff --git a/app/features/sendouq/queries/addSkills.server.ts b/app/features/sendouq/queries/addSkills.server.ts index 1fb702f02..e54843461 100644 --- a/app/features/sendouq/queries/addSkills.server.ts +++ b/app/features/sendouq/queries/addSkills.server.ts @@ -1,6 +1,6 @@ import { ordinal } from "openskill"; import { sql } from "~/db/sql"; -import type { ParsedMemento, Skill } from "~/db/types"; +import type { ParsedMemento, Tables } from "~/db/tables"; import { identifierToUserIds } from "~/features/mmr/mmr-utils"; import type { MementoSkillDifferences } from "../core/skills.server"; @@ -55,7 +55,7 @@ export function addSkills({ }: { groupMatchId: number; skills: Pick< - Skill, + Tables["Skill"], "groupMatchId" | "identifier" | "mu" | "season" | "sigma" | "userId" >[]; oldMatchMemento: ParsedMemento; @@ -66,7 +66,7 @@ export function addSkills({ const insertedSkill = stm.get({ ...skill, ordinal: ordinal(skill), - }) as Skill; + }) as Tables["Skill"]; if (insertedSkill.identifier) { for (const userId of identifierToUserIds(insertedSkill.identifier)) { diff --git a/app/features/sendouq/queries/createMatch.server.ts b/app/features/sendouq/queries/createMatch.server.ts index 84a36400f..d893a4dd4 100644 --- a/app/features/sendouq/queries/createMatch.server.ts +++ b/app/features/sendouq/queries/createMatch.server.ts @@ -1,7 +1,6 @@ import { nanoid } from "nanoid"; import { sql } from "~/db/sql"; -import type { ParsedMemento } from "~/db/tables"; -import type { GroupMatch } from "~/db/types"; +import type { ParsedMemento, Tables } from "~/db/tables"; import type { TournamentMapListMap } from "~/modules/tournament-map-list-generator"; import { syncGroupTeamId } from "./syncGroupTeamId.server"; @@ -53,7 +52,7 @@ export const createMatch = sql.transaction( bravoGroupId, chatCode: nanoid(10), memento: JSON.stringify(memento), - }) as GroupMatch; + }) as Tables["GroupMatch"]; for (const [i, { mode, source, stageId }] of mapList.entries()) { createMatchMapStm.run({ diff --git a/app/features/sendouq/queries/findCurrentGroupByUserId.server.ts b/app/features/sendouq/queries/findCurrentGroupByUserId.server.ts index eb85912bf..39e3d16c3 100644 --- a/app/features/sendouq/queries/findCurrentGroupByUserId.server.ts +++ b/app/features/sendouq/queries/findCurrentGroupByUserId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Group, GroupMember } from "~/db/types"; +import type { Tables } from "~/db/tables"; import invariant from "~/utils/invariant"; const stm = sql.prepare(/* sql */ ` @@ -21,11 +21,11 @@ const stm = sql.prepare(/* sql */ ` `); type ActiveGroup = Pick< - Group, + Tables["Group"], "id" | "status" | "latestActionAt" | "chatCode" > & { matchId?: number; - role: GroupMember["role"]; + role: Tables["GroupMember"]["role"]; }; export function findCurrentGroupByUserId( diff --git a/app/features/sendouq/queries/findGroupByInviteCode.server.ts b/app/features/sendouq/queries/findGroupByInviteCode.server.ts index fff434fe1..4c1e1d1a7 100644 --- a/app/features/sendouq/queries/findGroupByInviteCode.server.ts +++ b/app/features/sendouq/queries/findGroupByInviteCode.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Group, GroupMember } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { parseDBJsonArray } from "~/utils/sql"; const stm = sql.prepare(/* sql */ ` @@ -25,8 +25,12 @@ const stm = sql.prepare(/* sql */ ` export function findGroupByInviteCode(inviteCode: string): { id: number; - status: Group["status"]; - members: { id: number; username: string; role: GroupMember["role"] }[]; + status: Tables["Group"]["status"]; + members: { + id: number; + username: string; + role: Tables["GroupMember"]["role"]; + }[]; } | null { const row = stm.get({ inviteCode }) as any; if (!row) return null; diff --git a/app/features/sendouq/queries/findMatchById.server.ts b/app/features/sendouq/queries/findMatchById.server.ts index c7e93b9a2..c74062069 100644 --- a/app/features/sendouq/queries/findMatchById.server.ts +++ b/app/features/sendouq/queries/findMatchById.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { GroupMatch, GroupMatchMap, ParsedMemento } from "~/db/types"; +import type { ParsedMemento, Tables } from "~/db/tables"; import { parseDBJsonArray } from "~/utils/sql"; const stm = sql.prepare(/* sql */ ` @@ -30,17 +30,20 @@ const stm = sql.prepare(/* sql */ ` `); export interface MatchById { - id: GroupMatch["id"]; - alphaGroupId: GroupMatch["alphaGroupId"]; - bravoGroupId: GroupMatch["bravoGroupId"]; - createdAt: GroupMatch["createdAt"]; - reportedAt: GroupMatch["reportedAt"]; - reportedByUserId: GroupMatch["reportedByUserId"]; - chatCode: GroupMatch["chatCode"]; + id: Tables["GroupMatch"]["id"]; + alphaGroupId: Tables["GroupMatch"]["alphaGroupId"]; + bravoGroupId: Tables["GroupMatch"]["bravoGroupId"]; + createdAt: Tables["GroupMatch"]["createdAt"]; + reportedAt: Tables["GroupMatch"]["reportedAt"]; + reportedByUserId: Tables["GroupMatch"]["reportedByUserId"]; + chatCode: Tables["GroupMatch"]["chatCode"]; isLocked: boolean; memento: ParsedMemento; mapList: Array< - Pick + Pick< + Tables["GroupMatchMap"], + "id" | "mode" | "stageId" | "source" | "winnerGroupId" + > >; } diff --git a/app/features/sendouq/queries/findRecentMatchPlayersByUserId.server.ts b/app/features/sendouq/queries/findRecentMatchPlayersByUserId.server.ts index efc31676d..ffcccfb40 100644 --- a/app/features/sendouq/queries/findRecentMatchPlayersByUserId.server.ts +++ b/app/features/sendouq/queries/findRecentMatchPlayersByUserId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { GroupMember } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql*/ ` with "MostRecentGroupMatch" as ( @@ -25,7 +25,10 @@ const stm = sql.prepare(/* sql*/ ` "MostRecentGroupMatch"."createdAt" > unixepoch() - 60 * 60 * 2 `); -export type RecentMatchPlayer = Pick; +export type RecentMatchPlayer = Pick< + Tables["GroupMember"], + "groupId" | "userId" +>; export function findRecentMatchPlayersByUserId(userId: number) { return stm.all({ userId }) as Array; diff --git a/app/features/sendouq/queries/groupSuccessorOwner.ts b/app/features/sendouq/queries/groupSuccessorOwner.ts index b764675e3..13328e503 100644 --- a/app/features/sendouq/queries/groupSuccessorOwner.ts +++ b/app/features/sendouq/queries/groupSuccessorOwner.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { GroupMember } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -13,7 +13,7 @@ const stm = sql.prepare(/* sql */ ` export const groupSuccessorOwner = (groupId: number) => { const rows = stm.all({ groupId }) as Array< - Pick + Pick >; if (rows.length === 0) { diff --git a/app/features/sendouq/queries/morphGroups.server.ts b/app/features/sendouq/queries/morphGroups.server.ts index aa25ce0ec..29f03e332 100644 --- a/app/features/sendouq/queries/morphGroups.server.ts +++ b/app/features/sendouq/queries/morphGroups.server.ts @@ -1,6 +1,6 @@ import { nanoid } from "nanoid"; import { sql } from "~/db/sql"; -import type { GroupMember, User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { deleteLikesByGroupId } from "./deleteLikesByGroupId.server"; const findToBeDeletedGroupNonRegularsStm = sql.prepare(/* sql */ ` @@ -41,7 +41,7 @@ export const morphGroups = sql.transaction( }) => { const toBeDeletedGroupNonRegulars = findToBeDeletedGroupNonRegularsStm .all({ groupId: otherGroupId }) - .map((row: any) => row.userId) as Array; + .map((row: any) => row.userId) as Array; deleteLikesByGroupId(survivingGroupId); @@ -52,11 +52,8 @@ export const morphGroups = sql.transaction( }); for (const userId of newMembers) { - const role: GroupMember["role"] = toBeDeletedGroupNonRegulars.includes( - userId, - ) - ? "MANAGER" - : "REGULAR"; + const role: Tables["GroupMember"]["role"] = + toBeDeletedGroupNonRegulars.includes(userId) ? "MANAGER" : "REGULAR"; updateGroupMemberStm.run({ newGroupId: survivingGroupId, oldGroupId: otherGroupId, diff --git a/app/features/sendouq/queries/reportScore.server.ts b/app/features/sendouq/queries/reportScore.server.ts index 6a7add3dd..8f4c7c338 100644 --- a/app/features/sendouq/queries/reportScore.server.ts +++ b/app/features/sendouq/queries/reportScore.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { GroupMatch } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { dateToDatabaseTimestamp } from "~/utils/dates"; const updateMatchStm = sql.prepare(/* sql */ ` @@ -35,7 +35,7 @@ export const reportScore = ({ reportedAt: dateToDatabaseTimestamp(new Date()), reportedByUserId, matchId, - }) as GroupMatch; + }) as Tables["GroupMatch"]; clearMatchMapWinnersStm.run({ matchId }); diff --git a/app/features/sendouq/queries/reportedWeaponsByMatchId.server.ts b/app/features/sendouq/queries/reportedWeaponsByMatchId.server.ts index 289a0ecf2..0f25a493f 100644 --- a/app/features/sendouq/queries/reportedWeaponsByMatchId.server.ts +++ b/app/features/sendouq/queries/reportedWeaponsByMatchId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { GroupMatchMap, ReportedWeapon } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -15,8 +15,8 @@ const stm = sql.prepare(/* sql */ ` export function reportedWeaponsByMatchId(matchId: number) { const rows = stm.all({ matchId }) as Array< - ReportedWeapon & { - mapIndex: GroupMatchMap["index"]; + Tables["ReportedWeapon"] & { + mapIndex: Tables["GroupMatchMap"]["index"]; groupMatchMapId: number; } >; diff --git a/app/features/sendouq/queries/seasonMatchesByUserId.server.ts b/app/features/sendouq/queries/seasonMatchesByUserId.server.ts index 586fdd584..e8f220bb2 100644 --- a/app/features/sendouq/queries/seasonMatchesByUserId.server.ts +++ b/app/features/sendouq/queries/seasonMatchesByUserId.server.ts @@ -1,7 +1,6 @@ import { add } from "date-fns"; import { sql } from "~/db/sql"; -import type { ParsedMemento } from "~/db/tables"; -import type { GroupMatch, GroupMatchMap, User } from "~/db/types"; +import type { ParsedMemento, Tables } from "~/db/tables"; import { seasonObject } from "~/features/mmr/season"; import { MATCHES_PER_SEASONS_PAGE } from "~/features/user-page/user-page-constants"; import type { MainWeaponId } from "~/modules/in-game-lists"; @@ -98,25 +97,25 @@ const weaponsStm = sql.prepare(/* sql */ ` `); interface SeasonMatchByUserId { - id: GroupMatch["id"]; - alphaGroupId: GroupMatch["alphaGroupId"]; - bravoGroupId: GroupMatch["bravoGroupId"]; - winnerGroupIds: Array; - createdAt: GroupMatch["createdAt"]; + id: Tables["GroupMatch"]["id"]; + alphaGroupId: Tables["GroupMatch"]["alphaGroupId"]; + bravoGroupId: Tables["GroupMatch"]["bravoGroupId"]; + winnerGroupIds: Array; + createdAt: Tables["GroupMatch"]["createdAt"]; isLocked: number; spDiff: number | null; groupAlphaMembers: Array<{ - id: User["id"]; - username: User["username"]; - discordId: User["discordId"]; - discordAvatar: User["discordAvatar"]; + id: Tables["User"]["id"]; + username: Tables["User"]["username"]; + discordId: Tables["User"]["discordId"]; + discordAvatar: Tables["User"]["discordAvatar"]; weaponSplId?: MainWeaponId; }>; groupBravoMembers: Array<{ - id: User["id"]; - username: User["username"]; - discordId: User["discordId"]; - discordAvatar: User["discordAvatar"]; + id: Tables["User"]["id"]; + username: Tables["User"]["username"]; + discordId: Tables["User"]["discordId"]; + discordAvatar: Tables["User"]["discordAvatar"]; weaponSplId?: MainWeaponId; }>; } diff --git a/app/features/sendouq/queries/seasonStagesByUserId.server.ts b/app/features/sendouq/queries/seasonStagesByUserId.server.ts index a78400929..b76ba6de1 100644 --- a/app/features/sendouq/queries/seasonStagesByUserId.server.ts +++ b/app/features/sendouq/queries/seasonStagesByUserId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { MapResult } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { ModeShort, StageId } from "~/modules/in-game-lists"; const stm = sql.prepare(/* sql */ ` @@ -19,7 +19,7 @@ export function seasonStagesByUserId({ userId: number; season: number; }) { - const rows = stm.all({ userId, season }) as Array; + const rows = stm.all({ userId, season }) as Array; return rows.reduce( (acc, cur) => { diff --git a/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts b/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts index fe1f52f02..faf4957ad 100644 --- a/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts +++ b/app/features/sendouq/queries/seasonsMatesEnemiesByUserId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { PlayerResult, User } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -30,7 +30,7 @@ export function seasonsMatesEnemiesByUserId({ }: { userId: number; season: number; - type: PlayerResult["type"]; + type: Tables["PlayerResult"]["type"]; }) { const rows = stm.all({ userId, season, type }) as any[]; @@ -43,7 +43,7 @@ export function seasonsMatesEnemiesByUserId({ setWins: number; setLosses: number; user: Pick< - User, + Tables["User"], "id" | "username" | "discordAvatar" | "discordId" | "customUrl" >; }>; diff --git a/app/features/sendouq/queries/setGroupAsActive.server.ts b/app/features/sendouq/queries/setGroupAsActive.server.ts index 236229883..46a4fd36c 100644 --- a/app/features/sendouq/queries/setGroupAsActive.server.ts +++ b/app/features/sendouq/queries/setGroupAsActive.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Group } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` update "Group" @@ -7,6 +7,6 @@ const stm = sql.prepare(/* sql */ ` where "id" = @groupId `); -export function setGroupAsActive(groupId: Group["id"]) { +export function setGroupAsActive(groupId: Tables["Group"]["id"]) { stm.run({ groupId }); } diff --git a/app/features/sendouq/queries/updateNote.server.ts b/app/features/sendouq/queries/updateNote.server.ts index cf0bd6673..79d32b528 100644 --- a/app/features/sendouq/queries/updateNote.server.ts +++ b/app/features/sendouq/queries/updateNote.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { GroupMember } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` update "GroupMember" @@ -8,9 +8,9 @@ const stm = sql.prepare(/* sql */ ` `); export function updateNote(args: { - note: GroupMember["note"]; - groupId: GroupMember["groupId"]; - userId: GroupMember["userId"]; + note: Tables["GroupMember"]["note"]; + groupId: Tables["GroupMember"]["groupId"]; + userId: Tables["GroupMember"]["userId"]; }) { stm.run(args); } diff --git a/app/features/sendouq/routes/q.match.$id.tsx b/app/features/sendouq/routes/q.match.$id.tsx index b6cf7be07..6ff74f8a0 100644 --- a/app/features/sendouq/routes/q.match.$id.tsx +++ b/app/features/sendouq/routes/q.match.$id.tsx @@ -36,7 +36,6 @@ import { DiscordIcon } from "~/components/icons/Discord"; import { RefreshArrowsIcon } from "~/components/icons/RefreshArrows"; import { ScaleIcon } from "~/components/icons/Scale"; import { sql } from "~/db/sql"; -import type { GroupMember, ReportedWeapon } from "~/db/types"; import { useUser } from "~/features/auth/core/user"; import { getUserId, requireUser } from "~/features/auth/core/user.server"; import * as ChatSystemMessage from "~/features/chat/ChatSystemMessage.server"; @@ -113,6 +112,7 @@ import { reportedWeaponsByMatchId } from "../queries/reportedWeaponsByMatchId.se import { setGroupAsInactive } from "../queries/setGroupAsInactive.server"; import "../q.css"; import { SendouSwitch } from "~/components/elements/Switch"; +import type { ReportedWeapon, Tables } from "~/db/tables"; import { metaTags } from "~/utils/remix"; export const meta: MetaFunction = (args) => { @@ -751,7 +751,7 @@ function AfterMatchActions({ setShowWeaponsForm, }: { ownGroupId: number; - role: GroupMember["role"]; + role: Tables["GroupMember"]["role"]; reportedAt: number; showWeaponsForm: boolean; setShowWeaponsForm: (show: boolean) => void; diff --git a/app/features/sendouq/routes/q.tsx b/app/features/sendouq/routes/q.tsx index 58d16402f..2911510f9 100644 --- a/app/features/sendouq/routes/q.tsx +++ b/app/features/sendouq/routes/q.tsx @@ -21,7 +21,6 @@ import { SubmitButton } from "~/components/SubmitButton"; import { UserIcon } from "~/components/icons/User"; import { UsersIcon } from "~/components/icons/Users"; import { sql } from "~/db/sql"; -import type { GroupMember } from "~/db/types"; import { useUser } from "~/features/auth/core/user"; import { getUserId, requireUser } from "~/features/auth/core/user.server"; import type { RankingSeason } from "~/features/mmr/season"; @@ -67,6 +66,7 @@ import { deleteLikesByGroupId } from "../queries/deleteLikesByGroupId.server"; import { findCurrentGroupByUserId } from "../queries/findCurrentGroupByUserId.server"; import { findGroupByInviteCode } from "../queries/findGroupByInviteCode.server"; import "../q.css"; +import type { Tables } from "~/db/tables"; import { metaTags } from "~/utils/remix"; export const handle: SendouRouteHandle = { @@ -402,7 +402,7 @@ function JoinTeamDialog({ close: () => void; members: { username: string; - role: GroupMember["role"]; + role: Tables["GroupMember"]["role"]; }[]; }) { const { t } = useTranslation(["q"]); diff --git a/app/features/team/loaders/t.server.ts b/app/features/team/loaders/t.server.ts index 01a78c9e4..c80313d64 100644 --- a/app/features/team/loaders/t.server.ts +++ b/app/features/team/loaders/t.server.ts @@ -1,5 +1,5 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; -import type { UserWithPlusTier } from "~/db/types"; +import type { UserWithPlusTier } from "~/db/tables"; import { getUserId } from "~/features/auth/core/user.server"; import { sumArray } from "~/utils/number"; import * as TeamRepository from "../TeamRepository.server"; diff --git a/app/features/top-search/queries/findPlacements.server.ts b/app/features/top-search/queries/findPlacements.server.ts index b3a072c76..97be32a03 100644 --- a/app/features/top-search/queries/findPlacements.server.ts +++ b/app/features/top-search/queries/findPlacements.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { User, XRankPlacement } from "~/db/types"; +import type { Tables } from "~/db/tables"; const query = (byPlayer?: boolean) => /* sql */ ` select @@ -48,7 +48,7 @@ const ofMonthStm = sql.prepare(query()); const byPlayerStm = sql.prepare(query(true)); export type FindPlacement = Pick< - XRankPlacement, + Tables["XRankPlacement"], | "id" | "weaponSplId" | "name" @@ -60,15 +60,17 @@ export type FindPlacement = Pick< | "playerId" | "mode" > & - Pick; + Pick; export function findPlacementsOfMonth( - args: Pick, + args: Pick, ) { return ofMonthStm.all(args) as Array; } -export function findPlacementsByPlayerId(playerId: XRankPlacement["playerId"]) { +export function findPlacementsByPlayerId( + playerId: Tables["XRankPlacement"]["playerId"], +) { const results = byPlayerStm.all({ playerId }) as Array; if (!results) return null; diff --git a/app/features/top-search/routes/xsearch.tsx b/app/features/top-search/routes/xsearch.tsx index e18d71085..c4481fdc0 100644 --- a/app/features/top-search/routes/xsearch.tsx +++ b/app/features/top-search/routes/xsearch.tsx @@ -3,7 +3,6 @@ import { useLoaderData, useSearchParams } from "@remix-run/react"; import { nanoid } from "nanoid"; import { useTranslation } from "react-i18next"; import { Main } from "~/components/Main"; -import type { XRankPlacement } from "~/db/types"; import type { RankedModeShort } from "~/modules/in-game-lists"; import { rankedModesShort } from "~/modules/in-game-lists/modes"; import invariant from "~/utils/invariant"; @@ -16,6 +15,7 @@ import { monthYears } from "../queries/monthYears"; import type { MonthYear } from "../top-search-utils"; import "../top-search.css"; +import type { Tables } from "~/db/tables"; export const handle: SendouRouteHandle = { breadcrumb: () => ({ @@ -152,7 +152,7 @@ export default function XSearchPage() { interface SelectOption { id: string; - region: XRankPlacement["region"]; + region: Tables["XRankPlacement"]["region"]; mode: RankedModeShort; span: { from: MonthYear; diff --git a/app/features/tournament-bracket/core/brackets-manager/crud-db.server.ts b/app/features/tournament-bracket/core/brackets-manager/crud-db.server.ts index ffacd504c..f06a7369a 100644 --- a/app/features/tournament-bracket/core/brackets-manager/crud-db.server.ts +++ b/app/features/tournament-bracket/core/brackets-manager/crud-db.server.ts @@ -2,13 +2,7 @@ import { nanoid } from "nanoid"; import { sql } from "~/db/sql"; -import type { TournamentRoundMaps } from "~/db/tables"; -import type { - TournamentGroup, - TournamentMatch, - TournamentRound, - TournamentStage, -} from "~/db/types"; +import type { Tables, TournamentRoundMaps } from "~/db/tables"; import type { Group as GroupType, Match as MatchType, @@ -54,20 +48,20 @@ const stage_updateSettingsStm = sql.prepare(/*sql*/ ` `); export class Stage { - id?: TournamentStage["id"]; - tournamentId: TournamentStage["tournamentId"]; - number: TournamentStage["number"]; - name: TournamentStage["name"]; + id?: Tables["TournamentStage"]["id"]; + tournamentId: Tables["TournamentStage"]["tournamentId"]; + number: Tables["TournamentStage"]["number"]; + name: Tables["TournamentStage"]["name"]; type: StageType["type"]; - settings: TournamentStage["settings"]; + settings: Tables["TournamentStage"]["settings"]; constructor( - id: TournamentStage["id"] | undefined, - tournamentId: TournamentStage["tournamentId"], - number: TournamentStage["number"], - name: TournamentStage["name"], + id: Tables["TournamentStage"]["id"] | undefined, + tournamentId: Tables["TournamentStage"]["tournamentId"], + number: Tables["TournamentStage"]["number"], + name: Tables["TournamentStage"]["name"], type: StageType["type"], - settings: TournamentStage["settings"], + settings: Tables["TournamentStage"]["settings"], ) { this.id = id; this.tournamentId = tournamentId; @@ -92,7 +86,7 @@ export class Stage { return true; } - static #convertStage(rawStage: TournamentStage): StageType { + static #convertStage(rawStage: Tables["TournamentStage"]): StageType { return { id: rawStage.id, name: rawStage.name, @@ -104,7 +98,7 @@ export class Stage { }; } - static getById(id: TournamentStage["id"]): StageType { + static getById(id: Tables["TournamentStage"]["id"]): StageType { const stage = stage_getByIdStm.get({ id }) as any; if (!stage) return stage; return Stage.#convertStage(stage); @@ -117,8 +111,8 @@ export class Stage { } static updateSettings( - id: TournamentStage["id"], - settings: TournamentStage["settings"], + id: Tables["TournamentStage"]["id"], + settings: Tables["TournamentStage"]["settings"], ) { stage_updateSettingsStm.run({ id, settings }); @@ -155,21 +149,21 @@ const group_insertStm = sql.prepare(/*sql*/ ` `); export class Group { - id?: TournamentGroup["id"]; - stageId: TournamentGroup["stageId"]; - number: TournamentGroup["number"]; + id?: Tables["TournamentGroup"]["id"]; + stageId: Tables["TournamentGroup"]["stageId"]; + number: Tables["TournamentGroup"]["number"]; constructor( - id: TournamentGroup["id"] | undefined, - stageId: TournamentGroup["stageId"], - number: TournamentGroup["number"], + id: Tables["TournamentGroup"]["id"] | undefined, + stageId: Tables["TournamentGroup"]["stageId"], + number: Tables["TournamentGroup"]["number"], ) { this.id = id; this.stageId = stageId; this.number = number; } - static #convertGroup(rawGroup: TournamentGroup): GroupType { + static #convertGroup(rawGroup: Tables["TournamentGroup"]): GroupType { return { id: rawGroup.id, number: rawGroup.number, @@ -177,21 +171,21 @@ export class Group { }; } - static getById(id: TournamentGroup["id"]): GroupType { + static getById(id: Tables["TournamentGroup"]["id"]): GroupType { const group = group_getByIdStm.get({ id }) as any; if (!group) return group; return Group.#convertGroup(group); } - static getByStageId(stageId: TournamentStage["id"]): GroupType[] { + static getByStageId(stageId: Tables["TournamentStage"]["id"]): GroupType[] { return (group_getByStageIdStm.all({ stageId }) as any[]).map( Group.#convertGroup, ); } static getByStageAndNumber( - stageId: TournamentStage["id"], - number: TournamentGroup["number"], + stageId: Tables["TournamentStage"]["id"], + number: Tables["TournamentGroup"]["number"], ): GroupType { const group = group_getByStageAndNumberStm.get({ stageId, number }) as any; if (!group) return group; @@ -245,17 +239,17 @@ const round_insertStm = sql.prepare(/*sql*/ ` `); export class Round { - id?: TournamentRound["id"]; - stageId: TournamentRound["stageId"]; - groupId: TournamentRound["groupId"]; - number: TournamentRound["number"]; + id?: Tables["TournamentRound"]["id"]; + stageId: Tables["TournamentRound"]["stageId"]; + groupId: Tables["TournamentRound"]["groupId"]; + number: Tables["TournamentRound"]["number"]; maps: Pick; constructor( - id: TournamentRound["id"] | undefined, - stageId: TournamentRound["stageId"], - groupId: TournamentRound["groupId"], - number: TournamentRound["number"], + id: Tables["TournamentRound"]["id"] | undefined, + stageId: Tables["TournamentRound"]["stageId"], + groupId: Tables["TournamentRound"]["groupId"], + number: Tables["TournamentRound"]["number"], maps: Pick, ) { this.id = id; @@ -278,7 +272,7 @@ export class Round { } static #convertRound( - rawRound: TournamentRound & { maps?: string | null }, + rawRound: Tables["TournamentRound"] & { maps?: string | null }, ): RoundType { const parsedMaps = rawRound.maps ? JSON.parse(rawRound.maps) : null; @@ -297,28 +291,28 @@ export class Round { }; } - static getByStageId(stageId: TournamentStage["id"]): RoundType[] { + static getByStageId(stageId: Tables["TournamentStage"]["id"]): RoundType[] { return (round_getByStageIdStm.all({ stageId }) as any[]).map( Round.#convertRound, ); } - static getByGroupId(groupId: TournamentGroup["id"]): RoundType[] { + static getByGroupId(groupId: Tables["TournamentGroup"]["id"]): RoundType[] { return (round_getByGroupIdStm.all({ groupId }) as any[]).map( Round.#convertRound, ); } static getByGroupAndNumber( - groupId: TournamentGroup["id"], - number: TournamentRound["number"], + groupId: Tables["TournamentGroup"]["id"], + number: Tables["TournamentRound"]["number"], ): RoundType { const round = round_getByGroupAndNumberStm.get({ groupId, number }) as any; if (!round) return round; return Round.#convertRound(round); } - static getById(id: TournamentRound["id"]): RoundType { + static getById(id: Tables["TournamentRound"]["id"]): RoundType { const round = round_getByIdStm.get({ id }) as any; if (!round) return round; return Round.#convertRound(round); @@ -380,27 +374,27 @@ const match_updateStm = sql.prepare(/*sql*/ ` `); export class Match { - id?: TournamentMatch["id"]; - roundId: TournamentMatch["roundId"]; - stageId: TournamentMatch["stageId"]; - groupId: TournamentMatch["groupId"]; - number: TournamentMatch["number"]; - opponentOne: TournamentMatch["opponentOne"]; - opponentTwo: TournamentMatch["opponentTwo"]; - status: TournamentMatch["status"]; + id?: Tables["TournamentMatch"]["id"]; + roundId: Tables["TournamentMatch"]["roundId"]; + stageId: Tables["TournamentMatch"]["stageId"]; + groupId: Tables["TournamentMatch"]["groupId"]; + number: Tables["TournamentMatch"]["number"]; + opponentOne: string; + opponentTwo: string; + status: Tables["TournamentMatch"]["status"]; constructor( - id: TournamentMatch["id"] | undefined, - status: TournamentMatch["status"], - stageId: TournamentMatch["stageId"], - groupId: TournamentMatch["groupId"], - roundId: TournamentMatch["roundId"], - number: TournamentMatch["number"], + id: Tables["TournamentMatch"]["id"] | undefined, + status: Tables["TournamentMatch"]["status"], + stageId: Tables["TournamentMatch"]["stageId"], + groupId: Tables["TournamentMatch"]["groupId"], + roundId: Tables["TournamentMatch"]["roundId"], + number: Tables["TournamentMatch"]["number"], _unknown1: null, _unknown2: null, _unknown3: null, - opponentOne: TournamentMatch["opponentOne"], - opponentTwo: TournamentMatch["opponentTwo"], + opponentOne: string, + opponentTwo: string, ) { this.id = id; this.roundId = roundId; @@ -413,7 +407,9 @@ export class Match { } static #convertMatch( - rawMatch: TournamentMatch & { + rawMatch: Tables["TournamentMatch"] & { + opponentOne: string; + opponentTwo: string; opponentOnePointsTotal: number | null; opponentTwoPointsTotal: number | null; lastGameFinishedAt: number | null; @@ -446,27 +442,27 @@ export class Match { }; } - static getById(id: TournamentMatch["id"]): MatchType { + static getById(id: Tables["TournamentMatch"]["id"]): MatchType { const match = match_getByIdStm.get({ id }) as any; if (!match) return match; return Match.#convertMatch(match); } - static getByRoundId(roundId: TournamentRound["id"]): MatchType[] { + static getByRoundId(roundId: Tables["TournamentRound"]["id"]): MatchType[] { return (match_getByRoundIdStm.all({ roundId }) as any[]).map( Match.#convertMatch, ); } - static getByStageId(stageId: TournamentStage["id"]): MatchType[] { + static getByStageId(stageId: Tables["TournamentStage"]["id"]): MatchType[] { return (match_getByStageIdStm.all({ stageId }) as any[]).map( Match.#convertMatch, ); } static getByRoundAndNumber( - roundId: TournamentRound["id"], - number: TournamentMatch["number"], + roundId: Tables["TournamentRound"]["id"], + number: Tables["TournamentMatch"]["number"], ): MatchType { const match = match_getByRoundAndNumberStm.get({ roundId, number }) as any; if (!match) return match; diff --git a/app/features/tournament-bracket/core/summarizer.server.ts b/app/features/tournament-bracket/core/summarizer.server.ts index c204eb0c1..1675fdf56 100644 --- a/app/features/tournament-bracket/core/summarizer.server.ts +++ b/app/features/tournament-bracket/core/summarizer.server.ts @@ -1,12 +1,6 @@ import shuffle from "just-shuffle"; import type { Rating } from "node_modules/openskill/dist/types"; import { ordinal } from "openskill"; -import type { - MapResult, - PlayerResult, - Skill, - TournamentResult, -} from "~/db/types"; import { identifierToUserIds, rate, @@ -21,13 +15,16 @@ import type { Standing } from "./Bracket"; export interface TournamentSummary { skills: Omit< - Skill, + Tables["Skill"], "tournamentId" | "id" | "ordinal" | "season" | "groupMatchId" >[]; seedingSkills: Tables["SeedingSkill"][]; - mapResultDeltas: Omit[]; - playerResultDeltas: Omit[]; - tournamentResults: Omit[]; + mapResultDeltas: Omit[]; + playerResultDeltas: Omit[]; + tournamentResults: Omit< + Tables["TournamentResult"], + "tournamentId" | "isHighlight" + >[]; } type UserIdToTeamId = Record; @@ -294,7 +291,7 @@ function mapResultDeltas( const result: TournamentSummary["mapResultDeltas"] = []; const addMapResult = ( - mapResult: Pick & { + mapResult: Pick & { type: "win" | "loss"; }, ) => { diff --git a/app/features/tournament-bracket/queries/addSummary.server.ts b/app/features/tournament-bracket/queries/addSummary.server.ts index f715be9fa..bd51c4a32 100644 --- a/app/features/tournament-bracket/queries/addSummary.server.ts +++ b/app/features/tournament-bracket/queries/addSummary.server.ts @@ -1,6 +1,6 @@ import { ordinal } from "openskill"; import { sql } from "~/db/sql"; -import type { Skill } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { identifierToUserIds } from "~/features/mmr/mmr-utils"; import type { TournamentSummary } from "../core/summarizer.server"; @@ -140,7 +140,7 @@ export const addSummary = sql.transaction( identifier: skill.identifier ?? null, matchesCount: skill.matchesCount, season: season ?? null, - }) as Skill; + }) as Tables["Skill"]; if (insertedSkill.identifier) { for (const userId of identifierToUserIds(insertedSkill.identifier)) { diff --git a/app/features/tournament-bracket/queries/bestOfsByTournamentId.server.ts b/app/features/tournament-bracket/queries/bestOfsByTournamentId.server.ts index 50b8d50f5..55f5edf38 100644 --- a/app/features/tournament-bracket/queries/bestOfsByTournamentId.server.ts +++ b/app/features/tournament-bracket/queries/bestOfsByTournamentId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentMatch, TournamentRound } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -13,8 +13,8 @@ const stm = sql.prepare(/* sql */ ` `); interface BestOfByTournamentId { - roundId: TournamentRound["id"]; - bestOf: TournamentMatch["bestOf"]; + roundId: Tables["TournamentRound"]["id"]; + bestOf: Tables["TournamentMatch"]["bestOf"]; } export function bestOfsByTournamentId(tournamentId: number) { diff --git a/app/features/tournament-bracket/queries/findMapPoolByTeamId.server.ts b/app/features/tournament-bracket/queries/findMapPoolByTeamId.server.ts index d7460d256..144a48f3f 100644 --- a/app/features/tournament-bracket/queries/findMapPoolByTeamId.server.ts +++ b/app/features/tournament-bracket/queries/findMapPoolByTeamId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { MapPoolMap } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/*sql*/ ` select @@ -12,5 +12,7 @@ const stm = sql.prepare(/*sql*/ ` `); export function findMapPoolByTeamId(teamId: number) { - return stm.all({ teamId }) as Array>; + return stm.all({ teamId }) as Array< + Pick + >; } diff --git a/app/features/tournament-bracket/queries/findMatchById.server.ts b/app/features/tournament-bracket/queries/findMatchById.server.ts index dbec6961c..2eea3aec5 100644 --- a/app/features/tournament-bracket/queries/findMatchById.server.ts +++ b/app/features/tournament-bracket/queries/findMatchById.server.ts @@ -1,11 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentRoundMaps } from "~/db/tables"; -import type { - Tournament, - TournamentMatch, - TournamentTeamMember, - User, -} from "~/db/types"; +import type { Tables, TournamentRoundMaps } from "~/db/tables"; import type { Match } from "~/modules/brackets-model"; import { parseDBArray } from "~/utils/sql"; @@ -57,10 +51,12 @@ export type FindMatchById = ReturnType; export const findMatchById = (id: number) => { const row = stm.get({ id }) as | ((Pick< - TournamentMatch, - "id" | "groupId" | "opponentOne" | "opponentTwo" | "bestOf" | "chatCode" + Tables["TournamentMatch"], + "id" | "groupId" | "bestOf" | "chatCode" > & - Pick & { players: string }) & { + Pick & { players: string }) & { + opponentOne: string; + opponentTwo: string; roundId: number; roundMaps: string | null; }) @@ -81,13 +77,13 @@ export const findMatchById = (id: number) => { opponentTwo: JSON.parse(row.opponentTwo) as Match["opponent2"], players: ( parseDBArray(row.players) as Array<{ - id: User["id"]; - username: User["username"]; - tournamentTeamId: TournamentTeamMember["tournamentTeamId"]; - inGameName: User["inGameName"]; - discordId: User["discordId"]; - customUrl: User["customUrl"]; - discordAvatar: User["discordAvatar"]; + id: Tables["User"]["id"]; + username: Tables["User"]["username"]; + tournamentTeamId: Tables["TournamentTeamMember"]["tournamentTeamId"]; + inGameName: Tables["User"]["inGameName"]; + discordId: Tables["User"]["discordId"]; + customUrl: Tables["User"]["customUrl"]; + discordAvatar: Tables["User"]["discordAvatar"]; chatNameColor: string | null; }> ).filter((player) => player.id), diff --git a/app/features/tournament-bracket/queries/findResultsByMatchId.server.ts b/app/features/tournament-bracket/queries/findResultsByMatchId.server.ts index 087f09ff9..54a87ac1d 100644 --- a/app/features/tournament-bracket/queries/findResultsByMatchId.server.ts +++ b/app/features/tournament-bracket/queries/findResultsByMatchId.server.ts @@ -1,6 +1,5 @@ import { sql } from "~/db/sql"; import type { Tables } from "~/db/tables"; -import type { TournamentMatchGameResult } from "~/db/types"; import { parseDBArray } from "~/utils/sql"; const stm = sql.prepare(/* sql */ ` @@ -27,17 +26,17 @@ const stm = sql.prepare(/* sql */ ` `); interface FindResultsByMatchIdResult { - id: TournamentMatchGameResult["id"]; - winnerTeamId: TournamentMatchGameResult["winnerTeamId"]; - stageId: TournamentMatchGameResult["stageId"]; - mode: TournamentMatchGameResult["mode"]; + id: Tables["TournamentMatchGameResult"]["id"]; + winnerTeamId: Tables["TournamentMatchGameResult"]["winnerTeamId"]; + stageId: Tables["TournamentMatchGameResult"]["stageId"]; + mode: Tables["TournamentMatchGameResult"]["mode"]; participants: Array< Pick< Tables["TournamentMatchGameResultParticipant"], "tournamentTeamId" | "userId" > >; - createdAt: TournamentMatchGameResult["createdAt"]; + createdAt: Tables["TournamentMatchGameResult"]["createdAt"]; opponentOnePoints: Tables["TournamentMatchGameResult"]["opponentOnePoints"]; opponentTwoPoints: Tables["TournamentMatchGameResult"]["opponentTwoPoints"]; } diff --git a/app/features/tournament-bracket/queries/findTieBreakerMapPoolByTournamentId.server.ts b/app/features/tournament-bracket/queries/findTieBreakerMapPoolByTournamentId.server.ts index 0eac8abfc..b3ad2c11a 100644 --- a/app/features/tournament-bracket/queries/findTieBreakerMapPoolByTournamentId.server.ts +++ b/app/features/tournament-bracket/queries/findTieBreakerMapPoolByTournamentId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { MapPoolMap } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/*sql*/ ` select @@ -17,6 +17,6 @@ const stm = sql.prepare(/*sql*/ ` export function findTieBreakerMapPoolByTournamentId(tournamentId: number) { return stm.all({ tournamentId }) as Array< - Pick + Pick >; } diff --git a/app/features/tournament-bracket/queries/insertTournamentMatchGameResult.server.ts b/app/features/tournament-bracket/queries/insertTournamentMatchGameResult.server.ts index ed3bc3847..d2cf4f5ad 100644 --- a/app/features/tournament-bracket/queries/insertTournamentMatchGameResult.server.ts +++ b/app/features/tournament-bracket/queries/insertTournamentMatchGameResult.server.ts @@ -1,6 +1,5 @@ import { sql } from "~/db/sql"; import type { Tables } from "~/db/tables"; -import type { TournamentMatchGameResult } from "~/db/types"; const stm = sql.prepare(/* sql */ ` insert into "TournamentMatchGameResult" @@ -13,5 +12,5 @@ const stm = sql.prepare(/* sql */ ` export function insertTournamentMatchGameResult( args: Omit, ) { - return stm.get(args) as TournamentMatchGameResult; + return stm.get(args) as Tables["TournamentMatchGameResult"]; } diff --git a/app/features/tournament-bracket/queries/playersThatPlayedByTeamId.server.ts b/app/features/tournament-bracket/queries/playersThatPlayedByTeamId.server.ts index 62a91ae95..5341b3179 100644 --- a/app/features/tournament-bracket/queries/playersThatPlayedByTeamId.server.ts +++ b/app/features/tournament-bracket/queries/playersThatPlayedByTeamId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` select @@ -26,7 +26,7 @@ const stm = sql.prepare(/* sql */ ` `); export type PlayerThatPlayedByTeamId = Pick< - User, + Tables["User"], "id" | "username" | "discordAvatar" | "discordId" | "customUrl" | "country" > & { tournamentTeamId: number }; diff --git a/app/features/tournament-bracket/tournament-bracket-utils.ts b/app/features/tournament-bracket/tournament-bracket-utils.ts index a4868532c..1c73c563d 100644 --- a/app/features/tournament-bracket/tournament-bracket-utils.ts +++ b/app/features/tournament-bracket/tournament-bracket-utils.ts @@ -1,6 +1,5 @@ import type { TFunction } from "i18next"; -import type { TournamentRoundMaps } from "~/db/tables"; -import type { TournamentMatch } from "~/db/types"; +import type { Tables, TournamentRoundMaps } from "~/db/tables"; import type { TournamentManagerDataSet } from "~/modules/brackets-manager/types"; import type { ModeShort, StageId } from "~/modules/in-game-lists"; import type { TournamentMaplistSource } from "~/modules/tournament-map-list-generator"; @@ -28,7 +27,7 @@ const NUM_MAP = { "9": ["9", "6", "8"], "0": ["0", "8"], }; -export function resolveRoomPass(matchId: TournamentMatch["id"]) { +export function resolveRoomPass(matchId: Tables["TournamentMatch"]["id"]) { let pass = "5"; for (let i = 0; i < 3; i++) { const { shuffle } = seededRandom(`${matchId}-${i}`); diff --git a/app/features/tournament-subs/queries/deleteSub.server.ts b/app/features/tournament-subs/queries/deleteSub.server.ts index 55daa19cc..65a08d050 100644 --- a/app/features/tournament-subs/queries/deleteSub.server.ts +++ b/app/features/tournament-subs/queries/deleteSub.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentSub } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` delete from "TournamentSub" @@ -9,7 +9,7 @@ const stm = sql.prepare(/* sql */ ` `); export function deleteSub( - args: Pick, + args: Pick, ) { stm.run(args); } diff --git a/app/features/tournament-subs/queries/findSubsByTournamentId.server.ts b/app/features/tournament-subs/queries/findSubsByTournamentId.server.ts index d729bf4ce..5ebf4d312 100644 --- a/app/features/tournament-subs/queries/findSubsByTournamentId.server.ts +++ b/app/features/tournament-subs/queries/findSubsByTournamentId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentSub, UserWithPlusTier } from "~/db/types"; +import type { Tables, UserWithPlusTier } from "~/db/tables"; import type { MainWeaponId } from "~/modules/in-game-lists"; const stm = sql.prepare(/* sql */ ` @@ -31,13 +31,13 @@ const stm = sql.prepare(/* sql */ ` `); export interface SubByTournamentId { - canVc: TournamentSub["canVc"]; + canVc: Tables["TournamentSub"]["canVc"]; bestWeapons: MainWeaponId[]; okWeapons: MainWeaponId[] | null; - message: TournamentSub["message"]; - visibility: TournamentSub["visibility"]; - createdAt: TournamentSub["createdAt"]; - userId: TournamentSub["userId"]; + message: Tables["TournamentSub"]["message"]; + visibility: Tables["TournamentSub"]["visibility"]; + createdAt: Tables["TournamentSub"]["createdAt"]; + userId: Tables["TournamentSub"]["userId"]; username: UserWithPlusTier["username"]; discordAvatar: UserWithPlusTier["discordAvatar"]; discordId: UserWithPlusTier["discordId"]; diff --git a/app/features/tournament-subs/queries/upsertSub.server.ts b/app/features/tournament-subs/queries/upsertSub.server.ts index 7d00e8cbd..f0e7524c9 100644 --- a/app/features/tournament-subs/queries/upsertSub.server.ts +++ b/app/features/tournament-subs/queries/upsertSub.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentSub } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` insert into "TournamentSub" ( @@ -30,6 +30,6 @@ const stm = sql.prepare(/* sql */ ` "visibility" = @visibility `); -export function upsertSub(args: Omit) { +export function upsertSub(args: Omit) { stm.run(args); } diff --git a/app/features/tournament/components/TeamWithRoster.tsx b/app/features/tournament/components/TeamWithRoster.tsx index 4bc592e35..d9af1c962 100644 --- a/app/features/tournament/components/TeamWithRoster.tsx +++ b/app/features/tournament/components/TeamWithRoster.tsx @@ -2,7 +2,7 @@ import { Link } from "@remix-run/react"; import clsx from "clsx"; import { Avatar } from "~/components/Avatar"; import { ModeImage, StageImage } from "~/components/Image"; -import type { MapPoolMap, User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { useUser } from "~/features/auth/core/user"; import type { TournamentDataTeam } from "~/features/tournament-bracket/core/Tournament.server"; import { databaseTimestampToDate } from "~/utils/dates"; @@ -18,10 +18,10 @@ export function TeamWithRoster({ activePlayers, }: { team: TournamentDataTeam; - mapPool?: Array> | null; + mapPool?: Array> | null; seed?: number; teamPageUrl?: string; - activePlayers?: User["id"][]; + activePlayers?: Tables["User"]["id"][]; }) { const user = useUser(); const tournament = useTournament(); @@ -136,7 +136,7 @@ function FreshAccountEmoji({ discordId }: { discordId: string }) { function TeamMapPool({ mapPool, }: { - mapPool: Array>; + mapPool: Array>; }) { return (
>; diff --git a/app/features/tournament/queries/changeTeamOwner.server.ts b/app/features/tournament/queries/changeTeamOwner.server.ts index 7ec13bde8..492d3f5ad 100644 --- a/app/features/tournament/queries/changeTeamOwner.server.ts +++ b/app/features/tournament/queries/changeTeamOwner.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentTeam, User } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/* sql */ ` update TournamentTeamMember @@ -11,9 +11,9 @@ const stm = sql.prepare(/* sql */ ` export const changeTeamOwner = sql.transaction( (args: { - tournamentTeamId: TournamentTeam["id"]; - oldCaptainId: User["id"]; - newCaptainId: User["id"]; + tournamentTeamId: Tables["TournamentTeam"]["id"]; + oldCaptainId: Tables["User"]["id"]; + newCaptainId: Tables["User"]["id"]; }) => { stm.run({ tournamentTeamId: args.tournamentTeamId, diff --git a/app/features/tournament/queries/findByIdentifier.server.ts b/app/features/tournament/queries/findByIdentifier.server.ts index 718ac7181..c5b5597ca 100644 --- a/app/features/tournament/queries/findByIdentifier.server.ts +++ b/app/features/tournament/queries/findByIdentifier.server.ts @@ -1,11 +1,5 @@ import { sql } from "~/db/sql"; import type { Tables } from "~/db/tables"; -import type { - CalendarEvent, - CalendarEventDate, - Tournament, - User, -} from "~/db/types"; const stm = sql.prepare(/*sql*/ ` select @@ -29,13 +23,13 @@ select `); type FindByIdentifierRow = (Pick< - CalendarEvent, + Tables["CalendarEvent"], "bracketUrl" | "name" | "description" | "authorId" > & - Pick & - Pick & - Pick) & { - eventId: CalendarEvent["id"]; + Pick & + Pick & + Pick) & { + eventId: Tables["CalendarEvent"]["id"]; } & { settings: string }; export function findByIdentifier(identifier: string | number) { @@ -59,7 +53,7 @@ export function findByIdentifier(identifier: string | number) { } function resolveEarliestStartTime( - rows: Pick[], + rows: Pick[], ) { return Math.min(...rows.map((row) => row.startTime)); } diff --git a/app/features/tournament/queries/findMapPoolsByTournamentId.server.ts b/app/features/tournament/queries/findMapPoolsByTournamentId.server.ts index 1a614bdd9..05f9185cc 100644 --- a/app/features/tournament/queries/findMapPoolsByTournamentId.server.ts +++ b/app/features/tournament/queries/findMapPoolsByTournamentId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { MapPoolMap } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { parseDBArray } from "~/utils/sql"; const stm = sql.prepare(/*sql*/ ` @@ -20,7 +20,7 @@ const stm = sql.prepare(/*sql*/ ` interface FindMapPoolsByTournamentIdItem { tournamentTeamId: number; - mapPool: Array>; + mapPool: Array>; } export function findMapPoolsByTournamentId( diff --git a/app/features/tournament/queries/findOwnTournamentTeam.server.ts b/app/features/tournament/queries/findOwnTournamentTeam.server.ts index 8a024fac1..5dd5c801c 100644 --- a/app/features/tournament/queries/findOwnTournamentTeam.server.ts +++ b/app/features/tournament/queries/findOwnTournamentTeam.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentTeam, TournamentTeamCheckIn } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/*sql*/ ` select @@ -20,8 +20,8 @@ const stm = sql.prepare(/*sql*/ ` `); type FindOwnTeam = - | (Pick & - Pick) + | (Pick & + Pick) | null; export function findOwnTournamentTeam({ diff --git a/app/features/tournament/queries/hasTournamentFinalized.server.ts b/app/features/tournament/queries/hasTournamentFinalized.server.ts index c0bbe81f0..af5a232aa 100644 --- a/app/features/tournament/queries/hasTournamentFinalized.server.ts +++ b/app/features/tournament/queries/hasTournamentFinalized.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Tournament } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/*sql*/ ` select 1 @@ -7,6 +7,8 @@ const stm = sql.prepare(/*sql*/ ` where "TournamentResult"."tournamentId" = @tournamentId `); -export default function hasTournamentFinalized(tournamentId: Tournament["id"]) { +export default function hasTournamentFinalized( + tournamentId: Tables["Tournament"]["id"], +) { return Boolean(stm.get({ tournamentId })); } diff --git a/app/features/tournament/queries/hasTournamentStarted.server.ts b/app/features/tournament/queries/hasTournamentStarted.server.ts index 6528513b9..a1047d0a3 100644 --- a/app/features/tournament/queries/hasTournamentStarted.server.ts +++ b/app/features/tournament/queries/hasTournamentStarted.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Tournament } from "~/db/types"; +import type { Tables } from "~/db/tables"; const stm = sql.prepare(/*sql*/ ` select 1 @@ -7,6 +7,8 @@ const stm = sql.prepare(/*sql*/ ` where "TournamentStage"."tournamentId" = @tournamentId `); -export default function hasTournamentStarted(tournamentId: Tournament["id"]) { +export default function hasTournamentStarted( + tournamentId: Tables["Tournament"]["id"], +) { return Boolean(stm.get({ tournamentId })); } diff --git a/app/features/tournament/queries/setHistoryByTeamId.server.ts b/app/features/tournament/queries/setHistoryByTeamId.server.ts index a82fa210b..1fbbff89a 100644 --- a/app/features/tournament/queries/setHistoryByTeamId.server.ts +++ b/app/features/tournament/queries/setHistoryByTeamId.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentMatchGameResult, User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { ModeShort, StageId } from "~/modules/in-game-lists"; import { removeDuplicatesByProperty } from "~/utils/arrays"; import { parseDBArray } from "~/utils/sql"; @@ -89,12 +89,15 @@ export interface SetHistoryByTeamIdItem { groupNumber: number; matches: { stageId: StageId; - source: TournamentMatchGameResult["source"]; + source: Tables["TournamentMatchGameResult"]["source"]; mode: ModeShort; wasWinner: number; }[]; players: Array< - Pick + Pick< + Tables["User"], + "id" | "username" | "discordAvatar" | "discordId" | "customUrl" + > >; } @@ -110,7 +113,7 @@ export function setHistoryByTeamId( // TODO: there is probably a way to do this in SQL players: removeDuplicatesByProperty( parseDBArray(row.players), - (u: Pick) => u.id, + (u: Pick) => u.id, ), }; }); diff --git a/app/features/tournament/queries/upsertCounterpickMaps.server.ts b/app/features/tournament/queries/upsertCounterpickMaps.server.ts index b2f5b5c64..c123c4ec2 100644 --- a/app/features/tournament/queries/upsertCounterpickMaps.server.ts +++ b/app/features/tournament/queries/upsertCounterpickMaps.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { TournamentTeam } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { MapPool } from "~/features/map-list-generator/core/map-pool"; const deleteCounterpickMapsByTeamIdStm = sql.prepare(/* sql */ ` @@ -21,7 +21,7 @@ export const upsertCounterpickMaps = sql.transaction( tournamentTeamId, mapPool, }: { - tournamentTeamId: TournamentTeam["id"]; + tournamentTeamId: Tables["TournamentTeam"]["id"]; mapPool: MapPool; }) => { deleteCounterpickMapsByTeamIdStm.run({ tournamentTeamId }); diff --git a/app/features/tournament/tournament-utils.ts b/app/features/tournament/tournament-utils.ts index d612f69cf..3586a2873 100644 --- a/app/features/tournament/tournament-utils.ts +++ b/app/features/tournament/tournament-utils.ts @@ -1,5 +1,4 @@ import type { Params } from "@remix-run/react"; -import type { Tournament } from "~/db/types"; import type { ModeShort, StageId } from "~/modules/in-game-lists"; import { rankedModesShort } from "~/modules/in-game-lists/modes"; import { weekNumberToDate } from "~/utils/dates"; @@ -23,7 +22,7 @@ export function tournamentIdFromParams(params: Params) { } export function modesIncluded( - tournament: Pick, + tournament: Pick, ): ModeShort[] { switch (tournament.mapPickingStyle) { case "AUTO_SZ": { @@ -45,7 +44,7 @@ export function modesIncluded( } export function isOneModeTournamentOf( - tournament: Pick, + tournament: Pick, ) { return modesIncluded(tournament).length === 1 ? modesIncluded(tournament)[0] diff --git a/app/features/user-page/UserRepository.server.ts b/app/features/user-page/UserRepository.server.ts index 378940aa2..6d1d32cce 100644 --- a/app/features/user-page/UserRepository.server.ts +++ b/app/features/user-page/UserRepository.server.ts @@ -5,10 +5,10 @@ import { db, sql as dbDirect } from "~/db/sql"; import type { BuildSort, DB, + Tables, TablesInsertable, UserPreferences, } from "~/db/tables"; -import type { User } from "~/db/types"; import { dateToDatabaseTimestamp } from "~/utils/dates"; import invariant from "~/utils/invariant"; import type { CommonUser } from "~/utils/kysely.server"; @@ -744,7 +744,7 @@ export function updateBuildSorting({ } export type UpdatePatronDataArgs = Array< - Pick + Pick >; export function updatePatronData(users: UpdatePatronDataArgs) { return db.transaction().execute(async (trx) => { @@ -792,7 +792,7 @@ export const updateMany = dbDirect.transaction( ( argsArr: Array< Pick< - User, + Tables["User"], "discordAvatar" | "discordName" | "discordUniqueName" | "discordId" > >, diff --git a/app/features/user-page/routes/u.$identifier.builds.new.tsx b/app/features/user-page/routes/u.$identifier.builds.new.tsx index f29f02e37..a0a577594 100644 --- a/app/features/user-page/routes/u.$identifier.builds.new.tsx +++ b/app/features/user-page/routes/u.$identifier.builds.new.tsx @@ -19,7 +19,6 @@ import { SubmitButton } from "~/components/SubmitButton"; import { CrossIcon } from "~/components/icons/Cross"; import { PlusIcon } from "~/components/icons/Plus"; import { BUILD } from "~/constants"; -import type { GearType } from "~/db/types"; import { validatedBuildFromSearchParams, validatedWeaponIdFromSearchParams, @@ -35,6 +34,7 @@ import type { SendouRouteHandle } from "~/utils/remix.server"; import { modeImageUrl } from "~/utils/urls"; import type { UserPageLoaderData } from "./u.$identifier"; +import type { GearType } from "~/db/tables"; import { action } from "../actions/u.$identifier.builds.new.server"; import { loader } from "../loaders/u.$identifier.builds.new.server"; export { loader, action }; diff --git a/app/features/user-page/routes/u.$identifier.edit.tsx b/app/features/user-page/routes/u.$identifier.edit.tsx index f2dbab952..4eae7f3b4 100644 --- a/app/features/user-page/routes/u.$identifier.edit.tsx +++ b/app/features/user-page/routes/u.$identifier.edit.tsx @@ -22,7 +22,6 @@ import { StarIcon } from "~/components/icons/Star"; import { StarFilledIcon } from "~/components/icons/StarFilled"; import { TrashIcon } from "~/components/icons/Trash"; import { USER } from "~/constants"; -import type { User } from "~/db/types"; import { useUser } from "~/features/auth/core/user"; import { requireUser, requireUserId } from "~/features/auth/core/user.server"; import * as TournamentTeamRepository from "~/features/tournament/TournamentTeamRepository.server"; @@ -56,6 +55,7 @@ import { userParamsSchema } from "../user-page-schemas.server"; import type { UserPageLoaderData } from "./u.$identifier"; import "~/styles/u-edit.css"; import { SendouSwitch } from "~/components/elements/Switch"; +import type { Tables } from "~/db/tables"; import { clearTournamentDataCache } from "~/features/tournament-bracket/core/Tournament.server"; export const userEditActionSchema = z @@ -555,7 +555,9 @@ function WeaponPoolSelect() { ); } -function BioTextarea({ initialValue }: { initialValue: User["bio"] }) { +function BioTextarea({ + initialValue, +}: { initialValue: Tables["User"]["bio"] }) { const { t } = useTranslation("user"); const [value, setValue] = React.useState(initialValue ?? ""); @@ -664,7 +666,7 @@ function CommissionsOpenToggle({ function CommissionTextArea({ initialValue, }: { - initialValue: User["commissionText"]; + initialValue: Tables["User"]["commissionText"]; }) { const { t } = useTranslation(["user"]); const [value, setValue] = React.useState(initialValue ?? ""); diff --git a/app/features/vods/queries/createVod.server.ts b/app/features/vods/queries/createVod.server.ts index 7c50193f1..d2b8545fe 100644 --- a/app/features/vods/queries/createVod.server.ts +++ b/app/features/vods/queries/createVod.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Video } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { dateToDatabaseTimestamp, dayMonthYearToDatabaseTimestamp, @@ -61,7 +61,7 @@ export const createVod = sql.transaction( validatedAt: args.isValidated ? dateToDatabaseTimestamp(new Date()) : null, - }) as Video; + }) as Tables["Video"]; for (const match of args.matches) { const videoMatch = createVideoMatchStm.get({ diff --git a/app/features/vods/queries/findVods.server.ts b/app/features/vods/queries/findVods.server.ts index 9f4118e37..4a009db6b 100644 --- a/app/features/vods/queries/findVods.server.ts +++ b/app/features/vods/queries/findVods.server.ts @@ -1,5 +1,5 @@ import { sql } from "~/db/sql"; -import type { Video } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { MainWeaponId, ModeShort, StageId } from "~/modules/in-game-lists"; import { removeDuplicates } from "~/utils/arrays"; import { parseDBArray, parseDBJsonArray } from "~/utils/sql"; @@ -57,7 +57,7 @@ export function findVods({ weapon?: MainWeaponId; mode?: ModeShort; stageId?: StageId; - type?: Video["type"]; + type?: Tables["Video"]["type"]; userId?: number; limit?: number; }): Array { diff --git a/app/features/vods/routes/vods.new.tsx b/app/features/vods/routes/vods.new.tsx index 6bc3d9d04..1edd12241 100644 --- a/app/features/vods/routes/vods.new.tsx +++ b/app/features/vods/routes/vods.new.tsx @@ -21,7 +21,7 @@ import { Main } from "~/components/Main"; import { UserSearch } from "~/components/UserSearch"; import { AddFieldButton } from "~/components/form/AddFieldButton"; import { RemoveFieldButton } from "~/components/form/RemoveFieldButton"; -import type { Video } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { requireUser } from "~/features/auth/core/user.server"; import { type MainWeaponId, @@ -62,7 +62,7 @@ export const action: ActionFunction = async ({ request }) => { throw new Response(null, { status: 401 }); } - let video: Video; + let video: Tables["Video"]; if (data.vodToEditId) { const vod = notFoundIfFalsy(findVodById(data.vodToEditId)); @@ -301,7 +301,9 @@ function PovFormField() { ); } -function MatchesFormfield({ videoType }: { videoType: Video["type"] }) { +function MatchesFormfield({ + videoType, +}: { videoType: Tables["Video"]["type"] }) { const { formState: { errors }, } = useFormContext(); @@ -347,7 +349,7 @@ function MatchesFieldset({ idx: number; remove: (idx: number) => void; canRemove: boolean; - videoType: Video["type"]; + videoType: Tables["Video"]["type"]; }) { const id = React.useId(); const { t } = useTranslation(["vods", "game-misc"]); diff --git a/app/features/vods/vods-constants.ts b/app/features/vods/vods-constants.ts index f322231c5..97455da82 100644 --- a/app/features/vods/vods-constants.ts +++ b/app/features/vods/vods-constants.ts @@ -1,4 +1,4 @@ -import type { Video } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { assertType } from "~/utils/types"; export const videoMatchTypes = [ @@ -8,6 +8,9 @@ export const videoMatchTypes = [ "MATCHMAKING", "SENDOUQ", ] as const; -assertType<(typeof videoMatchTypes)[number], Array[number]>(); +assertType< + (typeof videoMatchTypes)[number], + Array[number] +>(); export const VODS_PAGE_BATCH_SIZE = 24; diff --git a/app/features/vods/vods-types.ts b/app/features/vods/vods-types.ts index 84dede338..035d62b2f 100644 --- a/app/features/vods/vods-types.ts +++ b/app/features/vods/vods-types.ts @@ -1,5 +1,5 @@ import type { z } from "zod"; -import type { User, Video, VideoMatch } from "~/db/types"; +import type { Tables } from "~/db/tables"; import type { MainWeaponId } from "~/modules/in-game-lists"; import type { videoMatchSchema, videoSchema } from "./vods-schemas"; @@ -10,23 +10,23 @@ export type VideoBeingAdded = z.infer; export type VideoMatchBeingAdded = z.infer; export interface Vod { - id: Video["id"]; + id: Tables["Video"]["id"]; pov?: | Pick< - User, + Tables["User"], "username" | "discordId" | "discordAvatar" | "customUrl" | "id" > | string; - title: Video["title"]; - type: Video["type"]; - youtubeDate: Video["youtubeDate"]; - youtubeId: Video["youtubeId"]; + title: Tables["Video"]["title"]; + type: Tables["Video"]["type"]; + youtubeDate: Tables["Video"]["youtubeDate"]; + youtubeId: Tables["Video"]["youtubeId"]; matches: Array; - submitterUserId: Video["submitterUserId"]; + submitterUserId: Tables["Video"]["submitterUserId"]; } export type VodMatch = Pick< - VideoMatch, + Tables["VideoMatch"], "id" | "mode" | "stageId" | "startsAt" > & { weapons: Array; @@ -34,5 +34,5 @@ export type VodMatch = Pick< export type ListVod = Omit & { weapons: Array; - type: Video["type"]; + type: Tables["Video"]["type"]; }; diff --git a/app/features/vods/vods-utils.ts b/app/features/vods/vods-utils.ts index 8f3e8b08f..e6e92afca 100644 --- a/app/features/vods/vods-utils.ts +++ b/app/features/vods/vods-utils.ts @@ -1,4 +1,4 @@ -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { isAdmin } from "~/permissions"; import { databaseTimestampToDate } from "../../utils/dates"; import { HOURS_MINUTES_SECONDS_REGEX } from "./vods-schemas"; @@ -41,9 +41,9 @@ export function canEditVideo({ submitterUserId, povUserId, }: { - userId?: User["id"]; - submitterUserId: User["id"]; - povUserId?: User["id"]; + userId?: Tables["User"]["id"]; + submitterUserId: Tables["User"]["id"]; + povUserId?: Tables["User"]["id"]; }) { if (!userId) return false; diff --git a/app/modules/brackets-manager/test/double-elimination.test.ts b/app/modules/brackets-manager/test/double-elimination.test.ts index f70d9148f..ab668c710 100644 --- a/app/modules/brackets-manager/test/double-elimination.test.ts +++ b/app/modules/brackets-manager/test/double-elimination.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, test } from "vitest"; -import { Status } from "~/db/types"; +import { TournamentMatchStatus } from "~/db/tables"; import { InMemoryDatabase } from "~/modules/brackets-memory-db"; import { BracketsManager } from "../manager"; @@ -125,7 +125,7 @@ describe("Previous and next match update in double elimination stage", () => { expect(matchSemiLB.opponent2.id).toBe(loserId); expect(matchSemiLB.opponent2.result).toBe("win"); - expect(matchSemiLB.status).toBe(Status.Completed); + expect(matchSemiLB.status).toBe(TournamentMatchStatus.Completed); expect( storage.select("match", 4).opponent2.id, // Propagated winner in LB Final because of the BYE. @@ -136,7 +136,7 @@ describe("Previous and next match update in double elimination stage", () => { matchSemiLB = storage.select("match", 3); expect(matchSemiLB.opponent2.id).toBeNull(); expect(matchSemiLB.opponent2.result).toBeUndefined(); - expect(matchSemiLB.status).toBe(Status.Locked); + expect(matchSemiLB.status).toBe(TournamentMatchStatus.Locked); expect(storage.select("match", 4).opponent2.id).toBeNull(); // Propagated winner is removed. }); @@ -198,8 +198,12 @@ describe("Previous and next match update in double elimination stage", () => { storage.select("match", 6).opponent2.id, // Determined opponent for the grand final (round 2) ).toBe(storage.select("match", 1).opponent2.id); // Winner of LB Final - expect(storage.select("match", 5).status).toBe(Status.Completed); // Grand final (round 1) - expect(storage.select("match", 6).status).toBe(Status.Ready); // Grand final (round 2) + expect(storage.select("match", 5).status).toBe( + TournamentMatchStatus.Completed, + ); // Grand final (round 1) + expect(storage.select("match", 6).status).toBe( + TournamentMatchStatus.Ready, + ); // Grand final (round 2) manager.update.match({ id: 6, // Grand Final round 2 @@ -269,7 +273,9 @@ describe("Previous and next match update in double elimination stage", () => { manager.update.match({ id: 15, opponent1: { result: "win" } }); // LB 1.1 manager.update.match({ id: 19, opponent1: { result: "win" } }); // LB 2.1 - expect(storage.select("match", 8).status).toBe(Status.Completed); // WB 2.1 + expect(storage.select("match", 8).status).toBe( + TournamentMatchStatus.Completed, + ); // WB 2.1 }); test("should send the losers to the right LB matches in round 1", () => { diff --git a/app/modules/brackets-manager/test/single-elimination.test.ts b/app/modules/brackets-manager/test/single-elimination.test.ts index 23bca0a0c..f0aeb2502 100644 --- a/app/modules/brackets-manager/test/single-elimination.test.ts +++ b/app/modules/brackets-manager/test/single-elimination.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, test } from "vitest"; -import { Status } from "~/db/types"; +import { TournamentMatchStatus } from "~/db/tables"; import { InMemoryDatabase } from "~/modules/brackets-memory-db"; import { BracketsManager } from "../manager"; @@ -219,8 +219,12 @@ describe("Previous and next match update", () => { expect(storage.select("match", 3).opponent2.id).toBe( storage.select("match", 1).opponent1.id, ); - expect(storage.select("match", 2).status).toBe(Status.Ready); - expect(storage.select("match", 3).status).toBe(Status.Ready); + expect(storage.select("match", 2).status).toBe( + TournamentMatchStatus.Ready, + ); + expect(storage.select("match", 3).status).toBe( + TournamentMatchStatus.Ready, + ); }); test("should play both the final and consolation final in parallel", () => { @@ -250,8 +254,12 @@ describe("Previous and next match update", () => { opponent2: { score: 9 }, }); - expect(storage.select("match", 2).status).toBe(Status.Running); - expect(storage.select("match", 3).status).toBe(Status.Ready); + expect(storage.select("match", 2).status).toBe( + TournamentMatchStatus.Running, + ); + expect(storage.select("match", 3).status).toBe( + TournamentMatchStatus.Ready, + ); manager.update.match({ id: 3, // Consolation final @@ -259,8 +267,12 @@ describe("Previous and next match update", () => { opponent2: { score: 9 }, }); - expect(storage.select("match", 2).status).toBe(Status.Running); - expect(storage.select("match", 3).status).toBe(Status.Running); + expect(storage.select("match", 2).status).toBe( + TournamentMatchStatus.Running, + ); + expect(storage.select("match", 3).status).toBe( + TournamentMatchStatus.Running, + ); manager.update.match({ id: 3, // Consolation final @@ -268,7 +280,9 @@ describe("Previous and next match update", () => { opponent2: { score: 9 }, }); - expect(storage.select("match", 2).status).toBe(Status.Running); + expect(storage.select("match", 2).status).toBe( + TournamentMatchStatus.Running, + ); manager.update.match({ id: 2, // Final diff --git a/app/modules/brackets-manager/test/update.test.ts b/app/modules/brackets-manager/test/update.test.ts index 47c1267ab..5dce89d92 100644 --- a/app/modules/brackets-manager/test/update.test.ts +++ b/app/modules/brackets-manager/test/update.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, test } from "vitest"; -import { Status } from "~/db/types"; +import { TournamentMatchStatus } from "~/db/tables"; import { InMemoryDatabase } from "~/modules/brackets-memory-db"; import { BracketsManager } from "../manager"; @@ -22,7 +22,7 @@ describe("Update matches", () => { test("should start a match", () => { const before = storage.select("match", 0); - expect(before.status).toBe(Status.Ready); + expect(before.status).toBe(TournamentMatchStatus.Ready); manager.update.match({ id: 0, @@ -31,7 +31,7 @@ describe("Update matches", () => { }); const after = storage.select("match", 0); - expect(after.status).toBe(Status.Running); + expect(after.status).toBe(TournamentMatchStatus.Running); }); test("should update the scores for a match and set it to running", () => { @@ -42,7 +42,7 @@ describe("Update matches", () => { }); const after = storage.select("match", 0); - expect(after.status).toBe(Status.Running); + expect(after.status).toBe(TournamentMatchStatus.Running); expect(after.opponent1.score).toBe(2); // Name should stay. It shouldn't be overwritten. @@ -59,7 +59,7 @@ describe("Update matches", () => { }); const after = storage.select("match", 0); - expect(after.status).toBe(Status.Completed); + expect(after.status).toBe(TournamentMatchStatus.Completed); expect(after.opponent1.result).toBe("win"); expect(after.opponent2.result).toBe("loss"); }); @@ -78,12 +78,12 @@ describe("Update matches", () => { }); const after = storage.select("match", 0); - expect(after.status).toBe(Status.Completed); + expect(after.status).toBe(TournamentMatchStatus.Completed); expect(after.opponent1.result).toBe("loss"); expect(after.opponent2.result).toBe("win"); const nextMatch = storage.select("match", 8); - expect(nextMatch.status).toBe(Status.Waiting); + expect(nextMatch.status).toBe(TournamentMatchStatus.Waiting); expect(nextMatch.opponent1.id).toBe(2); }); @@ -93,20 +93,24 @@ describe("Update matches", () => { opponent1: { result: "win" }, }); - expect(storage.select("match", 8).status).toBe(Status.Waiting); + expect(storage.select("match", 8).status).toBe( + TournamentMatchStatus.Waiting, + ); manager.update.match({ id: 1, opponent1: { result: "win" }, }); - expect(storage.select("match", 8).status).toBe(Status.Ready); + expect(storage.select("match", 8).status).toBe( + TournamentMatchStatus.Ready, + ); }); test("should end the match by setting winner and loser", () => { manager.update.match({ id: 0, - status: Status.Running, + status: TournamentMatchStatus.Running, }); manager.update.match({ @@ -116,7 +120,7 @@ describe("Update matches", () => { }); const after = storage.select("match", 0); - expect(after.status).toBe(Status.Completed); + expect(after.status).toBe(TournamentMatchStatus.Completed); expect(after.opponent1.result).toBe("win"); expect(after.opponent2.result).toBe("loss"); }); @@ -131,7 +135,7 @@ describe("Update matches", () => { manager.reset.matchResults(0); const after = storage.select("match", 0); - expect(after.status).toBe(Status.Ready); + expect(after.status).toBe(TournamentMatchStatus.Ready); expect(after.opponent1.result).toBeFalsy(); expect(after.opponent2.result).toBeFalsy(); }); @@ -146,7 +150,7 @@ describe("Update matches", () => { manager.reset.matchResults(0); const after = storage.select("match", 0); - expect(after.status).toBe(Status.Running); + expect(after.status).toBe(TournamentMatchStatus.Running); expect(after.opponent1.result).toBeFalsy(); expect(after.opponent2.result).toBeFalsy(); }); @@ -160,7 +164,7 @@ describe("Update matches", () => { }); const after = storage.select("match", 1); - expect(after.status).toBe(Status.Running); + expect(after.status).toBe(TournamentMatchStatus.Running); expect(after.opponent1.score).toBe(1); expect(after.opponent2.score).toBeFalsy(); }); @@ -173,7 +177,7 @@ describe("Update matches", () => { }); const after = storage.select("match", 1); - expect(after.status).toBe(Status.Completed); + expect(after.status).toBe(TournamentMatchStatus.Completed); expect(after.opponent1.result).toBe("loss"); expect(after.opponent1.score).toBe(6); diff --git a/app/permissions.ts b/app/permissions.ts index 4422ab262..364d70c4a 100644 --- a/app/permissions.ts +++ b/app/permissions.ts @@ -1,12 +1,7 @@ +import type { Tables, UserWithPlusTier } from "~/db/tables"; import type * as PlusSuggestionRepository from "~/features/plus-suggestions/PlusSuggestionRepository.server"; import invariant from "~/utils/invariant"; import { ADMIN_ID, LOHI_TOKEN_HEADER_NAME, MOD_IDS } from "./constants"; -import type { - CalendarEvent, - PlusSuggestion, - User, - UserWithPlusTier, -} from "./db/types"; import { currentSeason, nextSeason } from "./features/mmr/season"; import { isVotingActive } from "./features/plus-voting/core"; import type { FindMatchById } from "./features/tournament-bracket/queries/findMatchById.server"; @@ -15,7 +10,7 @@ import { databaseTimestampToDate } from "./utils/dates"; // TODO: 1) move "root checkers" to one file and utils to one file 2) make utils const for more terseness -type IsAdminUser = Pick; +type IsAdminUser = Pick; export function isAdmin(user?: IsAdminUser) { return user?.id === ADMIN_ID; } @@ -44,7 +39,7 @@ function adminOverride(user?: IsAdminUser) { interface CanAddCommentToSuggestionArgs { user?: Pick; suggestions: PlusSuggestionRepository.FindAllByMonthItem[]; - suggested: Pick; + suggested: Pick; targetPlusTier: NonNullable; } export function canAddCommentToSuggestionFE( @@ -76,9 +71,9 @@ export function canAddCommentToSuggestionBE({ } interface CanDeleteCommentArgs { - suggestionId: PlusSuggestion["id"]; - author: Pick; - user?: Pick; + suggestionId: Tables["PlusSuggestion"]["id"]; + author: Pick; + user?: Pick; suggestions: PlusSuggestionRepository.FindAllByMonthItem[]; } export function canDeleteComment(args: CanDeleteCommentArgs) { @@ -234,7 +229,7 @@ export function canAccessLohiEndpoint(request: Request) { } interface CanEditBadgeOwnersArgs { - user?: Pick; + user?: Pick; managers: { id: number }[]; } @@ -255,8 +250,8 @@ export function canEditBadgeManagers(user?: IsAdminUser) { } interface CanEditCalendarEventArgs { - user?: Pick; - event: Pick; + user?: Pick; + event: Pick; } export function canEditCalendarEvent({ user, @@ -276,8 +271,8 @@ export function canDeleteCalendarEvent({ } interface CanReportCalendarEventWinnersArgs { - user?: Pick; - event: Pick; + user?: Pick; + event: Pick; startTimes: number[]; } export function canReportCalendarEventWinners({ @@ -316,7 +311,7 @@ export function canReportTournamentScore({ } export function canAddCustomizedColorsToUserProfile( - user?: Pick, + user?: Pick, ) { if (!user) return false; diff --git a/app/utils/strings.ts b/app/utils/strings.ts index 9bf2bc425..99737663d 100644 --- a/app/utils/strings.ts +++ b/app/utils/strings.ts @@ -1,4 +1,4 @@ -import type { GearType } from "~/db/types"; +import type { GearType } from "~/db/tables"; import { assertUnreachable } from "./types"; export function inGameNameWithoutDiscriminator(inGameName: string) { diff --git a/app/utils/urls.ts b/app/utils/urls.ts index 98f4f9434..5675503fc 100644 --- a/app/utils/urls.ts +++ b/app/utils/urls.ts @@ -1,15 +1,5 @@ import slugify from "slugify"; -import type { Preference } from "~/db/tables"; -import type { - Art, - Badge, - CalendarEvent, - GearType, - GroupMatch, - MapPoolMap, - User, - XRankPlacement, -} from "~/db/types"; +import type { GearType, Preference, Tables } from "~/db/tables"; import type { ArtSource } from "~/features/art/art-types"; import type { AuthErrorCode } from "~/features/auth/core/errors"; import { serializeBuild } from "~/features/build-analyzer"; @@ -154,8 +144,8 @@ export const NOTIFICATIONS_PEAK_ROUTE = "/notifications/peek"; export const NOTIFICATIONS_MARK_AS_SEEN_ROUTE = "/notifications/seen"; interface UserLinkArgs { - discordId: User["discordId"]; - customUrl?: User["customUrl"]; + discordId: Tables["User"]["discordId"]; + customUrl?: Tables["User"]["customUrl"]; } export const userPage = (user: UserLinkArgs) => @@ -188,7 +178,7 @@ export const userArtPage = ( bigArtId?: number, ) => `${userPage(user)}/art${source ? `?source=${source}` : ""}${bigArtId ? `?big=${bigArtId}` : ""}`; -export const newArtPage = (artId?: Art["id"]) => +export const newArtPage = (artId?: Tables["Art"]["id"]) => `${artPage()}/new${artId ? `?art=${artId}` : ""}`; export const userNewBuildPage = ( user: UserLinkArgs, @@ -222,7 +212,7 @@ export const topSearchPage = (args?: { month: number; year: number; mode: ModeShort; - region: XRankPlacement["region"]; + region: Tables["XRankPlacement"]["region"]; }) => args ? `/xsearch?month=${args.month}&year=${args.year}&mode=${args.mode}®ion=${args.region}` @@ -360,7 +350,7 @@ export const tournamentOrganizationEditPage = (organizationSlug: string) => export const sendouQInviteLink = (inviteCode: string) => `${SENDOUQ_PAGE}?${JOIN_CODE_SEARCH_PARAM_KEY}=${inviteCode}`; -export const sendouQMatchPage = (id: GroupMatch["id"]) => { +export const sendouQMatchPage = (id: Tables["GroupMatch"]["id"]) => { return `${SENDOUQ_PAGE}/match/${id}`; }; @@ -378,9 +368,9 @@ export const getWeaponUsage = ({ return `/weapon-usage?userId=${userId}&season=${season}&modeShort=${modeShort}&stageId=${stageId}`; }; -export const mapsPage = (eventId?: MapPoolMap["calendarEventId"]) => +export const mapsPage = (eventId?: Tables["MapPoolMap"]["calendarEventId"]) => `/maps${eventId ? `?eventId=${eventId}` : ""}`; -export const readonlyMapsPage = (eventId: CalendarEvent["id"]) => +export const readonlyMapsPage = (eventId: Tables["CalendarEvent"]["id"]) => `/maps?readonly&eventId=${eventId}`; export const articlePage = (slug: string) => `${ARTICLES_MAIN_PAGE}/${slug}`; export const analyzerPage = (args?: { @@ -417,7 +407,7 @@ export const badgeUrl = ({ code, extension, }: { - code: Badge["code"]; + code: Tables["Badge"]["code"]; extension?: "gif"; }) => `/static-assets/badges/${code}${extension ? `.${extension}` : ""}`; export const articlePreviewUrl = (slug: string) => diff --git a/app/utils/users.ts b/app/utils/users.ts index 0956118a9..79b96172c 100644 --- a/app/utils/users.ts +++ b/app/utils/users.ts @@ -1,9 +1,9 @@ -import type { User } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { isAdmin } from "~/permissions"; import { isCustomUrl } from "./urls"; export function isAtLeastFiveDollarTierPatreon( - user?: Pick, + user?: Pick, ) { if (!user) return false; diff --git a/scripts/placements/index.ts b/scripts/placements/index.ts index 654d8972a..b7ae0c4d0 100644 --- a/scripts/placements/index.ts +++ b/scripts/placements/index.ts @@ -1,7 +1,7 @@ import "dotenv/config"; import { sql } from "~/db/sql"; -import type { XRankPlacement } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { syncXPBadges } from "~/features/badges/queries/syncXPBadges.server"; import { type MainWeaponId, mainWeaponIds } from "~/modules/in-game-lists"; import invariant from "~/utils/invariant"; @@ -17,7 +17,7 @@ invariant( ); type Placements = Array< - Omit & { playerSplId: string } + Omit & { playerSplId: string } >; const modes = ["splatzones", "towercontrol", "rainmaker", "clamblitz"] as const; diff --git a/scripts/season-initial-powers.ts b/scripts/season-initial-powers.ts index bed05175c..e1851a4f7 100644 --- a/scripts/season-initial-powers.ts +++ b/scripts/season-initial-powers.ts @@ -1,7 +1,7 @@ import "dotenv/config"; import { ordinal } from "openskill"; import { db, sql } from "~/db/sql"; -import type { Skill } from "~/db/types"; +import type { Tables } from "~/db/tables"; import { TIERS, type TierName } from "~/features/mmr/mmr-constants"; import { freshUserSkills } from "~/features/mmr/tiered.server"; import { addInitialSkill } from "~/features/sendouq/queries/addInitialSkill.server"; @@ -151,13 +151,13 @@ const midPoints = Object.entries(groupedSkills).reduce( const midPointSkill = skillStm.get({ userId: midPoint.userId, ordinal: midPoint.ordinal, - }) as Skill; + }) as Tables["Skill"]; invariant(midPointSkill, "midPointSkill not found"); acc[tier as TierName] = midPointSkill; return acc; }, - {} as Record, + {} as Record, ); const newSkills = allSkills.map((s) => {