Unify notFoundIfFalsy and notFoundIfNullLike

This commit is contained in:
Kalle 2026-07-25 21:06:56 +03:00
parent 463dfc71b8
commit 0c5d9d1136
59 changed files with 139 additions and 132 deletions

View File

@ -8,7 +8,7 @@ import * as UserRepository from "~/features/user-page/UserRepository.server";
import { requireRole } from "~/modules/permissions/guards.server";
import {
errorToast,
notFoundIfFalsy,
notFoundIfNullish,
parseRequestPayload,
successToast,
} from "~/utils/remix.server";
@ -129,7 +129,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
case "BAN_USER": {
requireRole("STAFF");
const bannedUser = notFoundIfFalsy(
const bannedUser = notFoundIfNullish(
await UserRepository.findLeanById(data.user),
);
const banExpiresAt = data.duration ? new Date(data.duration) : null;
@ -156,7 +156,7 @@ export const action = async ({ request }: ActionFunctionArgs) => {
case "UNBAN_USER": {
requireRole("STAFF");
const unbannedUser = notFoundIfFalsy(
const unbannedUser = notFoundIfNullish(
await UserRepository.findLeanById(data.user),
);

View File

@ -3,7 +3,7 @@ import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { db } from "~/db/sql";
import { concatUserSubmittedImagePrefix } from "~/utils/kysely.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetTournamentOrganizationResponse } from "../schema";
@ -14,7 +14,7 @@ const paramsSchema = z.object({
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { id } = parseParams({ params, schema: paramsSchema });
const organization = notFoundIfFalsy(
const organization = notFoundIfNullish(
await db
.selectFrom("TournamentOrganization")
.leftJoin(

View File

@ -2,7 +2,7 @@ import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import * as SQMatchRepository from "~/features/sendouq-match/SQMatchRepository.server";
import { getFixedTForLanguage } from "~/modules/i18n/i18next.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetSendouqMatchResponse, MapListMap } from "../schema";
@ -16,7 +16,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
schema: paramsSchema,
});
const match = notFoundIfFalsy(await SQMatchRepository.findById(matchId));
const match = notFoundIfNullish(await SQMatchRepository.findById(matchId));
const t = await getFixedTForLanguage("en", ["game-misc"]);

View File

@ -2,7 +2,7 @@ import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { db } from "~/db/sql";
import { concatUserSubmittedImagePrefix } from "~/utils/kysely.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetTeamResponse } from "../schema";
@ -13,7 +13,7 @@ const paramsSchema = z.object({
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { id: teamId } = parseParams({ params, schema: paramsSchema });
const team = notFoundIfFalsy(
const team = notFoundIfNullish(
await db
.selectFrom("Team")
.leftJoin(

View File

@ -8,7 +8,7 @@ import { tournamentFromDBCached } from "~/features/tournament-bracket/core/Tourn
import { resolveMapList } from "~/features/tournament-match/core/mapList.server";
import { getFixedTForLanguage } from "~/modules/i18n/i18next.server";
import { logger } from "~/utils/logger";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetTournamentMatchResponse } from "../schema";
@ -23,7 +23,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
schema: paramsSchema,
});
const match = notFoundIfFalsy(
const match = notFoundIfNullish(
await db
.selectFrom("TournamentMatch")
.innerJoin(

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetTournamentBracketStandingsResponse } from "../schema";
@ -18,8 +18,8 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
tournamentId: id,
});
const bracket = notFoundIfFalsy(tournament.bracketByIdx(bidx));
notFoundIfFalsy(!bracket.preview);
const bracket = notFoundIfNullish(tournament.bracketByIdx(bidx));
if (bracket.preview) throw new Response(null, { status: 404 });
const result: GetTournamentBracketStandingsResponse = {
standings: bracket.standings.map((standing) => ({

View File

@ -2,7 +2,7 @@ import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import type { Bracket } from "~/features/tournament-bracket/core/Bracket";
import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetTournamentBracketResponse } from "../schema";
@ -19,7 +19,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
tournamentId: id,
});
const bracket = notFoundIfFalsy(tournament.bracketByIdx(bidx));
const bracket = notFoundIfNullish(tournament.bracketByIdx(bidx));
const result: GetTournamentBracketResponse = {
data: bracket.data,

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { db } from "~/db/sql";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetCastedTournamentMatchesResponse } from "../schema";
@ -15,7 +15,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
schema: paramsSchema,
});
const tournament = notFoundIfFalsy(
const tournament = notFoundIfNullish(
await db
.selectFrom("Tournament")
.select(["Tournament.castedMatchesInfo"])

View File

@ -3,7 +3,7 @@ import { jsonArrayFrom } from "kysely/helpers/sqlite";
import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { db } from "~/db/sql";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetTournamentStreamsResponse } from "../schema";
@ -17,7 +17,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
schema: paramsSchema,
});
const tournament = notFoundIfFalsy(
const tournament = notFoundIfNullish(
await db
.selectFrom("Tournament")
.select([

View File

@ -3,7 +3,7 @@ import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { db } from "~/db/sql";
import { databaseTimestampToDate } from "~/utils/dates";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import type { GetTournamentResponse } from "../schema";
@ -14,7 +14,7 @@ const paramsSchema = z.object({
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { id } = parseParams({ params, schema: paramsSchema });
const tournament = notFoundIfFalsy(
const tournament = notFoundIfNullish(
await db
.selectFrom("Tournament")
.innerJoin("CalendarEvent", "CalendarEvent.tournamentId", "Tournament.id")

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod/v4";
import { identifierToUserIdQuery } from "~/features/user-page/UserRepository.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import type { GetUserIdsResponse } from "../schema";
const paramsSchema = z.object({
@ -11,7 +11,7 @@ const paramsSchema = z.object({
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { identifier } = parseParams({ params, schema: paramsSchema });
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await identifierToUserIdQuery(identifier)
.select(["User.discordId", "User.customUrl"])
.executeTakeFirst(),

View File

@ -8,7 +8,7 @@ import { peakXpOverallSql } from "~/features/top-search/XRankPlacementRepository
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { getFixedTForLanguage } from "~/modules/i18n/i18next.server";
import { safeNumberParse } from "~/utils/number";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { badgeUrl } from "~/utils/urls";
import type { GetUserResponse } from "../schema";
@ -20,7 +20,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
const t = await getFixedTForLanguage("en", ["weapons"]);
const { identifier } = parseParams({ params, schema: paramsSchema });
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await db
.selectFrom("User")
.leftJoin("PlusTier", "PlusTier.userId", "User.id")

View File

@ -1,12 +1,12 @@
import type { LoaderFunctionArgs } from "react-router";
import invariant from "~/utils/invariant";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { articleBySlug } from "../core/bySlug.server";
export const loader = ({ params }: LoaderFunctionArgs) => {
invariant(params.slug);
const article = notFoundIfFalsy(articleBySlug(params.slug));
const article = notFoundIfNullish(articleBySlug(params.slug));
return { ...article, slug: params.slug };
};

View File

@ -7,7 +7,7 @@ import {
requireRole,
} from "~/modules/permissions/guards.server";
import { diff } from "~/utils/arrays";
import { notFoundIfFalsy, parseRequestPayload } from "~/utils/remix.server";
import { notFoundIfNullish, parseRequestPayload } from "~/utils/remix.server";
import { assertUnreachable } from "~/utils/types";
import { badgePage } from "~/utils/urls";
import { actualNumber } from "~/utils/zod";
@ -20,7 +20,7 @@ export const action: ActionFunction = async ({ request, params }) => {
schema: editBadgeActionSchema,
});
const badgeId = z.preprocess(actualNumber, z.number()).parse(params.id);
const badge = notFoundIfFalsy(await BadgeRepository.findById(badgeId));
const badge = notFoundIfNullish(await BadgeRepository.findById(badgeId));
switch (data._action) {
case "MANAGERS": {

View File

@ -1,6 +1,6 @@
import type { LoaderFunctionArgs } from "react-router";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { idObject } from "~/utils/zod";
import * as BadgeRepository from "../BadgeRepository.server";
@ -10,7 +10,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
params,
schema: idObject,
});
const badge = notFoundIfFalsy(await BadgeRepository.findById(id));
const badge = notFoundIfNullish(await BadgeRepository.findById(id));
return {
badge,

View File

@ -4,14 +4,14 @@ import * as BuildRepository from "~/features/builds/BuildRepository.server";
import { getServerTFunction } from "~/modules/i18n/i18next.server";
import { weaponIdToType } from "~/modules/in-game-lists/weapon-ids";
import { cache, IN_MILLISECONDS, ttl } from "~/utils/cache.server";
import { notFoundIfNullLike } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { weaponNameSlugToId } from "~/utils/unslugify.server";
import { popularBuilds } from "../build-stats-utils";
export const loader = async ({ params }: LoaderFunctionArgs) => {
const t = getServerTFunction(["builds", "weapons"]);
const slug = params.slug;
const weaponId = notFoundIfNullLike(weaponNameSlugToId(slug));
const weaponId = notFoundIfNullish(weaponNameSlugToId(slug));
if (weaponIdToType(weaponId) === "ALT_SKIN") {
throw new Response(null, { status: 404 });

View File

@ -4,13 +4,13 @@ import * as BuildRepository from "~/features/builds/BuildRepository.server";
import { getServerTFunction } from "~/modules/i18n/i18next.server";
import { weaponIdToType } from "~/modules/in-game-lists/weapon-ids";
import { cache } from "~/utils/cache.server";
import { notFoundIfNullLike } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { weaponNameSlugToId } from "~/utils/unslugify.server";
import { abilityPointCountsToAverages } from "../build-stats-utils";
export const loader = async ({ params }: LoaderFunctionArgs) => {
const t = getServerTFunction(["builds", "weapons"]);
const weaponId = notFoundIfNullLike(weaponNameSlugToId(params.slug));
const weaponId = notFoundIfNullish(weaponNameSlugToId(params.slug));
if (weaponIdToType(weaponId) === "ALT_SKIN") {
throw new Response(null, { status: 404 });

View File

@ -4,7 +4,7 @@ import { requireUser } from "~/features/auth/core/user.server";
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
import {
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
safeParseRequestFormData,
} from "~/utils/remix.server";
@ -30,7 +30,7 @@ export const action: ActionFunction = async (args) => {
};
}
const event = notFoundIfFalsy(await CalendarRepository.findById(params.id));
const event = notFoundIfNullish(await CalendarRepository.findById(params.id));
errorToastIfFalsy(
canReportCalendarEventWinners({
user,

View File

@ -9,7 +9,7 @@ import {
tournamentManagerData,
} from "~/features/tournament-bracket/core/Tournament.server";
import { databaseTimestampToDate } from "~/utils/dates";
import { errorToastIfFalsy, notFoundIfFalsy } from "~/utils/remix.server";
import { errorToastIfFalsy, notFoundIfNullish } from "~/utils/remix.server";
import { CALENDAR_PAGE } from "~/utils/urls";
import { actualNumber, id } from "~/utils/zod";
import { canDeleteCalendarEvent } from "../calendar-utils";
@ -19,7 +19,7 @@ export const action: ActionFunction = async ({ params }) => {
const parsedParams = z
.object({ id: z.preprocess(actualNumber, id) })
.parse(params);
const event = notFoundIfFalsy(
const event = notFoundIfNullish(
await CalendarRepository.findById(parsedParams.id),
);

View File

@ -2,7 +2,7 @@ import type { LoaderFunctionArgs } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
import {
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
unauthorizedIfFalsy,
} from "~/utils/remix.server";
@ -15,7 +15,7 @@ export const loader = async (args: LoaderFunctionArgs) => {
schema: idObject,
});
const user = requireUser();
const event = notFoundIfFalsy(await CalendarRepository.findById(params.id));
const event = notFoundIfNullish(await CalendarRepository.findById(params.id));
unauthorizedIfFalsy(
canReportCalendarEventWinners({

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { redirect } from "react-router";
import * as CalendarRepository from "~/features/calendar/CalendarRepository.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { tournamentPage } from "~/utils/urls";
import { idObject } from "~/utils/zod";
@ -10,7 +10,7 @@ export const loader = async (args: LoaderFunctionArgs) => {
params: args.params,
schema: idObject,
});
const event = notFoundIfFalsy(
const event = notFoundIfNullish(
await CalendarRepository.findById(params.id, {
includeBadgePrizes: true,
includeMapPool: true,

View File

@ -5,7 +5,7 @@ import { requirePermission } from "~/modules/permissions/guards.server";
import {
errorToast,
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
parseRequestPayload,
} from "~/utils/remix.server";
@ -23,7 +23,7 @@ import { parseMapPoolInput } from "../scrims-utils";
export const action = async ({ request, params }: ActionFunctionArgs) => {
const { id } = parseParams({ params, schema: idObject });
const post = notFoundIfFalsy(await ScrimPostRepository.findById(id));
const post = notFoundIfNullish(await ScrimPostRepository.findById(id));
const user = requireUser();
const data = await parseRequestPayload({

View File

@ -3,7 +3,7 @@ import { chatAccessible } from "~/features/chat/chat-utils";
import * as UserCardRepository from "~/features/user-card/UserCardRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { databaseTimestampToDate } from "~/utils/dates";
import { notFoundIfFalsy } from "../../../utils/remix.server";
import { notFoundIfNullish } from "../../../utils/remix.server";
import {
type AuthenticatedUser,
requireUser,
@ -17,7 +17,7 @@ import * as ScrimPostRepository from "../ScrimPostRepository.server";
export const loader = async ({ params }: LoaderFunctionArgs) => {
const user = requireUser();
const post = notFoundIfFalsy(
const post = notFoundIfNullish(
await ScrimPostRepository.findById(Number(params.id)),
);

View File

@ -19,7 +19,7 @@ import { logger } from "~/utils/logger";
import {
errorToast,
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
parseRequestPayload,
} from "~/utils/remix.server";
@ -39,7 +39,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
schema: matchSchema,
});
const match = notFoundIfFalsy(await SQMatchRepository.findById(matchId));
const match = notFoundIfNullish(await SQMatchRepository.findById(matchId));
const isStaff = user.roles.includes("STAFF");
const isParticipant = [
...match.groupAlpha.members,

View File

@ -8,7 +8,7 @@ import * as SQMatchRepository from "~/features/sendouq-match/SQMatchRepository.s
import * as UserCardRepository from "~/features/user-card/UserCardRepository.server";
import { databaseTimestampToDate } from "~/utils/dates";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { qMatchPageParamsSchema } from "../q-match-schemas";
export const loader = async ({ params }: LoaderFunctionArgs) => {
@ -18,7 +18,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
schema: qMatchPageParamsSchema,
}).id;
const matchUnmapped = notFoundIfFalsy(
const matchUnmapped = notFoundIfNullish(
await SQMatchRepository.findById(matchId),
);

View File

@ -3,7 +3,7 @@ import { redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import { parseFormDataWithImages } from "~/form/parse.server";
import { clampThemeToGamut } from "~/utils/oklch-gamut";
import { errorToastIfFalsy, notFoundIfFalsy } from "~/utils/remix.server";
import { errorToastIfFalsy, notFoundIfNullish } from "~/utils/remix.server";
import { assertUnreachable } from "~/utils/types";
import { mySlugify, teamPage } from "~/utils/urls";
import * as TeamRepository from "../TeamRepository.server";
@ -14,7 +14,9 @@ export const action: ActionFunction = async ({ request, params }) => {
const user = requireUser();
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl),
);
errorToastIfFalsy(
isTeamManager({ team, user }) || user.roles.includes("ADMIN"),

View File

@ -3,7 +3,7 @@ import { redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import {
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseRequestPayload,
} from "~/utils/remix.server";
import { assertUnreachable } from "~/utils/types";
@ -22,7 +22,9 @@ export const action: ActionFunction = async ({ request, params }) => {
});
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl),
);
switch (data._action) {
case "LEAVE_TEAM": {

View File

@ -1,6 +1,6 @@
import { type ActionFunction, redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import { errorToastIfFalsy, notFoundIfFalsy } from "~/utils/remix.server";
import { errorToastIfFalsy, notFoundIfNullish } from "~/utils/remix.server";
import { teamPage } from "~/utils/urls";
import { validateInviteCode } from "../loaders/t.$customUrl.join.server";
import * as TeamRepository from "../TeamRepository.server";
@ -11,7 +11,7 @@ export const action: ActionFunction = async ({ params, url }) => {
const user = requireUser();
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl, {
includeInviteCode: true,
}),

View File

@ -3,7 +3,7 @@ import { redirect } from "react-router";
import type { MemberRole, MemberRoleType } from "~/db/tables";
import { requireUser } from "~/features/auth/core/user.server";
import { parseFormData } from "~/form/parse.server";
import { errorToastIfFalsy, notFoundIfFalsy } from "~/utils/remix.server";
import { errorToastIfFalsy, notFoundIfNullish } from "~/utils/remix.server";
import { assertUnreachable } from "~/utils/types";
import { teamPage } from "~/utils/urls";
import * as TeamRepository from "../TeamRepository.server";
@ -15,7 +15,9 @@ export const action: ActionFunction = async ({ request, params }) => {
const user = requireUser();
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl),
);
errorToastIfFalsy(
isTeamManager({ team, user }) || user.roles.includes("ADMIN"),
"Only team manager or owner can manage roster",

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { teamPage } from "~/utils/urls";
import * as TeamRepository from "../TeamRepository.server";
import { teamParamsSchema } from "../team-schemas.server";
@ -11,7 +11,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
const user = requireUser();
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl, {
includeUnvalidatedImages: true,
}),

View File

@ -2,7 +2,7 @@ import type { LoaderFunctionArgs } from "react-router";
import { redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import { SHORT_NANOID_LENGTH } from "~/utils/id";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { teamPage } from "~/utils/urls";
import * as TeamRepository from "../TeamRepository.server";
import { TEAM } from "../team-constants";
@ -13,7 +13,7 @@ export const loader = async ({ params, url }: LoaderFunctionArgs) => {
const user = requireUser();
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl, {
includeInviteCode: true,
}),

View File

@ -1,6 +1,6 @@
import type { LoaderFunctionArgs } from "react-router";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import * as TeamRepository from "../TeamRepository.server";
import { teamParamsSchema } from "../team-schemas.server";
@ -9,7 +9,9 @@ export type TeamResultsLoaderData = SerializeFrom<typeof loader>;
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl),
);
const results = await TeamRepository.findResultsById(team.id);

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { teamPage } from "~/utils/urls";
import * as TeamRepository from "../TeamRepository.server";
import { teamParamsSchema } from "../team-schemas.server";
@ -11,7 +11,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
const user = requireUser();
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl, {
includeInviteCode: true,
}),

View File

@ -1,6 +1,6 @@
import type { LoaderFunctionArgs } from "react-router";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import * as TeamRepository from "../TeamRepository.server";
import { teamParamsSchema } from "../team-schemas.server";
import { canAddCustomizedColors } from "../team-utils";
@ -10,7 +10,9 @@ export type TeamLoaderData = SerializeFrom<typeof loader>;
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { customUrl } = teamParamsSchema.parse(params);
const team = notFoundIfFalsy(await TeamRepository.findByCustomUrl(customUrl));
const team = notFoundIfNullish(
await TeamRepository.findByCustomUrl(customUrl),
);
const results = await TeamRepository.findResultPlacementsById(team.id);

View File

@ -4,7 +4,7 @@ import * as BadgeRepository from "~/features/badges/BadgeRepository.server";
import { logger } from "~/utils/logger";
import {
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
successToast,
} from "~/utils/remix.server";
@ -18,7 +18,7 @@ export const action = async ({ params }: ActionFunctionArgs) => {
schema: idObject,
});
const placements = notFoundIfFalsy(
const placements = notFoundIfNullish(
await XRankPlacementRepository.findPlacementsByPlayerId(id),
);
const currentLinkedUserDiscordId = placements[0].discordId;

View File

@ -1,6 +1,6 @@
import type { LoaderFunctionArgs } from "react-router";
import * as R from "remeda";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { idObject } from "~/utils/zod";
import * as XRankPlacementRepository from "../XRankPlacementRepository.server";
@ -10,7 +10,7 @@ export const loader = async (args: LoaderFunctionArgs) => {
schema: idObject,
});
const placements = notFoundIfFalsy(
const placements = notFoundIfNullish(
await XRankPlacementRepository.findPlacementsByPlayerId(params.id),
);

View File

@ -6,7 +6,7 @@ import { getTentativeTier } from "~/features/tournament-organization/core/tentat
import type { TournamentManagerDataSet } from "~/modules/brackets-manager/types";
import { isAdmin } from "~/modules/permissions/utils";
import { databaseTimestampToDate } from "~/utils/dates";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import type { Unwrapped } from "~/utils/types";
import { getServerTournamentManager } from "./brackets-manager/manager.server";
import { RunningTournaments } from "./RunningTournaments.server";
@ -91,7 +91,7 @@ export async function tournamentFromDB(args: {
user: { id: number } | undefined;
tournamentId: number;
}) {
const data = notFoundIfFalsy(await tournamentData(args));
const data = notFoundIfNullish(await tournamentData(args));
const tournament = new Tournament({ ...data, simulateBrackets: false });
syncTournamentToRegistry(tournament);
@ -103,7 +103,7 @@ export async function tournamentFromDBCached(args: {
user: { id: number } | undefined;
tournamentId: number;
}) {
const data = notFoundIfFalsy(await tournamentDataCached(args));
const data = notFoundIfNullish(await tournamentDataCached(args));
return new Tournament({ ...data, simulateBrackets: false });
}
@ -122,14 +122,14 @@ export async function tournamentDataCached({
tournamentId: number;
}) {
if (ServerConfig.disableCache) {
return notFoundIfFalsy(await tournamentData({ user, tournamentId }));
return notFoundIfNullish(await tournamentData({ user, tournamentId }));
}
if (!tournamentDataCache.has(tournamentId)) {
tournamentDataCache.set(tournamentId, combinedTournamentData(tournamentId));
}
const data = notFoundIfFalsy(await tournamentDataCache.get(tournamentId));
const data = notFoundIfNullish(await tournamentDataCache.get(tournamentId));
return dataMapped({ user, ...data });
}

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { getUser } from "~/features/auth/core/user.server";
import * as TournamentRepository from "~/features/tournament/TournamentRepository.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { idObject } from "~/utils/zod";
import type { Unwrapped } from "../../../utils/types";
import { tournamentFromDB } from "../core/Tournament.server";
@ -13,7 +13,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
schema: idObject,
});
const divisions = notFoundIfFalsy(await divisionsCached(tournamentId));
const divisions = notFoundIfNullish(await divisionsCached(tournamentId));
return {
divisions,

View File

@ -29,7 +29,7 @@ import invariant from "~/utils/invariant";
import { logger } from "~/utils/logger";
import {
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
parseRequestPayload,
} from "~/utils/remix.server";
@ -57,7 +57,7 @@ export const action: ActionFunction = async ({ params, request }) => {
params,
schema: matchPageParamsSchema,
});
const match = notFoundIfFalsy(
const match = notFoundIfNullish(
await TournamentMatchRepository.findMatchById(matchId),
);

View File

@ -18,7 +18,7 @@ import { cache, IN_MILLISECONDS, ttl } from "~/utils/cache.server";
import { IS_E2E_TEST_RUN } from "~/utils/e2e";
import { logger } from "~/utils/logger";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import { tournamentMatchPage } from "~/utils/urls";
import { executeRoll } from "../core/executeRoll.server";
import { mapListFromResults, resolveMapList } from "../core/mapList.server";
@ -38,7 +38,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
user: undefined,
});
const match = notFoundIfFalsy(
const match = notFoundIfNullish(
await TournamentMatchRepository.findMatchById(matchId),
);

View File

@ -1,6 +1,6 @@
import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { notFoundIfNullish, parseParams } from "~/utils/remix.server";
import * as TournamentOrganizationRepository from "./TournamentOrganizationRepository.server";
const organizationParamsSchema = z.object({
@ -11,7 +11,7 @@ export async function organizationFromParams(
params: LoaderFunctionArgs["params"],
) {
const { slug } = parseParams({ params, schema: organizationParamsSchema });
return notFoundIfFalsy(
return notFoundIfNullish(
await TournamentOrganizationRepository.findBySlug(slug),
);
}

View File

@ -12,7 +12,7 @@ import * as UserRepository from "~/features/user-page/UserRepository.server";
import invariant from "~/utils/invariant";
import {
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
} from "~/utils/remix.server";
import { tournamentPage, tournamentRegisterPage } from "~/utils/urls";
@ -32,7 +32,7 @@ export const action: ActionFunction = async ({ params, url }) => {
const inviteCode = url.searchParams.get("code");
invariant(inviteCode, "code is missing");
const leanTeam = notFoundIfFalsy(
const leanTeam = notFoundIfNullish(
await TournamentTeamRepository.findByInviteCode(inviteCode),
);

View File

@ -1,12 +1,12 @@
import { redirect } from "react-router";
import { notFoundIfFalsy } from "../../../utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { tournamentPage } from "../../../utils/urls";
import { LEAGUES } from "../tournament-constants";
const maybeLatest = LEAGUES.LUTI?.at(-1);
export const loader = () => {
const latest = notFoundIfFalsy(maybeLatest);
const latest = notFoundIfNullish(maybeLatest);
return redirect(tournamentPage(latest.tournamentId));
};

View File

@ -6,7 +6,7 @@ import { adminTabActionSchema } from "~/features/user-page/user-page-schemas";
import { requireRole } from "~/modules/permissions/guards.server";
import {
badRequestIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseRequestPayload,
} from "~/utils/remix.server";
import { assertUnreachable } from "~/utils/types";
@ -21,7 +21,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
schema: adminTabActionSchema,
});
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.findLayoutDataByIdentifier(params.identifier!),
);

View File

@ -6,7 +6,7 @@ import * as UserReportRepository from "~/features/user-report/UserReportReposito
import { requireRole } from "~/modules/permissions/guards.server";
import { databaseTimestampToDate } from "~/utils/dates";
import { logger } from "~/utils/logger";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { convertSnowflakeToDate } from "~/utils/users";
const REPORT_GRAPH_MONTHS = 12;
@ -16,7 +16,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
requireRole("STAFF");
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.findLayoutDataByIdentifier(params.identifier!),
);
@ -24,7 +24,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
`User ${loggedInUser.username} (#${loggedInUser.id}) is viewing admin tab for user ${user.username} (#${user.id})`,
);
const userData = notFoundIfFalsy(
const userData = notFoundIfNullish(
await UserRepository.findModInfoById(user.id),
);

View File

@ -3,14 +3,14 @@ import * as ArtRepository from "~/features/art/ArtRepository.server";
import { getUser } from "~/features/auth/core/user.server";
import * as ImageRepository from "~/features/img-upload/ImageRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { userParamsSchema } from "../user-page-schemas";
export const loader = async ({ params }: LoaderFunctionArgs) => {
const loggedInUser = getUser();
const { identifier } = userParamsSchema.parse(params);
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.identifierToUserId(identifier),
);

View File

@ -4,7 +4,7 @@ import { getUser } from "~/features/auth/core/user.server";
import * as BuildRepository from "~/features/builds/BuildRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy, privatelyCachedJson } from "~/utils/remix.server";
import { notFoundIfNullish, privatelyCachedJson } from "~/utils/remix.server";
import { sortBuilds } from "../core/build-sorting.server";
import { userParamsSchema } from "../user-page-schemas";
@ -13,7 +13,7 @@ export type UserBuildsPageData = SerializeFrom<typeof loader>;
export const loader = async ({ params }: LoaderFunctionArgs) => {
const loggedInUser = getUser();
const { identifier } = userParamsSchema.parse(params);
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.identifierToBuildFields(identifier),
);

View File

@ -1,14 +1,14 @@
import { type LoaderFunctionArgs, redirect } from "react-router";
import { requireUser } from "~/features/auth/core/user.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { userPage } from "~/utils/urls";
import { userParamsSchema } from "../user-page-schemas";
export const loader = async ({ params }: LoaderFunctionArgs) => {
const user = requireUser();
const { identifier } = userParamsSchema.parse(params);
const userToBeEdited = notFoundIfFalsy(
const userToBeEdited = notFoundIfNullish(
await UserRepository.findLayoutDataByIdentifier(identifier),
);
if (user.id !== userToBeEdited.id) {

View File

@ -1,10 +1,10 @@
import type { LoaderFunctionArgs } from "react-router";
import * as UserCardRepository from "~/features/user-card/UserCardRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
export const loader = async ({ params }: LoaderFunctionArgs) => {
const { id: userId } = notFoundIfFalsy(
const { id: userId } = notFoundIfNullish(
await UserRepository.identifierToUserId(params.identifier!),
);
@ -17,14 +17,14 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
if (widgetsEnabled) {
return {
type: "new" as const,
widgets: notFoundIfFalsy(
widgets: notFoundIfNullish(
await UserRepository.widgetsByUserId(params.identifier!),
),
...userCards,
};
}
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.findProfileByIdentifier(params.identifier!),
);

View File

@ -3,7 +3,7 @@ import { getUser } from "~/features/auth/core/user.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import type { SerializeFrom } from "~/utils/remix";
import {
notFoundIfFalsy,
notFoundIfNullish,
parseSafeSearchParams,
redirectIfPageOutOfBounds,
} from "~/utils/remix.server";
@ -21,7 +21,7 @@ export const loader = async ({ params, request, url }: LoaderFunctionArgs) => {
schema: userResultsPageSearchParamsSchema,
});
const userId = notFoundIfFalsy(
const userId = notFoundIfNullish(
await UserRepository.identifierToUserId(params.identifier!),
).id;
const hasHighlightedResults =

View File

@ -4,7 +4,7 @@ import * as LeaderboardRepository from "~/features/leaderboards/LeaderboardRepos
import * as SQMatchRepository from "~/features/sendouq-match/SQMatchRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import {
seasonsSearchParamsSchema,
userParamsSchema,
@ -21,7 +21,7 @@ export const loader = async ({ params, url }: LoaderFunctionArgs) => {
Object.fromEntries(url.searchParams),
);
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.identifierToUserId(identifier),
);
const seasonsParticipatedIn =

View File

@ -7,7 +7,7 @@ import * as PlayerStatRepository from "~/features/sendouq-match/PlayerStatReposi
import * as SQMatchRepository from "~/features/sendouq-match/SQMatchRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import {
seasonsSearchParamsSchema,
userParamsSchema,
@ -24,7 +24,7 @@ export const loader = async ({ params, url }: LoaderFunctionArgs) => {
Object.fromEntries(url.searchParams),
);
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.identifierToUserId(identifier),
);
const seasonsParticipatedIn =

View File

@ -5,7 +5,7 @@ import * as PlayerStatRepository from "~/features/sendouq-match/PlayerStatReposi
import * as ReportedWeaponRepository from "~/features/sendouq-match/ReportedWeaponRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import {
seasonsSearchParamsSchema,
userParamsSchema,
@ -22,7 +22,7 @@ export const loader = async ({ params, url }: LoaderFunctionArgs) => {
Object.fromEntries(url.searchParams),
);
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.identifierToUserId(identifier),
);
const seasonsParticipatedIn =

View File

@ -3,14 +3,14 @@ import { getUser } from "~/features/auth/core/user.server";
import * as FriendRepository from "~/features/friends/FriendRepository.server";
import * as UserRepository from "~/features/user-page/UserRepository.server";
import type { SerializeFrom } from "~/utils/remix";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
export type UserPageLoaderData = SerializeFrom<typeof loader>;
export const loader = async ({ params }: LoaderFunctionArgs) => {
const loggedInUser = getUser();
const user = notFoundIfFalsy(
const user = notFoundIfNullish(
await UserRepository.findLayoutDataByIdentifier(
params.identifier!,
loggedInUser?.id,

View File

@ -4,13 +4,13 @@ import * as VodRepository from "~/features/vods/VodRepository.server";
import { VODS_PAGE_BATCH_SIZE } from "~/features/vods/vods-constants";
import { userVodsSearchParamsSchema } from "~/features/vods/vods-schemas";
import {
notFoundIfFalsy,
notFoundIfNullish,
parseSearchParams,
redirectIfPageOutOfBounds,
} from "~/utils/remix.server";
export const loader = async ({ params, request, url }: LoaderFunctionArgs) => {
const userId = notFoundIfFalsy(
const userId = notFoundIfNullish(
await UserRepository.identifierToUserId(params.identifier!),
).id;

View File

@ -4,7 +4,7 @@ import * as UserRepository from "~/features/user-page/UserRepository.server";
import { parseFormData } from "~/form/parse.server";
import {
errorToastIfFalsy,
notFoundIfFalsy,
notFoundIfNullish,
parseParams,
} from "~/utils/remix.server";
import { sendUserReportWebhook } from "../core/discord-webhook.server";
@ -22,7 +22,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
errorToastIfFalsy(reportedUserId !== user.id, "Can't report yourself");
const reportedUser = notFoundIfFalsy(
const reportedUser = notFoundIfNullish(
await UserRepository.findLeanById(reportedUserId),
);

View File

@ -1,9 +1,9 @@
import type { LoaderFunctionArgs } from "react-router";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import * as VodRepository from "../VodRepository.server";
export const loader = async ({ params }: LoaderFunctionArgs) => {
const vod = notFoundIfFalsy(
const vod = notFoundIfNullish(
await VodRepository.findVodById(Number(params.id)),
);

View File

@ -1,7 +1,7 @@
import type { LoaderFunctionArgs } from "react-router";
import { z } from "zod";
import { requireUser } from "~/features/auth/core/user.server";
import { notFoundIfFalsy } from "~/utils/remix.server";
import { notFoundIfNullish } from "~/utils/remix.server";
import { actualNumber, id } from "~/utils/zod";
import * as VodRepository from "../VodRepository.server";
import { canEditVideo, vodToVideoBeingAdded } from "../vods-utils";
@ -21,7 +21,9 @@ export const loader = async ({ url }: LoaderFunctionArgs) => {
return { vodToEdit: null };
}
const vod = notFoundIfFalsy(await VodRepository.findVodById(params.data.vod));
const vod = notFoundIfNullish(
await VodRepository.findVodById(params.data.vod),
);
const vodToEdit = vodToVideoBeingAdded(vod);
if (

View File

@ -10,15 +10,10 @@ import { ServerConfig } from "~/config.server";
import { logger } from "./logger";
import { currentRequestPathname } from "./request-context.server";
export function notFoundIfFalsy<T>(value: T | null | undefined): T {
if (!value) throw new Response(null, { status: 404 });
return value;
}
export function notFoundIfNullLike<T>(value: T | null | undefined): T {
if (value === null || value === undefined)
export function notFoundIfNullish<T>(value: T | null | undefined): T {
if (value === null || value === undefined) {
throw new Response(null, { status: 404 });
}
return value;
}