From f4db781f9d28f1be1152433106c6f832ab038378 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Fri, 6 Jan 2023 20:45:32 +0000 Subject: [PATCH] checkpoint: 15 --- .eslintrc | 10 ++++++- .../components/util/query/fetchUGPTData.ts | 6 ++-- common/src/index.ts | 3 ++ common/src/types/game-config-utils.ts | 2 -- server/src/external/mongo/db.ts | 28 +++++++++++++------ server/src/lib/jobs/backsync-bms-pms-data.ts | 4 +-- server/src/lib/orphan-queue/orphan-queue.ts | 8 +++--- .../common/batch-manual/converter.ts | 10 +++---- .../lib/score-mutation/update-isprimary.ts | 2 +- server/src/lib/search/search.ts | 4 +-- server/src/lib/showcase/get-related.ts | 4 +-- server/src/lib/targets/goal-utils.ts | 6 ++-- .../src/server/router/api/v1/admin/router.ts | 2 +- .../_playtype/charts/_chartID/middleware.ts | 2 +- .../_game/_playtype/charts/_chartID/router.ts | 2 +- .../v1/games/_game/_playtype/charts/router.ts | 4 +-- .../api/v1/games/_game/_playtype/router.ts | 2 +- .../_playtype/songs/_songID/middleware.ts | 2 +- .../_game/_playtype/songs/_songID/router.ts | 2 +- .../games/_game/_playtype/pbs/router.ts | 10 +++---- .../games/_game/_playtype/rivals/router.ts | 2 +- .../_userID/games/_game/_playtype/router.ts | 4 +-- .../games/_game/_playtype/scores/router.ts | 2 +- .../_game/_playtype/settings/router.test.ts | 2 +- .../games/_game/_playtype/settings/router.ts | 4 +-- .../games/_game/_playtype/showcase/router.ts | 4 +-- .../games/_game/_playtype/targets/router.ts | 2 +- .../src/server/router/ir/usc/_playtype/usc.ts | 2 +- server/src/test-utils/misc.ts | 4 +-- server/src/test-utils/test-data.ts | 4 +-- server/src/utils/db.ts | 10 +++---- server/src/utils/misc.ts | 4 ++- server/src/utils/queries/charts.ts | 16 +++++------ server/src/utils/queries/songs.ts | 6 ++-- 34 files changed, 100 insertions(+), 79 deletions(-) diff --git a/.eslintrc b/.eslintrc index e0e129a53..98363f8e7 100644 --- a/.eslintrc +++ b/.eslintrc @@ -14,7 +14,15 @@ ], "rules": { // broken - "lines-around-comment": "off" + "lines-around-comment": "off", + + // TENPORARILY OFF AS THEY'RE BROKEN. + "@typescript-eslint/no-unsafe-assignment": "off", + "@typescript-eslint/no-unsafe-return": "off", + "@typescript-eslint/no-unsafe-argument": "off", + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/no-unsafe-property-computation": "off", + "@typescript-eslint/no-unsafe-call": "off" } }, { diff --git a/client/src/components/util/query/fetchUGPTData.ts b/client/src/components/util/query/fetchUGPTData.ts index b208da275..9d9124e86 100644 --- a/client/src/components/util/query/fetchUGPTData.ts +++ b/client/src/components/util/query/fetchUGPTData.ts @@ -4,7 +4,7 @@ import { Game, Playtype, UserDocument, - UGPTSettings, + UGPTSettingsDocument, UserGameStats, } from "tachi-common"; import { UGPTStatsReturn } from "types/api-returns"; @@ -15,7 +15,7 @@ import { UGPTStatsReturn } from "types/api-returns"; * It's worth keeping this around for both the currently-viewed user and the currently-logged-in user. */ export interface UGPTData { - settings: UGPTSettings; + settings: UGPTSettingsDocument; stats: UserGameStats; game: Game; playtype: Playtype; @@ -48,7 +48,7 @@ export default async function fetchUGPTData( ); } - const settingsRes = await APIFetchV1( + const settingsRes = await APIFetchV1( `/users/${userID}/games/${game}/${playtype}/settings` ); diff --git a/common/src/index.ts b/common/src/index.ts index 0da8c0853..a78661801 100644 --- a/common/src/index.ts +++ b/common/src/index.ts @@ -2,6 +2,9 @@ export * from "./types"; export * from "./config/config"; export * as StaticConfig from "./constants/import-types"; + +export type { GamePTConfig } from "./types/internals"; + export * from "./utils/util"; export * from "./webhooks"; export * from "./constants/game"; diff --git a/common/src/types/game-config-utils.ts b/common/src/types/game-config-utils.ts index 794b2a0d2..eccc900f5 100644 --- a/common/src/types/game-config-utils.ts +++ b/common/src/types/game-config-utils.ts @@ -1,8 +1,6 @@ // Types related to game configuration. These are used by our `internal` game config // types -import type { integer } from "../types"; - export interface RatingAlgorithmConfig { /** * Write a short descrption for this rating algorithm. diff --git a/server/src/external/mongo/db.ts b/server/src/external/mongo/db.ts index c7938f4f4..0eaa00c28 100644 --- a/server/src/external/mongo/db.ts +++ b/server/src/external/mongo/db.ts @@ -6,7 +6,7 @@ import { ONE_MINUTE } from "lib/constants/time"; import CreateLogCtx from "lib/logger/logger"; import { Environment, ServerConfig } from "lib/setup/config"; import monk from "monk"; -import { allSupportedGames } from "tachi-common/config/static-config"; +import { allSupportedGames } from "tachi-common"; import { GetMillisecondsSince } from "utils/misc"; import type { OrphanScoreDocument } from "lib/score-import/import-types/common/types"; import type { TMiddleware, ICollection } from "monk"; @@ -31,7 +31,7 @@ import type { QuestlineDocument, QuestSubscriptionDocument, NotificationDocument, - OrphanChart, + OrphanChartDocument, PBScoreDocument, UserDocument, RecentlyViewedFolderDocument, @@ -40,13 +40,14 @@ import type { SongDocument, TableDocument, TachiAPIClientDocument, - UGPTSettings, + UGPTSettingsDocument, UserGameStats, UserGameStatsSnapshotDocument, - UserSettings, + UserSettingsDocument, KsHookSettingsDocument, ImportTrackerDocument as ImportTrackerDocument, CGCardInfo, + GPTStrings, } from "tachi-common"; import type { MigrationDocument, PrivateUserInfoDocument } from "utils/types"; @@ -125,17 +126,26 @@ export async function CloseMongoConnection() { // Force cast it out. const songs = Object.fromEntries( allSupportedGames.map((e) => [e, monkDB.get(`songs-${e}`)]) -) as unknown as Record>; +) as unknown as { + [G in Game]: ICollection>; +}; const charts = Object.fromEntries( allSupportedGames.map((e) => [e, monkDB.get(`charts-${e}`)]) -) as unknown as Record>; +) as unknown as { + [G in Game]: ICollection>; +}; const db = { // i have to handwrite this out for TS... :( // dont worry, it was all macro'd. songs, charts, + + // intended for when you want to query arbitrary chart/song documents. + anyCharts: charts as Record>, + anySongs: songs as Record>, + scores: monkDB.get("scores"), "personal-bests": monkDB.get("personal-bests"), folders: monkDB.get("folders"), @@ -160,9 +170,9 @@ const db = { "import-locks": monkDB.get<{ userID: integer; locked: boolean }>("import-locks"), tables: monkDB.get("tables"), "invite-locks": monkDB.get<{ userID: integer; locked: boolean }>("invite-locks"), - "game-settings": monkDB.get("game-settings"), + "game-settings": monkDB.get("game-settings"), "game-stats-snapshots": monkDB.get("game-stats-snapshots"), - "user-settings": monkDB.get("user-settings"), + "user-settings": monkDB.get("user-settings"), "user-private-information": monkDB.get("user-private-information"), "api-clients": monkDB.get("api-clients"), @@ -173,7 +183,7 @@ const db = { "fer-settings": monkDB.get("fer-settings"), "kshook-sv6c-settings": monkDB.get("kshook-sv6c-settings"), - "orphan-chart-queue": monkDB.get("orphan-chart-queue"), + "orphan-chart-queue": monkDB.get("orphan-chart-queue"), "password-reset-codes": monkDB.get<{ code: string; userID: integer; diff --git a/server/src/lib/jobs/backsync-bms-pms-data.ts b/server/src/lib/jobs/backsync-bms-pms-data.ts index a166f6aea..65abb552c 100644 --- a/server/src/lib/jobs/backsync-bms-pms-data.ts +++ b/server/src/lib/jobs/backsync-bms-pms-data.ts @@ -18,7 +18,7 @@ export async function BacksyncBMSPMSSongsAndCharts() { logger.info(`Fetching ${game} songs from DB.`); // did you know, this code is liable to blow up in my face and OOM one day? - let songs = await db.songs[game].find({}); + let songs = await db.anySongs[game].find({}); logger.info(`Found ${songs.length} ${game} songs.`); @@ -30,7 +30,7 @@ export async function BacksyncBMSPMSSongsAndCharts() { songs = null; logger.info(`Fetching ${game} charts from DB.`); - let charts = await db.charts[game].find({}); + let charts = await db.anyCharts[game].find({}); logger.info(`Found ${charts.length} bms charts.`); diff --git a/server/src/lib/orphan-queue/orphan-queue.ts b/server/src/lib/orphan-queue/orphan-queue.ts index 3d98722e8..e1575ed60 100644 --- a/server/src/lib/orphan-queue/orphan-queue.ts +++ b/server/src/lib/orphan-queue/orphan-queue.ts @@ -79,8 +79,8 @@ export async function HandleOrphanQueue( songDoc.id = songID; chartDoc.songID = songID; - await db.songs[game].insert(songDoc); - await db.charts[game].insert(chartDoc); + await db.anySongs[game].insert(songDoc); + await db.anyCharts[game].insert(chartDoc); await db["orphan-chart-queue"].remove({ _id: orphanChart._id, }); @@ -137,8 +137,8 @@ export async function DeorphanIfInQueue( songDoc.id = songID; chartDoc.songID = songID; - await db.songs[game].insert(songDoc); - await db.charts[game].insert(chartDoc); + await db.anySongs[game].insert(songDoc); + await db.anyCharts[game].insert(chartDoc); await db["orphan-chart-queue"].remove({ _id: orphanChart._id, }); diff --git a/server/src/lib/score-import/import-types/common/batch-manual/converter.ts b/server/src/lib/score-import/import-types/common/batch-manual/converter.ts index a6e931801..3b26b7315 100644 --- a/server/src/lib/score-import/import-types/common/batch-manual/converter.ts +++ b/server/src/lib/score-import/import-types/common/batch-manual/converter.ts @@ -330,7 +330,7 @@ export async function ResolveMatchTypeToTachiData( ); } - const song = await db.songs[game].findOne({ id: chart.songID }); + const song = await db.anySongs[game].findOne({ id: chart.songID }); if (!song) { logger.severe(`Song-Chart desync on ${chart.songID}.`); @@ -348,14 +348,14 @@ export async function ResolveMatchTypeToTachiData( let chart; if (context.version) { - chart = await db.charts[game].findOne({ + chart = await db.anyCharts[game].findOne({ "data.inGameID": identifier, playtype: context.playtype, difficulty, versions: context.version, }); } else { - chart = await db.charts[game].findOne({ + chart = await db.anyCharts[game].findOne({ "data.inGameID": identifier, playtype: context.playtype, difficulty, @@ -371,7 +371,7 @@ export async function ResolveMatchTypeToTachiData( ); } - const song = await db.songs[game].findOne({ id: chart.songID }); + const song = await db.anySongs[game].findOne({ id: chart.songID }); if (!song) { logger.severe(`Song-Chart desync on ${chart.songID}.`); @@ -400,7 +400,7 @@ export async function ResolveMatchTypeToTachiData( ); } - const song = await db.songs[game].findOne({ id: chart.songID }); + const song = await db.anySongs[game].findOne({ id: chart.songID }); if (!song) { logger.severe(`Song-Chart desync on ${chart.songID}.`); diff --git a/server/src/lib/score-mutation/update-isprimary.ts b/server/src/lib/score-mutation/update-isprimary.ts index f14cdc6fc..8b3bd248a 100644 --- a/server/src/lib/score-mutation/update-isprimary.ts +++ b/server/src/lib/score-mutation/update-isprimary.ts @@ -5,7 +5,7 @@ import { TachiConfig } from "lib/setup/config"; export default async function UpdateIsPrimaryStatus() { for (const game of TachiConfig.GAMES) { const chartIDs = ( - await db.charts[game].find({ + await db.anyCharts[game].find({ isPrimary: false, }) ).map((e) => e.chartID); diff --git a/server/src/lib/search/search.ts b/server/src/lib/search/search.ts index c07130a3c..014253e96 100644 --- a/server/src/lib/search/search.ts +++ b/server/src/lib/search/search.ts @@ -75,7 +75,7 @@ export function SearchSpecificGameSongs( search: string, limit = 100 ): Promise> { - return SearchCollection(db.songs[game], search, {}, limit); + return SearchCollection(db.anySongs[game], search, {}, limit); } export async function SearchSpecificGameSongsAndCharts( @@ -94,7 +94,7 @@ export async function SearchSpecificGameSongsAndCharts( chartQuery.playtype = playtype; } - const charts = (await db.charts[game].find(chartQuery)) as Array; + const charts = (await db.anyCharts[game].find(chartQuery)) as Array; return { songs, charts }; } diff --git a/server/src/lib/showcase/get-related.ts b/server/src/lib/showcase/get-related.ts index 675abb76f..b2b7368ce 100644 --- a/server/src/lib/showcase/get-related.ts +++ b/server/src/lib/showcase/get-related.ts @@ -7,14 +7,14 @@ const logger = CreateLogCtx(__filename); export async function GetRelatedStatDocuments(stat: ShowcaseStatDetails, game: Game) { switch (stat.mode) { case "chart": { - const chart = await db.charts[game].findOne({ chartID: stat.chartID }); + const chart = await db.anyCharts[game].findOne({ chartID: stat.chartID }); if (!chart) { logger.error(`This stat refers to a chart that does not exist?`, { stat }); throw new Error(`Stat refers to a chart that does not exist? ${stat.chartID}.`); } - const song = await db.songs[game].findOne({ id: chart.songID }); + const song = await db.anySongs[game].findOne({ id: chart.songID }); if (!song) { logger.severe(`Song-Chart Mismatch - ${chart.songID}.`, { chart }); diff --git a/server/src/lib/targets/goal-utils.ts b/server/src/lib/targets/goal-utils.ts index ed773ff40..7333a3191 100644 --- a/server/src/lib/targets/goal-utils.ts +++ b/server/src/lib/targets/goal-utils.ts @@ -153,7 +153,7 @@ export async function ValidateGoalChartsAndCriteria( switch (charts.type) { case "single": { - const chart = await db.charts[game].findOne({ + const chart = await db.anyCharts[game].findOne({ playtype, chartID: charts.data, }); @@ -192,7 +192,7 @@ export async function ValidateGoalChartsAndCriteria( ); } - const multiCharts = await db.charts[game].find({ + const multiCharts = await db.anyCharts[game].find({ playtype, chartID: { $in: charts.data }, }); @@ -268,7 +268,7 @@ export async function ValidateGoalChartsAndCriteria( ); } - const relatedChart = (await db.charts[game].findOne({ + const relatedChart = (await db.anyCharts[game].findOne({ playtype, chartID: charts.data, })) as ChartDocument< diff --git a/server/src/server/router/api/v1/admin/router.ts b/server/src/server/router/api/v1/admin/router.ts index 468959cac..6db31c439 100644 --- a/server/src/server/router/api/v1/admin/router.ts +++ b/server/src/server/router/api/v1/admin/router.ts @@ -253,7 +253,7 @@ router.post( await DeleteMultipleScores(scores); - await db.charts[game].remove({ + await db.anyCharts[game].remove({ chartID, }); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/middleware.ts b/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/middleware.ts index 82af0057e..988f8b1f7 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/middleware.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/middleware.ts @@ -5,7 +5,7 @@ import type { RequestHandler } from "express"; export const ValidateAndGetChart: RequestHandler = async (req, res, next) => { const { game, playtype } = GetGPT(req); - const chart = await db.charts[game].findOne({ + const chart = await db.anyCharts[game].findOne({ chartID: req.params.chartID, // technically redundant, but we're under playtypes here URL wise. diff --git a/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/router.ts index 7cc0f2ad3..b916910a2 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/charts/_chartID/router.ts @@ -26,7 +26,7 @@ router.get("/", async (req, res) => { const chart = GetTachiData(req, "chartDoc"); const game = GetTachiData(req, "game"); - const song = await db.songs[game].findOne({ + const song = await db.anySongs[game].findOne({ id: chart.songID, }); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/charts/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/charts/router.ts index 30d382f3f..a8f1d0fc2 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/charts/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/charts/router.ts @@ -6,7 +6,7 @@ import { SearchSpecificGameSongs } from "lib/search/search"; import { IsString } from "utils/misc"; import { FindChartsOnPopularity } from "utils/queries/charts"; import { GetGPT } from "utils/req-tachi-data"; -import type { ChartDocument, integer, UGPTSettings } from "tachi-common"; +import type { ChartDocument, integer, UGPTSettingsDocument } from "tachi-common"; const router: Router = Router({ mergeParams: true }); @@ -75,7 +75,7 @@ router.get("/", async (req, res) => { // @optimisable // could use songIDs from above instead of refetching // but this is not very expensive. - const songs = await db.songs[game].find({ + const songs = await db.anySongs[game].find({ id: { $in: charts.map((e) => e.songID) }, }); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/router.ts index bfdb3a7a7..beb8ab9c4 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/router.ts @@ -46,7 +46,7 @@ async function GetGameStats( game, playtype, }), - db.charts[game].count({ playtype }), + db.anyCharts[game].count({ playtype }), ]); gptStatCache.set(`${game}:${playtype}`, { scoreCount, playerCount, chartCount }, ONE_HOUR); diff --git a/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/middleware.ts b/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/middleware.ts index 258dde69a..7b6238013 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/middleware.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/middleware.ts @@ -15,7 +15,7 @@ export const ValidateAndGetSong: RequestHandler = async (req, res, next) => { const game = GetTachiData(req, "game"); - const song = await db.songs[game].findOne({ id: songID }); + const song = await db.anySongs[game].findOne({ id: songID }); if (!song) { return res.status(404).json({ diff --git a/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/router.ts b/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/router.ts index 131583309..7720d4fbd 100644 --- a/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/router.ts +++ b/server/src/server/router/api/v1/games/_game/_playtype/songs/_songID/router.ts @@ -16,7 +16,7 @@ router.get("/", async (req, res) => { const song = GetTachiData(req, "songDoc"); const { game, playtype } = GetGPT(req); - const charts = await db.charts[game].find({ + const charts = await db.anyCharts[game].find({ songID: song.id, playtype, }); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/pbs/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/pbs/router.ts index ba93d4662..129def73b 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/pbs/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/pbs/router.ts @@ -106,9 +106,9 @@ router.get("/best", prValidate({ alg: "*string" }), async (req, res) => { if (req.query.alg !== undefined && !IsValidScoreAlg(gptConfig, req.query.alg)) { return res.status(400).json({ success: false, - description: `Invalid score algorithm. Expected any of ${gptConfig.scoreRatingAlgs.join( - ", " - )}`, + description: `Invalid score algorithm. Expected any of ${Object.keys( + gptConfig.scoreRatingAlgs + ).join(", ")}`, }); } @@ -153,7 +153,7 @@ router.get("/best", prValidate({ alg: "*string" }), async (req, res) => { router.get("/:chartID", async (req, res) => { const { user, game, playtype } = GetUGPT(req); - const chart = await db.charts[game].findOne({ + const chart = await db.anyCharts[game].findOne({ chartID: req.params.chartID, playtype, }); @@ -245,7 +245,7 @@ router.get("/:chartID/rivals", async (req, res) => { router.get("/:chartID/leaderboard-adjacent", async (req, res) => { const { user, game, playtype } = GetUGPT(req); - const chart = await db.charts[game].findOne({ + const chart = await db.anyCharts[game].findOne({ chartID: req.params.chartID, playtype, }); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/rivals/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/rivals/router.ts index 030e13d4f..92362bf90 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/rivals/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/rivals/router.ts @@ -128,7 +128,7 @@ router.get("/pb-leaderboard", async (req, res) => { success: false, description: `Invalid value of ${ req.query.alg - } for alg. Expected one of ${gptConfig.scoreRatingAlgs.join(", ")}`, + } for alg. Expected one of ${Object.keys(gptConfig.scoreRatingAlgs).join(", ")}`, }); } diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts index 1fc495026..e7832b695 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/router.ts @@ -216,8 +216,8 @@ router.get("/most-played", async (req, res) => { const songIDs = mostPlayed.map((e) => e.songID); const [songs, charts, pbs] = await Promise.all([ - await db.songs[game].find({ id: { $in: songIDs } }), - await db.charts[game].find({ chartID: { $in: chartIDs } }), + await db.anySongs[game].find({ id: { $in: songIDs } }), + await db.anyCharts[game].find({ chartID: { $in: chartIDs } }), await db["personal-bests"].find({ chartID: { $in: chartIDs }, userID: user.id }), ]); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts index 78100a5fa..334cc6e9e 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/scores/router.ts @@ -124,7 +124,7 @@ router.get("/recent", async (req, res) => { router.get("/:chartID", async (req, res) => { const { user, game, playtype } = GetUGPT(req); - const chart = await db.charts[game].findOne({ + const chart = await db.anyCharts[game].findOne({ chartID: req.params.chartID, playtype, }); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts index 80dcafcff..87077808b 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.test.ts @@ -4,7 +4,7 @@ import t from "tap"; import { mkFakeUser } from "test-utils/misc"; import mockApi from "test-utils/mock-api"; import ResetDBState from "test-utils/resets"; -import type { UGPTSettings } from "tachi-common"; +import type { UGPTSettingsDocument } from "tachi-common"; t.test("GET /api/v1/users/:userID/games/:game/:playtype/settings", (t) => { t.beforeEach(ResetDBState); diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts index d02160eab..c32a79f0b 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/settings/router.ts @@ -9,7 +9,7 @@ import { PR_GAMESPECIFIC_SETTINGS } from "tachi-common/lib/schemas"; import { FormatPrError, optNull } from "utils/prudence"; import { GetUGPT } from "utils/req-tachi-data"; import { FormatUserDoc } from "utils/user"; -import type { UGPTSettings } from "tachi-common"; +import type { UGPTSettingsDocument } from "tachi-common"; const logger = CreateLogCtx(__filename); @@ -51,7 +51,7 @@ router.patch( }); } - const body = req.safeBody as Partial; + const body = req.safeBody as Partial; if (typeof body.defaultTable === "string") { const table = await db.tables.findOne({ diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.ts index 426e07a04..25249686d 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/showcase/router.ts @@ -126,7 +126,7 @@ router.get("/custom", async (req, res) => { }); } - const chart = await db.charts[game].findOne({ chartID: req.query.chartID as string }); + const chart = await db.anyCharts[game].findOne({ chartID: req.query.chartID as string }); if (!chart || chart.playtype !== playtype) { return res.status(400).json({ @@ -250,7 +250,7 @@ router.put("/", RequireAuthedAsUser, RequirePermissions("customise_profile"), as if (stat.mode === "chart") { // eslint-disable-next-line no-await-in-loop - const chart = await db.charts[game].findOne({ chartID: stat.chartID }); + const chart = await db.anyCharts[game].findOne({ chartID: stat.chartID }); if (!chart || chart.playtype !== playtype) { return res.status(400).json({ diff --git a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts index 7b0858684..7b9c529f2 100644 --- a/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts +++ b/server/src/server/router/api/v1/users/_userID/games/_game/_playtype/targets/router.ts @@ -85,7 +85,7 @@ router.get("/on-chart/:chartID", async (req, res) => { const chartID = req.params.chartID; - const chart = await db.charts[game].findOne({ chartID, playtype }); + const chart = await db.anyCharts[game].findOne({ chartID, playtype }); if (!chart) { return res.status(404).json({ diff --git a/server/src/server/router/ir/usc/_playtype/usc.ts b/server/src/server/router/ir/usc/_playtype/usc.ts index 69956728a..82bb3a8f4 100644 --- a/server/src/server/router/ir/usc/_playtype/usc.ts +++ b/server/src/server/router/ir/usc/_playtype/usc.ts @@ -80,7 +80,7 @@ export async function TachiScoreToServerScore( near: tachiScore.scoreData.judgements.near ?? 0, error: tachiScore.scoreData.judgements.miss ?? 0, ranking: tachiScore.rankingData.rank, - lamp: TACHI_LAMP_TO_USC[tachiScore.scoreData.lamp], + lamp: TACHI_LAMP_TO_USC[tachiScore.scoreData.lamp.string], username: userDoc.username, noteMod: scorePB.scoreMeta.noteMod ?? "NORMAL", gaugeMod: scorePB.scoreMeta.gaugeMod ?? "NORMAL", diff --git a/server/src/test-utils/misc.ts b/server/src/test-utils/misc.ts index b8e145414..ca43b8cc2 100644 --- a/server/src/test-utils/misc.ts +++ b/server/src/test-utils/misc.ts @@ -25,7 +25,7 @@ import type { Playtype, UserDocument, ScoreDocument, - UGPTSettings, + UGPTSettingsDocument, UserGameStats, } from "tachi-common"; @@ -71,7 +71,7 @@ export function mkFakeGameSettings( userID: integer, game: Game, playtype: Playtype, - modifant: Partial = {} + modifant: Partial = {} ) { return dmf(FakeGameSettings, { userID, diff --git a/server/src/test-utils/test-data.ts b/server/src/test-utils/test-data.ts index 6f4e740d6..88f860182 100644 --- a/server/src/test-utils/test-data.ts +++ b/server/src/test-utils/test-data.ts @@ -34,7 +34,7 @@ import type { UserDocument, ScoreDocument, SongDocument, - UGPTSettings, + UGPTSettingsDocument, } from "tachi-common"; const file = (name: string) => path.join(__dirname, "/test-data", name); @@ -840,7 +840,7 @@ export const FakeOtherUser: UserDocument = { usernameLowercase: "other_user", }; -export const FakeGameSettings: UGPTSettings = { +export const FakeGameSettings: UGPTSettingsDocument = { game: "iidx", playtype: "SP", preferences: { diff --git a/server/src/utils/db.ts b/server/src/utils/db.ts index 0809755c6..5d5478bb0 100644 --- a/server/src/utils/db.ts +++ b/server/src/utils/db.ts @@ -71,10 +71,10 @@ export async function GetRelevantSongsAndCharts( game: Game ) { const [songs, charts] = await Promise.all([ - db.songs[game].find({ + db.anySongs[game].find({ id: { $in: scores.map((e) => e.songID) }, }), - db.charts[game].find({ + db.anyCharts[game].find({ chartID: { $in: scores.map((e) => e.chartID) }, }), ]); @@ -83,7 +83,7 @@ export async function GetRelevantSongsAndCharts( } export async function UpdateGameSongIDCounter(game: "bms" | "pms") { - const latestSong = await db.songs[game].findOne( + const latestSong = await db.anySongs[game].findOne( {}, { sort: { id: -1 }, @@ -112,7 +112,7 @@ export async function UpdateGameSongIDCounter(game: "bms" | "pms") { } export async function GetChartForIDGuaranteed(game: Game, chartID: string) { - const chart = await db.charts[game].findOne({ chartID }); + const chart = await db.anyCharts[game].findOne({ chartID }); if (!chart) { throw new Error(`Couldn't find chart with ID ${chartID} (${game}).`); @@ -122,7 +122,7 @@ export async function GetChartForIDGuaranteed(game: Game, chartID: string) { } export async function GetSongForIDGuaranteed(game: Game, songID: integer) { - const song = await db.songs[game].findOne({ id: songID }); + const song = await db.anySongs[game].findOne({ id: songID }); if (!song) { throw new Error(`Couldn't find song with ID ${songID} (${game}).`); diff --git a/server/src/utils/misc.ts b/server/src/utils/misc.ts index a3b7a1697..7b77e59c5 100644 --- a/server/src/utils/misc.ts +++ b/server/src/utils/misc.ts @@ -79,7 +79,9 @@ export function IsValidScoreAlg( gptConfig: GamePTConfig, str: unknown ): str is GamePTConfig["scoreRatingAlgs"][0] { - return gptConfig.scoreRatingAlgs.includes(str as GamePTConfig["scoreRatingAlgs"][0]); + return Object.keys(gptConfig.scoreRatingAlgs).includes( + str as GamePTConfig["scoreRatingAlgs"][0] + ); } export function IsString(val: unknown): val is string { diff --git a/server/src/utils/queries/charts.ts b/server/src/utils/queries/charts.ts index 4acaa5e76..1ca8a0e08 100644 --- a/server/src/utils/queries/charts.ts +++ b/server/src/utils/queries/charts.ts @@ -12,7 +12,7 @@ import type { } from "tachi-common"; export function FindChartWithChartID(game: Game, chartID: string) { - return db.charts[game].findOne({ chartID }); + return db.anyCharts[game].findOne({ chartID }); } /** @@ -25,7 +25,7 @@ export function FindChartWithPTDF< P extends Playtypes[G] = Playtypes[G], I extends GPTString = GPTString >(game: G, songID: integer, playtype: P, difficulty: Difficulties[I]) { - return db.charts[game].findOne({ + return db.anyCharts[game].findOne({ songID, playtype, difficulty, @@ -42,7 +42,7 @@ export function FindChartWithPTDFVersion< P extends Playtypes[G] = Playtypes[G], I extends GPTString = GPTString >(game: G, songID: integer, playtype: P, difficulty: Difficulties[I], version: Versions[I]) { - return db.charts[game].findOne({ + return db.anyCharts[game].findOne({ songID, playtype, difficulty, @@ -79,7 +79,7 @@ export function FindChartOnInGameID( throw new Error(`Cannot call FindChartOnInGameID for game ${game}.`); } - return db.charts[game].findOne({ + return db.anyCharts[game].findOne({ "data.inGameID": inGameID, playtype, difficulty, @@ -133,7 +133,7 @@ export function FindChartOnInGameIDVersion( difficulty: Difficulties[I], version: Versions[I] ) { - return db.charts[game].findOne({ + return db.anyCharts[game].findOne({ "data.inGameID": inGameID, versions: version, playtype, @@ -211,7 +211,7 @@ export function FindChartOnSHA256(game: Game, hash: string) { throw new Error(`Cannot call FindChartOnSHA256 for game ${game}.`); } - return db.charts[game].findOne({ + return db.anyCharts[game].findOne({ "data.hashSHA256": hash, }); } @@ -221,7 +221,7 @@ export function FindChartOnSHA256Playtype(game: Game, hash: string, playtype: Pl throw new Error(`Cannot call FindChartOnSHA256 for game ${game}.`); } - return db.charts[game].findOne({ + return db.anyCharts[game].findOne({ "data.hashSHA256": hash, playtype, }); @@ -256,7 +256,7 @@ export async function FindChartsOnPopularity( // magnitude faster. // Not entirely sure why, but $lookup is incredibly inefficient, // and you should just avoid it. - const charts = (await db.charts[game].find(matchQuery)) as unknown as Array< + const charts = (await db.anyCharts[game].find(matchQuery)) as unknown as Array< ChartDocument & { __playcount: integer; } diff --git a/server/src/utils/queries/songs.ts b/server/src/utils/queries/songs.ts index 52798954f..fb2848e69 100644 --- a/server/src/utils/queries/songs.ts +++ b/server/src/utils/queries/songs.ts @@ -15,7 +15,7 @@ import type { Game, integer, SongDocument } from "tachi-common"; */ export function FindSongOnTitle(game: Game, title: string): Promise> { // @optimisable: Performance should be tested here by having a utility field for all-titles. - return db.songs[game].findOne({ + return db.anySongs[game].findOne({ $or: [ { title, @@ -39,7 +39,7 @@ export function FindSongOnTitleInsensitive( const regex = new RegExp(`^${EscapeStringRegexp(title)}$`, "iu"); - return db.songs[game].findOne({ + return db.anySongs[game].findOne({ $or: [ { title: { $regex: regex }, @@ -59,7 +59,7 @@ export function FindSongOnTitleInsensitive( * @returns SongDocument */ export function FindSongOnID(game: Game, songID: integer): Promise> { - return db.songs[game].findOne({ + return db.anySongs[game].findOne({ id: songID, }); }