diff --git a/apps/frontend/app/routes/_dashboard.calendar.tsx b/apps/frontend/app/routes/_dashboard.calendar.tsx index c43a79df30..0459165717 100644 --- a/apps/frontend/app/routes/_dashboard.calendar.tsx +++ b/apps/frontend/app/routes/_dashboard.calendar.tsx @@ -15,12 +15,11 @@ import { UserCalendarEventsDocument, type UserCalendarEventsQuery, } from "@ryot/generated/graphql/backend/graphql"; -import { sum } from "@ryot/ts-utils"; +import { parseRequestSearchQuery, sum } from "@ryot/ts-utils"; import { IconChevronLeft, IconChevronRight } from "@tabler/icons-react"; import { Fragment } from "react/jsx-runtime"; import { match } from "ts-pattern"; import { z } from "zod"; -import { zx } from "zodix"; import { ApplicationGrid } from "~/components/common"; import { MetadataDisplayItem } from "~/components/media"; import { dayjsLib } from "~/lib/generals"; @@ -40,7 +39,7 @@ export type SearchParams = z.infer; export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("calendar", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const date = dayjsLib(query.date); const [{ userCalendarEvents }] = await Promise.all([ serverGqlService.authenticatedRequest(request, UserCalendarEventsDocument, { diff --git a/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx b/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx index 59a563ae76..c17803cd4b 100644 --- a/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.collections.$id._index.tsx @@ -24,7 +24,11 @@ import { GraphqlSortOrder, MediaLot, } from "@ryot/generated/graphql/backend/graphql"; -import { startCase, zodIntAsString } from "@ryot/ts-utils"; +import { + parseRequestSearchQuery, + startCase, + zodIntAsString, +} from "@ryot/ts-utils"; import { IconBucketDroplet, IconFilter, @@ -84,7 +88,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { request, ); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ collectionContents }] = await Promise.all([ serverGqlService.authenticatedRequest(request, CollectionContentsDocument, { input: { diff --git a/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx index 60356e140d..ef127946c8 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.$entity.list.tsx @@ -29,6 +29,7 @@ import { import { changeCase, humanizeDuration, + parseRequestSearchQuery, truncate, zodIntAsString, } from "@ryot/ts-utils"; @@ -92,7 +93,7 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => { }); const cookieName = await getEnhancedCookieName(`${entity}.list`, request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const itemList = await match(entity) .with(FitnessEntity.Workouts, async () => { const { userWorkoutsList } = await serverGqlService.authenticatedRequest( diff --git a/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx b/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx index 7fcaacc348..677d60e56e 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.exercises.$action.tsx @@ -33,6 +33,7 @@ import { import { cloneDeep, getActionIntent, + parseRequestSearchQuery, processSubmission, startCase, zodBoolAsString, @@ -64,7 +65,7 @@ enum Action { export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { action } = zx.parseParams(params, { action: z.nativeEnum(Action) }); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const details = await match(action) .with(Action.Create, () => undefined) .with(Action.Update, async () => { diff --git a/apps/frontend/app/routes/_dashboard.fitness.exercises.item.$id._index.tsx b/apps/frontend/app/routes/_dashboard.fitness.exercises.item.$id._index.tsx index cb91227831..0f9768c35a 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.exercises.item.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.exercises.item.$id._index.tsx @@ -44,6 +44,7 @@ import { import { changeCase, isNumber, + parseRequestSearchQuery, snakeCase, sortBy, startCase, @@ -111,7 +112,7 @@ const paramsSchema = { id: z.string() }; export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { id: exerciseId } = zx.parseParams(params, paramsSchema); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ exerciseDetails }, { userExerciseDetails }] = await Promise.all([ serverGqlService.request(ExerciseDetailsDocument, { exerciseId }), serverGqlService.authenticatedRequest( diff --git a/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx index f085dcc22d..5010e5c878 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.exercises.list.tsx @@ -47,6 +47,7 @@ import { import { getActionIntent, isNumber, + parseRequestSearchQuery, processSubmission, snakeCase, startCase, @@ -64,7 +65,6 @@ import { $path } from "remix-routes"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; -import { zx } from "zodix"; import { DebouncedSearchInput, FiltersModal } from "~/components/common"; import { dayjsLib, @@ -113,9 +113,9 @@ const searchParamsSchema = z.object({ level: z.nativeEnum(ExerciseLevel).optional(), force: z.nativeEnum(ExerciseForce).optional(), sortBy: z.nativeEnum(ExerciseSortBy).optional(), + muscle: z.nativeEnum(ExerciseMuscle).optional(), mechanic: z.nativeEnum(ExerciseMechanic).optional(), equipment: z.nativeEnum(ExerciseEquipment).optional(), - muscle: z.nativeEnum(ExerciseMuscle).optional(), }); export type SearchParams = z.infer; @@ -123,7 +123,7 @@ export type SearchParams = z.infer; export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("exercises.list", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); query.sortBy = query.sortBy ?? defaultFiltersValue.sortBy; query[pageQueryParam] = query[pageQueryParam] ?? 1; const [{ exercisesList }] = await Promise.all([ diff --git a/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx b/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx index 5a86603540..3d917844cf 100644 --- a/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx +++ b/apps/frontend/app/routes/_dashboard.fitness.measurements.list.tsx @@ -22,7 +22,12 @@ import { DeleteUserMeasurementDocument, UserMeasurementsListDocument, } from "@ryot/generated/graphql/backend/graphql"; -import { getActionIntent, processSubmission, startCase } from "@ryot/ts-utils"; +import { + getActionIntent, + parseRequestSearchQuery, + processSubmission, + startCase, +} from "@ryot/ts-utils"; import { IconChartArea, IconPlus, @@ -34,7 +39,6 @@ import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { useLocalStorage } from "usehooks-ts"; import { z } from "zod"; -import { zx } from "zodix"; import { TimeSpan, dayjsLib, @@ -67,7 +71,7 @@ const defaultTimeSpan = TimeSpan.Last30Days; export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("measurements.list", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const now = dayjsLib(); const startTime = getDateFromTimeSpan(query.timeSpan || defaultTimeSpan); const [{ userMeasurementsList }] = await Promise.all([ diff --git a/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx b/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx index 68bddd77ef..dfbe83e00a 100644 --- a/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx +++ b/apps/frontend/app/routes/_dashboard.media.$action.$lot.tsx @@ -38,6 +38,7 @@ import { } from "@ryot/generated/graphql/backend/graphql"; import { changeCase, + parseRequestSearchQuery, snakeCase, startCase, zodBoolAsString, @@ -126,13 +127,14 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { request, ); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, { + const schema = z.object({ query: z.string().optional(), [pageQueryParam]: zodIntAsString.default("1"), }); + const query = parseRequestSearchQuery(request, schema); const [totalResults, mediaList, mediaSearch] = await match(action) .with(Action.List, async () => { - const urlParse = zx.parseQuery(request, { + const listSchema = z.object({ collections: zodCommaDelimitedString, endDateRange: z.string().optional(), startDateRange: z.string().optional(), @@ -148,6 +150,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { .nativeEnum(MediaGeneralFilter) .default(defaultFilters.mineGeneralFilter), }); + const urlParse = parseRequestSearchQuery(request, listSchema); const { metadataList } = await serverGqlService.authenticatedRequest( request, MetadataListDocument, @@ -180,11 +183,12 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { (m) => m.lot === lot, ); if (!metadataSourcesForLot) throw new Error("Mapping not found"); - const urlParse = zx.parseQuery(request, { + const searchSchema = z.object({ source: z .nativeEnum(MediaSource) .default(metadataSourcesForLot.sources[0]), }); + const urlParse = parseRequestSearchQuery(request, searchSchema); let metadataSearch: MetadataSearchQuery["metadataSearch"] | false; try { const response = await serverGqlService.authenticatedRequest( @@ -193,8 +197,8 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { { input: { lot, - search: { page: query[pageQueryParam], query: query.query }, source: urlParse.source, + search: { page: query[pageQueryParam], query: query.query }, }, }, ); diff --git a/apps/frontend/app/routes/_dashboard.media.genre.$id._index.tsx b/apps/frontend/app/routes/_dashboard.media.genre.$id._index.tsx index a9aef6bf77..616e3eba47 100644 --- a/apps/frontend/app/routes/_dashboard.media.genre.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.media.genre.$id._index.tsx @@ -10,7 +10,7 @@ import { import type { LoaderFunctionArgs, MetaArgs } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { GenreDetailsDocument } from "@ryot/generated/graphql/backend/graphql"; -import { zodIntAsString } from "@ryot/ts-utils"; +import { parseRequestSearchQuery, zodIntAsString } from "@ryot/ts-utils"; import { z } from "zod"; import { zx } from "zodix"; import { ApplicationGrid } from "~/components/common"; @@ -34,7 +34,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: genreId } = zx.parseParams(params, { id: z.string() }); const cookieName = await getEnhancedCookieName(`genre.${genreId}`, request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ genreDetails }] = await Promise.all([ serverGqlService.request(GenreDetailsDocument, { input: { genreId, page: query[pageQueryParam] }, diff --git a/apps/frontend/app/routes/_dashboard.media.genre.list.tsx b/apps/frontend/app/routes/_dashboard.media.genre.list.tsx index b56879eed0..105d70fa0d 100644 --- a/apps/frontend/app/routes/_dashboard.media.genre.list.tsx +++ b/apps/frontend/app/routes/_dashboard.media.genre.list.tsx @@ -23,13 +23,13 @@ import { import { getInitials, isString, + parseRequestSearchQuery, truncate, zodIntAsString, } from "@ryot/ts-utils"; import { useQuery } from "@tanstack/react-query"; import { $path } from "remix-routes"; import { z } from "zod"; -import { zx } from "zodix"; import { ApplicationGrid, DebouncedSearchInput, @@ -65,7 +65,7 @@ export type SearchParams = z.infer; export const loader = async ({ request }: LoaderFunctionArgs) => { const cookieName = await getEnhancedCookieName("genre.list", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ genresList }] = await Promise.all([ serverGqlService.request(GenresListDocument, { input: { page: query[pageQueryParam], query: query.query }, diff --git a/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx b/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx index 7fa1a00014..038c74cb8a 100644 --- a/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.media.groups.$action.tsx @@ -29,6 +29,7 @@ import { import { changeCase, isString, + parseRequestSearchQuery, startCase, zodBoolAsString, zodIntAsString, @@ -82,13 +83,14 @@ enum Action { export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { action } = zx.parseParams(params, { action: z.nativeEnum(Action) }); const cookieName = await getEnhancedCookieName(`groups.${action}`, request); - const query = zx.parseQuery(request, { + const schema = z.object({ query: z.string().optional(), [pageQueryParam]: zodIntAsString.default("1"), }); + const query = parseRequestSearchQuery(request, schema); const [totalResults, list, search] = await match(action) .with(Action.List, async () => { - const urlParse = zx.parseQuery(request, { + const listSchema = z.object({ collections: zodCommaDelimitedString, invertCollection: zodBoolAsString.optional(), orderBy: z.nativeEnum(GraphqlSortOrder).default(defaultFilters.orderBy), @@ -96,16 +98,17 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { .nativeEnum(PersonAndMetadataGroupsSortBy) .default(defaultFilters.sortBy), }); + const urlParse = parseRequestSearchQuery(request, listSchema); const { metadataGroupsList } = await serverGqlService.authenticatedRequest( request, MetadataGroupsListDocument, { input: { - search: { page: query[pageQueryParam], query: query.query }, - sort: { by: urlParse.sortBy, order: urlParse.orderBy }, - filter: { collections: urlParse.collections }, invertCollection: urlParse.invertCollection, + filter: { collections: urlParse.collections }, + sort: { by: urlParse.sortBy, order: urlParse.orderBy }, + search: { page: query[pageQueryParam], query: query.query }, }, }, ); @@ -116,9 +119,10 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { ] as const; }) .with(Action.Search, async () => { - const urlParse = zx.parseQuery(request, { + const searchSchema = z.object({ source: z.nativeEnum(MediaSource).default(MediaSource.Tmdb), }); + const urlParse = parseRequestSearchQuery(request, searchSchema); const coreDetails = await getCoreDetails(); const lot = coreDetails.metadataGroupSourceLotMappings.find( (m) => m.source === urlParse.source, diff --git a/apps/frontend/app/routes/_dashboard.media.groups.item.$id._index.tsx b/apps/frontend/app/routes/_dashboard.media.groups.item.$id._index.tsx index 42a1c5437b..0aac869715 100644 --- a/apps/frontend/app/routes/_dashboard.media.groups.item.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.media.groups.item.$id._index.tsx @@ -17,6 +17,7 @@ import { MetadataGroupDetailsDocument, UserMetadataGroupDetailsDocument, } from "@ryot/generated/graphql/backend/graphql"; +import { parseRequestSearchQuery } from "@ryot/ts-utils"; import { IconDeviceTv, IconInfoCircle, @@ -49,7 +50,7 @@ export type SearchParams = z.infer; export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: metadataGroupId } = zx.parseParams(params, { id: z.string() }); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ metadataGroupDetails }, { userMetadataGroupDetails }] = await Promise.all([ serverGqlService.request(MetadataGroupDetailsDocument, { diff --git a/apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx b/apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx index eb02d422f6..5cbce2c540 100644 --- a/apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.media.item.$id._index.tsx @@ -64,6 +64,7 @@ import { isInteger, isNumber, isString, + parseRequestSearchQuery, processSubmission, } from "@ryot/ts-utils"; import { @@ -153,7 +154,7 @@ export type SearchParams = z.infer; export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: metadataId } = zx.parseParams(params, { id: z.string() }); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ metadataDetails }, { userMetadataDetails }] = await Promise.all([ serverGqlService.request(MetadataDetailsDocument, { metadataId }), serverGqlService.authenticatedRequest( diff --git a/apps/frontend/app/routes/_dashboard.media.people.$action.tsx b/apps/frontend/app/routes/_dashboard.media.people.$action.tsx index d906baf12d..b6ed773505 100644 --- a/apps/frontend/app/routes/_dashboard.media.people.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.media.people.$action.tsx @@ -28,6 +28,7 @@ import { } from "@ryot/generated/graphql/backend/graphql"; import { changeCase, + parseRequestSearchQuery, startCase, zodBoolAsString, zodIntAsString, @@ -77,7 +78,7 @@ enum Action { Search = "search", } -const searchUrlSchema = z.object({ +const searchSchema = z.object({ isTmdbCompany: zodBoolAsString.optional(), isAnilistStudio: zodBoolAsString.optional(), isHardcoverPublisher: zodBoolAsString.optional(), @@ -88,13 +89,14 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { action } = zx.parseParams(params, { action: z.nativeEnum(Action) }); const cookieName = await getEnhancedCookieName(`people.${action}`, request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, { + const schema = z.object({ query: z.string().optional(), [pageQueryParam]: zodIntAsString.default("1"), }); + const query = parseRequestSearchQuery(request, schema); const [totalResults, peopleList, peopleSearch] = await match(action) .with(Action.List, async () => { - const urlParse = zx.parseQuery(request, { + const listSchema = z.object({ collections: zodCommaDelimitedString, invertCollection: zodBoolAsString.optional(), orderBy: z.nativeEnum(GraphqlSortOrder).default(defaultFilters.orderBy), @@ -102,6 +104,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { .nativeEnum(PersonAndMetadataGroupsSortBy) .default(defaultFilters.sortBy), }); + const urlParse = parseRequestSearchQuery(request, listSchema); const { peopleList } = await serverGqlService.authenticatedRequest( request, PeopleListDocument, @@ -121,7 +124,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { ] as const; }) .with(Action.Search, async () => { - const urlParse = zx.parseQuery(request, searchUrlSchema); + const urlParse = parseRequestSearchQuery(request, searchSchema); const { peopleSearch } = await serverGqlService.authenticatedRequest( request, PeopleSearchDocument, @@ -397,7 +400,7 @@ const PersonSearchItem = (props: { const commitPerson = async ( name: string, identifier: string, - additionalData: z.infer, + additionalData: z.infer, ) => { const data = new FormData(); data.append("identifier", identifier); diff --git a/apps/frontend/app/routes/_dashboard.media.people.item.$id._index.tsx b/apps/frontend/app/routes/_dashboard.media.people.item.$id._index.tsx index 04fcfaeab3..4bd260a815 100644 --- a/apps/frontend/app/routes/_dashboard.media.people.item.$id._index.tsx +++ b/apps/frontend/app/routes/_dashboard.media.people.item.$id._index.tsx @@ -18,7 +18,7 @@ import { PersonDetailsDocument, UserPersonDetailsDocument, } from "@ryot/generated/graphql/backend/graphql"; -import { sum } from "@ryot/ts-utils"; +import { parseRequestSearchQuery, sum } from "@ryot/ts-utils"; import { IconDeviceTv, IconInfoCircle, @@ -57,7 +57,7 @@ export type SearchParams = z.infer; export const loader = async ({ request, params }: LoaderFunctionArgs) => { const { id: personId } = zx.parseParams(params, { id: z.string() }); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ personDetails }, { userPersonDetails }] = await Promise.all([ serverGqlService.request(PersonDetailsDocument, { personId }), serverGqlService.authenticatedRequest(request, UserPersonDetailsDocument, { diff --git a/apps/frontend/app/routes/_dashboard.media.update.$action.tsx b/apps/frontend/app/routes/_dashboard.media.update.$action.tsx index ba1ba470e7..64d3c0dd8a 100644 --- a/apps/frontend/app/routes/_dashboard.media.update.$action.tsx +++ b/apps/frontend/app/routes/_dashboard.media.update.$action.tsx @@ -28,7 +28,12 @@ import { MetadataDetailsDocument, UpdateCustomMetadataDocument, } from "@ryot/generated/graphql/backend/graphql"; -import { camelCase, changeCase, processSubmission } from "@ryot/ts-utils"; +import { + camelCase, + changeCase, + parseRequestSearchQuery, + processSubmission, +} from "@ryot/ts-utils"; import { IconCalendar, IconPhoto, IconVideo } from "@tabler/icons-react"; import { $path } from "remix-routes"; import invariant from "tiny-invariant"; @@ -52,7 +57,7 @@ export type SearchParams = z.infer; export const loader = async ({ params, request }: LoaderFunctionArgs) => { const { action } = zx.parseParams(params, { action: z.nativeEnum(Action) }); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const details = await match(action) .with(Action.Create, () => undefined) .with(Action.Edit, async () => { diff --git a/apps/frontend/app/routes/_dashboard.settings.preferences.tsx b/apps/frontend/app/routes/_dashboard.settings.preferences.tsx index f00ed34eca..cedf2a72a8 100644 --- a/apps/frontend/app/routes/_dashboard.settings.preferences.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.preferences.tsx @@ -41,6 +41,7 @@ import { cn, isBoolean, isNumber, + parseRequestSearchQuery, snakeCase, startCase, } from "@ryot/ts-utils"; @@ -55,7 +56,6 @@ import { type Draft, produce } from "immer"; import { Fragment, useState } from "react"; import { match } from "ts-pattern"; import { z } from "zod"; -import { zx } from "zodix"; import { PRO_REQUIRED_MESSAGE, clientGqlService } from "~/lib/generals"; import { useCoreDetails, @@ -70,7 +70,7 @@ const searchSchema = z.object({ }); export const loader = async ({ request }: LoaderFunctionArgs) => { - const query = zx.parseQuery(request, searchSchema); + const query = parseRequestSearchQuery(request, searchSchema); return { query }; }; diff --git a/apps/frontend/app/routes/_dashboard.settings.users.tsx b/apps/frontend/app/routes/_dashboard.settings.users.tsx index 71b6fa3e4f..d10a22cf67 100644 --- a/apps/frontend/app/routes/_dashboard.settings.users.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.users.tsx @@ -36,6 +36,7 @@ import { import { changeCase, getActionIntent, + parseRequestSearchQuery, processSubmission, truncate, zodCheckboxAsString, @@ -53,7 +54,6 @@ import { $path } from "remix-routes"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; -import { zx } from "zodix"; import { DebouncedSearchInput } from "~/components/common"; import { openConfirmationModal } from "~/lib/generals"; import { useConfirmSubmit, useCoreDetails } from "~/lib/hooks"; @@ -76,7 +76,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { if (userDetails.lot !== UserLot.Admin) throw redirect($path("/")); const cookieName = await getEnhancedCookieName("settings.users", request); await redirectUsingEnhancedCookieSearchParams(request, cookieName); - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const [{ usersList }] = await Promise.all([ serverGqlService.authenticatedRequest(request, UsersListDocument, { query: query.query, diff --git a/apps/frontend/app/routes/api.auth.tsx b/apps/frontend/app/routes/api.auth.tsx index bb750a4252..52ff5d198d 100644 --- a/apps/frontend/app/routes/api.auth.tsx +++ b/apps/frontend/app/routes/api.auth.tsx @@ -6,9 +6,9 @@ import { RegisterUserDocument, UserByOidcIssuerIdDocument, } from "@ryot/generated/graphql/backend/graphql"; +import { parseRequestSearchQuery } from "@ryot/ts-utils"; import { $path } from "remix-routes"; import { z } from "zod"; -import { zx } from "zodix"; import { getCookiesForApplication, getCoreDetails, @@ -21,7 +21,7 @@ const searchParamsSchema = z.object({ code: z.string() }); export type SearchParams = z.infer; export const loader = async ({ request }: LoaderFunctionArgs) => { - const input = zx.parseQuery(request, searchParamsSchema); + const input = parseRequestSearchQuery(request, searchParamsSchema); const { getOidcToken } = await serverGqlService.request( GetOidcTokenDocument, input, diff --git a/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx b/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx index 66dfe7dc71..ec5e0bef02 100644 --- a/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx +++ b/apps/frontend/app/routes/api.sharing.$accessLinkId.tsx @@ -3,7 +3,7 @@ import { ProcessAccessLinkDocument, type ProcessAccessLinkInput, } from "@ryot/generated/graphql/backend/graphql"; -import { zodBoolAsString } from "@ryot/ts-utils"; +import { parseRequestSearchQuery, zodBoolAsString } from "@ryot/ts-utils"; import { $path } from "remix-routes"; import { safeRedirect } from "remix-utils/safe-redirect"; import { z } from "zod"; @@ -23,8 +23,8 @@ const searchParamsSchema = z.object({ }); export const loader = async ({ request, params }: LoaderFunctionArgs) => { - const query = zx.parseQuery(request, searchParamsSchema); const routeParams = zx.parseParams(params, paramsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const input: ProcessAccessLinkInput = {}; if (query.isAccountDefault) input.username = routeParams.accessLinkId; else input.id = routeParams.accessLinkId; @@ -33,14 +33,13 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { { input }, ); if (processAccessLink.__typename === "ProcessAccessLinkResponse") { - const queryParams = zx.parseQuery(request, searchParamsSchema); const headers = await getCookiesForApplication( processAccessLink.apiKey, processAccessLink.tokenValidForDays, ); return redirect( safeRedirect( - queryParams[redirectToQueryParam] || + query[redirectToQueryParam] || processAccessLink.redirectTo || $path("/"), ), diff --git a/apps/frontend/app/routes/auth.tsx b/apps/frontend/app/routes/auth.tsx index e2a5bb73d5..3ff79530e3 100644 --- a/apps/frontend/app/routes/auth.tsx +++ b/apps/frontend/app/routes/auth.tsx @@ -28,6 +28,7 @@ import { } from "@ryot/generated/graphql/backend/graphql"; import { getActionIntent, + parseRequestSearchQuery, processSubmission, startCase, zodNumAsString, @@ -38,7 +39,6 @@ import { safeRedirect } from "remix-utils/safe-redirect"; import { match } from "ts-pattern"; import { withQuery } from "ufo"; import { z } from "zod"; -import { zx } from "zodix"; import { dayjsLib, redirectToQueryParam } from "~/lib/generals"; import { createToastHeaders, @@ -57,7 +57,7 @@ export type SearchParams = z.infer & Record; export const loader = async ({ request }: LoaderFunctionArgs) => { - const query = zx.parseQuery(request, searchParamsSchema); + const query = parseRequestSearchQuery(request, searchParamsSchema); const isAuthenticated = !!getAuthorizationCookie(request); if (isAuthenticated) { throw await redirectWithToast(