diff --git a/app/components/form/SendouForm.tsx b/app/components/form/SendouForm.tsx index aa8c4c1aa..04b7f88ba 100644 --- a/app/components/form/SendouForm.tsx +++ b/app/components/form/SendouForm.tsx @@ -1,9 +1,9 @@ -import { zodResolver } from "@hookform/resolvers/zod"; +import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"; import { useFetcher } from "@remix-run/react"; import * as React from "react"; import { type DefaultValues, FormProvider, useForm } from "react-hook-form"; import { useTranslation } from "react-i18next"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { logger } from "~/utils/logger"; import type { ActionError } from "~/utils/remix.server"; import { SubmitButton } from "../SubmitButton"; @@ -27,7 +27,7 @@ export function SendouForm({ const { t } = useTranslation(["common"]); const fetcher = useFetcher(); const methods = useForm({ - resolver: zodResolver(schema), + resolver: standardSchemaResolver(schema), defaultValues, }); @@ -47,7 +47,10 @@ export function SendouForm({ const onSubmit = React.useCallback( methods.handleSubmit((values) => - fetcher.submit(values, { method: "post", encType: "application/json" }), + fetcher.submit(values as Parameters[0], { + method: "post", + encType: "application/json", + }), ), [], ); diff --git a/app/features/admin/actions/admin.server.ts b/app/features/admin/actions/admin.server.ts index 297c34548..984fc5ec0 100644 --- a/app/features/admin/actions/admin.server.ts +++ b/app/features/admin/actions/admin.server.ts @@ -1,5 +1,5 @@ import type { ActionFunctionArgs } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import * as AdminRepository from "~/features/admin/AdminRepository.server"; import { makeArtist } from "~/features/art/queries/makeArtist.server"; import { requireUser } from "~/features/auth/core/user.server"; diff --git a/app/features/admin/admin-schemas.ts b/app/features/admin/admin-schemas.ts index 42c5cccf8..a3d67866d 100644 --- a/app/features/admin/admin-schemas.ts +++ b/app/features/admin/admin-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { friendCode } from "~/utils/zod"; export const adminActionSearchParamsSchema = z.object({ diff --git a/app/features/api-private/routes/seed.ts b/app/features/api-private/routes/seed.ts index f0a2517a0..79b4b1a6b 100644 --- a/app/features/api-private/routes/seed.ts +++ b/app/features/api-private/routes/seed.ts @@ -1,5 +1,5 @@ import type { ActionFunction } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { seed } from "~/db/seed"; import { parseRequestPayload } from "~/utils/remix.server"; diff --git a/app/features/api-public/routes/calendar.$year.$week.ts b/app/features/api-public/routes/calendar.$year.$week.ts index 32d1ee5c5..5d83d913b 100644 --- a/app/features/api-public/routes/calendar.$year.$week.ts +++ b/app/features/api-public/routes/calendar.$year.$week.ts @@ -1,6 +1,6 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { databaseTimestampToDate, diff --git a/app/features/api-public/routes/org.$id.ts b/app/features/api-public/routes/org.$id.ts index c08914146..cc37ff649 100644 --- a/app/features/api-public/routes/org.$id.ts +++ b/app/features/api-public/routes/org.$id.ts @@ -1,7 +1,7 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { jsonArrayFrom } from "kysely/helpers/sqlite"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { notFoundIfFalsy, parseParams } from "~/utils/remix.server"; import { userSubmittedImage } from "~/utils/urls"; diff --git a/app/features/api-public/routes/sendouq.active-match.$userId.ts b/app/features/api-public/routes/sendouq.active-match.$userId.ts index fba99b000..59a370a87 100644 --- a/app/features/api-public/routes/sendouq.active-match.$userId.ts +++ b/app/features/api-public/routes/sendouq.active-match.$userId.ts @@ -1,6 +1,6 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { findCurrentGroupByUserId } from "~/features/sendouq/queries/findCurrentGroupByUserId.server"; import { parseParams } from "~/utils/remix.server"; import { id } from "~/utils/zod"; diff --git a/app/features/api-public/routes/sendouq.match.$matchId.ts b/app/features/api-public/routes/sendouq.match.$matchId.ts index f1b8aaadf..ddcc0650f 100644 --- a/app/features/api-public/routes/sendouq.match.$matchId.ts +++ b/app/features/api-public/routes/sendouq.match.$matchId.ts @@ -1,6 +1,6 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import * as QMatchRepository from "~/features/sendouq-match/QMatchRepository.server"; import i18next from "~/modules/i18n/i18next.server"; import invariant from "~/utils/invariant"; diff --git a/app/features/api-public/routes/tournament-match.$id.ts b/app/features/api-public/routes/tournament-match.$id.ts index 512f4b154..f3dd1840f 100644 --- a/app/features/api-public/routes/tournament-match.$id.ts +++ b/app/features/api-public/routes/tournament-match.$id.ts @@ -1,7 +1,7 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { jsonArrayFrom } from "kysely/helpers/sqlite"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { tournamentFromDBCached } from "~/features/tournament-bracket/core/Tournament.server"; import { resolveMapList } from "~/features/tournament-bracket/core/mapList.server"; diff --git a/app/features/api-public/routes/tournament.$id.brackets.$bidx.standings.ts b/app/features/api-public/routes/tournament.$id.brackets.$bidx.standings.ts index ad46ccecb..56bd99eb4 100644 --- a/app/features/api-public/routes/tournament.$id.brackets.$bidx.standings.ts +++ b/app/features/api-public/routes/tournament.$id.brackets.$bidx.standings.ts @@ -1,6 +1,6 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server"; import { notFoundIfFalsy, parseParams } from "~/utils/remix.server"; import { id } from "~/utils/zod"; diff --git a/app/features/api-public/routes/tournament.$id.brackets.$bidx.ts b/app/features/api-public/routes/tournament.$id.brackets.$bidx.ts index 345bcbae4..8304dcde0 100644 --- a/app/features/api-public/routes/tournament.$id.brackets.$bidx.ts +++ b/app/features/api-public/routes/tournament.$id.brackets.$bidx.ts @@ -1,6 +1,6 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; 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"; diff --git a/app/features/api-public/routes/tournament.$id.casted.ts b/app/features/api-public/routes/tournament.$id.casted.ts index e8635fa7e..6bd5f239c 100644 --- a/app/features/api-public/routes/tournament.$id.casted.ts +++ b/app/features/api-public/routes/tournament.$id.casted.ts @@ -1,6 +1,6 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { notFoundIfFalsy, parseParams } from "~/utils/remix.server"; import { id } from "~/utils/zod"; diff --git a/app/features/api-public/routes/tournament.$id.teams.ts b/app/features/api-public/routes/tournament.$id.teams.ts index 16d781c8b..673dc13ad 100644 --- a/app/features/api-public/routes/tournament.$id.teams.ts +++ b/app/features/api-public/routes/tournament.$id.teams.ts @@ -1,7 +1,7 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { jsonArrayFrom, jsonObjectFrom } from "kysely/helpers/sqlite"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { ordinalToSp } from "~/features/mmr/mmr-utils"; import * as TournamentRepository from "~/features/tournament/TournamentRepository.server"; diff --git a/app/features/api-public/routes/tournament.$id.ts b/app/features/api-public/routes/tournament.$id.ts index b71006f95..f5a48cd6a 100644 --- a/app/features/api-public/routes/tournament.$id.ts +++ b/app/features/api-public/routes/tournament.$id.ts @@ -1,7 +1,7 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { jsonArrayFrom } from "kysely/helpers/sqlite"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { HACKY_resolvePicture } from "~/features/tournament/tournament-utils"; import { databaseTimestampToDate } from "~/utils/dates"; diff --git a/app/features/api-public/routes/user.$identifier.ts b/app/features/api-public/routes/user.$identifier.ts index 27656e583..54d99db49 100644 --- a/app/features/api-public/routes/user.$identifier.ts +++ b/app/features/api-public/routes/user.$identifier.ts @@ -1,7 +1,7 @@ import { type LoaderFunctionArgs, json } from "@remix-run/node"; import { jsonArrayFrom } from "kysely/helpers/sqlite"; import { cors } from "remix-utils/cors"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { i18next } from "~/modules/i18n/i18next.server"; import { safeNumberParse } from "~/utils/number"; diff --git a/app/features/art/art-schemas.server.ts b/app/features/art/art-schemas.server.ts index d6667c98b..f988be7e0 100644 --- a/app/features/art/art-schemas.server.ts +++ b/app/features/art/art-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, checkboxValueToDbBoolean, diff --git a/app/features/articles/articles-schemas.server.ts b/app/features/articles/articles-schemas.server.ts index 7ae2847d0..a1c636bd5 100644 --- a/app/features/articles/articles-schemas.server.ts +++ b/app/features/articles/articles-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; const authorName = z.string().min(1); diff --git a/app/features/articles/core/bySlug.server.ts b/app/features/articles/core/bySlug.server.ts index 92029da0d..2c3ccb682 100644 --- a/app/features/articles/core/bySlug.server.ts +++ b/app/features/articles/core/bySlug.server.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import path from "node:path"; import matter from "gray-matter"; -import { ZodError, type z } from "zod"; +import { ZodError, type z } from "zod/v4"; import { ARTICLES_FOLDER_PATH } from "../articles-constants"; import { articleDataSchema } from "../articles-schemas.server"; diff --git a/app/features/associations/associations-schemas.ts b/app/features/associations/associations-schemas.ts index 5d5c2ae74..c80960f5a 100644 --- a/app/features/associations/associations-schemas.ts +++ b/app/features/associations/associations-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, id, inviteCode, safeStringSchema } from "~/utils/zod"; import { ASSOCIATION } from "./associations-constants"; diff --git a/app/features/associations/routes/associations.new.tsx b/app/features/associations/routes/associations.new.tsx index ecfebf116..7ecfba6fb 100644 --- a/app/features/associations/routes/associations.new.tsx +++ b/app/features/associations/routes/associations.new.tsx @@ -1,5 +1,5 @@ import { useTranslation } from "react-i18next"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { SendouDialog } from "~/components/elements/Dialog"; import { InputFormField } from "~/components/form/InputFormField"; import { SendouForm } from "~/components/form/SendouForm"; diff --git a/app/features/auth/core/DiscordStrategy.server.ts b/app/features/auth/core/DiscordStrategy.server.ts index d97d83192..7128cdf79 100644 --- a/app/features/auth/core/DiscordStrategy.server.ts +++ b/app/features/auth/core/DiscordStrategy.server.ts @@ -1,5 +1,5 @@ import { OAuth2Strategy } from "remix-auth-oauth2"; -import { z } from "zod"; +import { z } from "zod/v4"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import invariant from "~/utils/invariant"; import { logger } from "~/utils/logger"; diff --git a/app/features/auth/core/routes.server.ts b/app/features/auth/core/routes.server.ts index 51fe7d38c..20c442f53 100644 --- a/app/features/auth/core/routes.server.ts +++ b/app/features/auth/core/routes.server.ts @@ -1,7 +1,7 @@ import type { ActionFunction, LoaderFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; import { isbot } from "isbot"; -import { z } from "zod"; +import { z } from "zod/v4"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { requireRole } from "~/modules/permissions/guards.server"; import { logger } from "~/utils/logger"; diff --git a/app/features/badges/actions/badges.$id.edit.server.ts b/app/features/badges/actions/badges.$id.edit.server.ts index 52bc9f56c..df5633e6c 100644 --- a/app/features/badges/actions/badges.$id.edit.server.ts +++ b/app/features/badges/actions/badges.$id.edit.server.ts @@ -1,6 +1,6 @@ import type { ActionFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import { notify } from "~/features/notifications/core/notify.server"; import { diff --git a/app/features/badges/badges-schemas.server.ts b/app/features/badges/badges-schemas.server.ts index 848af75bf..d537c401a 100644 --- a/app/features/badges/badges-schemas.server.ts +++ b/app/features/badges/badges-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, id, noDuplicates, safeJSONParse } from "~/utils/zod"; export const editBadgeActionSchema = z.union([ diff --git a/app/features/builds/builds-schemas.server.ts b/app/features/builds/builds-schemas.server.ts index 784a32ca7..36d9e209b 100644 --- a/app/features/builds/builds-schemas.server.ts +++ b/app/features/builds/builds-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { ability, modeShort, safeJSONParse } from "~/utils/zod"; import { MAX_BUILD_FILTERS } from "./builds-constants"; diff --git a/app/features/builds/loaders/builds.$slug.server.ts b/app/features/builds/loaders/builds.$slug.server.ts index a189f1148..a8cbc38ee 100644 --- a/app/features/builds/loaders/builds.$slug.server.ts +++ b/app/features/builds/loaders/builds.$slug.server.ts @@ -40,7 +40,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { if (!filters.success) { console.error( "Invalid filters", - JSON.stringify(filters.error.errors, null, 2), + JSON.stringify(filters.error.issues, null, 2), ); } diff --git a/app/features/calendar/actions/calendar.$id.server.ts b/app/features/calendar/actions/calendar.$id.server.ts index 4228c5026..b2fb069f3 100644 --- a/app/features/calendar/actions/calendar.$id.server.ts +++ b/app/features/calendar/actions/calendar.$id.server.ts @@ -1,6 +1,6 @@ import type { ActionFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUserId } from "~/features/auth/core/user.server"; import * as CalendarRepository from "~/features/calendar/CalendarRepository.server"; import * as ShowcaseTournaments from "~/features/front-page/core/ShowcaseTournaments.server"; diff --git a/app/features/calendar/calendar-schemas.server.ts b/app/features/calendar/calendar-schemas.server.ts index 0c76209a5..f6d098848 100644 --- a/app/features/calendar/calendar-schemas.server.ts +++ b/app/features/calendar/calendar-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import * as CalendarRepository from "~/features/calendar/CalendarRepository.server"; import { MapPool } from "~/features/map-list-generator/core/map-pool"; import { rankedModesShort } from "~/modules/in-game-lists/modes"; diff --git a/app/features/calendar/calendar-schemas.ts b/app/features/calendar/calendar-schemas.ts index 2ad834587..30d2175e8 100644 --- a/app/features/calendar/calendar-schemas.ts +++ b/app/features/calendar/calendar-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { type CalendarEventTag, TOURNAMENT_STAGE_TYPES } from "~/db/tables"; import * as Progression from "~/features/tournament-bracket/core/Progression"; import { TOURNAMENT } from "~/features/tournament/tournament-constants"; diff --git a/app/features/calendar/calendar-types.ts b/app/features/calendar/calendar-types.ts index ebc7569e6..4fd7e5e45 100644 --- a/app/features/calendar/calendar-types.ts +++ b/app/features/calendar/calendar-types.ts @@ -1,4 +1,4 @@ -import type { z } from "zod"; +import type { z } from "zod/v4"; import type { CalendarEventTag, Tables } from "~/db/tables"; import type { calendarFiltersSearchParamsSchema } from "~/features/calendar/calendar-schemas"; import type { ModeShortWithSpecial } from "~/modules/in-game-lists/types"; diff --git a/app/features/front-page/core/Changelog.server.ts b/app/features/front-page/core/Changelog.server.ts index 0b11456c5..20ab4a51e 100644 --- a/app/features/front-page/core/Changelog.server.ts +++ b/app/features/front-page/core/Changelog.server.ts @@ -1,5 +1,5 @@ import { formatDistance } from "date-fns"; -import { z } from "zod"; +import { z } from "zod/v4"; import { logger } from "~/utils/logger"; const BSKY_URL = diff --git a/app/features/img-upload/actions/upload.server.ts b/app/features/img-upload/actions/upload.server.ts index ad0fe8f63..45fa408d0 100644 --- a/app/features/img-upload/actions/upload.server.ts +++ b/app/features/img-upload/actions/upload.server.ts @@ -5,7 +5,7 @@ import { unstable_parseMultipartFormData as parseMultipartFormData, redirect, } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import * as TeamRepository from "~/features/team/TeamRepository.server"; import { isTeamManager } from "~/features/team/team-utils"; diff --git a/app/features/img-upload/upload-schemas.server.ts b/app/features/img-upload/upload-schemas.server.ts index 83590e660..8194e0713 100644 --- a/app/features/img-upload/upload-schemas.server.ts +++ b/app/features/img-upload/upload-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, id, safeJSONParse } from "~/utils/zod"; const validateManySchema = z.object({ diff --git a/app/features/lfg/actions/lfg.new.server.ts b/app/features/lfg/actions/lfg.new.server.ts index c31b36666..fb0783633 100644 --- a/app/features/lfg/actions/lfg.new.server.ts +++ b/app/features/lfg/actions/lfg.new.server.ts @@ -1,6 +1,6 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { errorToastIfFalsy, parseRequestPayload } from "~/utils/remix.server"; diff --git a/app/features/lfg/actions/lfg.server.ts b/app/features/lfg/actions/lfg.server.ts index 5c9756410..cc4ed0ec1 100644 --- a/app/features/lfg/actions/lfg.server.ts +++ b/app/features/lfg/actions/lfg.server.ts @@ -1,5 +1,5 @@ import type { ActionFunctionArgs } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import { errorToastIfFalsy, parseRequestPayload } from "~/utils/remix.server"; import { _action, id } from "~/utils/zod"; diff --git a/app/features/lfg/loaders/lfg.new.server.ts b/app/features/lfg/loaders/lfg.new.server.ts index b0a5ad457..4cdd6e866 100644 --- a/app/features/lfg/loaders/lfg.new.server.ts +++ b/app/features/lfg/loaders/lfg.new.server.ts @@ -1,5 +1,5 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import * as QSettingsRepository from "~/features/sendouq-settings/QSettingsRepository.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; diff --git a/app/features/notifications/notifications-schemas.ts b/app/features/notifications/notifications-schemas.ts index f15c7670c..08f98fc42 100644 --- a/app/features/notifications/notifications-schemas.ts +++ b/app/features/notifications/notifications-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { id } from "~/utils/zod"; import { NOTIFICATIONS } from "./notifications-contants"; diff --git a/app/features/plus-suggestions/plus-suggestions-schemas.ts b/app/features/plus-suggestions/plus-suggestions-schemas.ts index 1095801ca..33878c16d 100644 --- a/app/features/plus-suggestions/plus-suggestions-schemas.ts +++ b/app/features/plus-suggestions/plus-suggestions-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, actualNumber, trimmedString } from "~/utils/zod"; import { PLUS_SUGGESTION, PLUS_TIERS } from "./plus-suggestions-constants"; diff --git a/app/features/plus-voting/plus-voting-schemas.ts b/app/features/plus-voting/plus-voting-schemas.ts index cce352476..5aebd0dbd 100644 --- a/app/features/plus-voting/plus-voting-schemas.ts +++ b/app/features/plus-voting/plus-voting-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import type { PlusVoteFromFE } from "~/features/plus-voting/core"; import { assertType } from "~/utils/types"; import { safeJSONParse } from "~/utils/zod"; diff --git a/app/features/scrims/actions/scrims.new.server.ts b/app/features/scrims/actions/scrims.new.server.ts index abd601f16..91a3910cc 100644 --- a/app/features/scrims/actions/scrims.new.server.ts +++ b/app/features/scrims/actions/scrims.new.server.ts @@ -1,5 +1,5 @@ import { type ActionFunctionArgs, redirect } from "@remix-run/node"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import type { Tables } from "~/db/tables"; import { requireUser } from "~/features/auth/core/user.server"; import { userIsBanned } from "~/features/ban/core/banned.server"; diff --git a/app/features/scrims/routes/scrims.$id.tsx b/app/features/scrims/routes/scrims.$id.tsx index 02df30a95..0c1c83797 100644 --- a/app/features/scrims/routes/scrims.$id.tsx +++ b/app/features/scrims/routes/scrims.$id.tsx @@ -1,7 +1,7 @@ import { Link, useLoaderData } from "@remix-run/react"; import * as React from "react"; import { useTranslation } from "react-i18next"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { Alert } from "~/components/Alert"; import TimePopover from "~/components/TimePopover"; import { SendouButton } from "~/components/elements/Button"; diff --git a/app/features/scrims/routes/scrims.new.tsx b/app/features/scrims/routes/scrims.new.tsx index 0a9a5fb03..79255ea59 100644 --- a/app/features/scrims/routes/scrims.new.tsx +++ b/app/features/scrims/routes/scrims.new.tsx @@ -2,7 +2,7 @@ import { useLoaderData } from "@remix-run/react"; import * as React from "react"; import { Controller, useFormContext, useWatch } from "react-hook-form"; import { useTranslation } from "react-i18next"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { Label } from "~/components/Label"; import { DateFormField } from "~/components/form/DateFormField"; import { SendouForm } from "~/components/form/SendouForm"; diff --git a/app/features/scrims/routes/scrims.tsx b/app/features/scrims/routes/scrims.tsx index 587952174..bc14d01f7 100644 --- a/app/features/scrims/routes/scrims.tsx +++ b/app/features/scrims/routes/scrims.tsx @@ -4,7 +4,7 @@ import clsx from "clsx"; import * as React from "react"; import { useTranslation } from "react-i18next"; import * as R from "remeda"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { AddNewButton } from "~/components/AddNewButton"; import { Avatar } from "~/components/Avatar"; import { Divider } from "~/components/Divider"; diff --git a/app/features/scrims/scrims-schemas.ts b/app/features/scrims/scrims-schemas.ts index c68dde7f0..ac54ce480 100644 --- a/app/features/scrims/scrims-schemas.ts +++ b/app/features/scrims/scrims-schemas.ts @@ -1,5 +1,5 @@ import { add, sub } from "date-fns"; -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, date, diff --git a/app/features/sendouq-match/q-match-schemas.ts b/app/features/sendouq-match/q-match-schemas.ts index b6f830f40..516a55a40 100644 --- a/app/features/sendouq-match/q-match-schemas.ts +++ b/app/features/sendouq-match/q-match-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { SENDOUQ, SENDOUQ_BEST_OF } from "~/features/sendouq/q-constants"; import { _action, diff --git a/app/features/sendouq-settings/q-settings-schemas.server.ts b/app/features/sendouq-settings/q-settings-schemas.server.ts index d1ba3ad77..a1bad3133 100644 --- a/app/features/sendouq-settings/q-settings-schemas.server.ts +++ b/app/features/sendouq-settings/q-settings-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { languagesUnified } from "~/modules/i18n/config"; import { modesShort } from "~/modules/in-game-lists/modes"; import { diff --git a/app/features/sendouq/q-schemas.server.ts b/app/features/sendouq/q-schemas.server.ts index b76b91103..c04aa2287 100644 --- a/app/features/sendouq/q-schemas.server.ts +++ b/app/features/sendouq/q-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, deduplicate, diff --git a/app/features/settings/settings-schemas.ts b/app/features/settings/settings-schemas.ts index 55d4b6b0a..b5dcc9519 100644 --- a/app/features/settings/settings-schemas.ts +++ b/app/features/settings/settings-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action } from "~/utils/zod"; export const settingsEditSchema = z.union([ diff --git a/app/features/team/team-schemas.server.ts b/app/features/team/team-schemas.server.ts index 99d47a2c1..b96c4b2dc 100644 --- a/app/features/team/team-schemas.server.ts +++ b/app/features/team/team-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, customCssVarObject, diff --git a/app/features/tournament-bracket/tournament-bracket-schemas.server.ts b/app/features/tournament-bracket/tournament-bracket-schemas.server.ts index 2f42fdd7a..c239af006 100644 --- a/app/features/tournament-bracket/tournament-bracket-schemas.server.ts +++ b/app/features/tournament-bracket/tournament-bracket-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, checkboxValueToBoolean, diff --git a/app/features/tournament-organization/loaders/org.$slug.server.ts b/app/features/tournament-organization/loaders/org.$slug.server.ts index 2f2534f6d..7de4ce906 100644 --- a/app/features/tournament-organization/loaders/org.$slug.server.ts +++ b/app/features/tournament-organization/loaders/org.$slug.server.ts @@ -1,5 +1,5 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { getUser } from "~/features/auth/core/user.server"; import { parseSafeSearchParams } from "~/utils/remix.server"; import { id } from "~/utils/zod"; diff --git a/app/features/tournament-organization/routes/org.$slug.edit.tsx b/app/features/tournament-organization/routes/org.$slug.edit.tsx index 21a3d8bf1..96b3689de 100644 --- a/app/features/tournament-organization/routes/org.$slug.edit.tsx +++ b/app/features/tournament-organization/routes/org.$slug.edit.tsx @@ -1,7 +1,7 @@ import { Link, useLoaderData } from "@remix-run/react"; import { Controller, useFieldArray, useFormContext } from "react-hook-form"; import { useTranslation } from "react-i18next"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { FormMessage } from "~/components/FormMessage"; import { Label } from "~/components/Label"; import { Main } from "~/components/Main"; diff --git a/app/features/tournament-organization/tournament-organization-schemas.ts b/app/features/tournament-organization/tournament-organization-schemas.ts index 16de6ac95..e97fd4605 100644 --- a/app/features/tournament-organization/tournament-organization-schemas.ts +++ b/app/features/tournament-organization/tournament-organization-schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { TOURNAMENT_ORGANIZATION_ROLES } from "~/db/tables"; import { mySlugify } from "~/utils/urls"; import { falsyToNull, id } from "~/utils/zod"; diff --git a/app/features/tournament-organization/tournament-organization-utils.server.ts b/app/features/tournament-organization/tournament-organization-utils.server.ts index e9d838a15..6c8449fdd 100644 --- a/app/features/tournament-organization/tournament-organization-utils.server.ts +++ b/app/features/tournament-organization/tournament-organization-utils.server.ts @@ -1,5 +1,5 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { notFoundIfFalsy, parseParams } from "~/utils/remix.server"; import * as TournamentOrganizationRepository from "./TournamentOrganizationRepository.server"; diff --git a/app/features/tournament-subs/tournament-subs-schemas.server.ts b/app/features/tournament-subs/tournament-subs-schemas.server.ts index 2ffd86012..3a3375562 100644 --- a/app/features/tournament-subs/tournament-subs-schemas.server.ts +++ b/app/features/tournament-subs/tournament-subs-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { mainWeaponIds } from "~/modules/in-game-lists/weapon-ids"; import { id, processMany, removeDuplicates, safeJSONParse } from "~/utils/zod"; import { TOURNAMENT_SUB } from "./tournament-subs-constants"; diff --git a/app/features/tournament/actions/to.$id.admin.server.ts b/app/features/tournament/actions/to.$id.admin.server.ts index 6575beb7a..f5fa60c70 100644 --- a/app/features/tournament/actions/to.$id.admin.server.ts +++ b/app/features/tournament/actions/to.$id.admin.server.ts @@ -1,5 +1,5 @@ import type { ActionFunction } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import { userIsBanned } from "~/features/ban/core/banned.server"; import { bracketProgressionSchema } from "~/features/calendar/calendar-schemas"; diff --git a/app/features/tournament/tournament-schemas.server.ts b/app/features/tournament/tournament-schemas.server.ts index 9790b9fe5..02f7427df 100644 --- a/app/features/tournament/tournament-schemas.server.ts +++ b/app/features/tournament/tournament-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { _action, checkboxValueToBoolean, diff --git a/app/features/user-page/actions/u.$identifier.builds.new.server.ts b/app/features/user-page/actions/u.$identifier.builds.new.server.ts index 5815b2526..c68fcbcb5 100644 --- a/app/features/user-page/actions/u.$identifier.builds.new.server.ts +++ b/app/features/user-page/actions/u.$identifier.builds.new.server.ts @@ -1,6 +1,6 @@ import { type ActionFunction, redirect } from "@remix-run/node"; import * as R from "remeda"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import * as BuildRepository from "~/features/builds/BuildRepository.server"; import { BUILD } from "~/features/builds/builds-constants"; diff --git a/app/features/user-page/actions/u.$identifier.builds.server.ts b/app/features/user-page/actions/u.$identifier.builds.server.ts index fcf598c94..a8dcbded0 100644 --- a/app/features/user-page/actions/u.$identifier.builds.server.ts +++ b/app/features/user-page/actions/u.$identifier.builds.server.ts @@ -1,5 +1,5 @@ import { type ActionFunction, redirect } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { BUILD_SORT_IDENTIFIERS } from "~/db/tables"; import { requireUser } from "~/features/auth/core/user.server"; import * as BuildRepository from "~/features/builds/BuildRepository.server"; diff --git a/app/features/user-page/loaders/u.$identifier.builds.new.server.ts b/app/features/user-page/loaders/u.$identifier.builds.new.server.ts index b8f07722d..acf3ebe23 100644 --- a/app/features/user-page/loaders/u.$identifier.builds.new.server.ts +++ b/app/features/user-page/loaders/u.$identifier.builds.new.server.ts @@ -1,5 +1,5 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUserId } from "~/features/auth/core/user.server"; import * as BuildRepository from "~/features/builds/BuildRepository.server"; import type { Ability } from "~/modules/in-game-lists/types"; diff --git a/app/features/user-page/user-page-schemas.server.ts b/app/features/user-page/user-page-schemas.server.ts index 163032cb5..92ac6563f 100644 --- a/app/features/user-page/user-page-schemas.server.ts +++ b/app/features/user-page/user-page-schemas.server.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { BADGE } from "~/features/badges/badges-constants"; import { isCustomUrl } from "~/utils/urls"; import { diff --git a/app/features/user-search/loaders/u.server.ts b/app/features/user-search/loaders/u.server.ts index 9b7722d19..f66301852 100644 --- a/app/features/user-search/loaders/u.server.ts +++ b/app/features/user-search/loaders/u.server.ts @@ -1,5 +1,5 @@ import type { LoaderFunctionArgs, SerializeFrom } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { getUserId } from "~/features/auth/core/user.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { parseSearchParams } from "~/utils/remix.server"; diff --git a/app/features/vods/loaders/vods.new.server.ts b/app/features/vods/loaders/vods.new.server.ts index 79e8cfc00..987165c32 100644 --- a/app/features/vods/loaders/vods.new.server.ts +++ b/app/features/vods/loaders/vods.new.server.ts @@ -1,5 +1,5 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; -import { z } from "zod"; +import { z } from "zod/v4"; import { requireUser } from "~/features/auth/core/user.server"; import { notFoundIfFalsy } from "~/utils/remix.server"; import { actualNumber, id } from "~/utils/zod"; diff --git a/app/features/vods/routes/vods.new.tsx b/app/features/vods/routes/vods.new.tsx index 058af5bd9..3635c3167 100644 --- a/app/features/vods/routes/vods.new.tsx +++ b/app/features/vods/routes/vods.new.tsx @@ -8,7 +8,7 @@ import { useWatch, } from "react-hook-form"; import { useTranslation } from "react-i18next"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { WeaponCombobox } from "~/components/Combobox"; import { FormMessage } from "~/components/FormMessage"; import { Label } from "~/components/Label"; diff --git a/app/features/vods/vods-schemas.ts b/app/features/vods/vods-schemas.ts index 401fde209..6f109ebf6 100644 --- a/app/features/vods/vods-schemas.ts +++ b/app/features/vods/vods-schemas.ts @@ -1,5 +1,5 @@ import { add } from "date-fns"; -import { z } from "zod"; +import { z } from "zod/v4"; import { dayMonthYear, id, diff --git a/app/features/vods/vods-types.ts b/app/features/vods/vods-types.ts index dbef67b54..bfbdefd1b 100644 --- a/app/features/vods/vods-types.ts +++ b/app/features/vods/vods-types.ts @@ -1,4 +1,4 @@ -import type { z } from "zod"; +import type { z } from "zod/v4"; import type { Tables } from "~/db/tables"; import type { MainWeaponId } from "~/modules/in-game-lists/types"; import type { videoMatchSchema, videoSchema } from "./vods-schemas"; diff --git a/app/modules/patreon/schema.ts b/app/modules/patreon/schema.ts index 1622adde1..d41b63dc5 100644 --- a/app/modules/patreon/schema.ts +++ b/app/modules/patreon/schema.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import { TIER_1_ID, TIER_2_ID, diff --git a/app/modules/patreon/updater.ts b/app/modules/patreon/updater.ts index f41df966d..c02f6cf18 100644 --- a/app/modules/patreon/updater.ts +++ b/app/modules/patreon/updater.ts @@ -1,4 +1,4 @@ -import type { z } from "zod"; +import type { z } from "zod/v4"; import { STAFF_DISCORD_IDS } from "~/features/admin/admin-constants"; import * as UserRepository from "~/features/user-page/UserRepository.server"; import { dateToDatabaseTimestamp } from "~/utils/dates"; diff --git a/app/modules/twitch/schemas.ts b/app/modules/twitch/schemas.ts index 04e41f405..eaa6a1a1a 100644 --- a/app/modules/twitch/schemas.ts +++ b/app/modules/twitch/schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; import type { Unpacked } from "~/utils/types"; export const streamsSchema = z.object({ diff --git a/app/utils/Test.ts b/app/utils/Test.ts index 600dbb912..02f5169ce 100644 --- a/app/utils/Test.ts +++ b/app/utils/Test.ts @@ -1,7 +1,7 @@ import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; import type { Params } from "@remix-run/react"; import { expect } from "vitest"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import { REGULAR_USER_TEST_ID } from "~/db/seed/constants"; import { db, sql } from "~/db/sql"; import { ADMIN_ID } from "~/features/admin/admin-constants"; @@ -27,7 +27,7 @@ export function wrappedAction({ params = {}, }: { user?: "admin" | "regular"; params?: Params } = {}, ) => { - const body = new URLSearchParams(args); + const body = new URLSearchParams(args as any); const request = new Request("http://app.com/path", { method: "POST", body, diff --git a/app/utils/remix.server.ts b/app/utils/remix.server.ts index a8a99e71c..f11c3d4e6 100644 --- a/app/utils/remix.server.ts +++ b/app/utils/remix.server.ts @@ -7,7 +7,7 @@ import { import type { Params, UIMatch } from "@remix-run/react"; import type { Namespace, TFunction } from "i18next"; import { nanoid } from "nanoid"; -import type { z } from "zod"; +import type { z } from "zod/v4"; import type { navItems } from "~/components/layout/nav-items"; import { s3UploadHandler } from "~/features/img-upload"; import invariant from "./invariant"; @@ -65,7 +65,7 @@ export function parseSafeSearchParams({ }: { request: Request; schema: T; -}): z.SafeParseReturnType> { +}) { const url = new URL(request.url); return schema.safeParse(Object.fromEntries(url.searchParams)); } @@ -152,7 +152,9 @@ export async function safeParseRequestFormData({ if (!parsed.success) { return { success: false, - errors: parsed.error.errors.map((error) => error.message), + errors: parsed.error.issues.map( + (issue: { message: string }) => issue.message, + ), }; } diff --git a/app/utils/zod.ts b/app/utils/zod.ts index a726fb1d7..7aff2e0a0 100644 --- a/app/utils/zod.ts +++ b/app/utils/zod.ts @@ -1,5 +1,5 @@ -import type { ZodType } from "zod"; -import { z } from "zod"; +import type { ZodType } from "zod/v4"; +import { z } from "zod/v4"; import { CUSTOM_CSS_VAR_COLORS } from "~/features/user-page/user-page-constants"; import { abilities, @@ -318,7 +318,7 @@ export function checkboxValueToDbBoolean(value: unknown) { return 0; } -export const _action = (value: T) => +export const _action = (value: T) => z.preprocess(deduplicate, z.literal(value)); // Fix bug at least in Safari 15 where SubmitButton value might get sent twice @@ -341,9 +341,10 @@ export function numericEnum( return z.number().superRefine((val, ctx) => { if (!values.includes(val)) { ctx.addIssue({ - code: z.ZodIssueCode.invalid_enum_value, - options: [...values], - received: val, + code: z.ZodIssueCode.invalid_value, + input: val, + values: [...values], + message: `Expected one of: ${values.join(", ")}, received ${val}`, }); } }) as ZodType; diff --git a/package-lock.json b/package-lock.json index cb0d697a4..9b6e8dd65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@epic-web/cachified": "^5.5.2", "@faker-js/faker": "^9.7.0", "@headlessui/react": "^1.7.19", - "@hookform/resolvers": "^5.0.1", + "@hookform/resolvers": "^5.1.1", "@remix-run/node": "^2.16.5", "@remix-run/react": "^2.16.5", "@remix-run/serve": "^2.16.5", @@ -62,7 +62,7 @@ "slugify": "^1.6.6", "swr": "^2.3.3", "web-push": "^3.6.7", - "zod": "^3.24.3" + "zod": "^3.25.61" }, "devDependencies": { "@biomejs/biome": "1.9.4", @@ -2267,9 +2267,9 @@ } }, "node_modules/@hookform/resolvers": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.0.1.tgz", - "integrity": "sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.1.1.tgz", + "integrity": "sha512-J/NVING3LMAEvexJkyTLjruSm7aOFx7QX21pzkiJfMoNG0wl5aFEjLTl7ay7IQb9EWY6AkrBy7tHL2Alijpdcg==", "license": "MIT", "dependencies": { "@standard-schema/utils": "^0.3.0" @@ -18693,9 +18693,9 @@ } }, "node_modules/zod": { - "version": "3.24.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz", - "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==", + "version": "3.25.61", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.61.tgz", + "integrity": "sha512-fzfJgUw78LTNnHujj9re1Ov/JJQkRZZGDMcYqSx7Hp4rPOkKywaFHq0S6GoHeXs0wGNE/sIOutkXgnwzrVOGCQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index 8a55fd14e..6892a075a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@epic-web/cachified": "^5.5.2", "@faker-js/faker": "^9.7.0", "@headlessui/react": "^1.7.19", - "@hookform/resolvers": "^5.0.1", + "@hookform/resolvers": "^5.1.1", "@remix-run/node": "^2.16.5", "@remix-run/react": "^2.16.5", "@remix-run/serve": "^2.16.5", @@ -81,7 +81,7 @@ "slugify": "^1.6.6", "swr": "^2.3.3", "web-push": "^3.6.7", - "zod": "^3.24.3" + "zod": "^3.25.61" }, "devDependencies": { "@biomejs/biome": "1.9.4", diff --git a/scripts/check-homemade-badges.ts b/scripts/check-homemade-badges.ts index a06cf86d9..f23017715 100644 --- a/scripts/check-homemade-badges.ts +++ b/scripts/check-homemade-badges.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import { z } from "zod"; +import { z } from "zod/v4"; import badgesJson from "../app/features/badges/homemade.json" with { type: "json", }; diff --git a/scripts/create-analyzer-json.ts b/scripts/create-analyzer-json.ts index c59cd3706..f5d6bfd7f 100644 --- a/scripts/create-analyzer-json.ts +++ b/scripts/create-analyzer-json.ts @@ -8,7 +8,7 @@ // 5) params (weapon folder) inside dicts import fs from "node:fs"; -import { z } from "zod"; +import { z } from "zod/v4"; import type { MainWeaponParams, SubWeaponParams } from "~/modules/analyzer"; import type { ParamsJson } from "~/modules/analyzer/types"; import { diff --git a/scripts/create-league-divisions.ts b/scripts/create-league-divisions.ts index 227503a08..b195ce45a 100644 --- a/scripts/create-league-divisions.ts +++ b/scripts/create-league-divisions.ts @@ -1,7 +1,7 @@ // for testing use the command `npx tsx ./scripts/create-league-divisions.ts 6 'https://gist.githubusercontent.com/Sendouc/38aa4d5d8426035ce178c09598ae627f/raw/17be9bb53a9f017c2097d0624f365d1c5a029f01/league.csv'` import "dotenv/config"; -import { z } from "zod"; +import { z } from "zod/v4"; import { db } from "~/db/sql"; import { ADMIN_ID } from "~/features/admin/admin-constants"; import * as CalendarRepository from "~/features/calendar/CalendarRepository.server"; diff --git a/scripts/placements/schemas.ts b/scripts/placements/schemas.ts index 0ebf7ff05..90348ecf5 100644 --- a/scripts/placements/schemas.ts +++ b/scripts/placements/schemas.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import { z } from "zod/v4"; const placements = z.object({ edges: z.array(