Upgrade all deps to latest

This commit is contained in:
Kalle 2023-12-06 12:40:39 +02:00
parent 859fa3fab7
commit 73fd2e4a6c
99 changed files with 6996 additions and 8007 deletions

View File

@ -139,8 +139,8 @@ const canPlaceAbilityAtSlot = (
rowIndex === 0
? "HEAD_MAIN_ONLY"
: rowIndex === 1
? "CLOTHES_MAIN_ONLY"
: "SHOES_MAIN_ONLY";
? "CLOTHES_MAIN_ONLY"
: "SHOES_MAIN_ONLY";
const isMainSlot = abilityIndex === 0;

View File

@ -1,6 +1,6 @@
import { Combobox as HeadlessCombobox } from "@headlessui/react";
import clsx from "clsx";
import Fuse from "fuse.js";
import Fuse, { type IFuseOptions } from "fuse.js";
import * as React from "react";
import type { GearType } from "~/db/types";
import { useAllEventsWithMapPools } from "~/hooks/swr";
@ -55,7 +55,7 @@ interface ComboboxProps<T> {
onChange?: (selectedOption: ComboboxOption<T> | null) => void;
fullWidth?: boolean;
nullable?: true;
fuseOptions?: Fuse.IFuseOptions<ComboboxOption<T>>;
fuseOptions?: IFuseOptions<ComboboxOption<T>>;
}
export function Combobox<
@ -356,8 +356,8 @@ export function GearCombobox({
gearType === "HEAD"
? headGearIds
: gearType === "CLOTHES"
? clothesGearIds
: shoesGearIds;
? clothesGearIds
: shoesGearIds;
const idToGear = (id: (typeof ids)[number]) => ({
value: String(id),

View File

@ -92,8 +92,8 @@ export function WeaponImage({
variant === "badge"
? outlinedMainWeaponImageUrl(weaponSplId)
: variant == "badge-5-star"
? outlinedFiveStarMainWeaponImageUrl(weaponSplId)
: mainWeaponImageUrl(weaponSplId)
? outlinedFiveStarMainWeaponImageUrl(weaponSplId)
: mainWeaponImageUrl(weaponSplId)
}
/>
);

View File

@ -1,4 +1,8 @@
import { useCatch, useLocation } from "@remix-run/react";
import {
useLocation,
useRouteError,
isRouteErrorResponse,
} from "@remix-run/react";
import clsx from "clsx";
import type * as React from "react";
import { useMatches } from "react-router";
@ -21,10 +25,11 @@ export const Main = ({
bigger?: boolean;
style?: React.CSSProperties;
}) => {
const caught = useCatch();
const error = useRouteError();
const data = useMatches()[0]?.data as RootLoaderData | undefined;
const user = useUser();
const showLeaderboard = data?.publisherId && !user?.patronTier && !caught;
const showLeaderboard =
data?.publisherId && !user?.patronTier && !isRouteErrorResponse(error);
const location = useLocation();
const isFrontPage = location.pathname === "/";

View File

@ -1,7 +1,9 @@
import { PassThrough } from "stream";
import type { EntryContext } from "@remix-run/node";
import { Response } from "@remix-run/node";
import {
createReadableStreamFromReadable,
type EntryContext,
} from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import isbot from "isbot";
import { renderToPipeableStream } from "react-dom/server";
@ -54,7 +56,7 @@ const handleBotRequest = (
responseHeaders.set("Content-Type", "text/html");
resolve(
new Response(body, {
new Response(createReadableStreamFromReadable(body), {
headers: responseHeaders,
status: didError ? 500 : responseStatusCode,
}),
@ -98,7 +100,7 @@ const handleBrowserRequest = (
responseHeaders.set("Content-Type", "text/html");
resolve(
new Response(body, {
new Response(createReadableStreamFromReadable(body), {
headers: responseHeaders,
status: didError ? 500 : responseStatusCode,
}),

View File

@ -1,10 +1,15 @@
import type {
ActionArgs,
ActionFunctionArgs,
LoaderFunction,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import { json, redirect } from "@remix-run/node";
import { useFetcher, useLoaderData, useNavigation } from "@remix-run/react";
import {
Form,
useFetcher,
useLoaderData,
useNavigation,
} from "@remix-run/react";
import * as React from "react";
import { Button } from "~/components/Button";
import { Catcher } from "~/components/Catcher";
@ -31,11 +36,11 @@ import { SEED_URL, STOP_IMPERSONATING_URL, impersonateUrl } from "~/utils/urls";
import { adminActionSchema } from "../admin-schemas.server";
import { plusTiersFromVotingAndLeaderboard } from "../core/plus-tier.server";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("Admin page") }];
};
export const action = async ({ request }: ActionArgs) => {
export const action = async ({ request }: ActionFunctionArgs) => {
const data = await parseRequestFormData({
request,
schema: adminActionSchema,
@ -151,12 +156,11 @@ export default function AdminPage() {
}
function Impersonate() {
const fetcher = useFetcher();
const [userId, setUserId] = React.useState<number>();
const { isImpersonating } = useLoaderData<AdminPageLoaderData>();
return (
<fetcher.Form
<Form
method="post"
action={impersonateUrl(userId ?? 0)}
className="stack md"
@ -180,7 +184,7 @@ function Impersonate() {
</Button>
) : null}
</div>
</fetcher.Form>
</Form>
);
}
@ -194,8 +198,8 @@ function MigrateUser() {
navigation.state === "submitting"
? "Migrating..."
: navigation.state === "loading"
? "Migrated!"
: "Migrate";
? "Migrated!"
: "Migrate";
return (
<fetcher.Form className="stack md" method="post">

View File

@ -1,4 +1,4 @@
import type { ActionFunction, LoaderArgs } from "@remix-run/node";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/node";
import { getUserId } from "~/features/auth/core/user.server";
import { updatePatreonData } from "~/modules/patreon";
import { canAccessLohiEndpoint, canPerformAdminActions } from "~/permissions";
@ -17,7 +17,7 @@ export const action: ActionFunction = async ({ request }) => {
return null;
};
export const loader = ({ request }: LoaderArgs) => {
export const loader = ({ request }: LoaderFunctionArgs) => {
validate(canAccessLohiEndpoint(request), "Invalid token", 403);
return UserRepository.findAllPatrons();

View File

@ -1,4 +1,4 @@
import type { ActionFunction, LoaderArgs } from "@remix-run/node";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/node";
import {
unstable_composeUploadHandlers as composeUploadHandlers,
unstable_createMemoryUploadHandler as createMemoryUploadHandler,
@ -114,7 +114,7 @@ export const action: ActionFunction = async ({ request }) => {
throw redirect(userArtPage(user));
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await requireUser(request);
validate(user.isArtist, "Lacking artist role", 403);

View File

@ -1,7 +1,7 @@
import type {
LoaderArgs,
LoaderFunctionArgs,
SerializeFrom,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import type { ShouldRevalidateFunction } from "@remix-run/react";
import { useLoaderData, useSearchParams } from "@remix-run/react";
@ -44,7 +44,7 @@ export const handle: SendouRouteHandle = {
}),
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -52,7 +52,7 @@ export const meta: V2_MetaFunction = (args) => {
return [{ title: data.title }];
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const t = await i18next.getFixedT(request);
const allTags = allArtTags();

View File

@ -3,8 +3,8 @@ import { Main } from "~/components/Main";
import {
json,
type SerializeFrom,
type LoaderArgs,
type V2_MetaFunction,
type LoaderFunctionArgs,
type MetaFunction,
} from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import * as React from "react";
@ -41,7 +41,7 @@ export const handle: SendouRouteHandle = {
},
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
invariant(args.params["slug"]);
const data = args.data as SerializeFrom<typeof loader> | null;
@ -61,7 +61,7 @@ export const meta: V2_MetaFunction = (args) => {
];
};
export const loader = ({ params }: LoaderArgs) => {
export const loader = ({ params }: LoaderFunctionArgs) => {
invariant(params["slug"]);
const article = notFoundIfFalsy(articleBySlug(params["slug"]));

View File

@ -1,4 +1,4 @@
import type { LoaderArgs, SerializeFrom } from "@remix-run/node";
import type { LoaderFunctionArgs, SerializeFrom } from "@remix-run/node";
import { Outlet, useLoaderData, useMatches, useParams } from "@remix-run/react";
import clsx from "clsx";
import { Badge } from "~/components/Badge";
@ -9,17 +9,17 @@ import { useUser } from "~/features/auth/core";
import { canEditBadgeOwners, isMod } from "~/permissions";
import { BADGES_PAGE } from "~/utils/urls";
import { type BadgesLoaderData } from "./badges";
import { type TFunction } from "react-i18next";
import { useTranslation } from "~/hooks/useTranslation";
import { SPLATOON_3_XP_BADGE_VALUES } from "~/constants";
import * as BadgeRepository from "../BadgeRepository.server";
import type { TFunction } from "i18next";
export interface BadgeDetailsContext {
badgeName: string;
}
export type BadgeDetailsLoaderData = SerializeFrom<typeof loader>;
export const loader = async ({ params }: LoaderArgs) => {
export const loader = async ({ params }: LoaderFunctionArgs) => {
const badgeId = Number(params["id"]);
if (Number.isNaN(badgeId)) {
throw new Response(null, { status: 404 });

View File

@ -799,8 +799,8 @@ function runSpeed(args: StatFunctionInput): AnalyzedBuild["stats"]["runSpeed"] {
args.mainWeaponParams.WeaponSpeedType === "Fast"
? "_Fast"
: args.mainWeaponParams.WeaponSpeedType === "Slow"
? "_Slow"
: "";
? "_Slow"
: "";
const RUN_SPEED_ABILITY = "RSU";
const { baseEffect, effect } = abilityPointsToEffects({
abilityPoints: apFromMap({
@ -874,8 +874,8 @@ function swimSpeed(
args.mainWeaponParams.WeaponSpeedType === "Fast"
? "_Fast"
: args.mainWeaponParams.WeaponSpeedType === "Slow"
? "_Slow"
: "";
? "_Slow"
: "";
const SWIM_SPEED_ABILITY = "SSU";
const { baseEffect, effect } = abilityPointsToEffects({
abilityPoints: apFromMap({

View File

@ -1,4 +1,4 @@
import { type LinksFunction, type V2_MetaFunction } from "@remix-run/node";
import { type LinksFunction, type MetaFunction } from "@remix-run/node";
import type { ShouldRevalidateFunction } from "@remix-run/react";
import { Link } from "@remix-run/react";
import clsx from "clsx";
@ -80,7 +80,7 @@ import invariant from "tiny-invariant";
export const CURRENT_PATCH = "6.0";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [
{ title: makeTitle("Build Analyzer") },
{
@ -974,11 +974,11 @@ function StatChart({
mainWeaponId,
})
: typeof subWeaponId === "number"
? subDefenseGraphOptions({
subWeaponId,
distanceLabel,
})
: [];
? subDefenseGraphOptions({
subWeaponId,
distanceLabel,
})
: [];
}, [statKey, modifiedBy, mainWeaponId, subWeaponId, distanceLabel]);
// prevent crash but this should not happen
@ -1417,8 +1417,8 @@ function StatCard({
{typeof stat === "number"
? t("value")
: showComparison
? t("build1")
: t("base")}
? t("build1")
: t("base")}
</h4>{" "}
<div
className="analyzer__stat-card__value__number"

View File

@ -1,6 +1,6 @@
import type {
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
@ -24,7 +24,7 @@ import { abilitiesByWeaponId } from "../queries/abilitiesByWeaponId.server";
import { cache, ttl } from "~/utils/cache.server";
import { ONE_HOUR_IN_MS } from "~/constants";
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -59,7 +59,7 @@ export const handle: SendouRouteHandle = {
},
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const t = await i18next.getFixedT(request, ["builds", "weapons", "common"]);
const slug = params["slug"];
const weaponId = notFoundIfNullLike(weaponNameSlugToId(slug));

View File

@ -1,7 +1,7 @@
import type {
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
@ -26,7 +26,7 @@ import { makeTitle } from "~/utils/strings";
import { cache, ttl } from "~/utils/cache.server";
import { cachified } from "cachified";
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -65,7 +65,7 @@ export const handle: SendouRouteHandle = {
},
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const t = await i18next.getFixedT(request, ["builds", "weapons", "common"]);
const weaponId = notFoundIfNullLike(weaponNameSlugToId(params["slug"]));

View File

@ -1,7 +1,7 @@
import {
type LoaderArgs,
type LoaderFunctionArgs,
type SerializeFrom,
type V2_MetaFunction,
type MetaFunction,
} from "@remix-run/node";
import {
type ShouldRevalidateFunction,
@ -111,7 +111,7 @@ export const shouldRevalidate: ShouldRevalidateFunction = (args) => {
return args.defaultShouldRevalidate;
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -141,7 +141,7 @@ export const handle: SendouRouteHandle = {
},
};
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const t = await i18next.getFixedT(request, ["weapons", "common"], {
lng: "en",
});

View File

@ -13,12 +13,12 @@ import {
} from "~/utils/urls";
import { type SendouRouteHandle } from "~/utils/remix";
import styles from "~/styles/builds.css";
import type { LinksFunction, V2_MetaFunction } from "@remix-run/node";
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import { Main } from "~/components/Main";
import { makeTitle } from "~/utils/strings";
import { useSetTitle } from "~/hooks/useSetTitle";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [
{ title: makeTitle("Builds") },
{

View File

@ -2,7 +2,7 @@ import { json, redirect } from "@remix-run/node";
import type {
SerializeFrom,
ActionFunction,
LoaderArgs,
LoaderFunctionArgs,
} from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
import clsx from "clsx";
@ -141,7 +141,7 @@ export const handle: SendouRouteHandle = {
i18n: "calendar",
};
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const parsedParams = reportWinnersParamsSchema.parse(params);
const user = await requireUserId(request);
const event = notFoundIfFalsy(

View File

@ -3,8 +3,8 @@ import type {
ActionFunction,
SerializeFrom,
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
} from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { Link } from "@remix-run/react/dist/components";
@ -87,7 +87,7 @@ export const links: LinksFunction = () => {
];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader>;
if (!data) return [];
@ -120,7 +120,7 @@ export const handle: SendouRouteHandle = {
},
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const t = await i18next.getFixedT(request);
const parsedParams = z
.object({ id: z.preprocess(actualNumber, id) })

View File

@ -3,8 +3,8 @@ import type {
SerializeFrom,
ActionFunction,
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
} from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
import clsx from "clsx";
@ -85,7 +85,7 @@ export const links: LinksFunction = () => {
];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -208,7 +208,7 @@ export const handle: SendouRouteHandle = {
i18n: ["calendar", "game-misc"],
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const t = await i18next.getFixedT(request);
const user = await requireUser(request);
const url = new URL(request.url);

View File

@ -1,7 +1,7 @@
import { json } from "@remix-run/node";
import type {
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
LinksFunction,
} from "@remix-run/node";
@ -50,7 +50,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -82,7 +82,7 @@ const loaderSearchParamsSchema = z.object({
year: z.preprocess(actualNumber, z.number().int()),
});
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUserId(request);
const t = await i18next.getFixedT(request);
const url = new URL(request.url);
@ -269,10 +269,10 @@ function WeekLinkTitle({
week.number === data.currentWeek && isSameYear
? t("week.this")
: week.number - data.currentWeek === 1 && isSameYear
? t("week.next")
: week.number - data.currentWeek === -1 && isSameYear
? t("week.last")
: null;
? t("week.next")
: week.number - data.currentWeek === -1 && isSameYear
? t("week.last")
: null;
if (relativeWeekIdentifier) {
return (

View File

@ -1,4 +1,4 @@
import type { ActionFunction, LoaderArgs } from "@remix-run/node";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
import { Main } from "~/components/Main";
import { SubmitButton } from "~/components/SubmitButton";
@ -25,7 +25,7 @@ export const action: ActionFunction = async ({ request }) => {
return null;
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await requireUserId(request);
notFoundIfFalsy(isMod(user));

View File

@ -1,4 +1,8 @@
import type { ActionArgs, LoaderArgs, UploadHandler } from "@remix-run/node";
import type {
ActionFunctionArgs,
LoaderFunctionArgs,
UploadHandler,
} from "@remix-run/node";
import {
redirect,
unstable_composeUploadHandlers as composeUploadHandlers,
@ -30,7 +34,7 @@ import { requestToImgType } from "../upload-utils";
import { findByIdentifier, isTeamOwner } from "~/features/team";
import * as TeamRepository from "~/features/team/TeamRepository.server";
export const action = async ({ request }: ActionArgs) => {
export const action = async ({ request }: ActionFunctionArgs) => {
const user = await requireUser(request);
const team = await TeamRepository.findByUserId(user.id);
@ -81,7 +85,7 @@ export const action = async ({ request }: ActionArgs) => {
return null;
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await requireUser(request);
const team = await TeamRepository.findByUserId(user.id);
const validatedType = requestToImgType(request);

View File

@ -4,10 +4,7 @@ import { PassThrough } from "stream";
import type AWS from "aws-sdk";
import { Upload } from "@aws-sdk/lib-storage";
import {
type CompleteMultipartUploadCommandOutput,
S3,
} from "@aws-sdk/client-s3";
import { S3 } from "@aws-sdk/client-s3";
import type { UploadHandler } from "@remix-run/node";
import { writeAsyncIterableToWritable } from "@remix-run/node";
import { nanoid } from "nanoid";
@ -77,7 +74,7 @@ export async function uploadStreamToS3(data: any, filename: string) {
});
await writeAsyncIterableToWritable(data, stream.writeStream);
const file = await stream.promise;
return (file as CompleteMultipartUploadCommandOutput).Location;
return file.Location;
}
// predeciding file name is useful when you are uploading more than one asset

View File

@ -1,4 +1,4 @@
import type { V2_MetaFunction } from "@remix-run/node";
import type { MetaFunction } from "@remix-run/node";
import { Trans } from "react-i18next";
import { Main } from "~/components/Main";
import { useSetTitle } from "~/hooks/useSetTitle";
@ -19,7 +19,7 @@ import { type SendouRouteHandle } from "~/utils/remix";
import { useTranslation } from "~/hooks/useTranslation";
import * as React from "react";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("Contributions") }];
};

View File

@ -1,4 +1,4 @@
import type { LinksFunction, V2_MetaFunction } from "@remix-run/node";
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import { useTranslation } from "~/hooks/useTranslation";
import { Main } from "~/components/Main";
import { useSetTitle } from "~/hooks/useSetTitle";
@ -8,7 +8,7 @@ import { type SendouRouteHandle } from "~/utils/remix";
const AMOUNT_OF_QUESTIONS = 9;
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [
{ title: makeTitle("FAQ") },
{ name: "description", content: "Frequently asked questions" },

View File

@ -1,8 +1,8 @@
import type { V2_MetaFunction } from "@remix-run/node";
import type { MetaFunction } from "@remix-run/node";
import { Main } from "~/components/Main";
import { makeTitle } from "~/utils/strings";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("Privacy Policy") }];
};

View File

@ -1,4 +1,4 @@
import type { LinksFunction, V2_MetaFunction } from "@remix-run/node";
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import { Main } from "~/components/Main";
import styles from "../support.css";
import * as React from "react";
@ -15,7 +15,7 @@ import { Trans } from "react-i18next";
import { makeTitle } from "~/utils/strings";
import { useSetTitle } from "~/hooks/useSetTitle";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("Support") }];
};

View File

@ -1,8 +1,8 @@
import type {
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
V2_MetaFunction,
} from "@remix-run/node";
import { Link, useLoaderData, useSearchParams } from "@remix-run/react";
import { Avatar } from "~/components/Avatar";
@ -74,7 +74,7 @@ export const handle: SendouRouteHandle = {
}),
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -96,7 +96,7 @@ export const links: LinksFunction = () => {
const TYPE_SEARCH_PARAM_KEY = "type";
const SEASON_SEARCH_PARAM_KEY = "season";
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUser(request);
const t = await i18next.getFixedT(request);
const unvalidatedType = new URL(request.url).searchParams.get(
@ -181,10 +181,10 @@ export const loader = async ({ request }: LoaderArgs) => {
type === "XP-ALL"
? allXPLeaderboard()
: type.startsWith("XP-MODE")
? modeXPLeaderboard(type.split("-")[2] as RankedModeShort)
: type.startsWith("XP-WEAPON")
? weaponXPLeaderboard(Number(type.split("-")[2]) as MainWeaponId)
: null,
? modeXPLeaderboard(type.split("-")[2] as RankedModeShort)
: type.startsWith("XP-WEAPON")
? weaponXPLeaderboard(Number(type.split("-")[2]) as MainWeaponId)
: null,
title: makeTitle(t("pages.leaderboards")),
season,
};

View File

@ -1,7 +1,7 @@
import type {
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import type { ShouldRevalidateFunction } from "@remix-run/react";
@ -48,7 +48,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -65,7 +65,7 @@ export const handle: SendouRouteHandle = {
}),
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUserId(request);
const url = new URL(request.url);
const calendarEventId = url.searchParams.get("eventId");

View File

@ -1,5 +1,5 @@
import { lazy } from "react";
import type { LinksFunction, V2_MetaFunction } from "@remix-run/node";
import type { LinksFunction, MetaFunction } from "@remix-run/node";
import styles from "../plans.css";
import type { SendouRouteHandle } from "~/utils/remix";
import { useIsMounted } from "~/hooks/useIsMounted";
@ -8,7 +8,7 @@ import { makeTitle } from "~/utils/strings";
import { useTranslation } from "~/hooks/useTranslation";
import { useSetTitle } from "~/hooks/useSetTitle";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [
{ title: makeTitle("Planner") },
{

View File

@ -30,8 +30,8 @@ export function useObjectDamage() {
anyWeapon.type === "MAIN"
? anyWeapon.id
: anyWeapon.type === "SPECIAL"
? exampleMainWeaponIdWithSpecialWeaponId(anyWeapon.id)
: 0,
? exampleMainWeaponIdWithSpecialWeaponId(anyWeapon.id)
: 0,
hasTacticooler: false,
});

View File

@ -47,8 +47,8 @@ function calculate({
typeof subWeaponId === "number"
? { type: "SUB", id: subWeaponId }
: typeof specialWeaponId === "number"
? { type: "SPECIAL", id: specialWeaponId }
: { type: "MAIN", id: mainWeaponId },
? { type: "SPECIAL", id: specialWeaponId }
: { type: "MAIN", id: mainWeaponId },
damageType,
isMultiShot: true,
});

View File

@ -131,8 +131,8 @@ export function resolveAllUniqueDamageTypes({
anyWeapon.type === "SUB"
? []
: anyWeapon.type === "SPECIAL"
? analyzed.stats.specialWeaponDamages.map((d) => d.type)
: analyzed.stats.damages.map((d) => d.type);
? analyzed.stats.specialWeaponDamages.map((d) => d.type)
: analyzed.stats.damages.map((d) => d.type);
return removeDuplicates(damageTypes).filter(
(dmg) => !dmg.includes("SECONDARY"),

View File

@ -1,7 +1,7 @@
import type {
ActionFunction,
SerializeFrom,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import type { ShouldRevalidateFunction } from "@remix-run/react";
import { Link, Outlet, useLoaderData, useSearchParams } from "@remix-run/react";
@ -36,7 +36,7 @@ import { assertUnreachable } from "~/utils/types";
import { userPage } from "~/utils/urls";
import { _action, actualNumber } from "~/utils/zod";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [
{ title: makeTitle("Plus Server suggestions") },
{

View File

@ -1,8 +1,8 @@
import type {
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
SerializeFrom,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import { Link, useLoaderData } from "@remix-run/react";
import clsx from "clsx";
@ -21,7 +21,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader>;
if (!data) return [];
@ -37,7 +37,7 @@ export const meta: V2_MetaFunction = (args) => {
];
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUser(request);
const results = await PlusVotingRepository.resultsByMonthYear(
lastCompletedVoting(new Date()),

View File

@ -1,7 +1,7 @@
import type {
ActionFunction,
LoaderFunction,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import { json } from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
@ -30,7 +30,7 @@ import { dateToDatabaseTimestamp } from "~/utils/dates";
import invariant from "tiny-invariant";
import { isVotingActive } from "~/features/plus-voting/core/voting-time";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("Plus Server voting") }];
};

View File

@ -90,8 +90,8 @@ function Sentiment({
sentimentRadio === "POSITIVE"
? "PREFER"
: sentimentRadio === "NEGATIVE"
? "AVOID"
: undefined,
? "AVOID"
: undefined,
)}
alt=""
width={18}

View File

@ -1,5 +1,9 @@
import { RadioGroup } from "@headlessui/react";
import type { ActionArgs, LinksFunction, LoaderArgs } from "@remix-run/node";
import type {
ActionFunctionArgs,
LinksFunction,
LoaderFunctionArgs,
} from "@remix-run/node";
import { useFetcher, useLoaderData } from "@remix-run/react";
import clsx from "clsx";
import * as React from "react";
@ -60,7 +64,7 @@ export const handle: SendouRouteHandle = {
],
};
export const action = async ({ request }: ActionArgs) => {
export const action = async ({ request }: ActionFunctionArgs) => {
const user = await requireUserId(request);
const data = await parseRequestFormData({
request,
@ -105,7 +109,7 @@ export const action = async ({ request }: ActionArgs) => {
return { ok: true };
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await requireUserId(request);
return {

View File

@ -149,12 +149,12 @@ export function GroupCard({
{action === "MATCH_UP"
? t("q:looking.groups.actions.startMatch")
: action === "LIKE" && !group.members
? t("q:looking.groups.actions.challenge")
: action === "LIKE"
? t("q:looking.groups.actions.invite")
: action === "GROUP_UP"
? t("q:looking.groups.actions.groupUp")
: t("q:looking.groups.actions.undo")}
? t("q:looking.groups.actions.challenge")
: action === "LIKE"
? t("q:looking.groups.actions.invite")
: action === "GROUP_UP"
? t("q:looking.groups.actions.groupUp")
: t("q:looking.groups.actions.undo")}
</SubmitButton>
</fetcher.Form>
) : null}
@ -639,8 +639,8 @@ function VoiceChatInfo({
member.vc === "YES"
? MicrophoneIcon
: member.vc === "LISTEN_ONLY"
? SpeakerIcon
: SpeakerXIcon;
? SpeakerIcon
: SpeakerXIcon;
const color = () => {
const languagesMatch =
@ -655,8 +655,8 @@ function VoiceChatInfo({
return member.vc === "YES"
? "text-success"
: member.vc === "LISTEN_ONLY"
? "text-warning"
: "text-error";
? "text-warning"
: "text-error";
};
const languageToFull = (code: string) =>

View File

@ -97,8 +97,8 @@ export function weaponUsageStats({
row.weaponUserId === userId
? "SELF"
: row.weaponUserGroupId === row.ownerGroupId
? "MATE"
: "ENEMY";
? "MATE"
: "ENEMY";
const won = () => {
const targetWon = row.winnerGroupId === row.ownerGroupId;

View File

@ -1,8 +1,8 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
} from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { useFetcher, useLoaderData, useSearchParams } from "@remix-run/react";
@ -93,7 +93,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("SendouQ") }];
};
@ -384,7 +384,7 @@ export const action: ActionFunction = async ({ request }) => {
return null;
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUser(request);
const currentGroup = user ? findCurrentGroupByUserId(user.id) : undefined;

View File

@ -1,9 +1,9 @@
import type {
ActionArgs,
ActionFunctionArgs,
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
SerializeFrom,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import { redirect } from "@remix-run/node";
import type { FetcherWithComponents } from "@remix-run/react";
@ -103,7 +103,7 @@ import { NewTabs } from "~/components/NewTabs";
import { Alert } from "~/components/Alert";
import cachified from "cachified";
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -136,7 +136,7 @@ export const handle: SendouRouteHandle = {
}),
};
export const action = async ({ request, params }: ActionArgs) => {
export const action = async ({ request, params }: ActionFunctionArgs) => {
const matchId = matchIdFromParams(params);
const user = await requireUser(request);
const data = await parseRequestFormData({
@ -382,7 +382,7 @@ export const action = async ({ request, params }: ActionArgs) => {
return null;
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const user = await getUserId(request);
const matchId = matchIdFromParams(params);
const match = notFoundIfFalsy(await QMatchRepository.findById(matchId));
@ -448,8 +448,8 @@ export const loader = async ({ params, request }: LoaderArgs) => {
groupMemberOf: isTeamAlphaMember
? ("ALPHA" as const)
: isTeamBravoMember
? ("BRAVO" as const)
: null,
? ("BRAVO" as const)
: null,
reportedWeapons: match.reportedAt
? reportedWeaponsToArrayOfArrays({
groupAlpha,
@ -485,8 +485,8 @@ export default function QMatchPage() {
const ownGroup = data.groupAlpha.members.some((m) => m.id === user?.id)
? data.groupAlpha
: data.groupBravo.members.some((m) => m.id === user?.id)
? data.groupBravo
: null;
? data.groupBravo
: null;
const ownTeamReported = Boolean(
data.match.reportedByUserId &&

View File

@ -1,8 +1,8 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
} from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { useFetcher, useLoaderData } from "@remix-run/react";
@ -51,7 +51,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("SendouQ") }];
};
@ -111,7 +111,7 @@ export const action: ActionFunction = async ({ request }) => {
}
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUser(request);
const currentGroup = user ? findCurrentGroupByUserId(user.id) : undefined;

View File

@ -1,8 +1,8 @@
import type { V2_MetaFunction } from "@remix-run/react";
import type { MetaFunction } from "@remix-run/react";
import { Main } from "~/components/Main";
import { makeTitle } from "~/utils/strings";
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [{ title: makeTitle("SendouQ Rules") }];
};

View File

@ -1,9 +1,9 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
SerializeFrom,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { Link, useFetcher, useLoaderData } from "@remix-run/react";
@ -74,7 +74,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [
{ title: makeTitle("SendouQ") },
{
@ -148,7 +148,7 @@ export const action: ActionFunction = async ({ request }) => {
}
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUserId(request);
const code = new URL(request.url).searchParams.get(

View File

@ -1,11 +1,11 @@
import type { LoaderArgs, SerializeFrom } from "@remix-run/node";
import type { LoaderFunctionArgs, SerializeFrom } from "@remix-run/node";
import { parseSearchParams } from "~/utils/remix";
import { weaponUsageSearchParamsSchema } from "../q-schemas.server";
import { weaponUsageStats } from "../queries/weaponUsageStats.server";
export type WeaponUsageLoaderData = SerializeFrom<typeof loader>;
export const loader = ({ request }: LoaderArgs) => {
export const loader = ({ request }: LoaderFunctionArgs) => {
const data = parseSearchParams({
request,
schema: weaponUsageSearchParamsSchema,

View File

@ -1,10 +1,10 @@
import { redirect } from "@remix-run/node";
import type {
LinksFunction,
V2_MetaFunction,
MetaFunction,
SerializeFrom,
ActionFunction,
LoaderArgs,
LoaderFunctionArgs,
} from "@remix-run/node";
import { Form, Link, useLoaderData } from "@remix-run/react";
import * as React from "react";
@ -46,11 +46,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = ({
data,
}: {
data: SerializeFrom<typeof loader>;
}) => {
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [];
return [{ title: makeTitle(data.team.name) }];
@ -122,7 +118,7 @@ export const action: ActionFunction = async ({ request, params }) => {
}
};
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUserId(request);
const { customUrl } = teamParamsSchema.parse(params);

View File

@ -1,7 +1,7 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
} from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
@ -61,7 +61,7 @@ export const handle: SendouRouteHandle = {
i18n: ["team"],
};
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUser(request);
const { customUrl } = teamParamsSchema.parse(params);

View File

@ -1,10 +1,10 @@
import { redirect } from "@remix-run/node";
import type {
LinksFunction,
V2_MetaFunction,
MetaFunction,
SerializeFrom,
ActionFunction,
LoaderArgs,
LoaderFunctionArgs,
} from "@remix-run/node";
import { Form, useFetcher, useLoaderData } from "@remix-run/react";
import clsx from "clsx";
@ -45,11 +45,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = ({
data,
}: {
data: SerializeFrom<typeof loader>;
}) => {
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [];
return [{ title: makeTitle(data.team.name) }];
@ -124,7 +120,7 @@ export const handle: SendouRouteHandle = {
},
};
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUserId(request);
const { customUrl } = teamParamsSchema.parse(params);

View File

@ -1,8 +1,8 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { Link, useLoaderData } from "@remix-run/react";
@ -48,11 +48,7 @@ import {
} from "../team-utils";
import styles from "../team.css";
export const meta: V2_MetaFunction = ({
data,
}: {
data: SerializeFrom<typeof loader>;
}) => {
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [];
return [
@ -103,7 +99,7 @@ export const handle: SendouRouteHandle = {
},
};
export const loader = ({ params }: LoaderArgs) => {
export const loader = ({ params }: LoaderFunctionArgs) => {
const { customUrl } = teamParamsSchema.parse(params);
const { team, css } = notFoundIfFalsy(findByIdentifier(customUrl));

View File

@ -1,9 +1,8 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
V2_MetaFunction,
SerializeFrom,
LoaderFunctionArgs,
MetaFunction,
} from "@remix-run/node";
import { redirect } from "@remix-run/node";
import {
@ -44,11 +43,7 @@ import styles from "../team.css";
import { usePagination } from "~/hooks/usePagination";
import { Pagination } from "~/components/Pagination";
export const meta: V2_MetaFunction = ({
data,
}: {
data: SerializeFrom<typeof loader>;
}) => {
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [];
return [{ title: data.title }];
@ -100,7 +95,7 @@ export const handle: SendouRouteHandle = {
}),
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUserId(request);
const t = await i18next.getFixedT(request);

View File

@ -1,7 +1,7 @@
import type {
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { Link, useLoaderData } from "@remix-run/react";
@ -48,7 +48,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -62,7 +62,7 @@ export const meta: V2_MetaFunction = (args) => {
];
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const placements = notFoundIfFalsy(
findPlacementsByPlayerId(Number(params["id"])),
);

View File

@ -1,7 +1,7 @@
import type {
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { useLoaderData, useSearchParams } from "@remix-run/react";
@ -34,7 +34,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -45,7 +45,7 @@ export const meta: V2_MetaFunction = (args) => {
];
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const availableMonthYears = monthYears();
const { month: latestMonth, year: latestYear } = availableMonthYears[0]!;

View File

@ -1,11 +1,11 @@
import type { LoaderArgs } from "@remix-run/node";
import { eventStream } from "remix-utils";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { eventStream } from "remix-utils/sse/server";
import { emitter } from "../core/emitters.server";
import { bracketSubscriptionKey } from "../tournament-bracket-utils";
import { tournamentIdFromParams } from "~/features/tournament";
export const loader = ({ request, params }: LoaderArgs) => {
export const loader = ({ request, params }: LoaderFunctionArgs) => {
const tournamentId = tournamentIdFromParams(params);
return eventStream(request.signal, (send) => {

View File

@ -1,7 +1,7 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
SerializeFrom,
} from "@remix-run/node";
import {
@ -51,7 +51,7 @@ import {
resolveTournamentStageType,
} from "../tournament-bracket-utils";
import { sql } from "~/db/sql";
import { useEventSource } from "remix-utils";
import { useEventSource } from "remix-utils/sse/react";
import { Status } from "~/db/types";
import clsx from "clsx";
import { Button, LinkButton } from "~/components/Button";
@ -216,7 +216,7 @@ export const action: ActionFunction = async ({ params, request }) => {
export type TournamentBracketLoaderData = SerializeFrom<typeof loader>;
export const loader = ({ params }: LoaderArgs) => {
export const loader = ({ params }: LoaderFunctionArgs) => {
const tournamentId = tournamentIdFromParams(params);
const hasStarted = hasTournamentStarted(tournamentId);

View File

@ -1,5 +1,5 @@
import type { LoaderArgs } from "@remix-run/node";
import { eventStream } from "remix-utils";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { eventStream } from "remix-utils/sse/server";
import { emitter } from "../core/emitters.server";
import {
@ -8,7 +8,7 @@ import {
} from "../tournament-bracket-utils";
import { getUserId } from "~/features/auth/core/user.server";
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const loggedInUser = await getUserId(request);
const matchId = matchIdFromParams(params);

View File

@ -1,7 +1,7 @@
import type {
ActionFunction,
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
} from "@remix-run/node";
import {
Link,
@ -12,7 +12,7 @@ import {
import clsx from "clsx";
import { nanoid } from "nanoid";
import * as React from "react";
import { useEventSource } from "remix-utils";
import { useEventSource } from "remix-utils/sse/react";
import invariant from "tiny-invariant";
import { Avatar } from "~/components/Avatar";
import { LinkButton } from "~/components/Button";
@ -291,7 +291,7 @@ export const action: ActionFunction = async ({ params, request }) => {
export type TournamentMatchLoaderData = typeof loader;
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const user = await getUserId(request);
const tournamentId = tournamentIdFromParams(params);
const matchId = matchIdFromParams(params);
@ -379,8 +379,8 @@ export default function TournamentMatchPage() {
})
? "EDIT"
: isMemberOfATeam
? "MEMBER"
: "OTHER";
? "MEMBER"
: "OTHER";
const showRosterPeek = () => {
if (matchIsOver) return false;

View File

@ -152,8 +152,8 @@ export function HACKY_resolvePoolCode({
const prefix = event.name.includes("In The Zone")
? "ITZ"
: HACKY_isInviteOnlyEvent(event)
? "SQ"
: "PN";
? "SQ"
: "PN";
const lastDigit = hostingTeamId % 10;
return { prefix, lastDigit };

View File

@ -2,7 +2,7 @@ import {
redirect,
type ActionFunction,
type LinksFunction,
type LoaderArgs,
type LoaderFunctionArgs,
} from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
import React from "react";
@ -61,7 +61,7 @@ export const action: ActionFunction = async ({ params, request }) => {
throw redirect(tournamentSubsPage(tournamentId));
};
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const user = await requireUser(request);
const tournamentId = tournamentIdFromParams(params);

View File

@ -10,7 +10,7 @@ import {
redirect,
type ActionFunction,
type LinksFunction,
type LoaderArgs,
type LoaderFunctionArgs,
} from "@remix-run/node";
import { Link, useLoaderData, useOutletContext } from "@remix-run/react";
import { getUser, requireUser, useUser } from "~/features/auth/core";
@ -54,7 +54,7 @@ export const action: ActionFunction = async ({ request, params }) => {
return null;
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const user = await getUser(request);
const tournamentId = tournamentIdFromParams(params);

View File

@ -1,9 +1,9 @@
import { redirect, type LoaderArgs } from "@remix-run/node";
import { redirect, type LoaderFunctionArgs } from "@remix-run/node";
import { tournamentBracketsPage, tournamentRegisterPage } from "~/utils/urls";
import hasTournamentStarted from "../queries/hasTournamentStarted.server";
import { tournamentIdFromParams } from "../tournament-utils";
export const loader = ({ params }: LoaderArgs) => {
export const loader = ({ params }: LoaderFunctionArgs) => {
const eventId = tournamentIdFromParams(params);
if (!hasTournamentStarted(eventId)) {

View File

@ -1,4 +1,4 @@
import type { ActionFunction, LoaderArgs } from "@remix-run/node";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { Form, useLoaderData, useOutletContext } from "@remix-run/react";
import invariant from "tiny-invariant";
@ -66,10 +66,10 @@ export const action: ActionFunction = async ({ request, params }) => {
const whatToDoWithPreviousTeam = !previousTeam
? undefined
: previousTeam.members.some(
(member) => member.userId === user.id && member.isOwner,
)
? "DELETE"
: "LEAVE";
(member) => member.userId === user.id && member.isOwner,
)
? "DELETE"
: "LEAVE";
joinTeam({
userId: user.id,
@ -97,7 +97,7 @@ export const action: ActionFunction = async ({ request, params }) => {
throw redirect(tournamentPage(leanTeam.tournamentId));
};
export const loader = ({ request, params }: LoaderArgs) => {
export const loader = ({ request, params }: LoaderFunctionArgs) => {
const tournamentId = tournamentIdFromParams(params);
const url = new URL(request.url);
const inviteCode = url.searchParams.get("code");

View File

@ -1,4 +1,4 @@
import type { LinksFunction, LoaderArgs } from "@remix-run/node";
import type { LinksFunction, LoaderFunctionArgs } from "@remix-run/node";
import { redirect } from "@remix-run/node";
import {
useActionData,
@ -48,7 +48,7 @@ type TeamInState = {
mapPool?: Pick<MapPoolMap, "mode" | "stageId">[];
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const tournamentId = tournamentIdFromParams(params);
const user = await getUserId(request);
const tournament = notFoundIfFalsy(

View File

@ -1,7 +1,7 @@
import {
redirect,
type ActionFunction,
type LoaderArgs,
type LoaderFunctionArgs,
} from "@remix-run/node";
import {
Link,
@ -226,7 +226,7 @@ export const action: ActionFunction = async ({ request, params }) => {
export type TournamentRegisterPageLoader = typeof loader;
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const eventId = tournamentIdFromParams(params);
const hasStarted = hasTournamentStarted(eventId);

View File

@ -14,7 +14,7 @@ import {
verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import { redirect } from "@remix-run/node";
import type { LoaderArgs, ActionFunction } from "@remix-run/node";
import type { LoaderFunctionArgs, ActionFunction } from "@remix-run/node";
import {
useFetcher,
useLoaderData,
@ -66,7 +66,7 @@ export const action: ActionFunction = async ({ request, params }) => {
return null;
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const user = await requireUser(request);
const tournamentId = tournamentIdFromParams(params);
const hasStarted = hasTournamentStarted(tournamentId);

View File

@ -1,4 +1,4 @@
import type { LoaderArgs } from "@remix-run/node";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData, useOutletContext } from "@remix-run/react";
import { streamsByTournamentId } from "../core/streams.server";
import { tournamentIdFromParams } from "../tournament-utils";
@ -9,7 +9,7 @@ import { tournamentRegisterPage, twitchUrl } from "~/utils/urls";
import { UserIcon } from "~/components/icons/User";
import { useTranslation } from "~/hooks/useTranslation";
export const loader = async ({ params }: LoaderArgs) => {
export const loader = async ({ params }: LoaderFunctionArgs) => {
const tournamentId = tournamentIdFromParams(params);
return {

View File

@ -1,4 +1,4 @@
import type { LoaderArgs } from "@remix-run/node";
import type { LoaderFunctionArgs } from "@remix-run/node";
import { Link, useLoaderData, useOutletContext } from "@remix-run/react";
import { Placement } from "~/components/Placement";
import {
@ -39,7 +39,7 @@ import { getUserId } from "~/features/auth/core/user.server";
import { notFoundIfFalsy } from "~/utils/remix";
import * as TournamentRepository from "../TournamentRepository.server";
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const user = await getUserId(request);
const tournamentId = tournamentIdFromParams(params);
const tournamentTeamId = tournamentTeamIdFromParams(params);

View File

@ -1,8 +1,8 @@
import type {
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
SerializeFrom,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import {
Outlet,
@ -50,7 +50,7 @@ export const shouldRevalidate: ShouldRevalidateFunction = (args) => {
return args.defaultShouldRevalidate;
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader>;
if (!data) return [];
@ -69,7 +69,7 @@ export const handle: SendouRouteHandle = {
export type TournamentLoaderTeam = Unpacked<TournamentLoaderData["teams"]>;
export type TournamentLoaderData = SerializeFrom<typeof loader>;
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const user = await getUser(request);
const tournamentId = tournamentIdFromParams(params);
const tournament = notFoundIfFalsy(

View File

@ -1,4 +1,4 @@
import type { ActionFunction, LoaderArgs } from "@remix-run/node";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/node";
import type { UserPageLoaderData } from "./u.$identifier";
import { userParamsSchema } from "./u.$identifier";
import {
@ -49,7 +49,7 @@ export const action: ActionFunction = async ({ request }) => {
return null;
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const loggedInUser = await getUserId(request);
const { identifier } = userParamsSchema.parse(params);
@ -109,8 +109,8 @@ export default function UserArtPage() {
type === "ALL" || !hasBothArtMadeByAndMadeOf
? data.arts
: type === "MADE-BY"
? data.arts.filter((a) => !a.author)
: data.arts.filter((a) => a.author);
? data.arts.filter((a) => !a.author)
: data.arts.filter((a) => a.author);
if (filteredTag) {
arts = arts.filter((a) => a.tags?.includes(filteredTag));

View File

@ -2,7 +2,7 @@ import {
json,
redirect,
type ActionFunction,
type LoaderArgs,
type LoaderFunctionArgs,
} from "@remix-run/node";
import { Form, useLoaderData, useSearchParams } from "@remix-run/react";
import clone from "just-clone";
@ -181,7 +181,7 @@ const newBuildLoaderParamsSchema = z.object({
buildId: z.preprocess(actualNumber, id),
});
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await requireUserId(request);
const url = new URL(request.url);
@ -439,10 +439,10 @@ function GearSelector({
const initialGearId = !buildToEdit
? undefined
: type === "HEAD"
? buildToEdit.headGearSplId
: type === "CLOTHES"
? buildToEdit.clothesGearSplId
: buildToEdit.shoesGearSplId;
? buildToEdit.headGearSplId
: type === "CLOTHES"
? buildToEdit.clothesGearSplId
: buildToEdit.shoesGearSplId;
return (
<div>

View File

@ -1,4 +1,4 @@
import type { ActionFunction, LoaderArgs } from "@remix-run/node";
import type { ActionFunction, LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData, useMatches } from "@remix-run/react";
import { z } from "zod";
import { BuildCard } from "~/components/BuildCard";
@ -52,7 +52,7 @@ export const handle: SendouRouteHandle = {
i18n: ["weapons", "builds", "gear"],
};
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const loggedInUser = await getUserId(request);
const { identifier } = userParamsSchema.parse(params);
const user = notFoundIfFalsy(

View File

@ -2,10 +2,11 @@ import {
redirect,
type ActionFunction,
type LinksFunction,
type LoaderArgs,
type LoaderFunctionArgs,
} from "@remix-run/node";
import { Form, Link, useLoaderData, useMatches } from "@remix-run/react";
import { countries } from "countries-list";
import { countries, getEmojiFlag } from "countries-list";
import type { TCountryCode } from "countries-list";
import * as React from "react";
import { Trans } from "react-i18next";
import invariant from "tiny-invariant";
@ -192,7 +193,7 @@ export const action: ActionFunction = async ({ request }) => {
}
};
export const loader = async ({ request, params }: LoaderArgs) => {
export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const locale = await i18next.getLocale(request);
const user = await requireUser(request);
@ -210,7 +211,7 @@ export const loader = async ({ request, params }: LoaderArgs) => {
countries: Object.entries(countries)
.map(([code, country]) => ({
code,
emoji: country.emoji,
emoji: getEmojiFlag(code as TCountryCode),
name:
translatedCountry({
countryCode: code,

View File

@ -1,4 +1,4 @@
import type { LoaderArgs, SerializeFrom } from "@remix-run/node";
import type { LoaderFunctionArgs, SerializeFrom } from "@remix-run/node";
import {
Link,
useLoaderData,
@ -74,7 +74,7 @@ export const seasonsSearchParamsSchema = z.object({
.refine((nth) => !nth || allSeasons(new Date()).includes(nth)),
});
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const { identifier } = userParamsSchema.parse(params);
const parsedSearchParams = seasonsSearchParamsSchema.safeParse(
Object.fromEntries(new URL(request.url).searchParams),

View File

@ -1,7 +1,7 @@
import type {
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { Outlet, useLoaderData, useLocation } from "@remix-run/react";
@ -40,11 +40,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = ({
data,
}: {
data: UserPageLoaderData;
}) => {
export const meta: MetaFunction<typeof loader> = ({ data }) => {
if (!data) return [];
return [{ title: makeTitle(discordFullName(data)) }];
@ -76,7 +72,7 @@ export const userParamsSchema = z.object({ identifier: z.string() });
export type UserPageLoaderData = SerializeFrom<typeof loader>;
export const loader = async ({ params, request }: LoaderArgs) => {
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
const loggedInUser = await getUserId(request);
const { identifier } = userParamsSchema.parse(params);
const user = notFoundIfFalsy(

View File

@ -1,4 +1,8 @@
import type { LinksFunction, LoaderArgs, SerializeFrom } from "@remix-run/node";
import type {
LinksFunction,
LoaderFunctionArgs,
SerializeFrom,
} from "@remix-run/node";
import { Main } from "~/components/Main";
import { parseSearchParams, type SendouRouteHandle } from "~/utils/remix";
import { navIconUrl, userPage, USER_SEARCH_PAGE } from "~/utils/urls";
@ -34,7 +38,7 @@ const searchParamsSchema = z.object({
limit: z.coerce.number().int().min(1).max(25).default(25),
});
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { q: query, limit } = parseSearchParams({
request,
schema: searchParamsSchema,

View File

@ -1,7 +1,7 @@
import type {
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
@ -59,7 +59,7 @@ export const handle: SendouRouteHandle = {
},
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -67,7 +67,7 @@ export const meta: V2_MetaFunction = (args) => {
return [{ title: makeTitle(data.vod.title) }];
};
export const loader = ({ params }: LoaderArgs) => {
export const loader = ({ params }: LoaderFunctionArgs) => {
const vod = notFoundIfFalsy(findVodById(Number(params["id"])));
return { vod };

View File

@ -1,6 +1,6 @@
import {
type ActionFunction,
type LoaderArgs,
type LoaderFunctionArgs,
redirect,
} from "@remix-run/node";
import { Form, useLoaderData } from "@remix-run/react";
@ -93,7 +93,7 @@ const newVodLoaderParamsSchema = z.object({
vod: z.preprocess(actualNumber, id),
});
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await requireUser(request);
if (!canAddVideo(user)) {

View File

@ -1,7 +1,7 @@
import type {
LinksFunction,
LoaderArgs,
V2_MetaFunction,
LoaderFunctionArgs,
MetaFunction,
SerializeFrom,
} from "@remix-run/node";
import { useLoaderData, useSearchParams } from "@remix-run/react";
@ -33,7 +33,7 @@ export const links: LinksFunction = () => {
return [{ rel: "stylesheet", href: styles }];
};
export const meta: V2_MetaFunction = (args) => {
export const meta: MetaFunction = (args) => {
const data = args.data as SerializeFrom<typeof loader> | null;
if (!data) return [];
@ -41,7 +41,7 @@ export const meta: V2_MetaFunction = (args) => {
return [{ title: data.title }];
};
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const t = await i18next.getFixedT(request);
const url = new URL(request.url);

View File

@ -3,5 +3,5 @@ import { useMatches } from "@remix-run/react";
export function useBaseUrl() {
const matches = useMatches();
return matches[0]?.data["baseUrl"] as string;
return (matches[0]?.data as any)["baseUrl"] as string;
}

View File

@ -1,15 +1,13 @@
import * as React from "react";
import { useMatches } from "@remix-run/react";
import {
type DefaultNamespace,
type KeyPrefix,
type Namespace,
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
useTranslation as useTranslationOriginal,
type UseTranslationOptions,
type UseTranslationResponse,
} from "react-i18next";
import type { SendouRouteHandle } from "~/utils/remix";
import type { DefaultNamespace, KeyPrefix, Namespace } from "i18next";
// Wraps useTranslation for better error detection with remix-i18next.
// Only has an effect in non-production environments.
@ -41,8 +39,8 @@ export function useTranslation<
nsFixed === undefined
? ["common"]
: typeof nsFixed === "string"
? [nsFixed]
: nsFixed;
? [nsFixed]
: nsFixed;
for (const singleNs of nsArray) {
if (!loadedTranslations.has(singleNs)) {

View File

@ -5,9 +5,10 @@ import { resolve } from "node:path";
import { initReactI18next } from "react-i18next";
import { config } from "./config";
import i18next from "./i18next.server";
import type { i18n as i18nType } from "i18next";
export async function i18Instance(request: Request, context: EntryContext) {
const instance = createInstance();
const instance = createInstance() as i18nType;
const lng = await i18next.getLocale(request);
const ns = i18next.getRouteNamespaces(context);

View File

@ -1,9 +1,9 @@
import { json } from "@remix-run/node";
import type {
LinksFunction,
LoaderArgs,
LoaderFunctionArgs,
SerializeFrom,
V2_MetaFunction,
MetaFunction,
} from "@remix-run/node";
import {
Links,
@ -67,7 +67,7 @@ export const links: LinksFunction = () => {
];
};
export const meta: V2_MetaFunction = () => {
export const meta: MetaFunction = () => {
return [
{ title: "sendou.ink" },
{
@ -80,7 +80,7 @@ export const meta: V2_MetaFunction = () => {
export type RootLoaderData = SerializeFrom<typeof loader>;
export const loader = async ({ request }: LoaderArgs) => {
export const loader = async ({ request }: LoaderFunctionArgs) => {
const user = await getUser(request);
const locale = await i18next.getLocale(request);
const themeSession = await getThemeSession(request);
@ -225,12 +225,15 @@ function useCustomizedCSSVars() {
const matches = useMatches();
for (const match of matches) {
if (match.data?.[CUSTOMIZED_CSS_VARS_NAME]) {
if ((match.data as any)?.[CUSTOMIZED_CSS_VARS_NAME]) {
// cheating TypeScript here but no real way to keep up
// even an illusion of type safety here
return Object.fromEntries(
Object.entries(
match.data[CUSTOMIZED_CSS_VARS_NAME] as Record<string, string>,
(match.data as any)[CUSTOMIZED_CSS_VARS_NAME] as Record<
string,
string
>,
).map(([key, value]) => [`--${key}`, value]),
) as React.CSSProperties;
}

View File

@ -3,8 +3,7 @@
}
.calendar__add-new-button {
margin-inline-end: var(--s-8);
margin-inline-start: auto;
margin-inline: auto var(--s-8);
}
.calendar__weeks {

View File

@ -767,8 +767,7 @@ dialog::backdrop {
.calendar__event__tag-delete-button > svg {
width: 0.85rem !important;
color: var(--black-text);
margin-inline-end: 0 !important;
margin-inline-start: var(--s-1);
margin-inline: var(--s-1) 0 !important;
}
.alert {
@ -785,8 +784,7 @@ dialog::backdrop {
line-height: 1.4;
margin-inline: auto;
padding-block: var(--s-1-5);
padding-inline-end: var(--s-4);
padding-inline-start: var(--s-3);
padding-inline: var(--s-3) var(--s-4);
}
.alert.tiny {
@ -951,9 +949,8 @@ dialog::backdrop {
.builds-container {
display: grid;
justify-content: center;
column-gap: var(--s-3);
gap: var(--s-4) var(--s-3);
grid-template-columns: repeat(auto-fit, 240px);
row-gap: var(--s-4);
}
.builds-buttons {
@ -1089,10 +1086,9 @@ dialog::backdrop {
.build__gear-abilities {
display: grid;
column-gap: var(--s-1);
gap: var(--s-2) var(--s-1);
grid-template-columns: repeat(5, max-content);
place-items: center;
row-gap: var(--s-2);
}
.build__gear {
@ -1294,8 +1290,7 @@ dialog::backdrop {
color: #000;
font-size: var(--fonts-xxs);
padding-inline: var(--s-1);
margin-block-start: var(--s-1);
margin-block-end: var(--s-0-5);
margin-block: var(--s-1) var(--s-0-5);
}
.art__dialog__tag__user {
@ -1331,8 +1326,7 @@ dialog::backdrop {
.art__tags-container {
display: flex;
column-gap: var(--s-2);
row-gap: var(--s-0-5);
gap: var(--s-0-5) var(--s-2);
justify-content: center;
flex-wrap: wrap;
margin-block-start: var(--s-0-5);

View File

@ -17,10 +17,9 @@
.front__nav-items-container {
display: flex;
margin: 0 auto;
column-gap: var(--s-4);
gap: var(--s-4) var(--s-4);
font-size: 13px;
flex-wrap: wrap;
row-gap: var(--s-4);
justify-content: center;
}

View File

@ -115,8 +115,7 @@
}
.layout__main {
padding-block-end: var(--s-32);
padding-block-start: var(--s-4);
padding-block: var(--s-4) var(--s-32);
}
.layout__log-in-button {
@ -261,8 +260,7 @@
-webkit-backdrop-filter: var(--backdrop-filter);
backdrop-filter: var(--backdrop-filter);
background-color: transparent;
overflow-y: auto;
overflow-x: hidden;
overflow: hidden auto;
direction: rtl;
position: sticky;

View File

@ -131,8 +131,7 @@
line-height: 0.75;
margin-inline: auto;
padding-block: var(--s-1);
padding-inline-end: var(--s-4);
padding-inline-start: var(--s-3);
padding-inline: var(--s-3) var(--s-4);
}
.plus-voting__alert > svg {

View File

@ -1,4 +1,4 @@
import type { ActionArgs, LoaderArgs } from "@remix-run/node";
import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node";
import type { z } from "zod";
import { ADMIN_ID } from "~/constants";
import { NZAP_TEST_ID } from "~/db/seed/constants";
@ -17,8 +17,8 @@ export function wrappedAction<T extends z.ZodTypeAny>({
params = {},
}: {
// TODO: strongly type this
action: (args: ActionArgs) => any;
params?: ActionArgs["params"];
action: (args: ActionFunctionArgs) => any;
params?: ActionFunctionArgs["params"];
}) {
return async (
args: z.infer<T>,
@ -56,7 +56,7 @@ export function wrappedLoader<T>({
loader,
}: {
// TODO: strongly type this
loader: (args: LoaderArgs) => any;
loader: (args: LoaderFunctionArgs) => any;
}) {
return async ({ user }: { user?: "admin" | "regular" } = {}) => {
const request = new Request("http://app.com/path", {

View File

@ -1,8 +1,8 @@
import { z } from "zod";
import { type TFunction, type Namespace } from "react-i18next";
import { type RouteMatch } from "@remix-run/react";
import type { UIMatch } from "@remix-run/react";
import type navItems from "~/components/layout/nav-items.json";
import { json } from "@remix-run/node";
import type { Namespace, TFunction } from "i18next";
export function notFoundIfFalsy<T>(value: T | null | undefined): T {
if (!value) throw new Response(null, { status: 404 });
@ -164,7 +164,7 @@ export type SendouRouteHandle = {
* the <Breadcrumb> component
*/
breadcrumb?: (args: {
match: RouteMatch;
match: UIMatch;
t: TFunction<"common", undefined>;
}) => Breadcrumb | Array<Breadcrumb> | undefined;

View File

@ -44,10 +44,10 @@ export function startsWith<S extends string, Start extends string>(
type Split<S extends string, Sep extends string> = string extends S
? string[]
: S extends ""
? []
: S extends `${infer T}${Sep}${infer U}`
? [T, ...Split<U, Sep>]
: [S];
? []
: S extends `${infer T}${Sep}${infer U}`
? [T, ...Split<U, Sep>]
: [S];
export function split<S extends string, Sep extends string>(
str: S,

View File

@ -11,10 +11,10 @@ export const assertType = <A, B extends A>() => {}; // eslint-disable-line
export type Unpacked<T> = T extends (infer U)[]
? U
: T extends (...args: unknown[]) => infer U
? U
: T extends Promise<infer U>
? U
: T;
? U
: T extends Promise<infer U>
? U
: T;
export type Nullish<T> = T | null | undefined;

View File

@ -346,8 +346,8 @@ export const preferenceEmojiUrl = (preference?: Preference) => {
preference === "PREFER"
? "grin"
: preference === "AVOID"
? "unamused"
: "no-mouth";
? "unamused"
: "no-mouth";
return `/static-assets/img/emoji/${emoji}.svg`;
};

14200
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -48,89 +48,89 @@
"cf:noe2e": "npm run test:unit && npm run check-translation-jsons && npm run lint:css -- --fix && npm run lint:ts -- --fix && npm run prettier:write && npm run typecheck"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.428.0",
"@aws-sdk/lib-storage": "^3.428.0",
"@dnd-kit/core": "^6.0.8",
"@dnd-kit/sortable": "^7.0.2",
"@dnd-kit/utilities": "^3.2.1",
"@faker-js/faker": "^8.0.2",
"@aws-sdk/client-s3": "^3.465.0",
"@aws-sdk/lib-storage": "^3.465.0",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^8.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@faker-js/faker": "^8.3.1",
"@headlessui/react": "^1.7.17",
"@popperjs/core": "^2.11.8",
"@remix-run/node": "^1.19.3",
"@remix-run/react": "^1.19.3",
"@remix-run/serve": "^1.19.3",
"@remix-run/node": "^2.3.1",
"@remix-run/react": "^2.3.1",
"@remix-run/serve": "^2.3.1",
"@tldraw/tldraw": "^1.29.2",
"aws-sdk": "^2.1445.0",
"better-sqlite3": "^8.5.2",
"aws-sdk": "^2.1512.0",
"better-sqlite3": "^9.2.2",
"cachified": "^3.5.4",
"clsx": "^2.0.0",
"compressorjs": "^1.2.1",
"countries-list": "^2.6.1",
"countries-list": "^3.0.6",
"date-fns": "^2.30.0",
"fuse.js": "^6.6.2",
"fuse.js": "^7.0.0",
"gray-matter": "^4.0.3",
"i18next": "^21.9.2",
"i18next-browser-languagedetector": "^6.1.5",
"i18next-fs-backend": "^1.1.5",
"i18next-http-backend": "^1.4.4",
"isbot": "^3.6.13",
"i18next": "^23.7.7",
"i18next-browser-languagedetector": "^7.2.0",
"i18next-fs-backend": "^2.3.0",
"i18next-http-backend": "^2.4.2",
"isbot": "^3.7.1",
"just-capitalize": "^3.2.0",
"just-clone": "^6.2.0",
"just-random-integer": "^4.2.0",
"just-shuffle": "^4.2.0",
"kysely": "^0.26.3",
"lru-cache": "10.0.1",
"lru-cache": "10.1.0",
"markdown-to-jsx": "^7.3.2",
"nanoid": "~3.3.4",
"node-cron": "3.0.2",
"nanoid": "~5.0.4",
"node-cron": "3.0.3",
"nprogress": "^0.2.0",
"openskill": "^3.1.0",
"react": "^18.2.0",
"react-charts": "^3.0.0-beta.55",
"react-dom": "^18.2.0",
"react-flip-toolkit": "^7.1.0",
"react-i18next": "^11.18.6",
"react-i18next": "^13.5.0",
"react-popper": "^2.3.0",
"react-responsive-masonry": "^2.1.7",
"react-use": "^17.4.0",
"react-use": "^17.4.2",
"reconnecting-websocket": "^4.4.0",
"remix-auth": "^3.5.1",
"remix-auth-oauth2": "^1.8.0",
"remix-i18next": "^4.1.1",
"remix-utils": "^6.6.0",
"remix-auth": "^3.6.0",
"remix-auth-oauth2": "^1.11.0",
"remix-i18next": "^5.4.0",
"remix-utils": "^7.3.0",
"slugify": "^1.6.6",
"swr": "^2.2.1",
"swr": "^2.2.4",
"tiny-invariant": "^1.3.1",
"zod": "^3.22.3"
"zod": "^3.22.4"
},
"devDependencies": {
"@playwright/test": "^1.39.0",
"@remix-run/dev": "^1.19.3",
"@playwright/test": "^1.40.1",
"@remix-run/dev": "^2.3.1",
"@swc-node/register": "^1.6.8",
"@types/better-sqlite3": "7.6.4",
"@types/i18next-fs-backend": "^1.1.2",
"@types/node-cron": "^3.0.8",
"@types/nprogress": "^0.2.0",
"@types/better-sqlite3": "7.6.8",
"@types/i18next-fs-backend": "^1.1.5",
"@types/node-cron": "^3.0.11",
"@types/nprogress": "^0.2.3",
"@types/prettier": "3.0.0",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@types/react-responsive-masonry": "^2.1.0",
"@typescript-eslint/eslint-plugin": "^6.4.1",
"@typescript-eslint/parser": "^6.4.1",
"@types/react": "^18.2.42",
"@types/react-dom": "^18.2.17",
"@types/react-responsive-masonry": "^2.1.3",
"@typescript-eslint/eslint-plugin": "^6.13.2",
"@typescript-eslint/parser": "^6.13.2",
"cross-env": "^7.0.3",
"dotenv": "^16.3.1",
"eslint": "^8.48.0",
"eslint": "^8.55.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"ignore-styles": "^5.0.1",
"ley": "^0.8.1",
"mockdate": "^3.0.5",
"prettier": "3.0.2",
"stylelint": "^15.10.3",
"prettier": "3.1.0",
"stylelint": "^15.11.0",
"stylelint-config-standard": "^34.0.0",
"tsconfig-paths": "^4.2.0",
"tsm": "^2.3.0",
"typescript": "^5.2.2",
"typescript": "^5.3.2",
"uvu": "^0.5.6"
}
}

View File

@ -236,12 +236,10 @@ module.exports = {
});
},
serverModuleFormat: "cjs",
serverDependenciesToBundle: ["react-charts", "d3-time-format"],
future: {
v2_meta: true,
v2_normalizeFormMethod: true,
v2_dev: true,
v2_headers: true,
v2_errorBoundary: true,
},
serverDependenciesToBundle: [
"react-charts",
"d3-time-format",
"nanoid",
/^remix-utils.*/,
],
};

View File

@ -370,8 +370,8 @@ function MDMissingKeysList({
const keysLabel = allMissing
? "All keys"
: missingKeys.length === 1
? "1 key"
: `${missingKeys.length} keys`;
? "1 key"
: `${missingKeys.length} keys`;
const details = noneMissing
? ""

View File

@ -55,8 +55,8 @@ async function main() {
type === LEAN_CLOTHES_CODE
? "Clothes"
: type === LEAN_SHOES_CODE
? "Shoes"
: "Head"
? "Shoes"
: "Head"
}`;
allGear.push({

View File

@ -2,11 +2,11 @@
"include": ["./types/remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"module": "commonjs",
"module": "ESNext",
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"target": "ES2020",
"strict": true,