From 3e1ffe8e47953c84c23dd3d7c358c9dfbf55400a Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Sun, 1 Nov 2026 13:57:10 +0200 Subject: [PATCH] Report exports only used in their own file --- app/components/ObjectiveTimeline.tsx | 2 +- app/components/SortableTableHeader.tsx | 2 +- app/components/elements/Toast.tsx | 2 +- app/components/elements/useEntitySearch.ts | 6 +- app/components/layout/WeaponSearch.tsx | 2 +- app/components/match-page/MatchTimeline.tsx | 4 +- app/db/tables.ts | 278 +++++++++--------- app/features/build-analyzer/analyzer-types.ts | 2 +- app/features/chat/core/Attention.ts | 1 + app/features/chat/core/Stickers.ts | 1 + app/features/dev-tools/core/ConsoleCapture.ts | 2 +- app/features/dev-tools/core/EventsRecorder.ts | 2 +- .../dev-tools/core/RequestLog.server.ts | 2 +- app/features/lobbies/core/TeamShuffle.ts | 2 +- app/features/lobbies/core/WeaponRoll.ts | 2 +- .../scanner/components/CoachControls.tsx | 2 +- .../scanner/components/live-session.ts | 6 +- app/features/scanner/components/montage.ts | 6 +- app/features/scanner/components/settings.ts | 2 +- app/features/scanner/components/vod-scan.ts | 8 +- app/features/scanner/core/CoachEvents.ts | 2 +- .../scanner/core/detectors/check-plan.ts | 2 +- .../scanner/core/detectors/objective/index.ts | 7 +- .../core/detectors/objective/strip-weapons.ts | 2 +- .../scanner/core/detectors/x-rank/position.ts | 2 +- .../core/detectors/x-rank/set-result.ts | 2 +- app/features/scanner/core/montage.ts | 2 +- app/features/scanner/core/scanner-match.ts | 1 + app/features/scanner/node/game-data-zip.ts | 2 +- app/features/scanner/store/clips.ts | 4 +- .../scanner/tests/node-test-compat.ts | 2 +- app/features/scanner/worker/client.ts | 2 +- app/features/scanner/worker/cubic-upscaler.ts | 2 +- app/features/scanner/worker/gpu-matcher.ts | 2 +- app/features/scanner/worker/protocol.ts | 2 +- app/features/scrims/scrims-types.ts | 2 +- .../components/RematchVotePanel.tsx | 2 +- app/features/sidebar/core/sidebar.server.ts | 2 +- .../splatoon-rotations-constants.ts | 2 +- .../tournament-bracket/core/PickBan.ts | 2 + .../tournament-bracket/core/Progression.ts | 2 +- app/features/tournament/core/tiering.ts | 1 + app/features/vods/vods-types.ts | 2 +- app/features/voice/voice-activity.ts | 4 +- app/features/voice/voice-client.ts | 4 +- app/form/SendouForm.tsx | 4 +- app/form/types.ts | 4 +- app/modules/permissions/types.ts | 2 +- knip.ts | 4 - 49 files changed, 205 insertions(+), 202 deletions(-) diff --git a/app/components/ObjectiveTimeline.tsx b/app/components/ObjectiveTimeline.tsx index 310235dd5..01f420a58 100644 --- a/app/components/ObjectiveTimeline.tsx +++ b/app/components/ObjectiveTimeline.tsx @@ -38,7 +38,7 @@ const TOOLTIP_FLIP_RATIO = 0.55; const SIDES = [0, 1] as const; /** One objective-counter read, values in `[alpha, bravo]` order. */ -export interface ObjectiveTimelineSample { +interface ObjectiveTimelineSample { /** seconds shown on the match timer at the read ("3:35" = 215); null = unreadable */ time: number | null; /** displayed count per team; null = unreadable */ diff --git a/app/components/SortableTableHeader.tsx b/app/components/SortableTableHeader.tsx index d2dc5f016..76a2e33e9 100644 --- a/app/components/SortableTableHeader.tsx +++ b/app/components/SortableTableHeader.tsx @@ -2,7 +2,7 @@ import clsx from "clsx"; import { ArrowDown, ArrowUp, ChevronsUpDown } from "lucide-react"; import styles from "./SortableTableHeader.module.css"; -export type SortDirection = "asc" | "desc"; +type SortDirection = "asc" | "desc"; export type SortState = { key: Key; diff --git a/app/components/elements/Toast.tsx b/app/components/elements/Toast.tsx index 67f20b999..986575df9 100644 --- a/app/components/elements/Toast.tsx +++ b/app/components/elements/Toast.tsx @@ -7,7 +7,7 @@ import { Flipper } from "../Flipper"; import { SendouButton } from "./Button"; import styles from "./Toast.module.css"; -export interface SendouToast { +interface SendouToast { message: string; variant: "error" | "success" | "info"; } diff --git a/app/components/elements/useEntitySearch.ts b/app/components/elements/useEntitySearch.ts index 69b25a414..c0e8214c6 100644 --- a/app/components/elements/useEntitySearch.ts +++ b/app/components/elements/useEntitySearch.ts @@ -4,11 +4,9 @@ import { SEARCH_DEBOUNCE_MS } from "~/features/search/search-constants"; import { useDebounce } from "~/hooks/useDebounce"; /** Sentinel items rendered in place of real results while loading or when empty. */ -export type EntitySearchPlaceholder = - | { id: "PLACEHOLDER" } - | { id: "NO_RESULTS" }; +type EntitySearchPlaceholder = { id: "PLACEHOLDER" } | { id: "NO_RESULTS" }; -export type EntitySearchItem = TItem | EntitySearchPlaceholder; +type EntitySearchItem = TItem | EntitySearchPlaceholder; interface UseEntitySearchArgs { /** Builds the loader URL queried (debounced) as the user types. */ diff --git a/app/components/layout/WeaponSearch.tsx b/app/components/layout/WeaponSearch.tsx index 702df677b..b44b78fc5 100644 --- a/app/components/layout/WeaponSearch.tsx +++ b/app/components/layout/WeaponSearch.tsx @@ -50,7 +50,7 @@ const WEAPON_DESTINATIONS = [ "art", "lfg", ] as const; -export type WeaponDestination = (typeof WEAPON_DESTINATIONS)[number]; +type WeaponDestination = (typeof WEAPON_DESTINATIONS)[number]; export interface SelectedWeapon { id: MainWeaponId; diff --git a/app/components/match-page/MatchTimeline.tsx b/app/components/match-page/MatchTimeline.tsx index da061b83e..e101dfb28 100644 --- a/app/components/match-page/MatchTimeline.tsx +++ b/app/components/match-page/MatchTimeline.tsx @@ -52,12 +52,12 @@ const ABILITY_NAMES: ReadonlySet = new Set( type MatchSide = "ALPHA" | "BRAVO"; -export interface TimelineTeam { +interface TimelineTeam { name: string; avatar?: string; } -export interface TimelineScoreboardPlayer { +interface TimelineScoreboardPlayer { name: string; weaponSplId: MainWeaponId | null; ka: number | null; diff --git a/app/db/tables.ts b/app/db/tables.ts index 2469ed883..25288ffd1 100644 --- a/app/db/tables.ts +++ b/app/db/tables.ts @@ -103,7 +103,7 @@ type Generated = export type DBBoolean = 0 | 1; /** Shape shared by the `AllTeam` table and the `Team` view. See {@link DB} for which to select from. */ -export interface Team { +interface Team { avatarImgId: number | null; bannerImgId: number | null; bio: string | null; @@ -125,7 +125,7 @@ export interface Team { * Shape shared by the `AllTeamMember` table and the `TeamMember` & * `TeamMemberWithSecondary` views. See {@link DB} for which to select from. */ -export interface TeamMember { +interface TeamMember { createdAt: Generated; isOwner: Generated; isManager: Generated; @@ -142,7 +142,7 @@ export interface TeamMember { isMainTeam: Generated; } -export interface Art { +interface Art { authorId: number; createdAt: Generated; description: string | null; @@ -151,24 +151,24 @@ export interface Art { isShowcase: Generated; } -export interface ArtTag { +interface ArtTag { authorId: number; createdAt: Generated; id: GeneratedAlways; name: string; } -export interface ArtUserMetadata { +interface ArtUserMetadata { artId: number; userId: number; } -export interface TaggedArt { +interface TaggedArt { artId: number; tagId: number; } -export interface Badge { +interface Badge { id: GeneratedAlways; code: string; displayName: string; @@ -177,19 +177,19 @@ export interface Badge { authorId: number | null; } -export interface BadgeManager { +interface BadgeManager { badgeId: number; userId: number; } /** Read-only. See {@link DB} for how this view is composed. */ -export interface BadgeOwner { +interface BadgeOwner { badgeId: number; userId: number; count: number; } -export interface Trophy { +interface Trophy { id: GeneratedAlways; name: string; model: string; @@ -200,20 +200,20 @@ export interface Trophy { managerId: number | null; } -export interface TrophyOwner { +interface TrophyOwner { trophyId: number; userId: number; tournamentId: number; tier: number | null; } -export interface SpecialTrophyOwner { +interface SpecialTrophyOwner { trophyId: number; userId: number; createdAt: number; } -export interface PendingTrophy { +interface PendingTrophy { id: GeneratedAlways; name: string; model: string; @@ -230,14 +230,14 @@ export interface PendingTrophy { creatorId: number | null; } -export interface PendingTrophyApproval { +interface PendingTrophyApproval { pendingTrophyId: number; userId: number; createdAt: number; } /** Abilities are stored as JSON in `abilities`, `BuildAbilitySum` & `BuildWeaponAbility` denormalize them for computing ability point averages. */ -export interface Build { +interface Build { clothesGearSplId: number | null; description: string | null; headGearSplId: number | null; @@ -268,21 +268,21 @@ export interface BuildWeapon { } /** Per-build ability point sums across all gear slots. Used to compute global `findAllAbilityPointAverages`. */ -export interface BuildAbilitySum { +interface BuildAbilitySum { buildId: number; ability: Ability; abilityPoints: number; } /** Per-weapon, per-build ability point sums. Used to compute per-weapon `findAllAbilityPointAverages`. One row per canonical weapon × build × ability with non-zero AP. */ -export interface BuildWeaponAbility { +interface BuildWeaponAbility { canonicalWeaponSplId: MainWeaponId; buildId: number; ability: Ability; abilityPoints: number; } -export interface CalendarEvent { +interface CalendarEvent { authorId: number; bracketUrl: string; description: string | null; @@ -299,33 +299,33 @@ export interface CalendarEvent { trophyId: number | null; } -export interface CalendarEventBadge { +interface CalendarEventBadge { badgeId: number; eventId: number; } /** A regular calendar event can have many dates, a tournament only one. */ -export interface CalendarEventDate { +interface CalendarEventDate { eventId: number; id: GeneratedAlways; startsAt: number; } -export interface CalendarEventResultPlayer { +interface CalendarEventResultPlayer { name: string | null; teamId: number; userId: number | null; } /** Results of events not hosted on sendou.ink. */ -export interface CalendarEventResultTeam { +interface CalendarEventResultTeam { eventId: number; id: GeneratedAlways; name: string; placement: number; } -export interface ChatRoom { +interface ChatRoom { /** Set by a routine ~a month after `expiresAt`; messages are kept but access narrows to staff and tournament organizers. */ closedAt: number | null; createdAt: Generated; @@ -336,7 +336,7 @@ export interface ChatRoom { type: ChatRoomType; } -export interface ChatMessage { +interface ChatMessage { /** The sender, or for a system message the actor it describes. `null` only when that account has since been deleted. */ authorUserId: number | null; /** `null` for system messages, whose text is rendered client-side from {@link ChatMessage.type}. */ @@ -350,7 +350,7 @@ export interface ChatMessage { type: PersistedSystemMessageType | null; } -export interface ChatMessageReadIndicator { +interface ChatMessageReadIndicator { /** Id of the newest message the user has seen in the room; upserts keep the MAX. */ lastSeenMessageId: number; roomId: number; @@ -358,7 +358,7 @@ export interface ChatMessageReadIndicator { } /** SendouQ group. A new group is created every time even if the same players rejoin the queue after their match. */ -export interface Group { +interface Group { chatRoomId: number | null; createdAt: Generated; id: GeneratedAlways; @@ -379,7 +379,7 @@ export interface Group { tierIsPlus: Generated; } -export interface GroupLike { +interface GroupLike { createdAt: Generated; likerGroupId: number; targetGroupId: number; @@ -389,7 +389,7 @@ export interface GroupLike { createdByUserId: number | null; } -export interface GroupMatch { +interface GroupMatch { alphaGroupId: number; bravoGroupId: number; chatRoomId: number | null; @@ -403,7 +403,7 @@ export interface GroupMatch { } /** One team's account of why a SendouQ match was canceled. Staff-only information. */ -export interface GroupMatchCancelReport { +interface GroupMatchCancelReport { id: GeneratedAlways; groupMatchId: number; groupId: number; @@ -413,12 +413,12 @@ export interface GroupMatchCancelReport { } /** Player nominated as a cause of the cancellation in a {@link GroupMatchCancelReport}. */ -export interface GroupMatchCancelReportPlayer { +interface GroupMatchCancelReportPlayer { cancelReportId: number; userId: number; } -export interface GroupMatchContinueVote { +interface GroupMatchContinueVote { id: GeneratedAlways; groupId: number; userId: number; @@ -426,7 +426,7 @@ export interface GroupMatchContinueVote { votedAt: Generated; } -export interface GroupMatchMap { +interface GroupMatchMap { id: GeneratedAlways; index: number; matchId: number; @@ -438,7 +438,7 @@ export interface GroupMatchMap { winnerGroupId: number | null; } -export interface GroupMember { +interface GroupMember { /** Member who quick added this one as their friend, `null` if they joined on their own. */ addedByUserId: number | null; createdAt: Generated; @@ -458,7 +458,7 @@ export interface GroupMember { } /** Both groups' members confirming they are ready to play, before their match is created */ -export interface GroupReadyCheck { +interface GroupReadyCheck { alphaGroupId: number; bravoGroupId: number; createdAt: Generated; @@ -466,14 +466,14 @@ export interface GroupReadyCheck { } /** One member confirming they are ready to play in a {@link GroupReadyCheck} */ -export interface GroupReadyCheckConfirmation { +interface GroupReadyCheckConfirmation { createdAt: Generated; readyCheckId: number; userId: number; } /** A group member pointing their own group at another group, without inviting it */ -export interface GroupSuggestion { +interface GroupSuggestion { createdAt: Generated; /** Group whose members see the suggestion */ suggesterGroupId: number; @@ -481,7 +481,7 @@ export interface GroupSuggestion { createdByUserId: number; } -export interface PrivateUserNote { +interface PrivateUserNote { authorId: number; targetId: number; text: string | null; @@ -490,7 +490,7 @@ export interface PrivateUserNote { } /** History of user written public texts, kept for moderators to review */ -export interface ModAuditLog { +interface ModAuditLog { id: GeneratedAlways; type: "SENDOUQ_PUBLIC_NOTE"; /** Author of the text */ @@ -500,13 +500,13 @@ export interface ModAuditLog { } /** Log-in links generated via the Lohi Discord bot commands. */ -export interface LogInLink { +interface LogInLink { code: string; expiresAt: number; userId: number; } -export interface LFGPost { +interface LFGPost { id: GeneratedAlways; type: LFGType; text: string; @@ -526,7 +526,7 @@ export interface LFGPost { * - a tournament's map pool, organizer picked or the custom pool of a team picked tournament (`calendarEventId`) * - a tournament team's map picks in a team picked tournament (`tournamentTeamId`), the modes and counts live in `Tournament.settings.teamPick` */ -export interface MapPoolMap { +interface MapPoolMap { calendarEventId: number | null; mode: ModeShort; stageId: StageId; @@ -534,7 +534,7 @@ export interface MapPoolMap { } /** Denormalized win/loss counts per user, map and season so they are efficient to fetch. */ -export interface MapResult { +interface MapResult { losses: number; mode: ModeShort; season: number; @@ -544,7 +544,7 @@ export interface MapResult { } /** Denormalized head-to-head results between two users per season so they are efficient to fetch. */ -export interface PlayerResult { +interface PlayerResult { mapLosses: number; mapWins: number; otherUserId: number; @@ -557,7 +557,7 @@ export interface PlayerResult { } /** Comments to a suggestion are also stored as suggestions, same as the suggestion itself. */ -export interface PlusSuggestion { +interface PlusSuggestion { authorId: number; createdAt: Generated; id: GeneratedAlways; @@ -570,12 +570,12 @@ export interface PlusSuggestion { } /** Result of the latest voting (`PlusVoting.computeFreshPlusTiers`) with players from the leaderboard added, materialized for performance. */ -export interface PlusTier { +interface PlusTier { tier: number; userId: number; } -export interface PlusVote { +interface PlusVote { authorId: number; month: number; score: number; @@ -587,7 +587,7 @@ export interface PlusVote { } /** Read-only. See {@link DB} for how this view is composed. */ -export interface PlusVotingResult { +interface PlusVotingResult { votedId: number; tier: number; score: number; @@ -597,7 +597,7 @@ export interface PlusVotingResult { } /** Exactly one of `groupMatchId`, `tournamentMatchId` and `lobbySetId` is set. */ -export interface ReportedWeapon { +interface ReportedWeapon { groupMatchId: number | null; tournamentMatchId: number | null; lobbySetId: number | null; @@ -609,7 +609,7 @@ export interface ReportedWeapon { ingestedMatchId: number | null; } -export interface IngestedMatch { +interface IngestedMatch { id: GeneratedAlways; povUserId: number | null; submitterUserId: number | null; @@ -627,7 +627,7 @@ export interface IngestedMatch { } /** Links an ingested match to the game result it describes (exactly one target). */ -export interface IngestedMatchLink { +interface IngestedMatchLink { id: GeneratedAlways; ingestedMatchId: number; tournamentMatchGameResultId: number | null; @@ -636,7 +636,7 @@ export interface IngestedMatchLink { createdAt: Generated; } -export interface Skill { +interface Skill { groupMatchId: number | null; id: GeneratedAlways; /** Set for team ratings, `null` for the solo ratings identified by `userId` instead. */ @@ -652,13 +652,13 @@ export interface Skill { createdAt: number | null; } -export interface SkillTeamUser { +interface SkillTeamUser { skillId: number; userId: number; } /** A team that is shown on the team leaderboard but doesn't count for its placements, e.g. because its players want to qualify with another roster. */ -export interface LeaderboardTeamSkip { +interface LeaderboardTeamSkip { id: GeneratedAlways; season: number; /** The team's roster, same as `Skill.identifier`. */ @@ -668,7 +668,7 @@ export interface LeaderboardTeamSkip { } /** Used for tournament auto-seeding. Calculates off tournament matches same as SP but does not have seasonal resets. */ -export interface SeedingSkill { +interface SeedingSkill { mu: number; ordinal: number; sigma: number; @@ -676,7 +676,7 @@ export interface SeedingSkill { type: "RANKED" | "UNRANKED"; } -export interface SplatoonPlayer { +interface SplatoonPlayer { id: GeneratedAlways; splId: string; userId: number | null; @@ -685,7 +685,7 @@ export interface SplatoonPlayer { } /** The bracket tables (`TournamentStage`, `TournamentGroup`, `TournamentRound`, `TournamentMatch`) mimic the [brackets-manager.js schema](https://github.com/Drarig29/brackets-manager.js/issues/111#issuecomment-997417423). */ -export interface Tournament { +interface Tournament { settings: JSONColumnType; id: GeneratedAlways; mapPickingStyle: TournamentMapPickingStyle; @@ -705,7 +705,7 @@ export interface Tournament { vodsSyncCount: Generated; } -export interface SavedCalendarEvent { +interface SavedCalendarEvent { id: GeneratedAlways; userId: number; calendarEventId: number; @@ -717,7 +717,7 @@ export interface SavedCalendarEvent { * checked in to it. Tournaments where every team plays the same bracket have one row (bracket idx 0) * matching `Tournament.tier`, tournaments with many starting brackets one row per division. */ -export interface TournamentDivisionTier { +interface TournamentDivisionTier { tournamentId: number; /** Idx of the starting bracket in `Tournament.settings.bracketProgression`. */ bracketIdx: number; @@ -725,7 +725,7 @@ export interface TournamentDivisionTier { tier: TournamentTierNumber; } -export interface TournamentBadgeOwner { +interface TournamentBadgeOwner { badgeId: number; userId: number; /** Which tournament the badge is from, if null was added manually by a badge manager as opposed to once a tournament was finalized. */ @@ -739,13 +739,13 @@ export interface TournamentBadgeOwner { * or an elimination bracket whose rounds {@link TournamentRound.section} splits into winners, losers * and finals. Every elimination stage has one group for now. */ -export interface TournamentGroup { +interface TournamentGroup { id: GeneratedAlways; number: number; stageId: number; } -export interface TournamentMatch { +interface TournamentMatch { chatRoomId: number | null; groupId: number; id: GeneratedAlways; @@ -765,7 +765,7 @@ export interface TournamentMatch { } /** Leagues: a candidate time one team put on the set's scheduling board. Only exists while open, accepting or rejecting deletes the match's proposals. */ -export interface TournamentMatchScheduleProposal { +interface TournamentMatchScheduleProposal { id: GeneratedAlways; matchId: number; tournamentTeamId: number; @@ -776,7 +776,7 @@ export interface TournamentMatchScheduleProposal { } /** Represents one decision, pick or ban, during tournaments pick/ban (counterpick, ban 2) phase. */ -export interface TournamentMatchPickBanEvent { +interface TournamentMatchPickBanEvent { type: "PICK" | "BAN" | "ROLL" | "MODE_PICK" | "MODE_BAN"; stageId: StageId | null; mode: ModeShort | null; @@ -786,7 +786,7 @@ export interface TournamentMatchPickBanEvent { createdAt: Generated; } -export interface TournamentMatchGameResult { +interface TournamentMatchGameResult { createdAt: Generated; id: GeneratedAlways; /** Whether the game ended in a knockout. `null` if not collected for this bracket. */ @@ -800,13 +800,13 @@ export interface TournamentMatchGameResult { winnerTeamId: number; } -export interface TournamentMatchGameResultParticipant { +interface TournamentMatchGameResultParticipant { matchGameResultId: number; userId: number; tournamentTeamId: number; } -export interface TournamentResult { +interface TournamentResult { isHighlight: Generated; participantCount: number; placement: number; @@ -820,7 +820,7 @@ export interface TournamentResult { } /** Groups matches played at the same time (round-robin, swiss) or one round of a bracket (elimination). */ -export interface TournamentRound { +interface TournamentRound { groupId: number; id: GeneratedAlways; /** Restarts from 1 per group, and in an elimination group per {@link TournamentRound.section}. */ @@ -834,7 +834,7 @@ export interface TournamentRound { } /** A stage is an intermediate phase in a tournament. In essence a bracket. */ -export interface TournamentStage { +interface TournamentStage { id: GeneratedAlways; name: string; number: number; @@ -844,19 +844,19 @@ export interface TournamentStage { createdAt: Generated; } -export interface TournamentLFGLike { +interface TournamentLFGLike { likerTeamId: number; targetTeamId: number; createdAt: Generated; } -export interface TournamentStaff { +interface TournamentStaff { tournamentId: number; userId: number; role: TournamentStaffRole; } -export interface TournamentTeam { +interface TournamentTeam { createdAt: Generated; id: GeneratedAlways; inviteCode: string; @@ -890,7 +890,7 @@ export interface TournamentTeam { tournamentTeamHistoryId: number | null; } -export interface TournamentTeamCheckIn { +interface TournamentTeamCheckIn { checkedInAt: number; /** Which bracket checked in for. If missing is check in for the whole event. */ bracketIdx: number | null; @@ -899,7 +899,7 @@ export interface TournamentTeamCheckIn { isCheckOut: Generated; } -export interface TournamentTeamMember { +interface TournamentTeamMember { createdAt: Generated; inGameName: string | null; tournamentTeamId: number; @@ -915,7 +915,7 @@ export interface TournamentTeamMember { } /** Stable shadow of a tournament team's identity that survives the team's hard-deletion, so the audit log can still resolve its name. */ -export interface TournamentTeamHistory { +interface TournamentTeamHistory { /** Surrogate key. Audit log rows reference this so a reused `TournamentTeam.id` can never collide with an older team's history. */ id: GeneratedAlways; /** Mirrors the original `TournamentTeam.id` at creation time. Informational only; not a live or unique foreign key, so it is not cascade-deleted with the team and may repeat across teams that reused an id. */ @@ -924,7 +924,7 @@ export interface TournamentTeamHistory { name: string; } -export interface TournamentAuditLog { +interface TournamentAuditLog { id: GeneratedAlways; tournamentId: number; type: TournamentAuditLogType; @@ -937,7 +937,7 @@ export interface TournamentAuditLog { createdAt: Generated; } -export interface TournamentOrganization { +interface TournamentOrganization { id: GeneratedAlways; name: string; slug: string; @@ -947,19 +947,19 @@ export interface TournamentOrganization { isEstablished: Generated; } -export interface TournamentOrganizationMember { +interface TournamentOrganizationMember { organizationId: number; userId: number; role: TournamentOrganizationRole; roleDisplayName: string | null; } -export interface TournamentOrganizationBadge { +interface TournamentOrganizationBadge { organizationId: number; badgeId: number; } -export interface TournamentOrganizationSeries { +interface TournamentOrganizationSeries { id: GeneratedAlways; organizationId: number; name: string; @@ -969,14 +969,14 @@ export interface TournamentOrganizationSeries { tierHistory: JSONColumnTypeNullable; } -export interface TournamentBracketProgressionOverride { +interface TournamentBracketProgressionOverride { sourceBracketIdx: number; destinationBracketIdx: number; tournamentTeamId: number; tournamentId: number; } -export interface TournamentOrganizationBannedUser { +interface TournamentOrganizationBannedUser { organizationId: number; userId: number; privateNote: string | null; @@ -985,14 +985,14 @@ export interface TournamentOrganizationBannedUser { } /** Indicates a user trusts another. Allows direct adding to groups/teams without invite links. */ -export interface TrustRelationship { +interface TrustRelationship { trustGiverUserId: number; trustReceiverUserId: number; lastUsedAt: number; } /** Mutual friendship between two users. Invariant: userOneId < userTwoId. */ -export interface Friendship { +interface Friendship { id: GeneratedAlways; userOneId: number; userTwoId: number; @@ -1004,14 +1004,14 @@ export interface Friendship { } /** Pending friend request from one user to another. */ -export interface FriendRequest { +interface FriendRequest { id: GeneratedAlways; senderId: number; receiverId: number; createdAt: Generated; } -export interface UnvalidatedUserSubmittedImage { +interface UnvalidatedUserSubmittedImage { id: GeneratedAlways; submitterUserId: number; url: string; @@ -1019,7 +1019,7 @@ export interface UnvalidatedUserSubmittedImage { validatedAt: number | null; } -export interface UnvalidatedVideo { +interface UnvalidatedVideo { eventId: number | null; id: GeneratedAlways; submitterUserId: number; @@ -1031,7 +1031,7 @@ export interface UnvalidatedVideo { youtubeId: string; } -export interface User { +interface User { /** 1 = permabanned, timestamp = ban active till then */ banned: Generated; bannedReason: string | null; @@ -1100,13 +1100,13 @@ export interface User { xpDivision: XRankPlacementRegion | null; } -export interface UserResultHighlight { +interface UserResultHighlight { teamId: number; userId: number; } /** Read-only. See {@link DB} for how this view relates to `UnvalidatedUserSubmittedImage`. */ -export interface UserSubmittedImage { +interface UserSubmittedImage { id: GeneratedAlways; submitterUserId: number | null; url: string; @@ -1117,7 +1117,7 @@ export interface UserSubmittedImage { /** FTS5 trigram index over User's searchable columns (external content table, * kept in sync with triggers). Only meant for reading: filter with * `match` and join `rowid` to `User.id`. */ -export interface UserSearch { +interface UserSearch { rowid: GeneratedAlways; username: GeneratedAlways; inGameName: GeneratedAlways; @@ -1125,31 +1125,31 @@ export interface UserSearch { customUrl: GeneratedAlways; } -export interface UserWeaponPool { +interface UserWeaponPool { userId: number; sortOrder: number; weaponSplId: MainWeaponId; isFavorite: Generated; } -export interface TenStarWeapon { +interface TenStarWeapon { userId: number; weaponSplId: MainWeaponId; } -export interface UserFriendCode { +interface UserFriendCode { friendCode: string; userId: number; submitterUserId: number; createdAt: Generated; } -export interface UserWidget { +interface UserWidget { userId: number; index: number; widget: JSONColumnType; } -export interface ApiToken { +interface ApiToken { id: GeneratedAlways; userId: number; token: string; @@ -1158,7 +1158,7 @@ export interface ApiToken { } /** Splatoon 3 stream live right now, replaced wholesale on every sync. */ -export interface LiveStream { +interface LiveStream { id: GeneratedAlways; platform: StreamPlatform; /** Twitch login or YouTube channel id */ @@ -1172,7 +1172,7 @@ export interface LiveStream { } /** Account seen streaming the tournament while it was running, used to find match VoDs afterwards. */ -export interface TournamentStreamer { +interface TournamentStreamer { id: GeneratedAlways; /** Null for cast accounts not linked to a sendou.ink user. */ userId: number | null; @@ -1181,7 +1181,7 @@ export interface TournamentStreamer { account: string; } -export interface ExternalStream { +interface ExternalStream { id: GeneratedAlways; name: string; url: string; @@ -1191,7 +1191,7 @@ export interface ExternalStream { } /** Past broadcast VoD of a tournament match with the offset to jump to the match. */ -export interface TournamentMatchVod { +interface TournamentMatchVod { id: GeneratedAlways; matchId: number; userId: number | null; @@ -1202,7 +1202,7 @@ export interface TournamentMatchVod { viewCount: number; } -export interface BanLog { +interface BanLog { id: GeneratedAlways; userId: number; banned: number | null; @@ -1211,7 +1211,7 @@ export interface BanLog { createdAt: Generated; } -export interface ModNote { +interface ModNote { id: GeneratedAlways; userId: number; authorId: number; @@ -1220,7 +1220,7 @@ export interface ModNote { isDeleted: Generated; } -export interface UserReport { +interface UserReport { id: GeneratedAlways; reportedUserId: number; reporterUserId: number; @@ -1231,7 +1231,7 @@ export interface UserReport { } /** Read-only. See {@link DB} for how this view relates to `UnvalidatedVideo`. */ -export interface Video { +interface Video { eventId: number | null; id: GeneratedAlways; submitterUserId: number; @@ -1244,7 +1244,7 @@ export interface Video { youtubeId: string; } -export interface VideoMatch { +interface VideoMatch { id: GeneratedAlways; mode: ModeShort; stageId: StageId; @@ -1252,7 +1252,7 @@ export interface VideoMatch { videoId: number; } -export interface VideoMatchPlayer { +interface VideoMatchPlayer { player: number; playerName: string | null; playerUserId: number | null; @@ -1262,7 +1262,7 @@ export interface VideoMatchPlayer { export type UserVoiceChat = "YES" | "NO" | "LISTEN_ONLY"; -export interface VoiceSession { +interface VoiceSession { id: GeneratedAlways; /** `null` once the chat room has been deleted. The session stays for the statistics. */ roomId: number | null; @@ -1287,7 +1287,7 @@ export interface VoiceSession { inputMode: VoiceInputMode | null; } -export interface VoiceClientError { +interface VoiceClientError { id: GeneratedAlways; voiceSessionId: number | null; userId: number; @@ -1297,7 +1297,7 @@ export interface VoiceClientError { createdAt: Generated; } -export interface VoiceFeedback { +interface VoiceFeedback { id: GeneratedAlways; voiceSessionId: number; userId: number; @@ -1307,7 +1307,7 @@ export interface VoiceFeedback { createdAt: Generated; } -export interface VoiceSettings { +interface VoiceSettings { id: GeneratedAlways; /** Manual kill switch. */ isDisabled: Generated; @@ -1319,7 +1319,7 @@ export interface VoiceSettings { updatedByUserId: number | null; } -export interface XRankPlacement { +interface XRankPlacement { badges: string; bannerSplId: number; id: GeneratedAlways; @@ -1336,7 +1336,7 @@ export interface XRankPlacement { year: number; } -export interface ScrimPost { +interface ScrimPost { id: GeneratedAlways; startsAt: number; /** Optional end of time range indicating team accepts scrims starting between startsAt and rangeEndsAt */ @@ -1363,7 +1363,7 @@ export interface ScrimPost { updatedAt: Generated; } -export interface ScrimMapList { +interface ScrimMapList { id: GeneratedAlways; scrimPostId: number; side: "ALPHA" | "BRAVO"; @@ -1373,7 +1373,7 @@ export interface ScrimMapList { updatedAt: number; } -export interface ScrimMap { +interface ScrimMap { id: GeneratedAlways; scrimPostId: number; index: number; @@ -1384,26 +1384,26 @@ export interface ScrimMap { reportedByUserId: number | null; } -export interface ScrimPostUser { +interface ScrimPostUser { scrimPostId: number; userId: number; isOwner: DBBoolean; } -export interface ScrimPickupRoster { +interface ScrimPickupRoster { id: GeneratedAlways; userId: number; /** When the roster was last used to make a scrim post */ usedAt: Generated; } -export interface ScrimPickupRosterUser { +interface ScrimPickupRosterUser { scrimPickupRosterId: number; /** Member of the pick-up roster, excluding the roster's owner */ userId: number; } -export interface ScrimPostRequest { +interface ScrimPostRequest { id: GeneratedAlways; scrimPostId: number; teamId: number | null; @@ -1414,13 +1414,13 @@ export interface ScrimPostRequest { createdAt: Generated; } -export interface ScrimPostRequestUser { +interface ScrimPostRequestUser { scrimPostRequestId: number; userId: number; isOwner: DBBoolean; } -export interface Lobby { +interface Lobby { id: GeneratedAlways; /** Plays like everyone else and is the lobby's sole admin. Passed on to the longest-tenured participant when they leave. */ hostUserId: number; @@ -1446,7 +1446,7 @@ export interface Lobby { createdAt: Generated; } -export interface LobbyParticipant { +interface LobbyParticipant { id: GeneratedAlways; lobbyId: number; userId: number; @@ -1460,14 +1460,14 @@ export interface LobbyParticipant { } /** Kicked out of the lobby by the host, can't sign up for it again. */ -export interface LobbyKickedUser { +interface LobbyKickedUser { lobbyId: number; userId: number; createdAt: Generated; } /** One best-of, teams shuffled from the participants in the room. */ -export interface LobbySet { +interface LobbySet { id: GeneratedAlways; lobbyId: number; bestOf: LobbyBestOf; @@ -1487,7 +1487,7 @@ export interface LobbySet { createdAt: Generated; } -export interface LobbySetParticipant { +interface LobbySetParticipant { setId: number; userId: number; /** `null` = sat the set out */ @@ -1495,7 +1495,7 @@ export interface LobbySetParticipant { } /** A map of a set, generated with the set and reported as it is played */ -export interface LobbyGame { +interface LobbyGame { id: GeneratedAlways; setId: number; index: number; @@ -1507,7 +1507,7 @@ export interface LobbyGame { } /** Asking the waitlist to confirm they are present, to fill vacant slots of the room. */ -export interface LobbyReadyCheck { +interface LobbyReadyCheck { id: GeneratedAlways; lobbyId: number; /** End of the waitlist's priority, after it slots are first come, first served */ @@ -1515,14 +1515,14 @@ export interface LobbyReadyCheck { createdAt: Generated; } -export interface LobbyReadyCheckUser { +interface LobbyReadyCheckUser { readyCheckId: number; userId: number; confirmedAt: number | null; } /** A player's place on the lobby's leaderboard, saved when the lobby ends. Only those who played a finished set. */ -export interface LobbyResult { +interface LobbyResult { lobbyId: number; userId: number; /** Players with the same record share the placement */ @@ -1533,7 +1533,7 @@ export interface LobbyResult { * One audience step of a scrim post's or a lobby's visibility schedule (exactly one of the entity columns is set). * The entity is visible to a viewer when a row with `visibleFrom` in the past matches them. */ -export interface ContentVisibility { +interface ContentVisibility { id: GeneratedAlways; scrimPostId: number | null; lobbyId: number | null; @@ -1547,21 +1547,21 @@ export interface ContentVisibility { isPublic: Generated; } -export interface Association { +interface Association { id: GeneratedAlways; name: string; inviteCode: string; createdAt: Generated; } -export interface AssociationMember { +interface AssociationMember { userId: number; associationId: number; /** MANAGER can also share the invite link, ADMIN (one per association) can also manage the members */ role: "MEMBER" | "MANAGER" | "ADMIN"; } -export interface Notification { +interface Notification { id: GeneratedAlways; type: NotificationValue["type"]; meta: JSONColumnTypeNullable>; @@ -1569,20 +1569,20 @@ export interface Notification { createdAt: Generated; } -export interface NotificationUser { +interface NotificationUser { notificationId: number; userId: number; seen: Generated; } /** A subscription of user's browser indicating where push notifications can be sent to. */ -export interface NotificationUserSubscription { +interface NotificationUserSubscription { id: GeneratedAlways; userId: number; subscription: JSONColumnType; } -export interface SplatoonRotation { +interface SplatoonRotation { id: GeneratedAlways; type: SplatoonRotationType; mode: RankedModeShort; @@ -1593,7 +1593,7 @@ export interface SplatoonRotation { } /** One week of availability a user reported. The row existing means the week was submitted, which is what tells "unavailable all week" (submitted, no slots) apart from "unknown" (no row). */ -export interface AvailabilityWeek { +interface AvailabilityWeek { id: GeneratedAlways; userId: number; /** Monday 00:00 of the week, in `timezone` */ @@ -1605,14 +1605,14 @@ export interface AvailabilityWeek { } /** A range the user is available for. Absolute, so a range crossing midnight is one row like any other. */ -export interface AvailabilitySlot { +interface AvailabilitySlot { id: GeneratedAlways; availabilityWeekId: number; startsAt: number; endsAt: number; } -export interface AvailabilityDayNote { +interface AvailabilityDayNote { availabilityWeekId: number; /** YYYY-MM-DD, in the week's `timezone` */ date: string; @@ -1620,7 +1620,7 @@ export interface AvailabilityDayNote { } /** Something the team does together that is not a tournament or a scrim, e.g. a VoD review. Blocks the members' availability. */ -export interface TeamEvent { +interface TeamEvent { id: GeneratedAlways; teamId: number; /** User who created the event. Null if their account has since been deleted. */ @@ -1632,7 +1632,7 @@ export interface TeamEvent { } /** Participant of a team event limited to selected members. No rows for an event = the whole team takes part. */ -export interface TeamEventMember { +interface TeamEventMember { teamEventId: number; userId: number; } diff --git a/app/features/build-analyzer/analyzer-types.ts b/app/features/build-analyzer/analyzer-types.ts index aa9ba7b7d..4b65e7491 100644 --- a/app/features/build-analyzer/analyzer-types.ts +++ b/app/features/build-analyzer/analyzer-types.ts @@ -125,7 +125,7 @@ export interface BaseWeaponStats extends RangeParams { /** A way of shooting a main weapon with its own flight, e.g. a roller's vertical or horizontal swing */ export type RangeVariantKey = (typeof RANGE_VARIANT_KEYS)[number]; -export interface RangeVariantParams extends RangeParams { +interface RangeVariantParams extends RangeParams { Range_VariantKey: RangeVariantKey; } diff --git a/app/features/chat/core/Attention.ts b/app/features/chat/core/Attention.ts index 4f8938991..a9a51b4c7 100644 --- a/app/features/chat/core/Attention.ts +++ b/app/features/chat/core/Attention.ts @@ -26,6 +26,7 @@ interface AttentionEnvironment { export type Tracker = ReturnType; // Whether the user is paying attention to this tab. It has to be visible, window focused, and be interacted with in the last 3 minutes +/** @internal */ export function createTracker( getEnvironment: () => AttentionEnvironment, { idleAfterMs = IDLE_AFTER_MS }: { idleAfterMs?: number } = {}, diff --git a/app/features/chat/core/Stickers.ts b/app/features/chat/core/Stickers.ts index 3d0f0be56..b4c8ba3c9 100644 --- a/app/features/chat/core/Stickers.ts +++ b/app/features/chat/core/Stickers.ts @@ -1,3 +1,4 @@ +/** @internal */ export const CHAT_STICKERS = [ { id: "booyah", name: "Booyah" }, { id: "despair", name: "Despair" }, diff --git a/app/features/dev-tools/core/ConsoleCapture.ts b/app/features/dev-tools/core/ConsoleCapture.ts index 978202dee..38ec006e4 100644 --- a/app/features/dev-tools/core/ConsoleCapture.ts +++ b/app/features/dev-tools/core/ConsoleCapture.ts @@ -8,7 +8,7 @@ export type CapturedSource = | "uncaught error" | "unhandled rejection"; -export interface CapturedEntry { +interface CapturedEntry { id: number; level: CapturedLevel; source: CapturedSource; diff --git a/app/features/dev-tools/core/EventsRecorder.ts b/app/features/dev-tools/core/EventsRecorder.ts index a413c2639..4e08b14d6 100644 --- a/app/features/dev-tools/core/EventsRecorder.ts +++ b/app/features/dev-tools/core/EventsRecorder.ts @@ -6,7 +6,7 @@ import type { ServerEvent } from "~/features/events/events-types"; const MAX_ENTRIES = 300; -export type RecordedEvent = +type RecordedEvent = | { id: number; at: number; type: "event"; event: ServerEvent } | { id: number; at: number; type: "connection"; state: EventsReadyState }; diff --git a/app/features/dev-tools/core/RequestLog.server.ts b/app/features/dev-tools/core/RequestLog.server.ts index a07f44bb2..56beea9ea 100644 --- a/app/features/dev-tools/core/RequestLog.server.ts +++ b/app/features/dev-tools/core/RequestLog.server.ts @@ -10,7 +10,7 @@ const UNTRACKED_PATH_PREFIXES = ["/dev/", "/sse"]; export type RequestKind = "document" | "data" | "action" | "resource"; -export interface LoggedQuery { +interface LoggedQuery { sql: string; parameters: unknown[]; durationMs: number; diff --git a/app/features/lobbies/core/TeamShuffle.ts b/app/features/lobbies/core/TeamShuffle.ts index 028bf1cae..1211dfe65 100644 --- a/app/features/lobbies/core/TeamShuffle.ts +++ b/app/features/lobbies/core/TeamShuffle.ts @@ -84,7 +84,7 @@ export interface TeammateHistory { } /** A candidate split of the players into two teams, scored by {@link splitCost}. */ -export interface Split { +interface Split { alpha: ShufflePlayer[]; bravo: ShufflePlayer[]; } diff --git a/app/features/lobbies/core/WeaponRoll.ts b/app/features/lobbies/core/WeaponRoll.ts index 49aa618d2..41d5fb786 100644 --- a/app/features/lobbies/core/WeaponRoll.ts +++ b/app/features/lobbies/core/WeaponRoll.ts @@ -162,7 +162,7 @@ export const ROLLABLE_WEAPON_IDS = mainWeaponIds.filter( (weaponId) => weaponIdToType(weaponId) !== "ALT_SKIN", ); -export interface WeaponRollCost { +interface WeaponRollCost { strength: number; shape: number; shapeMismatch: number; diff --git a/app/features/scanner/components/CoachControls.tsx b/app/features/scanner/components/CoachControls.tsx index 1d36291ba..8129d9d49 100644 --- a/app/features/scanner/components/CoachControls.tsx +++ b/app/features/scanner/components/CoachControls.tsx @@ -27,7 +27,7 @@ import { SendouMenu, SendouMenuItem } from "~/components/elements/Menu"; import * as CoachPlayback from "../core/CoachPlayback"; import styles from "./CoachControls.module.css"; -export type CoachStep = "GAME" | "LIFE" | "EVENT" | "SECONDS"; +type CoachStep = "GAME" | "LIFE" | "EVENT" | "SECONDS"; interface StepControl { label: string; diff --git a/app/features/scanner/components/live-session.ts b/app/features/scanner/components/live-session.ts index b7ee2df8a..60194f19d 100644 --- a/app/features/scanner/components/live-session.ts +++ b/app/features/scanner/components/live-session.ts @@ -103,11 +103,11 @@ const NO_SOURCE_ERROR = const MISSING_ATLASES_ERROR = "Some of the scanner's game data could not be downloaded — check the connection and start the capture again"; -export type LiveStatus = "idle" | "starting" | "running" | "error"; +type LiveStatus = "idle" | "starting" | "running" | "error"; /** `unsupported`: no WebCodecs/track processor; `failed`: the encoder refused this stream */ -export type ClipsState = "on" | "off" | "unsupported" | "failed"; +type ClipsState = "on" | "off" | "unsupported" | "failed"; /** `muted`: the browser gets nothing from the device; `silent`: it gets samples, all of them silence; `ended`: the track stopped (a share ended, say); `failed`: the encoder gave up */ -export type AudioSignal = "ok" | "silent" | "muted" | "ended" | "failed"; +type AudioSignal = "ok" | "silent" | "muted" | "ended" | "failed"; export interface LiveSnapshot { status: LiveStatus; diff --git a/app/features/scanner/components/montage.ts b/app/features/scanner/components/montage.ts index 4c02b9384..2c5c46f6b 100644 --- a/app/features/scanner/components/montage.ts +++ b/app/features/scanner/components/montage.ts @@ -60,7 +60,7 @@ import { describeError } from "./errors"; import { scannedTeamComps } from "./montage-comps"; import { cancelVodScan, startVodScan } from "./vod-scan"; -export interface MontageFolder { +interface MontageFolder { manifest: MontageManifest; /** the manifest's VoDs found in the folder */ vods: MontageManifestVod[]; @@ -69,7 +69,7 @@ export interface MontageFolder { directory: FileSystemDirectoryHandle | null; } -export type MontageScan = +type MontageScan = | { state: "scanning"; file: string; index: number; total: number } | { state: "done"; failed: string[] }; @@ -93,7 +93,7 @@ type GraphicCapture = (graphic: MontageGraphic) => Promise<{ revealRects: CardRevealRect[]; }>; -export type MontageRender = +type MontageRender = | ({ state: "rendering" } & MontageRenderProgress) | { state: "done"; error: string | null }; diff --git a/app/features/scanner/components/settings.ts b/app/features/scanner/components/settings.ts index 300c6b5cf..f222f8e77 100644 --- a/app/features/scanner/components/settings.ts +++ b/app/features/scanner/components/settings.ts @@ -26,7 +26,7 @@ export interface ScannerSettings { } export const CLIP_MIN_KILLS_OPTIONS = [3, 4, 5] as const; -export type ClipMinKills = (typeof CLIP_MIN_KILLS_OPTIONS)[number]; +type ClipMinKills = (typeof CLIP_MIN_KILLS_OPTIONS)[number]; /** * `source`: the video input's own audio side; `desktop`: the system's sound diff --git a/app/features/scanner/components/vod-scan.ts b/app/features/scanner/components/vod-scan.ts index 4b380b95e..d94d0937b 100644 --- a/app/features/scanner/components/vod-scan.ts +++ b/app/features/scanner/components/vod-scan.ts @@ -73,13 +73,13 @@ const UI_UPDATE_INTERVAL_MS = 250; */ const EVENTS_PUBLISH_INTERVAL_MS = 1000; -export type VodScanStatus = "idle" | "scanning" | "done" | "error"; +type VodScanStatus = "idle" | "scanning" | "done" | "error"; -export type ClipsWork = +type ClipsWork = | { state: "cutting"; done: number; total: number } | { state: "done"; saved: number; error: string | null }; -export type VodScanMode = "active" | "skim"; +type VodScanMode = "active" | "skim"; /** One worker's slice of the file. */ export interface VodScanLane { @@ -93,7 +93,7 @@ export interface VodScanLane { failed: boolean; } -export interface VodScanProgress { +interface VodScanProgress { t: number; duration: number; /** scan speed as a multiple of realtime */ diff --git a/app/features/scanner/core/CoachEvents.ts b/app/features/scanner/core/CoachEvents.ts index 4eb490506..90a469b24 100644 --- a/app/features/scanner/core/CoachEvents.ts +++ b/app/features/scanner/core/CoachEvents.ts @@ -483,7 +483,7 @@ export interface CoachLife { summary: CoachLifeSummary | null; } -export interface CoachLifeSummary { +interface CoachLifeSummary { /** seconds alive, the first life counted from the game clock's start when read */ duration: number; /** the POV player's splats in the life (a trade on the death's second included); null without a kill feed read */ diff --git a/app/features/scanner/core/detectors/check-plan.ts b/app/features/scanner/core/detectors/check-plan.ts index 79b7b6507..f2f182edc 100644 --- a/app/features/scanner/core/detectors/check-plan.ts +++ b/app/features/scanner/core/detectors/check-plan.ts @@ -13,7 +13,7 @@ const INTERVAL_EPSILON_S = 1e-6; /** Stepped samples remembered, so a plan made behind the decoder can be replayed up to it. */ const HISTORY_LIMIT = 512; -export interface DetectorCheckPlan { +interface DetectorCheckPlan { lastCheckT: number; /** intervals the detector's next check may come after */ next: readonly number[]; diff --git a/app/features/scanner/core/detectors/objective/index.ts b/app/features/scanner/core/detectors/objective/index.ts index 826e72619..d86ae7ef2 100644 --- a/app/features/scanner/core/detectors/objective/index.ts +++ b/app/features/scanner/core/detectors/objective/index.ts @@ -70,7 +70,7 @@ import { readTrackSteps, trackComb } from "./track"; export type ObjectiveData = ZonesObjectiveData | TrackObjectiveData; /** Splat Zones / Clam Blitz plates. */ -export interface ZonesObjectiveData { +interface ZonesObjectiveData { /** names the plates overlay: CB draws it too, so the match's mode tells the two apart */ mode: "SZ"; /** match timer seconds ("3:35" = 215); null = unreadable. Overtime display unattested so far. */ @@ -92,7 +92,10 @@ export interface ZonesObjectiveData { teamColor: [InkRgb | null, InkRgb | null]; } -/** Tower Control / Rainmaker: one overlay, told apart only by its checkpoint markers. */ +/** + * Tower Control / Rainmaker: one overlay, told apart only by its checkpoint markers. + * @internal + */ export interface TrackObjectiveData { /** off the checkpoint markers; null when none read (the match's mode decides) */ mode: "TC" | "RM" | null; diff --git a/app/features/scanner/core/detectors/objective/strip-weapons.ts b/app/features/scanner/core/detectors/objective/strip-weapons.ts index 14dad54f5..3d3f0e04d 100644 --- a/app/features/scanner/core/detectors/objective/strip-weapons.ts +++ b/app/features/scanner/core/detectors/objective/strip-weapons.ts @@ -29,7 +29,7 @@ import { export const STRIP_WEAPONS_EVENT_TYPE = "StripWeapons"; -export interface StripWeaponCandidate { +interface StripWeaponCandidate { weaponId: MainWeaponId; score: number; } diff --git a/app/features/scanner/core/detectors/x-rank/position.ts b/app/features/scanner/core/detectors/x-rank/position.ts index 8616206fe..1ef46beac 100644 --- a/app/features/scanner/core/detectors/x-rank/position.ts +++ b/app/features/scanner/core/detectors/x-rank/position.ts @@ -37,7 +37,7 @@ import { export const X_RANK_POSITION_EVENT_TYPE = "XRankPosition"; -export type XRankPositionDirection = "UP" | "DOWN" | "SAME"; +type XRankPositionDirection = "UP" | "DOWN" | "SAME"; export interface XRankPositionData { mode: RankedModeShort | null; diff --git a/app/features/scanner/core/detectors/x-rank/set-result.ts b/app/features/scanner/core/detectors/x-rank/set-result.ts index 884a048ab..c498b5a19 100644 --- a/app/features/scanner/core/detectors/x-rank/set-result.ts +++ b/app/features/scanner/core/detectors/x-rank/set-result.ts @@ -48,7 +48,7 @@ import { export const X_SET_RESULT_EVENT_TYPE = "XSetResult"; -export type XSetGameResult = "WIN" | "LOSE"; +type XSetGameResult = "WIN" | "LOSE"; export interface XSetResultData { mode: RankedModeShort | null; diff --git a/app/features/scanner/core/montage.ts b/app/features/scanner/core/montage.ts index d13fc8558..e2723eaf8 100644 --- a/app/features/scanner/core/montage.ts +++ b/app/features/scanner/core/montage.ts @@ -57,7 +57,7 @@ export type MontageManifestTopTeam = MontageManifestTeam & { placement: number; }; -export interface MontageManifestTeam { +interface MontageManifestTeam { id: number; name: string; logo: string | null; diff --git a/app/features/scanner/core/scanner-match.ts b/app/features/scanner/core/scanner-match.ts index 249b3a6d3..337f7f0ef 100644 --- a/app/features/scanner/core/scanner-match.ts +++ b/app/features/scanner/core/scanner-match.ts @@ -76,6 +76,7 @@ export interface ScannerMatchObjective { samples: ScannerMatchObjectiveSample[]; } +/** @internal */ export type ScannerMatchPlayerFlags = [boolean, boolean, boolean, boolean]; export interface ScannerMatchPlayerStatusSample { diff --git a/app/features/scanner/node/game-data-zip.ts b/app/features/scanner/node/game-data-zip.ts index 5d022474a..9e17b543c 100644 --- a/app/features/scanner/node/game-data-zip.ts +++ b/app/features/scanner/node/game-data-zip.ts @@ -80,7 +80,7 @@ const UNIX_FILE_TYPE_MASK = 0o170000; const UNIX_REGULAR_FILE = 0o100000; /** One analyzed frame of the game, as unpacked. */ -export interface GameDataFrame { +interface GameDataFrame { /** folder relative to the output directory, e.g. `frames/012-Death-1m42s` */ folder: string; eventType: (typeof EVENT_TYPES)[number]; diff --git a/app/features/scanner/store/clips.ts b/app/features/scanner/store/clips.ts index 7c9f5ab1d..443fd9f71 100644 --- a/app/features/scanner/store/clips.ts +++ b/app/features/scanner/store/clips.ts @@ -23,9 +23,9 @@ const STORAGE_RESERVE_BYTES = 250_000_000; /** clips saved before their size was kept were all encoded at 16 Mbps */ const LEGACY_BYTES_PER_SECOND = 2_000_000; -export type ClipBucket = "session" | "history" | "vod"; +type ClipBucket = "session" | "history" | "vod"; -export type ClipSource = +type ClipSource = | { kind: "live"; sessionKey: number } /** `visit`: the page load that cut it (see visit.ts) */ | { kind: "vod"; name: string; visit: string }; diff --git a/app/features/scanner/tests/node-test-compat.ts b/app/features/scanner/tests/node-test-compat.ts index 5fe0b81ec..f5359980a 100644 --- a/app/features/scanner/tests/node-test-compat.ts +++ b/app/features/scanner/tests/node-test-compat.ts @@ -10,7 +10,7 @@ import { test as vitestTest } from "vitest"; type SubtestBody = () => void | Promise; -export interface SubtestOptions { +interface SubtestOptions { skip?: boolean | string; expectFailure?: string; } diff --git a/app/features/scanner/worker/client.ts b/app/features/scanner/worker/client.ts index 3953a0fcf..9715dd9c1 100644 --- a/app/features/scanner/worker/client.ts +++ b/app/features/scanner/worker/client.ts @@ -23,7 +23,7 @@ export interface DoneInfo { telemetry: ScanTelemetry | null; } export type DoneHandler = (t: number, info: DoneInfo) => void; -export type ChunkProgress = Extract; +type ChunkProgress = Extract; export type ChunkProgressHandler = (progress: ChunkProgress) => void; /** Each chunk worker decodes and analyzes on its own; leave a core for the main thread and one for the media stack. */ diff --git a/app/features/scanner/worker/cubic-upscaler.ts b/app/features/scanner/worker/cubic-upscaler.ts index 0efac4ff1..46d09e982 100644 --- a/app/features/scanner/worker/cubic-upscaler.ts +++ b/app/features/scanner/worker/cubic-upscaler.ts @@ -56,7 +56,7 @@ fn main(@builtin(global_invocation_id) gid: vec3, @builtin(num_workgroups) `; /** The part of a source picture to upscale: `box` of an RGBA buffer `stride` pixels wide. */ -export interface UpscaleSource { +interface UpscaleSource { buffer: GPUBuffer; stride: number; box: { x: number; y: number; w: number; h: number }; diff --git a/app/features/scanner/worker/gpu-matcher.ts b/app/features/scanner/worker/gpu-matcher.ts index e214609e4..fdddbf2c7 100644 --- a/app/features/scanner/worker/gpu-matcher.ts +++ b/app/features/scanner/worker/gpu-matcher.ts @@ -326,7 +326,7 @@ function resolveJob(job: Job, score: number) { job.cache?.set(job.cacheKey, score); } -export interface GpuMatcherStats { +interface GpuMatcherStats { steps: number; dispatches: number; jobs: number; diff --git a/app/features/scanner/worker/protocol.ts b/app/features/scanner/worker/protocol.ts index 56d8829cf..b0b8693b8 100644 --- a/app/features/scanner/worker/protocol.ts +++ b/app/features/scanner/worker/protocol.ts @@ -43,7 +43,7 @@ export interface ScanChunkRequest { tEnd: number; } -export interface AbortChunkRequest { +interface AbortChunkRequest { kind: "abortChunk"; } diff --git a/app/features/scrims/scrims-types.ts b/app/features/scrims/scrims-types.ts index d1127966b..2d62788a2 100644 --- a/app/features/scrims/scrims-types.ts +++ b/app/features/scrims/scrims-types.ts @@ -68,7 +68,7 @@ interface ScrimPostTeam { avatarUrl: string | null; } -export interface TimeRange { +interface TimeRange { start: string; end: string; } diff --git a/app/features/sendouq-match/components/RematchVotePanel.tsx b/app/features/sendouq-match/components/RematchVotePanel.tsx index 953ec9816..7402cac26 100644 --- a/app/features/sendouq-match/components/RematchVotePanel.tsx +++ b/app/features/sendouq-match/components/RematchVotePanel.tsx @@ -11,7 +11,7 @@ import * as RejoinVote from "../core/RejoinVote"; import { matchSchema } from "../q-match-schemas"; import styles from "./RematchVotePanel.module.css"; -export type RematchVoteMember = { +type RematchVoteMember = { id: number; username: string; avatar: string | null; diff --git a/app/features/sidebar/core/sidebar.server.ts b/app/features/sidebar/core/sidebar.server.ts index 61a96e751..e31c6c3f6 100644 --- a/app/features/sidebar/core/sidebar.server.ts +++ b/app/features/sidebar/core/sidebar.server.ts @@ -72,7 +72,7 @@ export type SidebarEvent = { scrimStatus?: "booked" | "looking" | "requestPending"; }; -export type SidebarFriend = { +type SidebarFriend = { id: number; name: string; avatar: CommonUser["avatar"]; diff --git a/app/features/splatoon-rotations/splatoon-rotations-constants.ts b/app/features/splatoon-rotations/splatoon-rotations-constants.ts index a22c1cd03..eeda7ae35 100644 --- a/app/features/splatoon-rotations/splatoon-rotations-constants.ts +++ b/app/features/splatoon-rotations/splatoon-rotations-constants.ts @@ -1,3 +1,3 @@ -export const SPLATOON_ROTATION_TYPES = ["SERIES", "OPEN", "X"] as const; +const SPLATOON_ROTATION_TYPES = ["SERIES", "OPEN", "X"] as const; export type SplatoonRotationType = (typeof SPLATOON_ROTATION_TYPES)[number]; diff --git a/app/features/tournament-bracket/core/PickBan.ts b/app/features/tournament-bracket/core/PickBan.ts index c02377225..65e9f1c3a 100644 --- a/app/features/tournament-bracket/core/PickBan.ts +++ b/app/features/tournament-bracket/core/PickBan.ts @@ -516,6 +516,7 @@ export function isStageLegal({ return pool.some((m) => m.stageId === stageId && m.isLegal); } +/** @internal */ export interface PickBanEvent { type: string; stageId: StageId | null; @@ -769,6 +770,7 @@ const MAP_PICK_ACTIONS: ReadonlySet = new Set([ "PICK_NO_MODE_REPEAT", ]); +/** @internal */ export const CUSTOM_FLOW_VALIDATION_ERRORS = { STEP_MISSING_ACTION: "STEP_MISSING_ACTION", STEP_MISSING_WHO: "STEP_MISSING_WHO", diff --git a/app/features/tournament-bracket/core/Progression.ts b/app/features/tournament-bracket/core/Progression.ts index 68e519dcc..9ac3b0167 100644 --- a/app/features/tournament-bracket/core/Progression.ts +++ b/app/features/tournament-bracket/core/Progression.ts @@ -17,7 +17,7 @@ export interface DBSource { rest?: boolean; } -export interface EditableSource { +interface EditableSource { /** Frontend-only id while editing, replaced by an index once set. See DBSource.bracketIdx. */ bracketId: string; /** User editable, "1-3" and "1,2,3" mean the same. See DBSource.placements for the validated version. */ diff --git a/app/features/tournament/core/tiering.ts b/app/features/tournament/core/tiering.ts index 516c46750..06b5a9cda 100644 --- a/app/features/tournament/core/tiering.ts +++ b/app/features/tournament/core/tiering.ts @@ -22,6 +22,7 @@ const SIZE_BONUS = { MAX_BONUS_PER_10_TEAMS: 1.5, } as const; +/** @internal */ export const TIER_TO_NUMBER = { X: 1, "S+": 2, diff --git a/app/features/vods/vods-types.ts b/app/features/vods/vods-types.ts index ae664b3e7..604af23db 100644 --- a/app/features/vods/vods-types.ts +++ b/app/features/vods/vods-types.ts @@ -17,7 +17,7 @@ export interface Vod { submitterUserId: Tables["Video"]["submitterUserId"]; } -export type VodMatch = Pick< +type VodMatch = Pick< Tables["VideoMatch"], "id" | "mode" | "stageId" | "startsAt" > & { diff --git a/app/features/voice/voice-activity.ts b/app/features/voice/voice-activity.ts index 51a1cba92..c5ec224f7 100644 --- a/app/features/voice/voice-activity.ts +++ b/app/features/voice/voice-activity.ts @@ -20,7 +20,7 @@ import { import type { VoiceClientErrorKind, VoiceInputMode } from "./voice-constants"; import { useVoiceRooms, useVoiceSnapshot } from "./voice-hooks"; -export type VoiceActivityStatus = "AVAILABLE" | VoiceCallStatus; +type VoiceActivityStatus = "AVAILABLE" | VoiceCallStatus; export interface VoiceActivityParticipant { key: string; @@ -49,7 +49,7 @@ export interface VoiceActivityState { latencyMs: number | null; } -export interface VoiceActivityActions { +interface VoiceActivityActions { join: () => void; leave: () => void; setMicEnabled: (enabled: boolean) => void; diff --git a/app/features/voice/voice-client.ts b/app/features/voice/voice-client.ts index 08605b9c0..d3baca2d5 100644 --- a/app/features/voice/voice-client.ts +++ b/app/features/voice/voice-client.ts @@ -81,14 +81,14 @@ export interface VoiceSnapshot { inputMode: VoiceInputMode; } -export interface VoiceCallHandle { +interface VoiceCallHandle { setLocalAudio: (enabled: boolean) => void; ensureMic: (options: { mayAsk: boolean }) => Promise; leave: () => Promise; resumeAudio: () => void; } -export interface VoiceTelemetrySummary { +interface VoiceTelemetrySummary { lowQualitySeconds: number; talkSeconds: number; } diff --git a/app/form/SendouForm.tsx b/app/form/SendouForm.tsx index 16fbb200d..1e98c4e4e 100644 --- a/app/form/SendouForm.tsx +++ b/app/form/SendouForm.tsx @@ -104,7 +104,7 @@ export interface FormRenderProps { FormField: TypedFormFieldComponent; } -export type FormMode = "submit" | "autoSubmit" | "client"; +type FormMode = "submit" | "autoSubmit" | "client"; type BaseFormProps = { children: React.ReactNode | ((props: FormRenderProps) => React.ReactNode); @@ -159,7 +159,7 @@ type FormModeProps = saveAttempted?: boolean; }; -export type FormDefaultValues = Partial< +type FormDefaultValues = Partial< v.InferInput> >; diff --git a/app/form/types.ts b/app/form/types.ts index 90db8b472..fa14a888e 100644 --- a/app/form/types.ts +++ b/app/form/types.ts @@ -300,7 +300,7 @@ type FormFieldChildrenProps = { disabled?: boolean; }; -export type TypedFormFieldProps< +type TypedFormFieldProps< TSchema extends v.ObjectEntries, TName extends keyof TSchema & string, > = { @@ -324,7 +324,7 @@ export type TypedFormFieldProps< type NestedPath = `${string}.${string}` | `${string}[${string}`; /** FormField props with a free-form name, for nested paths like `${itemName}.field` */ -export type FlexibleFormFieldProps = { +type FlexibleFormFieldProps = { name: NestedPath; label?: string; disabled?: boolean; diff --git a/app/modules/permissions/types.ts b/app/modules/permissions/types.ts index 1a516ba0b..33782155a 100644 --- a/app/modules/permissions/types.ts +++ b/app/modules/permissions/types.ts @@ -1,4 +1,4 @@ -export type Permissions = Record; +type Permissions = Record; export type EntityWithPermissions = { permissions: Permissions; diff --git a/knip.ts b/knip.ts index ddbac3a13..28bce8b5d 100644 --- a/knip.ts +++ b/knip.ts @@ -1,8 +1,4 @@ const config = { - ignoreExportsUsedInFile: { - interface: true, - type: true, - }, tags: ["-lintignore"], ignoreBinaries: ["ffmpeg", "ffprobe", "yt-dlp"], astro: {